From fdc6c9468e3b65e05008bc6aa1cd2862ea8039cd Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 14 Apr 2023 09:09:29 +0200 Subject: [PATCH 001/186] Add error handler to duplex stream, see #329 --- components/devices/class.interface.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/components/devices/class.interface.js b/components/devices/class.interface.js index bc5dbb3..78cab52 100644 --- a/components/devices/class.interface.js +++ b/components/devices/class.interface.js @@ -134,6 +134,15 @@ module.exports = class Interface { writable: output }); + // when multiple reuqests are done parallal, sometimes a AbortedErr is thrown + // see #329 for details + // TODO: Check if the upstream is drained, and perform requests in series + // As "quick fix" till a solution is found for #312 catch the trown error + socket.on("error", (err) => { + console.log("Catched error on http.agent.createConnection", err); + this.stream.destroy(); + }); + /* [socket, this.stream, input, output].forEach((stream) => { let cleanup = finished(stream, (err) => { From 43c942dc6b2a10f71f7e02bf500d383dbc0cccbc Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 20 Apr 2023 12:01:25 +0200 Subject: [PATCH 002/186] Implemented delay between makro execution for scenes --- components/scenes/class.scene.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/components/scenes/class.scene.js b/components/scenes/class.scene.js index 2139c8c..25c708f 100644 --- a/components/scenes/class.scene.js +++ b/components/scenes/class.scene.js @@ -1,3 +1,5 @@ +const { setTimeout } = require("timers/promises"); + const Makro = require("./class.makro.js"); @@ -54,21 +56,33 @@ module.exports = class Scene { let ac = new AbortController(); this._ac = ac; - let init = this.makros.map((makro) => { + let init = this.makros.filter(({ + enabled = true + }) => { + + // execute only enabled makros + return enabled; + + }).map((makro) => { // bind scope to method return makro.execute.bind(makro); }).reduce((acc, cur, i) => { return (result) => { - return acc(result, this._ac.signal).then((r) => { + return acc(result, this._ac.signal).then(async (r) => { if (this.aborted) { return Promise.reject("Aborted!"); } else { + // NOTE: Intended to be a workaround for #329 & #312 + // But the general idea of this is not bad + await setTimeout(Number(process.env.SCENES_MAKRO_DELAY)); + this.index = i; + return cur(r, this._ac.signal); } From bc67964edd4be21240210ae9f29814a27f6838dc Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 20 Apr 2023 12:03:19 +0200 Subject: [PATCH 003/186] makro schema chagned: `enabled` prop added --- components/scenes/class.makro.js | 1 + 1 file changed, 1 insertion(+) diff --git a/components/scenes/class.makro.js b/components/scenes/class.makro.js index b1d9b29..1e6ff54 100644 --- a/components/scenes/class.makro.js +++ b/components/scenes/class.makro.js @@ -108,6 +108,7 @@ module.exports = class Makro { return String(new mongodb.ObjectId()); }), type: Joi.string().valid("command", "timer", "scene"/*, "state"*/).required(), + enabled: Joi.boolean().default(true), timestamps: Joi.object({ created: Joi.number().allow(null), updated: Joi.number().allow(null) From 00bff4c5d59507c410c4757dc929176e9760c2e4 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sat, 29 Apr 2023 13:00:24 +0200 Subject: [PATCH 004/186] fix #329 --- components/devices/class.interface.js | 106 +++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/components/devices/class.interface.js b/components/devices/class.interface.js index 78cab52..acc03b1 100644 --- a/components/devices/class.interface.js +++ b/components/devices/class.interface.js @@ -104,6 +104,8 @@ module.exports = class Interface { * * @link https://nodejs.org/dist/latest-v16.x/docs/api/http.html#new-agentoptions */ + /* + // *OLD* function, see #329 httpAgent(options) { options = Object.assign({ @@ -169,7 +171,7 @@ module.exports = class Interface { }); }); - */ + * // TODO implement other socket functions?! @@ -191,6 +193,108 @@ module.exports = class Interface { return agent; } + */ + + + // NEW VERSION, fix for #329 + httpAgent(options = {}) { + + let agent = new Agent({ + keepAlive: true, + maxSockets: 1, + ...options + }); + + //let settings = this.settings; + + + agent.createConnection = ({ host = null, port = null }) => { + + console.log(`############## Create connection to tcp://${host}:${port}`); + + /* + // check if passed host/port matches interface settings? + if (host != settings.host || port != settings.port) { + + let msg = "host/port for interface missmatch, expected:\r\n"; + msg += `\thost = ${host}; got = ${settings.host}\r\n`; + msg += `\tport = ${settings.port}; got = ${settings.port}`; + + throw new Error(msg); + + } + */ + + let readable = new PassThrough(); + let writable = new PassThrough(); + + + // TODO Implement "auto-drain" when no upstream is attached -> Move this "lower", e.g. before ws upstream? + /* + let writable = new Transform({ + transform(chunk, enc, cb) { + + debugger; + + //console.log("this.stream",); + console.error(">>>> Write data, flowing?", str.upstream ? true : false, settings.host); + + if (str.upstream) { + this.push(chunk); + } else { + while (this.read() !== null) { + // do nothing with writen input data + // empty readable queue + } + } + + cb(); + + } + }); + */ + + + let stream = new Duplex.from({ + readable, + writable + }); + + stream.destroy = (...args) => { + console.log("socket.destroy();", args); + }; + + stream.ref = (...args) => { + console.log("socket.unref();", args); + }; + + stream.unref = (...args) => { + console.log("socket.unref();", args); + }; + + stream.setKeepAlive = (...args) => { + console.log("socket.setKeepAlive()", args); + }; + + stream.setTimeout = (...args) => { + console.log("socket.setTimeout();", args); + }; + + stream.setNoDelay = (...args) => { + console.log("socket.setNotDelay();", args); + }; + + this.stream.pipe(readable, { end: false }); + writable.pipe(this.stream, { end: false }); + + return stream; + + }; + + return agent; + + } + }; \ No newline at end of file From b046c38fb58abce082ad0cfc16e1f138c6b6c73f Mon Sep 17 00:00:00 2001 From: mStirner Date: Mon, 8 May 2023 20:58:16 +0200 Subject: [PATCH 005/186] note added --- adapter/eol.js | 1 + 1 file changed, 1 insertion(+) diff --git a/adapter/eol.js b/adapter/eol.js index e30cc5b..429fee5 100644 --- a/adapter/eol.js +++ b/adapter/eol.js @@ -25,6 +25,7 @@ module.exports = (options = {}) => { let decode = new Transform({ transform(chunk, encoding, cb) { log.trace("[encode] (%s) %j", encoding, chunk); + // NOTE (mstirner) is this right? cb(null, chunk.subarray(0, nl.length)); }, ...options From a8b351b8bc699ca3b3125fe3ba06243043391eeb Mon Sep 17 00:00:00 2001 From: mStirner Date: Mon, 8 May 2023 20:58:56 +0200 Subject: [PATCH 006/186] draft/note for triggers --- components/scenes/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/components/scenes/index.js b/components/scenes/index.js index 4331014..06d5082 100644 --- a/components/scenes/index.js +++ b/components/scenes/index.js @@ -26,6 +26,7 @@ class C_SCENES extends COMPONENT { }), name: Joi.string().required(), makros: Joi.array().items(Makro.schema()).default([]) + //triggers: Joi.array().items(Trigger.schema()).default([]) }, module); this.hooks.post("add", (data, next) => { From d7fc96459ae8e7d3d0015f75f348a995b117ed27 Mon Sep 17 00:00:00 2001 From: mStirner Date: Mon, 8 May 2023 20:59:35 +0200 Subject: [PATCH 007/186] `cronjob` added --- system/cronjob/class.cron.js | 144 +++++++++++++++++++++++++++++++++++ system/cronjob/class.job.js | 44 +++++++++++ system/cronjob/index.js | 77 +++++++++++++++++++ 3 files changed, 265 insertions(+) create mode 100644 system/cronjob/class.cron.js create mode 100644 system/cronjob/class.job.js create mode 100644 system/cronjob/index.js diff --git a/system/cronjob/class.cron.js b/system/cronjob/class.cron.js new file mode 100644 index 0000000..c666a85 --- /dev/null +++ b/system/cronjob/class.cron.js @@ -0,0 +1,144 @@ +const Job = require("./class.job.js"); + +module.exports = class Cron { + + // based on https://gist.github.com/shimondoodkin/1926749 + + /** + * @class Cron + * @description + * + * @param {Boolean} [autostart=true] Start automaticly processing jobs + * + * @property {Array} jobs + * @property {Number|null} timer + * @property {Number} interval + * @property {Boolean} autostart + */ + constructor(autostart = true) { + + this.jobs = []; + this.timer = null; + this.interval = 60 * 1000; + this.autostart = autostart; + + if (this.autostart) { + this.start(); + } + + } + + + /** + * @function match + * Checks if time/date matches with job + * + * @param {String} a + * @param {String} b + * + * @returns {Boolean} + */ + match(a, b) { + + for (let c, b0, i = 0; i < a.length; i++) { + + c = a[i]; + + if (c[0] === -1 || (b >= c[0] && b <= c[1])) { + + b0 = b - c[0]; + + if (c[2] === -1 || b0 === 0 || b0 % c[2] === 0) { + return true; + } + + } + + } + + return false; + + } + + + /** + * @function process + * Procces jobs + * + * @internal + */ + process() { + + let now = new Date(); + + this.jobs.forEach(({ minute, hour, date, month, day, fnc }) => { + + let run = 1; + + run &= this.match(minute, now.getMinutes()); + run &= this.match(hour, now.getHours()); + run &= this.match(date, now.getDate()); + run &= this.match(month, now.getMonth()); + run &= this.match(day, now.getDay()); + + if (run) { + fnc(); + } + + }); + + } + + + /** + * @function add + * Add new job + * + * @param {String} cron Time declaration + * @param {Function} fnc Function to exectute + * + * @returns {Number} Index of the job in the jobs array + */ + add(cron, fnc) { + return this.jobs.push(new Job(cron, fnc)) - 1; + } + + + /** + * @function remove + * Removes a job from being executed + * + * @param {Number} i Index of the job + * + * @returns {Object} The removed job object + */ + remove(i) { + return this.jobs.splice(i, 1)[0]; + } + + + /** + * @function start + * Start executing jobs + */ + start() { + if (!this.timer) { + this.timer = setInterval(() => { + console.log(); + this.process(); + }, this.interval); + } + } + + + /** + * @function stop + * Stop executing jobs + */ + stop() { + clearInterval(this.timer); + this.timer = null; + } + + +}; \ No newline at end of file diff --git a/system/cronjob/class.job.js b/system/cronjob/class.job.js new file mode 100644 index 0000000..1c33e25 --- /dev/null +++ b/system/cronjob/class.job.js @@ -0,0 +1,44 @@ +module.exports = class Job { + + constructor(cron, fnc) { + + // TODO (mstirner) fix eslint rule + // eslint-disable-next-line no-useless-escape + let parts = cron.match(/^([0-9,\-\/]+|\*{1}|\*{1}\/[0-9]+)\s+([0-9,\-\/]+|\*{1}|\*{1}\/[0-9]+)\s+([0-9,\-\/]+|\*{1}|\*{1}\/[0-9]+)\s+([0-9,\-\/]+|\*{1}|\*{1}\/[0-9]+)\s+([0-9,\-\/]+|\*{1}|\*{1}\/[0-9]+)\s*$/); + + this.minute = this.parse(parts[1]); + this.hour = this.parse(parts[2]); + this.date = this.parse(parts[3]); + this.month = this.parse(parts[4]); + this.day = this.parse(parts[5]); + + this.fnc = fnc; + + } + + parse(a) { + return a.split(",").map((i) => { + + let z = i.split("/"); + let x = z[0].split("-"); + + if (x[0] == "*") { + x[0] = -1; + } + + if (x.length == 1) { + x.push(x[0]); + } + + x[2] = z.length === 1 ? -1 : z[1]; + // parsed array structure: + x[0] = parseInt(x[0]); // 0 - from + x[1] = parseInt(x[1]); // 1 - to + x[2] = parseInt(x[2]); // 2 modulus + + return x; + + }); + } + +}; \ No newline at end of file diff --git a/system/cronjob/index.js b/system/cronjob/index.js new file mode 100644 index 0000000..30a1c59 --- /dev/null +++ b/system/cronjob/index.js @@ -0,0 +1,77 @@ +const Cron = require("./class.cron.js"); +const Job = require("./class.job.js"); + +/** + * @description + * This describes the component staff in the system folder.
+ * Every component depends on this classes and inherits all properties/methods. + * + * The `index.js` file is just a shortcut to the class files: + * + * + * @example + * ```js +const Cron = require("./class.cron.js"); +const Job = require("./class.job.js"); + +module.exports = { + Cron, + Job +}; + * ``` + */ +module.exports = { + Cron, + Job +}; + +/* +const cron = new Cron(); + +cron.add("* * * * *", () => { + console.log('cron job 1 just ran - every minute'); +}); + + +// *2 = *\/2 = \/ = / +cron.add("*2 * * * *", () => { + console.log('cron job 1.5 just ran - every 2 minute'); +}); + +cron.add("5 * * * *", () => { + console.log('cron job 2 just ran - every hour on minute 5') +}); + +cron.add("15 * * * *", () => { + console.log('cron job 3 just ran') +}); + +cron.add("30 * * * *", () => { + console.log('cron job 4 just ran') +}); + +cron.start(); + +// Cron already running, but we can add more jobs, no problem +cron.add("0 * * * *", () => { + console.log('cron job 5 just ran') +}); + +cron.add("7 9 * * 1,2,3,4,5", () => { + console.log('at 9:07 of every morning from sunday to thursday') +}); + + +let i = cron.add("* * * * *", () => { + console.log("Manuall created job: * * * * *") +}); + + +console.log(cron.jobs.length, i); + +setTimeout(() => { + console.log("Remove: Manuall created job"); + cron.remove(i); + cron.remove(0); +}, 1000 * 60 * 3); +*/ \ No newline at end of file From 80c5d3a6e7c03b38ee6263a71570c73ff413a242 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 4 Jun 2023 08:44:37 +0200 Subject: [PATCH 008/186] Removed useless `console.log` --- system/cronjob/class.cron.js | 1 - 1 file changed, 1 deletion(-) diff --git a/system/cronjob/class.cron.js b/system/cronjob/class.cron.js index c666a85..7834bcd 100644 --- a/system/cronjob/class.cron.js +++ b/system/cronjob/class.cron.js @@ -124,7 +124,6 @@ module.exports = class Cron { start() { if (!this.timer) { this.timer = setInterval(() => { - console.log(); this.process(); }, this.interval); } From 7d879ec8461320bacfbe0d08f3335ce69f471bc6 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 4 Jun 2023 08:44:58 +0200 Subject: [PATCH 009/186] var renamed --- adapter/eol.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adapter/eol.js b/adapter/eol.js index 429fee5..28c7d4f 100644 --- a/adapter/eol.js +++ b/adapter/eol.js @@ -8,7 +8,7 @@ module.exports = (options = {}) => { // https://github.com/OpenHausIO/backend/issues/315 let cr = Buffer.from("\r"); let lf = Buffer.from("\n"); - //let eol = Buffer.from("\x1A"); + //let eof = Buffer.from("\x1A"); let nl = Buffer.concat([ cr, lf From d821c8c147e5642a4d9d7905a8f02ed422f49a97 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 4 Jun 2023 08:46:59 +0200 Subject: [PATCH 010/186] Scene handling trigger implemented --- routes/router.api.webhooks.js | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/routes/router.api.webhooks.js b/routes/router.api.webhooks.js index a60171a..1c0681c 100644 --- a/routes/router.api.webhooks.js +++ b/routes/router.api.webhooks.js @@ -1,5 +1,5 @@ const C_WEBHOOKS = require("../components/webhooks"); - +const C_SCENES = require("../components/scenes"); module.exports = (app, router) => { @@ -27,9 +27,25 @@ module.exports = (app, router) => { router.all("/:_id/trigger", (req, res) => { - //res.end(`Hello from webhook: ${req.method}, ${JSON.stringify(req.item)}`); + let trigger = C_SCENES.items.map(({ triggers }) => { + return triggers; + }).flat().find(({ type, params }) => { + + let found = 1; + + found &= type === "webhook"; + found &= params?._id === req.params._id; + found &= req.item._handler.length === 0; + + return found; + + }); - req.item._trigger(req.body, req.query); + if (trigger) { + trigger.fire(); + } else { + req.item._trigger(req.body, req.query, req); + } res.status(202).end(); From 4bc85c8cd6f733439cf120b7e66a7e9d3d1654c9 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 4 Jun 2023 08:48:33 +0200 Subject: [PATCH 011/186] draft/commented added --- system/dispatcher.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/system/dispatcher.js b/system/dispatcher.js index 5a2ce93..b42be26 100644 --- a/system/dispatcher.js +++ b/system/dispatcher.js @@ -28,7 +28,21 @@ module.exports = function dispatch({ component, item, method, args }) { let C_COMPONENT = require(`../components/${component}`); return C_COMPONENT.get(item).then((item) => { - return Reflect.apply(item[method], item, args); + + let result = Reflect.apply(item[method], item, args); + + /* + // draft for component/scene + // "example" for trigger that allow to check when a scene is executed + this.emit(component, { + item, + method, + args + }); + */ + + return result; + }).catch((err) => { return Promise.reject(err); }); From ac9cc7a7b07178ce78a501665ab03f0d2a4f734b Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 4 Jun 2023 08:50:47 +0200 Subject: [PATCH 012/186] schema changed, `triggers` added --- components/scenes/index.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/scenes/index.js b/components/scenes/index.js index 06d5082..40b323d 100644 --- a/components/scenes/index.js +++ b/components/scenes/index.js @@ -7,6 +7,7 @@ const COMPONENT = require("../../system/component/class.component.js"); const Scene = require("./class.scene.js"); const Makro = require("./class.makro.js"); +const Trigger = require("./class.trigger.js"); /** * @description @@ -25,8 +26,8 @@ class C_SCENES extends COMPONENT { return String(new mongodb.ObjectId()); }), name: Joi.string().required(), - makros: Joi.array().items(Makro.schema()).default([]) - //triggers: Joi.array().items(Trigger.schema()).default([]) + makros: Joi.array().items(Makro.schema()).default([]), + triggers: Joi.array().items(Trigger.schema()).default([]) }, module); this.hooks.post("add", (data, next) => { From c1e3c97821c406002cddf5ed0bda292628e2bb69 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 4 Jun 2023 08:51:24 +0200 Subject: [PATCH 013/186] comments added --- routes/router.api.mdns.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/routes/router.api.mdns.js b/routes/router.api.mdns.js index a5895d3..60774b4 100644 --- a/routes/router.api.mdns.js +++ b/routes/router.api.mdns.js @@ -12,6 +12,17 @@ module.exports = (app, router) => { noServer: true }); + + /* + C_MDNS.events.on("query", (query) => { + wss.clients.forEach((client) => { + if (client.readyState === WebSocket.OPEN) { + client.send(query); + } + }); + }); + */ + // detect broken connections let interval = setInterval(() => { wss.clients.forEach((ws) => { @@ -36,6 +47,7 @@ module.exports = (app, router) => { // http route handler + // TODO: Reformat to match router.api.mdns.js code style/if-else router.get("/", (req, res, next) => { console.log("Request to /api/mdns"); From 450b5e1a0ac1a31215fe140ae653ef8aa7bc0a9b Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 4 Jun 2023 08:51:48 +0200 Subject: [PATCH 014/186] added --- components/scenes/class.trigger.js | 114 +++++++++++++++++++++++++++++ components/scenes/makro-types.js | 53 ++++++++++++++ components/scenes/trigger-types.js | 46 ++++++++++++ 3 files changed, 213 insertions(+) create mode 100644 components/scenes/class.trigger.js create mode 100644 components/scenes/makro-types.js create mode 100644 components/scenes/trigger-types.js diff --git a/components/scenes/class.trigger.js b/components/scenes/class.trigger.js new file mode 100644 index 0000000..109deae --- /dev/null +++ b/components/scenes/class.trigger.js @@ -0,0 +1,114 @@ +const { EventEmitter } = require("events"); + +const Joi = require("joi"); +const mongodb = require("mongodb"); + +const types = require("./trigger-types.js"); + +module.exports = class Trigger { + + /** + * @class Trigger + * + * @param {Object} obj Parameter object + * + * @property {EventEmitter} signal Event Emitter signal + * @property {Number|null} fired Last fired timestamp + * @property {Object} prams Parameter object + */ + constructor(obj) { + + //this.signal = new TriggerSignal(); + this.signal = new EventEmitter(); + this.fired = null; + + Object.assign(this, obj); + + if (types[obj.type]) { + types[obj.type](this, this.params); + } + + } + + + /** + * @function schema + * State schema, see properties above. + * + * @static + * + * @returns {Object} Joi Object + * + * @link https://joi.dev/api/?v=17.6.0#anyvalidatevalue-options + */ + static schema() { + return Joi.object({ + _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { + return String(new mongodb.ObjectId()); + }), + type: Joi.string().valid("cronjob", "webhook"/*, "state", "scene"*/).required(), + enabled: Joi.boolean().default(true), + //params: Joi.object().... + timestamps: Joi.object({ + created: Joi.number().allow(null), + updated: Joi.number().allow(null) + }) + }).when(".type", { + switch: [{ + is: "cronjob", + then: Joi.object({ + params: Joi.object({ + cron: Joi.string().pattern(/^((((\d+,)+\d+|(\d+(\/|-|#)\d+)|\d+L?|\*(\/\d+)?|L(-\d+)?|\?|[A-Z]{3}(-[A-Z]{3})?) ?){5,7})$/), + }) + }) + }, { + is: "webhook", + then: Joi.object({ + params: Joi.object({ + _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).required() + }) + }) + }/*,{ + is: "state", + then: Joi.object({ + params: Joi.object({ + _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).required(), + threshold: Joi.alternatives(Joi.number(), Joi.string(), Joi.boolean()).required(), + }) + }) + },{ + is: "scene", + then: Joi.object({ + params: Joi.object({ + _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).required() + }) + }) + }**/] + }); + } + + + /** + * @function validate + * Validate schema object + * + * @static + * + * @param {Object} obj Input data that matches the schema + * + * @returns {Object} Joi validation object + * + * @link https://joi.dev/api/?v=17.6.0#anyvalidatevalue-options + */ + static validate(obj) { + return Trigger.schema().validate(obj); + } + + fire() { + if (this.enabled) { + this.fired = Date.now(); + this.signal.emit("fire"); + } + } + +}; \ No newline at end of file diff --git a/components/scenes/makro-types.js b/components/scenes/makro-types.js new file mode 100644 index 0000000..1175eb9 --- /dev/null +++ b/components/scenes/makro-types.js @@ -0,0 +1,53 @@ +const dispatcher = require("../../system/dispatcher"); + +module.exports = { + + // TODO (mstirner) change to "sleep" instead! + "timer": ({ _id, value }, result, signal) => { + return new Promise((resolve) => { + + let timeout = setTimeout(() => { + resolve(_id, signal); + }, value); + + signal.addEventListener("abort", () => { + clearTimeout(timeout); + }, { + once: true + }); + + }); + }, + + "command": ({ endpoint, _id, command }) => { + return new Promise((resolve) => { + + // TODO (mstirner) replace dispatcher with eventbus + dispatcher({ + "component": "endpoints", + "item": endpoint, + "method": "trigger", + "args": [command] + }); + + resolve(_id); + + }); + }, + + "scene": ({ scene }) => { + return new Promise((resolve) => { + + dispatcher({ + "component": "scenes", + "item": scene, + "method": "trigger", + "args": [] + }); + + resolve(); + + }); + } + +}; \ No newline at end of file diff --git a/components/scenes/trigger-types.js b/components/scenes/trigger-types.js new file mode 100644 index 0000000..335f1fc --- /dev/null +++ b/components/scenes/trigger-types.js @@ -0,0 +1,46 @@ +const { Cron } = require("../../system/cronjob"); +const cron = new Cron(); + +module.exports = { + + "cronjob": (trigger, params) => { + cron.add(params.cron, () => { + trigger.fire(); + }); + }, + + /* + "state": (trigger, { params }) => { + // this should check for state changes of endpoints + // requires a "eventbus" and some additionl code in endpoints + // params.endpoint = endpoint object id + // params.state = endpoint state object id + // check if greater/lower than threshold or how to react? + } + */ + + /* + "webhook": (trigger, { param }) => { + // this waits for a http client to hit a webhook route + // the webhook itself should be "fire" some event + // we can listen to from the eventbus + // param.webhhok = mongodb _id + } + */ + + /* + "scene": (trigger, { param }) => { + // this waits for another scene to get executed + // check for dispatcher events? + // but this would only be executed when dispatcher is used + // how to check for all scenes? + // would be much easier with eventbus + dispatcher.on("scene", ({scene}) => { + if(scene === param._id){ + trigger.fire(); + } + }); + } + */ + +}; \ No newline at end of file From a96acca53e2bf443bed1084b17edb365ba90fd30 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 4 Jun 2023 08:53:48 +0200 Subject: [PATCH 015/186] changed --- components/scenes/class.makro.js | 13 ++++++++++++- components/scenes/class.scene.js | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/components/scenes/class.makro.js b/components/scenes/class.makro.js index 1e6ff54..b0b8689 100644 --- a/components/scenes/class.makro.js +++ b/components/scenes/class.makro.js @@ -1,8 +1,9 @@ const Joi = require("joi"); const mongodb = require("mongodb"); -const dispatcher = require("../../system/dispatcher"); +//const dispatcher = require("../../system/dispatcher"); //const C_ENDPOINTS = require("../endpoints"); +const types = require("./makro-types.js"); /** * @description @@ -44,6 +45,14 @@ module.exports = class Makro { * @returns */ execute(result, signal) { + + if (types[this.type]) { + return types[this.type](this, result, signal); + } else { + throw new Error(`Type ${this.type} handler not found`); + } + + /* return new Promise((resolve, reject) => { try { if (this.type === "timer") { @@ -89,6 +98,8 @@ module.exports = class Makro { } }); + */ + } diff --git a/components/scenes/class.scene.js b/components/scenes/class.scene.js index 25c708f..41f573c 100644 --- a/components/scenes/class.scene.js +++ b/components/scenes/class.scene.js @@ -1,6 +1,7 @@ const { setTimeout } = require("timers/promises"); const Makro = require("./class.makro.js"); +const Trigger = require("./class.trigger.js"); module.exports = class Scene { @@ -14,6 +15,18 @@ module.exports = class Scene { return new Makro(makro); }); + this.triggers = obj.triggers.map((data) => { + + let trigger = new Trigger(data); + + trigger.signal.on("fire", () => { + this.trigger(); + }); + + return trigger; + + }); + Object.defineProperty(this, "running", { value: false, enumerable: false, @@ -57,7 +70,12 @@ module.exports = class Scene { this._ac = ac; let init = this.makros.filter(({ + + // enabled is per default "true" + // when a marko should be disabled + // this has explicit to be set to false enabled = true + }) => { // execute only enabled makros From b97efbe813b34934207529dca6e72f6b56542c4c Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 4 Jun 2023 08:53:56 +0200 Subject: [PATCH 016/186] comments added --- system/cronjob/class.job.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/system/cronjob/class.job.js b/system/cronjob/class.job.js index 1c33e25..e7c9df3 100644 --- a/system/cronjob/class.job.js +++ b/system/cronjob/class.job.js @@ -1,3 +1,23 @@ +/** + * @description + * Job that represents a cronjob job.
+ * Note: Non-standard predefined scheduling definitions, like `@weekly`, are not supported! + * + * @class Job + * + * @param {String} cron String that reprentes when the job should be run + * @param {Function} fnc Callback function to execute, gets called when its time to run job + * + * @property {Array} minute + * @property {Array} hour + * @property {Array} date + * @property {Array} month + * @property {Array} day + * @property {Function} fnc Callback that gets called when its time to run job + * + * @link https://en.wikipedia.org/wiki/Cron#Overview + * @link https://crontab.guru/ + */ module.exports = class Job { constructor(cron, fnc) { @@ -16,6 +36,14 @@ module.exports = class Job { } + /** + * @function parse + * Parse a time expression + * + * @param {String} a + * + * @returns {Array} + */ parse(a) { return a.split(",").map((i) => { From 4d4dce41809a3d651d3c5fc04d00b6325da78736 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 4 Jun 2023 10:32:25 +0200 Subject: [PATCH 017/186] schema changed: added `visible` property --- components/scenes/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/scenes/index.js b/components/scenes/index.js index 40b323d..c54d314 100644 --- a/components/scenes/index.js +++ b/components/scenes/index.js @@ -27,7 +27,8 @@ class C_SCENES extends COMPONENT { }), name: Joi.string().required(), makros: Joi.array().items(Makro.schema()).default([]), - triggers: Joi.array().items(Trigger.schema()).default([]) + triggers: Joi.array().items(Trigger.schema()).default([]), + visible: Joi.boolean().default(true) }, module); this.hooks.post("add", (data, next) => { From 727717b3b4d7e698c3c24c1dd34c9cab54cc94c7 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 4 Jun 2023 10:55:59 +0200 Subject: [PATCH 018/186] unref `setInterval` --- system/cronjob/class.cron.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/system/cronjob/class.cron.js b/system/cronjob/class.cron.js index 7834bcd..9d7d1fd 100644 --- a/system/cronjob/class.cron.js +++ b/system/cronjob/class.cron.js @@ -123,9 +123,17 @@ module.exports = class Cron { */ start() { if (!this.timer) { + this.timer = setInterval(() => { this.process(); }, this.interval); + + // do not wait for the interl to exit node + // if this is not done, the unit tests never finish + // https://nodejs.org/api/timers.html#timers_timeout_unref + // https://bilaldurrani.com/post/2018/02/21/mocha-tests-hanging-with-timers/ + this.timer.unref(); + } } From 63605a1b202aecc60d0faef5cb34603039abe589 Mon Sep 17 00:00:00 2001 From: mStirner Date: Wed, 7 Jun 2023 22:11:34 +0200 Subject: [PATCH 019/186] fix #327 --- index.js | 50 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/index.js b/index.js index 2a8cc72..99c5158 100644 --- a/index.js +++ b/index.js @@ -7,6 +7,7 @@ const mongodb = require("mongodb"); const pkg = require("./package.json"); const { exec } = require("child_process"); const uuid = require("uuid"); +const { URL } = require("url"); const env = require("dotenv").config({ @@ -144,22 +145,32 @@ const init_db = () => { return new Promise((resolve, reject) => { logger.debug("Init Database..."); - let constr = process.env.DATABASE_URL; - if (!process.env.DATABASE_URL) { - constr = `mongodb://${process.env.DATABASE_HOST}:${process.env.DATABASE_PORT}/${process.env.DATABASE_NAME}`; + let url = new URL(`mongodb://${process.env.DATABASE_HOST}:${process.env.DATABASE_PORT}/${process.env.DATABASE_NAME}`); + + if (process.env.DATABASE_AUTH_USERNAME) { + url.username = process.env.DATABASE_AUTH_USERNAME; + } + + if (process.env.DATABASE_AUTH_USERNAME) { + url.password = process.env.DATABASE_AUTH_PASSWORD; + } + + if (process.env.DATABASE_URL) { + console.log("OVerride DATBAASE_URL"); + Object.assign(url, new URL(process.env.DATABASE_URL)); } // feedback - logger.verbose(`Connecting to "%s"...`, process.env.DATABASE_URL || constr); + logger.verbose(`Connecting to "%s"...`, url.toString()); - mongodb.MongoClient.connect(constr, { + mongodb.MongoClient.connect(url.toString(), { useUnifiedTopology: true, useNewUrlParser: true, //connectTimeoutMS: Number(process.env.DATABASE_TIMEOUT) * 1000, // #9 //socketTimeoutMS: Number(process.env.DATABASE_TIMEOUT) * 1000 // #9 - }, (err, client) => { + }, async (err, client) => { if (err) { logger.error(err, "Could not connect to database"); @@ -172,10 +183,6 @@ const init_db = () => { mongodb.connection = client; mongodb.client = client.db(); - // feedback - logger.info(`Connected to "%s"`, constr); - - resolve(); client.on("error", (err) => { logger.error(err, "Could not connecto to databse: %s", err.message); @@ -186,6 +193,29 @@ const init_db = () => { }); + try { + + // test authenticiation + // throws a error is auth is noc successfull + await mongodb.client.stats(); + + // feedback + logger.info(`Connected to "mongodb://${url.hostname}:${url.port}${url.pathname}"`); + + resolve(); + + } catch (err) { + + if (err?.code == 13) { + logger.error("Invalid database credentials!"); + } + + client.emit("error", err); + reject(err); + + } + + }); }); From e50417a713d1fbeff99eca577cdf8ab275db0731 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 14:27:35 +0000 Subject: [PATCH 020/186] Bump fast-xml-parser and @aws-sdk/credential-providers Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) and [@aws-sdk/credential-providers](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/credential-providers). These dependencies needed to be updated together. Updates `fast-xml-parser` from 4.0.11 to 4.2.4 - [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases) - [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md) - [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v4.0.11...v4.2.4) Updates `@aws-sdk/credential-providers` from 3.196.0 to 3.351.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/credential-providers/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.351.0/packages/credential-providers) --- updated-dependencies: - dependency-name: fast-xml-parser dependency-type: indirect - dependency-name: "@aws-sdk/credential-providers" dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 2393 +++++++++++++++++++++++++-------------------- 1 file changed, 1313 insertions(+), 1080 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7c675f4..647fa6d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "backend", - "version": "2.0.0", + "version": "2.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "backend", - "version": "2.0.0", + "version": "2.2.0", "hasInstallScript": true, "license": "ISC", "dependencies": { @@ -42,10 +42,27 @@ "node": ">=0.16.0" } }, + "node_modules/@aws-crypto/crc32": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", + "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", + "optional": true, + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/crc32/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "optional": true + }, "node_modules/@aws-crypto/ie11-detection": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-2.0.2.tgz", - "integrity": "sha512-5XDMQY98gMAf/WRTic5G++jfmS/VLM0rwpiOpaainKi4L0nqWMSB1SzsrEG5rjFZGYN6ZAefO+/Yta2dFM0kMw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", + "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==", "optional": true, "dependencies": { "tslib": "^1.11.1" @@ -58,16 +75,16 @@ "optional": true }, "node_modules/@aws-crypto/sha256-browser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-2.0.0.tgz", - "integrity": "sha512-rYXOQ8BFOaqMEHJrLHul/25ckWH6GTJtdLSajhlqGMx0PmSueAuvboCuZCTqEKlxR8CQOwRarxYMZZSYlhRA1A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz", + "integrity": "sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==", "optional": true, "dependencies": { - "@aws-crypto/ie11-detection": "^2.0.0", - "@aws-crypto/sha256-js": "^2.0.0", - "@aws-crypto/supports-web-crypto": "^2.0.0", - "@aws-crypto/util": "^2.0.0", - "@aws-sdk/types": "^3.1.0", + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/sha256-js": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-locate-window": "^3.0.0", "@aws-sdk/util-utf8-browser": "^3.0.0", "tslib": "^1.11.1" @@ -80,13 +97,13 @@ "optional": true }, "node_modules/@aws-crypto/sha256-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-2.0.0.tgz", - "integrity": "sha512-VZY+mCY4Nmrs5WGfitmNqXzaE873fcIZDu54cbaDaaamsaTOP1DBImV9F4pICc3EHjQXujyE8jig+PFCaew9ig==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz", + "integrity": "sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==", "optional": true, "dependencies": { - "@aws-crypto/util": "^2.0.0", - "@aws-sdk/types": "^3.1.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", "tslib": "^1.11.1" } }, @@ -97,9 +114,9 @@ "optional": true }, "node_modules/@aws-crypto/supports-web-crypto": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-2.0.2.tgz", - "integrity": "sha512-6mbSsLHwZ99CTOOswvCRP3C+VCWnzBf+1SnbWxzzJ9lR0mA0JnY2JEAhp8rqmTE0GPFy88rrM27ffgp62oErMQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz", + "integrity": "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==", "optional": true, "dependencies": { "tslib": "^1.11.1" @@ -112,12 +129,12 @@ "optional": true }, "node_modules/@aws-crypto/util": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-2.0.2.tgz", - "integrity": "sha512-Lgu5v/0e/BcrZ5m/IWqzPUf3UYFTy/PpeED+uc9SWUR1iZQL8XXbGQg10UfllwwBryO3hFF5dizK+78aoXC1eA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", + "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", "optional": true, "dependencies": { - "@aws-sdk/types": "^3.110.0", + "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-utf8-browser": "^3.0.0", "tslib": "^1.11.1" } @@ -129,467 +146,522 @@ "optional": true }, "node_modules/@aws-sdk/abort-controller": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.193.0.tgz", - "integrity": "sha512-MYPBm5PWyKP+Tq37mKs5wDbyAyVMocF5iYmx738LYXBSj8A1V4LTFrvfd4U16BRC/sM0DYB9fBFJUQ9ISFRVYw==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.347.0.tgz", + "integrity": "sha512-P/2qE6ntYEmYG4Ez535nJWZbXqgbkJx8CMz7ChEuEg3Gp3dvVYEKg+iEUEvlqQ2U5dWP5J3ehw5po9t86IsVPQ==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.196.0.tgz", - "integrity": "sha512-EwO3G3YPQuT1nkzaVByfoyV1Jyx1WVmbt3HH5nIQDP2bgKCPkq8mytiSS14H0VyejGHmc8/1wZ7Q/MRPosdgEg==", - "optional": true, - "dependencies": { - "@aws-crypto/sha256-browser": "2.0.0", - "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/client-sts": "3.196.0", - "@aws-sdk/config-resolver": "3.193.0", - "@aws-sdk/credential-provider-node": "3.196.0", - "@aws-sdk/fetch-http-handler": "3.193.0", - "@aws-sdk/hash-node": "3.193.0", - "@aws-sdk/invalid-dependency": "3.193.0", - "@aws-sdk/middleware-content-length": "3.193.0", - "@aws-sdk/middleware-endpoint": "3.193.0", - "@aws-sdk/middleware-host-header": "3.193.0", - "@aws-sdk/middleware-logger": "3.193.0", - "@aws-sdk/middleware-recursion-detection": "3.193.0", - "@aws-sdk/middleware-retry": "3.193.0", - "@aws-sdk/middleware-serde": "3.193.0", - "@aws-sdk/middleware-signing": "3.193.0", - "@aws-sdk/middleware-stack": "3.193.0", - "@aws-sdk/middleware-user-agent": "3.193.0", - "@aws-sdk/node-config-provider": "3.193.0", - "@aws-sdk/node-http-handler": "3.193.0", - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/smithy-client": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/url-parser": "3.193.0", - "@aws-sdk/util-base64-browser": "3.188.0", - "@aws-sdk/util-base64-node": "3.188.0", - "@aws-sdk/util-body-length-browser": "3.188.0", - "@aws-sdk/util-body-length-node": "3.188.0", - "@aws-sdk/util-defaults-mode-browser": "3.193.0", - "@aws-sdk/util-defaults-mode-node": "3.193.0", - "@aws-sdk/util-endpoints": "3.196.0", - "@aws-sdk/util-user-agent-browser": "3.193.0", - "@aws-sdk/util-user-agent-node": "3.193.0", - "@aws-sdk/util-utf8-browser": "3.188.0", - "@aws-sdk/util-utf8-node": "3.188.0", - "tslib": "^2.3.1" - }, - "engines": { - "node": ">=12.0.0" + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.350.0.tgz", + "integrity": "sha512-46AhBvGWo6TEzlvZieNlZHC2w4NJUJA52KfDUtgr8PmChGgxqzlLBAiOpqbDJ83GR3YB6CNEjXxzN5tmyJKICA==", + "optional": true, + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sts": "3.350.0", + "@aws-sdk/config-resolver": "3.347.0", + "@aws-sdk/credential-provider-node": "3.350.0", + "@aws-sdk/fetch-http-handler": "3.347.0", + "@aws-sdk/hash-node": "3.347.0", + "@aws-sdk/invalid-dependency": "3.347.0", + "@aws-sdk/middleware-content-length": "3.347.0", + "@aws-sdk/middleware-endpoint": "3.347.0", + "@aws-sdk/middleware-host-header": "3.347.0", + "@aws-sdk/middleware-logger": "3.347.0", + "@aws-sdk/middleware-recursion-detection": "3.347.0", + "@aws-sdk/middleware-retry": "3.347.0", + "@aws-sdk/middleware-serde": "3.347.0", + "@aws-sdk/middleware-signing": "3.347.0", + "@aws-sdk/middleware-stack": "3.347.0", + "@aws-sdk/middleware-user-agent": "3.347.0", + "@aws-sdk/node-config-provider": "3.347.0", + "@aws-sdk/node-http-handler": "3.350.0", + "@aws-sdk/smithy-client": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/url-parser": "3.347.0", + "@aws-sdk/util-base64": "3.310.0", + "@aws-sdk/util-body-length-browser": "3.310.0", + "@aws-sdk/util-body-length-node": "3.310.0", + "@aws-sdk/util-defaults-mode-browser": "3.347.0", + "@aws-sdk/util-defaults-mode-node": "3.347.0", + "@aws-sdk/util-endpoints": "3.347.0", + "@aws-sdk/util-retry": "3.347.0", + "@aws-sdk/util-user-agent-browser": "3.347.0", + "@aws-sdk/util-user-agent-node": "3.347.0", + "@aws-sdk/util-utf8": "3.310.0", + "@smithy/protocol-http": "^1.0.1", + "@smithy/types": "^1.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.196.0.tgz", - "integrity": "sha512-u+UnxrVHLjLDdfCZft1AuyIhyv+77/inCHR4LcKsGASRA+jAg3z+OY+B7Q9hWHNcVt5ECMw7rxe4jA9BLf42sw==", - "optional": true, - "dependencies": { - "@aws-crypto/sha256-browser": "2.0.0", - "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/config-resolver": "3.193.0", - "@aws-sdk/fetch-http-handler": "3.193.0", - "@aws-sdk/hash-node": "3.193.0", - "@aws-sdk/invalid-dependency": "3.193.0", - "@aws-sdk/middleware-content-length": "3.193.0", - "@aws-sdk/middleware-endpoint": "3.193.0", - "@aws-sdk/middleware-host-header": "3.193.0", - "@aws-sdk/middleware-logger": "3.193.0", - "@aws-sdk/middleware-recursion-detection": "3.193.0", - "@aws-sdk/middleware-retry": "3.193.0", - "@aws-sdk/middleware-serde": "3.193.0", - "@aws-sdk/middleware-stack": "3.193.0", - "@aws-sdk/middleware-user-agent": "3.193.0", - "@aws-sdk/node-config-provider": "3.193.0", - "@aws-sdk/node-http-handler": "3.193.0", - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/smithy-client": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/url-parser": "3.193.0", - "@aws-sdk/util-base64-browser": "3.188.0", - "@aws-sdk/util-base64-node": "3.188.0", - "@aws-sdk/util-body-length-browser": "3.188.0", - "@aws-sdk/util-body-length-node": "3.188.0", - "@aws-sdk/util-defaults-mode-browser": "3.193.0", - "@aws-sdk/util-defaults-mode-node": "3.193.0", - "@aws-sdk/util-endpoints": "3.196.0", - "@aws-sdk/util-user-agent-browser": "3.193.0", - "@aws-sdk/util-user-agent-node": "3.193.0", - "@aws-sdk/util-utf8-browser": "3.188.0", - "@aws-sdk/util-utf8-node": "3.188.0", - "tslib": "^2.3.1" - }, - "engines": { - "node": ">=12.0.0" + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.350.0.tgz", + "integrity": "sha512-2vpiv6SEjmQGK3ZueGzvTMG6NenjWp0CHjmda71d1Iqr+tZ2UlfC35+3ioU8JP+jiXLL+y9r+SCer3IC8N/i+Q==", + "optional": true, + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/config-resolver": "3.347.0", + "@aws-sdk/fetch-http-handler": "3.347.0", + "@aws-sdk/hash-node": "3.347.0", + "@aws-sdk/invalid-dependency": "3.347.0", + "@aws-sdk/middleware-content-length": "3.347.0", + "@aws-sdk/middleware-endpoint": "3.347.0", + "@aws-sdk/middleware-host-header": "3.347.0", + "@aws-sdk/middleware-logger": "3.347.0", + "@aws-sdk/middleware-recursion-detection": "3.347.0", + "@aws-sdk/middleware-retry": "3.347.0", + "@aws-sdk/middleware-serde": "3.347.0", + "@aws-sdk/middleware-stack": "3.347.0", + "@aws-sdk/middleware-user-agent": "3.347.0", + "@aws-sdk/node-config-provider": "3.347.0", + "@aws-sdk/node-http-handler": "3.350.0", + "@aws-sdk/smithy-client": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/url-parser": "3.347.0", + "@aws-sdk/util-base64": "3.310.0", + "@aws-sdk/util-body-length-browser": "3.310.0", + "@aws-sdk/util-body-length-node": "3.310.0", + "@aws-sdk/util-defaults-mode-browser": "3.347.0", + "@aws-sdk/util-defaults-mode-node": "3.347.0", + "@aws-sdk/util-endpoints": "3.347.0", + "@aws-sdk/util-retry": "3.347.0", + "@aws-sdk/util-user-agent-browser": "3.347.0", + "@aws-sdk/util-user-agent-node": "3.347.0", + "@aws-sdk/util-utf8": "3.310.0", + "@smithy/protocol-http": "^1.0.1", + "@smithy/types": "^1.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sso-oidc": { + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.350.0.tgz", + "integrity": "sha512-v3UrWIglg9PPzGXqhyGB/qPZ8ifiGM9r4LV8vve1TpiKsUdf1Khtx1eB8yqjNO0vIsYUF+j1C23QT1qAN2DcEA==", + "optional": true, + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/config-resolver": "3.347.0", + "@aws-sdk/fetch-http-handler": "3.347.0", + "@aws-sdk/hash-node": "3.347.0", + "@aws-sdk/invalid-dependency": "3.347.0", + "@aws-sdk/middleware-content-length": "3.347.0", + "@aws-sdk/middleware-endpoint": "3.347.0", + "@aws-sdk/middleware-host-header": "3.347.0", + "@aws-sdk/middleware-logger": "3.347.0", + "@aws-sdk/middleware-recursion-detection": "3.347.0", + "@aws-sdk/middleware-retry": "3.347.0", + "@aws-sdk/middleware-serde": "3.347.0", + "@aws-sdk/middleware-stack": "3.347.0", + "@aws-sdk/middleware-user-agent": "3.347.0", + "@aws-sdk/node-config-provider": "3.347.0", + "@aws-sdk/node-http-handler": "3.350.0", + "@aws-sdk/smithy-client": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/url-parser": "3.347.0", + "@aws-sdk/util-base64": "3.310.0", + "@aws-sdk/util-body-length-browser": "3.310.0", + "@aws-sdk/util-body-length-node": "3.310.0", + "@aws-sdk/util-defaults-mode-browser": "3.347.0", + "@aws-sdk/util-defaults-mode-node": "3.347.0", + "@aws-sdk/util-endpoints": "3.347.0", + "@aws-sdk/util-retry": "3.347.0", + "@aws-sdk/util-user-agent-browser": "3.347.0", + "@aws-sdk/util-user-agent-node": "3.347.0", + "@aws-sdk/util-utf8": "3.310.0", + "@smithy/protocol-http": "^1.0.1", + "@smithy/types": "^1.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.196.0.tgz", - "integrity": "sha512-ChzK8606CugwnRLm7iwerXzeMqOsjGLe3j1j1HtQShzXZu4/ysQ3mUBBPAt2Lltx+1ep8MoI9vaQVyfw5h35ww==", - "optional": true, - "dependencies": { - "@aws-crypto/sha256-browser": "2.0.0", - "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/config-resolver": "3.193.0", - "@aws-sdk/credential-provider-node": "3.196.0", - "@aws-sdk/fetch-http-handler": "3.193.0", - "@aws-sdk/hash-node": "3.193.0", - "@aws-sdk/invalid-dependency": "3.193.0", - "@aws-sdk/middleware-content-length": "3.193.0", - "@aws-sdk/middleware-endpoint": "3.193.0", - "@aws-sdk/middleware-host-header": "3.193.0", - "@aws-sdk/middleware-logger": "3.193.0", - "@aws-sdk/middleware-recursion-detection": "3.193.0", - "@aws-sdk/middleware-retry": "3.193.0", - "@aws-sdk/middleware-sdk-sts": "3.193.0", - "@aws-sdk/middleware-serde": "3.193.0", - "@aws-sdk/middleware-signing": "3.193.0", - "@aws-sdk/middleware-stack": "3.193.0", - "@aws-sdk/middleware-user-agent": "3.193.0", - "@aws-sdk/node-config-provider": "3.193.0", - "@aws-sdk/node-http-handler": "3.193.0", - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/smithy-client": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/url-parser": "3.193.0", - "@aws-sdk/util-base64-browser": "3.188.0", - "@aws-sdk/util-base64-node": "3.188.0", - "@aws-sdk/util-body-length-browser": "3.188.0", - "@aws-sdk/util-body-length-node": "3.188.0", - "@aws-sdk/util-defaults-mode-browser": "3.193.0", - "@aws-sdk/util-defaults-mode-node": "3.193.0", - "@aws-sdk/util-endpoints": "3.196.0", - "@aws-sdk/util-user-agent-browser": "3.193.0", - "@aws-sdk/util-user-agent-node": "3.193.0", - "@aws-sdk/util-utf8-browser": "3.188.0", - "@aws-sdk/util-utf8-node": "3.188.0", - "fast-xml-parser": "4.0.11", - "tslib": "^2.3.1" - }, - "engines": { - "node": ">=12.0.0" + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.350.0.tgz", + "integrity": "sha512-s8RsJ6upWQgeUt8GdV3j3ZeTS7BQXedk77RhZ7wzvVwAjO9wow4uS7Iyic4kS3Y/6d26s0MO2vP4bR6HW6U6ZQ==", + "optional": true, + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/config-resolver": "3.347.0", + "@aws-sdk/credential-provider-node": "3.350.0", + "@aws-sdk/fetch-http-handler": "3.347.0", + "@aws-sdk/hash-node": "3.347.0", + "@aws-sdk/invalid-dependency": "3.347.0", + "@aws-sdk/middleware-content-length": "3.347.0", + "@aws-sdk/middleware-endpoint": "3.347.0", + "@aws-sdk/middleware-host-header": "3.347.0", + "@aws-sdk/middleware-logger": "3.347.0", + "@aws-sdk/middleware-recursion-detection": "3.347.0", + "@aws-sdk/middleware-retry": "3.347.0", + "@aws-sdk/middleware-sdk-sts": "3.347.0", + "@aws-sdk/middleware-serde": "3.347.0", + "@aws-sdk/middleware-signing": "3.347.0", + "@aws-sdk/middleware-stack": "3.347.0", + "@aws-sdk/middleware-user-agent": "3.347.0", + "@aws-sdk/node-config-provider": "3.347.0", + "@aws-sdk/node-http-handler": "3.350.0", + "@aws-sdk/smithy-client": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/url-parser": "3.347.0", + "@aws-sdk/util-base64": "3.310.0", + "@aws-sdk/util-body-length-browser": "3.310.0", + "@aws-sdk/util-body-length-node": "3.310.0", + "@aws-sdk/util-defaults-mode-browser": "3.347.0", + "@aws-sdk/util-defaults-mode-node": "3.347.0", + "@aws-sdk/util-endpoints": "3.347.0", + "@aws-sdk/util-retry": "3.347.0", + "@aws-sdk/util-user-agent-browser": "3.347.0", + "@aws-sdk/util-user-agent-node": "3.347.0", + "@aws-sdk/util-utf8": "3.310.0", + "@smithy/protocol-http": "^1.0.1", + "@smithy/types": "^1.0.0", + "fast-xml-parser": "4.2.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/config-resolver": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.193.0.tgz", - "integrity": "sha512-HIjuv2A1glgkXy9g/A8bfsiz3jTFaRbwGZheoHFZod6iEQQEbbeAsBe3u2AZyzOrVLgs8lOvBtgU8XKSJWjDkw==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.347.0.tgz", + "integrity": "sha512-2ja+Sf/VnUO7IQ3nKbDQ5aumYKKJUaTm/BuVJ29wNho8wYHfuf7wHZV0pDTkB8RF5SH7IpHap7zpZAj39Iq+EA==", "optional": true, "dependencies": { - "@aws-sdk/signature-v4": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/util-config-provider": "3.188.0", - "@aws-sdk/util-middleware": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-config-provider": "3.310.0", + "@aws-sdk/util-middleware": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.196.0.tgz", - "integrity": "sha512-yXpb8kx1RpHRJty6MNX3ssTu0h3SYZVpUinQtBXPdHoVZ5/DyF/KGd2jr0LWYrgTx8G42GHTltz3Ss4nYjosnQ==", + "version": "3.351.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.351.0.tgz", + "integrity": "sha512-c9XyDUj82ttqQqF8h4Ie7k2Fl3bMh8/yBGEQWIPzWRhfy40m4ChqjilKAcBeoxR/w4Qp3RsdDfLRTLC8sJTpIg==", "optional": true, "dependencies": { - "@aws-sdk/client-cognito-identity": "3.196.0", - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/client-cognito-identity": "3.350.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.193.0.tgz", - "integrity": "sha512-pRqZoIaqCdWB4JJdR6DqDn3u+CwKJchwiCPnRtChwC8KXCMkT4njq9J1bWG3imYeTxP/G06O1PDONEuD4pPtNQ==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.347.0.tgz", + "integrity": "sha512-UnEM+LKGpXKzw/1WvYEQsC6Wj9PupYZdQOE+e2Dgy2dqk/pVFy4WueRtFXYDT2B41ppv3drdXUuKZRIDVqIgNQ==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-imds": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.193.0.tgz", - "integrity": "sha512-jC7uT7uVpO/iitz49toHMGFKXQ2igWQQG2SKirREqDRaz5HSXwEP1V3rcOlNNyGIBPMggDjZnxYgJHqBXSq9Ag==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.347.0.tgz", + "integrity": "sha512-7scCy/DCDRLIhlqTxff97LQWDnRwRXji3bxxMg+xWOTTaJe7PWx+etGSbBWaL42vsBHFShQjSLvJryEgoBktpw==", "optional": true, "dependencies": { - "@aws-sdk/node-config-provider": "3.193.0", - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/url-parser": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/node-config-provider": "3.347.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/url-parser": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.196.0.tgz", - "integrity": "sha512-3lL+YLBQ9KwQxG4AdRm4u2cvBNZeBmS/i3BWnCPomg96lNGPMrTEloVaVEpnrzOff6sgFxRtjkbLkVxmdipIrw==", - "optional": true, - "dependencies": { - "@aws-sdk/credential-provider-env": "3.193.0", - "@aws-sdk/credential-provider-imds": "3.193.0", - "@aws-sdk/credential-provider-sso": "3.196.0", - "@aws-sdk/credential-provider-web-identity": "3.193.0", - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/shared-ini-file-loader": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.350.0.tgz", + "integrity": "sha512-mGGU0PpnG0VDNKSuGi083U1egjprrU9/XoRtgf+iYvAKXRR/0XA4pGW5c7zpHY7m4iLhBuRj6N4oxQsH9cMtWg==", + "optional": true, + "dependencies": { + "@aws-sdk/credential-provider-env": "3.347.0", + "@aws-sdk/credential-provider-imds": "3.347.0", + "@aws-sdk/credential-provider-process": "3.347.0", + "@aws-sdk/credential-provider-sso": "3.350.0", + "@aws-sdk/credential-provider-web-identity": "3.347.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/shared-ini-file-loader": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.196.0.tgz", - "integrity": "sha512-PGY7pkmqgfEwTHsuUH6fGrXWri93jqKkMbhq/QJafMGtsVupfvXvE37Rl+qgjsZjRfROrEaeLw2DGrPPmVh2cg==", - "optional": true, - "dependencies": { - "@aws-sdk/credential-provider-env": "3.193.0", - "@aws-sdk/credential-provider-imds": "3.193.0", - "@aws-sdk/credential-provider-ini": "3.196.0", - "@aws-sdk/credential-provider-process": "3.193.0", - "@aws-sdk/credential-provider-sso": "3.196.0", - "@aws-sdk/credential-provider-web-identity": "3.193.0", - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/shared-ini-file-loader": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.350.0.tgz", + "integrity": "sha512-xmqwCFwj/CZPx6AKHNb24Kpr0eHW9VISt9r+SfgH8PaYg5cNyX1pKmMbQCket5ov+WvHEQtOK7aBafak7dhauA==", + "optional": true, + "dependencies": { + "@aws-sdk/credential-provider-env": "3.347.0", + "@aws-sdk/credential-provider-imds": "3.347.0", + "@aws-sdk/credential-provider-ini": "3.350.0", + "@aws-sdk/credential-provider-process": "3.347.0", + "@aws-sdk/credential-provider-sso": "3.350.0", + "@aws-sdk/credential-provider-web-identity": "3.347.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/shared-ini-file-loader": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.193.0.tgz", - "integrity": "sha512-zpXxtQzQqkaUuFqmHW9dSkh9p/1k+XNKlwEkG8FTwAJNUWmy2ZMJv+8NTVn4s4vaRu7xJ1er9chspYr7mvxHlA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.347.0.tgz", + "integrity": "sha512-yl1z4MsaBdXd4GQ2halIvYds23S67kElyOwz7g8kaQ4kHj+UoYWxz3JVW/DGusM6XmQ9/F67utBrUVA0uhQYyw==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/shared-ini-file-loader": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/shared-ini-file-loader": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.196.0.tgz", - "integrity": "sha512-hJV4LDVfvPfj5zC0ysHx3zkwwJOyF+BaMGaMzaScrHyijv5e3qZzdoBLbOQFmrqVnt7DjCU02NvRSS8amLpmSw==", + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.350.0.tgz", + "integrity": "sha512-u/3kv+PJeVawzBtWBei+IX1/z50mwhpPe3VrKSTns4CPUw8b5sqIYWkAaw5hxm0td69+xcL98RzIJsEpJc4QSQ==", "optional": true, "dependencies": { - "@aws-sdk/client-sso": "3.196.0", - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/shared-ini-file-loader": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/client-sso": "3.350.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/shared-ini-file-loader": "3.347.0", + "@aws-sdk/token-providers": "3.350.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.193.0.tgz", - "integrity": "sha512-MIQY9KwLCBnRyIt7an4EtMrFQZz2HC1E8vQDdKVzmeQBBePhW61fnX9XDP9bfc3Ypg1NggLG00KBPEC88twLFg==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.347.0.tgz", + "integrity": "sha512-DxoTlVK8lXjS1zVphtz/Ab+jkN/IZor9d6pP2GjJHNoAIIzXfRwwj5C8vr4eTayx/5VJ7GRP91J8GJ2cKly8Qw==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-providers": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.196.0.tgz", - "integrity": "sha512-IE2Lq0EMCkPqvh0on6Dfg5Nofcm2hbsDH8etQNKRpvZ/K8elz1aArh2gcL9F01smrJChAHWwD8uZbk/eQ/Zf2w==", - "optional": true, - "dependencies": { - "@aws-sdk/client-cognito-identity": "3.196.0", - "@aws-sdk/client-sso": "3.196.0", - "@aws-sdk/client-sts": "3.196.0", - "@aws-sdk/credential-provider-cognito-identity": "3.196.0", - "@aws-sdk/credential-provider-env": "3.193.0", - "@aws-sdk/credential-provider-imds": "3.193.0", - "@aws-sdk/credential-provider-ini": "3.196.0", - "@aws-sdk/credential-provider-node": "3.196.0", - "@aws-sdk/credential-provider-process": "3.193.0", - "@aws-sdk/credential-provider-sso": "3.196.0", - "@aws-sdk/credential-provider-web-identity": "3.193.0", - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/shared-ini-file-loader": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "version": "3.351.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.351.0.tgz", + "integrity": "sha512-KVfLTVpeDKnOPl0u5w3RJdNz+AtFIOj3dsfpyLkGCV5bHClLN05YFf1ajh93Z5FijuhvDSYuLT1Xr3Ud+AIudQ==", + "optional": true, + "dependencies": { + "@aws-sdk/client-cognito-identity": "3.350.0", + "@aws-sdk/client-sso": "3.350.0", + "@aws-sdk/client-sts": "3.350.0", + "@aws-sdk/credential-provider-cognito-identity": "3.351.0", + "@aws-sdk/credential-provider-env": "3.347.0", + "@aws-sdk/credential-provider-imds": "3.347.0", + "@aws-sdk/credential-provider-ini": "3.350.0", + "@aws-sdk/credential-provider-node": "3.350.0", + "@aws-sdk/credential-provider-process": "3.347.0", + "@aws-sdk/credential-provider-sso": "3.350.0", + "@aws-sdk/credential-provider-web-identity": "3.347.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/eventstream-codec": { + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-codec/-/eventstream-codec-3.347.0.tgz", + "integrity": "sha512-61q+SyspjsaQ4sdgjizMyRgVph2CiW4aAtfpoH69EJFJfTxTR/OqnZ9Jx/3YiYi0ksrvDenJddYodfWWJqD8/w==", + "optional": true, + "dependencies": { + "@aws-crypto/crc32": "3.0.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-hex-encoding": "3.310.0", + "tslib": "^2.5.0" } }, "node_modules/@aws-sdk/fetch-http-handler": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.193.0.tgz", - "integrity": "sha512-UhIS2LtCK9hqBzYVon6BI8WebJW1KC0GGIL/Gse5bqzU9iAGgFLAe66qg9k+/h3Jjc5LNAYzqXNVizMwn7689Q==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.347.0.tgz", + "integrity": "sha512-sQ5P7ivY8//7wdxfA76LT1sF6V2Tyyz1qF6xXf9sihPN5Q1Y65c+SKpMzXyFSPqWZ82+SQQuDliYZouVyS6kQQ==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/querystring-builder": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/util-base64-browser": "3.188.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.347.0", + "@aws-sdk/querystring-builder": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-base64": "3.310.0", + "tslib": "^2.5.0" } }, "node_modules/@aws-sdk/hash-node": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.193.0.tgz", - "integrity": "sha512-O2SLPVBjrCUo+4ouAdRUoHBYsyurO9LcjNZNYD7YQOotBTbVFA3cx7kTZu+K4B6kX7FDaGbqbE1C/T1/eg/r+w==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.347.0.tgz", + "integrity": "sha512-96+ml/4EaUaVpzBdOLGOxdoXOjkPgkoJp/0i1fxOJEvl8wdAQSwc3IugVK9wZkCxy2DlENtgOe6DfIOhfffm/g==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.193.0", - "@aws-sdk/util-buffer-from": "3.188.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-buffer-from": "3.310.0", + "@aws-sdk/util-utf8": "3.310.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/invalid-dependency": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.193.0.tgz", - "integrity": "sha512-54DCknekLwJAI1os76XJ8XCzfAH7BGkBGtlWk5WCNkZTfj3rf5RUiXz4uoKUMWE1rZmyMDoDDS1PBo+yTVKW5w==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.347.0.tgz", + "integrity": "sha512-8imQcwLwqZ/wTJXZqzXT9pGLIksTRckhGLZaXT60tiBOPKuerTsus2L59UstLs5LP8TKaVZKFFSsjRIn9dQdmQ==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "node_modules/@aws-sdk/is-array-buffer": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.188.0.tgz", - "integrity": "sha512-n69N4zJZCNd87Rf4NzufPzhactUeM877Y0Tp/F3KiHqGeTnVjYUa4Lv1vLBjqtfjYb2HWT3NKlYn5yzrhaEwiQ==", + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.310.0.tgz", + "integrity": "sha512-urnbcCR+h9NWUnmOtet/s4ghvzsidFmspfhYaHAmSRdy9yDjdjBJMFjjsn85A1ODUktztm+cVncXjQ38WCMjMQ==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-content-length": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.193.0.tgz", - "integrity": "sha512-em0Sqo7O7DFOcVXU460pbcYuIjblDTZqK2YE62nQ0T+5Nbj+MSjuoite+rRRdRww9VqBkUROGKON45bUNjogtQ==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.347.0.tgz", + "integrity": "sha512-i4qtWTDImMaDUtwKQPbaZpXsReiwiBomM1cWymCU4bhz81HL01oIxOxOBuiM+3NlDoCSPr3KI6txZSz/8cqXCQ==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-endpoint": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.193.0.tgz", - "integrity": "sha512-Inbpt7jcHGvzF7UOJOCxx9wih0+eAQYERikokidWJa7M405EJpVYq1mGbeOcQUPANU3uWF1AObmUUFhbkriHQw==", - "optional": true, - "dependencies": { - "@aws-sdk/middleware-serde": "3.193.0", - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/signature-v4": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/url-parser": "3.193.0", - "@aws-sdk/util-config-provider": "3.188.0", - "@aws-sdk/util-middleware": "3.193.0", - "tslib": "^2.3.1" + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.347.0.tgz", + "integrity": "sha512-unF0c6dMaUL1ffU+37Ugty43DgMnzPWXr/Jup/8GbK5fzzWT5NQq6dj9KHPubMbWeEjQbmczvhv25JuJdK8gNQ==", + "optional": true, + "dependencies": { + "@aws-sdk/middleware-serde": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/url-parser": "3.347.0", + "@aws-sdk/util-middleware": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.193.0.tgz", - "integrity": "sha512-aegzj5oRWd//lmfmkzRmgG2b4l3140v8Ey4QkqCxcowvAEX5a7rh23yuKaGtmiePwv2RQalCKz+tN6JXCm8g6Q==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.347.0.tgz", + "integrity": "sha512-kpKmR9OvMlnReqp5sKcJkozbj1wmlblbVSbnQAIkzeQj2xD5dnVR3Nn2ogQKxSmU1Fv7dEroBtrruJ1o3fY38A==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.193.0.tgz", - "integrity": "sha512-D/h1pU5tAcyJpJ8ZeD1Sta0S9QZPcxERYRBiJdEl8VUrYwfy3Cl1WJedVOmd5nG73ZLRSyHeXHewb/ohge3yKQ==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.347.0.tgz", + "integrity": "sha512-NYC+Id5UCkVn+3P1t/YtmHt75uED06vwaKyxDy0UmB2K66PZLVtwWbLpVWrhbroaw1bvUHYcRyQ9NIfnVcXQjA==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.193.0.tgz", - "integrity": "sha512-fMWP76Q1GOb/9OzS1arizm6Dbfo02DPZ6xp7OoAN3PS6ybH3Eb47s/gP3jzgBPAITQacFj4St/4a06YWYrN3NA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.347.0.tgz", + "integrity": "sha512-qfnSvkFKCAMjMHR31NdsT0gv5Sq/ZHTUD4yQsSLpbVQ6iYAS834lrzXt41iyEHt57Y514uG7F/Xfvude3u4icQ==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-retry": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.193.0.tgz", - "integrity": "sha512-zTQkHLBQBJi6ns655WYcYLyLPc1tgbEYU080Oc8zlveLUqoDn1ogkcmNhG7XMeQuBvWZBYN7J3/wFaXlDzeCKg==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.347.0.tgz", + "integrity": "sha512-CpdM+8dCSbX96agy4FCzOfzDmhNnGBM/pxrgIVLm5nkYTLuXp/d7ubpFEUHULr+4hCd5wakHotMt7yO29NFaVw==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/service-error-classification": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/util-middleware": "3.193.0", - "tslib": "^2.3.1", + "@aws-sdk/protocol-http": "3.347.0", + "@aws-sdk/service-error-classification": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-middleware": "3.347.0", + "@aws-sdk/util-retry": "3.347.0", + "tslib": "^2.5.0", "uuid": "^8.3.2" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-retry/node_modules/uuid": { @@ -602,419 +674,442 @@ } }, "node_modules/@aws-sdk/middleware-sdk-sts": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.193.0.tgz", - "integrity": "sha512-TafiDkeflUsnbNa89TLkDnAiRRp1gAaZLDAjt75AzriRKZnhtFfYUXWb+qAuN50T+CkJ/gZI9LHDZL5ogz/HxQ==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.347.0.tgz", + "integrity": "sha512-38LJ0bkIoVF3W97x6Jyyou72YV9Cfbml4OaDEdnrCOo0EssNZM5d7RhjMvQDwww7/3OBY/BzeOcZKfJlkYUXGw==", "optional": true, "dependencies": { - "@aws-sdk/middleware-signing": "3.193.0", - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/signature-v4": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/middleware-signing": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-serde": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.193.0.tgz", - "integrity": "sha512-dH93EJYVztY+ZDPzSMRi9LfAZfKO+luH62raNy49hlNa4jiyE1Tc/+qwlmOEpfGsrtcZ9TgsON1uFF9sgBXXaA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.347.0.tgz", + "integrity": "sha512-x5Foi7jRbVJXDu9bHfyCbhYDH5pKK+31MmsSJ3k8rY8keXLBxm2XEEg/AIoV9/TUF9EeVvZ7F1/RmMpJnWQsEg==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-signing": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.193.0.tgz", - "integrity": "sha512-obBoELGPf5ikvHYZwbzllLeuODiokdDfe92Ve2ufeOa/d8+xsmbqNzNdCTLNNTmr1tEIaEE7ngZVTOiHqAVhyw==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.347.0.tgz", + "integrity": "sha512-zVBF/4MGKnvhAE/J+oAL/VAehiyv+trs2dqSQXwHou9j8eA8Vm8HS2NdOwpkZQchIxTuwFlqSusDuPEdYFbvGw==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/signature-v4": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/util-middleware": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/protocol-http": "3.347.0", + "@aws-sdk/signature-v4": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-middleware": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-stack": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.193.0.tgz", - "integrity": "sha512-Ix5d7gE6bZwFNIVf0dGnjYuymz1gjitNoAZDPpv1nEZlUMek/jcno5lmzWFzUZXY/azpbIyaPwq/wm/c69au5A==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.347.0.tgz", + "integrity": "sha512-Izidg4rqtYMcKuvn2UzgEpPLSmyd8ub9+LQ2oIzG3mpIzCBITq7wp40jN1iNkMg+X6KEnX9vdMJIYZsPYMCYuQ==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.193.0.tgz", - "integrity": "sha512-0vT6F9NwYQK7ARUUJeHTUIUPnupsO3IbmjHSi1+clkssFlJm2UfmSGeafiWe4AYH3anATTvZEtcxX5DZT/ExbA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.347.0.tgz", + "integrity": "sha512-wJbGN3OE1/daVCrwk49whhIr9E0j1N4gWwN/wi4WuyYIA+5lMUfVp0aGIOvZR+878DxuFz2hQ4XcZVT4K2WvQw==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-endpoints": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/node-config-provider": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.193.0.tgz", - "integrity": "sha512-5RLdjQLH69ISRG8TX9klSLOpEySXxj+z9E9Em39HRvw0/rDcd8poCTADvjYIOqRVvMka0z/hm+elvUTIVn/DRw==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.347.0.tgz", + "integrity": "sha512-faU93d3+5uTTUcotGgMXF+sJVFjrKh+ufW+CzYKT4yUHammyaIab/IbTPWy2hIolcEGtuPeVoxXw8TXbkh/tuw==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/shared-ini-file-loader": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/shared-ini-file-loader": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/node-http-handler": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.193.0.tgz", - "integrity": "sha512-DP4BmFw64HOShgpAPEEMZedVnRmKKjHOwMEoXcnNlAkMXnYUFHiKvudYq87Q2AnSlT6OHkyMviB61gEvIk73dA==", + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.350.0.tgz", + "integrity": "sha512-oD96GAlmpzYilCdC8wwyURM5lNfNHZCjm/kxBkQulHKa2kRbIrnD9GfDqdCkWA5cTpjh1NzGLT4D6e6UFDjt9w==", "optional": true, "dependencies": { - "@aws-sdk/abort-controller": "3.193.0", - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/querystring-builder": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/abort-controller": "3.347.0", + "@aws-sdk/protocol-http": "3.347.0", + "@aws-sdk/querystring-builder": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/property-provider": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.193.0.tgz", - "integrity": "sha512-IaDR/PdZjKlAeSq2E/6u6nkPsZF9wvhHZckwH7uumq4ocWsWXFzaT+hKpV4YZPHx9n+K2YV4Gn/bDedpz99W1Q==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.347.0.tgz", + "integrity": "sha512-t3nJ8CYPLKAF2v9nIHOHOlF0CviQbTvbFc2L4a+A+EVd/rM4PzL3+3n8ZJsr0h7f6uD04+b5YRFgKgnaqLXlEg==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/protocol-http": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.193.0.tgz", - "integrity": "sha512-r0wbTwFJyXq0uiImI6giqG3g/RO1N/y4wwPA7qr7OC+KXJ0NkyVxIf6e7Vx8h06aM1ATtngbwJaMP59kVCp85A==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.347.0.tgz", + "integrity": "sha512-2YdBhc02Wvy03YjhGwUxF0UQgrPWEy8Iq75pfS42N+/0B/+eWX1aQgfjFxIpLg7YSjT5eKtYOQGlYd4MFTgj9g==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/querystring-builder": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.193.0.tgz", - "integrity": "sha512-PRaK6649iw0UO45UjUoiUzFcOKXZb8pMjjFJpqALpEvdZT3twxqhlPXujT7GWPKrSwO4uPLNnyYEtPY82wx2vw==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.347.0.tgz", + "integrity": "sha512-phtKTe6FXoV02MoPkIVV6owXI8Mwr5IBN3bPoxhcPvJG2AjEmnetSIrhb8kwc4oNhlwfZwH6Jo5ARW/VEWbZtg==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.193.0", - "@aws-sdk/util-uri-escape": "3.188.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-uri-escape": "3.310.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/querystring-parser": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.193.0.tgz", - "integrity": "sha512-dGEPCe8SK4/td5dSpiaEI3SvT5eHXrbJWbLGyD4FL3n7WCGMy2xVWAB/yrgzD0GdLDjDa8L5vLVz6yT1P9i+hA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.347.0.tgz", + "integrity": "sha512-5VXOhfZz78T2W7SuXf2avfjKglx1VZgZgp9Zfhrt/Rq+MTu2D+PZc5zmJHhYigD7x83jLSLogpuInQpFMA9LgA==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/service-error-classification": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.193.0.tgz", - "integrity": "sha512-bPnXVu8ErE1RfWVVQKc2TE7EuoImUi4dSPW9g80fGRzJdQNwXb636C+7OUuWvSDzmFwuBYqZza8GZjVd+rz2zQ==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.347.0.tgz", + "integrity": "sha512-xZ3MqSY81Oy2gh5g0fCtooAbahqh9VhsF8vcKjVX8+XPbGC8y+kej82+MsMg4gYL8gRFB9u4hgYbNgIS6JTAvg==", "optional": true, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/shared-ini-file-loader": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.193.0.tgz", - "integrity": "sha512-hnvZup8RSpFXfah7Rrn6+lQJnAOCO+OiDJ2R/iMgZQh475GRQpLbu3cPhCOkjB14vVLygJtW8trK/0+zKq93bQ==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.347.0.tgz", + "integrity": "sha512-Xw+zAZQVLb+xMNHChXQ29tzzLqm3AEHsD8JJnlkeFjeMnWQtXdUfOARl5s8NzAppcKQNlVe2gPzjaKjoy2jz1Q==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/signature-v4": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.193.0.tgz", - "integrity": "sha512-JEqqOB8wQZz6g1ERNUOIBFDFt8OJtz5G5Uh1CdkS5W66gyWnJEz/dE1hA2VTqqQwHGGEsIEV/hlzruU1lXsvFA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.347.0.tgz", + "integrity": "sha512-58Uq1do+VsTHYkP11dTK+DF53fguoNNJL9rHRWhzP+OcYv3/mBMLoS2WPz/x9FO5mBg4ESFsug0I6mXbd36tjw==", "optional": true, "dependencies": { - "@aws-sdk/is-array-buffer": "3.188.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/util-hex-encoding": "3.188.0", - "@aws-sdk/util-middleware": "3.193.0", - "@aws-sdk/util-uri-escape": "3.188.0", - "tslib": "^2.3.1" + "@aws-sdk/eventstream-codec": "3.347.0", + "@aws-sdk/is-array-buffer": "3.310.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-hex-encoding": "3.310.0", + "@aws-sdk/util-middleware": "3.347.0", + "@aws-sdk/util-uri-escape": "3.310.0", + "@aws-sdk/util-utf8": "3.310.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/smithy-client": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.193.0.tgz", - "integrity": "sha512-BY0jhfW76vyXr7ODMaKO3eyS98RSrZgOMl6DTQV9sk7eFP/MPVlG7p7nfX/CDIgPBIO1z0A0i2CVIzYur9uGgQ==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.347.0.tgz", + "integrity": "sha512-PaGTDsJLGK0sTjA6YdYQzILRlPRN3uVFyqeBUkfltXssvUzkm8z2t1lz2H4VyJLAhwnG5ZuZTNEV/2mcWrU7JQ==", "optional": true, "dependencies": { - "@aws-sdk/middleware-stack": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/middleware-stack": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/types": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.193.0.tgz", - "integrity": "sha512-LV/wcPolRZKORrcHwkH59QMCkiDR5sM+9ZtuTxvyUGG2QFW/kjoxs08fUF10OWNJMrotBI+czDc5QJRgN8BlAw==", + "node_modules/@aws-sdk/token-providers": { + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.350.0.tgz", + "integrity": "sha512-VIfVMV5An1VQQ6bOKQTHPsRFHD3/YRGOPk9lDTVJGOK0G1DIFYd/10ZaLQ86rCWLck2lGhjxsOen2N2n6MtA0A==", "optional": true, + "dependencies": { + "@aws-sdk/client-sso-oidc": "3.350.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/shared-ini-file-loader": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" + }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/url-parser": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.193.0.tgz", - "integrity": "sha512-hwD1koJlOu2a6GvaSbNbdo7I6a3tmrsNTZr8bCjAcbqpc5pDThcpnl/Uaz3zHmMPs92U8I6BvWoK6pH8By06qw==", + "node_modules/@aws-sdk/types": { + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.347.0.tgz", + "integrity": "sha512-GkCMy79mdjU9OTIe5KT58fI/6uqdf8UmMdWqVHmFJ+UpEzOci7L/uw4sOXWo7xpPzLs6cJ7s5ouGZW4GRPmHFA==", "optional": true, "dependencies": { - "@aws-sdk/querystring-parser": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-base64-browser": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-browser/-/util-base64-browser-3.188.0.tgz", - "integrity": "sha512-qlH+5NZBLiyKziL335BEPedYxX6j+p7KFRWXvDQox9S+s+gLCayednpK+fteOhBenCcR9fUZOVuAPScy1I8qCg==", + "node_modules/@aws-sdk/url-parser": { + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.347.0.tgz", + "integrity": "sha512-lhrnVjxdV7hl+yCnJfDZOaVLSqKjxN20MIOiijRiqaWGLGEAiSqBreMhL89X1WKCifxAs4zZf9YB9SbdziRpAA==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "@aws-sdk/querystring-parser": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, - "node_modules/@aws-sdk/util-base64-node": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-node/-/util-base64-node-3.188.0.tgz", - "integrity": "sha512-r1dccRsRjKq+OhVRUfqFiW3sGgZBjHbMeHLbrAs9jrOjU2PTQ8PSzAXLvX/9lmp7YjmX17Qvlsg0NCr1tbB9OA==", + "node_modules/@aws-sdk/util-base64": { + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64/-/util-base64-3.310.0.tgz", + "integrity": "sha512-v3+HBKQvqgdzcbL+pFswlx5HQsd9L6ZTlyPVL2LS9nNXnCcR3XgGz9jRskikRUuUvUXtkSG1J88GAOnJ/apTPg==", "optional": true, "dependencies": { - "@aws-sdk/util-buffer-from": "3.188.0", - "tslib": "^2.3.1" + "@aws-sdk/util-buffer-from": "3.310.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-body-length-browser": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.188.0.tgz", - "integrity": "sha512-8VpnwFWXhnZ/iRSl9mTf+VKOX9wDE8QtN4bj9pBfxwf90H1X7E8T6NkiZD3k+HubYf2J94e7DbeHs7fuCPW5Qg==", + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.310.0.tgz", + "integrity": "sha512-sxsC3lPBGfpHtNTUoGXMQXLwjmR0zVpx0rSvzTPAuoVILVsp5AU/w5FphNPxD5OVIjNbZv9KsKTuvNTiZjDp9g==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "node_modules/@aws-sdk/util-body-length-node": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.188.0.tgz", - "integrity": "sha512-XwqP3vxk60MKp4YDdvDeCD6BPOiG2e+/Ou4AofZOy5/toB6NKz2pFNibQIUg2+jc7mPMnGnvOW3MQEgSJ+gu/Q==", + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.310.0.tgz", + "integrity": "sha512-2tqGXdyKhyA6w4zz7UPoS8Ip+7sayOg9BwHNidiGm2ikbDxm1YrCfYXvCBdwaJxa4hJfRVz+aL9e+d3GqPI9pQ==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-buffer-from": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.188.0.tgz", - "integrity": "sha512-NX1WXZ8TH20IZb4jPFT2CnLKSqZWddGxtfiWxD9M47YOtq/SSQeR82fhqqVjJn4P8w2F5E28f+Du4ntg/sGcxA==", + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.310.0.tgz", + "integrity": "sha512-i6LVeXFtGih5Zs8enLrt+ExXY92QV25jtEnTKHsmlFqFAuL3VBeod6boeMXkN2p9lbSVVQ1sAOOYZOHYbYkntw==", "optional": true, "dependencies": { - "@aws-sdk/is-array-buffer": "3.188.0", - "tslib": "^2.3.1" + "@aws-sdk/is-array-buffer": "3.310.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-config-provider": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.188.0.tgz", - "integrity": "sha512-LBA7tLbi7v4uvbOJhSnjJrxbcRifKK/1ZVK94JTV2MNSCCyNkFotyEI5UWDl10YKriTIUyf7o5cakpiDZ3O4xg==", + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.310.0.tgz", + "integrity": "sha512-xIBaYo8dwiojCw8vnUcIL4Z5tyfb1v3yjqyJKJWV/dqKUFOOS0U591plmXbM+M/QkXyML3ypon1f8+BoaDExrg==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-defaults-mode-browser": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.193.0.tgz", - "integrity": "sha512-9riQKFrSJcsNAMnPA/3ltpSxNykeO20klE/UKjxEoD7UWjxLwsPK22UJjFwMRaHoAFcZD0LU/SgPxbC0ktCYCg==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.347.0.tgz", + "integrity": "sha512-+JHFA4reWnW/nMWwrLKqL2Lm/biw/Dzi/Ix54DAkRZ08C462jMKVnUlzAI+TfxQE3YLm99EIa0G7jiEA+p81Qw==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/types": "3.193.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/types": "3.347.0", "bowser": "^2.11.0", - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { "node": ">= 10.0.0" } }, "node_modules/@aws-sdk/util-defaults-mode-node": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.193.0.tgz", - "integrity": "sha512-occQmckvPRiM4YQIZnulfKKKjykGKWloa5ByGC5gOEGlyeP9zJpfs4zc/M2kArTAt+d2r3wkBtsKe5yKSlVEhA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.347.0.tgz", + "integrity": "sha512-A8BzIVhAAZE5WEukoAN2kYebzTc99ZgncbwOmgCCbvdaYlk5tzguR/s+uoT4G0JgQGol/4hAMuJEl7elNgU6RQ==", "optional": true, "dependencies": { - "@aws-sdk/config-resolver": "3.193.0", - "@aws-sdk/credential-provider-imds": "3.193.0", - "@aws-sdk/node-config-provider": "3.193.0", - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/config-resolver": "3.347.0", + "@aws-sdk/credential-provider-imds": "3.347.0", + "@aws-sdk/node-config-provider": "3.347.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { "node": ">= 10.0.0" } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.196.0.tgz", - "integrity": "sha512-X+DOpRUy/ij49a0GQtggk09oyIQGn0mhER6PbMT69IufZPIg3D5fC5FPEp8bfsPkb70fTEYQEsj/X/rgMQJKsA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.347.0.tgz", + "integrity": "sha512-/WUkirizeNAqwVj0zkcrqdQ9pUm1HY5kU+qy7xTR0OebkuJauglkmSTMD+56L1JPunWqHhlwCMVRaz5eaJdSEQ==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-hex-encoding": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.188.0.tgz", - "integrity": "sha512-QyWovTtjQ2RYxqVM+STPh65owSqzuXURnfoof778spyX4iQ4z46wOge1YV2ZtwS8w5LWd9eeVvDrLu5POPYOnA==", + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.310.0.tgz", + "integrity": "sha512-sVN7mcCCDSJ67pI1ZMtk84SKGqyix6/0A1Ab163YKn+lFBQRMKexleZzpYzNGxYzmQS6VanP/cfU7NiLQOaSfA==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-locate-window": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.188.0.tgz", - "integrity": "sha512-SxobBVLZkkLSawTCfeQnhVX3Azm9O+C2dngZVe1+BqtF8+retUbVTs7OfYeWBlawVkULKF2e781lTzEHBBjCzw==", + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz", + "integrity": "sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-middleware": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.193.0.tgz", - "integrity": "sha512-+aC6pmkcGgpxaMWCH/FXTsGWl2W342oQGs1OYKGi+W8z9UguXrqamWjdkdMqgunvj9qOEG2KBMKz1FWFFZlUyA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.347.0.tgz", + "integrity": "sha512-8owqUA3ePufeYTUvlzdJ7Z0miLorTwx+rNol5lourGQZ9JXsVMo23+yGA7nOlFuXSGkoKpMOtn6S0BT2bcfeiw==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-retry": { + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-retry/-/util-retry-3.347.0.tgz", + "integrity": "sha512-NxnQA0/FHFxriQAeEgBonA43Q9/VPFQa8cfJDuT2A1YZruMasgjcltoZszi1dvoIRWSZsFTW42eY2gdOd0nffQ==", + "optional": true, + "dependencies": { + "@aws-sdk/service-error-classification": "3.347.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">= 14.0.0" } }, "node_modules/@aws-sdk/util-uri-escape": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.188.0.tgz", - "integrity": "sha512-4Y6AYZMT483Tiuq8dxz5WHIiPNdSFPGrl6tRTo2Oi2FcwypwmFhqgEGcqxeXDUJktvaCBxeA08DLr/AemVhPCg==", + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.310.0.tgz", + "integrity": "sha512-drzt+aB2qo2LgtDoiy/3sVG8w63cgLkqFIa2NFlGpUgHFWTXkqtbgf4L5QdjRGKWhmZsnqkbtL7vkSWEcYDJ4Q==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.193.0.tgz", - "integrity": "sha512-1EkGYsUtOMEyJG/UBIR4PtmO3lVjKNoUImoMpLtEucoGbWz5RG9zFSwLevjFyFs5roUBFlxkSpTMo8xQ3aRzQg==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.347.0.tgz", + "integrity": "sha512-ydxtsKVtQefgbk1Dku1q7pMkjDYThauG9/8mQkZUAVik55OUZw71Zzr3XO8J8RKvQG8lmhPXuAQ0FKAyycc0RA==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.193.0", + "@aws-sdk/types": "3.347.0", "bowser": "^2.11.0", - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.193.0.tgz", - "integrity": "sha512-G/2/1cSgsxVtREAm8Eq8Duib5PXzXknFRHuDpAxJ5++lsJMXoYMReS278KgV54cojOkAVfcODDTqmY3Av0WHhQ==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.347.0.tgz", + "integrity": "sha512-6X0b9qGsbD1s80PmbaB6v1/ZtLfSx6fjRX8caM7NN0y/ObuLoX8LhYnW6WlB2f1+xb4EjaCNgpP/zCf98MXosw==", "optional": true, "dependencies": { - "@aws-sdk/node-config-provider": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/node-config-provider": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" }, "peerDependencies": { "aws-crt": ">=1.0.0" @@ -1025,26 +1120,26 @@ } } }, - "node_modules/@aws-sdk/util-utf8-browser": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.188.0.tgz", - "integrity": "sha512-jt627x0+jE+Ydr9NwkFstg3cUvgWh56qdaqAMDsqgRlKD21md/6G226z/Qxl7lb1VEW2LlmCx43ai/37Qwcj2Q==", + "node_modules/@aws-sdk/util-utf8": { + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8/-/util-utf8-3.310.0.tgz", + "integrity": "sha512-DnLfFT8uCO22uOJc0pt0DsSNau1GTisngBCDw8jQuWT5CqogMJu4b/uXmwEqfj8B3GX6Xsz8zOd6JpRlPftQoA==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "@aws-sdk/util-buffer-from": "3.310.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-utf8-node": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-node/-/util-utf8-node-3.188.0.tgz", - "integrity": "sha512-hCgP4+C0Lekjpjt2zFJ2R/iHes5sBGljXa5bScOFAEkRUc0Qw0VNgTv7LpEbIOAwGmqyxBoCwBW0YHPW1DfmYQ==", + "node_modules/@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", + "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", "optional": true, "dependencies": { - "@aws-sdk/util-buffer-from": "3.188.0", "tslib": "^2.3.1" - }, - "engines": { - "node": ">= 12.0.0" } }, "node_modules/@eslint/eslintrc": { @@ -1309,6 +1404,31 @@ "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, + "node_modules/@smithy/protocol-http": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-1.0.1.tgz", + "integrity": "sha512-9OrEn0WfOVtBNYJUjUAn9AOiJ4lzERCJJ/JeZs8E6yajTGxBaFRxUnNBHiNqoDJVg076hY36UmEnPx7xXrvUSg==", + "optional": true, + "dependencies": { + "@smithy/types": "^1.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-1.0.0.tgz", + "integrity": "sha512-kc1m5wPBHQCTixwuaOh9vnak/iJm21DrSf9UK6yDE5S3mQQ4u11pqAUiKWnlrZnYkeLfAI9UEHj9OaMT1v5Umg==", + "optional": true, + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@types/node": { "version": "18.11.6", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.6.tgz", @@ -2756,19 +2876,25 @@ "dev": true }, "node_modules/fast-xml-parser": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.11.tgz", - "integrity": "sha512-4aUg3aNRR/WjQAcpceODG1C3x3lFANXRo8+1biqfieHmg9pyMt7qB4lQV/Ta6sJCTbA5vfD8fnA8S54JATiFUA==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.4.tgz", + "integrity": "sha512-fbfMDvgBNIdDJLdLOwacjFAPYt67tr31H9ZhWSm45CDAxvd0I6WTlSOUo7K2P/K5sA5JgMKG64PI3DMcaFdWpQ==", + "funding": [ + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + }, + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], "optional": true, "dependencies": { "strnum": "^1.0.5" }, "bin": { "fxparser": "src/cli/cli.js" - }, - "funding": { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" } }, "node_modules/fastq": { @@ -6473,9 +6599,9 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", "optional": true }, "node_modules/tweetnacl": { @@ -6867,10 +6993,29 @@ } }, "dependencies": { + "@aws-crypto/crc32": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", + "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", + "optional": true, + "requires": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "optional": true + } + } + }, "@aws-crypto/ie11-detection": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-2.0.2.tgz", - "integrity": "sha512-5XDMQY98gMAf/WRTic5G++jfmS/VLM0rwpiOpaainKi4L0nqWMSB1SzsrEG5rjFZGYN6ZAefO+/Yta2dFM0kMw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", + "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==", "optional": true, "requires": { "tslib": "^1.11.1" @@ -6885,16 +7030,16 @@ } }, "@aws-crypto/sha256-browser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-2.0.0.tgz", - "integrity": "sha512-rYXOQ8BFOaqMEHJrLHul/25ckWH6GTJtdLSajhlqGMx0PmSueAuvboCuZCTqEKlxR8CQOwRarxYMZZSYlhRA1A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz", + "integrity": "sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==", "optional": true, "requires": { - "@aws-crypto/ie11-detection": "^2.0.0", - "@aws-crypto/sha256-js": "^2.0.0", - "@aws-crypto/supports-web-crypto": "^2.0.0", - "@aws-crypto/util": "^2.0.0", - "@aws-sdk/types": "^3.1.0", + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/sha256-js": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-locate-window": "^3.0.0", "@aws-sdk/util-utf8-browser": "^3.0.0", "tslib": "^1.11.1" @@ -6909,13 +7054,13 @@ } }, "@aws-crypto/sha256-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-2.0.0.tgz", - "integrity": "sha512-VZY+mCY4Nmrs5WGfitmNqXzaE873fcIZDu54cbaDaaamsaTOP1DBImV9F4pICc3EHjQXujyE8jig+PFCaew9ig==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz", + "integrity": "sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==", "optional": true, "requires": { - "@aws-crypto/util": "^2.0.0", - "@aws-sdk/types": "^3.1.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", "tslib": "^1.11.1" }, "dependencies": { @@ -6928,9 +7073,9 @@ } }, "@aws-crypto/supports-web-crypto": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-2.0.2.tgz", - "integrity": "sha512-6mbSsLHwZ99CTOOswvCRP3C+VCWnzBf+1SnbWxzzJ9lR0mA0JnY2JEAhp8rqmTE0GPFy88rrM27ffgp62oErMQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz", + "integrity": "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==", "optional": true, "requires": { "tslib": "^1.11.1" @@ -6945,12 +7090,12 @@ } }, "@aws-crypto/util": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-2.0.2.tgz", - "integrity": "sha512-Lgu5v/0e/BcrZ5m/IWqzPUf3UYFTy/PpeED+uc9SWUR1iZQL8XXbGQg10UfllwwBryO3hFF5dizK+78aoXC1eA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", + "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", "optional": true, "requires": { - "@aws-sdk/types": "^3.110.0", + "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-utf8-browser": "^3.0.0", "tslib": "^1.11.1" }, @@ -6964,400 +7109,452 @@ } }, "@aws-sdk/abort-controller": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.193.0.tgz", - "integrity": "sha512-MYPBm5PWyKP+Tq37mKs5wDbyAyVMocF5iYmx738LYXBSj8A1V4LTFrvfd4U16BRC/sM0DYB9fBFJUQ9ISFRVYw==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.347.0.tgz", + "integrity": "sha512-P/2qE6ntYEmYG4Ez535nJWZbXqgbkJx8CMz7ChEuEg3Gp3dvVYEKg+iEUEvlqQ2U5dWP5J3ehw5po9t86IsVPQ==", "optional": true, "requires": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/client-cognito-identity": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.196.0.tgz", - "integrity": "sha512-EwO3G3YPQuT1nkzaVByfoyV1Jyx1WVmbt3HH5nIQDP2bgKCPkq8mytiSS14H0VyejGHmc8/1wZ7Q/MRPosdgEg==", - "optional": true, - "requires": { - "@aws-crypto/sha256-browser": "2.0.0", - "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/client-sts": "3.196.0", - "@aws-sdk/config-resolver": "3.193.0", - "@aws-sdk/credential-provider-node": "3.196.0", - "@aws-sdk/fetch-http-handler": "3.193.0", - "@aws-sdk/hash-node": "3.193.0", - "@aws-sdk/invalid-dependency": "3.193.0", - "@aws-sdk/middleware-content-length": "3.193.0", - "@aws-sdk/middleware-endpoint": "3.193.0", - "@aws-sdk/middleware-host-header": "3.193.0", - "@aws-sdk/middleware-logger": "3.193.0", - "@aws-sdk/middleware-recursion-detection": "3.193.0", - "@aws-sdk/middleware-retry": "3.193.0", - "@aws-sdk/middleware-serde": "3.193.0", - "@aws-sdk/middleware-signing": "3.193.0", - "@aws-sdk/middleware-stack": "3.193.0", - "@aws-sdk/middleware-user-agent": "3.193.0", - "@aws-sdk/node-config-provider": "3.193.0", - "@aws-sdk/node-http-handler": "3.193.0", - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/smithy-client": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/url-parser": "3.193.0", - "@aws-sdk/util-base64-browser": "3.188.0", - "@aws-sdk/util-base64-node": "3.188.0", - "@aws-sdk/util-body-length-browser": "3.188.0", - "@aws-sdk/util-body-length-node": "3.188.0", - "@aws-sdk/util-defaults-mode-browser": "3.193.0", - "@aws-sdk/util-defaults-mode-node": "3.193.0", - "@aws-sdk/util-endpoints": "3.196.0", - "@aws-sdk/util-user-agent-browser": "3.193.0", - "@aws-sdk/util-user-agent-node": "3.193.0", - "@aws-sdk/util-utf8-browser": "3.188.0", - "@aws-sdk/util-utf8-node": "3.188.0", - "tslib": "^2.3.1" + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.350.0.tgz", + "integrity": "sha512-46AhBvGWo6TEzlvZieNlZHC2w4NJUJA52KfDUtgr8PmChGgxqzlLBAiOpqbDJ83GR3YB6CNEjXxzN5tmyJKICA==", + "optional": true, + "requires": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sts": "3.350.0", + "@aws-sdk/config-resolver": "3.347.0", + "@aws-sdk/credential-provider-node": "3.350.0", + "@aws-sdk/fetch-http-handler": "3.347.0", + "@aws-sdk/hash-node": "3.347.0", + "@aws-sdk/invalid-dependency": "3.347.0", + "@aws-sdk/middleware-content-length": "3.347.0", + "@aws-sdk/middleware-endpoint": "3.347.0", + "@aws-sdk/middleware-host-header": "3.347.0", + "@aws-sdk/middleware-logger": "3.347.0", + "@aws-sdk/middleware-recursion-detection": "3.347.0", + "@aws-sdk/middleware-retry": "3.347.0", + "@aws-sdk/middleware-serde": "3.347.0", + "@aws-sdk/middleware-signing": "3.347.0", + "@aws-sdk/middleware-stack": "3.347.0", + "@aws-sdk/middleware-user-agent": "3.347.0", + "@aws-sdk/node-config-provider": "3.347.0", + "@aws-sdk/node-http-handler": "3.350.0", + "@aws-sdk/smithy-client": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/url-parser": "3.347.0", + "@aws-sdk/util-base64": "3.310.0", + "@aws-sdk/util-body-length-browser": "3.310.0", + "@aws-sdk/util-body-length-node": "3.310.0", + "@aws-sdk/util-defaults-mode-browser": "3.347.0", + "@aws-sdk/util-defaults-mode-node": "3.347.0", + "@aws-sdk/util-endpoints": "3.347.0", + "@aws-sdk/util-retry": "3.347.0", + "@aws-sdk/util-user-agent-browser": "3.347.0", + "@aws-sdk/util-user-agent-node": "3.347.0", + "@aws-sdk/util-utf8": "3.310.0", + "@smithy/protocol-http": "^1.0.1", + "@smithy/types": "^1.0.0", + "tslib": "^2.5.0" } }, "@aws-sdk/client-sso": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.196.0.tgz", - "integrity": "sha512-u+UnxrVHLjLDdfCZft1AuyIhyv+77/inCHR4LcKsGASRA+jAg3z+OY+B7Q9hWHNcVt5ECMw7rxe4jA9BLf42sw==", - "optional": true, - "requires": { - "@aws-crypto/sha256-browser": "2.0.0", - "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/config-resolver": "3.193.0", - "@aws-sdk/fetch-http-handler": "3.193.0", - "@aws-sdk/hash-node": "3.193.0", - "@aws-sdk/invalid-dependency": "3.193.0", - "@aws-sdk/middleware-content-length": "3.193.0", - "@aws-sdk/middleware-endpoint": "3.193.0", - "@aws-sdk/middleware-host-header": "3.193.0", - "@aws-sdk/middleware-logger": "3.193.0", - "@aws-sdk/middleware-recursion-detection": "3.193.0", - "@aws-sdk/middleware-retry": "3.193.0", - "@aws-sdk/middleware-serde": "3.193.0", - "@aws-sdk/middleware-stack": "3.193.0", - "@aws-sdk/middleware-user-agent": "3.193.0", - "@aws-sdk/node-config-provider": "3.193.0", - "@aws-sdk/node-http-handler": "3.193.0", - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/smithy-client": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/url-parser": "3.193.0", - "@aws-sdk/util-base64-browser": "3.188.0", - "@aws-sdk/util-base64-node": "3.188.0", - "@aws-sdk/util-body-length-browser": "3.188.0", - "@aws-sdk/util-body-length-node": "3.188.0", - "@aws-sdk/util-defaults-mode-browser": "3.193.0", - "@aws-sdk/util-defaults-mode-node": "3.193.0", - "@aws-sdk/util-endpoints": "3.196.0", - "@aws-sdk/util-user-agent-browser": "3.193.0", - "@aws-sdk/util-user-agent-node": "3.193.0", - "@aws-sdk/util-utf8-browser": "3.188.0", - "@aws-sdk/util-utf8-node": "3.188.0", - "tslib": "^2.3.1" + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.350.0.tgz", + "integrity": "sha512-2vpiv6SEjmQGK3ZueGzvTMG6NenjWp0CHjmda71d1Iqr+tZ2UlfC35+3ioU8JP+jiXLL+y9r+SCer3IC8N/i+Q==", + "optional": true, + "requires": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/config-resolver": "3.347.0", + "@aws-sdk/fetch-http-handler": "3.347.0", + "@aws-sdk/hash-node": "3.347.0", + "@aws-sdk/invalid-dependency": "3.347.0", + "@aws-sdk/middleware-content-length": "3.347.0", + "@aws-sdk/middleware-endpoint": "3.347.0", + "@aws-sdk/middleware-host-header": "3.347.0", + "@aws-sdk/middleware-logger": "3.347.0", + "@aws-sdk/middleware-recursion-detection": "3.347.0", + "@aws-sdk/middleware-retry": "3.347.0", + "@aws-sdk/middleware-serde": "3.347.0", + "@aws-sdk/middleware-stack": "3.347.0", + "@aws-sdk/middleware-user-agent": "3.347.0", + "@aws-sdk/node-config-provider": "3.347.0", + "@aws-sdk/node-http-handler": "3.350.0", + "@aws-sdk/smithy-client": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/url-parser": "3.347.0", + "@aws-sdk/util-base64": "3.310.0", + "@aws-sdk/util-body-length-browser": "3.310.0", + "@aws-sdk/util-body-length-node": "3.310.0", + "@aws-sdk/util-defaults-mode-browser": "3.347.0", + "@aws-sdk/util-defaults-mode-node": "3.347.0", + "@aws-sdk/util-endpoints": "3.347.0", + "@aws-sdk/util-retry": "3.347.0", + "@aws-sdk/util-user-agent-browser": "3.347.0", + "@aws-sdk/util-user-agent-node": "3.347.0", + "@aws-sdk/util-utf8": "3.310.0", + "@smithy/protocol-http": "^1.0.1", + "@smithy/types": "^1.0.0", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/client-sso-oidc": { + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.350.0.tgz", + "integrity": "sha512-v3UrWIglg9PPzGXqhyGB/qPZ8ifiGM9r4LV8vve1TpiKsUdf1Khtx1eB8yqjNO0vIsYUF+j1C23QT1qAN2DcEA==", + "optional": true, + "requires": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/config-resolver": "3.347.0", + "@aws-sdk/fetch-http-handler": "3.347.0", + "@aws-sdk/hash-node": "3.347.0", + "@aws-sdk/invalid-dependency": "3.347.0", + "@aws-sdk/middleware-content-length": "3.347.0", + "@aws-sdk/middleware-endpoint": "3.347.0", + "@aws-sdk/middleware-host-header": "3.347.0", + "@aws-sdk/middleware-logger": "3.347.0", + "@aws-sdk/middleware-recursion-detection": "3.347.0", + "@aws-sdk/middleware-retry": "3.347.0", + "@aws-sdk/middleware-serde": "3.347.0", + "@aws-sdk/middleware-stack": "3.347.0", + "@aws-sdk/middleware-user-agent": "3.347.0", + "@aws-sdk/node-config-provider": "3.347.0", + "@aws-sdk/node-http-handler": "3.350.0", + "@aws-sdk/smithy-client": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/url-parser": "3.347.0", + "@aws-sdk/util-base64": "3.310.0", + "@aws-sdk/util-body-length-browser": "3.310.0", + "@aws-sdk/util-body-length-node": "3.310.0", + "@aws-sdk/util-defaults-mode-browser": "3.347.0", + "@aws-sdk/util-defaults-mode-node": "3.347.0", + "@aws-sdk/util-endpoints": "3.347.0", + "@aws-sdk/util-retry": "3.347.0", + "@aws-sdk/util-user-agent-browser": "3.347.0", + "@aws-sdk/util-user-agent-node": "3.347.0", + "@aws-sdk/util-utf8": "3.310.0", + "@smithy/protocol-http": "^1.0.1", + "@smithy/types": "^1.0.0", + "tslib": "^2.5.0" } }, "@aws-sdk/client-sts": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.196.0.tgz", - "integrity": "sha512-ChzK8606CugwnRLm7iwerXzeMqOsjGLe3j1j1HtQShzXZu4/ysQ3mUBBPAt2Lltx+1ep8MoI9vaQVyfw5h35ww==", - "optional": true, - "requires": { - "@aws-crypto/sha256-browser": "2.0.0", - "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/config-resolver": "3.193.0", - "@aws-sdk/credential-provider-node": "3.196.0", - "@aws-sdk/fetch-http-handler": "3.193.0", - "@aws-sdk/hash-node": "3.193.0", - "@aws-sdk/invalid-dependency": "3.193.0", - "@aws-sdk/middleware-content-length": "3.193.0", - "@aws-sdk/middleware-endpoint": "3.193.0", - "@aws-sdk/middleware-host-header": "3.193.0", - "@aws-sdk/middleware-logger": "3.193.0", - "@aws-sdk/middleware-recursion-detection": "3.193.0", - "@aws-sdk/middleware-retry": "3.193.0", - "@aws-sdk/middleware-sdk-sts": "3.193.0", - "@aws-sdk/middleware-serde": "3.193.0", - "@aws-sdk/middleware-signing": "3.193.0", - "@aws-sdk/middleware-stack": "3.193.0", - "@aws-sdk/middleware-user-agent": "3.193.0", - "@aws-sdk/node-config-provider": "3.193.0", - "@aws-sdk/node-http-handler": "3.193.0", - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/smithy-client": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/url-parser": "3.193.0", - "@aws-sdk/util-base64-browser": "3.188.0", - "@aws-sdk/util-base64-node": "3.188.0", - "@aws-sdk/util-body-length-browser": "3.188.0", - "@aws-sdk/util-body-length-node": "3.188.0", - "@aws-sdk/util-defaults-mode-browser": "3.193.0", - "@aws-sdk/util-defaults-mode-node": "3.193.0", - "@aws-sdk/util-endpoints": "3.196.0", - "@aws-sdk/util-user-agent-browser": "3.193.0", - "@aws-sdk/util-user-agent-node": "3.193.0", - "@aws-sdk/util-utf8-browser": "3.188.0", - "@aws-sdk/util-utf8-node": "3.188.0", - "fast-xml-parser": "4.0.11", - "tslib": "^2.3.1" + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.350.0.tgz", + "integrity": "sha512-s8RsJ6upWQgeUt8GdV3j3ZeTS7BQXedk77RhZ7wzvVwAjO9wow4uS7Iyic4kS3Y/6d26s0MO2vP4bR6HW6U6ZQ==", + "optional": true, + "requires": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/config-resolver": "3.347.0", + "@aws-sdk/credential-provider-node": "3.350.0", + "@aws-sdk/fetch-http-handler": "3.347.0", + "@aws-sdk/hash-node": "3.347.0", + "@aws-sdk/invalid-dependency": "3.347.0", + "@aws-sdk/middleware-content-length": "3.347.0", + "@aws-sdk/middleware-endpoint": "3.347.0", + "@aws-sdk/middleware-host-header": "3.347.0", + "@aws-sdk/middleware-logger": "3.347.0", + "@aws-sdk/middleware-recursion-detection": "3.347.0", + "@aws-sdk/middleware-retry": "3.347.0", + "@aws-sdk/middleware-sdk-sts": "3.347.0", + "@aws-sdk/middleware-serde": "3.347.0", + "@aws-sdk/middleware-signing": "3.347.0", + "@aws-sdk/middleware-stack": "3.347.0", + "@aws-sdk/middleware-user-agent": "3.347.0", + "@aws-sdk/node-config-provider": "3.347.0", + "@aws-sdk/node-http-handler": "3.350.0", + "@aws-sdk/smithy-client": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/url-parser": "3.347.0", + "@aws-sdk/util-base64": "3.310.0", + "@aws-sdk/util-body-length-browser": "3.310.0", + "@aws-sdk/util-body-length-node": "3.310.0", + "@aws-sdk/util-defaults-mode-browser": "3.347.0", + "@aws-sdk/util-defaults-mode-node": "3.347.0", + "@aws-sdk/util-endpoints": "3.347.0", + "@aws-sdk/util-retry": "3.347.0", + "@aws-sdk/util-user-agent-browser": "3.347.0", + "@aws-sdk/util-user-agent-node": "3.347.0", + "@aws-sdk/util-utf8": "3.310.0", + "@smithy/protocol-http": "^1.0.1", + "@smithy/types": "^1.0.0", + "fast-xml-parser": "4.2.4", + "tslib": "^2.5.0" } }, "@aws-sdk/config-resolver": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.193.0.tgz", - "integrity": "sha512-HIjuv2A1glgkXy9g/A8bfsiz3jTFaRbwGZheoHFZod6iEQQEbbeAsBe3u2AZyzOrVLgs8lOvBtgU8XKSJWjDkw==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.347.0.tgz", + "integrity": "sha512-2ja+Sf/VnUO7IQ3nKbDQ5aumYKKJUaTm/BuVJ29wNho8wYHfuf7wHZV0pDTkB8RF5SH7IpHap7zpZAj39Iq+EA==", "optional": true, "requires": { - "@aws-sdk/signature-v4": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/util-config-provider": "3.188.0", - "@aws-sdk/util-middleware": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-config-provider": "3.310.0", + "@aws-sdk/util-middleware": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-cognito-identity": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.196.0.tgz", - "integrity": "sha512-yXpb8kx1RpHRJty6MNX3ssTu0h3SYZVpUinQtBXPdHoVZ5/DyF/KGd2jr0LWYrgTx8G42GHTltz3Ss4nYjosnQ==", + "version": "3.351.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.351.0.tgz", + "integrity": "sha512-c9XyDUj82ttqQqF8h4Ie7k2Fl3bMh8/yBGEQWIPzWRhfy40m4ChqjilKAcBeoxR/w4Qp3RsdDfLRTLC8sJTpIg==", "optional": true, "requires": { - "@aws-sdk/client-cognito-identity": "3.196.0", - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/client-cognito-identity": "3.350.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-env": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.193.0.tgz", - "integrity": "sha512-pRqZoIaqCdWB4JJdR6DqDn3u+CwKJchwiCPnRtChwC8KXCMkT4njq9J1bWG3imYeTxP/G06O1PDONEuD4pPtNQ==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.347.0.tgz", + "integrity": "sha512-UnEM+LKGpXKzw/1WvYEQsC6Wj9PupYZdQOE+e2Dgy2dqk/pVFy4WueRtFXYDT2B41ppv3drdXUuKZRIDVqIgNQ==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-imds": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.193.0.tgz", - "integrity": "sha512-jC7uT7uVpO/iitz49toHMGFKXQ2igWQQG2SKirREqDRaz5HSXwEP1V3rcOlNNyGIBPMggDjZnxYgJHqBXSq9Ag==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.347.0.tgz", + "integrity": "sha512-7scCy/DCDRLIhlqTxff97LQWDnRwRXji3bxxMg+xWOTTaJe7PWx+etGSbBWaL42vsBHFShQjSLvJryEgoBktpw==", "optional": true, "requires": { - "@aws-sdk/node-config-provider": "3.193.0", - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/url-parser": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/node-config-provider": "3.347.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/url-parser": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-ini": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.196.0.tgz", - "integrity": "sha512-3lL+YLBQ9KwQxG4AdRm4u2cvBNZeBmS/i3BWnCPomg96lNGPMrTEloVaVEpnrzOff6sgFxRtjkbLkVxmdipIrw==", - "optional": true, - "requires": { - "@aws-sdk/credential-provider-env": "3.193.0", - "@aws-sdk/credential-provider-imds": "3.193.0", - "@aws-sdk/credential-provider-sso": "3.196.0", - "@aws-sdk/credential-provider-web-identity": "3.193.0", - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/shared-ini-file-loader": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.350.0.tgz", + "integrity": "sha512-mGGU0PpnG0VDNKSuGi083U1egjprrU9/XoRtgf+iYvAKXRR/0XA4pGW5c7zpHY7m4iLhBuRj6N4oxQsH9cMtWg==", + "optional": true, + "requires": { + "@aws-sdk/credential-provider-env": "3.347.0", + "@aws-sdk/credential-provider-imds": "3.347.0", + "@aws-sdk/credential-provider-process": "3.347.0", + "@aws-sdk/credential-provider-sso": "3.350.0", + "@aws-sdk/credential-provider-web-identity": "3.347.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/shared-ini-file-loader": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-node": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.196.0.tgz", - "integrity": "sha512-PGY7pkmqgfEwTHsuUH6fGrXWri93jqKkMbhq/QJafMGtsVupfvXvE37Rl+qgjsZjRfROrEaeLw2DGrPPmVh2cg==", - "optional": true, - "requires": { - "@aws-sdk/credential-provider-env": "3.193.0", - "@aws-sdk/credential-provider-imds": "3.193.0", - "@aws-sdk/credential-provider-ini": "3.196.0", - "@aws-sdk/credential-provider-process": "3.193.0", - "@aws-sdk/credential-provider-sso": "3.196.0", - "@aws-sdk/credential-provider-web-identity": "3.193.0", - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/shared-ini-file-loader": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.350.0.tgz", + "integrity": "sha512-xmqwCFwj/CZPx6AKHNb24Kpr0eHW9VISt9r+SfgH8PaYg5cNyX1pKmMbQCket5ov+WvHEQtOK7aBafak7dhauA==", + "optional": true, + "requires": { + "@aws-sdk/credential-provider-env": "3.347.0", + "@aws-sdk/credential-provider-imds": "3.347.0", + "@aws-sdk/credential-provider-ini": "3.350.0", + "@aws-sdk/credential-provider-process": "3.347.0", + "@aws-sdk/credential-provider-sso": "3.350.0", + "@aws-sdk/credential-provider-web-identity": "3.347.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/shared-ini-file-loader": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-process": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.193.0.tgz", - "integrity": "sha512-zpXxtQzQqkaUuFqmHW9dSkh9p/1k+XNKlwEkG8FTwAJNUWmy2ZMJv+8NTVn4s4vaRu7xJ1er9chspYr7mvxHlA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.347.0.tgz", + "integrity": "sha512-yl1z4MsaBdXd4GQ2halIvYds23S67kElyOwz7g8kaQ4kHj+UoYWxz3JVW/DGusM6XmQ9/F67utBrUVA0uhQYyw==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/shared-ini-file-loader": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/shared-ini-file-loader": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-sso": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.196.0.tgz", - "integrity": "sha512-hJV4LDVfvPfj5zC0ysHx3zkwwJOyF+BaMGaMzaScrHyijv5e3qZzdoBLbOQFmrqVnt7DjCU02NvRSS8amLpmSw==", + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.350.0.tgz", + "integrity": "sha512-u/3kv+PJeVawzBtWBei+IX1/z50mwhpPe3VrKSTns4CPUw8b5sqIYWkAaw5hxm0td69+xcL98RzIJsEpJc4QSQ==", "optional": true, "requires": { - "@aws-sdk/client-sso": "3.196.0", - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/shared-ini-file-loader": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/client-sso": "3.350.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/shared-ini-file-loader": "3.347.0", + "@aws-sdk/token-providers": "3.350.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-web-identity": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.193.0.tgz", - "integrity": "sha512-MIQY9KwLCBnRyIt7an4EtMrFQZz2HC1E8vQDdKVzmeQBBePhW61fnX9XDP9bfc3Ypg1NggLG00KBPEC88twLFg==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.347.0.tgz", + "integrity": "sha512-DxoTlVK8lXjS1zVphtz/Ab+jkN/IZor9d6pP2GjJHNoAIIzXfRwwj5C8vr4eTayx/5VJ7GRP91J8GJ2cKly8Qw==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-providers": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.196.0.tgz", - "integrity": "sha512-IE2Lq0EMCkPqvh0on6Dfg5Nofcm2hbsDH8etQNKRpvZ/K8elz1aArh2gcL9F01smrJChAHWwD8uZbk/eQ/Zf2w==", - "optional": true, - "requires": { - "@aws-sdk/client-cognito-identity": "3.196.0", - "@aws-sdk/client-sso": "3.196.0", - "@aws-sdk/client-sts": "3.196.0", - "@aws-sdk/credential-provider-cognito-identity": "3.196.0", - "@aws-sdk/credential-provider-env": "3.193.0", - "@aws-sdk/credential-provider-imds": "3.193.0", - "@aws-sdk/credential-provider-ini": "3.196.0", - "@aws-sdk/credential-provider-node": "3.196.0", - "@aws-sdk/credential-provider-process": "3.193.0", - "@aws-sdk/credential-provider-sso": "3.196.0", - "@aws-sdk/credential-provider-web-identity": "3.193.0", - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/shared-ini-file-loader": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "version": "3.351.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.351.0.tgz", + "integrity": "sha512-KVfLTVpeDKnOPl0u5w3RJdNz+AtFIOj3dsfpyLkGCV5bHClLN05YFf1ajh93Z5FijuhvDSYuLT1Xr3Ud+AIudQ==", + "optional": true, + "requires": { + "@aws-sdk/client-cognito-identity": "3.350.0", + "@aws-sdk/client-sso": "3.350.0", + "@aws-sdk/client-sts": "3.350.0", + "@aws-sdk/credential-provider-cognito-identity": "3.351.0", + "@aws-sdk/credential-provider-env": "3.347.0", + "@aws-sdk/credential-provider-imds": "3.347.0", + "@aws-sdk/credential-provider-ini": "3.350.0", + "@aws-sdk/credential-provider-node": "3.350.0", + "@aws-sdk/credential-provider-process": "3.347.0", + "@aws-sdk/credential-provider-sso": "3.350.0", + "@aws-sdk/credential-provider-web-identity": "3.347.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" + } + }, + "@aws-sdk/eventstream-codec": { + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-codec/-/eventstream-codec-3.347.0.tgz", + "integrity": "sha512-61q+SyspjsaQ4sdgjizMyRgVph2CiW4aAtfpoH69EJFJfTxTR/OqnZ9Jx/3YiYi0ksrvDenJddYodfWWJqD8/w==", + "optional": true, + "requires": { + "@aws-crypto/crc32": "3.0.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-hex-encoding": "3.310.0", + "tslib": "^2.5.0" } }, "@aws-sdk/fetch-http-handler": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.193.0.tgz", - "integrity": "sha512-UhIS2LtCK9hqBzYVon6BI8WebJW1KC0GGIL/Gse5bqzU9iAGgFLAe66qg9k+/h3Jjc5LNAYzqXNVizMwn7689Q==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.347.0.tgz", + "integrity": "sha512-sQ5P7ivY8//7wdxfA76LT1sF6V2Tyyz1qF6xXf9sihPN5Q1Y65c+SKpMzXyFSPqWZ82+SQQuDliYZouVyS6kQQ==", "optional": true, "requires": { - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/querystring-builder": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/util-base64-browser": "3.188.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.347.0", + "@aws-sdk/querystring-builder": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-base64": "3.310.0", + "tslib": "^2.5.0" } }, "@aws-sdk/hash-node": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.193.0.tgz", - "integrity": "sha512-O2SLPVBjrCUo+4ouAdRUoHBYsyurO9LcjNZNYD7YQOotBTbVFA3cx7kTZu+K4B6kX7FDaGbqbE1C/T1/eg/r+w==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.347.0.tgz", + "integrity": "sha512-96+ml/4EaUaVpzBdOLGOxdoXOjkPgkoJp/0i1fxOJEvl8wdAQSwc3IugVK9wZkCxy2DlENtgOe6DfIOhfffm/g==", "optional": true, "requires": { - "@aws-sdk/types": "3.193.0", - "@aws-sdk/util-buffer-from": "3.188.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-buffer-from": "3.310.0", + "@aws-sdk/util-utf8": "3.310.0", + "tslib": "^2.5.0" } }, "@aws-sdk/invalid-dependency": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.193.0.tgz", - "integrity": "sha512-54DCknekLwJAI1os76XJ8XCzfAH7BGkBGtlWk5WCNkZTfj3rf5RUiXz4uoKUMWE1rZmyMDoDDS1PBo+yTVKW5w==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.347.0.tgz", + "integrity": "sha512-8imQcwLwqZ/wTJXZqzXT9pGLIksTRckhGLZaXT60tiBOPKuerTsus2L59UstLs5LP8TKaVZKFFSsjRIn9dQdmQ==", "optional": true, "requires": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/is-array-buffer": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.188.0.tgz", - "integrity": "sha512-n69N4zJZCNd87Rf4NzufPzhactUeM877Y0Tp/F3KiHqGeTnVjYUa4Lv1vLBjqtfjYb2HWT3NKlYn5yzrhaEwiQ==", + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.310.0.tgz", + "integrity": "sha512-urnbcCR+h9NWUnmOtet/s4ghvzsidFmspfhYaHAmSRdy9yDjdjBJMFjjsn85A1ODUktztm+cVncXjQ38WCMjMQ==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-content-length": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.193.0.tgz", - "integrity": "sha512-em0Sqo7O7DFOcVXU460pbcYuIjblDTZqK2YE62nQ0T+5Nbj+MSjuoite+rRRdRww9VqBkUROGKON45bUNjogtQ==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.347.0.tgz", + "integrity": "sha512-i4qtWTDImMaDUtwKQPbaZpXsReiwiBomM1cWymCU4bhz81HL01oIxOxOBuiM+3NlDoCSPr3KI6txZSz/8cqXCQ==", "optional": true, "requires": { - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-endpoint": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.193.0.tgz", - "integrity": "sha512-Inbpt7jcHGvzF7UOJOCxx9wih0+eAQYERikokidWJa7M405EJpVYq1mGbeOcQUPANU3uWF1AObmUUFhbkriHQw==", - "optional": true, - "requires": { - "@aws-sdk/middleware-serde": "3.193.0", - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/signature-v4": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/url-parser": "3.193.0", - "@aws-sdk/util-config-provider": "3.188.0", - "@aws-sdk/util-middleware": "3.193.0", - "tslib": "^2.3.1" + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.347.0.tgz", + "integrity": "sha512-unF0c6dMaUL1ffU+37Ugty43DgMnzPWXr/Jup/8GbK5fzzWT5NQq6dj9KHPubMbWeEjQbmczvhv25JuJdK8gNQ==", + "optional": true, + "requires": { + "@aws-sdk/middleware-serde": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/url-parser": "3.347.0", + "@aws-sdk/util-middleware": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-host-header": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.193.0.tgz", - "integrity": "sha512-aegzj5oRWd//lmfmkzRmgG2b4l3140v8Ey4QkqCxcowvAEX5a7rh23yuKaGtmiePwv2RQalCKz+tN6JXCm8g6Q==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.347.0.tgz", + "integrity": "sha512-kpKmR9OvMlnReqp5sKcJkozbj1wmlblbVSbnQAIkzeQj2xD5dnVR3Nn2ogQKxSmU1Fv7dEroBtrruJ1o3fY38A==", "optional": true, "requires": { - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-logger": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.193.0.tgz", - "integrity": "sha512-D/h1pU5tAcyJpJ8ZeD1Sta0S9QZPcxERYRBiJdEl8VUrYwfy3Cl1WJedVOmd5nG73ZLRSyHeXHewb/ohge3yKQ==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.347.0.tgz", + "integrity": "sha512-NYC+Id5UCkVn+3P1t/YtmHt75uED06vwaKyxDy0UmB2K66PZLVtwWbLpVWrhbroaw1bvUHYcRyQ9NIfnVcXQjA==", "optional": true, "requires": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-recursion-detection": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.193.0.tgz", - "integrity": "sha512-fMWP76Q1GOb/9OzS1arizm6Dbfo02DPZ6xp7OoAN3PS6ybH3Eb47s/gP3jzgBPAITQacFj4St/4a06YWYrN3NA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.347.0.tgz", + "integrity": "sha512-qfnSvkFKCAMjMHR31NdsT0gv5Sq/ZHTUD4yQsSLpbVQ6iYAS834lrzXt41iyEHt57Y514uG7F/Xfvude3u4icQ==", "optional": true, "requires": { - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-retry": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.193.0.tgz", - "integrity": "sha512-zTQkHLBQBJi6ns655WYcYLyLPc1tgbEYU080Oc8zlveLUqoDn1ogkcmNhG7XMeQuBvWZBYN7J3/wFaXlDzeCKg==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.347.0.tgz", + "integrity": "sha512-CpdM+8dCSbX96agy4FCzOfzDmhNnGBM/pxrgIVLm5nkYTLuXp/d7ubpFEUHULr+4hCd5wakHotMt7yO29NFaVw==", "optional": true, "requires": { - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/service-error-classification": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/util-middleware": "3.193.0", - "tslib": "^2.3.1", + "@aws-sdk/protocol-http": "3.347.0", + "@aws-sdk/service-error-classification": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-middleware": "3.347.0", + "@aws-sdk/util-retry": "3.347.0", + "tslib": "^2.5.0", "uuid": "^8.3.2" }, "dependencies": { @@ -7370,353 +7567,370 @@ } }, "@aws-sdk/middleware-sdk-sts": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.193.0.tgz", - "integrity": "sha512-TafiDkeflUsnbNa89TLkDnAiRRp1gAaZLDAjt75AzriRKZnhtFfYUXWb+qAuN50T+CkJ/gZI9LHDZL5ogz/HxQ==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.347.0.tgz", + "integrity": "sha512-38LJ0bkIoVF3W97x6Jyyou72YV9Cfbml4OaDEdnrCOo0EssNZM5d7RhjMvQDwww7/3OBY/BzeOcZKfJlkYUXGw==", "optional": true, "requires": { - "@aws-sdk/middleware-signing": "3.193.0", - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/signature-v4": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/middleware-signing": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-serde": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.193.0.tgz", - "integrity": "sha512-dH93EJYVztY+ZDPzSMRi9LfAZfKO+luH62raNy49hlNa4jiyE1Tc/+qwlmOEpfGsrtcZ9TgsON1uFF9sgBXXaA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.347.0.tgz", + "integrity": "sha512-x5Foi7jRbVJXDu9bHfyCbhYDH5pKK+31MmsSJ3k8rY8keXLBxm2XEEg/AIoV9/TUF9EeVvZ7F1/RmMpJnWQsEg==", "optional": true, "requires": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-signing": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.193.0.tgz", - "integrity": "sha512-obBoELGPf5ikvHYZwbzllLeuODiokdDfe92Ve2ufeOa/d8+xsmbqNzNdCTLNNTmr1tEIaEE7ngZVTOiHqAVhyw==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.347.0.tgz", + "integrity": "sha512-zVBF/4MGKnvhAE/J+oAL/VAehiyv+trs2dqSQXwHou9j8eA8Vm8HS2NdOwpkZQchIxTuwFlqSusDuPEdYFbvGw==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/signature-v4": "3.193.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/util-middleware": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/protocol-http": "3.347.0", + "@aws-sdk/signature-v4": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-middleware": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-stack": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.193.0.tgz", - "integrity": "sha512-Ix5d7gE6bZwFNIVf0dGnjYuymz1gjitNoAZDPpv1nEZlUMek/jcno5lmzWFzUZXY/azpbIyaPwq/wm/c69au5A==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.347.0.tgz", + "integrity": "sha512-Izidg4rqtYMcKuvn2UzgEpPLSmyd8ub9+LQ2oIzG3mpIzCBITq7wp40jN1iNkMg+X6KEnX9vdMJIYZsPYMCYuQ==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-user-agent": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.193.0.tgz", - "integrity": "sha512-0vT6F9NwYQK7ARUUJeHTUIUPnupsO3IbmjHSi1+clkssFlJm2UfmSGeafiWe4AYH3anATTvZEtcxX5DZT/ExbA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.347.0.tgz", + "integrity": "sha512-wJbGN3OE1/daVCrwk49whhIr9E0j1N4gWwN/wi4WuyYIA+5lMUfVp0aGIOvZR+878DxuFz2hQ4XcZVT4K2WvQw==", "optional": true, "requires": { - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.347.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-endpoints": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/node-config-provider": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.193.0.tgz", - "integrity": "sha512-5RLdjQLH69ISRG8TX9klSLOpEySXxj+z9E9Em39HRvw0/rDcd8poCTADvjYIOqRVvMka0z/hm+elvUTIVn/DRw==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.347.0.tgz", + "integrity": "sha512-faU93d3+5uTTUcotGgMXF+sJVFjrKh+ufW+CzYKT4yUHammyaIab/IbTPWy2hIolcEGtuPeVoxXw8TXbkh/tuw==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/shared-ini-file-loader": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/shared-ini-file-loader": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/node-http-handler": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.193.0.tgz", - "integrity": "sha512-DP4BmFw64HOShgpAPEEMZedVnRmKKjHOwMEoXcnNlAkMXnYUFHiKvudYq87Q2AnSlT6OHkyMviB61gEvIk73dA==", + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.350.0.tgz", + "integrity": "sha512-oD96GAlmpzYilCdC8wwyURM5lNfNHZCjm/kxBkQulHKa2kRbIrnD9GfDqdCkWA5cTpjh1NzGLT4D6e6UFDjt9w==", "optional": true, "requires": { - "@aws-sdk/abort-controller": "3.193.0", - "@aws-sdk/protocol-http": "3.193.0", - "@aws-sdk/querystring-builder": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/abort-controller": "3.347.0", + "@aws-sdk/protocol-http": "3.347.0", + "@aws-sdk/querystring-builder": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/property-provider": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.193.0.tgz", - "integrity": "sha512-IaDR/PdZjKlAeSq2E/6u6nkPsZF9wvhHZckwH7uumq4ocWsWXFzaT+hKpV4YZPHx9n+K2YV4Gn/bDedpz99W1Q==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.347.0.tgz", + "integrity": "sha512-t3nJ8CYPLKAF2v9nIHOHOlF0CviQbTvbFc2L4a+A+EVd/rM4PzL3+3n8ZJsr0h7f6uD04+b5YRFgKgnaqLXlEg==", "optional": true, "requires": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/protocol-http": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.193.0.tgz", - "integrity": "sha512-r0wbTwFJyXq0uiImI6giqG3g/RO1N/y4wwPA7qr7OC+KXJ0NkyVxIf6e7Vx8h06aM1ATtngbwJaMP59kVCp85A==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.347.0.tgz", + "integrity": "sha512-2YdBhc02Wvy03YjhGwUxF0UQgrPWEy8Iq75pfS42N+/0B/+eWX1aQgfjFxIpLg7YSjT5eKtYOQGlYd4MFTgj9g==", "optional": true, "requires": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/querystring-builder": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.193.0.tgz", - "integrity": "sha512-PRaK6649iw0UO45UjUoiUzFcOKXZb8pMjjFJpqALpEvdZT3twxqhlPXujT7GWPKrSwO4uPLNnyYEtPY82wx2vw==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.347.0.tgz", + "integrity": "sha512-phtKTe6FXoV02MoPkIVV6owXI8Mwr5IBN3bPoxhcPvJG2AjEmnetSIrhb8kwc4oNhlwfZwH6Jo5ARW/VEWbZtg==", "optional": true, "requires": { - "@aws-sdk/types": "3.193.0", - "@aws-sdk/util-uri-escape": "3.188.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-uri-escape": "3.310.0", + "tslib": "^2.5.0" } }, "@aws-sdk/querystring-parser": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.193.0.tgz", - "integrity": "sha512-dGEPCe8SK4/td5dSpiaEI3SvT5eHXrbJWbLGyD4FL3n7WCGMy2xVWAB/yrgzD0GdLDjDa8L5vLVz6yT1P9i+hA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.347.0.tgz", + "integrity": "sha512-5VXOhfZz78T2W7SuXf2avfjKglx1VZgZgp9Zfhrt/Rq+MTu2D+PZc5zmJHhYigD7x83jLSLogpuInQpFMA9LgA==", "optional": true, "requires": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/service-error-classification": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.193.0.tgz", - "integrity": "sha512-bPnXVu8ErE1RfWVVQKc2TE7EuoImUi4dSPW9g80fGRzJdQNwXb636C+7OUuWvSDzmFwuBYqZza8GZjVd+rz2zQ==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.347.0.tgz", + "integrity": "sha512-xZ3MqSY81Oy2gh5g0fCtooAbahqh9VhsF8vcKjVX8+XPbGC8y+kej82+MsMg4gYL8gRFB9u4hgYbNgIS6JTAvg==", "optional": true }, "@aws-sdk/shared-ini-file-loader": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.193.0.tgz", - "integrity": "sha512-hnvZup8RSpFXfah7Rrn6+lQJnAOCO+OiDJ2R/iMgZQh475GRQpLbu3cPhCOkjB14vVLygJtW8trK/0+zKq93bQ==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.347.0.tgz", + "integrity": "sha512-Xw+zAZQVLb+xMNHChXQ29tzzLqm3AEHsD8JJnlkeFjeMnWQtXdUfOARl5s8NzAppcKQNlVe2gPzjaKjoy2jz1Q==", "optional": true, "requires": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/signature-v4": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.193.0.tgz", - "integrity": "sha512-JEqqOB8wQZz6g1ERNUOIBFDFt8OJtz5G5Uh1CdkS5W66gyWnJEz/dE1hA2VTqqQwHGGEsIEV/hlzruU1lXsvFA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.347.0.tgz", + "integrity": "sha512-58Uq1do+VsTHYkP11dTK+DF53fguoNNJL9rHRWhzP+OcYv3/mBMLoS2WPz/x9FO5mBg4ESFsug0I6mXbd36tjw==", "optional": true, "requires": { - "@aws-sdk/is-array-buffer": "3.188.0", - "@aws-sdk/types": "3.193.0", - "@aws-sdk/util-hex-encoding": "3.188.0", - "@aws-sdk/util-middleware": "3.193.0", - "@aws-sdk/util-uri-escape": "3.188.0", - "tslib": "^2.3.1" + "@aws-sdk/eventstream-codec": "3.347.0", + "@aws-sdk/is-array-buffer": "3.310.0", + "@aws-sdk/types": "3.347.0", + "@aws-sdk/util-hex-encoding": "3.310.0", + "@aws-sdk/util-middleware": "3.347.0", + "@aws-sdk/util-uri-escape": "3.310.0", + "@aws-sdk/util-utf8": "3.310.0", + "tslib": "^2.5.0" } }, "@aws-sdk/smithy-client": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.193.0.tgz", - "integrity": "sha512-BY0jhfW76vyXr7ODMaKO3eyS98RSrZgOMl6DTQV9sk7eFP/MPVlG7p7nfX/CDIgPBIO1z0A0i2CVIzYur9uGgQ==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.347.0.tgz", + "integrity": "sha512-PaGTDsJLGK0sTjA6YdYQzILRlPRN3uVFyqeBUkfltXssvUzkm8z2t1lz2H4VyJLAhwnG5ZuZTNEV/2mcWrU7JQ==", "optional": true, "requires": { - "@aws-sdk/middleware-stack": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/middleware-stack": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, - "@aws-sdk/types": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.193.0.tgz", - "integrity": "sha512-LV/wcPolRZKORrcHwkH59QMCkiDR5sM+9ZtuTxvyUGG2QFW/kjoxs08fUF10OWNJMrotBI+czDc5QJRgN8BlAw==", - "optional": true + "@aws-sdk/token-providers": { + "version": "3.350.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.350.0.tgz", + "integrity": "sha512-VIfVMV5An1VQQ6bOKQTHPsRFHD3/YRGOPk9lDTVJGOK0G1DIFYd/10ZaLQ86rCWLck2lGhjxsOen2N2n6MtA0A==", + "optional": true, + "requires": { + "@aws-sdk/client-sso-oidc": "3.350.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/shared-ini-file-loader": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" + } }, - "@aws-sdk/url-parser": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.193.0.tgz", - "integrity": "sha512-hwD1koJlOu2a6GvaSbNbdo7I6a3tmrsNTZr8bCjAcbqpc5pDThcpnl/Uaz3zHmMPs92U8I6BvWoK6pH8By06qw==", + "@aws-sdk/types": { + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.347.0.tgz", + "integrity": "sha512-GkCMy79mdjU9OTIe5KT58fI/6uqdf8UmMdWqVHmFJ+UpEzOci7L/uw4sOXWo7xpPzLs6cJ7s5ouGZW4GRPmHFA==", "optional": true, "requires": { - "@aws-sdk/querystring-parser": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, - "@aws-sdk/util-base64-browser": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-browser/-/util-base64-browser-3.188.0.tgz", - "integrity": "sha512-qlH+5NZBLiyKziL335BEPedYxX6j+p7KFRWXvDQox9S+s+gLCayednpK+fteOhBenCcR9fUZOVuAPScy1I8qCg==", + "@aws-sdk/url-parser": { + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.347.0.tgz", + "integrity": "sha512-lhrnVjxdV7hl+yCnJfDZOaVLSqKjxN20MIOiijRiqaWGLGEAiSqBreMhL89X1WKCifxAs4zZf9YB9SbdziRpAA==", "optional": true, "requires": { - "tslib": "^2.3.1" + "@aws-sdk/querystring-parser": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, - "@aws-sdk/util-base64-node": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-node/-/util-base64-node-3.188.0.tgz", - "integrity": "sha512-r1dccRsRjKq+OhVRUfqFiW3sGgZBjHbMeHLbrAs9jrOjU2PTQ8PSzAXLvX/9lmp7YjmX17Qvlsg0NCr1tbB9OA==", + "@aws-sdk/util-base64": { + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64/-/util-base64-3.310.0.tgz", + "integrity": "sha512-v3+HBKQvqgdzcbL+pFswlx5HQsd9L6ZTlyPVL2LS9nNXnCcR3XgGz9jRskikRUuUvUXtkSG1J88GAOnJ/apTPg==", "optional": true, "requires": { - "@aws-sdk/util-buffer-from": "3.188.0", - "tslib": "^2.3.1" + "@aws-sdk/util-buffer-from": "3.310.0", + "tslib": "^2.5.0" } }, "@aws-sdk/util-body-length-browser": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.188.0.tgz", - "integrity": "sha512-8VpnwFWXhnZ/iRSl9mTf+VKOX9wDE8QtN4bj9pBfxwf90H1X7E8T6NkiZD3k+HubYf2J94e7DbeHs7fuCPW5Qg==", + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.310.0.tgz", + "integrity": "sha512-sxsC3lPBGfpHtNTUoGXMQXLwjmR0zVpx0rSvzTPAuoVILVsp5AU/w5FphNPxD5OVIjNbZv9KsKTuvNTiZjDp9g==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-body-length-node": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.188.0.tgz", - "integrity": "sha512-XwqP3vxk60MKp4YDdvDeCD6BPOiG2e+/Ou4AofZOy5/toB6NKz2pFNibQIUg2+jc7mPMnGnvOW3MQEgSJ+gu/Q==", + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.310.0.tgz", + "integrity": "sha512-2tqGXdyKhyA6w4zz7UPoS8Ip+7sayOg9BwHNidiGm2ikbDxm1YrCfYXvCBdwaJxa4hJfRVz+aL9e+d3GqPI9pQ==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-buffer-from": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.188.0.tgz", - "integrity": "sha512-NX1WXZ8TH20IZb4jPFT2CnLKSqZWddGxtfiWxD9M47YOtq/SSQeR82fhqqVjJn4P8w2F5E28f+Du4ntg/sGcxA==", + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.310.0.tgz", + "integrity": "sha512-i6LVeXFtGih5Zs8enLrt+ExXY92QV25jtEnTKHsmlFqFAuL3VBeod6boeMXkN2p9lbSVVQ1sAOOYZOHYbYkntw==", "optional": true, "requires": { - "@aws-sdk/is-array-buffer": "3.188.0", - "tslib": "^2.3.1" + "@aws-sdk/is-array-buffer": "3.310.0", + "tslib": "^2.5.0" } }, "@aws-sdk/util-config-provider": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.188.0.tgz", - "integrity": "sha512-LBA7tLbi7v4uvbOJhSnjJrxbcRifKK/1ZVK94JTV2MNSCCyNkFotyEI5UWDl10YKriTIUyf7o5cakpiDZ3O4xg==", + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.310.0.tgz", + "integrity": "sha512-xIBaYo8dwiojCw8vnUcIL4Z5tyfb1v3yjqyJKJWV/dqKUFOOS0U591plmXbM+M/QkXyML3ypon1f8+BoaDExrg==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-defaults-mode-browser": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.193.0.tgz", - "integrity": "sha512-9riQKFrSJcsNAMnPA/3ltpSxNykeO20klE/UKjxEoD7UWjxLwsPK22UJjFwMRaHoAFcZD0LU/SgPxbC0ktCYCg==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.347.0.tgz", + "integrity": "sha512-+JHFA4reWnW/nMWwrLKqL2Lm/biw/Dzi/Ix54DAkRZ08C462jMKVnUlzAI+TfxQE3YLm99EIa0G7jiEA+p81Qw==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/types": "3.193.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/types": "3.347.0", "bowser": "^2.11.0", - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-defaults-mode-node": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.193.0.tgz", - "integrity": "sha512-occQmckvPRiM4YQIZnulfKKKjykGKWloa5ByGC5gOEGlyeP9zJpfs4zc/M2kArTAt+d2r3wkBtsKe5yKSlVEhA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.347.0.tgz", + "integrity": "sha512-A8BzIVhAAZE5WEukoAN2kYebzTc99ZgncbwOmgCCbvdaYlk5tzguR/s+uoT4G0JgQGol/4hAMuJEl7elNgU6RQ==", "optional": true, "requires": { - "@aws-sdk/config-resolver": "3.193.0", - "@aws-sdk/credential-provider-imds": "3.193.0", - "@aws-sdk/node-config-provider": "3.193.0", - "@aws-sdk/property-provider": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/config-resolver": "3.347.0", + "@aws-sdk/credential-provider-imds": "3.347.0", + "@aws-sdk/node-config-provider": "3.347.0", + "@aws-sdk/property-provider": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/util-endpoints": { - "version": "3.196.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.196.0.tgz", - "integrity": "sha512-X+DOpRUy/ij49a0GQtggk09oyIQGn0mhER6PbMT69IufZPIg3D5fC5FPEp8bfsPkb70fTEYQEsj/X/rgMQJKsA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.347.0.tgz", + "integrity": "sha512-/WUkirizeNAqwVj0zkcrqdQ9pUm1HY5kU+qy7xTR0OebkuJauglkmSTMD+56L1JPunWqHhlwCMVRaz5eaJdSEQ==", "optional": true, "requires": { - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/util-hex-encoding": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.188.0.tgz", - "integrity": "sha512-QyWovTtjQ2RYxqVM+STPh65owSqzuXURnfoof778spyX4iQ4z46wOge1YV2ZtwS8w5LWd9eeVvDrLu5POPYOnA==", + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.310.0.tgz", + "integrity": "sha512-sVN7mcCCDSJ67pI1ZMtk84SKGqyix6/0A1Ab163YKn+lFBQRMKexleZzpYzNGxYzmQS6VanP/cfU7NiLQOaSfA==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-locate-window": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.188.0.tgz", - "integrity": "sha512-SxobBVLZkkLSawTCfeQnhVX3Azm9O+C2dngZVe1+BqtF8+retUbVTs7OfYeWBlawVkULKF2e781lTzEHBBjCzw==", + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz", + "integrity": "sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-middleware": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.193.0.tgz", - "integrity": "sha512-+aC6pmkcGgpxaMWCH/FXTsGWl2W342oQGs1OYKGi+W8z9UguXrqamWjdkdMqgunvj9qOEG2KBMKz1FWFFZlUyA==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.347.0.tgz", + "integrity": "sha512-8owqUA3ePufeYTUvlzdJ7Z0miLorTwx+rNol5lourGQZ9JXsVMo23+yGA7nOlFuXSGkoKpMOtn6S0BT2bcfeiw==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" + } + }, + "@aws-sdk/util-retry": { + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-retry/-/util-retry-3.347.0.tgz", + "integrity": "sha512-NxnQA0/FHFxriQAeEgBonA43Q9/VPFQa8cfJDuT2A1YZruMasgjcltoZszi1dvoIRWSZsFTW42eY2gdOd0nffQ==", + "optional": true, + "requires": { + "@aws-sdk/service-error-classification": "3.347.0", + "tslib": "^2.5.0" } }, "@aws-sdk/util-uri-escape": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.188.0.tgz", - "integrity": "sha512-4Y6AYZMT483Tiuq8dxz5WHIiPNdSFPGrl6tRTo2Oi2FcwypwmFhqgEGcqxeXDUJktvaCBxeA08DLr/AemVhPCg==", + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.310.0.tgz", + "integrity": "sha512-drzt+aB2qo2LgtDoiy/3sVG8w63cgLkqFIa2NFlGpUgHFWTXkqtbgf4L5QdjRGKWhmZsnqkbtL7vkSWEcYDJ4Q==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-user-agent-browser": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.193.0.tgz", - "integrity": "sha512-1EkGYsUtOMEyJG/UBIR4PtmO3lVjKNoUImoMpLtEucoGbWz5RG9zFSwLevjFyFs5roUBFlxkSpTMo8xQ3aRzQg==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.347.0.tgz", + "integrity": "sha512-ydxtsKVtQefgbk1Dku1q7pMkjDYThauG9/8mQkZUAVik55OUZw71Zzr3XO8J8RKvQG8lmhPXuAQ0FKAyycc0RA==", "optional": true, "requires": { - "@aws-sdk/types": "3.193.0", + "@aws-sdk/types": "3.347.0", "bowser": "^2.11.0", - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-user-agent-node": { - "version": "3.193.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.193.0.tgz", - "integrity": "sha512-G/2/1cSgsxVtREAm8Eq8Duib5PXzXknFRHuDpAxJ5++lsJMXoYMReS278KgV54cojOkAVfcODDTqmY3Av0WHhQ==", + "version": "3.347.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.347.0.tgz", + "integrity": "sha512-6X0b9qGsbD1s80PmbaB6v1/ZtLfSx6fjRX8caM7NN0y/ObuLoX8LhYnW6WlB2f1+xb4EjaCNgpP/zCf98MXosw==", "optional": true, "requires": { - "@aws-sdk/node-config-provider": "3.193.0", - "@aws-sdk/types": "3.193.0", - "tslib": "^2.3.1" + "@aws-sdk/node-config-provider": "3.347.0", + "@aws-sdk/types": "3.347.0", + "tslib": "^2.5.0" } }, - "@aws-sdk/util-utf8-browser": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.188.0.tgz", - "integrity": "sha512-jt627x0+jE+Ydr9NwkFstg3cUvgWh56qdaqAMDsqgRlKD21md/6G226z/Qxl7lb1VEW2LlmCx43ai/37Qwcj2Q==", + "@aws-sdk/util-utf8": { + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8/-/util-utf8-3.310.0.tgz", + "integrity": "sha512-DnLfFT8uCO22uOJc0pt0DsSNau1GTisngBCDw8jQuWT5CqogMJu4b/uXmwEqfj8B3GX6Xsz8zOd6JpRlPftQoA==", "optional": true, "requires": { - "tslib": "^2.3.1" + "@aws-sdk/util-buffer-from": "3.310.0", + "tslib": "^2.5.0" } }, - "@aws-sdk/util-utf8-node": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-node/-/util-utf8-node-3.188.0.tgz", - "integrity": "sha512-hCgP4+C0Lekjpjt2zFJ2R/iHes5sBGljXa5bScOFAEkRUc0Qw0VNgTv7LpEbIOAwGmqyxBoCwBW0YHPW1DfmYQ==", + "@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", + "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", "optional": true, "requires": { - "@aws-sdk/util-buffer-from": "3.188.0", "tslib": "^2.3.1" } }, @@ -7938,6 +8152,25 @@ "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, + "@smithy/protocol-http": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-1.0.1.tgz", + "integrity": "sha512-9OrEn0WfOVtBNYJUjUAn9AOiJ4lzERCJJ/JeZs8E6yajTGxBaFRxUnNBHiNqoDJVg076hY36UmEnPx7xXrvUSg==", + "optional": true, + "requires": { + "@smithy/types": "^1.0.0", + "tslib": "^2.5.0" + } + }, + "@smithy/types": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-1.0.0.tgz", + "integrity": "sha512-kc1m5wPBHQCTixwuaOh9vnak/iJm21DrSf9UK6yDE5S3mQQ4u11pqAUiKWnlrZnYkeLfAI9UEHj9OaMT1v5Umg==", + "optional": true, + "requires": { + "tslib": "^2.5.0" + } + }, "@types/node": { "version": "18.11.6", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.6.tgz", @@ -9042,9 +9275,9 @@ "dev": true }, "fast-xml-parser": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.11.tgz", - "integrity": "sha512-4aUg3aNRR/WjQAcpceODG1C3x3lFANXRo8+1biqfieHmg9pyMt7qB4lQV/Ta6sJCTbA5vfD8fnA8S54JATiFUA==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.4.tgz", + "integrity": "sha512-fbfMDvgBNIdDJLdLOwacjFAPYt67tr31H9ZhWSm45CDAxvd0I6WTlSOUo7K2P/K5sA5JgMKG64PI3DMcaFdWpQ==", "optional": true, "requires": { "strnum": "^1.0.5" @@ -11874,9 +12107,9 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", "optional": true }, "tweetnacl": { From 5bfa7aa4314e6fd4c94388378188f28a5e463778 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 4 Jul 2023 10:29:06 +0200 Subject: [PATCH 021/186] added --- .github/workflows/docker-nightly.yml | 41 ++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/workflows/docker-nightly.yml diff --git a/.github/workflows/docker-nightly.yml b/.github/workflows/docker-nightly.yml new file mode 100644 index 0000000..3463f7e --- /dev/null +++ b/.github/workflows/docker-nightly.yml @@ -0,0 +1,41 @@ +name: Publish Docker nightly image + +on: + push: + branches: [dev] + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + steps: + - name: Check out the repo + uses: actions/checkout@v3 + + - name: Use Node.js 16.x + uses: actions/setup-node@v3 + with: + node-version: 16.x + - run: npm ci + - run: npm run build + + - name: Log in to Docker Hub + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: openhaus/backend + + - name: Build and push Docker image + uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 + with: + context: . + file: ./Dockerfile + push: true + tags: openhaus/backend:nightly + labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file From 965aa0449ffda6177cf0475e52ac6b0edf1a82cd Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 4 Jul 2023 10:33:49 +0200 Subject: [PATCH 022/186] Update docker-nightly.yml --- .github/workflows/docker-nightly.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-nightly.yml b/.github/workflows/docker-nightly.yml index 3463f7e..eb4d95d 100644 --- a/.github/workflows/docker-nightly.yml +++ b/.github/workflows/docker-nightly.yml @@ -22,8 +22,8 @@ jobs: - name: Log in to Docker Hub uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta @@ -38,4 +38,4 @@ jobs: file: ./Dockerfile push: true tags: openhaus/backend:nightly - labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file + labels: ${{ steps.meta.outputs.labels }} From c929d889d81076fed7f2d41c63f3e566ab40a7dc Mon Sep 17 00:00:00 2001 From: mStirner Date: Mon, 2 Oct 2023 14:23:25 +0200 Subject: [PATCH 023/186] fix #339 --- components/scenes/class.trigger.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/components/scenes/class.trigger.js b/components/scenes/class.trigger.js index 109deae..3f57e54 100644 --- a/components/scenes/class.trigger.js +++ b/components/scenes/class.trigger.js @@ -19,8 +19,20 @@ module.exports = class Trigger { constructor(obj) { //this.signal = new TriggerSignal(); - this.signal = new EventEmitter(); - this.fired = null; + //this.signal = new EventEmitter(); + //this.fired = null; + + Object.defineProperty(this, "signal", { + value: new EventEmitter(), + writable: false, + enumerable: false + }); + + Object.defineProperty(this, "fired", { + value: null, + writable: true, + enumerable: false + }); Object.assign(this, obj); From 57a4c418aea895cdb74e98c1f6d78c88b23df127 Mon Sep 17 00:00:00 2001 From: mStirner Date: Mon, 2 Oct 2023 14:23:45 +0200 Subject: [PATCH 024/186] notes added --- routes/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/routes/index.js b/routes/index.js index b95a861..cac8f27 100644 --- a/routes/index.js +++ b/routes/index.js @@ -39,6 +39,7 @@ module.exports = (server) => { const api = express.Router(); const logs = express.Router(); const about = express.Router(); + //const system = express.Router(); // https://expressjs.com/en/guide/behind-proxies.html app.set("trust proxy", [ @@ -59,13 +60,18 @@ module.exports = (server) => { require("./router.auth.js")(app, auth); // mount logs router under /api + // TODO move to /system/logs api.use("/logs", logs); require("./router.api.logs.js")(app, logs); // mount logs router under /api + // TODO remove api.use("/about", about); require("./router.api.about.js")(app, about); + //app.use("/system", system); + //require("./router.system.notifications.js")(app, system); + // /api routes (() => { From e3fe10a142033e87989fb30bf133e189acf0778e Mon Sep 17 00:00:00 2001 From: mStirner Date: Mon, 2 Oct 2023 14:29:06 +0200 Subject: [PATCH 025/186] test fix for #341 --- .github/workflows/docker-nightly.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/docker-nightly.yml b/.github/workflows/docker-nightly.yml index eb4d95d..b7517bb 100644 --- a/.github/workflows/docker-nightly.yml +++ b/.github/workflows/docker-nightly.yml @@ -11,6 +11,9 @@ jobs: steps: - name: Check out the repo uses: actions/checkout@v3 + with: + ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} - name: Use Node.js 16.x uses: actions/setup-node@v3 From fa576360852639a43fee9346f357673768b352ef Mon Sep 17 00:00:00 2001 From: mStirner Date: Mon, 2 Oct 2023 14:32:39 +0200 Subject: [PATCH 026/186] test fix #341 --- .github/workflows/docker-nightly.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/docker-nightly.yml b/.github/workflows/docker-nightly.yml index b7517bb..90d4c50 100644 --- a/.github/workflows/docker-nightly.yml +++ b/.github/workflows/docker-nightly.yml @@ -8,12 +8,10 @@ jobs: push_to_registry: name: Push Docker image to Docker Hub runs-on: ubuntu-latest + if: github.repository == 'OpenHausIO/backend' steps: - name: Check out the repo uses: actions/checkout@v3 - with: - ref: ${{github.event.pull_request.head.ref}} - repository: ${{github.event.pull_request.head.repo.full_name}} - name: Use Node.js 16.x uses: actions/setup-node@v3 From b70543acb838943998d84012d2408a1e9e4e4929 Mon Sep 17 00:00:00 2001 From: mStirner Date: Tue, 3 Oct 2023 17:06:24 +0200 Subject: [PATCH 027/186] fix #343 --- components/devices/class.interface.js | 38 ++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/components/devices/class.interface.js b/components/devices/class.interface.js index acc03b1..ce94879 100644 --- a/components/devices/class.interface.js +++ b/components/devices/class.interface.js @@ -1,7 +1,7 @@ const Joi = require("joi"); const { Agent } = require("http"); const mongodb = require("mongodb"); -const { PassThrough, Duplex } = require("stream"); +const { Transform, Duplex } = require("stream"); /** * @description @@ -212,6 +212,9 @@ module.exports = class Interface { console.log(`############## Create connection to tcp://${host}:${port}`); + // cleanup, could be possible be piped from previous "connections" + this.stream.unpipe(); + /* // check if passed host/port matches interface settings? if (host != settings.host || port != settings.port) { @@ -225,8 +228,37 @@ module.exports = class Interface { } */ - let readable = new PassThrough(); - let writable = new PassThrough(); + //let readable = new PassThrough(); + //let writable = new PassThrough(); + + let readable = new Transform({ + transform(chunk, enc, cb) { + + //console.log("[incoming]", chunk.toString()); + + // temp fix for #343 + // this is not the prefered fix for this issue + // it should be handled on "stream/socket" level instead + // the issue above occoured with a "shelly 1pm" and parallel requests to /status /ota /settings + // NOTE: what if the body contains json that has a `connection: close` property/key/value? + chunk = chunk.toString().replace(/connection:\s?close\r\n/i, "connection: keep-alive\r\n"); + + this.push(chunk); + cb(); + + } + }); + + let writable = new Transform({ + transform(chunk, enc, cb) { + + //console.log("[outgoing]", chunk.toString()); + + this.push(chunk); + cb(); + + } + }); // TODO Implement "auto-drain" when no upstream is attached -> Move this "lower", e.g. before ws upstream? From aa17caf86111fbbb137105e475e62f32ad29c6d6 Mon Sep 17 00:00:00 2001 From: mStirner Date: Tue, 3 Oct 2023 22:32:24 +0200 Subject: [PATCH 028/186] updated newman & nodemon --- package-lock.json | 4447 +++++++++++++++++++++++---------------------- package.json | 6 +- 2 files changed, 2308 insertions(+), 2145 deletions(-) diff --git a/package-lock.json b/package-lock.json index 647fa6d..83f6778 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,8 +34,8 @@ "minimist": "^1.2.6", "mocha": "^9.2.2", "mocha.parallel": "^0.15.6", - "newman": "^5.3.2", - "nodemon": "^2.0.19", + "newman": "^6.0.0", + "nodemon": "^3.0.1", "sinon": "^14.0.2" }, "engines": { @@ -145,60 +145,48 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "optional": true }, - "node_modules/@aws-sdk/abort-controller": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.347.0.tgz", - "integrity": "sha512-P/2qE6ntYEmYG4Ez535nJWZbXqgbkJx8CMz7ChEuEg3Gp3dvVYEKg+iEUEvlqQ2U5dWP5J3ehw5po9t86IsVPQ==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.350.0.tgz", - "integrity": "sha512-46AhBvGWo6TEzlvZieNlZHC2w4NJUJA52KfDUtgr8PmChGgxqzlLBAiOpqbDJ83GR3YB6CNEjXxzN5tmyJKICA==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.423.0.tgz", + "integrity": "sha512-9nyilMrihznN7Y6T/dVhbg4YGsdk7szzShoyoSGwofOg61ugobnHbBvh0tPPOQcHhlzXvD8LZdOQ6Kd4KvNp/A==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.350.0", - "@aws-sdk/config-resolver": "3.347.0", - "@aws-sdk/credential-provider-node": "3.350.0", - "@aws-sdk/fetch-http-handler": "3.347.0", - "@aws-sdk/hash-node": "3.347.0", - "@aws-sdk/invalid-dependency": "3.347.0", - "@aws-sdk/middleware-content-length": "3.347.0", - "@aws-sdk/middleware-endpoint": "3.347.0", - "@aws-sdk/middleware-host-header": "3.347.0", - "@aws-sdk/middleware-logger": "3.347.0", - "@aws-sdk/middleware-recursion-detection": "3.347.0", - "@aws-sdk/middleware-retry": "3.347.0", - "@aws-sdk/middleware-serde": "3.347.0", - "@aws-sdk/middleware-signing": "3.347.0", - "@aws-sdk/middleware-stack": "3.347.0", - "@aws-sdk/middleware-user-agent": "3.347.0", - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/node-http-handler": "3.350.0", - "@aws-sdk/smithy-client": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-body-length-browser": "3.310.0", - "@aws-sdk/util-body-length-node": "3.310.0", - "@aws-sdk/util-defaults-mode-browser": "3.347.0", - "@aws-sdk/util-defaults-mode-node": "3.347.0", - "@aws-sdk/util-endpoints": "3.347.0", - "@aws-sdk/util-retry": "3.347.0", - "@aws-sdk/util-user-agent-browser": "3.347.0", - "@aws-sdk/util-user-agent-node": "3.347.0", - "@aws-sdk/util-utf8": "3.310.0", - "@smithy/protocol-http": "^1.0.1", - "@smithy/types": "^1.0.0", + "@aws-sdk/client-sts": "3.423.0", + "@aws-sdk/credential-provider-node": "3.423.0", + "@aws-sdk/middleware-host-header": "3.418.0", + "@aws-sdk/middleware-logger": "3.418.0", + "@aws-sdk/middleware-recursion-detection": "3.418.0", + "@aws-sdk/middleware-signing": "3.418.0", + "@aws-sdk/middleware-user-agent": "3.418.0", + "@aws-sdk/region-config-resolver": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@aws-sdk/util-endpoints": "3.418.0", + "@aws-sdk/util-user-agent-browser": "3.418.0", + "@aws-sdk/util-user-agent-node": "3.418.0", + "@smithy/config-resolver": "^2.0.10", + "@smithy/fetch-http-handler": "^2.1.5", + "@smithy/hash-node": "^2.0.9", + "@smithy/invalid-dependency": "^2.0.9", + "@smithy/middleware-content-length": "^2.0.11", + "@smithy/middleware-endpoint": "^2.0.9", + "@smithy/middleware-retry": "^2.0.12", + "@smithy/middleware-serde": "^2.0.9", + "@smithy/middleware-stack": "^2.0.2", + "@smithy/node-config-provider": "^2.0.12", + "@smithy/node-http-handler": "^2.1.5", + "@smithy/protocol-http": "^3.0.5", + "@smithy/smithy-client": "^2.1.6", + "@smithy/types": "^2.3.3", + "@smithy/url-parser": "^2.0.9", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.1.0", + "@smithy/util-defaults-mode-browser": "^2.0.10", + "@smithy/util-defaults-mode-node": "^2.0.12", + "@smithy/util-retry": "^2.0.2", + "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" }, "engines": { @@ -206,87 +194,44 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.350.0.tgz", - "integrity": "sha512-2vpiv6SEjmQGK3ZueGzvTMG6NenjWp0CHjmda71d1Iqr+tZ2UlfC35+3ioU8JP+jiXLL+y9r+SCer3IC8N/i+Q==", - "optional": true, - "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/config-resolver": "3.347.0", - "@aws-sdk/fetch-http-handler": "3.347.0", - "@aws-sdk/hash-node": "3.347.0", - "@aws-sdk/invalid-dependency": "3.347.0", - "@aws-sdk/middleware-content-length": "3.347.0", - "@aws-sdk/middleware-endpoint": "3.347.0", - "@aws-sdk/middleware-host-header": "3.347.0", - "@aws-sdk/middleware-logger": "3.347.0", - "@aws-sdk/middleware-recursion-detection": "3.347.0", - "@aws-sdk/middleware-retry": "3.347.0", - "@aws-sdk/middleware-serde": "3.347.0", - "@aws-sdk/middleware-stack": "3.347.0", - "@aws-sdk/middleware-user-agent": "3.347.0", - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/node-http-handler": "3.350.0", - "@aws-sdk/smithy-client": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-body-length-browser": "3.310.0", - "@aws-sdk/util-body-length-node": "3.310.0", - "@aws-sdk/util-defaults-mode-browser": "3.347.0", - "@aws-sdk/util-defaults-mode-node": "3.347.0", - "@aws-sdk/util-endpoints": "3.347.0", - "@aws-sdk/util-retry": "3.347.0", - "@aws-sdk/util-user-agent-browser": "3.347.0", - "@aws-sdk/util-user-agent-node": "3.347.0", - "@aws-sdk/util-utf8": "3.310.0", - "@smithy/protocol-http": "^1.0.1", - "@smithy/types": "^1.0.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.350.0.tgz", - "integrity": "sha512-v3UrWIglg9PPzGXqhyGB/qPZ8ifiGM9r4LV8vve1TpiKsUdf1Khtx1eB8yqjNO0vIsYUF+j1C23QT1qAN2DcEA==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.423.0.tgz", + "integrity": "sha512-znIufHkwhCIePgaYciIs3x/+BpzR57CZzbCKHR9+oOvGyufEPPpUT5bFLvbwTgfiVkTjuk6sG/ES3U5Bc+xtrA==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/config-resolver": "3.347.0", - "@aws-sdk/fetch-http-handler": "3.347.0", - "@aws-sdk/hash-node": "3.347.0", - "@aws-sdk/invalid-dependency": "3.347.0", - "@aws-sdk/middleware-content-length": "3.347.0", - "@aws-sdk/middleware-endpoint": "3.347.0", - "@aws-sdk/middleware-host-header": "3.347.0", - "@aws-sdk/middleware-logger": "3.347.0", - "@aws-sdk/middleware-recursion-detection": "3.347.0", - "@aws-sdk/middleware-retry": "3.347.0", - "@aws-sdk/middleware-serde": "3.347.0", - "@aws-sdk/middleware-stack": "3.347.0", - "@aws-sdk/middleware-user-agent": "3.347.0", - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/node-http-handler": "3.350.0", - "@aws-sdk/smithy-client": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-body-length-browser": "3.310.0", - "@aws-sdk/util-body-length-node": "3.310.0", - "@aws-sdk/util-defaults-mode-browser": "3.347.0", - "@aws-sdk/util-defaults-mode-node": "3.347.0", - "@aws-sdk/util-endpoints": "3.347.0", - "@aws-sdk/util-retry": "3.347.0", - "@aws-sdk/util-user-agent-browser": "3.347.0", - "@aws-sdk/util-user-agent-node": "3.347.0", - "@aws-sdk/util-utf8": "3.310.0", - "@smithy/protocol-http": "^1.0.1", - "@smithy/types": "^1.0.0", + "@aws-sdk/middleware-host-header": "3.418.0", + "@aws-sdk/middleware-logger": "3.418.0", + "@aws-sdk/middleware-recursion-detection": "3.418.0", + "@aws-sdk/middleware-user-agent": "3.418.0", + "@aws-sdk/region-config-resolver": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@aws-sdk/util-endpoints": "3.418.0", + "@aws-sdk/util-user-agent-browser": "3.418.0", + "@aws-sdk/util-user-agent-node": "3.418.0", + "@smithy/config-resolver": "^2.0.10", + "@smithy/fetch-http-handler": "^2.1.5", + "@smithy/hash-node": "^2.0.9", + "@smithy/invalid-dependency": "^2.0.9", + "@smithy/middleware-content-length": "^2.0.11", + "@smithy/middleware-endpoint": "^2.0.9", + "@smithy/middleware-retry": "^2.0.12", + "@smithy/middleware-serde": "^2.0.9", + "@smithy/middleware-stack": "^2.0.2", + "@smithy/node-config-provider": "^2.0.12", + "@smithy/node-http-handler": "^2.1.5", + "@smithy/protocol-http": "^3.0.5", + "@smithy/smithy-client": "^2.1.6", + "@smithy/types": "^2.3.3", + "@smithy/url-parser": "^2.0.9", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.1.0", + "@smithy/util-defaults-mode-browser": "^2.0.10", + "@smithy/util-defaults-mode-node": "^2.0.12", + "@smithy/util-retry": "^2.0.2", + "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" }, "engines": { @@ -294,62 +239,48 @@ } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.350.0.tgz", - "integrity": "sha512-s8RsJ6upWQgeUt8GdV3j3ZeTS7BQXedk77RhZ7wzvVwAjO9wow4uS7Iyic4kS3Y/6d26s0MO2vP4bR6HW6U6ZQ==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.423.0.tgz", + "integrity": "sha512-EcpkKu02QZbRX6dQE0u7a8RgWrn/5riz1qAlKd7rM8FZJpr/D6GGX8ZzWxjgp7pRUgfNvinTmIudDnyQY3v9Mg==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/config-resolver": "3.347.0", - "@aws-sdk/credential-provider-node": "3.350.0", - "@aws-sdk/fetch-http-handler": "3.347.0", - "@aws-sdk/hash-node": "3.347.0", - "@aws-sdk/invalid-dependency": "3.347.0", - "@aws-sdk/middleware-content-length": "3.347.0", - "@aws-sdk/middleware-endpoint": "3.347.0", - "@aws-sdk/middleware-host-header": "3.347.0", - "@aws-sdk/middleware-logger": "3.347.0", - "@aws-sdk/middleware-recursion-detection": "3.347.0", - "@aws-sdk/middleware-retry": "3.347.0", - "@aws-sdk/middleware-sdk-sts": "3.347.0", - "@aws-sdk/middleware-serde": "3.347.0", - "@aws-sdk/middleware-signing": "3.347.0", - "@aws-sdk/middleware-stack": "3.347.0", - "@aws-sdk/middleware-user-agent": "3.347.0", - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/node-http-handler": "3.350.0", - "@aws-sdk/smithy-client": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-body-length-browser": "3.310.0", - "@aws-sdk/util-body-length-node": "3.310.0", - "@aws-sdk/util-defaults-mode-browser": "3.347.0", - "@aws-sdk/util-defaults-mode-node": "3.347.0", - "@aws-sdk/util-endpoints": "3.347.0", - "@aws-sdk/util-retry": "3.347.0", - "@aws-sdk/util-user-agent-browser": "3.347.0", - "@aws-sdk/util-user-agent-node": "3.347.0", - "@aws-sdk/util-utf8": "3.310.0", - "@smithy/protocol-http": "^1.0.1", - "@smithy/types": "^1.0.0", - "fast-xml-parser": "4.2.4", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/config-resolver": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.347.0.tgz", - "integrity": "sha512-2ja+Sf/VnUO7IQ3nKbDQ5aumYKKJUaTm/BuVJ29wNho8wYHfuf7wHZV0pDTkB8RF5SH7IpHap7zpZAj39Iq+EA==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-config-provider": "3.310.0", - "@aws-sdk/util-middleware": "3.347.0", + "@aws-sdk/credential-provider-node": "3.423.0", + "@aws-sdk/middleware-host-header": "3.418.0", + "@aws-sdk/middleware-logger": "3.418.0", + "@aws-sdk/middleware-recursion-detection": "3.418.0", + "@aws-sdk/middleware-sdk-sts": "3.418.0", + "@aws-sdk/middleware-signing": "3.418.0", + "@aws-sdk/middleware-user-agent": "3.418.0", + "@aws-sdk/region-config-resolver": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@aws-sdk/util-endpoints": "3.418.0", + "@aws-sdk/util-user-agent-browser": "3.418.0", + "@aws-sdk/util-user-agent-node": "3.418.0", + "@smithy/config-resolver": "^2.0.10", + "@smithy/fetch-http-handler": "^2.1.5", + "@smithy/hash-node": "^2.0.9", + "@smithy/invalid-dependency": "^2.0.9", + "@smithy/middleware-content-length": "^2.0.11", + "@smithy/middleware-endpoint": "^2.0.9", + "@smithy/middleware-retry": "^2.0.12", + "@smithy/middleware-serde": "^2.0.9", + "@smithy/middleware-stack": "^2.0.2", + "@smithy/node-config-provider": "^2.0.12", + "@smithy/node-http-handler": "^2.1.5", + "@smithy/protocol-http": "^3.0.5", + "@smithy/smithy-client": "^2.1.6", + "@smithy/types": "^2.3.3", + "@smithy/url-parser": "^2.0.9", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.1.0", + "@smithy/util-defaults-mode-browser": "^2.0.10", + "@smithy/util-defaults-mode-node": "^2.0.12", + "@smithy/util-retry": "^2.0.2", + "@smithy/util-utf8": "^2.0.0", + "fast-xml-parser": "4.2.5", "tslib": "^2.5.0" }, "engines": { @@ -357,14 +288,15 @@ } }, "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.351.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.351.0.tgz", - "integrity": "sha512-c9XyDUj82ttqQqF8h4Ie7k2Fl3bMh8/yBGEQWIPzWRhfy40m4ChqjilKAcBeoxR/w4Qp3RsdDfLRTLC8sJTpIg==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.423.0.tgz", + "integrity": "sha512-FuuCOeUkAn3tZU2GUN3eUjs4AC88t5je4N5/NVbTaSN0e2FGf9PnN5nrwTKwaOGVLSe6/FvfudW01LZ/+PRQOQ==", "optional": true, "dependencies": { - "@aws-sdk/client-cognito-identity": "3.350.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@aws-sdk/client-cognito-identity": "3.423.0", + "@aws-sdk/types": "3.418.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" }, "engines": { @@ -372,29 +304,32 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.347.0.tgz", - "integrity": "sha512-UnEM+LKGpXKzw/1WvYEQsC6Wj9PupYZdQOE+e2Dgy2dqk/pVFy4WueRtFXYDT2B41ppv3drdXUuKZRIDVqIgNQ==", + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.418.0.tgz", + "integrity": "sha512-e74sS+x63EZUBO+HaI8zor886YdtmULzwKdctsZp5/37Xho1CVUNtEC+fYa69nigBD9afoiH33I4JggaHgrekQ==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@aws-sdk/types": "3.418.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/credential-provider-imds": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.347.0.tgz", - "integrity": "sha512-7scCy/DCDRLIhlqTxff97LQWDnRwRXji3bxxMg+xWOTTaJe7PWx+etGSbBWaL42vsBHFShQjSLvJryEgoBktpw==", + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.423.0.tgz", + "integrity": "sha512-y/mutbiCU/4HGN/ChcNBhPaXo4pgg6lAcWyuMTSSfAR03hjoXe1cMwbPcUiEwzQrZ/+1yufLpZhmoiAWsgAkNw==", "optional": true, "dependencies": { - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", + "@aws-sdk/types": "3.418.0", + "@smithy/fetch-http-handler": "^2.1.5", + "@smithy/node-http-handler": "^2.1.5", + "@smithy/property-provider": "^2.0.0", + "@smithy/protocol-http": "^3.0.5", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" }, "engines": { @@ -402,19 +337,20 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.350.0.tgz", - "integrity": "sha512-mGGU0PpnG0VDNKSuGi083U1egjprrU9/XoRtgf+iYvAKXRR/0XA4pGW5c7zpHY7m4iLhBuRj6N4oxQsH9cMtWg==", - "optional": true, - "dependencies": { - "@aws-sdk/credential-provider-env": "3.347.0", - "@aws-sdk/credential-provider-imds": "3.347.0", - "@aws-sdk/credential-provider-process": "3.347.0", - "@aws-sdk/credential-provider-sso": "3.350.0", - "@aws-sdk/credential-provider-web-identity": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/types": "3.347.0", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.423.0.tgz", + "integrity": "sha512-7CsFWz8g7dQmblp57XzzxMirO4ClowGZIOwAheBkmk6q1XHbllcHFnbh2kdPyQQ0+JmjDg6waztIc7dY7Ycfvw==", + "optional": true, + "dependencies": { + "@aws-sdk/credential-provider-env": "3.418.0", + "@aws-sdk/credential-provider-process": "3.418.0", + "@aws-sdk/credential-provider-sso": "3.423.0", + "@aws-sdk/credential-provider-web-identity": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@smithy/credential-provider-imds": "^2.0.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" }, "engines": { @@ -422,20 +358,21 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.350.0.tgz", - "integrity": "sha512-xmqwCFwj/CZPx6AKHNb24Kpr0eHW9VISt9r+SfgH8PaYg5cNyX1pKmMbQCket5ov+WvHEQtOK7aBafak7dhauA==", - "optional": true, - "dependencies": { - "@aws-sdk/credential-provider-env": "3.347.0", - "@aws-sdk/credential-provider-imds": "3.347.0", - "@aws-sdk/credential-provider-ini": "3.350.0", - "@aws-sdk/credential-provider-process": "3.347.0", - "@aws-sdk/credential-provider-sso": "3.350.0", - "@aws-sdk/credential-provider-web-identity": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/types": "3.347.0", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.423.0.tgz", + "integrity": "sha512-lygbGJJUnDpgo8OEqdoYd51BKkyBVQ1Catiua/m0aHvL+SCmVrHiYPQPawWYGxpH8X3DXdXa0nd0LkEaevrHRg==", + "optional": true, + "dependencies": { + "@aws-sdk/credential-provider-env": "3.418.0", + "@aws-sdk/credential-provider-ini": "3.423.0", + "@aws-sdk/credential-provider-process": "3.418.0", + "@aws-sdk/credential-provider-sso": "3.423.0", + "@aws-sdk/credential-provider-web-identity": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@smithy/credential-provider-imds": "^2.0.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" }, "engines": { @@ -443,14 +380,15 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.347.0.tgz", - "integrity": "sha512-yl1z4MsaBdXd4GQ2halIvYds23S67kElyOwz7g8kaQ4kHj+UoYWxz3JVW/DGusM6XmQ9/F67utBrUVA0uhQYyw==", + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.418.0.tgz", + "integrity": "sha512-xPbdm2WKz1oH6pTkrJoUmr3OLuqvvcPYTQX0IIlc31tmDwDWPQjXGGFD/vwZGIZIkKaFpFxVMgAzfFScxox7dw==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@aws-sdk/types": "3.418.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" }, "engines": { @@ -458,16 +396,17 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.350.0.tgz", - "integrity": "sha512-u/3kv+PJeVawzBtWBei+IX1/z50mwhpPe3VrKSTns4CPUw8b5sqIYWkAaw5hxm0td69+xcL98RzIJsEpJc4QSQ==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.423.0.tgz", + "integrity": "sha512-zAH68IjRMmW22USbsCVQ5Q6AHqhmWABwLbZAMocSGMasddTGv/nkA/nUiVCJ/B4LI3P81FoPQVrG5JxNmkNH0w==", "optional": true, "dependencies": { - "@aws-sdk/client-sso": "3.350.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/token-providers": "3.350.0", - "@aws-sdk/types": "3.347.0", + "@aws-sdk/client-sso": "3.423.0", + "@aws-sdk/token-providers": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" }, "engines": { @@ -475,13 +414,14 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.347.0.tgz", - "integrity": "sha512-DxoTlVK8lXjS1zVphtz/Ab+jkN/IZor9d6pP2GjJHNoAIIzXfRwwj5C8vr4eTayx/5VJ7GRP91J8GJ2cKly8Qw==", + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.418.0.tgz", + "integrity": "sha512-do7ang565n9p3dS1JdsQY01rUfRx8vkxQqz5M8OlcEHBNiCdi2PvSjNwcBdrv/FKkyIxZb0TImOfBSt40hVdxQ==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@aws-sdk/types": "3.418.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" }, "engines": { @@ -489,465 +429,670 @@ } }, "node_modules/@aws-sdk/credential-providers": { - "version": "3.351.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.351.0.tgz", - "integrity": "sha512-KVfLTVpeDKnOPl0u5w3RJdNz+AtFIOj3dsfpyLkGCV5bHClLN05YFf1ajh93Z5FijuhvDSYuLT1Xr3Ud+AIudQ==", - "optional": true, - "dependencies": { - "@aws-sdk/client-cognito-identity": "3.350.0", - "@aws-sdk/client-sso": "3.350.0", - "@aws-sdk/client-sts": "3.350.0", - "@aws-sdk/credential-provider-cognito-identity": "3.351.0", - "@aws-sdk/credential-provider-env": "3.347.0", - "@aws-sdk/credential-provider-imds": "3.347.0", - "@aws-sdk/credential-provider-ini": "3.350.0", - "@aws-sdk/credential-provider-node": "3.350.0", - "@aws-sdk/credential-provider-process": "3.347.0", - "@aws-sdk/credential-provider-sso": "3.350.0", - "@aws-sdk/credential-provider-web-identity": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.423.0.tgz", + "integrity": "sha512-jsjIrnu+bVUz2lekcg9wxpPlO8jWd9q26MP/rRwdkm9LHqroICjZY7tIYqSJliVkeSyJHJ9pq/jNDceWhy6a0A==", + "optional": true, + "dependencies": { + "@aws-sdk/client-cognito-identity": "3.423.0", + "@aws-sdk/client-sso": "3.423.0", + "@aws-sdk/client-sts": "3.423.0", + "@aws-sdk/credential-provider-cognito-identity": "3.423.0", + "@aws-sdk/credential-provider-env": "3.418.0", + "@aws-sdk/credential-provider-http": "3.423.0", + "@aws-sdk/credential-provider-ini": "3.423.0", + "@aws-sdk/credential-provider-node": "3.423.0", + "@aws-sdk/credential-provider-process": "3.418.0", + "@aws-sdk/credential-provider-sso": "3.423.0", + "@aws-sdk/credential-provider-web-identity": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@smithy/credential-provider-imds": "^2.0.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/eventstream-codec": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-codec/-/eventstream-codec-3.347.0.tgz", - "integrity": "sha512-61q+SyspjsaQ4sdgjizMyRgVph2CiW4aAtfpoH69EJFJfTxTR/OqnZ9Jx/3YiYi0ksrvDenJddYodfWWJqD8/w==", - "optional": true, - "dependencies": { - "@aws-crypto/crc32": "3.0.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-hex-encoding": "3.310.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/fetch-http-handler": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.347.0.tgz", - "integrity": "sha512-sQ5P7ivY8//7wdxfA76LT1sF6V2Tyyz1qF6xXf9sihPN5Q1Y65c+SKpMzXyFSPqWZ82+SQQuDliYZouVyS6kQQ==", - "optional": true, - "dependencies": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/querystring-builder": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-base64": "3.310.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/hash-node": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.347.0.tgz", - "integrity": "sha512-96+ml/4EaUaVpzBdOLGOxdoXOjkPgkoJp/0i1fxOJEvl8wdAQSwc3IugVK9wZkCxy2DlENtgOe6DfIOhfffm/g==", + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.418.0.tgz", + "integrity": "sha512-LrMTdzalkPw/1ujLCKPLwCGvPMCmT4P+vOZQRbSEVZPnlZk+Aj++aL/RaHou0jL4kJH3zl8iQepriBt4a7UvXQ==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-buffer-from": "3.310.0", - "@aws-sdk/util-utf8": "3.310.0", + "@aws-sdk/types": "3.418.0", + "@smithy/protocol-http": "^3.0.5", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/invalid-dependency": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.347.0.tgz", - "integrity": "sha512-8imQcwLwqZ/wTJXZqzXT9pGLIksTRckhGLZaXT60tiBOPKuerTsus2L59UstLs5LP8TKaVZKFFSsjRIn9dQdmQ==", - "optional": true, - "dependencies": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/is-array-buffer": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.310.0.tgz", - "integrity": "sha512-urnbcCR+h9NWUnmOtet/s4ghvzsidFmspfhYaHAmSRdy9yDjdjBJMFjjsn85A1ODUktztm+cVncXjQ38WCMjMQ==", + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.418.0.tgz", + "integrity": "sha512-StKGmyPVfoO/wdNTtKemYwoJsqIl4l7oqarQY7VSf2Mp3mqaa+njLViHsQbirYpyqpgUEusOnuTlH5utxJ1NsQ==", "optional": true, "dependencies": { + "@aws-sdk/types": "3.418.0", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/middleware-content-length": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.347.0.tgz", - "integrity": "sha512-i4qtWTDImMaDUtwKQPbaZpXsReiwiBomM1cWymCU4bhz81HL01oIxOxOBuiM+3NlDoCSPr3KI6txZSz/8cqXCQ==", + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.418.0.tgz", + "integrity": "sha512-kKFrIQglBLUFPbHSDy1+bbe3Na2Kd70JSUC3QLMbUHmqipXN8KeXRfAj7vTv97zXl0WzG0buV++WcNwOm1rFjg==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@aws-sdk/types": "3.418.0", + "@smithy/protocol-http": "^3.0.5", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/middleware-endpoint": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.347.0.tgz", - "integrity": "sha512-unF0c6dMaUL1ffU+37Ugty43DgMnzPWXr/Jup/8GbK5fzzWT5NQq6dj9KHPubMbWeEjQbmczvhv25JuJdK8gNQ==", + "node_modules/@aws-sdk/middleware-sdk-sts": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.418.0.tgz", + "integrity": "sha512-cW8ijrCTP+mgihvcq4+TbhAcE/we5lFl4ydRqvTdtcSnYQAVQADg47rnTScQiFsPFEB3NKq7BGeyTJF9MKolPA==", "optional": true, "dependencies": { - "@aws-sdk/middleware-serde": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "@aws-sdk/util-middleware": "3.347.0", + "@aws-sdk/middleware-signing": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.347.0.tgz", - "integrity": "sha512-kpKmR9OvMlnReqp5sKcJkozbj1wmlblbVSbnQAIkzeQj2xD5dnVR3Nn2ogQKxSmU1Fv7dEroBtrruJ1o3fY38A==", + "node_modules/@aws-sdk/middleware-signing": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.418.0.tgz", + "integrity": "sha512-onvs5KoYQE8OlOE740RxWBGtsUyVIgAo0CzRKOQO63ZEYqpL1Os+MS1CGzdNhvQnJgJruE1WW+Ix8fjN30zKPA==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@aws-sdk/types": "3.418.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/protocol-http": "^3.0.5", + "@smithy/signature-v4": "^2.0.0", + "@smithy/types": "^2.3.3", + "@smithy/util-middleware": "^2.0.2", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/middleware-logger": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.347.0.tgz", - "integrity": "sha512-NYC+Id5UCkVn+3P1t/YtmHt75uED06vwaKyxDy0UmB2K66PZLVtwWbLpVWrhbroaw1bvUHYcRyQ9NIfnVcXQjA==", + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.418.0.tgz", + "integrity": "sha512-Jdcztg9Tal9SEAL0dKRrnpKrm6LFlWmAhvuwv0dQ7bNTJxIxyEFbpqdgy7mpQHsLVZgq1Aad/7gT/72c9igyZw==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.347.0", + "@aws-sdk/types": "3.418.0", + "@aws-sdk/util-endpoints": "3.418.0", + "@smithy/protocol-http": "^3.0.5", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.347.0.tgz", - "integrity": "sha512-qfnSvkFKCAMjMHR31NdsT0gv5Sq/ZHTUD4yQsSLpbVQ6iYAS834lrzXt41iyEHt57Y514uG7F/Xfvude3u4icQ==", + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.418.0.tgz", + "integrity": "sha512-lJRZ/9TjZU6yLz+mAwxJkcJZ6BmyYoIJVo1p5+BN//EFdEmC8/c0c9gXMRzfISV/mqWSttdtccpAyN4/goHTYA==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@smithy/node-config-provider": "^2.0.12", + "@smithy/types": "^2.3.3", + "@smithy/util-config-provider": "^2.0.0", + "@smithy/util-middleware": "^2.0.2", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/middleware-retry": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.347.0.tgz", - "integrity": "sha512-CpdM+8dCSbX96agy4FCzOfzDmhNnGBM/pxrgIVLm5nkYTLuXp/d7ubpFEUHULr+4hCd5wakHotMt7yO29NFaVw==", + "node_modules/@aws-sdk/token-providers": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.418.0.tgz", + "integrity": "sha512-9P7Q0VN0hEzTngy3Sz5eya2qEOEf0Q8qf1vB3um0gE6ID6EVAdz/nc/DztfN32MFxk8FeVBrCP5vWdoOzmd72g==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/service-error-classification": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-middleware": "3.347.0", - "@aws-sdk/util-retry": "3.347.0", - "tslib": "^2.5.0", - "uuid": "^8.3.2" + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/middleware-host-header": "3.418.0", + "@aws-sdk/middleware-logger": "3.418.0", + "@aws-sdk/middleware-recursion-detection": "3.418.0", + "@aws-sdk/middleware-user-agent": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@aws-sdk/util-endpoints": "3.418.0", + "@aws-sdk/util-user-agent-browser": "3.418.0", + "@aws-sdk/util-user-agent-node": "3.418.0", + "@smithy/config-resolver": "^2.0.10", + "@smithy/fetch-http-handler": "^2.1.5", + "@smithy/hash-node": "^2.0.9", + "@smithy/invalid-dependency": "^2.0.9", + "@smithy/middleware-content-length": "^2.0.11", + "@smithy/middleware-endpoint": "^2.0.9", + "@smithy/middleware-retry": "^2.0.12", + "@smithy/middleware-serde": "^2.0.9", + "@smithy/middleware-stack": "^2.0.2", + "@smithy/node-config-provider": "^2.0.12", + "@smithy/node-http-handler": "^2.1.5", + "@smithy/property-provider": "^2.0.0", + "@smithy/protocol-http": "^3.0.5", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/smithy-client": "^2.1.6", + "@smithy/types": "^2.3.3", + "@smithy/url-parser": "^2.0.9", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.1.0", + "@smithy/util-defaults-mode-browser": "^2.0.10", + "@smithy/util-defaults-mode-node": "^2.0.12", + "@smithy/util-retry": "^2.0.2", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/middleware-retry/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "optional": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/@aws-sdk/middleware-sdk-sts": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.347.0.tgz", - "integrity": "sha512-38LJ0bkIoVF3W97x6Jyyou72YV9Cfbml4OaDEdnrCOo0EssNZM5d7RhjMvQDwww7/3OBY/BzeOcZKfJlkYUXGw==", + "node_modules/@aws-sdk/types": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.418.0.tgz", + "integrity": "sha512-y4PQSH+ulfFLY0+FYkaK4qbIaQI9IJNMO2xsxukW6/aNoApNymN1D2FSi2la8Qbp/iPjNDKsG8suNPm9NtsWXQ==", "optional": true, "dependencies": { - "@aws-sdk/middleware-signing": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/middleware-serde": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.347.0.tgz", - "integrity": "sha512-x5Foi7jRbVJXDu9bHfyCbhYDH5pKK+31MmsSJ3k8rY8keXLBxm2XEEg/AIoV9/TUF9EeVvZ7F1/RmMpJnWQsEg==", + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.418.0.tgz", + "integrity": "sha512-sYSDwRTl7yE7LhHkPzemGzmIXFVHSsi3AQ1KeNEk84eBqxMHHcCc2kqklaBk2roXWe50QDgRMy1ikZUxvtzNHQ==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.347.0", + "@aws-sdk/types": "3.418.0", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/middleware-signing": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.347.0.tgz", - "integrity": "sha512-zVBF/4MGKnvhAE/J+oAL/VAehiyv+trs2dqSQXwHou9j8eA8Vm8HS2NdOwpkZQchIxTuwFlqSusDuPEdYFbvGw==", + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz", + "integrity": "sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/signature-v4": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-middleware": "3.347.0", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/middleware-stack": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.347.0.tgz", - "integrity": "sha512-Izidg4rqtYMcKuvn2UzgEpPLSmyd8ub9+LQ2oIzG3mpIzCBITq7wp40jN1iNkMg+X6KEnX9vdMJIYZsPYMCYuQ==", + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.418.0.tgz", + "integrity": "sha512-c4p4mc0VV/jIeNH0lsXzhJ1MpWRLuboGtNEpqE4s1Vl9ck2amv9VdUUZUmHbg+bVxlMgRQ4nmiovA4qIrqGuyg==", "optional": true, "dependencies": { + "@aws-sdk/types": "3.418.0", + "@smithy/types": "^2.3.3", + "bowser": "^2.11.0", "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.347.0.tgz", - "integrity": "sha512-wJbGN3OE1/daVCrwk49whhIr9E0j1N4gWwN/wi4WuyYIA+5lMUfVp0aGIOvZR+878DxuFz2hQ4XcZVT4K2WvQw==", + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.418.0.tgz", + "integrity": "sha512-BXMskXFtg+dmzSCgmnWOffokxIbPr1lFqa1D9kvM3l3IFRiFGx2IyDg+8MAhq11aPDLvoa/BDuQ0Yqma5izOhg==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-endpoints": "3.347.0", + "@aws-sdk/types": "3.418.0", + "@smithy/node-config-provider": "^2.0.12", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } } }, - "node_modules/@aws-sdk/node-config-provider": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.347.0.tgz", - "integrity": "sha512-faU93d3+5uTTUcotGgMXF+sJVFjrKh+ufW+CzYKT4yUHammyaIab/IbTPWy2hIolcEGtuPeVoxXw8TXbkh/tuw==", + "node_modules/@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", + "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" + "tslib": "^2.3.1" } }, - "node_modules/@aws-sdk/node-http-handler": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.350.0.tgz", - "integrity": "sha512-oD96GAlmpzYilCdC8wwyURM5lNfNHZCjm/kxBkQulHKa2kRbIrnD9GfDqdCkWA5cTpjh1NzGLT4D6e6UFDjt9w==", + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, "optional": true, - "dependencies": { - "@aws-sdk/abort-controller": "3.347.0", - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/querystring-builder": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - }, "engines": { - "node": ">=14.0.0" + "node": ">=0.1.90" } }, - "node_modules/@aws-sdk/property-provider": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.347.0.tgz", - "integrity": "sha512-t3nJ8CYPLKAF2v9nIHOHOlF0CviQbTvbFc2L4a+A+EVd/rM4PzL3+3n8ZJsr0h7f6uD04+b5YRFgKgnaqLXlEg==", - "optional": true, + "node_modules/@eslint/eslintrc": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "dev": true, "dependencies": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=14.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@aws-sdk/protocol-http": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.347.0.tgz", - "integrity": "sha512-2YdBhc02Wvy03YjhGwUxF0UQgrPWEy8Iq75pfS42N+/0B/+eWX1aQgfjFxIpLg7YSjT5eKtYOQGlYd4MFTgj9g==", - "optional": true, + "node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "dependencies": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" + "ms": "2.1.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@aws-sdk/querystring-builder": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.347.0.tgz", - "integrity": "sha512-phtKTe6FXoV02MoPkIVV6owXI8Mwr5IBN3bPoxhcPvJG2AjEmnetSIrhb8kwc4oNhlwfZwH6Jo5ARW/VEWbZtg==", - "optional": true, + "node_modules/@eslint/eslintrc/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@faker-js/faker": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-5.5.3.tgz", + "integrity": "sha512-R11tGE6yIFwqpaIqcfkcg7AICXzFg14+5h5v0TfF/9+RMDL6jhzCy/pxHVOfbALGdtVYdt6JdR21tuxEgl34dw==", + "dev": true + }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", "dependencies": { - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-uri-escape": "3.310.0", - "tslib": "^2.5.0" + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", + "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" }, "engines": { - "node": ">=14.0.0" + "node": ">=10.10.0" } }, - "node_modules/@aws-sdk/querystring-parser": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.347.0.tgz", - "integrity": "sha512-5VXOhfZz78T2W7SuXf2avfjKglx1VZgZgp9Zfhrt/Rq+MTu2D+PZc5zmJHhYigD7x83jLSLogpuInQpFMA9LgA==", - "optional": true, + "node_modules/@humanwhocodes/config-array/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "dependencies": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" + "ms": "2.1.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@aws-sdk/service-error-classification": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.347.0.tgz", - "integrity": "sha512-xZ3MqSY81Oy2gh5g0fCtooAbahqh9VhsF8vcKjVX8+XPbGC8y+kej82+MsMg4gYL8gRFB9u4hgYbNgIS6JTAvg==", - "optional": true, + "node_modules/@humanwhocodes/config-array/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, "engines": { - "node": ">=14.0.0" + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@aws-sdk/shared-ini-file-loader": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.347.0.tgz", - "integrity": "sha512-Xw+zAZQVLb+xMNHChXQ29tzzLqm3AEHsD8JJnlkeFjeMnWQtXdUfOARl5s8NzAppcKQNlVe2gPzjaKjoy2jz1Q==", - "optional": true, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", + "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==", "dependencies": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" }, - "engines": { - "node": ">=14.0.0" + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" } }, - "node_modules/@aws-sdk/signature-v4": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.347.0.tgz", - "integrity": "sha512-58Uq1do+VsTHYkP11dTK+DF53fguoNNJL9rHRWhzP+OcYv3/mBMLoS2WPz/x9FO5mBg4ESFsug0I6mXbd36tjw==", + "node_modules/@mongodb-js/saslprep": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.0.tgz", + "integrity": "sha512-Xfijy7HvfzzqiOAhAepF4SGN5e9leLkMvg/OPOF97XemjfVCYN/oWa75wnkc6mltMSTwY+XlbhWgUOJmkFspSw==", "optional": true, "dependencies": { - "@aws-sdk/eventstream-codec": "3.347.0", - "@aws-sdk/is-array-buffer": "3.310.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-hex-encoding": "3.310.0", - "@aws-sdk/util-middleware": "3.347.0", - "@aws-sdk/util-uri-escape": "3.310.0", - "@aws-sdk/util-utf8": "3.310.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" + "sparse-bitfield": "^3.0.3" } }, - "node_modules/@aws-sdk/smithy-client": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.347.0.tgz", - "integrity": "sha512-PaGTDsJLGK0sTjA6YdYQzILRlPRN3uVFyqeBUkfltXssvUzkm8z2t1lz2H4VyJLAhwnG5ZuZTNEV/2mcWrU7JQ==", - "optional": true, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, "dependencies": { - "@aws-sdk/middleware-stack": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": ">=14.0.0" + "node": ">= 8" } }, - "node_modules/@aws-sdk/token-providers": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.350.0.tgz", - "integrity": "sha512-VIfVMV5An1VQQ6bOKQTHPsRFHD3/YRGOPk9lDTVJGOK0G1DIFYd/10ZaLQ86rCWLck2lGhjxsOen2N2n6MtA0A==", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@postman/form-data": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@postman/form-data/-/form-data-3.1.1.tgz", + "integrity": "sha512-vjh8Q2a8S6UCm/KKs31XFJqEEgmbjBmpPNVV2eVav6905wyFAwaUOBGA1NPBI4ERH9MMZc6w0umFgM6WbEPMdg==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@postman/tough-cookie": { + "version": "4.1.3-postman.1", + "resolved": "https://registry.npmjs.org/@postman/tough-cookie/-/tough-cookie-4.1.3-postman.1.tgz", + "integrity": "sha512-txpgUqZOnWYnUHZpHjkfb0IwVH4qJmyq77pPnJLlfhMtdCLMFTEeQHlzQiK906aaNCe4NEB5fGJHo9uzGbFMeA==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@postman/tunnel-agent": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@postman/tunnel-agent/-/tunnel-agent-0.6.3.tgz", + "integrity": "sha512-k57fzmAZ2PJGxfOA4SGR05ejorHbVAa/84Hxh/2nAztjNXc4ZjOm9NUIk6/Z6LCrBvJZqjRZbN8e/nROVUPVdg==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@sideway/address": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", + "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, + "node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.5.tgz", + "integrity": "sha512-rTpCA0wG1wUxglBSFdMMY0oTrKYvgf4fNgv/sXbfCVAdf+FnPBdKJR/7XbpTCwbCrvCbdPYnlWaUUYz4V2fPDA==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-7.0.1.tgz", + "integrity": "sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "dev": true + }, + "node_modules/@smithy/abort-controller": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.10.tgz", + "integrity": "sha512-xn7PnFD3m4rQIG00h1lPuDVnC2QMtTFhzRLX3y56KkgFaCysS7vpNevNBgmNUtmJ4eVFc+66Zucwo2KDLdicOg==", "optional": true, "dependencies": { - "@aws-sdk/client-sso-oidc": "3.350.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/types": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.347.0.tgz", - "integrity": "sha512-GkCMy79mdjU9OTIe5KT58fI/6uqdf8UmMdWqVHmFJ+UpEzOci7L/uw4sOXWo7xpPzLs6cJ7s5ouGZW4GRPmHFA==", + "node_modules/@smithy/config-resolver": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.0.11.tgz", + "integrity": "sha512-q97FnlUmbai1c4JlQJgLVBsvSxgV/7Nvg/JK76E1nRq/U5UM56Eqo3dn2fY7JibqgJLg4LPsGdwtIyqyOk35CQ==", + "optional": true, + "dependencies": { + "@smithy/node-config-provider": "^2.0.13", + "@smithy/types": "^2.3.4", + "@smithy/util-config-provider": "^2.0.0", + "@smithy/util-middleware": "^2.0.3", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.0.13.tgz", + "integrity": "sha512-/xe3wNoC4j+BeTemH9t2gSKLBfyZmk8LXB2pQm/TOEYi+QhBgT+PSolNDfNAhrR68eggNE17uOimsrnwSkCt4w==", "optional": true, "dependencies": { + "@smithy/node-config-provider": "^2.0.13", + "@smithy/property-provider": "^2.0.11", + "@smithy/types": "^2.3.4", + "@smithy/url-parser": "^2.0.10", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/url-parser": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.347.0.tgz", - "integrity": "sha512-lhrnVjxdV7hl+yCnJfDZOaVLSqKjxN20MIOiijRiqaWGLGEAiSqBreMhL89X1WKCifxAs4zZf9YB9SbdziRpAA==", + "node_modules/@smithy/eventstream-codec": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.0.10.tgz", + "integrity": "sha512-3SSDgX2nIsFwif6m+I4+ar4KDcZX463Noes8ekBgQHitULiWvaDZX8XqPaRQSQ4bl1vbeVXHklJfv66MnVO+lw==", "optional": true, "dependencies": { - "@aws-sdk/querystring-parser": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@aws-crypto/crc32": "3.0.0", + "@smithy/types": "^2.3.4", + "@smithy/util-hex-encoding": "^2.0.0", "tslib": "^2.5.0" } }, - "node_modules/@aws-sdk/util-base64": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64/-/util-base64-3.310.0.tgz", - "integrity": "sha512-v3+HBKQvqgdzcbL+pFswlx5HQsd9L6ZTlyPVL2LS9nNXnCcR3XgGz9jRskikRUuUvUXtkSG1J88GAOnJ/apTPg==", + "node_modules/@smithy/fetch-http-handler": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.2.1.tgz", + "integrity": "sha512-bXyM8PBAIKxVV++2ZSNBEposTDjFQ31XWOdHED+2hWMNvJHUoQqFbECg/uhcVOa6vHie2/UnzIZfXBSTpDBnEw==", "optional": true, "dependencies": { - "@aws-sdk/util-buffer-from": "3.310.0", + "@smithy/protocol-http": "^3.0.6", + "@smithy/querystring-builder": "^2.0.10", + "@smithy/types": "^2.3.4", + "@smithy/util-base64": "^2.0.0", + "tslib": "^2.5.0" + } + }, + "node_modules/@smithy/hash-node": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.0.10.tgz", + "integrity": "sha512-jSTf6uzPk/Vf+8aQ7tVXeHfjxe9wRXSCqIZcBymSDTf7/YrVxniBdpyN74iI8ZUOx/Pyagc81OK5FROLaEjbXQ==", + "optional": true, + "dependencies": { + "@smithy/types": "^2.3.4", + "@smithy/util-buffer-from": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-body-length-browser": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.310.0.tgz", - "integrity": "sha512-sxsC3lPBGfpHtNTUoGXMQXLwjmR0zVpx0rSvzTPAuoVILVsp5AU/w5FphNPxD5OVIjNbZv9KsKTuvNTiZjDp9g==", + "node_modules/@smithy/invalid-dependency": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.0.10.tgz", + "integrity": "sha512-zw9p/zsmJ2cFcW4KMz3CJoznlbRvEA6HG2mvEaX5eAca5dq4VGI2MwPDTfmteC/GsnURS4ogoMQ0p6aHM2SDVQ==", "optional": true, "dependencies": { + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" } }, - "node_modules/@aws-sdk/util-body-length-node": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.310.0.tgz", - "integrity": "sha512-2tqGXdyKhyA6w4zz7UPoS8Ip+7sayOg9BwHNidiGm2ikbDxm1YrCfYXvCBdwaJxa4hJfRVz+aL9e+d3GqPI9pQ==", + "node_modules/@smithy/is-array-buffer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.0.0.tgz", + "integrity": "sha512-z3PjFjMyZNI98JFRJi/U0nGoLWMSJlDjAW4QUX2WNZLas5C0CmVV6LJ01JI0k90l7FvpmixjWxPFmENSClQ7ug==", "optional": true, "dependencies": { "tslib": "^2.5.0" @@ -956,473 +1101,426 @@ "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-buffer-from": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.310.0.tgz", - "integrity": "sha512-i6LVeXFtGih5Zs8enLrt+ExXY92QV25jtEnTKHsmlFqFAuL3VBeod6boeMXkN2p9lbSVVQ1sAOOYZOHYbYkntw==", + "node_modules/@smithy/middleware-content-length": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.0.12.tgz", + "integrity": "sha512-QRhJTo5TjG7oF7np6yY4ZO9GDKFVzU/GtcqUqyEa96bLHE3yZHgNmsolOQ97pfxPHmFhH4vDP//PdpAIN3uI1Q==", "optional": true, "dependencies": { - "@aws-sdk/is-array-buffer": "3.310.0", + "@smithy/protocol-http": "^3.0.6", + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-config-provider": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.310.0.tgz", - "integrity": "sha512-xIBaYo8dwiojCw8vnUcIL4Z5tyfb1v3yjqyJKJWV/dqKUFOOS0U591plmXbM+M/QkXyML3ypon1f8+BoaDExrg==", + "node_modules/@smithy/middleware-endpoint": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.0.10.tgz", + "integrity": "sha512-O6m4puZc16xfenotZUHL4bRlMrwf4gTp+0I5l954M5KNd3dOK18P+FA/IIUgnXF/dX6hlCUcJkBp7nAzwrePKA==", "optional": true, "dependencies": { + "@smithy/middleware-serde": "^2.0.10", + "@smithy/types": "^2.3.4", + "@smithy/url-parser": "^2.0.10", + "@smithy/util-middleware": "^2.0.3", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-defaults-mode-browser": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.347.0.tgz", - "integrity": "sha512-+JHFA4reWnW/nMWwrLKqL2Lm/biw/Dzi/Ix54DAkRZ08C462jMKVnUlzAI+TfxQE3YLm99EIa0G7jiEA+p81Qw==", + "node_modules/@smithy/middleware-retry": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.0.13.tgz", + "integrity": "sha512-zuOva8xgWC7KYG8rEXyWIcZv2GWszO83DCTU6IKcf/FKu6OBmSE+EYv3EUcCGY+GfiwCX0EyJExC9Lpq9b0w5Q==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", - "bowser": "^2.11.0", - "tslib": "^2.5.0" + "@smithy/node-config-provider": "^2.0.13", + "@smithy/protocol-http": "^3.0.6", + "@smithy/service-error-classification": "^2.0.3", + "@smithy/types": "^2.3.4", + "@smithy/util-middleware": "^2.0.3", + "@smithy/util-retry": "^2.0.3", + "tslib": "^2.5.0", + "uuid": "^8.3.2" }, "engines": { - "node": ">= 10.0.0" + "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-defaults-mode-node": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.347.0.tgz", - "integrity": "sha512-A8BzIVhAAZE5WEukoAN2kYebzTc99ZgncbwOmgCCbvdaYlk5tzguR/s+uoT4G0JgQGol/4hAMuJEl7elNgU6RQ==", + "node_modules/@smithy/middleware-retry/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.0.10.tgz", + "integrity": "sha512-+A0AFqs768256H/BhVEsBF6HijFbVyAwYRVXY/izJFkTalVWJOp4JA0YdY0dpXQd+AlW0tzs+nMQCE1Ew+DcgQ==", "optional": true, "dependencies": { - "@aws-sdk/config-resolver": "3.347.0", - "@aws-sdk/credential-provider-imds": "3.347.0", - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" }, "engines": { - "node": ">= 10.0.0" + "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-endpoints": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.347.0.tgz", - "integrity": "sha512-/WUkirizeNAqwVj0zkcrqdQ9pUm1HY5kU+qy7xTR0OebkuJauglkmSTMD+56L1JPunWqHhlwCMVRaz5eaJdSEQ==", + "node_modules/@smithy/middleware-stack": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.0.4.tgz", + "integrity": "sha512-MW0KNKfh8ZGLagMZnxcLJWPNXoKqW6XV/st5NnCBmmA2e2JhrUjU0AJ5Ca/yjTyNEKs3xH7AQDwp1YmmpEpmQQ==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.347.0", + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-hex-encoding": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.310.0.tgz", - "integrity": "sha512-sVN7mcCCDSJ67pI1ZMtk84SKGqyix6/0A1Ab163YKn+lFBQRMKexleZzpYzNGxYzmQS6VanP/cfU7NiLQOaSfA==", + "node_modules/@smithy/node-config-provider": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.0.13.tgz", + "integrity": "sha512-pPpLqYuJcOq1sj1EGu+DoZK47DUS4gepqSTNgRezmrjnzNlSU2/Dcc9Ebzs+WZ0Z5vXKazuE+k+NksFLo07/AA==", "optional": true, "dependencies": { + "@smithy/property-provider": "^2.0.11", + "@smithy/shared-ini-file-loader": "^2.0.12", + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-locate-window": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz", - "integrity": "sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==", + "node_modules/@smithy/node-http-handler": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.1.6.tgz", + "integrity": "sha512-NspvD3aCwiUNtoSTcVHz0RZz1tQ/SaRIe1KPF+r0mAdCZ9eWuhIeJT8ZNPYa1ITn7/Lgg64IyFjqPynZ8KnYQw==", "optional": true, "dependencies": { + "@smithy/abort-controller": "^2.0.10", + "@smithy/protocol-http": "^3.0.6", + "@smithy/querystring-builder": "^2.0.10", + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-middleware": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.347.0.tgz", - "integrity": "sha512-8owqUA3ePufeYTUvlzdJ7Z0miLorTwx+rNol5lourGQZ9JXsVMo23+yGA7nOlFuXSGkoKpMOtn6S0BT2bcfeiw==", + "node_modules/@smithy/property-provider": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.0.11.tgz", + "integrity": "sha512-kzuOadu6XvrnlF1iXofpKXYmo4oe19st9/DE8f5gHNaFepb4eTkR8gD8BSdTnNnv7lxfv6uOwZPg4VS6hemX1w==", "optional": true, "dependencies": { + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-retry": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-retry/-/util-retry-3.347.0.tgz", - "integrity": "sha512-NxnQA0/FHFxriQAeEgBonA43Q9/VPFQa8cfJDuT2A1YZruMasgjcltoZszi1dvoIRWSZsFTW42eY2gdOd0nffQ==", + "node_modules/@smithy/protocol-http": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-3.0.6.tgz", + "integrity": "sha512-F0jAZzwznMmHaggiZgc7YoS08eGpmLvhVktY/Taz6+OAOHfyIqWSDNgFqYR+WHW9z5fp2XvY4mEUrQgYMQ71jw==", "optional": true, "dependencies": { - "@aws-sdk/service-error-classification": "3.347.0", + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" }, "engines": { - "node": ">= 14.0.0" + "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-uri-escape": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.310.0.tgz", - "integrity": "sha512-drzt+aB2qo2LgtDoiy/3sVG8w63cgLkqFIa2NFlGpUgHFWTXkqtbgf4L5QdjRGKWhmZsnqkbtL7vkSWEcYDJ4Q==", + "node_modules/@smithy/querystring-builder": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.0.10.tgz", + "integrity": "sha512-uujJGp8jzrrU1UHme8sUKEbawQTcTmUWsh8rbGXYD/lMwNLQ+9jQ9dMDWbbH9Hpoa9RER1BeL/38WzGrbpob2w==", "optional": true, "dependencies": { + "@smithy/types": "^2.3.4", + "@smithy/util-uri-escape": "^2.0.0", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.347.0.tgz", - "integrity": "sha512-ydxtsKVtQefgbk1Dku1q7pMkjDYThauG9/8mQkZUAVik55OUZw71Zzr3XO8J8RKvQG8lmhPXuAQ0FKAyycc0RA==", + "node_modules/@smithy/querystring-parser": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.0.10.tgz", + "integrity": "sha512-WSD4EU60Q8scacT5PIpx4Bahn6nWpt+MiYLcBkFt6fOj7AssrNeaNIU2Z0g40ftVmrwLcEOIKGX92ynbVDb3ZA==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.347.0", - "bowser": "^2.11.0", + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.347.0.tgz", - "integrity": "sha512-6X0b9qGsbD1s80PmbaB6v1/ZtLfSx6fjRX8caM7NN0y/ObuLoX8LhYnW6WlB2f1+xb4EjaCNgpP/zCf98MXosw==", + "node_modules/@smithy/service-error-classification": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.0.3.tgz", + "integrity": "sha512-b+m4QCHXb7oKAkM/jHwHrl5gpqhFoMTHF643L0/vAEkegrcUWyh1UjyoHttuHcP5FnHVVy4EtpPtLkEYD+xMFw==", "optional": true, "dependencies": { - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" + "@smithy/types": "^2.3.4" }, "engines": { "node": ">=14.0.0" - }, - "peerDependencies": { - "aws-crt": ">=1.0.0" - }, - "peerDependenciesMeta": { - "aws-crt": { - "optional": true - } } }, - "node_modules/@aws-sdk/util-utf8": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8/-/util-utf8-3.310.0.tgz", - "integrity": "sha512-DnLfFT8uCO22uOJc0pt0DsSNau1GTisngBCDw8jQuWT5CqogMJu4b/uXmwEqfj8B3GX6Xsz8zOd6JpRlPftQoA==", + "node_modules/@smithy/shared-ini-file-loader": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.0.12.tgz", + "integrity": "sha512-umi0wc4UBGYullAgYNUVfGLgVpxQyES47cnomTqzCKeKO5oudO4hyDNj+wzrOjqDFwK2nWYGVgS8Y0JgGietrw==", "optional": true, "dependencies": { - "@aws-sdk/util-buffer-from": "3.310.0", + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-utf8-browser": { - "version": "3.259.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", - "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", + "node_modules/@smithy/signature-v4": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.0.10.tgz", + "integrity": "sha512-S6gcP4IXfO/VMswovrhxPpqvQvMal7ZRjM4NvblHSPpE5aNBYx67UkHFF3kg0hR3tJKqNpBGbxwq0gzpdHKLRA==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "@smithy/eventstream-codec": "^2.0.10", + "@smithy/is-array-buffer": "^2.0.0", + "@smithy/types": "^2.3.4", + "@smithy/util-hex-encoding": "^2.0.0", + "@smithy/util-middleware": "^2.0.3", + "@smithy/util-uri-escape": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", - "dev": true, + "node_modules/@smithy/smithy-client": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.1.9.tgz", + "integrity": "sha512-HTicQSn/lOcXKJT+DKJ4YMu51S6PzbWsO8Z6Pwueo30mSoFKXg5P0BDkg2VCDqCVR0mtddM/F6hKhjW6YAV/yg==", + "optional": true, "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" + "@smithy/middleware-stack": "^2.0.4", + "@smithy/types": "^2.3.4", + "@smithy/util-stream": "^2.0.14", + "tslib": "^2.5.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=14.0.0" } }, - "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, + "node_modules/@smithy/types": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.3.4.tgz", + "integrity": "sha512-D7xlM9FOMFyFw7YnMXn9dK2KuN6+JhnrZwVt1fWaIu8hCk5CigysweeIT/H/nCo4YV+s8/oqUdLfexbkPZtvqw==", + "optional": true, "dependencies": { - "ms": "2.1.2" + "tslib": "^2.5.0" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=14.0.0" } }, - "node_modules/@eslint/eslintrc/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" - }, - "node_modules/@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "node_modules/@smithy/url-parser": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.0.10.tgz", + "integrity": "sha512-4TXQFGjHcqru8aH5VRB4dSnOFKCYNX6SR1Do6fwxZ+ExT2onLsh2W77cHpks7ma26W5jv6rI1u7d0+KX9F0aOw==", + "optional": true, "dependencies": { - "@hapi/hoek": "^9.0.0" + "@smithy/querystring-parser": "^2.0.10", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", - "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", - "dev": true, + "node_modules/@smithy/util-base64": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-2.0.0.tgz", + "integrity": "sha512-Zb1E4xx+m5Lud8bbeYi5FkcMJMnn+1WUnJF3qD7rAdXpaL7UjkFQLdmW5fHadoKbdHpwH9vSR8EyTJFHJs++tA==", + "optional": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@smithy/util-buffer-from": "^2.0.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">=10.10.0" + "node": ">=14.0.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, + "node_modules/@smithy/util-body-length-browser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-2.0.0.tgz", + "integrity": "sha512-JdDuS4ircJt+FDnaQj88TzZY3+njZ6O+D3uakS32f2VNnDo3vyEuNdBOh/oFd8Df1zSZOuH1HEChk2AOYDezZg==", + "optional": true, "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "tslib": "^2.5.0" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" - }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", - "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==", + "node_modules/@smithy/util-body-length-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-2.1.0.tgz", + "integrity": "sha512-/li0/kj/y3fQ3vyzn36NTLGmUwAICb7Jbe/CsWCktW363gh1MOcpEcSO3mJ344Gv2dqz8YJCLQpb6hju/0qOWw==", + "optional": true, "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" + "tslib": "^2.5.0" }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, + "node_modules/@smithy/util-buffer-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.0.0.tgz", + "integrity": "sha512-/YNnLoHsR+4W4Vf2wL5lGv0ksg8Bmk3GEGxn2vEQt52AQaPSCuaO5PM5VM7lP1K9qHRKHwrPGktqVoAHKWHxzw==", + "optional": true, "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@smithy/is-array-buffer": "^2.0.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" + "node": ">=14.0.0" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, + "node_modules/@smithy/util-config-provider": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-2.0.0.tgz", + "integrity": "sha512-xCQ6UapcIWKxXHEU4Mcs2s7LcFQRiU3XEluM2WcCjjBtQkUN71Tb+ydGmJFPxMUrW/GWMgQEEGipLym4XG0jZg==", + "optional": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "tslib": "^2.5.0" }, "engines": { - "node": ">= 8" + "node": ">=14.0.0" } }, - "node_modules/@postman/form-data": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@postman/form-data/-/form-data-3.1.1.tgz", - "integrity": "sha512-vjh8Q2a8S6UCm/KKs31XFJqEEgmbjBmpPNVV2eVav6905wyFAwaUOBGA1NPBI4ERH9MMZc6w0umFgM6WbEPMdg==", - "dev": true, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.13.tgz", + "integrity": "sha512-UmmOdUzaQjqdsl1EjbpEaQxM0VDFqTj6zDuI26/hXN7L/a1k1koTwkYpogHMvunDX3fjrQusg5gv1Td4UsGyog==", + "optional": true, "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "@smithy/property-provider": "^2.0.11", + "@smithy/smithy-client": "^2.1.9", + "@smithy/types": "^2.3.4", + "bowser": "^2.11.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">= 6" + "node": ">= 10.0.0" } }, - "node_modules/@postman/tunnel-agent": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@postman/tunnel-agent/-/tunnel-agent-0.6.3.tgz", - "integrity": "sha512-k57fzmAZ2PJGxfOA4SGR05ejorHbVAa/84Hxh/2nAztjNXc4ZjOm9NUIk6/Z6LCrBvJZqjRZbN8e/nROVUPVdg==", - "dev": true, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.15.tgz", + "integrity": "sha512-g6J7MHAibVPMTlXyH3mL+Iet4lMJKFVhsOhJmn+IKG81uy9m42CkRSDlwdQSJAcprLQBIaOPdFxNXQvrg2w1Uw==", + "optional": true, "dependencies": { - "safe-buffer": "^5.0.1" + "@smithy/config-resolver": "^2.0.11", + "@smithy/credential-provider-imds": "^2.0.13", + "@smithy/node-config-provider": "^2.0.13", + "@smithy/property-provider": "^2.0.11", + "@smithy/smithy-client": "^2.1.9", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" }, "engines": { - "node": "*" - } - }, - "node_modules/@sideway/address": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", - "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", - "dependencies": { - "@hapi/hoek": "^9.0.0" + "node": ">= 10.0.0" } }, - "node_modules/@sideway/formula": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" - }, - "node_modules/@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" - }, - "node_modules/@sinonjs/commons": { + "node_modules/@smithy/util-hex-encoding": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-2.0.0.tgz", + "integrity": "sha512-c5xY+NUnFqG6d7HFh1IFfrm3mGl29lC+vF+geHv4ToiuJCBmIfzx6IeHLg+OgRdPFKDXIw6pvi+p3CsscaMcMA==", + "optional": true, "dependencies": { - "type-detect": "4.0.8" + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, + "node_modules/@smithy/util-middleware": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.0.3.tgz", + "integrity": "sha512-+FOCFYOxd2HO7v/0hkFSETKf7FYQWa08wh/x/4KUeoVBnLR4juw8Qi+TTqZI6E2h5LkzD9uOaxC9lAjrpVzaaA==", + "optional": true, "dependencies": { - "@sinonjs/commons": "^1.7.0" + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.5.tgz", - "integrity": "sha512-rTpCA0wG1wUxglBSFdMMY0oTrKYvgf4fNgv/sXbfCVAdf+FnPBdKJR/7XbpTCwbCrvCbdPYnlWaUUYz4V2fPDA==", - "dev": true, + "node_modules/@smithy/util-retry": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.0.3.tgz", + "integrity": "sha512-gw+czMnj82i+EaH7NL7XKkfX/ZKrCS2DIWwJFPKs76bMgkhf0y1C94Lybn7f8GkBI9lfIOUdPYtzm19zQOC8sw==", + "optional": true, "dependencies": { - "type-detect": "4.0.8" + "@smithy/service-error-classification": "^2.0.3", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@sinonjs/samsam": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-7.0.1.tgz", - "integrity": "sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==", - "dev": true, + "node_modules/@smithy/util-stream": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.0.14.tgz", + "integrity": "sha512-XjvlDYe+9DieXhLf7p+EgkXwFtl34kHZcWfHnc5KaILbhyVfDLWuqKTFx6WwCFqb01iFIig8trGwExRIqqkBYg==", + "optional": true, "dependencies": { - "@sinonjs/commons": "^2.0.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" + "@smithy/fetch-http-handler": "^2.2.1", + "@smithy/node-http-handler": "^2.1.6", + "@smithy/types": "^2.3.4", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-buffer-from": "^2.0.0", + "@smithy/util-hex-encoding": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true - }, - "node_modules/@smithy/protocol-http": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-1.0.1.tgz", - "integrity": "sha512-9OrEn0WfOVtBNYJUjUAn9AOiJ4lzERCJJ/JeZs8E6yajTGxBaFRxUnNBHiNqoDJVg076hY36UmEnPx7xXrvUSg==", + "node_modules/@smithy/util-uri-escape": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-2.0.0.tgz", + "integrity": "sha512-ebkxsqinSdEooQduuk9CbKcI+wheijxEb3utGXkCoYQkJnwTnLbH1JXGimJtUkQwNQbsbuYwG2+aFVyZf5TLaw==", "optional": true, "dependencies": { - "@smithy/types": "^1.0.0", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@smithy/types": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-1.0.0.tgz", - "integrity": "sha512-kc1m5wPBHQCTixwuaOh9vnak/iJm21DrSf9UK6yDE5S3mQQ4u11pqAUiKWnlrZnYkeLfAI9UEHj9OaMT1v5Umg==", + "node_modules/@smithy/util-utf8": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.0.0.tgz", + "integrity": "sha512-rctU1VkziY84n5OXe3bPNpKR001ZCME2JCaBBFgtiM2hfKbHFudc/BkMuPab8hRbLd0j3vbnBTTZ1igBf0wgiQ==", "optional": true, "dependencies": { + "@smithy/util-buffer-from": "^2.0.0", "tslib": "^2.5.0" }, "engines": { @@ -1430,14 +1528,14 @@ } }, "node_modules/@types/node": { - "version": "18.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.6.tgz", - "integrity": "sha512-j3CEDa2vd96K0AXF8Wur7UucACvnjkk8hYyQAHhUNciabZLDl9nfAEVUSwmh245OOZV15bRA3Y590Gi5jUcDJg==" + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz", + "integrity": "sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==" }, "node_modules/@types/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.1.tgz", + "integrity": "sha512-8hKOnOan+Uu+NgMaCouhg3cT9x5fFZ92Jwf+uDLXLu/MFRbXxlWwGeQY7KVHkeSft6RvY+tdxklUBuyY9eIEKg==" }, "node_modules/@types/whatwg-url": { "version": "8.2.2", @@ -1758,9 +1856,9 @@ } }, "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", "dev": true }, "node_modules/balanced-match": { @@ -1923,9 +2021,9 @@ "dev": true }, "node_modules/bson": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.0.tgz", - "integrity": "sha512-VrlEE4vuiO1WTpfof4VmaVolCVYkYTgB9iWgYNOrVlnifpME/06fhFRmONgBhClD5pFC1t9ZWqFUQEQAzY43bA==", + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.2.tgz", + "integrity": "sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==", "dependencies": { "buffer": "^5.6.0" }, @@ -2034,9 +2132,9 @@ } }, "node_modules/chardet": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-1.4.0.tgz", - "integrity": "sha512-NpwMDdSIprbYx1CLnfbxEIarI0Z+s9MssEgggMNheGM+WD68yOhV7IEA/3r6tr0yTRgQD0HuZJDw32s99i6L+A==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-1.6.0.tgz", + "integrity": "sha512-+QOTw3otC4+FxdjK9RopGpNOglADbr4WPFi0SonkO99JbpkTPbMxmdm4NenhF5Zs+4gPXLI1+y2uazws5TMe8w==", "dev": true }, "node_modules/charset": { @@ -2096,21 +2194,21 @@ } }, "node_modules/cli-progress": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.10.0.tgz", - "integrity": "sha512-kLORQrhYCAtUPLZxqsAt2YJGOvRdt34+O6jl5cQGb7iF3dM55FQZlTR+rQyIK9JUcO9bBMwZsTlND+3dmFU2Cw==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.12.0.tgz", + "integrity": "sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==", "dev": true, "dependencies": { - "string-width": "^4.2.0" + "string-width": "^4.2.3" }, "engines": { "node": ">=4" } }, "node_modules/cli-table3": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz", - "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", "dev": true, "dependencies": { "string-width": "^4.2.0" @@ -2119,7 +2217,7 @@ "node": "10.* || >= 12.*" }, "optionalDependencies": { - "colors": "1.4.0" + "@colors/colors": "1.5.0" } }, "node_modules/cliui": { @@ -2180,12 +2278,12 @@ } }, "node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz", + "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==", "dev": true, "engines": { - "node": ">= 10" + "node": ">=16" } }, "node_modules/compress-commons": { @@ -2356,14 +2454,6 @@ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" }, - "node_modules/denque": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", - "engines": { - "node": ">=0.10" - } - }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -2372,6 +2462,16 @@ "node": ">= 0.8" } }, + "node_modules/des.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -2740,12 +2840,6 @@ "integrity": "sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==", "dev": true }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -2823,12 +2917,6 @@ "node >=0.6.0" ] }, - "node_modules/faker": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz", - "integrity": "sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g==", - "dev": true - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2876,9 +2964,9 @@ "dev": true }, "node_modules/fast-xml-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.4.tgz", - "integrity": "sha512-fbfMDvgBNIdDJLdLOwacjFAPYt67tr31H9ZhWSm45CDAxvd0I6WTlSOUo7K2P/K5sA5JgMKG64PI3DMcaFdWpQ==", + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz", + "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==", "funding": [ { "type": "paypal", @@ -2952,12 +3040,12 @@ } }, "node_modules/filesize": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", - "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", + "version": "10.0.12", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.0.12.tgz", + "integrity": "sha512-6RS9gDchbn+qWmtV2uSjo5vmKizgfCQeb5jKmqx8HyzA3MoLqqyQxN+QcjkGBJt7FjJ9qFce67Auyya5rRRbpw==", "dev": true, "engines": { - "node": ">= 0.4.0" + "node": ">= 10.4.0" } }, "node_modules/fill-range": { @@ -3642,13 +3730,13 @@ } }, "node_modules/handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, "dependencies": { "minimist": "^1.2.5", - "neo-async": "^2.6.0", + "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, @@ -3787,22 +3875,34 @@ } }, "node_modules/httpntlm": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.7.7.tgz", - "integrity": "sha512-Pv2Rvrz8H0qv1Dne5mAdZ9JegG1uc6Vu5lwLflIY6s8RKHdZQbW39L4dYswSgqMDT0pkJILUTKjeyU0VPNRZjA==", + "version": "1.8.13", + "resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.8.13.tgz", + "integrity": "sha512-2F2FDPiWT4rewPzNMg3uPhNkP3NExENlUGADRUDPQvuftuUTGW98nLZtGemCIW3G40VhWZYgkIDcQFAwZ3mf2Q==", "dev": true, + "funding": [ + { + "type": "paypal", + "url": "https://www.paypal.com/donate/?hosted_button_id=2CKNJLZJBW8ZC" + }, + { + "type": "buymeacoffee", + "url": "https://www.buymeacoffee.com/samdecrock" + } + ], "dependencies": { + "des.js": "^1.0.1", "httpreq": ">=0.4.22", + "js-md4": "^0.3.2", "underscore": "~1.12.1" }, "engines": { - "node": ">=0.8.0" + "node": ">=10.4.0" } }, "node_modules/httpreq": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/httpreq/-/httpreq-0.5.2.tgz", - "integrity": "sha512-2Jm+x9WkExDOeFRrdBCBSpLPT5SokTcRHkunV3pjKmX/cx6av8zQ0WtHUMDrYb6O4hBFzNU6sxJEypvRUVYKnw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/httpreq/-/httpreq-1.1.1.tgz", + "integrity": "sha512-uhSZLPPD2VXXOSN8Cni3kIsoFHaU2pT/nySEU/fHr/ePbqHYr0jeiQRmUKLEirC09SFPsdMoA7LU7UXMd/w0Kw==", "dev": true, "engines": { "node": ">= 6.15.1" @@ -3942,15 +4042,6 @@ "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" }, - "node_modules/ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -4145,6 +4236,21 @@ "@sideway/pinpoint": "^2.0.0" } }, + "node_modules/jose": { + "version": "4.14.4", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.14.4.tgz", + "integrity": "sha512-j8GhLiKmUAh+dsFXlX1aJCbt5KMibuKb+d7j1JaOJG6s2UjX1PQlW+OKB/sD4a/5ZYF4RcmYmLSndOoU3Lt/3g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-md4": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/js-md4/-/js-md4-0.3.2.tgz", + "integrity": "sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA==", + "dev": true + }, "node_modules/js-sdsl": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", @@ -4470,9 +4576,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "bin": { "semver": "bin/semver.js" } @@ -4604,6 +4710,12 @@ "node": ">= 0.6" } }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4803,13 +4915,12 @@ } }, "node_modules/mongodb": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.11.0.tgz", - "integrity": "sha512-9l9n4Nk2BYZzljW3vHah3Z0rfS5npKw6ktnkmFgTcnzaXH1DRm3pDl6VMHu84EVb1lzmSaJC4OzWZqTkB5i2wg==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.17.1.tgz", + "integrity": "sha512-MBuyYiPUPRTqfH2dV0ya4dcr2E5N52ocBuZ8Sgg/M030nGF78v855B3Z27mZJnp8PxjnUquEnAtjOsphgMZOlQ==", "dependencies": { - "bson": "^4.7.0", - "denque": "^2.1.0", - "mongodb-connection-string-url": "^2.5.4", + "bson": "^4.7.2", + "mongodb-connection-string-url": "^2.6.0", "socks": "^2.7.1" }, "engines": { @@ -4817,13 +4928,13 @@ }, "optionalDependencies": { "@aws-sdk/credential-providers": "^3.186.0", - "saslprep": "^1.0.3" + "@mongodb-js/saslprep": "^1.1.0" } }, "node_modules/mongodb-connection-string-url": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.4.tgz", - "integrity": "sha512-SeAxuWs0ez3iI3vvmLk/j2y+zHwigTDKQhtdxTgt5ZCOQQS5+HW4g45/Xw5vzzbn7oQXCNQ24Z40AkJsizEy7w==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", "dependencies": { "@types/whatwg-url": "^8.2.1", "whatwg-url": "^11.0.0" @@ -4929,59 +5040,53 @@ "dev": true }, "node_modules/newman": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/newman/-/newman-5.3.2.tgz", - "integrity": "sha512-cWy8pV0iwvMOZLTw3hkAHcwo2ZA0GKkXm8oUMn1Ltii3ZI2nKpnrg9QGdIT0hGHChRkX6prY5e3Aar7uykMGNg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/newman/-/newman-6.0.0.tgz", + "integrity": "sha512-QaANQC5b6ga348MezIVRI9ZmMs+cg3MdYIp0tSEauH2tmWOAR9+cghNsFJNjU9JPui3jJp1ALC7pQq6g3Jqpxw==", "dev": true, "dependencies": { - "async": "3.2.3", - "chardet": "1.4.0", - "cli-progress": "3.10.0", - "cli-table3": "0.6.1", + "@postman/tough-cookie": "4.1.3-postman.1", + "async": "3.2.4", + "chardet": "1.6.0", + "cli-progress": "3.12.0", + "cli-table3": "0.6.3", "colors": "1.4.0", - "commander": "7.2.0", + "commander": "11.0.0", "csv-parse": "4.16.3", - "eventemitter3": "4.0.7", - "filesize": "8.0.7", + "filesize": "10.0.12", + "liquid-json": "0.3.1", "lodash": "4.17.21", - "mkdirp": "1.0.4", - "postman-collection": "4.1.1", - "postman-collection-transformer": "4.1.6", - "postman-request": "2.88.1-postman.31", - "postman-runtime": "7.29.0", + "mkdirp": "3.0.1", + "postman-collection": "4.2.1", + "postman-collection-transformer": "4.1.7", + "postman-request": "2.88.1-postman.33", + "postman-runtime": "7.33.0", "pretty-ms": "7.0.1", - "semver": "7.3.5", + "semver": "7.5.4", "serialised-error": "1.1.3", - "tough-cookie": "3.0.1", - "word-wrap": "1.2.3", + "word-wrap": "1.2.5", "xmlbuilder": "15.1.1" }, "bin": { "newman": "bin/newman.js" }, "engines": { - "node": ">=10" + "node": ">=16" } }, - "node_modules/newman/node_modules/async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", - "dev": true - }, - "node_modules/newman/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "node_modules/newman/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { - "semver": "bin/semver.js" + "mkdirp": "dist/cjs/src/bin.js" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/nise": { @@ -5061,9 +5166,9 @@ "dev": true }, "node_modules/nodemon": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", - "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", + "integrity": "sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==", "dev": true, "dependencies": { "chokidar": "^3.5.2", @@ -5071,8 +5176,8 @@ "ignore-by-default": "^1.0.1", "minimatch": "^3.1.2", "pstree.remy": "^1.1.8", - "semver": "^5.7.1", - "simple-update-notifier": "^1.0.7", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", "supports-color": "^5.5.0", "touch": "^3.1.0", "undefsafe": "^2.0.5" @@ -5081,7 +5186,7 @@ "nodemon": "bin/nodemon.js" }, "engines": { - "node": ">=8.10.0" + "node": ">=10" }, "funding": { "type": "opencollective", @@ -5112,15 +5217,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "node_modules/nodemon/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, "node_modules/nodemon/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -5482,21 +5578,21 @@ } }, "node_modules/postman-collection": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.1.1.tgz", - "integrity": "sha512-ODpJtlf8r99DMcTU7gFmi/yvQYckFzcuE6zL/fWnyrFT34ugdCBFlX+DN7M+AnP6lmR822fv5s60H4DnL4+fAg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.2.1.tgz", + "integrity": "sha512-DFLt3/yu8+ldtOTIzmBUctoupKJBOVK4NZO0t68K2lIir9smQg7OdQTBjOXYy+PDh7u0pSDvD66tm93eBHEPHA==", "dev": true, "dependencies": { - "faker": "5.5.3", + "@faker-js/faker": "5.5.3", "file-type": "3.9.0", "http-reasons": "0.1.0", "iconv-lite": "0.6.3", "liquid-json": "0.3.1", "lodash": "4.17.21", "mime-format": "2.0.1", - "mime-types": "2.1.34", + "mime-types": "2.1.35", "postman-url-encoder": "3.0.5", - "semver": "7.3.5", + "semver": "7.5.4", "uuid": "8.3.2" }, "engines": { @@ -5504,15 +5600,15 @@ } }, "node_modules/postman-collection-transformer": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/postman-collection-transformer/-/postman-collection-transformer-4.1.6.tgz", - "integrity": "sha512-xvdQb6sZoWcG9xZXUPSuxocjcd6WCZlINlGGiuHdSfxhgiwQhj9qhF0JRFbagZ8xB0+pYUairD5MiCENc6DEVA==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/postman-collection-transformer/-/postman-collection-transformer-4.1.7.tgz", + "integrity": "sha512-SxJkm/LnlFZs2splUBnS4jQFicgBptghpm4voHtNnaum3Ad64E2MHLV4fJhv58dVUmFwdSwdQUN3m2q0iLecnQ==", "dev": true, "dependencies": { "commander": "8.3.0", "inherits": "2.0.4", "lodash": "4.17.21", - "semver": "7.3.5", + "semver": "7.5.4", "strip-json-comments": "3.1.1" }, "bin": { @@ -5531,21 +5627,6 @@ "node": ">= 12" } }, - "node_modules/postman-collection-transformer/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/postman-collection/node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -5558,42 +5639,6 @@ "node": ">=0.10.0" } }, - "node_modules/postman-collection/node_modules/mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/postman-collection/node_modules/mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, - "dependencies": { - "mime-db": "1.51.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/postman-collection/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/postman-collection/node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -5604,16 +5649,17 @@ } }, "node_modules/postman-request": { - "version": "2.88.1-postman.31", - "resolved": "https://registry.npmjs.org/postman-request/-/postman-request-2.88.1-postman.31.tgz", - "integrity": "sha512-OJbYqP7ItxQ84yHyuNpDywCZB0HYbpHJisMQ9lb1cSL3N5H3Td6a2+3l/a74UMd3u82BiGC5yQyYmdOIETP/nQ==", + "version": "2.88.1-postman.33", + "resolved": "https://registry.npmjs.org/postman-request/-/postman-request-2.88.1-postman.33.tgz", + "integrity": "sha512-uL9sCML4gPH6Z4hreDWbeinKU0p0Ke261nU7OvII95NU22HN6Dk7T/SaVPaj6T4TsQqGKIFw6/woLZnH7ugFNA==", "dev": true, "dependencies": { "@postman/form-data": "~3.1.1", + "@postman/tough-cookie": "~4.1.3-postman.1", "@postman/tunnel-agent": "^0.6.3", "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "brotli": "~1.3.2", + "aws4": "^1.12.0", + "brotli": "^1.3.3", "caseless": "~0.12.0", "combined-stream": "~1.0.6", "extend": "~3.0.2", @@ -5623,14 +5669,13 @@ "is-typedarray": "~1.0.0", "isstream": "~0.1.2", "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", + "mime-types": "^2.1.35", "oauth-sign": "~0.9.0", "performance-now": "^2.1.0", - "qs": "~6.5.2", + "qs": "~6.5.3", "safe-buffer": "^5.1.2", "stream-length": "^1.0.2", - "tough-cookie": "~2.5.0", - "uuid": "^3.3.2" + "uuid": "^8.3.2" }, "engines": { "node": ">= 6" @@ -5645,81 +5690,76 @@ "node": ">=0.6" } }, - "node_modules/postman-request/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/postman-request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, "bin": { - "uuid": "bin/uuid" + "uuid": "dist/bin/uuid" } }, "node_modules/postman-runtime": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/postman-runtime/-/postman-runtime-7.29.0.tgz", - "integrity": "sha512-eXxHREE/fUpohkGPRgBY1YccSGx9cyW3mtGiPyIE4zD5fYzasgBHqW6kbEND3Xrd3yf/uht/YI1H8O7J1+A1+w==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/postman-runtime/-/postman-runtime-7.33.0.tgz", + "integrity": "sha512-cYCb+5Y12FwZU/T3gOj2SKiOz38pisVLc0tdppb+ZlG7iqn5aLgxghJwhjG62pZCV6uixKiQX1hNdLSk9a9Xtw==", "dev": true, "dependencies": { - "async": "3.2.3", - "aws4": "1.11.0", - "handlebars": "4.7.7", - "httpntlm": "1.7.7", + "@postman/tough-cookie": "4.1.3-postman.1", + "async": "3.2.4", + "aws4": "1.12.0", + "handlebars": "4.7.8", + "httpntlm": "1.8.13", + "jose": "4.14.4", "js-sha512": "0.8.0", "lodash": "4.17.21", - "mime-types": "2.1.34", + "mime-types": "2.1.35", "node-oauth1": "1.3.0", "performance-now": "2.1.0", - "postman-collection": "4.1.1", - "postman-request": "2.88.1-postman.31", - "postman-sandbox": "4.0.6", + "postman-collection": "4.2.0", + "postman-request": "2.88.1-postman.33", + "postman-sandbox": "4.2.7", "postman-url-encoder": "3.0.5", "serialised-error": "1.1.3", - "tough-cookie": "3.0.1", + "strip-json-comments": "3.1.1", "uuid": "8.3.2" }, "engines": { - "node": ">=10" + "node": ">=12" } }, - "node_modules/postman-runtime/node_modules/async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", - "dev": true - }, - "node_modules/postman-runtime/node_modules/mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "node_modules/postman-runtime/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=0.10.0" } }, - "node_modules/postman-runtime/node_modules/mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "node_modules/postman-runtime/node_modules/postman-collection": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.2.0.tgz", + "integrity": "sha512-tvOLgN1h6Kab6dt43PmBoV5kYO/YUta3x0C2QqfmbzmHZe47VTpZ/+gIkGlbNhjKNPUUub5X6ehxYKoaTYdy1w==", "dev": true, "dependencies": { - "mime-db": "1.51.0" + "@faker-js/faker": "5.5.3", + "file-type": "3.9.0", + "http-reasons": "0.1.0", + "iconv-lite": "0.6.3", + "liquid-json": "0.3.1", + "lodash": "4.17.21", + "mime-format": "2.0.1", + "mime-types": "2.1.35", + "postman-url-encoder": "3.0.5", + "semver": "7.5.4", + "uuid": "8.3.2" }, "engines": { - "node": ">= 0.6" + "node": ">=10" } }, "node_modules/postman-runtime/node_modules/uuid": { @@ -5732,19 +5772,63 @@ } }, "node_modules/postman-sandbox": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/postman-sandbox/-/postman-sandbox-4.0.6.tgz", - "integrity": "sha512-PPRanSNEE4zy3kO7CeSBHmAfJnGdD9ecHY/Mjh26CQuZZarGkNO8c0U/n+xX3+5M1BRNc82UYq6YCtdsSDqcng==", + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/postman-sandbox/-/postman-sandbox-4.2.7.tgz", + "integrity": "sha512-/EcCrKnb/o+9iLS4u+H76E0kBomJFjPptVjoDiq1uZ7Es/4aTv0MAX+0aoDxdDO+0h9sl8vy65uKQwyjN7AOaw==", "dev": true, "dependencies": { "lodash": "4.17.21", + "postman-collection": "4.2.0", "teleport-javascript": "1.0.0", - "uvm": "2.0.2" + "uvm": "2.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/postman-sandbox/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postman-sandbox/node_modules/postman-collection": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.2.0.tgz", + "integrity": "sha512-tvOLgN1h6Kab6dt43PmBoV5kYO/YUta3x0C2QqfmbzmHZe47VTpZ/+gIkGlbNhjKNPUUub5X6ehxYKoaTYdy1w==", + "dev": true, + "dependencies": { + "@faker-js/faker": "5.5.3", + "file-type": "3.9.0", + "http-reasons": "0.1.0", + "iconv-lite": "0.6.3", + "liquid-json": "0.3.1", + "lodash": "4.17.21", + "mime-format": "2.0.1", + "mime-types": "2.1.35", + "postman-url-encoder": "3.0.5", + "semver": "7.5.4", + "uuid": "8.3.2" }, "engines": { "node": ">=10" } }, + "node_modules/postman-sandbox/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/postman-url-encoder": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/postman-url-encoder/-/postman-url-encoder-3.0.5.tgz", @@ -5844,6 +5928,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -5983,6 +6073,12 @@ "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -6093,18 +6189,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "node_modules/saslprep": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", - "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", - "optional": true, - "dependencies": { - "sparse-bitfield": "^3.0.3" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/semaphore": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", @@ -6115,9 +6199,9 @@ } }, "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -6250,24 +6334,15 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/simple-update-notifier": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz", - "integrity": "sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", "dev": true, "dependencies": { - "semver": "~7.0.0" + "semver": "^7.5.3" }, "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "node": ">=10" } }, "node_modules/sinon": { @@ -6579,29 +6654,15 @@ "node": "*" } }, - "node_modules/tough-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", - "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", - "dev": true, - "dependencies": { - "ip-regex": "^2.1.0", - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "optional": true }, "node_modules/tweetnacl": { @@ -6701,6 +6762,15 @@ "node": "*" } }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -6727,6 +6797,16 @@ "node": ">= 0.10" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -6749,21 +6829,21 @@ } }, "node_modules/uvm": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/uvm/-/uvm-2.0.2.tgz", - "integrity": "sha512-Ra+aPiS5GXAbwXmyNExqdS42sTqmmx4XWEDF8uJlsTfOkKf9Rd9xNgav1Yckv4HfVEZg4iOFODWHFYuJ+9Fzfg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/uvm/-/uvm-2.1.1.tgz", + "integrity": "sha512-BZ5w8adTpNNr+zczOBRpaX/hH8UPKAf7fmCnidrcsqt3bn8KT9bDIfuS7hgRU9RXgiN01su2pwysBONY6w8W5w==", "dev": true, "dependencies": { - "flatted": "3.1.1" + "flatted": "3.2.6" }, "engines": { "node": ">=10" } }, "node_modules/uvm/node_modules/flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz", + "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", "dev": true }, "node_modules/v8flags": { @@ -6838,9 +6918,9 @@ } }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -7108,1078 +7188,1167 @@ } } }, - "@aws-sdk/abort-controller": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.347.0.tgz", - "integrity": "sha512-P/2qE6ntYEmYG4Ez535nJWZbXqgbkJx8CMz7ChEuEg3Gp3dvVYEKg+iEUEvlqQ2U5dWP5J3ehw5po9t86IsVPQ==", - "optional": true, - "requires": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" - } - }, "@aws-sdk/client-cognito-identity": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.350.0.tgz", - "integrity": "sha512-46AhBvGWo6TEzlvZieNlZHC2w4NJUJA52KfDUtgr8PmChGgxqzlLBAiOpqbDJ83GR3YB6CNEjXxzN5tmyJKICA==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.423.0.tgz", + "integrity": "sha512-9nyilMrihznN7Y6T/dVhbg4YGsdk7szzShoyoSGwofOg61ugobnHbBvh0tPPOQcHhlzXvD8LZdOQ6Kd4KvNp/A==", "optional": true, "requires": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.350.0", - "@aws-sdk/config-resolver": "3.347.0", - "@aws-sdk/credential-provider-node": "3.350.0", - "@aws-sdk/fetch-http-handler": "3.347.0", - "@aws-sdk/hash-node": "3.347.0", - "@aws-sdk/invalid-dependency": "3.347.0", - "@aws-sdk/middleware-content-length": "3.347.0", - "@aws-sdk/middleware-endpoint": "3.347.0", - "@aws-sdk/middleware-host-header": "3.347.0", - "@aws-sdk/middleware-logger": "3.347.0", - "@aws-sdk/middleware-recursion-detection": "3.347.0", - "@aws-sdk/middleware-retry": "3.347.0", - "@aws-sdk/middleware-serde": "3.347.0", - "@aws-sdk/middleware-signing": "3.347.0", - "@aws-sdk/middleware-stack": "3.347.0", - "@aws-sdk/middleware-user-agent": "3.347.0", - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/node-http-handler": "3.350.0", - "@aws-sdk/smithy-client": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-body-length-browser": "3.310.0", - "@aws-sdk/util-body-length-node": "3.310.0", - "@aws-sdk/util-defaults-mode-browser": "3.347.0", - "@aws-sdk/util-defaults-mode-node": "3.347.0", - "@aws-sdk/util-endpoints": "3.347.0", - "@aws-sdk/util-retry": "3.347.0", - "@aws-sdk/util-user-agent-browser": "3.347.0", - "@aws-sdk/util-user-agent-node": "3.347.0", - "@aws-sdk/util-utf8": "3.310.0", - "@smithy/protocol-http": "^1.0.1", - "@smithy/types": "^1.0.0", + "@aws-sdk/client-sts": "3.423.0", + "@aws-sdk/credential-provider-node": "3.423.0", + "@aws-sdk/middleware-host-header": "3.418.0", + "@aws-sdk/middleware-logger": "3.418.0", + "@aws-sdk/middleware-recursion-detection": "3.418.0", + "@aws-sdk/middleware-signing": "3.418.0", + "@aws-sdk/middleware-user-agent": "3.418.0", + "@aws-sdk/region-config-resolver": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@aws-sdk/util-endpoints": "3.418.0", + "@aws-sdk/util-user-agent-browser": "3.418.0", + "@aws-sdk/util-user-agent-node": "3.418.0", + "@smithy/config-resolver": "^2.0.10", + "@smithy/fetch-http-handler": "^2.1.5", + "@smithy/hash-node": "^2.0.9", + "@smithy/invalid-dependency": "^2.0.9", + "@smithy/middleware-content-length": "^2.0.11", + "@smithy/middleware-endpoint": "^2.0.9", + "@smithy/middleware-retry": "^2.0.12", + "@smithy/middleware-serde": "^2.0.9", + "@smithy/middleware-stack": "^2.0.2", + "@smithy/node-config-provider": "^2.0.12", + "@smithy/node-http-handler": "^2.1.5", + "@smithy/protocol-http": "^3.0.5", + "@smithy/smithy-client": "^2.1.6", + "@smithy/types": "^2.3.3", + "@smithy/url-parser": "^2.0.9", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.1.0", + "@smithy/util-defaults-mode-browser": "^2.0.10", + "@smithy/util-defaults-mode-node": "^2.0.12", + "@smithy/util-retry": "^2.0.2", + "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" } }, "@aws-sdk/client-sso": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.350.0.tgz", - "integrity": "sha512-2vpiv6SEjmQGK3ZueGzvTMG6NenjWp0CHjmda71d1Iqr+tZ2UlfC35+3ioU8JP+jiXLL+y9r+SCer3IC8N/i+Q==", - "optional": true, - "requires": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/config-resolver": "3.347.0", - "@aws-sdk/fetch-http-handler": "3.347.0", - "@aws-sdk/hash-node": "3.347.0", - "@aws-sdk/invalid-dependency": "3.347.0", - "@aws-sdk/middleware-content-length": "3.347.0", - "@aws-sdk/middleware-endpoint": "3.347.0", - "@aws-sdk/middleware-host-header": "3.347.0", - "@aws-sdk/middleware-logger": "3.347.0", - "@aws-sdk/middleware-recursion-detection": "3.347.0", - "@aws-sdk/middleware-retry": "3.347.0", - "@aws-sdk/middleware-serde": "3.347.0", - "@aws-sdk/middleware-stack": "3.347.0", - "@aws-sdk/middleware-user-agent": "3.347.0", - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/node-http-handler": "3.350.0", - "@aws-sdk/smithy-client": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-body-length-browser": "3.310.0", - "@aws-sdk/util-body-length-node": "3.310.0", - "@aws-sdk/util-defaults-mode-browser": "3.347.0", - "@aws-sdk/util-defaults-mode-node": "3.347.0", - "@aws-sdk/util-endpoints": "3.347.0", - "@aws-sdk/util-retry": "3.347.0", - "@aws-sdk/util-user-agent-browser": "3.347.0", - "@aws-sdk/util-user-agent-node": "3.347.0", - "@aws-sdk/util-utf8": "3.310.0", - "@smithy/protocol-http": "^1.0.1", - "@smithy/types": "^1.0.0", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/client-sso-oidc": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.350.0.tgz", - "integrity": "sha512-v3UrWIglg9PPzGXqhyGB/qPZ8ifiGM9r4LV8vve1TpiKsUdf1Khtx1eB8yqjNO0vIsYUF+j1C23QT1qAN2DcEA==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.423.0.tgz", + "integrity": "sha512-znIufHkwhCIePgaYciIs3x/+BpzR57CZzbCKHR9+oOvGyufEPPpUT5bFLvbwTgfiVkTjuk6sG/ES3U5Bc+xtrA==", "optional": true, "requires": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/config-resolver": "3.347.0", - "@aws-sdk/fetch-http-handler": "3.347.0", - "@aws-sdk/hash-node": "3.347.0", - "@aws-sdk/invalid-dependency": "3.347.0", - "@aws-sdk/middleware-content-length": "3.347.0", - "@aws-sdk/middleware-endpoint": "3.347.0", - "@aws-sdk/middleware-host-header": "3.347.0", - "@aws-sdk/middleware-logger": "3.347.0", - "@aws-sdk/middleware-recursion-detection": "3.347.0", - "@aws-sdk/middleware-retry": "3.347.0", - "@aws-sdk/middleware-serde": "3.347.0", - "@aws-sdk/middleware-stack": "3.347.0", - "@aws-sdk/middleware-user-agent": "3.347.0", - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/node-http-handler": "3.350.0", - "@aws-sdk/smithy-client": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-body-length-browser": "3.310.0", - "@aws-sdk/util-body-length-node": "3.310.0", - "@aws-sdk/util-defaults-mode-browser": "3.347.0", - "@aws-sdk/util-defaults-mode-node": "3.347.0", - "@aws-sdk/util-endpoints": "3.347.0", - "@aws-sdk/util-retry": "3.347.0", - "@aws-sdk/util-user-agent-browser": "3.347.0", - "@aws-sdk/util-user-agent-node": "3.347.0", - "@aws-sdk/util-utf8": "3.310.0", - "@smithy/protocol-http": "^1.0.1", - "@smithy/types": "^1.0.0", + "@aws-sdk/middleware-host-header": "3.418.0", + "@aws-sdk/middleware-logger": "3.418.0", + "@aws-sdk/middleware-recursion-detection": "3.418.0", + "@aws-sdk/middleware-user-agent": "3.418.0", + "@aws-sdk/region-config-resolver": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@aws-sdk/util-endpoints": "3.418.0", + "@aws-sdk/util-user-agent-browser": "3.418.0", + "@aws-sdk/util-user-agent-node": "3.418.0", + "@smithy/config-resolver": "^2.0.10", + "@smithy/fetch-http-handler": "^2.1.5", + "@smithy/hash-node": "^2.0.9", + "@smithy/invalid-dependency": "^2.0.9", + "@smithy/middleware-content-length": "^2.0.11", + "@smithy/middleware-endpoint": "^2.0.9", + "@smithy/middleware-retry": "^2.0.12", + "@smithy/middleware-serde": "^2.0.9", + "@smithy/middleware-stack": "^2.0.2", + "@smithy/node-config-provider": "^2.0.12", + "@smithy/node-http-handler": "^2.1.5", + "@smithy/protocol-http": "^3.0.5", + "@smithy/smithy-client": "^2.1.6", + "@smithy/types": "^2.3.3", + "@smithy/url-parser": "^2.0.9", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.1.0", + "@smithy/util-defaults-mode-browser": "^2.0.10", + "@smithy/util-defaults-mode-node": "^2.0.12", + "@smithy/util-retry": "^2.0.2", + "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" } }, "@aws-sdk/client-sts": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.350.0.tgz", - "integrity": "sha512-s8RsJ6upWQgeUt8GdV3j3ZeTS7BQXedk77RhZ7wzvVwAjO9wow4uS7Iyic4kS3Y/6d26s0MO2vP4bR6HW6U6ZQ==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.423.0.tgz", + "integrity": "sha512-EcpkKu02QZbRX6dQE0u7a8RgWrn/5riz1qAlKd7rM8FZJpr/D6GGX8ZzWxjgp7pRUgfNvinTmIudDnyQY3v9Mg==", "optional": true, "requires": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/config-resolver": "3.347.0", - "@aws-sdk/credential-provider-node": "3.350.0", - "@aws-sdk/fetch-http-handler": "3.347.0", - "@aws-sdk/hash-node": "3.347.0", - "@aws-sdk/invalid-dependency": "3.347.0", - "@aws-sdk/middleware-content-length": "3.347.0", - "@aws-sdk/middleware-endpoint": "3.347.0", - "@aws-sdk/middleware-host-header": "3.347.0", - "@aws-sdk/middleware-logger": "3.347.0", - "@aws-sdk/middleware-recursion-detection": "3.347.0", - "@aws-sdk/middleware-retry": "3.347.0", - "@aws-sdk/middleware-sdk-sts": "3.347.0", - "@aws-sdk/middleware-serde": "3.347.0", - "@aws-sdk/middleware-signing": "3.347.0", - "@aws-sdk/middleware-stack": "3.347.0", - "@aws-sdk/middleware-user-agent": "3.347.0", - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/node-http-handler": "3.350.0", - "@aws-sdk/smithy-client": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-body-length-browser": "3.310.0", - "@aws-sdk/util-body-length-node": "3.310.0", - "@aws-sdk/util-defaults-mode-browser": "3.347.0", - "@aws-sdk/util-defaults-mode-node": "3.347.0", - "@aws-sdk/util-endpoints": "3.347.0", - "@aws-sdk/util-retry": "3.347.0", - "@aws-sdk/util-user-agent-browser": "3.347.0", - "@aws-sdk/util-user-agent-node": "3.347.0", - "@aws-sdk/util-utf8": "3.310.0", - "@smithy/protocol-http": "^1.0.1", - "@smithy/types": "^1.0.0", - "fast-xml-parser": "4.2.4", - "tslib": "^2.5.0" - } - }, - "@aws-sdk/config-resolver": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.347.0.tgz", - "integrity": "sha512-2ja+Sf/VnUO7IQ3nKbDQ5aumYKKJUaTm/BuVJ29wNho8wYHfuf7wHZV0pDTkB8RF5SH7IpHap7zpZAj39Iq+EA==", - "optional": true, - "requires": { - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-config-provider": "3.310.0", - "@aws-sdk/util-middleware": "3.347.0", + "@aws-sdk/credential-provider-node": "3.423.0", + "@aws-sdk/middleware-host-header": "3.418.0", + "@aws-sdk/middleware-logger": "3.418.0", + "@aws-sdk/middleware-recursion-detection": "3.418.0", + "@aws-sdk/middleware-sdk-sts": "3.418.0", + "@aws-sdk/middleware-signing": "3.418.0", + "@aws-sdk/middleware-user-agent": "3.418.0", + "@aws-sdk/region-config-resolver": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@aws-sdk/util-endpoints": "3.418.0", + "@aws-sdk/util-user-agent-browser": "3.418.0", + "@aws-sdk/util-user-agent-node": "3.418.0", + "@smithy/config-resolver": "^2.0.10", + "@smithy/fetch-http-handler": "^2.1.5", + "@smithy/hash-node": "^2.0.9", + "@smithy/invalid-dependency": "^2.0.9", + "@smithy/middleware-content-length": "^2.0.11", + "@smithy/middleware-endpoint": "^2.0.9", + "@smithy/middleware-retry": "^2.0.12", + "@smithy/middleware-serde": "^2.0.9", + "@smithy/middleware-stack": "^2.0.2", + "@smithy/node-config-provider": "^2.0.12", + "@smithy/node-http-handler": "^2.1.5", + "@smithy/protocol-http": "^3.0.5", + "@smithy/smithy-client": "^2.1.6", + "@smithy/types": "^2.3.3", + "@smithy/url-parser": "^2.0.9", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.1.0", + "@smithy/util-defaults-mode-browser": "^2.0.10", + "@smithy/util-defaults-mode-node": "^2.0.12", + "@smithy/util-retry": "^2.0.2", + "@smithy/util-utf8": "^2.0.0", + "fast-xml-parser": "4.2.5", "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-cognito-identity": { - "version": "3.351.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.351.0.tgz", - "integrity": "sha512-c9XyDUj82ttqQqF8h4Ie7k2Fl3bMh8/yBGEQWIPzWRhfy40m4ChqjilKAcBeoxR/w4Qp3RsdDfLRTLC8sJTpIg==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.423.0.tgz", + "integrity": "sha512-FuuCOeUkAn3tZU2GUN3eUjs4AC88t5je4N5/NVbTaSN0e2FGf9PnN5nrwTKwaOGVLSe6/FvfudW01LZ/+PRQOQ==", "optional": true, "requires": { - "@aws-sdk/client-cognito-identity": "3.350.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@aws-sdk/client-cognito-identity": "3.423.0", + "@aws-sdk/types": "3.418.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-env": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.347.0.tgz", - "integrity": "sha512-UnEM+LKGpXKzw/1WvYEQsC6Wj9PupYZdQOE+e2Dgy2dqk/pVFy4WueRtFXYDT2B41ppv3drdXUuKZRIDVqIgNQ==", + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.418.0.tgz", + "integrity": "sha512-e74sS+x63EZUBO+HaI8zor886YdtmULzwKdctsZp5/37Xho1CVUNtEC+fYa69nigBD9afoiH33I4JggaHgrekQ==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@aws-sdk/types": "3.418.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" } }, - "@aws-sdk/credential-provider-imds": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.347.0.tgz", - "integrity": "sha512-7scCy/DCDRLIhlqTxff97LQWDnRwRXji3bxxMg+xWOTTaJe7PWx+etGSbBWaL42vsBHFShQjSLvJryEgoBktpw==", + "@aws-sdk/credential-provider-http": { + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.423.0.tgz", + "integrity": "sha512-y/mutbiCU/4HGN/ChcNBhPaXo4pgg6lAcWyuMTSSfAR03hjoXe1cMwbPcUiEwzQrZ/+1yufLpZhmoiAWsgAkNw==", "optional": true, "requires": { - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", + "@aws-sdk/types": "3.418.0", + "@smithy/fetch-http-handler": "^2.1.5", + "@smithy/node-http-handler": "^2.1.5", + "@smithy/property-provider": "^2.0.0", + "@smithy/protocol-http": "^3.0.5", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-ini": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.350.0.tgz", - "integrity": "sha512-mGGU0PpnG0VDNKSuGi083U1egjprrU9/XoRtgf+iYvAKXRR/0XA4pGW5c7zpHY7m4iLhBuRj6N4oxQsH9cMtWg==", - "optional": true, - "requires": { - "@aws-sdk/credential-provider-env": "3.347.0", - "@aws-sdk/credential-provider-imds": "3.347.0", - "@aws-sdk/credential-provider-process": "3.347.0", - "@aws-sdk/credential-provider-sso": "3.350.0", - "@aws-sdk/credential-provider-web-identity": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/types": "3.347.0", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.423.0.tgz", + "integrity": "sha512-7CsFWz8g7dQmblp57XzzxMirO4ClowGZIOwAheBkmk6q1XHbllcHFnbh2kdPyQQ0+JmjDg6waztIc7dY7Ycfvw==", + "optional": true, + "requires": { + "@aws-sdk/credential-provider-env": "3.418.0", + "@aws-sdk/credential-provider-process": "3.418.0", + "@aws-sdk/credential-provider-sso": "3.423.0", + "@aws-sdk/credential-provider-web-identity": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@smithy/credential-provider-imds": "^2.0.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-node": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.350.0.tgz", - "integrity": "sha512-xmqwCFwj/CZPx6AKHNb24Kpr0eHW9VISt9r+SfgH8PaYg5cNyX1pKmMbQCket5ov+WvHEQtOK7aBafak7dhauA==", - "optional": true, - "requires": { - "@aws-sdk/credential-provider-env": "3.347.0", - "@aws-sdk/credential-provider-imds": "3.347.0", - "@aws-sdk/credential-provider-ini": "3.350.0", - "@aws-sdk/credential-provider-process": "3.347.0", - "@aws-sdk/credential-provider-sso": "3.350.0", - "@aws-sdk/credential-provider-web-identity": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/types": "3.347.0", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.423.0.tgz", + "integrity": "sha512-lygbGJJUnDpgo8OEqdoYd51BKkyBVQ1Catiua/m0aHvL+SCmVrHiYPQPawWYGxpH8X3DXdXa0nd0LkEaevrHRg==", + "optional": true, + "requires": { + "@aws-sdk/credential-provider-env": "3.418.0", + "@aws-sdk/credential-provider-ini": "3.423.0", + "@aws-sdk/credential-provider-process": "3.418.0", + "@aws-sdk/credential-provider-sso": "3.423.0", + "@aws-sdk/credential-provider-web-identity": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@smithy/credential-provider-imds": "^2.0.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-process": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.347.0.tgz", - "integrity": "sha512-yl1z4MsaBdXd4GQ2halIvYds23S67kElyOwz7g8kaQ4kHj+UoYWxz3JVW/DGusM6XmQ9/F67utBrUVA0uhQYyw==", + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.418.0.tgz", + "integrity": "sha512-xPbdm2WKz1oH6pTkrJoUmr3OLuqvvcPYTQX0IIlc31tmDwDWPQjXGGFD/vwZGIZIkKaFpFxVMgAzfFScxox7dw==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@aws-sdk/types": "3.418.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-sso": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.350.0.tgz", - "integrity": "sha512-u/3kv+PJeVawzBtWBei+IX1/z50mwhpPe3VrKSTns4CPUw8b5sqIYWkAaw5hxm0td69+xcL98RzIJsEpJc4QSQ==", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.423.0.tgz", + "integrity": "sha512-zAH68IjRMmW22USbsCVQ5Q6AHqhmWABwLbZAMocSGMasddTGv/nkA/nUiVCJ/B4LI3P81FoPQVrG5JxNmkNH0w==", "optional": true, "requires": { - "@aws-sdk/client-sso": "3.350.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/token-providers": "3.350.0", - "@aws-sdk/types": "3.347.0", + "@aws-sdk/client-sso": "3.423.0", + "@aws-sdk/token-providers": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-web-identity": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.347.0.tgz", - "integrity": "sha512-DxoTlVK8lXjS1zVphtz/Ab+jkN/IZor9d6pP2GjJHNoAIIzXfRwwj5C8vr4eTayx/5VJ7GRP91J8GJ2cKly8Qw==", + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.418.0.tgz", + "integrity": "sha512-do7ang565n9p3dS1JdsQY01rUfRx8vkxQqz5M8OlcEHBNiCdi2PvSjNwcBdrv/FKkyIxZb0TImOfBSt40hVdxQ==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@aws-sdk/types": "3.418.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" } }, "@aws-sdk/credential-providers": { - "version": "3.351.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.351.0.tgz", - "integrity": "sha512-KVfLTVpeDKnOPl0u5w3RJdNz+AtFIOj3dsfpyLkGCV5bHClLN05YFf1ajh93Z5FijuhvDSYuLT1Xr3Ud+AIudQ==", - "optional": true, - "requires": { - "@aws-sdk/client-cognito-identity": "3.350.0", - "@aws-sdk/client-sso": "3.350.0", - "@aws-sdk/client-sts": "3.350.0", - "@aws-sdk/credential-provider-cognito-identity": "3.351.0", - "@aws-sdk/credential-provider-env": "3.347.0", - "@aws-sdk/credential-provider-imds": "3.347.0", - "@aws-sdk/credential-provider-ini": "3.350.0", - "@aws-sdk/credential-provider-node": "3.350.0", - "@aws-sdk/credential-provider-process": "3.347.0", - "@aws-sdk/credential-provider-sso": "3.350.0", - "@aws-sdk/credential-provider-web-identity": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", + "version": "3.423.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.423.0.tgz", + "integrity": "sha512-jsjIrnu+bVUz2lekcg9wxpPlO8jWd9q26MP/rRwdkm9LHqroICjZY7tIYqSJliVkeSyJHJ9pq/jNDceWhy6a0A==", + "optional": true, + "requires": { + "@aws-sdk/client-cognito-identity": "3.423.0", + "@aws-sdk/client-sso": "3.423.0", + "@aws-sdk/client-sts": "3.423.0", + "@aws-sdk/credential-provider-cognito-identity": "3.423.0", + "@aws-sdk/credential-provider-env": "3.418.0", + "@aws-sdk/credential-provider-http": "3.423.0", + "@aws-sdk/credential-provider-ini": "3.423.0", + "@aws-sdk/credential-provider-node": "3.423.0", + "@aws-sdk/credential-provider-process": "3.418.0", + "@aws-sdk/credential-provider-sso": "3.423.0", + "@aws-sdk/credential-provider-web-identity": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@smithy/credential-provider-imds": "^2.0.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" } }, - "@aws-sdk/eventstream-codec": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-codec/-/eventstream-codec-3.347.0.tgz", - "integrity": "sha512-61q+SyspjsaQ4sdgjizMyRgVph2CiW4aAtfpoH69EJFJfTxTR/OqnZ9Jx/3YiYi0ksrvDenJddYodfWWJqD8/w==", + "@aws-sdk/middleware-host-header": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.418.0.tgz", + "integrity": "sha512-LrMTdzalkPw/1ujLCKPLwCGvPMCmT4P+vOZQRbSEVZPnlZk+Aj++aL/RaHou0jL4kJH3zl8iQepriBt4a7UvXQ==", "optional": true, "requires": { - "@aws-crypto/crc32": "3.0.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-hex-encoding": "3.310.0", + "@aws-sdk/types": "3.418.0", + "@smithy/protocol-http": "^3.0.5", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" } }, - "@aws-sdk/fetch-http-handler": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.347.0.tgz", - "integrity": "sha512-sQ5P7ivY8//7wdxfA76LT1sF6V2Tyyz1qF6xXf9sihPN5Q1Y65c+SKpMzXyFSPqWZ82+SQQuDliYZouVyS6kQQ==", + "@aws-sdk/middleware-logger": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.418.0.tgz", + "integrity": "sha512-StKGmyPVfoO/wdNTtKemYwoJsqIl4l7oqarQY7VSf2Mp3mqaa+njLViHsQbirYpyqpgUEusOnuTlH5utxJ1NsQ==", "optional": true, "requires": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/querystring-builder": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-base64": "3.310.0", + "@aws-sdk/types": "3.418.0", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" } }, - "@aws-sdk/hash-node": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.347.0.tgz", - "integrity": "sha512-96+ml/4EaUaVpzBdOLGOxdoXOjkPgkoJp/0i1fxOJEvl8wdAQSwc3IugVK9wZkCxy2DlENtgOe6DfIOhfffm/g==", + "@aws-sdk/middleware-recursion-detection": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.418.0.tgz", + "integrity": "sha512-kKFrIQglBLUFPbHSDy1+bbe3Na2Kd70JSUC3QLMbUHmqipXN8KeXRfAj7vTv97zXl0WzG0buV++WcNwOm1rFjg==", "optional": true, "requires": { - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-buffer-from": "3.310.0", - "@aws-sdk/util-utf8": "3.310.0", + "@aws-sdk/types": "3.418.0", + "@smithy/protocol-http": "^3.0.5", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" } }, - "@aws-sdk/invalid-dependency": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.347.0.tgz", - "integrity": "sha512-8imQcwLwqZ/wTJXZqzXT9pGLIksTRckhGLZaXT60tiBOPKuerTsus2L59UstLs5LP8TKaVZKFFSsjRIn9dQdmQ==", + "@aws-sdk/middleware-sdk-sts": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.418.0.tgz", + "integrity": "sha512-cW8ijrCTP+mgihvcq4+TbhAcE/we5lFl4ydRqvTdtcSnYQAVQADg47rnTScQiFsPFEB3NKq7BGeyTJF9MKolPA==", "optional": true, "requires": { - "@aws-sdk/types": "3.347.0", + "@aws-sdk/middleware-signing": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" } }, - "@aws-sdk/is-array-buffer": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.310.0.tgz", - "integrity": "sha512-urnbcCR+h9NWUnmOtet/s4ghvzsidFmspfhYaHAmSRdy9yDjdjBJMFjjsn85A1ODUktztm+cVncXjQ38WCMjMQ==", + "@aws-sdk/middleware-signing": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.418.0.tgz", + "integrity": "sha512-onvs5KoYQE8OlOE740RxWBGtsUyVIgAo0CzRKOQO63ZEYqpL1Os+MS1CGzdNhvQnJgJruE1WW+Ix8fjN30zKPA==", "optional": true, "requires": { + "@aws-sdk/types": "3.418.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/protocol-http": "^3.0.5", + "@smithy/signature-v4": "^2.0.0", + "@smithy/types": "^2.3.3", + "@smithy/util-middleware": "^2.0.2", "tslib": "^2.5.0" } }, - "@aws-sdk/middleware-content-length": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.347.0.tgz", - "integrity": "sha512-i4qtWTDImMaDUtwKQPbaZpXsReiwiBomM1cWymCU4bhz81HL01oIxOxOBuiM+3NlDoCSPr3KI6txZSz/8cqXCQ==", + "@aws-sdk/middleware-user-agent": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.418.0.tgz", + "integrity": "sha512-Jdcztg9Tal9SEAL0dKRrnpKrm6LFlWmAhvuwv0dQ7bNTJxIxyEFbpqdgy7mpQHsLVZgq1Aad/7gT/72c9igyZw==", "optional": true, "requires": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@aws-sdk/types": "3.418.0", + "@aws-sdk/util-endpoints": "3.418.0", + "@smithy/protocol-http": "^3.0.5", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" } }, - "@aws-sdk/middleware-endpoint": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.347.0.tgz", - "integrity": "sha512-unF0c6dMaUL1ffU+37Ugty43DgMnzPWXr/Jup/8GbK5fzzWT5NQq6dj9KHPubMbWeEjQbmczvhv25JuJdK8gNQ==", + "@aws-sdk/region-config-resolver": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.418.0.tgz", + "integrity": "sha512-lJRZ/9TjZU6yLz+mAwxJkcJZ6BmyYoIJVo1p5+BN//EFdEmC8/c0c9gXMRzfISV/mqWSttdtccpAyN4/goHTYA==", "optional": true, "requires": { - "@aws-sdk/middleware-serde": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/url-parser": "3.347.0", - "@aws-sdk/util-middleware": "3.347.0", + "@smithy/node-config-provider": "^2.0.12", + "@smithy/types": "^2.3.3", + "@smithy/util-config-provider": "^2.0.0", + "@smithy/util-middleware": "^2.0.2", "tslib": "^2.5.0" } }, - "@aws-sdk/middleware-host-header": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.347.0.tgz", - "integrity": "sha512-kpKmR9OvMlnReqp5sKcJkozbj1wmlblbVSbnQAIkzeQj2xD5dnVR3Nn2ogQKxSmU1Fv7dEroBtrruJ1o3fY38A==", + "@aws-sdk/token-providers": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.418.0.tgz", + "integrity": "sha512-9P7Q0VN0hEzTngy3Sz5eya2qEOEf0Q8qf1vB3um0gE6ID6EVAdz/nc/DztfN32MFxk8FeVBrCP5vWdoOzmd72g==", "optional": true, "requires": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/middleware-host-header": "3.418.0", + "@aws-sdk/middleware-logger": "3.418.0", + "@aws-sdk/middleware-recursion-detection": "3.418.0", + "@aws-sdk/middleware-user-agent": "3.418.0", + "@aws-sdk/types": "3.418.0", + "@aws-sdk/util-endpoints": "3.418.0", + "@aws-sdk/util-user-agent-browser": "3.418.0", + "@aws-sdk/util-user-agent-node": "3.418.0", + "@smithy/config-resolver": "^2.0.10", + "@smithy/fetch-http-handler": "^2.1.5", + "@smithy/hash-node": "^2.0.9", + "@smithy/invalid-dependency": "^2.0.9", + "@smithy/middleware-content-length": "^2.0.11", + "@smithy/middleware-endpoint": "^2.0.9", + "@smithy/middleware-retry": "^2.0.12", + "@smithy/middleware-serde": "^2.0.9", + "@smithy/middleware-stack": "^2.0.2", + "@smithy/node-config-provider": "^2.0.12", + "@smithy/node-http-handler": "^2.1.5", + "@smithy/property-provider": "^2.0.0", + "@smithy/protocol-http": "^3.0.5", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/smithy-client": "^2.1.6", + "@smithy/types": "^2.3.3", + "@smithy/url-parser": "^2.0.9", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.1.0", + "@smithy/util-defaults-mode-browser": "^2.0.10", + "@smithy/util-defaults-mode-node": "^2.0.12", + "@smithy/util-retry": "^2.0.2", + "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" } }, - "@aws-sdk/middleware-logger": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.347.0.tgz", - "integrity": "sha512-NYC+Id5UCkVn+3P1t/YtmHt75uED06vwaKyxDy0UmB2K66PZLVtwWbLpVWrhbroaw1bvUHYcRyQ9NIfnVcXQjA==", + "@aws-sdk/types": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.418.0.tgz", + "integrity": "sha512-y4PQSH+ulfFLY0+FYkaK4qbIaQI9IJNMO2xsxukW6/aNoApNymN1D2FSi2la8Qbp/iPjNDKsG8suNPm9NtsWXQ==", "optional": true, "requires": { - "@aws-sdk/types": "3.347.0", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" } }, - "@aws-sdk/middleware-recursion-detection": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.347.0.tgz", - "integrity": "sha512-qfnSvkFKCAMjMHR31NdsT0gv5Sq/ZHTUD4yQsSLpbVQ6iYAS834lrzXt41iyEHt57Y514uG7F/Xfvude3u4icQ==", + "@aws-sdk/util-endpoints": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.418.0.tgz", + "integrity": "sha512-sYSDwRTl7yE7LhHkPzemGzmIXFVHSsi3AQ1KeNEk84eBqxMHHcCc2kqklaBk2roXWe50QDgRMy1ikZUxvtzNHQ==", "optional": true, "requires": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@aws-sdk/types": "3.418.0", "tslib": "^2.5.0" } }, - "@aws-sdk/middleware-retry": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.347.0.tgz", - "integrity": "sha512-CpdM+8dCSbX96agy4FCzOfzDmhNnGBM/pxrgIVLm5nkYTLuXp/d7ubpFEUHULr+4hCd5wakHotMt7yO29NFaVw==", - "optional": true, - "requires": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/service-error-classification": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-middleware": "3.347.0", - "@aws-sdk/util-retry": "3.347.0", - "tslib": "^2.5.0", - "uuid": "^8.3.2" - }, - "dependencies": { - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "optional": true - } - } - }, - "@aws-sdk/middleware-sdk-sts": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.347.0.tgz", - "integrity": "sha512-38LJ0bkIoVF3W97x6Jyyou72YV9Cfbml4OaDEdnrCOo0EssNZM5d7RhjMvQDwww7/3OBY/BzeOcZKfJlkYUXGw==", + "@aws-sdk/util-locate-window": { + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz", + "integrity": "sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==", "optional": true, "requires": { - "@aws-sdk/middleware-signing": "3.347.0", - "@aws-sdk/types": "3.347.0", "tslib": "^2.5.0" } }, - "@aws-sdk/middleware-serde": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.347.0.tgz", - "integrity": "sha512-x5Foi7jRbVJXDu9bHfyCbhYDH5pKK+31MmsSJ3k8rY8keXLBxm2XEEg/AIoV9/TUF9EeVvZ7F1/RmMpJnWQsEg==", + "@aws-sdk/util-user-agent-browser": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.418.0.tgz", + "integrity": "sha512-c4p4mc0VV/jIeNH0lsXzhJ1MpWRLuboGtNEpqE4s1Vl9ck2amv9VdUUZUmHbg+bVxlMgRQ4nmiovA4qIrqGuyg==", "optional": true, "requires": { - "@aws-sdk/types": "3.347.0", + "@aws-sdk/types": "3.418.0", + "@smithy/types": "^2.3.3", + "bowser": "^2.11.0", "tslib": "^2.5.0" } }, - "@aws-sdk/middleware-signing": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.347.0.tgz", - "integrity": "sha512-zVBF/4MGKnvhAE/J+oAL/VAehiyv+trs2dqSQXwHou9j8eA8Vm8HS2NdOwpkZQchIxTuwFlqSusDuPEdYFbvGw==", + "@aws-sdk/util-user-agent-node": { + "version": "3.418.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.418.0.tgz", + "integrity": "sha512-BXMskXFtg+dmzSCgmnWOffokxIbPr1lFqa1D9kvM3l3IFRiFGx2IyDg+8MAhq11aPDLvoa/BDuQ0Yqma5izOhg==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/signature-v4": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-middleware": "3.347.0", + "@aws-sdk/types": "3.418.0", + "@smithy/node-config-provider": "^2.0.12", + "@smithy/types": "^2.3.3", "tslib": "^2.5.0" } }, - "@aws-sdk/middleware-stack": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.347.0.tgz", - "integrity": "sha512-Izidg4rqtYMcKuvn2UzgEpPLSmyd8ub9+LQ2oIzG3mpIzCBITq7wp40jN1iNkMg+X6KEnX9vdMJIYZsPYMCYuQ==", + "@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", + "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", "optional": true, "requires": { - "tslib": "^2.5.0" + "tslib": "^2.3.1" } }, - "@aws-sdk/middleware-user-agent": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.347.0.tgz", - "integrity": "sha512-wJbGN3OE1/daVCrwk49whhIr9E0j1N4gWwN/wi4WuyYIA+5lMUfVp0aGIOvZR+878DxuFz2hQ4XcZVT4K2WvQw==", - "optional": true, - "requires": { - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-endpoints": "3.347.0", - "tslib": "^2.5.0" - } + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true }, - "@aws-sdk/node-config-provider": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.347.0.tgz", - "integrity": "sha512-faU93d3+5uTTUcotGgMXF+sJVFjrKh+ufW+CzYKT4yUHammyaIab/IbTPWy2hIolcEGtuPeVoxXw8TXbkh/tuw==", - "optional": true, - "requires": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" + "@eslint/eslintrc": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, - "@aws-sdk/node-http-handler": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.350.0.tgz", - "integrity": "sha512-oD96GAlmpzYilCdC8wwyURM5lNfNHZCjm/kxBkQulHKa2kRbIrnD9GfDqdCkWA5cTpjh1NzGLT4D6e6UFDjt9w==", - "optional": true, + "@faker-js/faker": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-5.5.3.tgz", + "integrity": "sha512-R11tGE6yIFwqpaIqcfkcg7AICXzFg14+5h5v0TfF/9+RMDL6jhzCy/pxHVOfbALGdtVYdt6JdR21tuxEgl34dw==", + "dev": true + }, + "@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + }, + "@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", "requires": { - "@aws-sdk/abort-controller": "3.347.0", - "@aws-sdk/protocol-http": "3.347.0", - "@aws-sdk/querystring-builder": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" + "@hapi/hoek": "^9.0.0" } }, - "@aws-sdk/property-provider": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.347.0.tgz", - "integrity": "sha512-t3nJ8CYPLKAF2v9nIHOHOlF0CviQbTvbFc2L4a+A+EVd/rM4PzL3+3n8ZJsr0h7f6uD04+b5YRFgKgnaqLXlEg==", - "optional": true, + "@humanwhocodes/config-array": { + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", + "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", + "dev": true, "requires": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, - "@aws-sdk/protocol-http": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.347.0.tgz", - "integrity": "sha512-2YdBhc02Wvy03YjhGwUxF0UQgrPWEy8Iq75pfS42N+/0B/+eWX1aQgfjFxIpLg7YSjT5eKtYOQGlYd4MFTgj9g==", - "optional": true, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + }, + "@mapbox/node-pre-gyp": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", + "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==", "requires": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" } }, - "@aws-sdk/querystring-builder": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.347.0.tgz", - "integrity": "sha512-phtKTe6FXoV02MoPkIVV6owXI8Mwr5IBN3bPoxhcPvJG2AjEmnetSIrhb8kwc4oNhlwfZwH6Jo5ARW/VEWbZtg==", + "@mongodb-js/saslprep": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.0.tgz", + "integrity": "sha512-Xfijy7HvfzzqiOAhAepF4SGN5e9leLkMvg/OPOF97XemjfVCYN/oWa75wnkc6mltMSTwY+XlbhWgUOJmkFspSw==", "optional": true, "requires": { - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-uri-escape": "3.310.0", - "tslib": "^2.5.0" + "sparse-bitfield": "^3.0.3" } }, - "@aws-sdk/querystring-parser": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.347.0.tgz", - "integrity": "sha512-5VXOhfZz78T2W7SuXf2avfjKglx1VZgZgp9Zfhrt/Rq+MTu2D+PZc5zmJHhYigD7x83jLSLogpuInQpFMA9LgA==", - "optional": true, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, "requires": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" } }, - "@aws-sdk/service-error-classification": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.347.0.tgz", - "integrity": "sha512-xZ3MqSY81Oy2gh5g0fCtooAbahqh9VhsF8vcKjVX8+XPbGC8y+kej82+MsMg4gYL8gRFB9u4hgYbNgIS6JTAvg==", - "optional": true + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true }, - "@aws-sdk/shared-ini-file-loader": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.347.0.tgz", - "integrity": "sha512-Xw+zAZQVLb+xMNHChXQ29tzzLqm3AEHsD8JJnlkeFjeMnWQtXdUfOARl5s8NzAppcKQNlVe2gPzjaKjoy2jz1Q==", - "optional": true, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, "requires": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" } }, - "@aws-sdk/signature-v4": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.347.0.tgz", - "integrity": "sha512-58Uq1do+VsTHYkP11dTK+DF53fguoNNJL9rHRWhzP+OcYv3/mBMLoS2WPz/x9FO5mBg4ESFsug0I6mXbd36tjw==", - "optional": true, + "@postman/form-data": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@postman/form-data/-/form-data-3.1.1.tgz", + "integrity": "sha512-vjh8Q2a8S6UCm/KKs31XFJqEEgmbjBmpPNVV2eVav6905wyFAwaUOBGA1NPBI4ERH9MMZc6w0umFgM6WbEPMdg==", + "dev": true, "requires": { - "@aws-sdk/eventstream-codec": "3.347.0", - "@aws-sdk/is-array-buffer": "3.310.0", - "@aws-sdk/types": "3.347.0", - "@aws-sdk/util-hex-encoding": "3.310.0", - "@aws-sdk/util-middleware": "3.347.0", - "@aws-sdk/util-uri-escape": "3.310.0", - "@aws-sdk/util-utf8": "3.310.0", - "tslib": "^2.5.0" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" } }, - "@aws-sdk/smithy-client": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.347.0.tgz", - "integrity": "sha512-PaGTDsJLGK0sTjA6YdYQzILRlPRN3uVFyqeBUkfltXssvUzkm8z2t1lz2H4VyJLAhwnG5ZuZTNEV/2mcWrU7JQ==", - "optional": true, + "@postman/tough-cookie": { + "version": "4.1.3-postman.1", + "resolved": "https://registry.npmjs.org/@postman/tough-cookie/-/tough-cookie-4.1.3-postman.1.tgz", + "integrity": "sha512-txpgUqZOnWYnUHZpHjkfb0IwVH4qJmyq77pPnJLlfhMtdCLMFTEeQHlzQiK906aaNCe4NEB5fGJHo9uzGbFMeA==", + "dev": true, "requires": { - "@aws-sdk/middleware-stack": "3.347.0", - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" } }, - "@aws-sdk/token-providers": { - "version": "3.350.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.350.0.tgz", - "integrity": "sha512-VIfVMV5An1VQQ6bOKQTHPsRFHD3/YRGOPk9lDTVJGOK0G1DIFYd/10ZaLQ86rCWLck2lGhjxsOen2N2n6MtA0A==", + "@postman/tunnel-agent": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@postman/tunnel-agent/-/tunnel-agent-0.6.3.tgz", + "integrity": "sha512-k57fzmAZ2PJGxfOA4SGR05ejorHbVAa/84Hxh/2nAztjNXc4ZjOm9NUIk6/Z6LCrBvJZqjRZbN8e/nROVUPVdg==", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "@sideway/address": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", + "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, + "@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + }, + "@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.5.tgz", + "integrity": "sha512-rTpCA0wG1wUxglBSFdMMY0oTrKYvgf4fNgv/sXbfCVAdf+FnPBdKJR/7XbpTCwbCrvCbdPYnlWaUUYz4V2fPDA==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + } + } + }, + "@sinonjs/samsam": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-7.0.1.tgz", + "integrity": "sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "dev": true + }, + "@smithy/abort-controller": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.10.tgz", + "integrity": "sha512-xn7PnFD3m4rQIG00h1lPuDVnC2QMtTFhzRLX3y56KkgFaCysS7vpNevNBgmNUtmJ4eVFc+66Zucwo2KDLdicOg==", "optional": true, "requires": { - "@aws-sdk/client-sso-oidc": "3.350.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/shared-ini-file-loader": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" } }, - "@aws-sdk/types": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.347.0.tgz", - "integrity": "sha512-GkCMy79mdjU9OTIe5KT58fI/6uqdf8UmMdWqVHmFJ+UpEzOci7L/uw4sOXWo7xpPzLs6cJ7s5ouGZW4GRPmHFA==", + "@smithy/config-resolver": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.0.11.tgz", + "integrity": "sha512-q97FnlUmbai1c4JlQJgLVBsvSxgV/7Nvg/JK76E1nRq/U5UM56Eqo3dn2fY7JibqgJLg4LPsGdwtIyqyOk35CQ==", "optional": true, "requires": { + "@smithy/node-config-provider": "^2.0.13", + "@smithy/types": "^2.3.4", + "@smithy/util-config-provider": "^2.0.0", + "@smithy/util-middleware": "^2.0.3", "tslib": "^2.5.0" } }, - "@aws-sdk/url-parser": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.347.0.tgz", - "integrity": "sha512-lhrnVjxdV7hl+yCnJfDZOaVLSqKjxN20MIOiijRiqaWGLGEAiSqBreMhL89X1WKCifxAs4zZf9YB9SbdziRpAA==", + "@smithy/credential-provider-imds": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.0.13.tgz", + "integrity": "sha512-/xe3wNoC4j+BeTemH9t2gSKLBfyZmk8LXB2pQm/TOEYi+QhBgT+PSolNDfNAhrR68eggNE17uOimsrnwSkCt4w==", "optional": true, "requires": { - "@aws-sdk/querystring-parser": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@smithy/node-config-provider": "^2.0.13", + "@smithy/property-provider": "^2.0.11", + "@smithy/types": "^2.3.4", + "@smithy/url-parser": "^2.0.10", "tslib": "^2.5.0" } }, - "@aws-sdk/util-base64": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64/-/util-base64-3.310.0.tgz", - "integrity": "sha512-v3+HBKQvqgdzcbL+pFswlx5HQsd9L6ZTlyPVL2LS9nNXnCcR3XgGz9jRskikRUuUvUXtkSG1J88GAOnJ/apTPg==", + "@smithy/eventstream-codec": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.0.10.tgz", + "integrity": "sha512-3SSDgX2nIsFwif6m+I4+ar4KDcZX463Noes8ekBgQHitULiWvaDZX8XqPaRQSQ4bl1vbeVXHklJfv66MnVO+lw==", "optional": true, "requires": { - "@aws-sdk/util-buffer-from": "3.310.0", + "@aws-crypto/crc32": "3.0.0", + "@smithy/types": "^2.3.4", + "@smithy/util-hex-encoding": "^2.0.0", "tslib": "^2.5.0" } }, - "@aws-sdk/util-body-length-browser": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.310.0.tgz", - "integrity": "sha512-sxsC3lPBGfpHtNTUoGXMQXLwjmR0zVpx0rSvzTPAuoVILVsp5AU/w5FphNPxD5OVIjNbZv9KsKTuvNTiZjDp9g==", + "@smithy/fetch-http-handler": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.2.1.tgz", + "integrity": "sha512-bXyM8PBAIKxVV++2ZSNBEposTDjFQ31XWOdHED+2hWMNvJHUoQqFbECg/uhcVOa6vHie2/UnzIZfXBSTpDBnEw==", "optional": true, "requires": { + "@smithy/protocol-http": "^3.0.6", + "@smithy/querystring-builder": "^2.0.10", + "@smithy/types": "^2.3.4", + "@smithy/util-base64": "^2.0.0", "tslib": "^2.5.0" } }, - "@aws-sdk/util-body-length-node": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.310.0.tgz", - "integrity": "sha512-2tqGXdyKhyA6w4zz7UPoS8Ip+7sayOg9BwHNidiGm2ikbDxm1YrCfYXvCBdwaJxa4hJfRVz+aL9e+d3GqPI9pQ==", + "@smithy/hash-node": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.0.10.tgz", + "integrity": "sha512-jSTf6uzPk/Vf+8aQ7tVXeHfjxe9wRXSCqIZcBymSDTf7/YrVxniBdpyN74iI8ZUOx/Pyagc81OK5FROLaEjbXQ==", "optional": true, "requires": { + "@smithy/types": "^2.3.4", + "@smithy/util-buffer-from": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" } }, - "@aws-sdk/util-buffer-from": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.310.0.tgz", - "integrity": "sha512-i6LVeXFtGih5Zs8enLrt+ExXY92QV25jtEnTKHsmlFqFAuL3VBeod6boeMXkN2p9lbSVVQ1sAOOYZOHYbYkntw==", + "@smithy/invalid-dependency": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.0.10.tgz", + "integrity": "sha512-zw9p/zsmJ2cFcW4KMz3CJoznlbRvEA6HG2mvEaX5eAca5dq4VGI2MwPDTfmteC/GsnURS4ogoMQ0p6aHM2SDVQ==", "optional": true, "requires": { - "@aws-sdk/is-array-buffer": "3.310.0", + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" } }, - "@aws-sdk/util-config-provider": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.310.0.tgz", - "integrity": "sha512-xIBaYo8dwiojCw8vnUcIL4Z5tyfb1v3yjqyJKJWV/dqKUFOOS0U591plmXbM+M/QkXyML3ypon1f8+BoaDExrg==", + "@smithy/is-array-buffer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.0.0.tgz", + "integrity": "sha512-z3PjFjMyZNI98JFRJi/U0nGoLWMSJlDjAW4QUX2WNZLas5C0CmVV6LJ01JI0k90l7FvpmixjWxPFmENSClQ7ug==", "optional": true, "requires": { "tslib": "^2.5.0" } }, - "@aws-sdk/util-defaults-mode-browser": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.347.0.tgz", - "integrity": "sha512-+JHFA4reWnW/nMWwrLKqL2Lm/biw/Dzi/Ix54DAkRZ08C462jMKVnUlzAI+TfxQE3YLm99EIa0G7jiEA+p81Qw==", + "@smithy/middleware-content-length": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.0.12.tgz", + "integrity": "sha512-QRhJTo5TjG7oF7np6yY4ZO9GDKFVzU/GtcqUqyEa96bLHE3yZHgNmsolOQ97pfxPHmFhH4vDP//PdpAIN3uI1Q==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", - "bowser": "^2.11.0", + "@smithy/protocol-http": "^3.0.6", + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" } }, - "@aws-sdk/util-defaults-mode-node": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.347.0.tgz", - "integrity": "sha512-A8BzIVhAAZE5WEukoAN2kYebzTc99ZgncbwOmgCCbvdaYlk5tzguR/s+uoT4G0JgQGol/4hAMuJEl7elNgU6RQ==", + "@smithy/middleware-endpoint": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.0.10.tgz", + "integrity": "sha512-O6m4puZc16xfenotZUHL4bRlMrwf4gTp+0I5l954M5KNd3dOK18P+FA/IIUgnXF/dX6hlCUcJkBp7nAzwrePKA==", "optional": true, "requires": { - "@aws-sdk/config-resolver": "3.347.0", - "@aws-sdk/credential-provider-imds": "3.347.0", - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/property-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@smithy/middleware-serde": "^2.0.10", + "@smithy/types": "^2.3.4", + "@smithy/url-parser": "^2.0.10", + "@smithy/util-middleware": "^2.0.3", "tslib": "^2.5.0" } }, - "@aws-sdk/util-endpoints": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.347.0.tgz", - "integrity": "sha512-/WUkirizeNAqwVj0zkcrqdQ9pUm1HY5kU+qy7xTR0OebkuJauglkmSTMD+56L1JPunWqHhlwCMVRaz5eaJdSEQ==", + "@smithy/middleware-retry": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.0.13.tgz", + "integrity": "sha512-zuOva8xgWC7KYG8rEXyWIcZv2GWszO83DCTU6IKcf/FKu6OBmSE+EYv3EUcCGY+GfiwCX0EyJExC9Lpq9b0w5Q==", "optional": true, "requires": { - "@aws-sdk/types": "3.347.0", - "tslib": "^2.5.0" + "@smithy/node-config-provider": "^2.0.13", + "@smithy/protocol-http": "^3.0.6", + "@smithy/service-error-classification": "^2.0.3", + "@smithy/types": "^2.3.4", + "@smithy/util-middleware": "^2.0.3", + "@smithy/util-retry": "^2.0.3", + "tslib": "^2.5.0", + "uuid": "^8.3.2" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "optional": true + } } }, - "@aws-sdk/util-hex-encoding": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.310.0.tgz", - "integrity": "sha512-sVN7mcCCDSJ67pI1ZMtk84SKGqyix6/0A1Ab163YKn+lFBQRMKexleZzpYzNGxYzmQS6VanP/cfU7NiLQOaSfA==", + "@smithy/middleware-serde": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.0.10.tgz", + "integrity": "sha512-+A0AFqs768256H/BhVEsBF6HijFbVyAwYRVXY/izJFkTalVWJOp4JA0YdY0dpXQd+AlW0tzs+nMQCE1Ew+DcgQ==", "optional": true, "requires": { + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" } }, - "@aws-sdk/util-locate-window": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz", - "integrity": "sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==", + "@smithy/middleware-stack": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.0.4.tgz", + "integrity": "sha512-MW0KNKfh8ZGLagMZnxcLJWPNXoKqW6XV/st5NnCBmmA2e2JhrUjU0AJ5Ca/yjTyNEKs3xH7AQDwp1YmmpEpmQQ==", "optional": true, "requires": { + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" } }, - "@aws-sdk/util-middleware": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.347.0.tgz", - "integrity": "sha512-8owqUA3ePufeYTUvlzdJ7Z0miLorTwx+rNol5lourGQZ9JXsVMo23+yGA7nOlFuXSGkoKpMOtn6S0BT2bcfeiw==", + "@smithy/node-config-provider": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.0.13.tgz", + "integrity": "sha512-pPpLqYuJcOq1sj1EGu+DoZK47DUS4gepqSTNgRezmrjnzNlSU2/Dcc9Ebzs+WZ0Z5vXKazuE+k+NksFLo07/AA==", "optional": true, "requires": { + "@smithy/property-provider": "^2.0.11", + "@smithy/shared-ini-file-loader": "^2.0.12", + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" } }, - "@aws-sdk/util-retry": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-retry/-/util-retry-3.347.0.tgz", - "integrity": "sha512-NxnQA0/FHFxriQAeEgBonA43Q9/VPFQa8cfJDuT2A1YZruMasgjcltoZszi1dvoIRWSZsFTW42eY2gdOd0nffQ==", + "@smithy/node-http-handler": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.1.6.tgz", + "integrity": "sha512-NspvD3aCwiUNtoSTcVHz0RZz1tQ/SaRIe1KPF+r0mAdCZ9eWuhIeJT8ZNPYa1ITn7/Lgg64IyFjqPynZ8KnYQw==", "optional": true, "requires": { - "@aws-sdk/service-error-classification": "3.347.0", + "@smithy/abort-controller": "^2.0.10", + "@smithy/protocol-http": "^3.0.6", + "@smithy/querystring-builder": "^2.0.10", + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" } }, - "@aws-sdk/util-uri-escape": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.310.0.tgz", - "integrity": "sha512-drzt+aB2qo2LgtDoiy/3sVG8w63cgLkqFIa2NFlGpUgHFWTXkqtbgf4L5QdjRGKWhmZsnqkbtL7vkSWEcYDJ4Q==", + "@smithy/property-provider": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.0.11.tgz", + "integrity": "sha512-kzuOadu6XvrnlF1iXofpKXYmo4oe19st9/DE8f5gHNaFepb4eTkR8gD8BSdTnNnv7lxfv6uOwZPg4VS6hemX1w==", "optional": true, "requires": { + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" } }, - "@aws-sdk/util-user-agent-browser": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.347.0.tgz", - "integrity": "sha512-ydxtsKVtQefgbk1Dku1q7pMkjDYThauG9/8mQkZUAVik55OUZw71Zzr3XO8J8RKvQG8lmhPXuAQ0FKAyycc0RA==", + "@smithy/protocol-http": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-3.0.6.tgz", + "integrity": "sha512-F0jAZzwznMmHaggiZgc7YoS08eGpmLvhVktY/Taz6+OAOHfyIqWSDNgFqYR+WHW9z5fp2XvY4mEUrQgYMQ71jw==", "optional": true, "requires": { - "@aws-sdk/types": "3.347.0", - "bowser": "^2.11.0", + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" } }, - "@aws-sdk/util-user-agent-node": { - "version": "3.347.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.347.0.tgz", - "integrity": "sha512-6X0b9qGsbD1s80PmbaB6v1/ZtLfSx6fjRX8caM7NN0y/ObuLoX8LhYnW6WlB2f1+xb4EjaCNgpP/zCf98MXosw==", + "@smithy/querystring-builder": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.0.10.tgz", + "integrity": "sha512-uujJGp8jzrrU1UHme8sUKEbawQTcTmUWsh8rbGXYD/lMwNLQ+9jQ9dMDWbbH9Hpoa9RER1BeL/38WzGrbpob2w==", "optional": true, "requires": { - "@aws-sdk/node-config-provider": "3.347.0", - "@aws-sdk/types": "3.347.0", + "@smithy/types": "^2.3.4", + "@smithy/util-uri-escape": "^2.0.0", "tslib": "^2.5.0" } }, - "@aws-sdk/util-utf8": { - "version": "3.310.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8/-/util-utf8-3.310.0.tgz", - "integrity": "sha512-DnLfFT8uCO22uOJc0pt0DsSNau1GTisngBCDw8jQuWT5CqogMJu4b/uXmwEqfj8B3GX6Xsz8zOd6JpRlPftQoA==", + "@smithy/querystring-parser": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.0.10.tgz", + "integrity": "sha512-WSD4EU60Q8scacT5PIpx4Bahn6nWpt+MiYLcBkFt6fOj7AssrNeaNIU2Z0g40ftVmrwLcEOIKGX92ynbVDb3ZA==", "optional": true, "requires": { - "@aws-sdk/util-buffer-from": "3.310.0", + "@smithy/types": "^2.3.4", "tslib": "^2.5.0" } }, - "@aws-sdk/util-utf8-browser": { - "version": "3.259.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", - "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", + "@smithy/service-error-classification": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.0.3.tgz", + "integrity": "sha512-b+m4QCHXb7oKAkM/jHwHrl5gpqhFoMTHF643L0/vAEkegrcUWyh1UjyoHttuHcP5FnHVVy4EtpPtLkEYD+xMFw==", "optional": true, "requires": { - "tslib": "^2.3.1" + "@smithy/types": "^2.3.4" } }, - "@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", - "dev": true, + "@smithy/shared-ini-file-loader": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.0.12.tgz", + "integrity": "sha512-umi0wc4UBGYullAgYNUVfGLgVpxQyES47cnomTqzCKeKO5oudO4hyDNj+wzrOjqDFwK2nWYGVgS8Y0JgGietrw==", + "optional": true, "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" } }, - "@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" - }, - "@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "@smithy/signature-v4": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.0.10.tgz", + "integrity": "sha512-S6gcP4IXfO/VMswovrhxPpqvQvMal7ZRjM4NvblHSPpE5aNBYx67UkHFF3kg0hR3tJKqNpBGbxwq0gzpdHKLRA==", + "optional": true, "requires": { - "@hapi/hoek": "^9.0.0" + "@smithy/eventstream-codec": "^2.0.10", + "@smithy/is-array-buffer": "^2.0.0", + "@smithy/types": "^2.3.4", + "@smithy/util-hex-encoding": "^2.0.0", + "@smithy/util-middleware": "^2.0.3", + "@smithy/util-uri-escape": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" } }, - "@humanwhocodes/config-array": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", - "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", - "dev": true, + "@smithy/smithy-client": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.1.9.tgz", + "integrity": "sha512-HTicQSn/lOcXKJT+DKJ4YMu51S6PzbWsO8Z6Pwueo30mSoFKXg5P0BDkg2VCDqCVR0mtddM/F6hKhjW6YAV/yg==", + "optional": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } + "@smithy/middleware-stack": "^2.0.4", + "@smithy/types": "^2.3.4", + "@smithy/util-stream": "^2.0.14", + "tslib": "^2.5.0" } }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" - }, - "@mapbox/node-pre-gyp": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", - "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==", + "@smithy/types": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.3.4.tgz", + "integrity": "sha512-D7xlM9FOMFyFw7YnMXn9dK2KuN6+JhnrZwVt1fWaIu8hCk5CigysweeIT/H/nCo4YV+s8/oqUdLfexbkPZtvqw==", + "optional": true, "requires": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" + "tslib": "^2.5.0" } }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, + "@smithy/url-parser": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.0.10.tgz", + "integrity": "sha512-4TXQFGjHcqru8aH5VRB4dSnOFKCYNX6SR1Do6fwxZ+ExT2onLsh2W77cHpks7ma26W5jv6rI1u7d0+KX9F0aOw==", + "optional": true, "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@smithy/querystring-parser": "^2.0.10", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" } }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true + "@smithy/util-base64": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-2.0.0.tgz", + "integrity": "sha512-Zb1E4xx+m5Lud8bbeYi5FkcMJMnn+1WUnJF3qD7rAdXpaL7UjkFQLdmW5fHadoKbdHpwH9vSR8EyTJFHJs++tA==", + "optional": true, + "requires": { + "@smithy/util-buffer-from": "^2.0.0", + "tslib": "^2.5.0" + } }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, + "@smithy/util-body-length-browser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-2.0.0.tgz", + "integrity": "sha512-JdDuS4ircJt+FDnaQj88TzZY3+njZ6O+D3uakS32f2VNnDo3vyEuNdBOh/oFd8Df1zSZOuH1HEChk2AOYDezZg==", + "optional": true, "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "tslib": "^2.5.0" } }, - "@postman/form-data": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@postman/form-data/-/form-data-3.1.1.tgz", - "integrity": "sha512-vjh8Q2a8S6UCm/KKs31XFJqEEgmbjBmpPNVV2eVav6905wyFAwaUOBGA1NPBI4ERH9MMZc6w0umFgM6WbEPMdg==", - "dev": true, + "@smithy/util-body-length-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-2.1.0.tgz", + "integrity": "sha512-/li0/kj/y3fQ3vyzn36NTLGmUwAICb7Jbe/CsWCktW363gh1MOcpEcSO3mJ344Gv2dqz8YJCLQpb6hju/0qOWw==", + "optional": true, "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "tslib": "^2.5.0" } }, - "@postman/tunnel-agent": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@postman/tunnel-agent/-/tunnel-agent-0.6.3.tgz", - "integrity": "sha512-k57fzmAZ2PJGxfOA4SGR05ejorHbVAa/84Hxh/2nAztjNXc4ZjOm9NUIk6/Z6LCrBvJZqjRZbN8e/nROVUPVdg==", - "dev": true, + "@smithy/util-buffer-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.0.0.tgz", + "integrity": "sha512-/YNnLoHsR+4W4Vf2wL5lGv0ksg8Bmk3GEGxn2vEQt52AQaPSCuaO5PM5VM7lP1K9qHRKHwrPGktqVoAHKWHxzw==", + "optional": true, "requires": { - "safe-buffer": "^5.0.1" + "@smithy/is-array-buffer": "^2.0.0", + "tslib": "^2.5.0" } }, - "@sideway/address": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", - "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "@smithy/util-config-provider": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-2.0.0.tgz", + "integrity": "sha512-xCQ6UapcIWKxXHEU4Mcs2s7LcFQRiU3XEluM2WcCjjBtQkUN71Tb+ydGmJFPxMUrW/GWMgQEEGipLym4XG0jZg==", + "optional": true, "requires": { - "@hapi/hoek": "^9.0.0" + "tslib": "^2.5.0" } }, - "@sideway/formula": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + "@smithy/util-defaults-mode-browser": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.13.tgz", + "integrity": "sha512-UmmOdUzaQjqdsl1EjbpEaQxM0VDFqTj6zDuI26/hXN7L/a1k1koTwkYpogHMvunDX3fjrQusg5gv1Td4UsGyog==", + "optional": true, + "requires": { + "@smithy/property-provider": "^2.0.11", + "@smithy/smithy-client": "^2.1.9", + "@smithy/types": "^2.3.4", + "bowser": "^2.11.0", + "tslib": "^2.5.0" + } }, - "@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + "@smithy/util-defaults-mode-node": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.15.tgz", + "integrity": "sha512-g6J7MHAibVPMTlXyH3mL+Iet4lMJKFVhsOhJmn+IKG81uy9m42CkRSDlwdQSJAcprLQBIaOPdFxNXQvrg2w1Uw==", + "optional": true, + "requires": { + "@smithy/config-resolver": "^2.0.11", + "@smithy/credential-provider-imds": "^2.0.13", + "@smithy/node-config-provider": "^2.0.13", + "@smithy/property-provider": "^2.0.11", + "@smithy/smithy-client": "^2.1.9", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" + } }, - "@sinonjs/commons": { + "@smithy/util-hex-encoding": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-2.0.0.tgz", + "integrity": "sha512-c5xY+NUnFqG6d7HFh1IFfrm3mGl29lC+vF+geHv4ToiuJCBmIfzx6IeHLg+OgRdPFKDXIw6pvi+p3CsscaMcMA==", + "optional": true, "requires": { - "type-detect": "4.0.8" + "tslib": "^2.5.0" } }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, + "@smithy/util-middleware": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.0.3.tgz", + "integrity": "sha512-+FOCFYOxd2HO7v/0hkFSETKf7FYQWa08wh/x/4KUeoVBnLR4juw8Qi+TTqZI6E2h5LkzD9uOaxC9lAjrpVzaaA==", + "optional": true, "requires": { - "@sinonjs/commons": "^1.7.0" - }, - "dependencies": { - "@sinonjs/commons": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.5.tgz", - "integrity": "sha512-rTpCA0wG1wUxglBSFdMMY0oTrKYvgf4fNgv/sXbfCVAdf+FnPBdKJR/7XbpTCwbCrvCbdPYnlWaUUYz4V2fPDA==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - } + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" } }, - "@sinonjs/samsam": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-7.0.1.tgz", - "integrity": "sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==", - "dev": true, + "@smithy/util-retry": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.0.3.tgz", + "integrity": "sha512-gw+czMnj82i+EaH7NL7XKkfX/ZKrCS2DIWwJFPKs76bMgkhf0y1C94Lybn7f8GkBI9lfIOUdPYtzm19zQOC8sw==", + "optional": true, "requires": { - "@sinonjs/commons": "^2.0.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" + "@smithy/service-error-classification": "^2.0.3", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" } }, - "@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true + "@smithy/util-stream": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.0.14.tgz", + "integrity": "sha512-XjvlDYe+9DieXhLf7p+EgkXwFtl34kHZcWfHnc5KaILbhyVfDLWuqKTFx6WwCFqb01iFIig8trGwExRIqqkBYg==", + "optional": true, + "requires": { + "@smithy/fetch-http-handler": "^2.2.1", + "@smithy/node-http-handler": "^2.1.6", + "@smithy/types": "^2.3.4", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-buffer-from": "^2.0.0", + "@smithy/util-hex-encoding": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" + } }, - "@smithy/protocol-http": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-1.0.1.tgz", - "integrity": "sha512-9OrEn0WfOVtBNYJUjUAn9AOiJ4lzERCJJ/JeZs8E6yajTGxBaFRxUnNBHiNqoDJVg076hY36UmEnPx7xXrvUSg==", + "@smithy/util-uri-escape": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-2.0.0.tgz", + "integrity": "sha512-ebkxsqinSdEooQduuk9CbKcI+wheijxEb3utGXkCoYQkJnwTnLbH1JXGimJtUkQwNQbsbuYwG2+aFVyZf5TLaw==", "optional": true, "requires": { - "@smithy/types": "^1.0.0", "tslib": "^2.5.0" } }, - "@smithy/types": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-1.0.0.tgz", - "integrity": "sha512-kc1m5wPBHQCTixwuaOh9vnak/iJm21DrSf9UK6yDE5S3mQQ4u11pqAUiKWnlrZnYkeLfAI9UEHj9OaMT1v5Umg==", + "@smithy/util-utf8": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.0.0.tgz", + "integrity": "sha512-rctU1VkziY84n5OXe3bPNpKR001ZCME2JCaBBFgtiM2hfKbHFudc/BkMuPab8hRbLd0j3vbnBTTZ1igBf0wgiQ==", "optional": true, "requires": { + "@smithy/util-buffer-from": "^2.0.0", "tslib": "^2.5.0" } }, "@types/node": { - "version": "18.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.6.tgz", - "integrity": "sha512-j3CEDa2vd96K0AXF8Wur7UucACvnjkk8hYyQAHhUNciabZLDl9nfAEVUSwmh245OOZV15bRA3Y590Gi5jUcDJg==" + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz", + "integrity": "sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==" }, "@types/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.1.tgz", + "integrity": "sha512-8hKOnOan+Uu+NgMaCouhg3cT9x5fFZ92Jwf+uDLXLu/MFRbXxlWwGeQY7KVHkeSft6RvY+tdxklUBuyY9eIEKg==" }, "@types/whatwg-url": { "version": "8.2.2", @@ -8436,9 +8605,9 @@ "dev": true }, "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", "dev": true }, "balanced-match": { @@ -8561,9 +8730,9 @@ "dev": true }, "bson": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.0.tgz", - "integrity": "sha512-VrlEE4vuiO1WTpfof4VmaVolCVYkYTgB9iWgYNOrVlnifpME/06fhFRmONgBhClD5pFC1t9ZWqFUQEQAzY43bA==", + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.2.tgz", + "integrity": "sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==", "requires": { "buffer": "^5.6.0" } @@ -8631,9 +8800,9 @@ } }, "chardet": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-1.4.0.tgz", - "integrity": "sha512-NpwMDdSIprbYx1CLnfbxEIarI0Z+s9MssEgggMNheGM+WD68yOhV7IEA/3r6tr0yTRgQD0HuZJDw32s99i6L+A==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-1.6.0.tgz", + "integrity": "sha512-+QOTw3otC4+FxdjK9RopGpNOglADbr4WPFi0SonkO99JbpkTPbMxmdm4NenhF5Zs+4gPXLI1+y2uazws5TMe8w==", "dev": true }, "charset": { @@ -8675,21 +8844,21 @@ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" }, "cli-progress": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.10.0.tgz", - "integrity": "sha512-kLORQrhYCAtUPLZxqsAt2YJGOvRdt34+O6jl5cQGb7iF3dM55FQZlTR+rQyIK9JUcO9bBMwZsTlND+3dmFU2Cw==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.12.0.tgz", + "integrity": "sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==", "dev": true, "requires": { - "string-width": "^4.2.0" + "string-width": "^4.2.3" } }, "cli-table3": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz", - "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", "dev": true, "requires": { - "colors": "1.4.0", + "@colors/colors": "1.5.0", "string-width": "^4.2.0" } }, @@ -8739,9 +8908,9 @@ } }, "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz", + "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==", "dev": true }, "compress-commons": { @@ -8873,16 +9042,21 @@ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" }, - "denque": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==" - }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, + "des.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, "destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -9155,12 +9329,6 @@ "integrity": "sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==", "dev": true }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -9226,12 +9394,6 @@ "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", "dev": true }, - "faker": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz", - "integrity": "sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g==", - "dev": true - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -9275,9 +9437,9 @@ "dev": true }, "fast-xml-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.4.tgz", - "integrity": "sha512-fbfMDvgBNIdDJLdLOwacjFAPYt67tr31H9ZhWSm45CDAxvd0I6WTlSOUo7K2P/K5sA5JgMKG64PI3DMcaFdWpQ==", + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz", + "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==", "optional": true, "requires": { "strnum": "^1.0.5" @@ -9325,9 +9487,9 @@ "dev": true }, "filesize": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", - "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", + "version": "10.0.12", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.0.12.tgz", + "integrity": "sha512-6RS9gDchbn+qWmtV2uSjo5vmKizgfCQeb5jKmqx8HyzA3MoLqqyQxN+QcjkGBJt7FjJ9qFce67Auyya5rRRbpw==", "dev": true }, "fill-range": { @@ -9858,13 +10020,13 @@ } }, "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, "requires": { "minimist": "^1.2.5", - "neo-async": "^2.6.0", + "neo-async": "^2.6.2", "source-map": "^0.6.1", "uglify-js": "^3.1.4", "wordwrap": "^1.0.0" @@ -9961,19 +10123,21 @@ } }, "httpntlm": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.7.7.tgz", - "integrity": "sha512-Pv2Rvrz8H0qv1Dne5mAdZ9JegG1uc6Vu5lwLflIY6s8RKHdZQbW39L4dYswSgqMDT0pkJILUTKjeyU0VPNRZjA==", + "version": "1.8.13", + "resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.8.13.tgz", + "integrity": "sha512-2F2FDPiWT4rewPzNMg3uPhNkP3NExENlUGADRUDPQvuftuUTGW98nLZtGemCIW3G40VhWZYgkIDcQFAwZ3mf2Q==", "dev": true, "requires": { + "des.js": "^1.0.1", "httpreq": ">=0.4.22", + "js-md4": "^0.3.2", "underscore": "~1.12.1" } }, "httpreq": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/httpreq/-/httpreq-0.5.2.tgz", - "integrity": "sha512-2Jm+x9WkExDOeFRrdBCBSpLPT5SokTcRHkunV3pjKmX/cx6av8zQ0WtHUMDrYb6O4hBFzNU6sxJEypvRUVYKnw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/httpreq/-/httpreq-1.1.1.tgz", + "integrity": "sha512-uhSZLPPD2VXXOSN8Cni3kIsoFHaU2pT/nySEU/fHr/ePbqHYr0jeiQRmUKLEirC09SFPsdMoA7LU7UXMd/w0Kw==", "dev": true }, "https-proxy-agent": { @@ -10072,12 +10236,6 @@ "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==", - "dev": true - }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -10224,6 +10382,18 @@ "@sideway/pinpoint": "^2.0.0" } }, + "jose": { + "version": "4.14.4", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.14.4.tgz", + "integrity": "sha512-j8GhLiKmUAh+dsFXlX1aJCbt5KMibuKb+d7j1JaOJG6s2UjX1PQlW+OKB/sD4a/5ZYF4RcmYmLSndOoU3Lt/3g==", + "dev": true + }, + "js-md4": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/js-md4/-/js-md4-0.3.2.tgz", + "integrity": "sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA==", + "dev": true + }, "js-sdsl": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", @@ -10506,9 +10676,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" } } }, @@ -10603,6 +10773,12 @@ "mime-db": "1.52.0" } }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -10750,22 +10926,21 @@ } }, "mongodb": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.11.0.tgz", - "integrity": "sha512-9l9n4Nk2BYZzljW3vHah3Z0rfS5npKw6ktnkmFgTcnzaXH1DRm3pDl6VMHu84EVb1lzmSaJC4OzWZqTkB5i2wg==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.17.1.tgz", + "integrity": "sha512-MBuyYiPUPRTqfH2dV0ya4dcr2E5N52ocBuZ8Sgg/M030nGF78v855B3Z27mZJnp8PxjnUquEnAtjOsphgMZOlQ==", "requires": { "@aws-sdk/credential-providers": "^3.186.0", - "bson": "^4.7.0", - "denque": "^2.1.0", - "mongodb-connection-string-url": "^2.5.4", - "saslprep": "^1.0.3", + "@mongodb-js/saslprep": "^1.1.0", + "bson": "^4.7.2", + "mongodb-connection-string-url": "^2.6.0", "socks": "^2.7.1" } }, "mongodb-connection-string-url": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.4.tgz", - "integrity": "sha512-SeAxuWs0ez3iI3vvmLk/j2y+zHwigTDKQhtdxTgt5ZCOQQS5+HW4g45/Xw5vzzbn7oQXCNQ24Z40AkJsizEy7w==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", "requires": { "@types/whatwg-url": "^8.2.1", "whatwg-url": "^11.0.0" @@ -10849,48 +11024,39 @@ "dev": true }, "newman": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/newman/-/newman-5.3.2.tgz", - "integrity": "sha512-cWy8pV0iwvMOZLTw3hkAHcwo2ZA0GKkXm8oUMn1Ltii3ZI2nKpnrg9QGdIT0hGHChRkX6prY5e3Aar7uykMGNg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/newman/-/newman-6.0.0.tgz", + "integrity": "sha512-QaANQC5b6ga348MezIVRI9ZmMs+cg3MdYIp0tSEauH2tmWOAR9+cghNsFJNjU9JPui3jJp1ALC7pQq6g3Jqpxw==", "dev": true, "requires": { - "async": "3.2.3", - "chardet": "1.4.0", - "cli-progress": "3.10.0", - "cli-table3": "0.6.1", + "@postman/tough-cookie": "4.1.3-postman.1", + "async": "3.2.4", + "chardet": "1.6.0", + "cli-progress": "3.12.0", + "cli-table3": "0.6.3", "colors": "1.4.0", - "commander": "7.2.0", + "commander": "11.0.0", "csv-parse": "4.16.3", - "eventemitter3": "4.0.7", - "filesize": "8.0.7", + "filesize": "10.0.12", + "liquid-json": "0.3.1", "lodash": "4.17.21", - "mkdirp": "1.0.4", - "postman-collection": "4.1.1", - "postman-collection-transformer": "4.1.6", - "postman-request": "2.88.1-postman.31", - "postman-runtime": "7.29.0", + "mkdirp": "3.0.1", + "postman-collection": "4.2.1", + "postman-collection-transformer": "4.1.7", + "postman-request": "2.88.1-postman.33", + "postman-runtime": "7.33.0", "pretty-ms": "7.0.1", - "semver": "7.3.5", + "semver": "7.5.4", "serialised-error": "1.1.3", - "tough-cookie": "3.0.1", - "word-wrap": "1.2.3", + "word-wrap": "1.2.5", "xmlbuilder": "15.1.1" }, "dependencies": { - "async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", + "mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } } } }, @@ -10964,9 +11130,9 @@ "dev": true }, "nodemon": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", - "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", + "integrity": "sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==", "dev": true, "requires": { "chokidar": "^3.5.2", @@ -10974,8 +11140,8 @@ "ignore-by-default": "^1.0.1", "minimatch": "^3.1.2", "pstree.remy": "^1.1.8", - "semver": "^5.7.1", - "simple-update-notifier": "^1.0.7", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", "supports-color": "^5.5.0", "touch": "^3.1.0", "undefsafe": "^2.0.5" @@ -11002,12 +11168,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -11272,21 +11432,21 @@ "dev": true }, "postman-collection": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.1.1.tgz", - "integrity": "sha512-ODpJtlf8r99DMcTU7gFmi/yvQYckFzcuE6zL/fWnyrFT34ugdCBFlX+DN7M+AnP6lmR822fv5s60H4DnL4+fAg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.2.1.tgz", + "integrity": "sha512-DFLt3/yu8+ldtOTIzmBUctoupKJBOVK4NZO0t68K2lIir9smQg7OdQTBjOXYy+PDh7u0pSDvD66tm93eBHEPHA==", "dev": true, "requires": { - "faker": "5.5.3", + "@faker-js/faker": "5.5.3", "file-type": "3.9.0", "http-reasons": "0.1.0", "iconv-lite": "0.6.3", "liquid-json": "0.3.1", "lodash": "4.17.21", "mime-format": "2.0.1", - "mime-types": "2.1.34", + "mime-types": "2.1.35", "postman-url-encoder": "3.0.5", - "semver": "7.3.5", + "semver": "7.5.4", "uuid": "8.3.2" }, "dependencies": { @@ -11299,30 +11459,6 @@ "safer-buffer": ">= 2.1.2 < 3.0.0" } }, - "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true - }, - "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, - "requires": { - "mime-db": "1.51.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -11332,15 +11468,15 @@ } }, "postman-collection-transformer": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/postman-collection-transformer/-/postman-collection-transformer-4.1.6.tgz", - "integrity": "sha512-xvdQb6sZoWcG9xZXUPSuxocjcd6WCZlINlGGiuHdSfxhgiwQhj9qhF0JRFbagZ8xB0+pYUairD5MiCENc6DEVA==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/postman-collection-transformer/-/postman-collection-transformer-4.1.7.tgz", + "integrity": "sha512-SxJkm/LnlFZs2splUBnS4jQFicgBptghpm4voHtNnaum3Ad64E2MHLV4fJhv58dVUmFwdSwdQUN3m2q0iLecnQ==", "dev": true, "requires": { "commander": "8.3.0", "inherits": "2.0.4", "lodash": "4.17.21", - "semver": "7.3.5", + "semver": "7.5.4", "strip-json-comments": "3.1.1" }, "dependencies": { @@ -11349,29 +11485,21 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } } } }, "postman-request": { - "version": "2.88.1-postman.31", - "resolved": "https://registry.npmjs.org/postman-request/-/postman-request-2.88.1-postman.31.tgz", - "integrity": "sha512-OJbYqP7ItxQ84yHyuNpDywCZB0HYbpHJisMQ9lb1cSL3N5H3Td6a2+3l/a74UMd3u82BiGC5yQyYmdOIETP/nQ==", + "version": "2.88.1-postman.33", + "resolved": "https://registry.npmjs.org/postman-request/-/postman-request-2.88.1-postman.33.tgz", + "integrity": "sha512-uL9sCML4gPH6Z4hreDWbeinKU0p0Ke261nU7OvII95NU22HN6Dk7T/SaVPaj6T4TsQqGKIFw6/woLZnH7ugFNA==", "dev": true, "requires": { "@postman/form-data": "~3.1.1", + "@postman/tough-cookie": "~4.1.3-postman.1", "@postman/tunnel-agent": "^0.6.3", "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "brotli": "~1.3.2", + "aws4": "^1.12.0", + "brotli": "^1.3.3", "caseless": "~0.12.0", "combined-stream": "~1.0.6", "extend": "~3.0.2", @@ -11381,14 +11509,13 @@ "is-typedarray": "~1.0.0", "isstream": "~0.1.2", "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", + "mime-types": "^2.1.35", "oauth-sign": "~0.9.0", "performance-now": "^2.1.0", - "qs": "~6.5.2", + "qs": "~6.5.3", "safe-buffer": "^5.1.2", "stream-length": "^1.0.2", - "tough-cookie": "~2.5.0", - "uuid": "^3.3.2" + "uuid": "^8.3.2" }, "dependencies": { "qs": { @@ -11397,67 +11524,66 @@ "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true } } }, "postman-runtime": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/postman-runtime/-/postman-runtime-7.29.0.tgz", - "integrity": "sha512-eXxHREE/fUpohkGPRgBY1YccSGx9cyW3mtGiPyIE4zD5fYzasgBHqW6kbEND3Xrd3yf/uht/YI1H8O7J1+A1+w==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/postman-runtime/-/postman-runtime-7.33.0.tgz", + "integrity": "sha512-cYCb+5Y12FwZU/T3gOj2SKiOz38pisVLc0tdppb+ZlG7iqn5aLgxghJwhjG62pZCV6uixKiQX1hNdLSk9a9Xtw==", "dev": true, "requires": { - "async": "3.2.3", - "aws4": "1.11.0", - "handlebars": "4.7.7", - "httpntlm": "1.7.7", + "@postman/tough-cookie": "4.1.3-postman.1", + "async": "3.2.4", + "aws4": "1.12.0", + "handlebars": "4.7.8", + "httpntlm": "1.8.13", + "jose": "4.14.4", "js-sha512": "0.8.0", "lodash": "4.17.21", - "mime-types": "2.1.34", + "mime-types": "2.1.35", "node-oauth1": "1.3.0", "performance-now": "2.1.0", - "postman-collection": "4.1.1", - "postman-request": "2.88.1-postman.31", - "postman-sandbox": "4.0.6", + "postman-collection": "4.2.0", + "postman-request": "2.88.1-postman.33", + "postman-sandbox": "4.2.7", "postman-url-encoder": "3.0.5", "serialised-error": "1.1.3", - "tough-cookie": "3.0.1", + "strip-json-comments": "3.1.1", "uuid": "8.3.2" }, "dependencies": { - "async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", - "dev": true - }, - "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } }, - "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "postman-collection": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.2.0.tgz", + "integrity": "sha512-tvOLgN1h6Kab6dt43PmBoV5kYO/YUta3x0C2QqfmbzmHZe47VTpZ/+gIkGlbNhjKNPUUub5X6ehxYKoaTYdy1w==", "dev": true, "requires": { - "mime-db": "1.51.0" + "@faker-js/faker": "5.5.3", + "file-type": "3.9.0", + "http-reasons": "0.1.0", + "iconv-lite": "0.6.3", + "liquid-json": "0.3.1", + "lodash": "4.17.21", + "mime-format": "2.0.1", + "mime-types": "2.1.35", + "postman-url-encoder": "3.0.5", + "semver": "7.5.4", + "uuid": "8.3.2" } }, "uuid": { @@ -11469,14 +11595,51 @@ } }, "postman-sandbox": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/postman-sandbox/-/postman-sandbox-4.0.6.tgz", - "integrity": "sha512-PPRanSNEE4zy3kO7CeSBHmAfJnGdD9ecHY/Mjh26CQuZZarGkNO8c0U/n+xX3+5M1BRNc82UYq6YCtdsSDqcng==", + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/postman-sandbox/-/postman-sandbox-4.2.7.tgz", + "integrity": "sha512-/EcCrKnb/o+9iLS4u+H76E0kBomJFjPptVjoDiq1uZ7Es/4aTv0MAX+0aoDxdDO+0h9sl8vy65uKQwyjN7AOaw==", "dev": true, "requires": { "lodash": "4.17.21", + "postman-collection": "4.2.0", "teleport-javascript": "1.0.0", - "uvm": "2.0.2" + "uvm": "2.1.1" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "postman-collection": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.2.0.tgz", + "integrity": "sha512-tvOLgN1h6Kab6dt43PmBoV5kYO/YUta3x0C2QqfmbzmHZe47VTpZ/+gIkGlbNhjKNPUUub5X6ehxYKoaTYdy1w==", + "dev": true, + "requires": { + "@faker-js/faker": "5.5.3", + "file-type": "3.9.0", + "http-reasons": "0.1.0", + "iconv-lite": "0.6.3", + "liquid-json": "0.3.1", + "lodash": "4.17.21", + "mime-format": "2.0.1", + "mime-types": "2.1.35", + "postman-url-encoder": "3.0.5", + "semver": "7.5.4", + "uuid": "8.3.2" + } + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + } } }, "postman-url-encoder": { @@ -11548,6 +11711,12 @@ "side-channel": "^1.0.4" } }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -11648,6 +11817,12 @@ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -11708,15 +11883,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "saslprep": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", - "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", - "optional": true, - "requires": { - "sparse-bitfield": "^3.0.3" - } - }, "semaphore": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", @@ -11724,9 +11890,9 @@ "dev": true }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "requires": { "lru-cache": "^6.0.0" } @@ -11838,20 +12004,12 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "simple-update-notifier": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz", - "integrity": "sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", "dev": true, "requires": { - "semver": "~7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true - } + "semver": "^7.5.3" } }, "sinon": { @@ -12090,26 +12248,15 @@ } } }, - "tough-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", - "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", - "dev": true, - "requires": { - "ip-regex": "^2.1.0", - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "optional": true }, "tweetnacl": { @@ -12182,6 +12329,12 @@ "util-deprecate": "^1.0.2" } }, + "universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -12202,6 +12355,16 @@ "integrity": "sha512-8pMuAn4KacYdGMkFaoQARicp4HSw24/DHOVKWqVRJ8LhhAwPPFpdGvdL9184JVmUwe7vz7Z9n6IqI6t5n2ELdg==", "dev": true }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -12218,18 +12381,18 @@ "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" }, "uvm": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/uvm/-/uvm-2.0.2.tgz", - "integrity": "sha512-Ra+aPiS5GXAbwXmyNExqdS42sTqmmx4XWEDF8uJlsTfOkKf9Rd9xNgav1Yckv4HfVEZg4iOFODWHFYuJ+9Fzfg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/uvm/-/uvm-2.1.1.tgz", + "integrity": "sha512-BZ5w8adTpNNr+zczOBRpaX/hH8UPKAf7fmCnidrcsqt3bn8KT9bDIfuS7hgRU9RXgiN01su2pwysBONY6w8W5w==", "dev": true, "requires": { - "flatted": "3.1.1" + "flatted": "3.2.6" }, "dependencies": { "flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz", + "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", "dev": true } } @@ -12291,9 +12454,9 @@ } }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, "wordwrap": { diff --git a/package.json b/package.json index 57b5ea4..dce9fae 100644 --- a/package.json +++ b/package.json @@ -51,8 +51,8 @@ "minimist": "^1.2.6", "mocha": "^9.2.2", "mocha.parallel": "^0.15.6", - "newman": "^5.3.2", - "nodemon": "^2.0.19", + "newman": "^6.0.0", + "nodemon": "^3.0.1", "sinon": "^14.0.2" } -} \ No newline at end of file +} From 417dd00a4704c5cd3e226d1c1b47993b707f5e93 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sat, 28 Oct 2023 11:46:21 +0200 Subject: [PATCH 029/186] close handler added. See #337 --- index.js | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 99c5158..619c383 100644 --- a/index.js +++ b/index.js @@ -202,6 +202,12 @@ const init_db = () => { // feedback logger.info(`Connected to "mongodb://${url.hostname}:${url.port}${url.pathname}"`); + process.once("SIGINT", () => { + mongodb.connection.close(() => { + logger.info(`Connection closed from "mongodb://${url.hostname}:${url.port}${url.pathname}"`); + }); + }); + resolve(); } catch (err) { @@ -324,6 +330,10 @@ const init_http = () => { }); + server.on("close", () => { + logger.info(`HTTP Server closed on http://${process.env.HTTP_ADDRESS}:${process.env.HTTP_PORT}`); + }); + require("./routes")(server); // bind/start http server @@ -355,6 +365,10 @@ const init_http = () => { }); + server.on("close", () => { + logger.info(`HTTP Server closed on ${process.env.HTTP_SOCKET}`); + }); + require("./routes")(server); try { @@ -382,7 +396,13 @@ const init_http = () => { ]; - Promise.all(servers).then(() => { + Promise.all(servers).then((servers) => { + + process.once("SIGINT", () => { + servers.forEach((server) => { + server.close(); + }); + }); resolve(); @@ -398,6 +418,9 @@ const init_http = () => { }; +// NOTE: Could/should be removed +// was only used in the early state of developing without the plugin component/system +/* const kickstart = () => { try { @@ -419,6 +442,7 @@ const kickstart = () => { } }; +*/ const starter = new Promise((resolve) => { @@ -456,7 +480,7 @@ const starter = new Promise((resolve) => { init_db, // phase 1 init_components, // phase 2 init_http, // phase 3 - kickstart + //kickstart ].reduce((cur, prev, i) => { return cur.then(prev).catch((err) => { @@ -518,4 +542,11 @@ const starter = new Promise((resolve) => { logger.info("Startup complete"); + process.once("SIGINT", () => { + logger.warn("Shuting down..."); + setTimeout(() => { + process.exit(); + }, 1000); + }); + }); From bad9712b14d641c06e3f2de8c442b6ef587ae0b8 Mon Sep 17 00:00:00 2001 From: mStirner Date: Thu, 16 Nov 2023 21:24:14 +0100 Subject: [PATCH 030/186] fix #87 --- index.js | 285 +--------------------------- system/component/class.component.js | 2 +- system/init/init.components.js | 77 ++++++++ system/init/init.database.js | 90 +++++++++ system/init/init.http-server.js | 118 ++++++++++++ 5 files changed, 289 insertions(+), 283 deletions(-) create mode 100644 system/init/init.components.js create mode 100644 system/init/init.database.js create mode 100644 system/init/init.http-server.js diff --git a/index.js b/index.js index 619c383..ce61883 100644 --- a/index.js +++ b/index.js @@ -1,13 +1,9 @@ const path = require("path"); -const http = require("http"); -const fs = require("fs"); const readline = require("readline"); const process = require("process"); -const mongodb = require("mongodb"); const pkg = require("./package.json"); const { exec } = require("child_process"); const uuid = require("uuid"); -const { URL } = require("url"); const env = require("dotenv").config({ @@ -141,281 +137,9 @@ if (process.env.GC_INTERVAL !== null && global.gc) { } -const init_db = () => { - return new Promise((resolve, reject) => { - - logger.debug("Init Database..."); - - let url = new URL(`mongodb://${process.env.DATABASE_HOST}:${process.env.DATABASE_PORT}/${process.env.DATABASE_NAME}`); - - if (process.env.DATABASE_AUTH_USERNAME) { - url.username = process.env.DATABASE_AUTH_USERNAME; - } - - if (process.env.DATABASE_AUTH_USERNAME) { - url.password = process.env.DATABASE_AUTH_PASSWORD; - } - - if (process.env.DATABASE_URL) { - console.log("OVerride DATBAASE_URL"); - Object.assign(url, new URL(process.env.DATABASE_URL)); - } - - // feedback - logger.verbose(`Connecting to "%s"...`, url.toString()); - - - mongodb.MongoClient.connect(url.toString(), { - useUnifiedTopology: true, - useNewUrlParser: true, - //connectTimeoutMS: Number(process.env.DATABASE_TIMEOUT) * 1000, // #9 - //socketTimeoutMS: Number(process.env.DATABASE_TIMEOUT) * 1000 // #9 - }, async (err, client) => { - - if (err) { - logger.error(err, "Could not connect to database"); - return reject(err); - } - - // monky patch db instance - // use this instance in other files - //mongodb.client = client.db(process.env.DATABASE_NAME); - mongodb.connection = client; - mongodb.client = client.db(); - - - client.on("error", (err) => { - logger.error(err, "Could not connecto to databse: %s", err.message); - }); - - client.on("close", () => { - process.exit(1000); - }); - - - try { - - // test authenticiation - // throws a error is auth is noc successfull - await mongodb.client.stats(); - - // feedback - logger.info(`Connected to "mongodb://${url.hostname}:${url.port}${url.pathname}"`); - - process.once("SIGINT", () => { - mongodb.connection.close(() => { - logger.info(`Connection closed from "mongodb://${url.hostname}:${url.port}${url.pathname}"`); - }); - }); - - resolve(); - - } catch (err) { - - if (err?.code == 13) { - logger.error("Invalid database credentials!"); - } - - client.emit("error", err); - reject(err); - - } - - - }); - - }); -}; - - -const init_components = () => { - return new Promise((resolve) => { - - logger.debug("Init components..."); - - const componentNames = [ - "devices", - "endpoints", - "plugins", - "rooms", - "ssdp", - "store", - "users", - "vault", - "webhooks", - "mqtt", - "mdns", - "scenes" - ].sort(() => { - - // pseudo randomize start/init of components - // https://stackoverflow.com/a/18650169/5781499 - return 0.5 - Math.random(); - - }); - - let componentConter = 0; - //let counter = componentNames.length; - - - // map over array - // create from each promise - // use Promise.all() ? - // better/quicker start? - componentNames.forEach((name) => { - try { - - // this should be trace method - logger.verbose(`Starting component "${name}"`); - - let component = require(`./components/${name}/index.js`); - - component.events.on("ready", () => { - - componentConter += 1; - - logger.debug(`Component "${name}" ready to use. (${componentConter}/${componentNames.length})`); - - if (componentConter === componentNames.length) { - logger.info(`All ${componentNames.length} Components ready`); - resolve(); - } - - }); - - // see issue #53, this should fire: - // the procces should not exit with a "unhandled execption" - // the try/catch block is for unhandled exception, not for startup errors - component.events.on("error", (err) => { - logger.error(err, `Component "${name}" error!`); - process.exit(1); // fix #53 - }); - - } catch (err) { - - console.error(err, "Component error"); - process.exit(800); - - } - }); - - }); -}; - - -const init_http = () => { - return new Promise((resolve, reject) => { - - logger.debug("Init http server..."); - - const servers = [ - - // http server for ip/port - new Promise((resolve, reject) => { - if (process.env.HTTP_ADDRESS !== "") { - - let server = http.createServer(); - - server.on("error", (err) => { - logger.error(err, `Could not start http server: ${err.message}`); - reject(err); - }); - - server.on("listening", () => { - - let addr = server.address(); - logger.info(`HTTP Server listening on http://${addr.address}:${addr.port}`); - - resolve(server); - - }); - - server.on("close", () => { - logger.info(`HTTP Server closed on http://${process.env.HTTP_ADDRESS}:${process.env.HTTP_PORT}`); - }); - - require("./routes")(server); - - // bind/start http server - server.listen(Number(process.env.HTTP_PORT), process.env.HTTP_ADDRESS); - - } else { - resolve(); - } - }), - - // http server fo unix socket - new Promise((resolve, reject) => { - if (process.env.HTTP_SOCKET !== "") { - - let server = http.createServer(); - - server.on("error", (err) => { - - logger.error(err, `Could not start http server: ${err.message}`); - reject(err); - - }); - - server.on("listening", () => { - - logger.info(`HTTP Server listening on ${process.env.HTTP_SOCKET}`); - - resolve(server); - - }); - - server.on("close", () => { - logger.info(`HTTP Server closed on ${process.env.HTTP_SOCKET}`); - }); - - require("./routes")(server); - - try { - - // cleanup - fs.unlinkSync(process.env.HTTP_SOCKET); - - } catch (err) { - if (err.code !== "ENOENT") { - - reject(err); - - } - } finally { - - // bind/start http server - server.listen(process.env.HTTP_SOCKET); - - } - - } else { - resolve(); - } - }) - - ]; - - Promise.all(servers).then((servers) => { - - process.once("SIGINT", () => { - servers.forEach((server) => { - server.close(); - }); - }); - - resolve(); - - }).catch((err) => { - - logger.error(err, "Could not start http server(s)", err); - - reject(err); - - }); - - }); -}; +const init_db = require("./system/init/init.database.js")(logger); +const init_components = require("./system/init/init.components.js")(logger); +const init_http = require("./system/init/init.http-server.js")(logger); // NOTE: Could/should be removed @@ -544,9 +268,6 @@ const starter = new Promise((resolve) => { process.once("SIGINT", () => { logger.warn("Shuting down..."); - setTimeout(() => { - process.exit(); - }, 1000); }); }); diff --git a/system/component/class.component.js b/system/component/class.component.js index 5abc169..b640008 100644 --- a/system/component/class.component.js +++ b/system/component/class.component.js @@ -47,7 +47,7 @@ module.exports = class COMPONENT extends COMMON { constructor(name, schema, parent) { if (parent) { - require("../prevent_cross_load")(parent); + //require("../prevent_cross_load")(parent); } super(require("../../system/logger").create(name)); diff --git a/system/init/init.components.js b/system/init/init.components.js new file mode 100644 index 0000000..513e018 --- /dev/null +++ b/system/init/init.components.js @@ -0,0 +1,77 @@ +const path = require("path"); + +module.exports = (logger) => { + return () => { + return new Promise((resolve) => { + + logger.debug("Init components..."); + + const componentNames = [ + "devices", + "endpoints", + "plugins", + "rooms", + "ssdp", + "store", + "users", + "vault", + "webhooks", + "mqtt", + "mdns", + "scenes" + ].sort(() => { + + // pseudo randomize start/init of components + // https://stackoverflow.com/a/18650169/5781499 + return 0.5 - Math.random(); + + }); + + let componentConter = 0; + //let counter = componentNames.length; + + + // map over array + // create from each promise + // use Promise.all() ? + // better/quicker start? + componentNames.forEach((name) => { + try { + + // this should be trace method + logger.verbose(`Starting component "${name}"`); + + let component = require(path.resolve(process.cwd(), `components/${name}/index.js`)); + + component.events.on("ready", () => { + + componentConter += 1; + + logger.debug(`Component "${name}" ready to use. (${componentConter}/${componentNames.length})`); + + if (componentConter === componentNames.length) { + logger.info(`All ${componentNames.length} Components ready`); + resolve(); + } + + }); + + // see issue #53, this should fire: + // the procces should not exit with a "unhandled execption" + // the try/catch block is for unhandled exception, not for startup errors + component.events.on("error", (err) => { + logger.error(err, `Component "${name}" error!`); + process.exit(1); // fix #53 + }); + + } catch (err) { + + console.error(err, "Component error"); + process.exit(800); + + } + }); + + }); + }; +}; \ No newline at end of file diff --git a/system/init/init.database.js b/system/init/init.database.js new file mode 100644 index 0000000..a77a96f --- /dev/null +++ b/system/init/init.database.js @@ -0,0 +1,90 @@ +const mongodb = require("mongodb"); +const { URL } = require("url"); + +module.exports = (logger) => { + return () => { + return new Promise((resolve, reject) => { + + logger.debug("Init Database..."); + + let url = new URL(`mongodb://${process.env.DATABASE_HOST}:${process.env.DATABASE_PORT}/${process.env.DATABASE_NAME}`); + + if (process.env.DATABASE_AUTH_USERNAME) { + url.username = process.env.DATABASE_AUTH_USERNAME; + } + + if (process.env.DATABASE_AUTH_USERNAME) { + url.password = process.env.DATABASE_AUTH_PASSWORD; + } + + if (process.env.DATABASE_URL) { + console.log("OVerride DATBAASE_URL"); + Object.assign(url, new URL(process.env.DATABASE_URL)); + } + + // feedback + logger.verbose(`Connecting to "mongodb://${url.hostname}:${url.port}${url.pathname}"...`); + + + mongodb.MongoClient.connect(url.toString(), { + useUnifiedTopology: true, + useNewUrlParser: true, + //connectTimeoutMS: Number(process.env.DATABASE_TIMEOUT) * 1000, // #9 + //socketTimeoutMS: Number(process.env.DATABASE_TIMEOUT) * 1000 // #9 + }, async (err, client) => { + + if (err) { + logger.error(err, "Could not connect to database"); + return reject(err); + } + + // monky patch db instance + // use this instance in other files + //mongodb.client = client.db(process.env.DATABASE_NAME); + mongodb.connection = client; + mongodb.client = client.db(); + + + client.on("error", (err) => { + logger.error(err, "Could not connecto to databse: %s", err.message); + }); + + client.on("close", () => { + process.exit(1000); + }); + + + try { + + // test authenticiation + // throws a error is auth is noc successfull + await mongodb.client.stats(); + + // feedback + logger.info(`Connected to "mongodb://${url.hostname}:${url.port}${url.pathname}"`); + + process.once("SIGINT", () => { + mongodb.connection.close(() => { + logger.info(`Connection closed from "mongodb://${url.hostname}:${url.port}${url.pathname}"`); + }); + }); + + resolve(); + + } catch (err) { + + if (err?.code == 13) { + logger.error("Invalid database credentials!"); + } + + client.emit("error", err); + reject(err); + + } + + + }); + + }); + }; +}; \ No newline at end of file diff --git a/system/init/init.http-server.js b/system/init/init.http-server.js new file mode 100644 index 0000000..b6f8daf --- /dev/null +++ b/system/init/init.http-server.js @@ -0,0 +1,118 @@ +const http = require("http"); +const fs = require("fs"); + +module.exports = (logger) => { + return () => { + return new Promise((resolve, reject) => { + + logger.debug("Init http server..."); + + const servers = [ + + // http server for ip/port + new Promise((resolve, reject) => { + if (process.env.HTTP_ADDRESS !== "") { + + let server = http.createServer(); + + server.on("error", (err) => { + logger.error(err, `Could not start http server: ${err.message}`); + reject(err); + }); + + server.on("listening", () => { + + let addr = server.address(); + logger.info(`HTTP Server listening on http://${addr.address}:${addr.port}`); + + resolve(server); + + }); + + server.on("close", () => { + logger.info(`HTTP Server closed on http://${process.env.HTTP_ADDRESS}:${process.env.HTTP_PORT}`); + }); + + require("../../routes/index.js")(server); + + // bind/start http server + server.listen(Number(process.env.HTTP_PORT), process.env.HTTP_ADDRESS); + + } else { + resolve(); + } + }), + + // http server for unix socket + new Promise((resolve, reject) => { + if (process.env.HTTP_SOCKET !== "") { + + let server = http.createServer(); + + server.on("error", (err) => { + + logger.error(err, `Could not start http server: ${err.message}`); + reject(err); + + }); + + server.on("listening", () => { + + logger.info(`HTTP Server listening on ${process.env.HTTP_SOCKET}`); + + resolve(server); + + }); + + server.on("close", () => { + logger.info(`HTTP Server closed on ${process.env.HTTP_SOCKET}`); + }); + + require("../../routes/index.js")(server); + + try { + + // cleanup + fs.unlinkSync(process.env.HTTP_SOCKET); + + } catch (err) { + if (err.code !== "ENOENT") { + + reject(err); + + } + } finally { + + // bind/start http server + server.listen(process.env.HTTP_SOCKET); + + } + + } else { + resolve(); + } + }) + + ]; + + Promise.all(servers).then((servers) => { + + process.once("SIGINT", () => { + servers.forEach((server) => { + server.close(); + }); + }); + + resolve(); + + }).catch((err) => { + + logger.error(err, "Could not start http server(s)", err); + + reject(err); + + }); + + }); + }; +}; \ No newline at end of file From 6582612728909dff66cfe6e34767801f1c358294 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 26 Nov 2023 00:19:08 +0100 Subject: [PATCH 031/186] banner option draft added --- Gruntfile.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index 734f958..2de66d2 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -24,7 +24,8 @@ module.exports = function (grunt) { options: { mangle: { toplevel: true - } + }, + //banner: fs.readFileSync(path.join(process.cwd(), "docs/banner.txt"), "utf8") }, build: { files: [{ From d0a2c3e7d6518baa65c8d7668b720a407292e796 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sat, 16 Dec 2023 21:49:07 +0100 Subject: [PATCH 032/186] fix #350 --- components/devices/class.interface.js | 41 ++++++++++++++++++--------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/components/devices/class.interface.js b/components/devices/class.interface.js index ce94879..dbf24bc 100644 --- a/components/devices/class.interface.js +++ b/components/devices/class.interface.js @@ -39,6 +39,14 @@ module.exports = class Interface { let { interfaceStreams } = require("../../system/shared.js"); interfaceStreams.set(this._id, stream); + // hot fix for #350 + Object.defineProperty(this, "cachedAgent", { + value: null, + enumerable: false, + configurable: false, + writable: true + }); + } /** @@ -199,6 +207,10 @@ module.exports = class Interface { // NEW VERSION, fix for #329 httpAgent(options = {}) { + if (this.cachedAgent) { + return this.cachedAgent; + } + let agent = new Agent({ keepAlive: true, maxSockets: 1, @@ -208,9 +220,9 @@ module.exports = class Interface { //let settings = this.settings; - agent.createConnection = ({ host = null, port = null }) => { + agent.createConnection = () => { - console.log(`############## Create connection to tcp://${host}:${port}`); + //console.log(`############## Create connection to tcp://${host}:${port}`); // cleanup, could be possible be piped from previous "connections" this.stream.unpipe(); @@ -292,28 +304,28 @@ module.exports = class Interface { writable }); - stream.destroy = (...args) => { - console.log("socket.destroy();", args); + stream.destroy = () => { + //console.log("socket.destroy();", args); }; - stream.ref = (...args) => { - console.log("socket.unref();", args); + stream.ref = () => { + //console.log("socket.unref();", args); }; - stream.unref = (...args) => { - console.log("socket.unref();", args); + stream.unref = () => { + //console.log("socket.unref();", args); }; - stream.setKeepAlive = (...args) => { - console.log("socket.setKeepAlive()", args); + stream.setKeepAlive = () => { + //console.log("socket.setKeepAlive()", args); }; - stream.setTimeout = (...args) => { - console.log("socket.setTimeout();", args); + stream.setTimeout = () => { + //console.log("socket.setTimeout();", args); }; - stream.setNoDelay = (...args) => { - console.log("socket.setNotDelay();", args); + stream.setNoDelay = () => { + //console.log("socket.setNotDelay();", args); }; this.stream.pipe(readable, { end: false }); @@ -323,6 +335,7 @@ module.exports = class Interface { }; + this.cachedAgent = agent; return agent; } From ef9bcc43720663b3dc915a92a3fec53b3ee54df2 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 17 Dec 2023 11:50:23 +0100 Subject: [PATCH 033/186] fix #351 --- system/component/class.component.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/system/component/class.component.js b/system/component/class.component.js index b640008..d7c9439 100644 --- a/system/component/class.component.js +++ b/system/component/class.component.js @@ -99,7 +99,7 @@ module.exports = class COMPONENT extends COMMON { ...schema, //labels: Joi.array().items(Joi.string().regex(/^[a-zA-Z0-9]+=[a-zA-Z0-9]+$/)).default([]) //labels: Joi.array().items(Joi.string().regex(/^[a-z0-9\.]+=[a-z0-9]+$/)).default([]), - labels: Joi.array().items(Joi.string().regex(/^[a-z0-9]+=[a-z0-9]+$/)).default([]), + labels: Joi.array().items(Joi.string()).default([]), timestamps: Joi.object({ ...schema?.timestamps, created: Joi.number().allow(null).default(null), @@ -654,6 +654,17 @@ module.exports = class COMPONENT extends COMMON { let loop = (filter, target) => { for (let key in filter) { + // fix for #351 + // NOTE: use later labels method to match more "effecive". e.g. for wildcards + if (key === "labels" && Array.isArray(filter[key]) && Array.isArray(target[key])) { + + found = filter[key].every((label) => { + return target[key].includes(label); + }); + + return; + } + if (typeof filter[key] === "object") { loop(filter[key], target[key]); return; @@ -725,7 +736,7 @@ module.exports = class COMPONENT extends COMMON { handler(filter, item); }; - // TODO: Ensure to no create a memory leak + // TODO: Ensure to not create a memory leak // E.g. When used in ssdp with "update" event // And the announcement timestamp gets updated // the function is triggerd again. How to prevent that? From 8680074b5e2fe3c0ffe8bacaed9c4f8acef06041 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 17 Dec 2023 11:52:39 +0100 Subject: [PATCH 034/186] fix #355 --- system/component/class.component.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/component/class.component.js b/system/component/class.component.js index d7c9439..8710eea 100644 --- a/system/component/class.component.js +++ b/system/component/class.component.js @@ -99,7 +99,7 @@ module.exports = class COMPONENT extends COMMON { ...schema, //labels: Joi.array().items(Joi.string().regex(/^[a-zA-Z0-9]+=[a-zA-Z0-9]+$/)).default([]) //labels: Joi.array().items(Joi.string().regex(/^[a-z0-9\.]+=[a-z0-9]+$/)).default([]), - labels: Joi.array().items(Joi.string()).default([]), + labels: Joi.array().items(Joi.string().regex(/^.+?=.+|.+=.+$/i)).default([]), timestamps: Joi.object({ ...schema?.timestamps, created: Joi.number().allow(null).default(null), From 3d77e554a6d87c0f5d4225a85119722fbaf5fe55 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 17 Dec 2023 12:23:36 +0100 Subject: [PATCH 035/186] added --- ISSUES.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 ISSUES.md diff --git a/ISSUES.md b/ISSUES.md new file mode 100644 index 0000000..c701352 --- /dev/null +++ b/ISSUES.md @@ -0,0 +1,38 @@ +```systemd +[Unit] +Description=firewalld - dynamic firewall daemon +Before=network-pre.target +Wants=network-pre.target +After=dbus.service +After=polkit.service +Conflicts=iptables.service ip6tables.service ebtables.service ipset.service nftables.service +Documentation=man:firewalld(1) + +[Service] +EnvironmentFile=-/etc/sysconfig/firewalld +ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS +ExecReload=/bin/kill -HUP $MAINPID +# supress to log debug and error output also to /var/log/messages +StandardOutput=null +StandardError=null +Type=dbus +BusName=org.fedoraproject.FirewallD1 +KillMode=mixed + +[Install] +WantedBy=multi-user.target +Alias=dbus-org.fedoraproject.FirewallD1.service +``` + +https://systemd-devel.freedesktop.narkive.com/dpY7US7K/a-little-help-with-mainpid-please + + +OpenHaus relevant/verbesserung?! + + +---------------- + +Use husky for git hooks? + +https://www.npmjs.com/package/husky +https://typicode.github.io/husky/ \ No newline at end of file From 45d0e8ec3f35f800ea8f93c1bfb7a98e05f86471 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 17 Dec 2023 12:24:34 +0100 Subject: [PATCH 036/186] `npm run dev:plugin` script added --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index dce9fae..95cc948 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "test:helper": "NODE_ENV=test ./node_modules/.bin/mocha ./tests/helper/index.js", "test:newman": "newman run postman.json", "dev": "./node_modules/.bin/nodemon -w . -w .env index.js", + "dev:plugin": "./node_modules/.bin/nodemon -w plugins -w . -w .env index.js", "lint": "./node_modules/.bin/eslint .", "lint:fix": "./node_modules/.bin/eslint --fix .", "mocha": "./node_modules/.bin/mocha ./tests/index.js", From 400ff50bf58b61d5cca7328cd9260a47dba4b174 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 17 Dec 2023 16:29:26 +0100 Subject: [PATCH 037/186] error fix --- routes/router.api.plugins.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/routes/router.api.plugins.js b/routes/router.api.plugins.js index 2b5c653..6a2caf0 100644 --- a/routes/router.api.plugins.js +++ b/routes/router.api.plugins.js @@ -67,7 +67,10 @@ module.exports = (app, router) => { } catch (err) { - res.status(500).end(err); + res.status(500).json({ + error: err.message, + stack: err.stack + }); } }); From befa4d878b314ee8574d88914da422b3d6e9e6c3 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 17 Dec 2023 16:31:55 +0100 Subject: [PATCH 038/186] fix #353 --- components/plugins/class.plugin.js | 50 ++++++++++++++++++++++++++++-- package-lock.json | 1 + package.json | 1 + 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/components/plugins/class.plugin.js b/components/plugins/class.plugin.js index 1b2129e..5ba3413 100644 --- a/components/plugins/class.plugin.js +++ b/components/plugins/class.plugin.js @@ -1,6 +1,8 @@ const fs = require("fs"); const path = require("path"); const logger = require("../../system/logger/index.js"); +const semver = require("semver"); +const pkg = require("../../package.json"); //const Bootstrap = require("./class.bootstrap.js"); @@ -26,6 +28,40 @@ class Plugin { Object.assign(this, obj); this._id = String(obj._id); + let json = {}; + + Object.defineProperty(this, "logger", { + value: logger.create(`plugins/${this.uuid}`), + configurable: false, + enumerable: false, + writable: false + }); + + try { + + let file = path.resolve(process.cwd(), "plugins", this.uuid, "package.json"); + let content = fs.readFileSync(file); + json = JSON.parse(content); + + } catch (err) { + if (err.code === "ENOENT") { + + this.logger.warn(err, `package.json for plugin "${this.name}" not found.`); + + } else { + + this.logger.warn(err); + + } + } + + Object.defineProperty(this, "package", { + value: json, + configurable: false, + enumerable: false, + writable: false, + }); + } /** @@ -35,7 +71,15 @@ class Plugin { start() { if (this.enabled) { + // feedback + logger.debug(`Start plugin "${this.name}"...`); + let plugin = path.resolve(process.cwd(), "plugins", this.uuid); + let compatible = semver.satisfies(pkg.version, this.package?.backend); + + if (!compatible) { + logger.warn(`Starting incomptaible plugin "${this.name}". It may work not properly or break something!`); + } if (fs.existsSync(plugin)) { @@ -79,11 +123,11 @@ class Plugin { }; init[Symbol.for("uuid")] = this.uuid; + init[Symbol.for("compatible")] = compatible; try { - let log = logger.create(`plugins/${this.uuid}`); - let returns = require(path.resolve(plugin, "index.js"))(this, log, init); + let returns = require(path.resolve(plugin, "index.js"))(this, this.logger, init); if (!returns) { return; @@ -94,6 +138,8 @@ class Plugin { throw new Error("Invalid init function returnd!"); } + this.started = true; + } catch (err) { logger.error(`Error in plugin "${this.name}": `, err); throw err; diff --git a/package-lock.json b/package-lock.json index 83f6778..8f2bc2f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "jsonwebtoken": "^9.0.0", "mongodb": "^4.11.0", "mqtt-packet": "^8.1.2", + "semver": "^7.5.4", "uuid": "^9.0.0", "ws": "^8.10.0" }, diff --git a/package.json b/package.json index 95cc948..1832a9d 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "jsonwebtoken": "^9.0.0", "mongodb": "^4.11.0", "mqtt-packet": "^8.1.2", + "semver": "^7.5.4", "uuid": "^9.0.0", "ws": "^8.10.0" }, From 24a2e620e0cddb275d8d1fc0277b4176e0629cc8 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 17 Dec 2023 16:33:52 +0100 Subject: [PATCH 039/186] fix #359 --- components/plugins/class.plugin.js | 121 ++++++++++++++++------------- 1 file changed, 65 insertions(+), 56 deletions(-) diff --git a/components/plugins/class.plugin.js b/components/plugins/class.plugin.js index 5ba3413..5cccbcc 100644 --- a/components/plugins/class.plugin.js +++ b/components/plugins/class.plugin.js @@ -37,6 +37,13 @@ class Plugin { writable: false }); + Object.defineProperty(this, "started", { + value: false, + configurable: false, + enumerable: false, + writable: true + }); + try { let file = path.resolve(process.cwd(), "plugins", this.uuid, "package.json"); @@ -69,96 +76,98 @@ class Plugin { * Start installed plugin */ start() { - if (this.enabled) { + if (!this.started) { + if (this.enabled) { - // feedback - logger.debug(`Start plugin "${this.name}"...`); + // feedback + logger.debug(`Start plugin "${this.name}"...`); - let plugin = path.resolve(process.cwd(), "plugins", this.uuid); - let compatible = semver.satisfies(pkg.version, this.package?.backend); + let plugin = path.resolve(process.cwd(), "plugins", this.uuid); + let compatible = semver.satisfies(pkg.version, this.package?.backend); - if (!compatible) { - logger.warn(`Starting incomptaible plugin "${this.name}". It may work not properly or break something!`); - } + if (!compatible) { + logger.warn(`Starting incomptaible plugin "${this.name}". It may work not properly or break something!`); + } - if (fs.existsSync(plugin)) { + if (fs.existsSync(plugin)) { - let init = (dependencies, cb) => { - try { + let init = (dependencies, cb) => { + try { - const granted = dependencies.every((c) => { - if (this.intents.includes(c)) { + const granted = dependencies.every((c) => { + if (this.intents.includes(c)) { - return true; + return true; - } else { + } else { - logger.warn(`Plugin ${this.uuid} (${this.name}) wants to access not registerd intens "${c}"`); - return false; + logger.warn(`Plugin ${this.uuid} (${this.name}) wants to access not registerd intens "${c}"`); + return false; - } - }); + } + }); - if (granted) { + if (granted) { - let components = dependencies.map((name) => { - return require(path.resolve(process.cwd(), `components/${name}`)); - }); + let components = dependencies.map((name) => { + return require(path.resolve(process.cwd(), `components/${name}`)); + }); + + cb(this, components); + return init; + + } else { + + throw new Error(`Unregisterd intents access approach`); - cb(this, components); - return init; + } - } else { + } catch (err) { - throw new Error(`Unregisterd intents access approach`); + logger.error(err, `Plugin could not initalize!`, err.message); + throw err; } + }; - } catch (err) { + init[Symbol.for("uuid")] = this.uuid; + init[Symbol.for("compatible")] = compatible; - logger.error(err, `Plugin could not initalize!`, err.message); - throw err; + try { - } - }; + let returns = require(path.resolve(plugin, "index.js"))(this, this.logger, init); - init[Symbol.for("uuid")] = this.uuid; - init[Symbol.for("compatible")] = compatible; + if (!returns) { + return; + } - try { + if (returns[Symbol.for("uuid")] !== this.uuid) { + logger.warn(`Plugin "${this.uuid}" (${this.name}) does not return the init function!`); + throw new Error("Invalid init function returnd!"); + } - let returns = require(path.resolve(plugin, "index.js"))(this, this.logger, init); + this.started = true; - if (!returns) { - return; + } catch (err) { + logger.error(`Error in plugin "${this.name}": `, err); + throw err; } - if (returns[Symbol.for("uuid")] !== this.uuid) { - logger.warn(`Plugin "${this.uuid}" (${this.name}) does not return the init function!`); - throw new Error("Invalid init function returnd!"); - } + } else { - this.started = true; + logger.error(`Could not found plugin file/folder "${this.uuid}"`); + throw new Error("Plugin not found"); - } catch (err) { - logger.error(`Error in plugin "${this.name}": `, err); - throw err; } } else { - logger.error(`Could not found plugin file/folder "${this.uuid}"`); - throw new Error("Plugin not found"); - - } + let err = Error("Plugin is not enabled!"); + err.code = "PLUGIN_NOT_ENABLED"; - } else { - - let err = Error("Plugin is not enabled!"); - err.code = "PLUGIN_NOT_ENABLED"; - - throw err; + throw err; + } } } From e1051cee3b0f96a5bbb5988d6f50dd100bc24a7c Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 19 Dec 2023 12:10:35 +0100 Subject: [PATCH 040/186] fix #358 --- components/devices/class.device.js | 29 ++++++ components/devices/index.js | 20 +--- components/endpoints/class.endpoint.js | 25 +++++ components/endpoints/index.js | 19 +--- components/mdns/class.mdns.js | 26 ++++- components/mdns/index.js | 14 +-- components/mqtt/class.mqtt.js | 17 ++++ components/mqtt/index.js | 11 +- components/plugins/class.plugin.js | 24 +++++ components/plugins/index.js | 19 +--- components/rooms/class.room.js | 21 ++++ components/rooms/index.js | 13 +-- components/scenes/class.scene.js | 19 ++++ components/scenes/index.js | 15 +-- components/ssdp/class.ssdp.js | 29 +++++- components/ssdp/index.js | 17 +--- components/store/class.store.js | 19 ++++ components/store/index.js | 16 +-- components/users/class.user.js | 26 +++++ components/users/index.js | 20 +--- components/vault/class.vault.js | 10 +- components/vault/index.js | 13 +-- components/webhooks/class.webhook.js | 16 +++ components/webhooks/index.js | 10 +- system/component/class.component.js | 6 +- system/eventbus/class.bus.js | 74 ++++++++++++++ system/eventbus/class.rpc.js | 122 +++++++++++++++++++++++ system/eventbus/class.topic.js | 74 ++++++++++++++ system/eventbus/index.js | 68 +++++++++++++ tests/system/component/test.component.js | 2 +- 30 files changed, 605 insertions(+), 189 deletions(-) create mode 100644 system/eventbus/class.bus.js create mode 100644 system/eventbus/class.rpc.js create mode 100644 system/eventbus/class.topic.js create mode 100644 system/eventbus/index.js diff --git a/components/devices/class.device.js b/components/devices/class.device.js index 6225fac..cd2ef78 100644 --- a/components/devices/class.device.js +++ b/components/devices/class.device.js @@ -1,3 +1,6 @@ +const Joi = require("joi"); +const mongodb = require("mongodb"); + const InterfaceStream = require("./class.interfaceStream.js"); const Interface = require("./class.interface.js"); @@ -21,6 +24,7 @@ const mixins = require("../../helper/mixins.js"); * @see interfaceStream components/devices/class.interfaceStream.js */ module.exports = class Device { + constructor(props) { // set properties from db @@ -61,4 +65,29 @@ module.exports = class Device { }); } + + static schema() { + return Joi.object({ + _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { + return String(new mongodb.ObjectId()); + }), + name: Joi.string().required(), + room: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).allow(null).default(null), + enabled: Joi.boolean().default(true), + //interfaces: Joi.array().items(Interface.schema()).min(1).required() + interfaces: Joi.array().min(1).items(Interface.schema()).required(), + meta: { + manufacturer: Joi.string().allow(null).default(null), + model: Joi.string().allow(null).default(null), + revision: Joi.number().allow(null).default(null), + serial: Joi.string().allow(null).default(null) + }, + icon: Joi.string().allow(null).default(null) + }); + } + + static validate(data) { + return Device.schema().validate(data); + } + }; \ No newline at end of file diff --git a/components/devices/index.js b/components/devices/index.js index f6da0b8..0bae134 100644 --- a/components/devices/index.js +++ b/components/devices/index.js @@ -1,5 +1,4 @@ const mongodb = require("mongodb"); -const Joi = require("joi"); // for development its usefull if we detect @@ -17,7 +16,6 @@ const COMPONENT = require("../../system/component/class.component.js"); //require("./class.interface.js"); //require("./class.interfaceStream"); -const Interface = require("./class.interface.js"); const Device = require("./class.device.js"); /** @@ -144,23 +142,7 @@ class C_DEVICES extends COMPONENT { // inject logger, collection and schema object // https://stackoverflow.com/a/37746388/5781499 - super("devices", { - _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { - return String(new mongodb.ObjectId()); - }), - name: Joi.string().required(), - room: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).allow(null).default(null), - enabled: Joi.boolean().default(true), - //interfaces: Joi.array().items(Interface.schema()).min(1).required() - interfaces: Joi.array().min(1).items(Interface.schema()).required(), - meta: { - manufacturer: Joi.string().allow(null).default(null), - model: Joi.string().allow(null).default(null), - revision: Joi.number().allow(null).default(null), - serial: Joi.string().allow(null).default(null) - }, - icon: Joi.string().allow(null).default(null) - }, module); + super("devices", Device.schema(), module); // create for new added device interfaces diff --git a/components/endpoints/class.endpoint.js b/components/endpoints/class.endpoint.js index 0240e6a..b501c9c 100644 --- a/components/endpoints/class.endpoint.js +++ b/components/endpoints/class.endpoint.js @@ -1,3 +1,6 @@ +const Joi = require("joi"); +const mongodb = require("mongodb"); + const Command = require("./class.command.js"); const State = require("./class.state.js"); //const Commands = require("./class.commands.js"); @@ -28,6 +31,7 @@ const _expose = require("../../helper/expose.js"); * @see InterfaceStream components/devices/class.interfaceStream.js */ module.exports = class Endpoint { + constructor(obj) { Object.assign(this, obj); @@ -59,4 +63,25 @@ module.exports = class Endpoint { }); } + + static schema() { + return Joi.object({ + _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { + return String(new mongodb.ObjectId()); + }), + name: Joi.string().required(), + enabled: Joi.boolean().default(true), + room: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).allow(null).default(null), + device: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).required(), + commands: Joi.array().items(Command.schema()).default([]), + states: Joi.array().items(State.schema()).default([]), + identifier: Joi.any().allow(null).default(null), // usefull for ssdp, etc. + icon: Joi.string().allow(null).default(null) + }); + } + + static validate(data) { + return Endpoint.schema().validate(data); + } + }; \ No newline at end of file diff --git a/components/endpoints/index.js b/components/endpoints/index.js index 4c58d11..b3f1a40 100644 --- a/components/endpoints/index.js +++ b/components/endpoints/index.js @@ -1,6 +1,3 @@ -const mongodb = require("mongodb"); -const Joi = require("joi"); - //const util = require("util"); //const logger = require("../../system/logger").create("endpoints"); @@ -9,8 +6,6 @@ const COMPONENT = require("../../system/component/class.component.js"); const Endpoint = require("./class.endpoint.js"); -const Command = require("./class.command.js"); -const State = require("./class.state.js"); //const _expose = require("../../helper/expose.js"); @@ -44,19 +39,7 @@ class C_ENDPOINTS extends COMPONENT { constructor() { // inject logger, collection and schema object - super("endpoints", { - _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { - return String(new mongodb.ObjectId()); - }), - name: Joi.string().required(), - enabled: Joi.boolean().default(true), - room: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).allow(null).default(null), - device: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).required(), - commands: Joi.array().items(Command.schema()).default([]), - states: Joi.array().items(State.schema()).default([]), - identifier: Joi.any().allow(null).default(null), // usefull for ssdp, etc. - icon: Joi.string().allow(null).default(null) - }, module); + super("endpoints", Endpoint.schema(), module); this.hooks.post("add", (data, next) => { diff --git a/components/mdns/class.mdns.js b/components/mdns/class.mdns.js index 19efe27..428eaaf 100644 --- a/components/mdns/class.mdns.js +++ b/components/mdns/class.mdns.js @@ -1,4 +1,7 @@ -class MDNS { +const Joi = require("joi"); +const mongodb = require("mongodb"); + +module.exports = class MDNS { constructor(obj) { @@ -14,10 +17,25 @@ class MDNS { } + static schema() { + return Joi.object({ + _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { + return String(new mongodb.ObjectId()); + }), + name: Joi.string().required(), + type: Joi.string().valid("SRV", "PTR", "A", "AAAA").default("A"), + timestamps: { + announced: Joi.number().allow(null).default(null) + } + }); + } + + static validate(data) { + return MDNS.schema().validate(data); + } + match(cb) { this._matches.push(cb); } -} - -module.exports = MDNS; \ No newline at end of file +}; \ No newline at end of file diff --git a/components/mdns/index.js b/components/mdns/index.js index 5435dd4..787bffc 100644 --- a/components/mdns/index.js +++ b/components/mdns/index.js @@ -1,6 +1,3 @@ -const mongodb = require("mongodb"); -const Joi = require("joi"); - //const logger = require("../../system/logger").create("rooms"); //const COMMON_COMPONENT = require("../../system/component/common.js"); const COMPONENT = require("../../system/component/class.component.js"); @@ -30,16 +27,7 @@ class C_MDNS extends COMPONENT { constructor() { // inject logger, collection and schema object - super("mdns", { - _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { - return String(new mongodb.ObjectId()); - }), - name: Joi.string().required(), - type: Joi.string().valid("SRV", "PTR", "A", "AAAA").default("A"), - timestamps: { - announced: Joi.number().allow(null).default(null) - } - }, module); + super("mdns", MDNS.schema(), module); this.hooks.post("add", (data, next) => { next(null, new MDNS(data)); diff --git a/components/mqtt/class.mqtt.js b/components/mqtt/class.mqtt.js index ecafe25..2e149ab 100644 --- a/components/mqtt/class.mqtt.js +++ b/components/mqtt/class.mqtt.js @@ -1,3 +1,6 @@ +const Joi = require("joi"); +const mongodb = require("mongodb"); + /** * @description * Represents a mqtt topic item @@ -33,6 +36,20 @@ class MQTT { } + static schema() { + return Joi.object({ + _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { + return String(new mongodb.ObjectId()); + }), + topic: Joi.string().required(), + description: Joi.string().allow(null).default(null) + }); + } + + static validate(data) { + return MQTT.schema().validate(data); + } + /** * Subscribe to this topic * @param {Function} cb Callback diff --git a/components/mqtt/index.js b/components/mqtt/index.js index 10deecd..e11b917 100644 --- a/components/mqtt/index.js +++ b/components/mqtt/index.js @@ -1,6 +1,3 @@ -const mongodb = require("mongodb"); -const Joi = require("joi"); - //const logger = require("../../system/logger").create("rooms"); //const COMMON_COMPONENT = require("../../system/component/common.js"); const COMPONENT = require("../../system/component/class.component.js"); @@ -49,13 +46,7 @@ class C_MQTT extends COMPONENT { constructor() { // inject logger, collection and schema object - super("mqtt", { - _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { - return String(new mongodb.ObjectId()); - }), - topic: Joi.string().required(), - description: Joi.string().allow(null).default(null) - }, module); + super("mqtt", MQTT.schema(), module); this.hooks.post("add", (data, next) => { next(null, new MQTT(data)); diff --git a/components/plugins/class.plugin.js b/components/plugins/class.plugin.js index 5cccbcc..617443c 100644 --- a/components/plugins/class.plugin.js +++ b/components/plugins/class.plugin.js @@ -1,8 +1,11 @@ const fs = require("fs"); const path = require("path"); +const Joi = require("joi"); +const mongodb = require("mongodb"); const logger = require("../../system/logger/index.js"); const semver = require("semver"); const pkg = require("../../package.json"); +const uuid = require("uuid"); //const Bootstrap = require("./class.bootstrap.js"); @@ -71,6 +74,27 @@ class Plugin { } + static schema() { + return Joi.object({ + _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { + return String(new mongodb.ObjectId()); + }), + name: Joi.string().required(), + uuid: Joi.string().default(() => { + return uuid.v4(); + }), + version: Joi.number().required(), + //runlevel: Joi.number().min(0).max(2).default(0), + autostart: Joi.boolean().default(true), + enabled: Joi.boolean().default(true), + intents: Joi.array().items("devices", "endpoints", "plugins", "rooms", "ssdp", "store", "users", "vault", "mqtt", "mdns", "webhooks").required() + }); + } + + static validate(data) { + return Plugin.schema().validate(data); + } + /** * @function start * Start installed plugin diff --git a/components/plugins/index.js b/components/plugins/index.js index 77153bf..791ed47 100644 --- a/components/plugins/index.js +++ b/components/plugins/index.js @@ -1,10 +1,6 @@ const fs = require("fs"); const path = require("path"); -const Joi = require("joi"); -const mongodb = require("mongodb"); -const uuid = require("uuid"); - //const logger = require("../../system/logger").create("plugins"); @@ -35,20 +31,7 @@ class C_PLUGINS extends COMPONENT { // inject logger, collection and schema object // super(logger, mongodb.client.collection("plugins"), { - super("plugins", { - _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { - return String(new mongodb.ObjectId()); - }), - name: Joi.string().required(), - uuid: Joi.string().default(() => { - return uuid.v4(); - }), - version: Joi.number().required(), - //runlevel: Joi.number().min(0).max(2).default(0), - autostart: Joi.boolean().default(true), - enabled: Joi.boolean().default(true), - intents: Joi.array().items("devices", "endpoints", "plugins", "rooms", "ssdp", "store", "users", "vault", "mqtt", "mdns", "webhooks").required() - }, module); + super("plugins", Plugin.schema(), module); this.hooks.post("add", (data, next) => { fs.mkdir(path.resolve(process.cwd(), "plugins", data.uuid), (err) => { diff --git a/components/rooms/class.room.js b/components/rooms/class.room.js index b2ee6fb..48bad30 100644 --- a/components/rooms/class.room.js +++ b/components/rooms/class.room.js @@ -1,3 +1,6 @@ +const Joi = require("joi"); +const mongodb = require("mongodb"); + /** * @description * Represents a room item @@ -12,8 +15,26 @@ * @property {String} [icon=null] fontawesome class string for the frontend */ module.exports = class Room { + constructor(obj) { Object.assign(this, obj); this._id = String(obj._id); } + + static schema() { + return Joi.object({ + _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { + return String(new mongodb.ObjectId()); + }), + name: Joi.string().required(), + number: Joi.number().allow(null).default(null), + floor: Joi.number().allow(null).default(null), + icon: Joi.string().allow(null).default(null) + }); + } + + static validate(data) { + return Room.schema().validate(data); + } + }; \ No newline at end of file diff --git a/components/rooms/index.js b/components/rooms/index.js index 5704fd5..9aff9e1 100644 --- a/components/rooms/index.js +++ b/components/rooms/index.js @@ -1,6 +1,3 @@ -const mongodb = require("mongodb"); -const Joi = require("joi"); - //const logger = require("../../system/logger").create("rooms"); //const COMMON_COMPONENT = require("../../system/component/common.js"); const COMPONENT = require("../../system/component/class.component.js"); @@ -51,15 +48,7 @@ class C_ROOMS extends COMPONENT { constructor() { // inject logger, collection and schema object - super("rooms", { - _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { - return String(new mongodb.ObjectId()); - }), - name: Joi.string().required(), - number: Joi.number().allow(null).default(null), - floor: Joi.number().allow(null).default(null), - icon: Joi.string().allow(null).default(null) - }, module); + super("rooms", Room.schema(), module); this.hooks.post("add", (data, next) => { next(null, new Room(data)); diff --git a/components/scenes/class.scene.js b/components/scenes/class.scene.js index 41f573c..75456ec 100644 --- a/components/scenes/class.scene.js +++ b/components/scenes/class.scene.js @@ -1,3 +1,6 @@ +const Joi = require("joi"); +const mongodb = require("mongodb"); + const { setTimeout } = require("timers/promises"); const Makro = require("./class.makro.js"); @@ -64,6 +67,22 @@ module.exports = class Scene { } + static schema() { + return Joi.object({ + _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { + return String(new mongodb.ObjectId()); + }), + name: Joi.string().required(), + makros: Joi.array().items(Makro.schema()).default([]), + triggers: Joi.array().items(Trigger.schema()).default([]), + visible: Joi.boolean().default(true) + }); + } + + static validate(data) { + return Scene.schema().validate(data); + } + trigger() { let ac = new AbortController(); diff --git a/components/scenes/index.js b/components/scenes/index.js index c54d314..c2ba50f 100644 --- a/components/scenes/index.js +++ b/components/scenes/index.js @@ -1,13 +1,8 @@ -const mongodb = require("mongodb"); -const Joi = require("joi"); - //const logger = require("../../system/logger").create("rooms"); //const COMMON_COMPONENT = require("../../system/component/common.js"); const COMPONENT = require("../../system/component/class.component.js"); const Scene = require("./class.scene.js"); -const Makro = require("./class.makro.js"); -const Trigger = require("./class.trigger.js"); /** * @description @@ -21,15 +16,7 @@ class C_SCENES extends COMPONENT { constructor() { // inject logger, collection and schema object - super("scenes", { - _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { - return String(new mongodb.ObjectId()); - }), - name: Joi.string().required(), - makros: Joi.array().items(Makro.schema()).default([]), - triggers: Joi.array().items(Trigger.schema()).default([]), - visible: Joi.boolean().default(true) - }, module); + super("scenes", Scene.schema(), module); this.hooks.post("add", (data, next) => { next(null, new Scene(data)); diff --git a/components/ssdp/class.ssdp.js b/components/ssdp/class.ssdp.js index 91971df..8c5c230 100644 --- a/components/ssdp/class.ssdp.js +++ b/components/ssdp/class.ssdp.js @@ -1,4 +1,7 @@ -class SSDP { +const Joi = require("joi"); +const mongodb = require("mongodb"); + +module.exports = class SSDP { constructor(obj) { @@ -14,10 +17,28 @@ class SSDP { } + static schema() { + return Joi.object({ + _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { + return String(new mongodb.ObjectId()); + }), + description: Joi.string().allow(null).default(null), + nt: Joi.string().allow(null).default(null), + usn: Joi.string().allow(null).default(null), + // NOTE: Removed head field since currently no unique index can be build with it + //headers: Joi.array().items(Joi.string()).allow(null).default([]), + timestamps: { + announced: Joi.number().allow(null).default(null) + } + }); + } + + static validate(data) { + return SSDP.schema().validate(data); + } + match(cb) { this._matches.push(cb); } -} - -module.exports = SSDP; \ No newline at end of file +}; \ No newline at end of file diff --git a/components/ssdp/index.js b/components/ssdp/index.js index c0a770e..b722d0d 100644 --- a/components/ssdp/index.js +++ b/components/ssdp/index.js @@ -1,6 +1,3 @@ -const mongodb = require("mongodb"); -const Joi = require("joi"); - //const logger = require("../../system/logger").create("rooms"); //const COMMON_COMPONENT = require("../../system/component/common.js"); const COMPONENT = require("../../system/component/class.component.js"); @@ -48,19 +45,7 @@ class C_SSDP extends COMPONENT { constructor() { // inject logger, collection and schema object - super("ssdp", { - _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { - return String(new mongodb.ObjectId()); - }), - description: Joi.string().allow(null).default(null), - nt: Joi.string().allow(null).default(null), - usn: Joi.string().allow(null).default(null), - // NOTE: Removed head field since currently no unique index can be build with it - //headers: Joi.array().items(Joi.string()).allow(null).default([]), - timestamps: { - announced: Joi.number().allow(null).default(null) - } - }, module); + super("ssdp", SSDP.schema(), module); this.hooks.post("add", (data, next) => { next(null, new SSDP(data)); diff --git a/components/store/class.store.js b/components/store/class.store.js index abbdb01..f113326 100644 --- a/components/store/class.store.js +++ b/components/store/class.store.js @@ -1,5 +1,8 @@ const { EventEmitter } = require("events"); +const Joi = require("joi"); +const mongodb = require("mongodb"); const Value = require("./class.value.js"); +const uuid = require("uuid"); /** @@ -55,6 +58,22 @@ class Store { } + static schema() { + return Joi.object({ + _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { + return String(new mongodb.ObjectId()); + }), + config: Joi.array().min(1).items(Value.schema()).required(), + item: Joi.string().allow(null).default(null), + namespace: Joi.string().default(() => { + return uuid.v4(); + }), + }); + } + + static validate(data) { + return Store.schema().validate(data); + } /** * @function changes diff --git a/components/store/index.js b/components/store/index.js index e30351f..012c478 100644 --- a/components/store/index.js +++ b/components/store/index.js @@ -1,13 +1,8 @@ -const mongodb = require("mongodb"); -const Joi = require("joi"); -const uuid = require("uuid"); - const COMPONENT = require("../../system/component/class.component.js"); //const Value = require("./class.value.js"); //const Namespace = require("./class.namespace.js"); const Store = require("./class.store.js"); -const Value = require("./class.value.js"); /** * @description @@ -38,16 +33,7 @@ class C_STORE extends COMPONENT { constructor() { // inject logger, collection and schema object - super("store", { - _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { - return String(new mongodb.ObjectId()); - }), - config: Joi.array().min(1).items(Value.schema()).required(), - item: Joi.string().allow(null).default(null), - namespace: Joi.string().default(() => { - return uuid.v4(); - }), - }, module); + super("store", Store.schema(), module); this.hooks.post("add", (data, next) => { next(null, new Store(data, this)); diff --git a/components/users/class.user.js b/components/users/class.user.js index 8dcaa26..be12712 100644 --- a/components/users/class.user.js +++ b/components/users/class.user.js @@ -1,4 +1,6 @@ const jwt = require("jsonwebtoken"); +const Joi = require("joi"); +const mongodb = require("mongodb"); const _promisify = require("../../helper/promisify"); @@ -34,6 +36,30 @@ module.exports = class User { } + static schema() { + return Joi.object({ + _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { + return String(new mongodb.ObjectId()); + }), + name: Joi.string().required(), + email: Joi.string().required(), + password: Joi.string().required(), + enabled: Joi.boolean().default(false), + tokens: Joi.array().items(Joi.string()).default([]), + admin: Joi.boolean().default(false), + timestamps: { + // NOTE: would be greate to have a expiration date for users + // expires: Joi.number().allow(null).default(null) + login: Joi.number().allow(null).default(null), + logout: Joi.number().allow(null).default(null) + } + }); + } + + static validate(data) { + return User.schema().validate(data); + } + /** * @function addToken * Adds a new JWT token for the user. diff --git a/components/users/index.js b/components/users/index.js index 5b2b2fb..d1b5654 100644 --- a/components/users/index.js +++ b/components/users/index.js @@ -1,6 +1,4 @@ // external modules -const mongodb = require("mongodb"); -const Joi = require("joi"); const bcrypt = require("bcrypt"); // system stuff @@ -25,23 +23,7 @@ class C_USERS extends COMPONENT { constructor() { // inject logger, collection and schema object - super("users", { - _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { - return String(new mongodb.ObjectId()); - }), - name: Joi.string().required(), - email: Joi.string().required(), - password: Joi.string().required(), - enabled: Joi.boolean().default(false), - tokens: Joi.array().items(Joi.string()).default([]), - admin: Joi.boolean().default(false), - timestamps: { - //would be greate to have a expiration date for users - //expires: Joi.number().allow(null).default(null) - login: Joi.number().allow(null).default(null), - logout: Joi.number().allow(null).default(null) - } - }, module); + super("users", User.schema(), module); this.hooks.post("add", (data, next) => { next(null, new User(this, data)); diff --git a/components/vault/class.vault.js b/components/vault/class.vault.js index aa33456..3619598 100644 --- a/components/vault/class.vault.js +++ b/components/vault/class.vault.js @@ -78,12 +78,16 @@ class Vault { _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { return String(new mongodb.ObjectId()); }), - key: Joi.string().required(), - value: Joi.any().required(), - description: Joi.string().required() + name: Joi.string().required(), + identifier: Joi.string().required(), + secrets: Joi.array().items(Secret.schema()).default([]) }); } + static validate(data) { + return Vault.schema().validate(data); + } + /** * @function changes diff --git a/components/vault/index.js b/components/vault/index.js index 820efdd..485b193 100644 --- a/components/vault/index.js +++ b/components/vault/index.js @@ -1,12 +1,8 @@ -const mongodb = require("mongodb"); -const Joi = require("joi"); - //const logger = require("../../system/logger").create("vault"); //const COMMON_COMPONENT = require("../../system/component/common.js"); const COMPONENT = require("../../system/component/class.component.js"); const Vault = require("./class.vault.js"); -const Secret = require("./class.secret.js"); const encrypt = require("./encrypt.js"); @@ -35,14 +31,7 @@ class C_VAULT extends COMPONENT { constructor() { // inject logger, collection and schema object - super("vault", { - _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { - return String(new mongodb.ObjectId()); - }), - name: Joi.string().required(), - identifier: Joi.string().required(), - secrets: Joi.array().items(Secret.schema()).default([]) - }, module); + super("vault", Vault.schema(), module); this.hooks.pre("add", (data, next) => { try { diff --git a/components/webhooks/class.webhook.js b/components/webhooks/class.webhook.js index 331c156..23d34d4 100644 --- a/components/webhooks/class.webhook.js +++ b/components/webhooks/class.webhook.js @@ -1,3 +1,6 @@ +const Joi = require("joi"); +const mongodb = require("mongodb"); + /** * @description * Represents a webhook item @@ -38,6 +41,19 @@ module.exports = class Webhook { } + static schema() { + return Joi.object({ + _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { + return String(new mongodb.ObjectId()); + }), + name: Joi.string().required() + }); + } + + static validate(data) { + return Webhook.schema().validate(data); + } + handle(cb) { this._handler.push(cb); } diff --git a/components/webhooks/index.js b/components/webhooks/index.js index b5f6b10..67afc8d 100644 --- a/components/webhooks/index.js +++ b/components/webhooks/index.js @@ -1,6 +1,3 @@ -const mongodb = require("mongodb"); -const Joi = require("joi"); - //const logger = require("../../system/logger").create("rooms"); //const COMMON_COMPONENT = require("../../system/component/common.js"); const COMPONENT = require("../../system/component/class.component.js"); @@ -18,12 +15,7 @@ class C_WEBHOOKS extends COMPONENT { constructor() { // inject logger, collection and schema object - super("webhooks", { - _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { - return String(new mongodb.ObjectId()); - }), - name: Joi.string().required() - }, module); + super("webhooks", Webhook.schema(), module); this.hooks.post("add", (data, next) => { next(null, new Webhook(data)); diff --git a/system/component/class.component.js b/system/component/class.component.js index 8710eea..e7a0b54 100644 --- a/system/component/class.component.js +++ b/system/component/class.component.js @@ -95,8 +95,7 @@ module.exports = class COMPONENT extends COMMON { this.collection = mongodb.client.collection(name); - this.schema = Joi.object({ - ...schema, + let baseSchema = Joi.object({ //labels: Joi.array().items(Joi.string().regex(/^[a-zA-Z0-9]+=[a-zA-Z0-9]+$/)).default([]) //labels: Joi.array().items(Joi.string().regex(/^[a-z0-9\.]+=[a-z0-9]+$/)).default([]), labels: Joi.array().items(Joi.string().regex(/^.+?=.+|.+=.+$/i)).default([]), @@ -107,6 +106,9 @@ module.exports = class COMPONENT extends COMMON { }) }); + // concat base schema with component specific + this.schema = baseSchema.concat(schema); + if (process.env.DATABASE_WATCH_CHANGES === "true") { try { diff --git a/system/eventbus/class.bus.js b/system/eventbus/class.bus.js new file mode 100644 index 0000000..2095239 --- /dev/null +++ b/system/eventbus/class.bus.js @@ -0,0 +1,74 @@ +const RPC = require("./class.rpc.js"); +const Topic = require("./class.topic.js"); + +module.exports = class Bus { + + /** + * @class Eventbus + * Eventbus class that allow to subscribe topics and call remote functions.
+ * + * @property {RPC} _rpc RPC class instance, for internal use! + * @property {Topic} _topic Topic class instance, for internal use! + * @property {RPC} RPC RPC class + * @property {Topic} Topic Topic class + */ + constructor() { + this._rpc = new RPC(); + this._topic = new Topic(); + } + + static RPC = RPC; + static Topic = Topic; + + /** + * @function call + * Calls a remote registered function.
+ * Wrapper for `_rpc.call();` + * + * @param {...any} args + * @returns + */ + call(...args) { + return Reflect.apply(this._rpc.call, this._rpc, args); + } + + + /** + * @function register + * Register a remote callable function.
+ * Wrapper for `_rpc.register();` + * + * @param {...any} args + * @returns + */ + register(...args) { + return Reflect.apply(this._rpc.register, this._rpc, args); + } + + + /** + * @function subscribe + * Subscribe to a topic.
+ * Wrapper for `_topic.subscribe();` + * + * @param {...any} args + * @returns + */ + subscribe(...args) { + return Reflect.apply(this._topic.subscribe, this._topic, args); + } + + + /** + * @function publish + * Publish a value for a topic.
+ * Warpper for `_topic.publish();` + * + * @param {...any} args + * @returns + */ + publish(...args) { + return Reflect.apply(this._topic.publish, this._topic, args); + } + +}; \ No newline at end of file diff --git a/system/eventbus/class.rpc.js b/system/eventbus/class.rpc.js new file mode 100644 index 0000000..f732918 --- /dev/null +++ b/system/eventbus/class.rpc.js @@ -0,0 +1,122 @@ +const { randomUUID } = require("crypto"); +const { EventEmitter } = require("events"); + +module.exports = class RPC extends EventEmitter { + + constructor() { + super(); + this._rpcs = {}; + this._pending = {}; + } + + /** + * @function register + * Register a RPC method that can be called + * + * @param {String} uri + * @param {Function} cb + */ + register(uri, cb) { + this._rpcs[uri] = cb; + return cb; + } + + + /** + * @function call + * Calls a rpc function + * + * @param {String} uri + * @param {Array} [args=[]] + * @param {Function} [cb=()=> {}] + */ + call(uri, args = [], cb) { + if (this._rpcs[uri]) { + + let id = randomUUID(); + this._pending[id] = cb; + + // TODO: Check if last arg is a function? + //if(args[args.length - 1] instanceof Function && !cb){ + // this._pending[id] = args.pop(); + //} + + try { + + let ret = Reflect.apply(this._rpcs[uri], null, args); + + if (ret instanceof Promise) { + + ret.then((val) => { + Reflect.apply(this._pending[id], null, [null, val]); + }).catch((err) => { + Reflect.apply(this._pending[id], null, [err]); + }).finally(() => { + delete this._pending[id]; + }); + + } else { + + Reflect.apply(this._pending[id], null, [null, ret]); + delete this._pending[id]; + + } + + } catch (err) { + + Reflect.apply(this._pending[id], null, [err]); + delete this._pending[id]; + + } + + if (!cb) { + return new Promise((resolve) => { + this._pending[id] = resolve; + }); + } + + } else { + + throw new Error(`RPC ${uri} not found`); + + } + } + + /* + regrpc(uri, rpc) { + console.log("Registering " + uri); + this._rpcs[uri] = rpc; + this.emit('RPCRegistered', [uri]) + }; + + unregrpc(uri) { + console.log("Unregistering " + uri); + delete this._rpcs[uri]; + this.emit('RPCUnregistered', [uri]); + }; + + callrpc(uri, args, callback) { + if (typeof this._rpcs[uri] !== 'undefined') { + + let invId = randomUUID(); + this._pending[invId] = callback; + this._rpcs[uri].apply(this, [invId, args]); + + return true; + + } else { + + return false; + + } + }; + + resrpc(invId, err, args) { + if (typeof _pending[invId] !== 'undefined') { + this._pending[invId].apply(this, [err, args]); + delete _pending[invId]; + } + }; + */ + +}; \ No newline at end of file diff --git a/system/eventbus/class.topic.js b/system/eventbus/class.topic.js new file mode 100644 index 0000000..82ede28 --- /dev/null +++ b/system/eventbus/class.topic.js @@ -0,0 +1,74 @@ +const { EventEmitter } = require("events"); + + +module.exports = class Topic extends EventEmitter { + + constructor() { + super(); + this._topics = {}; + } + + + subscribe(uri, cb) { + + console.log(this); + + if (!this._topics[uri]) { + this._topics[uri] = []; + } + + this._topics[uri].push(cb); + + } + + + publish(uri, val) { + if (this._topics[uri]) { + + this._topics[uri].forEach((cb) => { + cb(val); + }); + + } else { + + // do nothing? + //throw new Error(`Topic ${uri} not found`); + + } + } + + + /* + substopic(topicUri, subscriptionId, callback) { + console.log("Registering topic " + topicUri + " subsc id " + subscriptionId); + if (typeof this._topics[topicUri] === 'undefined') { + this._topics[topicUri] = {}; + } + this._topics[topicUri][subscriptionId] = callback; + this.emit('Subscribe', topicUri); + }; + + unsubstopic(topicUri, subscriptionId) { + console.log("Unregistering topic " + topicUri + " subsc id " + subscriptionId); + delete this._topics[topicUri][subscriptionId]; + this.emit('Unsubscribe', topicUri); + }; + + publish(topicUri, publicationId, args, kwargs) { + console.log("Publish " + topicUri + " " + publicationId); + this.emit('Publish', topicUri, args, kwargs); + if (typeof this._topics[topicUri] !== 'undefined') { + for (var key in this._topics[topicUri]) { + if (typeof this._topics[topicUri][key] !== 'undefined') { + this._topics[topicUri][key].apply(this, [publicationId, args, kwargs]); + } + } + return true; + } else { + console.log("Undefined topic "); + return false; + } + }; + */ + +}; \ No newline at end of file diff --git a/system/eventbus/index.js b/system/eventbus/index.js new file mode 100644 index 0000000..23b2713 --- /dev/null +++ b/system/eventbus/index.js @@ -0,0 +1,68 @@ +const RPC = require("./class.rpc.js"); +const Topic = require("./class.topic.js"); +const Bus = require("./class.bus.js"); + + +class Eventbus extends Bus { + + constructor(...args) { + super(...args); + } + + static RPC = RPC; + static Topic = Topic; + static Eventbus = Eventbus; + +} + + +const eventbus = new Eventbus(); +Object.assign(eventbus, Eventbus); +module.exports = eventbus; + + +console.log(eventbus); + +/* +eventbus.subscribe("endpoint/6458dc42b55679622e893e6d/state/6458dc53a7b3b998ebb67027", (value) => { + console.log("Topic published:", value); +}); + + +eventbus.publish("endpoint/6458dc42b55679622e893e6d/state/6458dc53a7b3b998ebb67027", 49); + + +//register(`${name}/${method}`, this[method]); + + +eventbus.register("components/rooms/foo", (a, b) => { + + + //return a + b; + //throw new Error("Foo bar alsdkflafjsdk") + + return new Promise((resolve, reject) => { + setTimeout(() => { + //reject(new Error("foo, math is bad")); + resolve(a + b); + }, 3000); + }); + +}); + + +eventbus.call("components/rooms/foo", [1, 2], (err, result) => { + console.log("Calculation done", err || result); +}); + + + +console.log(JSON.stringify({ + foo: true, + bar: "baz", + fnc: () => { + console.log("Hello World") + }, + buff: Buffer.from("Heöö") +})) +*/ \ No newline at end of file diff --git a/tests/system/component/test.component.js b/tests/system/component/test.component.js index 9193426..1978f56 100644 --- a/tests/system/component/test.component.js +++ b/tests/system/component/test.component.js @@ -25,7 +25,7 @@ const getItmes = (obj) => { describe("component", function () { - let instance = new COMPONENT("test", {}); + let instance = new COMPONENT("test", joi.object({})); describe("- should have following properties", () => { From 953e8ed4f771967b6c303e06e90fd13730e7ffe9 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 19 Dec 2023 14:17:47 +0100 Subject: [PATCH 041/186] Hot fix for #362 --- system/dispatcher.js | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/system/dispatcher.js b/system/dispatcher.js index b42be26..0148aa7 100644 --- a/system/dispatcher.js +++ b/system/dispatcher.js @@ -28,21 +28,27 @@ module.exports = function dispatch({ component, item, method, args }) { let C_COMPONENT = require(`../components/${component}`); return C_COMPONENT.get(item).then((item) => { + if (item && item[method] && item[method] instanceof Function) { - let result = Reflect.apply(item[method], item, args); + let result = Reflect.apply(item[method], item, args); - /* - // draft for component/scene - // "example" for trigger that allow to check when a scene is executed - this.emit(component, { - item, - method, - args - }); - */ + /* + // draft for component/scene + // "example" for trigger that allow to check when a scene is executed + this.emit(component, { + item, + method, + args + }); + */ - return result; + return result; + } else { + + return Promise.resolve(); + + } }).catch((err) => { return Promise.reject(err); }); From 9bcdf1b683091bd63b523d645e794730f6eb1f4e Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 19 Dec 2023 14:32:16 +0100 Subject: [PATCH 042/186] fix #364 --- components/scenes/index.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/components/scenes/index.js b/components/scenes/index.js index c2ba50f..5d94cc5 100644 --- a/components/scenes/index.js +++ b/components/scenes/index.js @@ -3,6 +3,7 @@ const COMPONENT = require("../../system/component/class.component.js"); const Scene = require("./class.scene.js"); +const Makro = require("./class.makro.js"); /** * @description @@ -22,6 +23,20 @@ class C_SCENES extends COMPONENT { next(null, new Scene(data)); }); + // handle change makro array + // see #364 + this.hooks.post("update", (data, next) => { + + data.makros.forEach((makro, i, arr) => { + if (!(makro instanceof Makro)) { + arr[i] = new Makro(makro); + } + }); + + next(); + + }); + } } From 7ac1d165b002df0de07253a7355c850664f5489e Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 19 Dec 2023 14:56:52 +0100 Subject: [PATCH 043/186] fix #365 --- routes/router.api.store.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/router.api.store.js b/routes/router.api.store.js index 7fbf1f1..a4954ea 100644 --- a/routes/router.api.store.js +++ b/routes/router.api.store.js @@ -7,7 +7,7 @@ module.exports = (app, router) => { }); if (!req.config) { - return res.status(404); + return res.status(404).end(); } next(); From 1a6da1084fb7f9ace71d68c1542cce6dccf1001d Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 19 Dec 2023 15:39:30 +0100 Subject: [PATCH 044/186] minor fix for http api test --- routes/router.api.scenes.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routes/router.api.scenes.js b/routes/router.api.scenes.js index 18ee2d1..10a3bda 100644 --- a/routes/router.api.scenes.js +++ b/routes/router.api.scenes.js @@ -3,13 +3,13 @@ module.exports = (app, router) => { router.post("/:_id/trigger", (req, res) => { console.log("Trigger scene", req.item); req.item.trigger(); - res.status(202).end(); + res.status(202).json(req.item); }); router.post("/:_id/abort", (req, res) => { console.log("Abort scene", req.item); req.item.abort(); - res.end(); + res.json(req.item); }); router.get("/:_id/state", ({ item: { From f46e74b7a5a6927a71288982b4a5570ab811ecad Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 19 Dec 2023 18:38:33 +0100 Subject: [PATCH 045/186] fix #367 --- system/component/class.component.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/system/component/class.component.js b/system/component/class.component.js index e7a0b54..f6aa86f 100644 --- a/system/component/class.component.js +++ b/system/component/class.component.js @@ -321,7 +321,15 @@ module.exports = class COMPONENT extends COMMON { let item = this.items.find((item) => { return Object.keys(err.keyValue).every((value) => { + + // fixing "Duplicate unique key/index in database, but no matching item" + // see #367 + if (err.keyValue[value] instanceof mongodb.ObjectId) { + return item[value] === err.keyValue[value].toString(); + } + return item[value] === err.keyValue[value]; + }); /* From 579db459bd873f1895ef0e439e3c20e7474dc7bd Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 19 Dec 2023 18:39:28 +0100 Subject: [PATCH 046/186] fix #366 --- routes/router.api.plugins.js | 40 ++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/routes/router.api.plugins.js b/routes/router.api.plugins.js index 6a2caf0..c98d09d 100644 --- a/routes/router.api.plugins.js +++ b/routes/router.api.plugins.js @@ -8,9 +8,33 @@ module.exports = (app, router) => { router.put("/:_id/files", (req, res) => { + if (Number(req.headers["content-length"]) <= 0) { + return res.status(400).json({ + error: "Invalid upload size." + }); + } + let p = path.resolve(process.cwd(), "plugins", req.item.uuid); let tar = exec(`tar vzxf - -C ${p}`); + tar.once("exit", (code) => { + + if (code > 0) { + if (!res.headersSent) { + + res.status(400).json({ + error: "tar could not read input file. Upload failed/client failer?", + details: `tar exit code ${code}` + }); + + } + } + + // trigger closing pipeline below + tar.stdin.close(); + + }); + let rl = readline.createInterface({ input: tar.stdout, //output: process.stdout @@ -27,10 +51,18 @@ module.exports = (app, router) => { pipeline(req, tar.stdin, (err) => { - if (err) { - res.status(500).end(err.message); - } else { - res.json(req.item); + if (!res.headersSent) { + if (err) { + + res.status(500).json({ + error: err.message + }); + + } else { + + res.json(req.item); + + } } rl.close(); From 17a5c19c90025e206fdfb23b66633b7552680a68 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 19 Dec 2023 21:36:44 +0100 Subject: [PATCH 047/186] fix #287 & fix #368 --- components/endpoints/index.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/components/endpoints/index.js b/components/endpoints/index.js index b3f1a40..f296761 100644 --- a/components/endpoints/index.js +++ b/components/endpoints/index.js @@ -6,6 +6,8 @@ const COMPONENT = require("../../system/component/class.component.js"); const Endpoint = require("./class.endpoint.js"); +const Command = require("./class.command.js"); +const State = require("./class.state.js"); //const _expose = require("../../helper/expose.js"); @@ -47,6 +49,27 @@ class C_ENDPOINTS extends COMPONENT { }); + this.hooks.post("update", (data, next) => { + + // fix for #368 + data.states.forEach((state, i, arr) => { + if (!(state instanceof State)) { + arr[i] = new State(state); + } + }); + + // fix for #287 + data.commands.forEach((command, i, arr) => { + if (!(command instanceof Command)) { + arr[i] = new Command(command); + } + }); + + next(); + + }); + + /* // expose item functions this.triggerCommand = _expose(this.items, "triggerCommand"); From a796cb2e7453ad8a6f28aa7d9ea950fee1898b16 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 20 Dec 2023 14:33:25 +0100 Subject: [PATCH 048/186] fix #363 --- components/endpoints/class.command.js | 6 ++++++ routes/router.api.endpoints.js | 22 ++++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/components/endpoints/class.command.js b/components/endpoints/class.command.js index 3dfa1de..1595d07 100644 --- a/components/endpoints/class.command.js +++ b/components/endpoints/class.command.js @@ -190,6 +190,12 @@ module.exports = class Command { let worker = this.#privates.get("handler"); let iface = interfaces.get(this.interface); + if (!iface) { + let err = new Error(`Interface "${this.interface}" not found, cant write to it.`); + err.code = "NO_INTERFACE"; + return cb(err, false); + } + let timer = _timeout(this.#privates.get("timeout"), (timedout, duration, args) => { if (timedout) { diff --git a/routes/router.api.endpoints.js b/routes/router.api.endpoints.js index e1a54c0..0fb8bf1 100644 --- a/routes/router.api.endpoints.js +++ b/routes/router.api.endpoints.js @@ -39,12 +39,26 @@ module.exports = (app, router) => { router.post("/:_id/commands/:_cid", (req, res) => { if (req.cmd) { - req.cmd.trigger(req.body, (success) => { + req.cmd.trigger(req.body, (err, success) => { + if (err) { + + if (err.code === "NO_INTERFACE") { + res.status(424).json({ + error: err.message + }); + } else { + res.status(500).end({ + error: err.message + }); + } - res.json({ - success - }); + } else { + res.json({ + success + }); + + } }); } else { From 1cf51d08d13b65ba88b4b68060ea92a825f02b8d Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 20 Dec 2023 14:34:17 +0100 Subject: [PATCH 049/186] fix minor bug: "`tar.stdin.end()` is not a function" --- routes/router.api.plugins.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/router.api.plugins.js b/routes/router.api.plugins.js index c98d09d..e51edea 100644 --- a/routes/router.api.plugins.js +++ b/routes/router.api.plugins.js @@ -31,7 +31,7 @@ module.exports = (app, router) => { } // trigger closing pipeline below - tar.stdin.close(); + tar.stdin.end(); }); From eb991e4adb4e8551b9770656cfdb37d8bf8a302d Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 20 Dec 2023 14:34:35 +0100 Subject: [PATCH 050/186] updated --- postman.json | 940 ++++++++++++++++----------------------------------- 1 file changed, 300 insertions(+), 640 deletions(-) diff --git a/postman.json b/postman.json index 56b667a..f822234 100644 --- a/postman.json +++ b/postman.json @@ -1,9 +1,10 @@ { "info": { - "_postman_id": "7c990139-b42a-4603-9c76-841a6cda01aa", + "_postman_id": "7b801daa-eb6a-407c-9c0c-66ac044ed8f3", "name": "OpenHaus", "description": "SmartHome/IoT application", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "6522444" }, "item": [ { @@ -28,37 +29,7 @@ "listen": "test", "script": { "exec": [ - "pm.test(\"status code: 200\", () => {", - " pm.response.to.have.status(200);", - "});", - "", - "pm.test(\"Check room name: input = output\", () => {", - "", - " let res = pm.response.json();", - " let req = JSON.parse(pm.request.body);", - "", - " pm.expect(res.name).to.eql(req.name);", - "", - "});", - "", - "pm.test(\"Check properties\", () => {", - "", - " let res = pm.response.json();", - "", - " let props = [", - " \"name\", \"timestamps\", \"_id\",", - " \"number\", \"floor\", \"icon\"", - " ];", - "", - " Object.keys(res).forEach((key) => {", - " pm.expect(props.includes(key)).to.be.true;", - " });", - "", - " props.forEach((item) => {", - " pm.expect(Object.prototype.hasOwnProperty.call(res, item)).to.be.true;", - " });", - "", - "})" + "" ], "type": "text/javascript" } @@ -69,7 +40,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"name\": \"Livingroom\"\n}", + "raw": "{\n \"_id\": \"65818753e275da05046aaa78\",\n \"name\": \"Livingroom\" \n}", "options": { "raw": { "language": "json" @@ -107,16 +78,7 @@ "listen": "test", "script": { "exec": [ - "pm.test(\"The response has all properties\", () => {", - " let json = pm.response.json();", - " pm.expect(json).to.have.lengthOf(json.length);", - "});", - "", - "pm.test(\"Status code is 200\", () => {", - " pm.response.to.have.status(200);", - "});", - "", - "console.log(\"Fooo\")" + "" ], "type": "text/javascript" } @@ -183,7 +145,7 @@ "method": "GET", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/rooms/{{_id}}", + "raw": "http://{{HOST}}:{{PORT}}/api/rooms/65818753e275da05046aaa78", "protocol": "http", "host": [ "{{HOST}}" @@ -192,7 +154,7 @@ "path": [ "api", "rooms", - "{{_id}}" + "65818753e275da05046aaa78" ] } }, @@ -205,29 +167,7 @@ "listen": "prerequest", "script": { "exec": [ - "const HOST = pm.collectionVariables.get(\"HOST\");", - "const PORT = pm.collectionVariables.get(\"PORT\");", - "", - "//console.log(pm.request.url.toString())", - "", - "pm.sendRequest({", - " url: `http://${HOST}:${PORT}/api/rooms/`,", - " method: 'GET',", - "}, function (err, res) {", - " if(err){", - "", - " consle.error(err);", - "", - " }else {", - "", - " let data = res.json();", - " let key = Math.floor(Math.random()*data.length);", - " let item = data[key];", - "", - " pm.variables.set(\"_id\", item._id);", - "", - " }", - "});" + "" ], "type": "text/javascript" } @@ -246,7 +186,7 @@ } }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/rooms/63bf017582fa29f44cf8dfd6", + "raw": "http://{{HOST}}:{{PORT}}/api/rooms/65818753e275da05046aaa78", "protocol": "http", "host": [ "{{HOST}}" @@ -255,7 +195,7 @@ "path": [ "api", "rooms", - "63bf017582fa29f44cf8dfd6" + "65818753e275da05046aaa78" ] } }, @@ -268,7 +208,7 @@ "listen": "prerequest", "script": { "exec": [ - "console.log(\"_id varaible\", pm.variables.get(\"_id\"));" + "" ], "type": "text/javascript" } @@ -277,11 +217,7 @@ "listen": "test", "script": { "exec": [ - "console.log(\"_id varaible\", pm.variables.get(\"_id\"));", - "", - "pm.test(\"status code: 200\", () => {", - " pm.response.to.have.status(200);", - "});" + "" ], "type": "text/javascript" } @@ -291,7 +227,7 @@ "method": "DELETE", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/rooms/63bf017582fa29f44cf8dfd6", + "raw": "http://{{HOST}}:{{PORT}}/api/rooms/65818753e275da05046aaa78", "protocol": "http", "host": [ "{{HOST}}" @@ -300,7 +236,7 @@ "path": [ "api", "rooms", - "63bf017582fa29f44cf8dfd6" + "65818753e275da05046aaa78" ] } }, @@ -347,37 +283,7 @@ "listen": "test", "script": { "exec": [ - "pm.test(\"status code: 200\", () => {", - " pm.response.to.have.status(200);", - "});", - "", - "pm.test(\"Check room name: input = output\", () => {", - "", - " let res = pm.response.json();", - " let req = JSON.parse(pm.request.body);", - "", - " pm.expect(res.name).to.eql(req.name);", - "", - "});", - "", - "pm.test(\"Check properties\", () => {", - "", - " let res = pm.response.json();", - "", - " let props = [", - " \"name\", \"timestamps\", \"_id\",", - " \"number\", \"floor\", \"icon\"", - " ];", - "", - " Object.keys(res).forEach((key) => {", - " pm.expect(props.includes(key)).to.be.true;", - " });", - "", - " props.forEach((item) => {", - " pm.expect(Object.prototype.hasOwnProperty.call(res, item)).to.be.true;", - " });", - "", - "})" + "" ], "type": "text/javascript" } @@ -388,7 +294,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"name\": \"Evening\",\n \"makros\": [{\n \"type\": \"command\",\n \"endpoint\": \"63a0ce5b33d59ec69d8ffe18\",\n \"command\": \"63a0ce5b33d59ec69d8ffe19\"\n }, {\n \"type\": \"command\",\n \"endpoint\": \"63a1753f44427ef1a83426bf\",\n \"command\": \"63a1753f44427ef1a83426c0\"\n }, {\n \"type\": \"command\",\n \"endpoint\": \"63a1753f44427ef1a83426af\",\n \"command\": \"63a1753f44427ef1a83426b0\"\n }]\n}", + "raw": "{\n \"_id\": \"658187db41c59ef57eb25df8\",\n \"name\": \"Evening\",\n \"makros\": [{\n \"type\": \"command\",\n \"endpoint\": \"63a0ce5b33d59ec69d8ffe18\",\n \"command\": \"63a0ce5b33d59ec69d8ffe19\"\n }, {\n \"type\": \"command\",\n \"endpoint\": \"63a1753f44427ef1a83426bf\",\n \"command\": \"63a1753f44427ef1a83426c0\"\n }, {\n \"type\": \"command\",\n \"endpoint\": \"63a1753f44427ef1a83426af\",\n \"command\": \"63a1753f44427ef1a83426b0\"\n }]\n}", "options": { "raw": { "language": "json" @@ -426,16 +332,7 @@ "listen": "test", "script": { "exec": [ - "pm.test(\"The response has all properties\", () => {", - " let json = pm.response.json();", - " pm.expect(json).to.have.lengthOf(json.length);", - "});", - "", - "pm.test(\"Status code is 200\", () => {", - " pm.response.to.have.status(200);", - "});", - "", - "console.log(\"Fooo\")" + "" ], "type": "text/javascript" } @@ -498,7 +395,7 @@ "method": "GET", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/scenes/6403506b0b4fe3536f0ba8d5", + "raw": "http://{{HOST}}:{{PORT}}/api/scenes/658187db41c59ef57eb25df8", "protocol": "http", "host": [ "{{HOST}}" @@ -507,39 +404,19 @@ "path": [ "api", "scenes", - "6403506b0b4fe3536f0ba8d5" + "658187db41c59ef57eb25df8" ] } }, "response": [] }, { - "name": "Update existing scene", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], + "name": "Get scene state", "request": { - "method": "PATCH", + "method": "GET", "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"name\": \"Evening\",\n \"makros\": [{\n \"type\": \"command\",\n \"endpoint\": \"63a0ce5b33d59ec69d8ffe18\",\n \"command\": \"63a0ce5b33d59ec69d8ffe19\"\n }, {\n \"type\": \"command\",\n \"endpoint\": \"63a1753f44427ef1a83426bf\",\n \"command\": \"63a1753f44427ef1a83426c0\"\n }, {\n \"type\": \"command\",\n \"endpoint\": \"63a1753f44427ef1a83426af\",\n \"command\": \"63a1753f44427ef1a83426b0\"\n }]\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/scenes/6406218c7f1a9f7c3f2b92e2", + "raw": "http://{{HOST}}:{{PORT}}/api/scenes/658187db41c59ef57eb25df8/state", "protocol": "http", "host": [ "{{HOST}}" @@ -548,43 +425,40 @@ "path": [ "api", "scenes", - "6406218c7f1a9f7c3f2b92e2" + "658187db41c59ef57eb25df8", + "state" ] } }, "response": [] }, { - "name": "Delete exisiting scene", + "name": "Update existing scene", "event": [ { "listen": "prerequest", "script": { "exec": [ - "console.log(\"_id varaible\", pm.variables.get(\"_id\"));" - ], - "type": "text/javascript" - } - }, - { - "listen": "test", - "script": { - "exec": [ - "console.log(\"_id varaible\", pm.variables.get(\"_id\"));", - "", - "pm.test(\"status code: 200\", () => {", - " pm.response.to.have.status(200);", - "});" + "" ], "type": "text/javascript" } } ], "request": { - "method": "DELETE", + "method": "PATCH", "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"Evening\",\n \"makros\": [{\n \"type\": \"command\",\n \"endpoint\": \"63a0ce5b33d59ec69d8ffe18\",\n \"command\": \"63a0ce5b33d59ec69d8ffe19\"\n }, {\n \"type\": \"command\",\n \"endpoint\": \"63a1753f44427ef1a83426bf\",\n \"command\": \"63a1753f44427ef1a83426c0\"\n }, {\n \"type\": \"timer\",\n \"value\": \"3000\"\n }, {\n \"type\": \"command\",\n \"endpoint\": \"63a1753f44427ef1a83426af\",\n \"command\": \"63a1753f44427ef1a83426b0\"\n }]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/scenes/6403506b0b4fe3536f0ba8d5", + "raw": "http://{{HOST}}:{{PORT}}/api/scenes/658187db41c59ef57eb25df8", "protocol": "http", "host": [ "{{HOST}}" @@ -593,7 +467,7 @@ "path": [ "api", "scenes", - "6403506b0b4fe3536f0ba8d5" + "658187db41c59ef57eb25df8" ] } }, @@ -605,7 +479,7 @@ "method": "POST", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/scenes/6403506b0b4fe3536f0ba8d5/trigger", + "raw": "http://{{HOST}}:{{PORT}}/api/scenes/658187db41c59ef57eb25df8/trigger", "protocol": "http", "host": [ "{{HOST}}" @@ -614,7 +488,7 @@ "path": [ "api", "scenes", - "6403506b0b4fe3536f0ba8d5", + "658187db41c59ef57eb25df8", "trigger" ] } @@ -627,7 +501,7 @@ "method": "POST", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/scenes/6403506b0b4fe3536f0ba8d5/abort", + "raw": "http://{{HOST}}:{{PORT}}/api/scenes/658187db41c59ef57eb25df8/abort", "protocol": "http", "host": [ "{{HOST}}" @@ -636,7 +510,7 @@ "path": [ "api", "scenes", - "6403506b0b4fe3536f0ba8d5", + "658187db41c59ef57eb25df8", "abort" ] } @@ -644,12 +518,32 @@ "response": [] }, { - "name": "Get scene state", + "name": "Delete exisiting scene", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], "request": { - "method": "GET", + "method": "DELETE", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/scenes/6403506b0b4fe3536f0ba8d5/state", + "raw": "http://{{HOST}}:{{PORT}}/api/scenes/658187db41c59ef57eb25df8", "protocol": "http", "host": [ "{{HOST}}" @@ -658,8 +552,7 @@ "path": [ "api", "scenes", - "6403506b0b4fe3536f0ba8d5", - "state" + "658187db41c59ef57eb25df8" ] } }, @@ -706,37 +599,7 @@ "listen": "test", "script": { "exec": [ - "pm.test(\"status code: 200\", () => {", - " pm.response.to.have.status(200);", - "});", - "", - "pm.test(\"Check room name: input = output\", () => {", - "", - " let res = pm.response.json();", - " let req = JSON.parse(pm.request.body);", - "", - " pm.expect(res.name).to.eql(req.name);", - "", - "});", - "", - "pm.test(\"Check properties\", () => {", - "", - " let res = pm.response.json();", - "", - " let props = [", - " \"name\", \"timestamps\", \"_id\",", - " \"number\", \"floor\", \"icon\"", - " ];", - "", - " Object.keys(res).forEach((key) => {", - " pm.expect(props.includes(key)).to.be.true;", - " });", - "", - " props.forEach((item) => {", - " pm.expect(Object.prototype.hasOwnProperty.call(res, item)).to.be.true;", - " });", - "", - "})" + "" ], "type": "text/javascript" } @@ -747,7 +610,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"name\": \"shelly*.local\",\n \"type\": \"A\"\n}", + "raw": "{\n \"_id\": \"658188273df500c8cd1524cc\",\n \"name\": \"shelly*.local\",\n \"type\": \"A\"\n}", "options": { "raw": { "language": "json" @@ -785,16 +648,7 @@ "listen": "test", "script": { "exec": [ - "pm.test(\"The response has all properties\", () => {", - " let json = pm.response.json();", - " pm.expect(json).to.have.lengthOf(json.length);", - "});", - "", - "pm.test(\"Status code is 200\", () => {", - " pm.response.to.have.status(200);", - "});", - "", - "console.log(\"Fooo\")" + "" ], "type": "text/javascript" } @@ -851,7 +705,7 @@ "method": "GET", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/mdns/63e7f7ba26b161df7f3af1d6", + "raw": "http://{{HOST}}:{{PORT}}/api/mdns/658188273df500c8cd1524cc", "protocol": "http", "host": [ "{{HOST}}" @@ -860,7 +714,7 @@ "path": [ "api", "mdns", - "63e7f7ba26b161df7f3af1d6" + "658188273df500c8cd1524cc" ] } }, @@ -873,29 +727,7 @@ "listen": "prerequest", "script": { "exec": [ - "const HOST = pm.collectionVariables.get(\"HOST\");", - "const PORT = pm.collectionVariables.get(\"PORT\");", - "", - "//console.log(pm.request.url.toString())", - "", - "pm.sendRequest({", - " url: `http://${HOST}:${PORT}/api/rooms/`,", - " method: 'GET',", - "}, function (err, res) {", - " if(err){", - "", - " consle.error(err);", - "", - " }else {", - "", - " let data = res.json();", - " let key = Math.floor(Math.random()*data.length);", - " let item = data[key];", - "", - " pm.variables.set(\"_id\", item._id);", - "", - " }", - "});" + "" ], "type": "text/javascript" } @@ -914,7 +746,7 @@ } }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/mdns/63e7f7ba26b161df7f3af1d6", + "raw": "http://{{HOST}}:{{PORT}}/api/mdns/658188273df500c8cd1524cc", "protocol": "http", "host": [ "{{HOST}}" @@ -923,7 +755,7 @@ "path": [ "api", "mdns", - "63e7f7ba26b161df7f3af1d6" + "658188273df500c8cd1524cc" ] } }, @@ -936,7 +768,7 @@ "listen": "prerequest", "script": { "exec": [ - "console.log(\"_id varaible\", pm.variables.get(\"_id\"));" + "" ], "type": "text/javascript" } @@ -945,11 +777,7 @@ "listen": "test", "script": { "exec": [ - "console.log(\"_id varaible\", pm.variables.get(\"_id\"));", - "", - "pm.test(\"status code: 200\", () => {", - " pm.response.to.have.status(200);", - "});" + "" ], "type": "text/javascript" } @@ -959,7 +787,7 @@ "method": "DELETE", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/mdns/63e7f7ba26b161df7f3af1d6", + "raw": "http://{{HOST}}:{{PORT}}/api/mdns/658188273df500c8cd1524cc", "protocol": "http", "host": [ "{{HOST}}" @@ -968,7 +796,7 @@ "path": [ "api", "mdns", - "63e7f7ba26b161df7f3af1d6" + "658188273df500c8cd1524cc" ] } }, @@ -1015,37 +843,7 @@ "listen": "test", "script": { "exec": [ - "pm.test(\"status code: 200\", () => {", - " pm.response.to.have.status(200);", - "});", - "", - "pm.test(\"Check room name: input = output\", () => {", - "", - " let res = pm.response.json();", - " let req = JSON.parse(pm.request.body);", - "", - " pm.expect(res.name).to.eql(req.name);", - "", - "});", - "", - "pm.test(\"Check properties\", () => {", - "", - " let res = pm.response.json();", - "", - " let props = [", - " \"name\", \"timestamps\", \"_id\",", - " \"number\", \"floor\", \"icon\"", - " ];", - "", - " Object.keys(res).forEach((key) => {", - " pm.expect(props.includes(key)).to.be.true;", - " });", - "", - " props.forEach((item) => {", - " pm.expect(Object.prototype.hasOwnProperty.call(res, item)).to.be.true;", - " });", - "", - "})" + "" ], "type": "text/javascript" } @@ -1056,7 +854,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"topic\": \"air-sensor/sensor/particulate_matter_25m_concentration\"\n}", + "raw": "{\n \"_id\": \"65818856464bebcf19ebec4c\",\n \"topic\": \"air-sensor/sensor/particulate_matter_25m_concentration\"\n}", "options": { "raw": { "language": "json" @@ -1094,16 +892,7 @@ "listen": "test", "script": { "exec": [ - "pm.test(\"The response has all properties\", () => {", - " let json = pm.response.json();", - " pm.expect(json).to.have.lengthOf(json.length);", - "});", - "", - "pm.test(\"Status code is 200\", () => {", - " pm.response.to.have.status(200);", - "});", - "", - "console.log(\"Fooo\")" + "" ], "type": "text/javascript" } @@ -1160,7 +949,7 @@ "method": "GET", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/mqtt/63e8f7d2ab413a9760e9b08c", + "raw": "http://{{HOST}}:{{PORT}}/api/mqtt/65818856464bebcf19ebec4c", "protocol": "http", "host": [ "{{HOST}}" @@ -1169,7 +958,7 @@ "path": [ "api", "mqtt", - "63e8f7d2ab413a9760e9b08c" + "65818856464bebcf19ebec4c" ] } }, @@ -1182,29 +971,7 @@ "listen": "prerequest", "script": { "exec": [ - "const HOST = pm.collectionVariables.get(\"HOST\");", - "const PORT = pm.collectionVariables.get(\"PORT\");", - "", - "//console.log(pm.request.url.toString())", - "", - "pm.sendRequest({", - " url: `http://${HOST}:${PORT}/api/rooms/`,", - " method: 'GET',", - "}, function (err, res) {", - " if(err){", - "", - " consle.error(err);", - "", - " }else {", - "", - " let data = res.json();", - " let key = Math.floor(Math.random()*data.length);", - " let item = data[key];", - "", - " pm.variables.set(\"_id\", item._id);", - "", - " }", - "});" + "" ], "type": "text/javascript" } @@ -1223,7 +990,7 @@ } }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/mqtt/63e8f7d2ab413a9760e9b08c", + "raw": "http://{{HOST}}:{{PORT}}/api/mqtt/65818856464bebcf19ebec4c", "protocol": "http", "host": [ "{{HOST}}" @@ -1232,7 +999,7 @@ "path": [ "api", "mqtt", - "63e8f7d2ab413a9760e9b08c" + "65818856464bebcf19ebec4c" ] } }, @@ -1245,7 +1012,7 @@ "listen": "prerequest", "script": { "exec": [ - "console.log(\"_id varaible\", pm.variables.get(\"_id\"));" + "" ], "type": "text/javascript" } @@ -1254,11 +1021,7 @@ "listen": "test", "script": { "exec": [ - "console.log(\"_id varaible\", pm.variables.get(\"_id\"));", - "", - "pm.test(\"status code: 200\", () => {", - " pm.response.to.have.status(200);", - "});" + "" ], "type": "text/javascript" } @@ -1268,7 +1031,7 @@ "method": "DELETE", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/mqtt/63e8f7d2ab413a9760e9b08c", + "raw": "http://{{HOST}}:{{PORT}}/api/mqtt/65818856464bebcf19ebec4c", "protocol": "http", "host": [ "{{HOST}}" @@ -1277,7 +1040,7 @@ "path": [ "api", "mqtt", - "63e8f7d2ab413a9760e9b08c" + "65818856464bebcf19ebec4c" ] } }, @@ -1324,37 +1087,7 @@ "listen": "test", "script": { "exec": [ - "pm.test(\"status code: 200\", () => {", - " pm.response.to.have.status(200);", - "});", - "", - "pm.test(\"Check room name: input = output\", () => {", - "", - " let res = pm.response.json();", - " let req = JSON.parse(pm.request.body);", - "", - " pm.expect(res.name).to.eql(req.name);", - "", - "});", - "", - "pm.test(\"Check properties\", () => {", - "", - " let res = pm.response.json();", - "", - " let props = [", - " \"name\", \"timestamps\", \"_id\",", - " \"number\", \"floor\", \"icon\"", - " ];", - "", - " Object.keys(res).forEach((key) => {", - " pm.expect(props.includes(key)).to.be.true;", - " });", - "", - " props.forEach((item) => {", - " pm.expect(Object.prototype.hasOwnProperty.call(res, item)).to.be.true;", - " });", - "", - "})" + "" ], "type": "text/javascript" } @@ -1365,7 +1098,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"nt\": \"urn:schemas-upnp-org:device:sensor:1\",\n \"description\": null,\n \"usn\": null\n}", + "raw": "{\n \"_id\": \"65818876deb8cb80755ade02\",\n \"nt\": \"urn:schemas-upnp-org:device:sensor:1\"\n}", "options": { "raw": { "language": "json" @@ -1403,16 +1136,7 @@ "listen": "test", "script": { "exec": [ - "pm.test(\"The response has all properties\", () => {", - " let json = pm.response.json();", - " pm.expect(json).to.have.lengthOf(json.length);", - "});", - "", - "pm.test(\"Status code is 200\", () => {", - " pm.response.to.have.status(200);", - "});", - "", - "console.log(\"Fooo\")" + "" ], "type": "text/javascript" } @@ -1469,7 +1193,7 @@ "method": "GET", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/ssdp/63cbcdb1f2c46434242de489", + "raw": "http://{{HOST}}:{{PORT}}/api/ssdp/65818876deb8cb80755ade02", "protocol": "http", "host": [ "{{HOST}}" @@ -1478,7 +1202,7 @@ "path": [ "api", "ssdp", - "63cbcdb1f2c46434242de489" + "65818876deb8cb80755ade02" ] } }, @@ -1510,7 +1234,7 @@ } }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/ssdp/63cbcdb1f2c46434242de489", + "raw": "http://{{HOST}}:{{PORT}}/api/ssdp/65818876deb8cb80755ade02", "protocol": "http", "host": [ "{{HOST}}" @@ -1519,7 +1243,7 @@ "path": [ "api", "ssdp", - "63cbcdb1f2c46434242de489" + "65818876deb8cb80755ade02" ] } }, @@ -1532,7 +1256,7 @@ "listen": "prerequest", "script": { "exec": [ - "console.log(\"_id varaible\", pm.variables.get(\"_id\"));" + "" ], "type": "text/javascript" } @@ -1541,11 +1265,7 @@ "listen": "test", "script": { "exec": [ - "console.log(\"_id varaible\", pm.variables.get(\"_id\"));", - "", - "pm.test(\"status code: 200\", () => {", - " pm.response.to.have.status(200);", - "});" + "" ], "type": "text/javascript" } @@ -1555,7 +1275,7 @@ "method": "DELETE", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/ssdp/63cbcdb1f2c46434242de489", + "raw": "http://{{HOST}}:{{PORT}}/api/ssdp/65818876deb8cb80755ade02", "protocol": "http", "host": [ "{{HOST}}" @@ -1564,7 +1284,7 @@ "path": [ "api", "ssdp", - "63cbcdb1f2c46434242de489" + "65818876deb8cb80755ade02" ] } }, @@ -1611,37 +1331,7 @@ "listen": "test", "script": { "exec": [ - "pm.test(\"status code: 200\", () => {", - " pm.response.to.have.status(200);", - "});", - "", - "pm.test(\"Check room name: input = output\", () => {", - "", - " let res = pm.response.json();", - " let req = JSON.parse(pm.request.body);", - "", - " pm.expect(res.name).to.eql(req.name);", - "", - "});", - "", - "pm.test(\"Check properties\", () => {", - "", - " let res = pm.response.json();", - "", - " let props = [", - " \"name\", \"timestamps\", \"_id\",", - " \"number\", \"floor\", \"icon\"", - " ];", - "", - " Object.keys(res).forEach((key) => {", - " pm.expect(props.includes(key)).to.be.true;", - " });", - "", - " props.forEach((item) => {", - " pm.expect(Object.prototype.hasOwnProperty.call(res, item)).to.be.true;", - " });", - "", - "})" + "" ], "type": "text/javascript" } @@ -1652,7 +1342,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"name\": \"Hans Hubert #3\",\n \"email\": \"hans.hubert3@example.com\",\n \"password\": \"Pa$$w0rd\"\n}", + "raw": "{\n \"_id\": \"658188a7aadfcc026a0e0131\",\n \"name\": \"Hans Hubert #3\",\n \"email\": \"hans.hubert3@example.com\",\n \"password\": \"Pa$$w0rd\"\n}", "options": { "raw": { "language": "json" @@ -1752,7 +1442,7 @@ "method": "GET", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/users/6288b67b1f3bc42774ce0ec1", + "raw": "http://{{HOST}}:{{PORT}}/api/users/658188a7aadfcc026a0e0131", "protocol": "http", "host": [ "{{HOST}}" @@ -1761,7 +1451,7 @@ "path": [ "api", "users", - "6288b67b1f3bc42774ce0ec1" + "658188a7aadfcc026a0e0131" ] } }, @@ -1774,29 +1464,7 @@ "listen": "prerequest", "script": { "exec": [ - "const HOST = pm.collectionVariables.get(\"HOST\");", - "const PORT = pm.collectionVariables.get(\"PORT\");", - "", - "//console.log(pm.request.url.toString())", - "", - "pm.sendRequest({", - " url: `http://${HOST}:${PORT}/api/rooms/`,", - " method: 'GET',", - "}, function (err, res) {", - " if(err){", - "", - " consle.error(err);", - "", - " }else {", - "", - " let data = res.json();", - " let key = Math.floor(Math.random()*data.length);", - " let item = data[key];", - "", - " pm.variables.set(\"_id\", item._id);", - "", - " }", - "});" + "" ], "type": "text/javascript" } @@ -1815,7 +1483,7 @@ } }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/users/6288b67b1f3bc42774ce0ec1", + "raw": "http://{{HOST}}:{{PORT}}/api/users/658188a7aadfcc026a0e0131", "protocol": "http", "host": [ "{{HOST}}" @@ -1824,7 +1492,7 @@ "path": [ "api", "users", - "6288b67b1f3bc42774ce0ec1" + "658188a7aadfcc026a0e0131" ] } }, @@ -1837,7 +1505,7 @@ "listen": "prerequest", "script": { "exec": [ - "console.log(\"_id varaible\", pm.variables.get(\"_id\"));" + "" ], "type": "text/javascript" } @@ -1846,11 +1514,7 @@ "listen": "test", "script": { "exec": [ - "console.log(\"_id varaible\", pm.variables.get(\"_id\"));", - "", - "pm.test(\"status code: 200\", () => {", - " pm.response.to.have.status(200);", - "});" + "" ], "type": "text/javascript" } @@ -1860,7 +1524,7 @@ "method": "DELETE", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/users/6288b67b1f3bc42774ce0ec1", + "raw": "http://{{HOST}}:{{PORT}}/api/users/658188a7aadfcc026a0e0131", "protocol": "http", "host": [ "{{HOST}}" @@ -1869,7 +1533,7 @@ "path": [ "api", "users", - "6288b67b1f3bc42774ce0ec1" + "658188a7aadfcc026a0e0131" ] } }, @@ -1907,7 +1571,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"name\": \"Phoscon Gateway\",\n \"enabled\": true,\n \"version\": 1,\n \"intents\": [\n \"devices\", \n \"endpoints\", \n \"ssdp\", \n \"vault\", \n \"store\"\n ]\n}", + "raw": "{\n \"_id\": \"658188e93cde9987c3228806\",\n \"name\": \"Plugin Boilerplate Demo\",\n \"enabled\": true,\n \"version\": 1,\n \"intents\": [\n \"devices\",\n \"endpoints\",\n \"plugins\",\n \"rooms\",\n \"ssdp\",\n \"store\",\n \"users\",\n \"vault\"\n ]\n}", "options": { "raw": { "language": "json" @@ -1931,18 +1595,12 @@ "response": [] }, { - "name": "Upload plugin *.tgz content", + "name": "Get all plugins", "request": { - "method": "PUT", + "method": "GET", "header": [], - "body": { - "mode": "file", - "file": { - "src": "" - } - }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/plugins/63a17284ba003ca7440f97e3/files", + "raw": "http://{{HOST}}:{{PORT}}/api/plugins", "protocol": "http", "host": [ "{{HOST}}" @@ -1950,27 +1608,19 @@ "port": "{{PORT}}", "path": [ "api", - "plugins", - "63a17284ba003ca7440f97e3", - "files" + "plugins" ] } }, "response": [] }, { - "name": "Delete plugin *.tgz content", + "name": "Get sinlge plugin", "request": { - "method": "DELETE", + "method": "GET", "header": [], - "body": { - "mode": "file", - "file": { - "src": "/home/marc/projects/playground/oh-plg-dummy/oh-plg-dummy-v1.0.0.tgz" - } - }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/plugins/639efd69e42746a787a02455/files", + "raw": "http://{{HOST}}:{{PORT}}/api/plugins/658188e93cde9987c3228806", "protocol": "http", "host": [ "{{HOST}}" @@ -1979,20 +1629,28 @@ "path": [ "api", "plugins", - "639efd69e42746a787a02455", - "files" + "658188e93cde9987c3228806" ] } }, "response": [] }, { - "name": "Get all plugins", + "name": "Update existing plugins", "request": { - "method": "GET", + "method": "PATCH", "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"New updated\",\n \"enabled\": true,\n \"autostart\": false\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/plugins", + "raw": "http://{{HOST}}:{{PORT}}/api/plugins/658188e93cde9987c3228806", "protocol": "http", "host": [ "{{HOST}}" @@ -2000,19 +1658,26 @@ "port": "{{PORT}}", "path": [ "api", - "plugins" + "plugins", + "658188e93cde9987c3228806" ] } }, "response": [] }, { - "name": "Get sinlge plugin", + "name": "Upload plugin *.tgz content", "request": { - "method": "GET", + "method": "PUT", "header": [], + "body": { + "mode": "file", + "file": { + "src": "/home/marc/projects/OpenHaus/plugins/plugin-boilerplate/dist/oh-plg-plugin-boilerplate.tgz" + } + }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/plugins/", + "raw": "http://{{HOST}}:{{PORT}}/api/plugins/658188e93cde9987c3228806/files", "protocol": "http", "host": [ "{{HOST}}" @@ -2021,28 +1686,20 @@ "path": [ "api", "plugins", - "" + "658188e93cde9987c3228806", + "files" ] } }, "response": [] }, { - "name": "Update existing plugins", + "name": "Start plugin", "request": { - "method": "PATCH", + "method": "POST", "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"enabled\": true,\n \"autostart\": false\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/plugins/61103781f897a74ae9ca89c7", + "raw": "http://{{HOST}}:{{PORT}}/api/plugins/658188e93cde9987c3228806/start", "protocol": "http", "host": [ "{{HOST}}" @@ -2051,19 +1708,26 @@ "path": [ "api", "plugins", - "61103781f897a74ae9ca89c7" + "658188e93cde9987c3228806", + "start" ] } }, "response": [] }, { - "name": "Delete exisiting plugins", + "name": "Delete plugin *.tgz content", "request": { "method": "DELETE", "header": [], + "body": { + "mode": "file", + "file": { + "src": "/home/marc/projects/playground/oh-plg-dummy/oh-plg-dummy-v1.0.0.tgz" + } + }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/plugins/62868c7e9af74130e98863c1", + "raw": "http://{{HOST}}:{{PORT}}/api/plugins/658188e93cde9987c3228806/files", "protocol": "http", "host": [ "{{HOST}}" @@ -2072,19 +1736,20 @@ "path": [ "api", "plugins", - "62868c7e9af74130e98863c1" + "658188e93cde9987c3228806", + "files" ] } }, "response": [] }, { - "name": "Start plugin", + "name": "Delete exisiting plugins", "request": { - "method": "POST", + "method": "DELETE", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/plugins/63f500ea2b40698e90e63beb/start", + "raw": "http://{{HOST}}:{{PORT}}/api/plugins/658188e93cde9987c3228806", "protocol": "http", "host": [ "{{HOST}}" @@ -2093,8 +1758,7 @@ "path": [ "api", "plugins", - "63f500ea2b40698e90e63beb", - "start" + "658188e93cde9987c3228806" ] } }, @@ -2112,7 +1776,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"name\": \"SmartMeter\",\n \"interfaces\": [{\n \"type\": \"ETHERNET\",\n \"description\": \"WebSocket API\",\n \"settings\": {\n \"host\": \"192.168.2.155\",\n \"port\": 8080\n },\n \"adapter\": [\"raw\"]\n }],\n \"room\": \"62a4bc8bd9256b5e8d6988a0\",\n \"icon\": \"fa-solid fa-gauge-high\"\n}", + "raw": "{\n \"_id\": \"65818918d32dad8dab53e433\",\n \"name\": \"SmartMeter\",\n \"interfaces\": [{\n \"_id\": \"6581c55abc21a0a3122b9998\",\n \"type\": \"ETHERNET\",\n \"description\": \"WebSocket API\",\n \"settings\": {\n \"host\": \"192.168.2.155\",\n \"port\": 8080\n },\n \"adapter\": [\"raw\"]\n }],\n \"room\": \"62a4bc8bd9256b5e8d6988a0\",\n \"icon\": \"fa-solid fa-gauge-high\"\n}", "options": { "raw": { "language": "json" @@ -2160,7 +1824,7 @@ "method": "GET", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/devices/6042785432c51e3e98e7acc0", + "raw": "http://{{HOST}}:{{PORT}}/api/devices/65818918d32dad8dab53e433", "protocol": "http", "host": [ "{{HOST}}" @@ -2169,7 +1833,7 @@ "path": [ "api", "devices", - "6042785432c51e3e98e7acc0" + "65818918d32dad8dab53e433" ] } }, @@ -2190,7 +1854,7 @@ } }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/devices/63bf020e82fa29f44cf8dfd8", + "raw": "http://{{HOST}}:{{PORT}}/api/devices/65818918d32dad8dab53e433", "protocol": "http", "host": [ "{{HOST}}" @@ -2199,7 +1863,7 @@ "path": [ "api", "devices", - "63bf020e82fa29f44cf8dfd8" + "65818918d32dad8dab53e433" ] } }, @@ -2211,7 +1875,7 @@ "method": "DELETE", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/devices/61103caa50139f51160ae790", + "raw": "http://{{HOST}}:{{PORT}}/api/devices/65818918d32dad8dab53e433", "protocol": "http", "host": [ "{{HOST}}" @@ -2220,7 +1884,7 @@ "path": [ "api", "devices", - "61103caa50139f51160ae790" + "65818918d32dad8dab53e433" ] } }, @@ -2238,7 +1902,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"name\": \"Dummy Endpoint\",\n \"device\": \"6398ae590dce390161f7fc2f\",\n \"states\": [\n {\n \"name\": \"Total Power\",\n \"alias\": \"POWER_TOTAL\",\n \"type\": \"number\"\n },\n {\n \"name\": \"Powerd on?\",\n \"alias\": \"POWERD_ON\",\n \"type\": \"boolean\"\n }\n ],\n \"commands\": [\n {\n \"name\": \"Switch to Input 03\",\n \"payload\": {\n \"type\": \"Buffer\",\n \"data\": [\n 115,\n 119,\n 32,\n 105,\n 48,\n 51,\n 13,\n 10\n ]\n },\n \"alias\": \"INPUT_03\",\n \"interface\": \"6398ae590dce390161f7fc30\"\n },\n {\n \"name\": \"Command as String\",\n \"payload\": \"foobar\",\n \"alias\": \"STRING_CMD\",\n \"interface\": \"6398ae590dce390161f7fc30\"\n }\n ]\n}\n", + "raw": "{\n \"_id\": \"658189336fa19198939caa21\",\n \"name\": \"Dummy Endpoint\",\n \"device\": \"6398ae590dce390161f7fc2f\",\n \"states\": [\n {\n \"_id\": \"658190d232fe653a07638863\",\n \"name\": \"Total Power\",\n \"alias\": \"POWER_TOTAL\",\n \"type\": \"number\"\n },\n {\n \"_id\": \"658190de4a1369d179c3387f\",\n \"name\": \"Powerd on?\",\n \"alias\": \"POWERD_ON\",\n \"type\": \"boolean\"\n }\n ],\n \"commands\": [\n {\n \"_id\": \"658190acbccb180491c2672c\",\n \"name\": \"Switch to Input 03\",\n \"payload\": {\n \"type\": \"Buffer\",\n \"data\": [\n 115,\n 119,\n 32,\n 105,\n 48,\n 51,\n 13,\n 10\n ]\n },\n \"alias\": \"INPUT_03\",\n \"interface\": \"6581c55abc21a0a3122b9998\"\n },\n {\n \"_id\": \"658190ec0e09c0d5d22c59f0\",\n \"name\": \"Command as String\",\n \"payload\": \"foobar\",\n \"alias\": \"STRING_CMD\",\n \"interface\": \"6581c55abc21a0a3122b9998\"\n }\n ]\n}\n", "options": { "raw": { "language": "json" @@ -2286,7 +1950,7 @@ "method": "GET", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/endpoints/604a75e6eb5de037846df24f", + "raw": "http://{{HOST}}:{{PORT}}/api/endpoints/658189336fa19198939caa21", "protocol": "http", "host": [ "{{HOST}}" @@ -2295,7 +1959,7 @@ "path": [ "api", "endpoints", - "604a75e6eb5de037846df24f" + "658189336fa19198939caa21" ] } }, @@ -2303,12 +1967,23 @@ }, { "name": "Update existing endpoint", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], "request": { "method": "PATCH", "header": [], "body": { "mode": "raw", - "raw": " {\n \"_id\": \"63a5a4c2bd5fe7cb165960d0\",\n \"name\": \"Fernseher\",\n \"device\": \"63a5a4c2bd5fe7cb165960cd\",\n \"commands\": [\n {\n \"payload\": \"KEY_0\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_0\",\n \"name\": \"KEY_0\",\n \"_id\": \"63a5a4c2bd5fe7cb165960d1\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_1\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_1\",\n \"name\": \"KEY_1\",\n \"_id\": \"63a5a4c2bd5fe7cb165960d2\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_2\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_2\",\n \"name\": \"KEY_2\",\n \"_id\": \"63a5a4c2bd5fe7cb165960d3\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_3\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_3\",\n \"name\": \"KEY_3\",\n \"_id\": \"63a5a4c2bd5fe7cb165960d4\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_4\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_4\",\n \"name\": \"KEY_4\",\n \"_id\": \"63a5a4c2bd5fe7cb165960d5\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_5\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_5\",\n \"name\": \"KEY_5\",\n \"_id\": \"63a5a4c2bd5fe7cb165960d6\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_6\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_6\",\n \"name\": \"KEY_6\",\n \"_id\": \"63a5a4c2bd5fe7cb165960d7\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_7\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_7\",\n \"name\": \"KEY_7\",\n \"_id\": \"63a5a4c2bd5fe7cb165960d8\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_8\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_8\",\n \"name\": \"KEY_8\",\n \"_id\": \"63a5a4c2bd5fe7cb165960d9\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_9\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_9\",\n \"name\": \"KEY_9\",\n \"_id\": \"63a5a4c2bd5fe7cb165960da\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_10\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_10\",\n \"name\": \"KEY_10\",\n \"_id\": \"63a5a4c2bd5fe7cb165960db\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_11\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_11\",\n \"name\": \"KEY_11\",\n \"_id\": \"63a5a4c2bd5fe7cb165960dc\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_12\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_12\",\n \"name\": \"KEY_12\",\n \"_id\": \"63a5a4c2bd5fe7cb165960dd\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_CHDOWN\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_CHDOWN\",\n \"name\": \"KEY_CHDOWN\",\n \"_id\": \"63a5a4c2bd5fe7cb165960de\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_CHUP\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_CHUP\",\n \"name\": \"KEY_CHUP\",\n \"_id\": \"63a5a4c2bd5fe7cb165960df\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_VOLDOWN\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_VOLDOWN\",\n \"name\": \"KEY_VOLDOWN\",\n \"_id\": \"63a5a4c2bd5fe7cb165960e0\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_VOLUP\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_VOLUP\",\n \"name\": \"KEY_VOLUP\",\n \"_id\": \"63a5a4c2bd5fe7cb165960e1\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_MUTE\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_MUTE\",\n \"name\": \"KEY_MUTE\",\n \"_id\": \"63a5a4c2bd5fe7cb165960e2\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_SOURCE\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_SOURCE\",\n \"name\": \"KEY_SOURCE\",\n \"_id\": \"63a5a4c2bd5fe7cb165960e3\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_LEFT\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_LEFT\",\n \"name\": \"KEY_LEFT\",\n \"_id\": \"63a5a4c2bd5fe7cb165960e4\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_RIGHT\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_RIGHT\",\n \"name\": \"KEY_RIGHT\",\n \"_id\": \"63a5a4c2bd5fe7cb165960e5\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_UP\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_UP\",\n \"name\": \"KEY_UP\",\n \"_id\": \"63a5a4c2bd5fe7cb165960e6\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_DOWN\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_DOWN\",\n \"name\": \"KEY_DOWN\",\n \"_id\": \"63a5a4c2bd5fe7cb165960e7\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_ENTER\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_ENTER\",\n \"name\": \"KEY_ENTER\",\n \"_id\": \"63a5a4c2bd5fe7cb165960e8\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_MENU\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_MENU\",\n \"name\": \"KEY_MENU\",\n \"_id\": \"63a5a4c2bd5fe7cb165960e9\",\n \"identifier\": null,\n \"description\": null\n },\n {\n \"payload\": \"KEY_EXIT\",\n \"interface\": \"63a5a4c2bd5fe7cb165960ce\",\n \"alias\": \"KEY_EXIT\",\n \"name\": \"KEY_EXIT\",\n \"_id\": \"63a5a4c2bd5fe7cb165960ea\",\n \"identifier\": null,\n \"description\": null\n }\n ],\n \"timestamps\": {\n \"created\": 1671800002321,\n \"updated\": null\n },\n \"enabled\": true,\n \"room\": \"62a4bbf0d9256b5e8d69889c\",\n \"states\": [],\n \"identifier\": null,\n \"icon\": \"fa-solid fa-tv\"\n }", + "raw": "{\n \"name\": \"Dummy Endpoint (name changed)\",\n \"device\": \"6398ae590dce390161f7fc2f\",\n \"commands\": [{\n \"_id\": \"6581fc8ac20cb522e02868ff\",\n \"name\": \"new command\",\n \"payload\": \"new_command\",\n \"alias\": \"new_cmd\",\n \"interface\": \"6398ae590dce390161f7fc30\"\n }]\n}\n", "options": { "raw": { "language": "json" @@ -2316,7 +1991,7 @@ } }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/endpoints/63a5a4c2bd5fe7cb165960d0", + "raw": "http://{{HOST}}:{{PORT}}/api/endpoints/658189336fa19198939caa21", "protocol": "http", "host": [ "{{HOST}}" @@ -2325,19 +2000,28 @@ "path": [ "api", "endpoints", - "63a5a4c2bd5fe7cb165960d0" + "658189336fa19198939caa21" ] } }, "response": [] }, { - "name": "Delete exisiting endpoint", + "name": "Set endpoint state", "request": { - "method": "DELETE", + "method": "POST", "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"value\": 54\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/endpoints/61103caa50139f51160ae790", + "raw": "http://{{HOST}}:{{PORT}}/api/endpoints/658189336fa19198939caa21/states/658190d232fe653a07638863", "protocol": "http", "host": [ "{{HOST}}" @@ -2346,9 +2030,12 @@ "path": [ "api", "endpoints", - "61103caa50139f51160ae790" + "658189336fa19198939caa21", + "states", + "658190d232fe653a07638863" ] - } + }, + "description": "TODO!" }, "response": [] }, @@ -2367,7 +2054,7 @@ } }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/endpoints/610e865a0c7edd636843a409/commands/610e865a0c7edd636843a406", + "raw": "http://{{HOST}}:{{PORT}}/api/endpoints/658189336fa19198939caa21/commands/6581fc8ac20cb522e02868ff", "protocol": "http", "host": [ "{{HOST}}" @@ -2376,30 +2063,21 @@ "path": [ "api", "endpoints", - "610e865a0c7edd636843a409", + "658189336fa19198939caa21", "commands", - "610e865a0c7edd636843a406" + "6581fc8ac20cb522e02868ff" ] } }, "response": [] }, { - "name": "Set endpoint state", + "name": "Delete exisiting endpoint", "request": { - "method": "POST", + "method": "DELETE", "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"value\": 54\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/endpoints/6398b0bcf8a893ef43e283d5/states/6398b0bcf8a893ef43e283d8", + "raw": "http://{{HOST}}:{{PORT}}/api/endpoints/658189336fa19198939caa21", "protocol": "http", "host": [ "{{HOST}}" @@ -2408,12 +2086,9 @@ "path": [ "api", "endpoints", - "6398b0bcf8a893ef43e283d5", - "states", - "6398b0bcf8a893ef43e283d8" + "658189336fa19198939caa21" ] - }, - "description": "TODO!" + } }, "response": [] } @@ -2429,7 +2104,7 @@ "listen": "prerequest", "script": { "exec": [ - "pm.request.payload = JSON.parse(pm.request.body.raw);" + "" ], "type": "text/javascript" } @@ -2438,16 +2113,7 @@ "listen": "test", "script": { "exec": [ - "", - "", - "", - "console.log(pm.request.payload)", - "", - "pm.test(\"Input = Output name\", () => {", - "", - " ", - "", - "});" + "" ], "type": "text/javascript" } @@ -2458,7 +2124,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"name\": \"FritzBox\",\n \"identifier\": \"FRITZBOX\",\n \"secrets\": [{\n \"key\": \"USERNAME\",\n \"name\": \"Username\",\n \"value\": \"username@example.com\"\n }, {\n \"key\": \"PASSWORD\",\n \"name\": \"Password\",\n \"value\": \"Pa$$w0rd\"\n }]\n}", + "raw": "{\n \"_id\": \"6581896929ae93ba734cc72a\",\n \"name\": \"FritzBox\",\n \"identifier\": \"FRITZBOX\",\n \"secrets\": [{\n \"_id\": \"65818cb27c731f3cba187149\",\n \"key\": \"USERNAME\",\n \"name\": \"Username\",\n \"value\": \"username@example.com\"\n }, {\n \"_id\": \"65818cbdb9302888a0b6ca35\",\n \"key\": \"PASSWORD\",\n \"name\": \"Password\",\n \"value\": \"Pa$$w0rd\"\n }]\n}", "options": { "raw": { "language": "json" @@ -2506,7 +2172,7 @@ "method": "GET", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/vault/63a5a4c2bd5fe7cb165960eb", + "raw": "http://{{HOST}}:{{PORT}}/api/vault/6581896929ae93ba734cc72a", "protocol": "http", "host": [ "{{HOST}}" @@ -2515,7 +2181,7 @@ "path": [ "api", "vault", - "63a5a4c2bd5fe7cb165960eb" + "6581896929ae93ba734cc72a" ] } }, @@ -2527,7 +2193,7 @@ "method": "GET", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/vault/639c9562cece5101bdccdeb1/secrets", + "raw": "http://{{HOST}}:{{PORT}}/api/vault/6581896929ae93ba734cc72a/secrets", "protocol": "http", "host": [ "{{HOST}}" @@ -2536,7 +2202,7 @@ "path": [ "api", "vault", - "639c9562cece5101bdccdeb1", + "6581896929ae93ba734cc72a", "secrets" ] } @@ -2558,7 +2224,7 @@ } }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/vault/637a5f290a21379bf30c62be/secrets/637a614b0a21379bf30c62c2/encrypt", + "raw": "http://{{HOST}}:{{PORT}}/api/vault/6581896929ae93ba734cc72a/secrets/65818cb27c731f3cba187149/encrypt", "protocol": "http", "host": [ "{{HOST}}" @@ -2567,9 +2233,9 @@ "path": [ "api", "vault", - "637a5f290a21379bf30c62be", + "6581896929ae93ba734cc72a", "secrets", - "637a614b0a21379bf30c62c2", + "65818cb27c731f3cba187149", "encrypt" ] } @@ -2583,7 +2249,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"PASSWORD\": \"Pa$$w0rd\",\n \"USERNAME\": \"user-1@example.com\"\n}", + "raw": "", "options": { "raw": { "language": "json" @@ -2591,7 +2257,7 @@ } }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/vault/637a5f290a21379bf30c62be/secrets/637a614b0a21379bf30c62c2/decrypt", + "raw": "http://{{HOST}}:{{PORT}}/api/vault/6581896929ae93ba734cc72a/secrets/65818cb27c731f3cba187149/decrypt", "protocol": "http", "host": [ "{{HOST}}" @@ -2600,9 +2266,9 @@ "path": [ "api", "vault", - "637a5f290a21379bf30c62be", + "6581896929ae93ba734cc72a", "secrets", - "637a614b0a21379bf30c62c2", + "65818cb27c731f3cba187149", "decrypt" ] } @@ -2624,7 +2290,7 @@ } }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/vault/61a15b436d63a6517e1385ed", + "raw": "http://{{HOST}}:{{PORT}}/api/vault/6581896929ae93ba734cc72a", "protocol": "http", "host": [ "{{HOST}}" @@ -2633,7 +2299,7 @@ "path": [ "api", "vault", - "61a15b436d63a6517e1385ed" + "6581896929ae93ba734cc72a" ] } }, @@ -2645,7 +2311,7 @@ "method": "DELETE", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/vault/", + "raw": "http://{{HOST}}:{{PORT}}/api/vault/6581896929ae93ba734cc72a", "protocol": "http", "host": [ "{{HOST}}" @@ -2654,7 +2320,7 @@ "path": [ "api", "vault", - "" + "6581896929ae93ba734cc72a" ] } }, @@ -2672,7 +2338,7 @@ "listen": "prerequest", "script": { "exec": [ - "pm.request.payload = JSON.parse(pm.request.body.raw);" + "" ], "type": "text/javascript" } @@ -2681,16 +2347,7 @@ "listen": "test", "script": { "exec": [ - "", - "", - "", - "console.log(pm.request.payload)", - "", - "pm.test(\"Input = Output name\", () => {", - "", - " ", - "", - "});" + "" ], "type": "text/javascript" } @@ -2701,7 +2358,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"config\": [{\n \"key\": \"pairing\",\n \"type\": \"boolean\",\n \"value\": false,\n \"description\": \"Is the Gateway ready for pairing?\"\n }, {\n \"key\": \"interval\",\n \"type\": \"number\",\n \"value\": 3000,\n \"description\": \"Sync intervall for Endpoints\"\n }]\n}", + "raw": "{\n \"_id\": \"65818986ca5133d8de2bb4a1\",\n \"config\": [{\n \"_id\": \"6581a14f1c6d01f32129dabc\",\n \"key\": \"pairing\",\n \"type\": \"boolean\",\n \"value\": false,\n \"description\": \"Is the Gateway ready for pairing?\"\n }, {\n \"_id\": \"6581a1520bcb15659d48b207\",\n \"key\": \"interval\",\n \"type\": \"number\",\n \"value\": 3000,\n \"description\": \"Sync intervall for Endpoints\"\n }]\n}", "options": { "raw": { "language": "json" @@ -2724,7 +2381,7 @@ "response": [] }, { - "name": "Get all config items", + "name": "Get all config stores", "request": { "method": "GET", "header": [], @@ -2744,12 +2401,12 @@ "response": [] }, { - "name": "Get single store item", + "name": "Get single store", "request": { "method": "GET", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/store/626cf0d940cbe8290f0b4e3f", + "raw": "http://{{HOST}}:{{PORT}}/api/store/65818986ca5133d8de2bb4a1", "protocol": "http", "host": [ "{{HOST}}" @@ -2758,7 +2415,7 @@ "path": [ "api", "store", - "626cf0d940cbe8290f0b4e3f" + "65818986ca5133d8de2bb4a1" ] } }, @@ -2770,7 +2427,7 @@ "method": "GET", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/store/6377697882393a47683cc76c/config", + "raw": "http://{{HOST}}:{{PORT}}/api/store/65818986ca5133d8de2bb4a1/config", "protocol": "http", "host": [ "{{HOST}}" @@ -2779,7 +2436,7 @@ "path": [ "api", "store", - "6377697882393a47683cc76c", + "65818986ca5133d8de2bb4a1", "config" ] } @@ -2792,7 +2449,7 @@ "method": "GET", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/store/6377697882393a47683cc76c/config/6377697882393a47683cc76e", + "raw": "http://{{HOST}}:{{PORT}}/api/store/65818986ca5133d8de2bb4a1/config/6581a14f1c6d01f32129dabc", "protocol": "http", "host": [ "{{HOST}}" @@ -2801,9 +2458,9 @@ "path": [ "api", "store", - "6377697882393a47683cc76c", + "65818986ca5133d8de2bb4a1", "config", - "6377697882393a47683cc76e" + "6581a14f1c6d01f32129dabc" ] } }, @@ -2824,7 +2481,7 @@ } }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/store/63a035ceb3add4c2c7b79d05/config/63a035ceb3add4c2c7b79d06", + "raw": "http://{{HOST}}:{{PORT}}/api/store/65818986ca5133d8de2bb4a1/config/6581a14f1c6d01f32129dabc", "protocol": "http", "host": [ "{{HOST}}" @@ -2833,9 +2490,9 @@ "path": [ "api", "store", - "63a035ceb3add4c2c7b79d05", + "65818986ca5133d8de2bb4a1", "config", - "63a035ceb3add4c2c7b79d06" + "6581a14f1c6d01f32129dabc" ] } }, @@ -2856,7 +2513,7 @@ } }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/store/6375352db0c7df8ecab9e7ad", + "raw": "http://{{HOST}}:{{PORT}}/api/store/65818986ca5133d8de2bb4a1", "protocol": "http", "host": [ "{{HOST}}" @@ -2865,19 +2522,19 @@ "path": [ "api", "store", - "6375352db0c7df8ecab9e7ad" + "65818986ca5133d8de2bb4a1" ] } }, "response": [] }, { - "name": "Delete config entry", + "name": "Delete config store", "request": { "method": "DELETE", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/store/63a035ceb3add4c2c7b79d05", + "raw": "http://{{HOST}}:{{PORT}}/api/store/65818986ca5133d8de2bb4a1", "protocol": "http", "host": [ "{{HOST}}" @@ -2886,7 +2543,7 @@ "path": [ "api", "store", - "63a035ceb3add4c2c7b79d05" + "65818986ca5133d8de2bb4a1" ] } }, @@ -2904,57 +2561,69 @@ "script": { "type": "text/javascript", "exec": [ - "console.log(\"compoents pre request script\")", - "", + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "let IGNORE = {", + " \"PUT\": [", + " \"/api/plugins/658188e93cde9987c3228806/files\"", + " ],", + " \"POST\": [", + " \"/api/plugins/658188e93cde9987c3228806/start\",", + " \"/api/endpoints/658189336fa19198939caa21/commands/6581fc8ac20cb522e02868ff\"", + " ]", + "};", "", - "/*", "", - " console.log(\"Name3\", name)", + "console.log(\"Check ignore object\", pm.request.method, pm.request.url.toString());", "", - " let HOST = pm.collectionVariables.get(\"HOST\");", - " let PORT = pm.collectionVariables.get(\"PORT\");", "", - " pm.sendRequest({", - " url: `http://${HOST}:${PORT}/api/${name}/`,", - " method: 'GET',", - " }, (err, res) => {", - " if(err){", + "if(Object.prototype.hasOwnProperty.call(IGNORE, pm.request.method)){", "", - " console.log(\"err\", err)", + " let skip = IGNORE[pm.request.method].some((url) => {", + " return pm.request.url.toString().includes(url);", + " });", "", - " consle.error(err);", - " done(err);", + " console.log(\"Ignore\", pm.request.url.toString(), skip);", "", - " }else {", + " if(skip){", + " return;", + " }", "", - " console.log(\"Callback\")", + "}", "", - " let data = res.json();", - " let key = Math.floor(Math.random()*data.length);", - " let item = data[key];", "", - " pm.variables.set(\"_id\", item._id);", + "pm.test(\"content-type = application/json\", () => {", + " pm.expect(pm.response.headers.get('Content-Type')).to.include('application/json');", + "});", "", - " done(null, item._id);", "", - " }", - " });", - "*/" - ] - } - }, - { - "listen": "test", - "script": { - "type": "text/javascript", - "exec": [ - "pm.test(\"application/content = json\", () => {", - " pm.response.to.be.json", + "pm.test(\"Status code 200 || 202\", () => {", + " pm.expect(pm.response.code).to.be.oneOf([", + " 200,", + " 202", + " ]);", "});", "", + "", "pm.test(\"Response has no error field\", () => {", + "", + " let length = pm.response.headers.get(\"content-length\");", + "", + " // ignore empty response/no body", + " if(!length || Number(length) === 0){", + " return;", + " }", + "", " let json = pm.response.json();", - " pm.expect(!json.error);", + " pm.expect(!json.error, true);", + "", "});" ] } @@ -2994,15 +2663,6 @@ } }, "response": [] - }, - { - "name": "New Request", - "request": { - "method": "GET", - "header": [], - "url": null - }, - "response": [] } ] }, From a5fd58b72cca6302079ae0d7d97227859bdc6c8a Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 20 Dec 2023 14:38:27 +0100 Subject: [PATCH 051/186] add http test, fix #370 --- tests/http-api/index.js | 84 +++++++++++++++++++++++++++++++++++++++++ tests/index.js | 1 + 2 files changed, 85 insertions(+) create mode 100644 tests/http-api/index.js diff --git a/tests/http-api/index.js b/tests/http-api/index.js new file mode 100644 index 0000000..1822d89 --- /dev/null +++ b/tests/http-api/index.js @@ -0,0 +1,84 @@ +const { describe, it } = require("mocha"); +const newman = require("newman"); +const { fork } = require("child_process"); +const path = require("path"); +const crypto = require("crypto"); +const assert = require("assert"); + +const collection = require("../../postman.json"); + + +describe("HTTP API", function () { + + this.timeout(10000); + + //let HTTP_PORT = crypto.randomInt(2048, 1024); + let child = null; + + it("- Should start OpenHaus", (done) => { + + child = fork(path.resolve(process.cwd(), "index.js"), { + silent: true, + env: Object.assign({}, process.env, { + UUID: crypto.randomUUID(), + DATABASE_NAME: "/test", + VAULT_MASTER_PASSWORD: crypto.randomBytes(24).toString("hex"), + USERS_JWT_SECRET: crypto.randomBytes(24).toString("hex") + }) + }); + + child.on("spawn", () => { + setTimeout(done, 1500); + }); + + child.on("error", (err) => { + done(err); + }); + + }); + + + // https://gist.github.com/davfive/eae043135ed98b9647ad631bbfc1ab38 + it("- Should not have any items in summary.run.failres array", (done) => { + + let emitter = newman.run({ + collection, + reporters: "json", + workingDir: __dirname + }); + + emitter.once("done", (err, summary) => { + if (err || summary.error) { + + // stop backend + child.kill(); + + done(err || summary.error); + + } else { + + // stop backend + child.kill(); + + summary.run.failures.forEach(({ source: { request }, error }) => { + console.error(`[${request.method}] ${request.url.toString()}`, error.message); + }); + + assert.equal(summary.run.failures.length, 0); + + // give some time to kill the backend + setTimeout(done, 1000); + //done(); + + } + }); + + }); + + + it("- Should stop the backend", () => { + assert(!child.connected); + }); + + +}); \ No newline at end of file diff --git a/tests/index.js b/tests/index.js index 616cee4..8e91993 100644 --- a/tests/index.js +++ b/tests/index.js @@ -67,6 +67,7 @@ describe("Database", () => { require("./helper/index.js"); require("./system/index.js"); require("./components/index.js"); + require("./http-api/index.js"); }); }); From a67f7d427c01c77fd66987df10a8d9b03204aa57 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 20 Dec 2023 15:04:42 +0100 Subject: [PATCH 052/186] fix endless running test --- tests/http-api/index.js | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/tests/http-api/index.js b/tests/http-api/index.js index 1822d89..5dd7dd9 100644 --- a/tests/http-api/index.js +++ b/tests/http-api/index.js @@ -48,27 +48,33 @@ describe("HTTP API", function () { }); emitter.once("done", (err, summary) => { - if (err || summary.error) { + try { + if (err || summary.error) { - // stop backend - child.kill(); + // stop backend + child.kill(); - done(err || summary.error); + done(err || summary.error); - } else { + } else { - // stop backend - child.kill(); + // stop backend + child.kill(); - summary.run.failures.forEach(({ source: { request }, error }) => { - console.error(`[${request.method}] ${request.url.toString()}`, error.message); - }); + summary.run.failures.forEach(({ source: { request }, error }) => { + console.error(`[${request.method}] ${request.url.toString()}`, error.message); + }); - assert.equal(summary.run.failures.length, 0); + assert.equal(summary.run.failures.length, 0); - // give some time to kill the backend - setTimeout(done, 1000); - //done(); + // give some time to kill the backend + setTimeout(done, 1000); + //done(); + + } + } catch (err) { + + done(err); } }); @@ -81,4 +87,10 @@ describe("HTTP API", function () { }); + // ensure to kill the backend + // so that github actions complete + this.afterAll(() => { + child.kill(); + }); + }); \ No newline at end of file From dd1f15ac92e4e7899621b5da6cde1f9f0747ac64 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 20 Dec 2023 15:12:13 +0100 Subject: [PATCH 053/186] test fix --- tests/http-api/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/http-api/index.js b/tests/http-api/index.js index 5dd7dd9..f1d3581 100644 --- a/tests/http-api/index.js +++ b/tests/http-api/index.js @@ -10,7 +10,7 @@ const collection = require("../../postman.json"); describe("HTTP API", function () { - this.timeout(10000); + this.timeout(30000); //let HTTP_PORT = crypto.randomInt(2048, 1024); let child = null; From 2a9b2c0dd9c77f2918db3793bec7584e5f0b28e9 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 20 Dec 2023 15:20:08 +0100 Subject: [PATCH 054/186] fix githu actions --- tests/http-api/index.js | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/tests/http-api/index.js b/tests/http-api/index.js index f1d3581..eedb994 100644 --- a/tests/http-api/index.js +++ b/tests/http-api/index.js @@ -51,39 +51,31 @@ describe("HTTP API", function () { try { if (err || summary.error) { - // stop backend - child.kill(); - done(err || summary.error); } else { - // stop backend - child.kill(); - summary.run.failures.forEach(({ source: { request }, error }) => { console.error(`[${request.method}] ${request.url.toString()}`, error.message); }); assert.equal(summary.run.failures.length, 0); - // give some time to kill the backend - setTimeout(done, 1000); - //done(); + done(); } } catch (err) { done(err); - } - }); + } finally { - }); + // stop backend + child.kill(); + } + }); - it("- Should stop the backend", () => { - assert(!child.connected); }); From 5d7296f6bc5622a9cb125a3a03172c690c2eeec3 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 20 Dec 2023 15:22:37 +0100 Subject: [PATCH 055/186] github actions test --- tests/http-api/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/http-api/index.js b/tests/http-api/index.js index eedb994..b8672d6 100644 --- a/tests/http-api/index.js +++ b/tests/http-api/index.js @@ -10,7 +10,7 @@ const collection = require("../../postman.json"); describe("HTTP API", function () { - this.timeout(30000); + this.timeout(120000); //let HTTP_PORT = crypto.randomInt(2048, 1024); let child = null; From 3f02b3f21eb258c15dbce57d3dbc44bfc56a3d44 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 20 Dec 2023 15:26:27 +0100 Subject: [PATCH 056/186] github actions test --- tests/http-api/index.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/http-api/index.js b/tests/http-api/index.js index b8672d6..d868961 100644 --- a/tests/http-api/index.js +++ b/tests/http-api/index.js @@ -48,6 +48,19 @@ describe("HTTP API", function () { }); emitter.once("done", (err, summary) => { + if (err || summary.error) { + + done(err || summary.error); + + } else { + + assert.equal(summary.run.failures.length, 0); + + done(); + + } + + /* try { if (err || summary.error) { @@ -55,9 +68,11 @@ describe("HTTP API", function () { } else { + /* summary.run.failures.forEach(({ source: { request }, error }) => { console.error(`[${request.method}] ${request.url.toString()}`, error.message); - }); + }) + * assert.equal(summary.run.failures.length, 0); @@ -74,6 +89,7 @@ describe("HTTP API", function () { child.kill(); } + */ }); }); From 847076914511e443cc5fe5c9da19df3a3726e2c6 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 20 Dec 2023 15:54:19 +0100 Subject: [PATCH 057/186] test github actions --- tests/http-api/index.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/http-api/index.js b/tests/http-api/index.js index d868961..8f07079 100644 --- a/tests/http-api/index.js +++ b/tests/http-api/index.js @@ -39,6 +39,7 @@ describe("HTTP API", function () { // https://gist.github.com/davfive/eae043135ed98b9647ad631bbfc1ab38 + // https://github.com/postmanlabs/newman/wiki/Newman-Run-Events it("- Should not have any items in summary.run.failres array", (done) => { let emitter = newman.run({ @@ -47,7 +48,15 @@ describe("HTTP API", function () { workingDir: __dirname }); + emitter.once("exception", (err, { error }) => { + console.error("Exception happend", err || error); + done(err || error); + }); + emitter.once("done", (err, summary) => { + + console.log("Done emitted!!!!!!!", err, summary.run.failures.length); + if (err || summary.error) { done(err || summary.error); From c5e7fdbecff9733297043f2e45b31bf645707dc2 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 20 Dec 2023 16:03:34 +0100 Subject: [PATCH 058/186] test github actions --- tests/http-api/index.js | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/tests/http-api/index.js b/tests/http-api/index.js index 8f07079..813176a 100644 --- a/tests/http-api/index.js +++ b/tests/http-api/index.js @@ -57,19 +57,6 @@ describe("HTTP API", function () { console.log("Done emitted!!!!!!!", err, summary.run.failures.length); - if (err || summary.error) { - - done(err || summary.error); - - } else { - - assert.equal(summary.run.failures.length, 0); - - done(); - - } - - /* try { if (err || summary.error) { @@ -77,11 +64,9 @@ describe("HTTP API", function () { } else { - /* summary.run.failures.forEach(({ source: { request }, error }) => { console.error(`[${request.method}] ${request.url.toString()}`, error.message); - }) - * + }); assert.equal(summary.run.failures.length, 0); @@ -92,13 +77,8 @@ describe("HTTP API", function () { done(err); - } finally { - - // stop backend - child.kill(); - } - */ + }); }); From 87049bbdab8cd40cf56a4fa7c0e1eb83a963a99e Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 20 Dec 2023 18:39:43 +0100 Subject: [PATCH 059/186] test github actions --- tests/http-api/index.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/http-api/index.js b/tests/http-api/index.js index 813176a..0f5dc29 100644 --- a/tests/http-api/index.js +++ b/tests/http-api/index.js @@ -10,7 +10,7 @@ const collection = require("../../postman.json"); describe("HTTP API", function () { - this.timeout(120000); + this.timeout(30000); //let HTTP_PORT = crypto.randomInt(2048, 1024); let child = null; @@ -42,10 +42,12 @@ describe("HTTP API", function () { // https://github.com/postmanlabs/newman/wiki/Newman-Run-Events it("- Should not have any items in summary.run.failres array", (done) => { + // https://www.npmjs.com/package/newman#newman-options let emitter = newman.run({ collection, reporters: "json", - workingDir: __dirname + workingDir: __dirname, + timeoutRequest: 3000 }); emitter.once("exception", (err, { error }) => { @@ -54,9 +56,6 @@ describe("HTTP API", function () { }); emitter.once("done", (err, summary) => { - - console.log("Done emitted!!!!!!!", err, summary.run.failures.length); - try { if (err || summary.error) { @@ -78,7 +77,6 @@ describe("HTTP API", function () { done(err); } - }); }); From e8cede4395f43c95c54f478cc56f5cf9f09eedfa Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 20 Dec 2023 20:29:45 +0100 Subject: [PATCH 060/186] logfile routes removed due to #346 --- postman.json | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/postman.json b/postman.json index f822234..e1a88f1 100644 --- a/postman.json +++ b/postman.json @@ -2630,42 +2630,6 @@ } ] }, - { - "name": "Logfiles", - "item": [ - { - "name": "Get logfile entrys", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/logs/?offset=0&limit=3", - "protocol": "http", - "host": [ - "{{HOST}}" - ], - "port": "{{PORT}}", - "path": [ - "api", - "logs", - "" - ], - "query": [ - { - "key": "offset", - "value": "0" - }, - { - "key": "limit", - "value": "3" - } - ] - } - }, - "response": [] - } - ] - }, { "name": "Authentication", "item": [ From d00f56c3b2d60d83546c6341284cfda01ec8c2c4 Mon Sep 17 00:00:00 2001 From: mStirner Date: Wed, 20 Dec 2023 22:37:28 +0100 Subject: [PATCH 061/186] fix #356 --- components/devices/class.device.js | 10 +++++++--- components/endpoints/class.endpoint.js | 10 +++++++--- components/mdns/class.mdns.js | 15 +++++++++------ components/mqtt/class.mqtt.js | 11 ++++++++--- components/plugins/class.plugin.js | 15 +++++++++------ components/rooms/class.room.js | 15 ++++++++++++--- components/scenes/class.scene.js | 11 ++++++++--- components/ssdp/class.ssdp.js | 15 +++++++++------ components/store/class.store.js | 16 +++++++++------- components/users/class.user.js | 11 ++++++++--- components/vault/class.vault.js | 15 +++++++++------ components/webhooks/class.webhook.js | 11 ++++++++--- system/component/class.item.js | 16 ++++++++++++++++ tests/components/test.workflow.js | 12 ++++++++++++ 14 files changed, 131 insertions(+), 52 deletions(-) create mode 100644 system/component/class.item.js diff --git a/components/devices/class.device.js b/components/devices/class.device.js index 6225fac..b8452bb 100644 --- a/components/devices/class.device.js +++ b/components/devices/class.device.js @@ -1,5 +1,6 @@ const InterfaceStream = require("./class.interfaceStream.js"); const Interface = require("./class.interface.js"); +const Item = require("../../system/component/class.item.js"); const mixins = require("../../helper/mixins.js"); @@ -20,12 +21,15 @@ const mixins = require("../../helper/mixins.js"); * @see interface components/devices/class.interface.js * @see interfaceStream components/devices/class.interfaceStream.js */ -module.exports = class Device { +module.exports = class Device extends Item { constructor(props) { + super(props); + + // removed for #356 // set properties from db - Object.assign(this, props); - this._id = String(props._id); + //Object.assign(this, props); + //this._id = String(props._id); // create for each interface a interface class instance // for each interface class, create a interface stream diff --git a/components/endpoints/class.endpoint.js b/components/endpoints/class.endpoint.js index 0240e6a..8d5712a 100644 --- a/components/endpoints/class.endpoint.js +++ b/components/endpoints/class.endpoint.js @@ -2,6 +2,7 @@ const Command = require("./class.command.js"); const State = require("./class.state.js"); //const Commands = require("./class.commands.js"); //const States = require("./!class.states.js"); +const Item = require("../../system/component/class.item.js"); const _expose = require("../../helper/expose.js"); @@ -27,11 +28,14 @@ const _expose = require("../../helper/expose.js"); * @see Devices components/devices/ * @see InterfaceStream components/devices/class.interfaceStream.js */ -module.exports = class Endpoint { +module.exports = class Endpoint extends Item { constructor(obj) { - Object.assign(this, obj); - this._id = String(obj._id); + super(obj); + + // removed for #356 + //Object.assign(this, obj); + //this._id = String(obj._id); //this.commands = new Commands(obj.commands); //this.states = new States(obj.states); diff --git a/components/mdns/class.mdns.js b/components/mdns/class.mdns.js index 19efe27..714dcd3 100644 --- a/components/mdns/class.mdns.js +++ b/components/mdns/class.mdns.js @@ -1,9 +1,14 @@ -class MDNS { +const Item = require("../../system/component/class.item.js"); + +module.exports = class MDNS extends Item { constructor(obj) { - Object.assign(this, obj); - this._id = String(obj._id); + super(obj); + + // removed for #356 + //Object.assign(this, obj); + //this._id = String(obj._id); Object.defineProperty(this, "_matches", { value: [], @@ -18,6 +23,4 @@ class MDNS { this._matches.push(cb); } -} - -module.exports = MDNS; \ No newline at end of file +}; \ No newline at end of file diff --git a/components/mqtt/class.mqtt.js b/components/mqtt/class.mqtt.js index ecafe25..efed9c2 100644 --- a/components/mqtt/class.mqtt.js +++ b/components/mqtt/class.mqtt.js @@ -1,3 +1,5 @@ +const Item = require("../../system/component/class.item.js"); + /** * @description * Represents a mqtt topic item @@ -10,12 +12,15 @@ * @property {String} topic MQTT topic e.g. `air-sensor/sensor/particulate_matter_25m_concentration/state` * @property {String} description Description for Admins/Topic */ -class MQTT { +class MQTT extends Item { constructor(obj) { - Object.assign(this, obj); - this._id = String(obj._id); + super(obj); + + // removed for #356 + //Object.assign(this, obj); + //this._id = String(obj._id); Object.defineProperty(this, "_subscriber", { value: [], diff --git a/components/plugins/class.plugin.js b/components/plugins/class.plugin.js index 5cccbcc..7c1f48e 100644 --- a/components/plugins/class.plugin.js +++ b/components/plugins/class.plugin.js @@ -4,6 +4,8 @@ const logger = require("../../system/logger/index.js"); const semver = require("semver"); const pkg = require("../../package.json"); +const Item = require("../../system/component/class.item.js"); + //const Bootstrap = require("./class.bootstrap.js"); /** @@ -21,12 +23,15 @@ const pkg = require("../../package.json"); * @property {Boolean} autostart Start the plugin after the backend has initzialized successful? * @property {Boolean} enabled Indicates if this thing can do anything */ -class Plugin { +module.exports = class Plugin extends Item { constructor(obj) { - Object.assign(this, obj); - this._id = String(obj._id); + super(obj); + + // removed for #356 + //Object.assign(this, obj); + //this._id = String(obj._id); let json = {}; @@ -178,6 +183,4 @@ class Plugin { } */ -} - -module.exports = Plugin; \ No newline at end of file +}; \ No newline at end of file diff --git a/components/rooms/class.room.js b/components/rooms/class.room.js index b2ee6fb..338d975 100644 --- a/components/rooms/class.room.js +++ b/components/rooms/class.room.js @@ -1,3 +1,5 @@ +const Item = require("../../system/component/class.item.js"); + /** * @description * Represents a room item @@ -11,9 +13,16 @@ * @property {Number} [floor=null] Floor on which the room is located * @property {String} [icon=null] fontawesome class string for the frontend */ -module.exports = class Room { +module.exports = class Room extends Item { + constructor(obj) { - Object.assign(this, obj); - this._id = String(obj._id); + + super(obj); + + // removed for #356 + //Object.assign(this, obj); + //this._id = String(obj._id); + } + }; \ No newline at end of file diff --git a/components/scenes/class.scene.js b/components/scenes/class.scene.js index 41f573c..c625ac0 100644 --- a/components/scenes/class.scene.js +++ b/components/scenes/class.scene.js @@ -3,13 +3,18 @@ const { setTimeout } = require("timers/promises"); const Makro = require("./class.makro.js"); const Trigger = require("./class.trigger.js"); +const Item = require("../../system/component/class.item.js"); -module.exports = class Scene { + +module.exports = class Scene extends Item { constructor(obj) { - Object.assign(this, obj); - this._id = String(obj._id); + super(obj); + + // removed for #356 + //Object.assign(this, obj); + //this._id = String(obj._id); this.makros = obj.makros.map((makro) => { return new Makro(makro); diff --git a/components/ssdp/class.ssdp.js b/components/ssdp/class.ssdp.js index 91971df..33e72e0 100644 --- a/components/ssdp/class.ssdp.js +++ b/components/ssdp/class.ssdp.js @@ -1,9 +1,14 @@ -class SSDP { +const Item = require("../../system/component/class.item.js"); + +module.exports = class SSDP extends Item { constructor(obj) { - Object.assign(this, obj); - this._id = String(obj._id); + super(obj); + + // removed for #356 + //Object.assign(this, obj); + //this._id = String(obj._id); Object.defineProperty(this, "_matches", { value: [], @@ -18,6 +23,4 @@ class SSDP { this._matches.push(cb); } -} - -module.exports = SSDP; \ No newline at end of file +}; \ No newline at end of file diff --git a/components/store/class.store.js b/components/store/class.store.js index abbdb01..4c28fdc 100644 --- a/components/store/class.store.js +++ b/components/store/class.store.js @@ -1,6 +1,7 @@ const { EventEmitter } = require("events"); const Value = require("./class.value.js"); +const Item = require("../../system/component/class.item.js"); /** * @description @@ -17,19 +18,22 @@ const Value = require("./class.value.js"); * * @see value components/store/class.value.js */ -class Store { +module.exports = class Store extends Item { #privates = new Map(); constructor(obj, scope) { + super(obj); + + // removed for #356 + //Object.assign(this, obj); + //this._id = String(obj._id); + // create event emitter for lean object let events = new EventEmitter(); this.#privates.set("events", events); - Object.assign(this, obj); - this._id = String(obj._id); - this.config = obj.config.map((data) => { return new Value(data, async () => { try { @@ -112,6 +116,4 @@ class Store { }, {}); } -} - -module.exports = Store; \ No newline at end of file +}; \ No newline at end of file diff --git a/components/users/class.user.js b/components/users/class.user.js index 8dcaa26..d70c038 100644 --- a/components/users/class.user.js +++ b/components/users/class.user.js @@ -2,6 +2,8 @@ const jwt = require("jsonwebtoken"); const _promisify = require("../../helper/promisify"); +const Item = require("../../system/component/class.item.js"); + /** * @description * Represents a user item @@ -18,12 +20,15 @@ const _promisify = require("../../helper/promisify"); * @property {Boolean} [enabled=false] Is user enabled/can login? * @property {Array} tokens Internal used to store JWTs (Active tokens/sessions) */ -module.exports = class User { +module.exports = class User extends Item { constructor(scope, obj) { - Object.assign(this, obj); - this._id = String(obj._id); + super(obj); + + // removed for #356 + //Object.assign(this, obj); + //this._id = String(obj._id); Object.defineProperty(this, "_scope", { value: scope, diff --git a/components/vault/class.vault.js b/components/vault/class.vault.js index aa33456..bd3e280 100644 --- a/components/vault/class.vault.js +++ b/components/vault/class.vault.js @@ -7,6 +7,8 @@ const _debounce = require("../../helper/debounce.js"); const Secret = require("./class.secret.js"); +const Item = require("../../system/component/class.item.js"); + /** * @description * Contains a collection of secrets @@ -22,12 +24,14 @@ const Secret = require("./class.secret.js"); * * @see secret components/vault/class.secret.js */ -class Vault { +module.exports = class Vault extends Item { #privates = new Map(); constructor(obj, scope) { + super(obj); + // create event emitter for lean object let events = new EventEmitter(); this.#privates.set("events", events); @@ -53,8 +57,9 @@ class Vault { } }, Number(process.env.DATABASE_UPDATE_DEBOUNCE_TIMER)); - Object.assign(this, obj); - this._id = String(obj._id); + // removed for #356 + //Object.assign(this, obj); + //this._id = String(obj._id); this.secrets = obj.secrets.map((secret) => { return new Secret(secret, () => { @@ -132,6 +137,4 @@ class Vault { }, {}); } -} - -module.exports = Vault; \ No newline at end of file +}; \ No newline at end of file diff --git a/components/webhooks/class.webhook.js b/components/webhooks/class.webhook.js index 331c156..6e9ffca 100644 --- a/components/webhooks/class.webhook.js +++ b/components/webhooks/class.webhook.js @@ -1,3 +1,5 @@ +const Item = require("../../system/component/class.item.js"); + /** * @description * Represents a webhook item @@ -9,12 +11,15 @@ * @property {String} _id MongoDB Object is as string * @property {String} name Webhook name */ -module.exports = class Webhook { +module.exports = class Webhook extends Item { constructor(obj) { - Object.assign(this, obj); - this._id = String(obj._id); + super(obj); + + // removed for #356 + //Object.assign(this, obj); + //this._id = String(obj._id); Object.defineProperty(this, "_handler", { value: [], diff --git a/system/component/class.item.js b/system/component/class.item.js new file mode 100644 index 0000000..efcba43 --- /dev/null +++ b/system/component/class.item.js @@ -0,0 +1,16 @@ +module.exports = class Item { + + constructor(obj) { + + Object.assign(this, obj); + + // override properties + this._id = String(obj._id); + + // create here class.label.js instance + // see issue https://github.com/OpenHausIO/backend/issues/352 + // this.labels = obj.labels.map(...); + + } + +}; \ No newline at end of file diff --git a/tests/components/test.workflow.js b/tests/components/test.workflow.js index 5a83433..5d5587a 100644 --- a/tests/components/test.workflow.js +++ b/tests/components/test.workflow.js @@ -4,6 +4,8 @@ const sinon = require("sinon"); const _iterate = require("../../helper/iterate.js"); +const Item = require("../../system/component/class.item.js"); + module.exports = (C_COMPONENT, method, desc, worker) => { if (!worker && desc instanceof Function) { @@ -51,6 +53,16 @@ module.exports = (C_COMPONENT, method, desc, worker) => { done(); }); + it("Component item should be instance of item class", (done) => { + assert.ok(C_COMPONENT.items[0] instanceof Item); + done(); + }); + + it("Component item _id property should be a string, not a ObjectId instance", (done) => { + assert.ok(typeof (C_COMPONENT.items[0]._id) === "string"); + done(); + }); + it(`Every array in item should have a _id property ${desc ? "(" + desc + ")" : ""}`, (done) => { try { From 542c1cde10e838a1c6b6397217046bc56309bc61 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 21 Dec 2023 12:11:00 +0100 Subject: [PATCH 062/186] `npm run dev` ignore plugin changes --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1832a9d..99ae8a5 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "test": "NODE_ENV=test ./node_modules/.bin/mocha ./tests/index.js", "test:helper": "NODE_ENV=test ./node_modules/.bin/mocha ./tests/helper/index.js", "test:newman": "newman run postman.json", - "dev": "./node_modules/.bin/nodemon -w . -w .env index.js", + "dev": "./node_modules/.bin/nodemon -i plugins -w . -w .env index.js", "dev:plugin": "./node_modules/.bin/nodemon -w plugins -w . -w .env index.js", "lint": "./node_modules/.bin/eslint .", "lint:fix": "./node_modules/.bin/eslint --fix .", @@ -57,4 +57,4 @@ "nodemon": "^3.0.1", "sinon": "^14.0.2" } -} +} \ No newline at end of file From aed531180beda634aab423cafa98c456ae49d394 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 21 Dec 2023 12:15:33 +0100 Subject: [PATCH 063/186] removed report output --- tests/http-api/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/http-api/index.js b/tests/http-api/index.js index 0f5dc29..378babc 100644 --- a/tests/http-api/index.js +++ b/tests/http-api/index.js @@ -45,8 +45,7 @@ describe("HTTP API", function () { // https://www.npmjs.com/package/newman#newman-options let emitter = newman.run({ collection, - reporters: "json", - workingDir: __dirname, + //reporters: "json", timeoutRequest: 3000 }); From 4c283b5c0c26344b13b60ed93f798330022b937e Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 21 Dec 2023 17:30:38 +0100 Subject: [PATCH 064/186] Test for label array added --- tests/components/endpoints.js | 12 ++++++++++-- tests/components/rooms.js | 6 +++++- tests/components/test.workflow.js | 19 ++++++++++++++++++- tests/components/users.js | 11 +++++++++-- 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/tests/components/endpoints.js b/tests/components/endpoints.js index 9f02635..1f5f595 100644 --- a/tests/components/endpoints.js +++ b/tests/components/endpoints.js @@ -16,7 +16,11 @@ try { C_COMPONENT.add({ _id, name: "Endpoint #1", - device: _device + device: _device, + labels: [ + "key1=value1", + "key2=value2" + ] }, (err, item) => { try { @@ -59,7 +63,11 @@ try { workflow(C_COMPONENT, "update", (done) => { C_COMPONENT.update(_id, { - name: "Endpoint #2 - updated" + name: "Endpoint #2 - updated", + labels: [ + "overriden=true", + "key3=value3" + ] }, (err, item) => { try { diff --git a/tests/components/rooms.js b/tests/components/rooms.js index 2fe23b3..f137a6a 100644 --- a/tests/components/rooms.js +++ b/tests/components/rooms.js @@ -15,7 +15,11 @@ try { C_COMPONENT.add({ _id, name: "Room #1", - floor: 1 + floor: 1, + labels: [ + "foo=bar", + "baz=true" + ] }, (err, item) => { try { diff --git a/tests/components/test.workflow.js b/tests/components/test.workflow.js index 5d5587a..af1594c 100644 --- a/tests/components/test.workflow.js +++ b/tests/components/test.workflow.js @@ -5,6 +5,7 @@ const sinon = require("sinon"); const _iterate = require("../../helper/iterate.js"); const Item = require("../../system/component/class.item.js"); +const Label = require("../../system/component/class.label.js"); module.exports = (C_COMPONENT, method, desc, worker) => { @@ -58,6 +59,18 @@ module.exports = (C_COMPONENT, method, desc, worker) => { done(); }); + it("Item .labels array should contain only class.label.js instances", () => { + + let valid = C_COMPONENT.items.map(({ labels }) => { + return labels; + }).flat().every((label) => { + return label instanceof Label; + }); + + assert.ok(valid); + + }); + it("Component item _id property should be a string, not a ObjectId instance", (done) => { assert.ok(typeof (C_COMPONENT.items[0]._id) === "string"); done(); @@ -71,11 +84,15 @@ module.exports = (C_COMPONENT, method, desc, worker) => { if (type === "array") { let result = value.every((entry) => { - if (entry instanceof Object) { + + // check if only "plain" objects have _id property + // otherwise this check fails on the .labels array items + if (entry instanceof Object && Object.getPrototypeOf(entry) === null) { return Object.hasOwnProperty.call(entry, "_id"); } else { return true; } + }); assert.ok(result === true); diff --git a/tests/components/users.js b/tests/components/users.js index 40c946e..6d0a9e8 100644 --- a/tests/components/users.js +++ b/tests/components/users.js @@ -59,7 +59,10 @@ try { workflow(C_COMPONENT, "update", (done) => { C_COMPONENT.update(_id, { - enabled: true + enabled: true, + labels: [ + "expires=29991231" + ] }, (err, item) => { try { @@ -83,7 +86,11 @@ try { // update call 1 C_COMPONENT.update(_id, { - password: "12345678" + password: "12345678", + labels: [ + "expires=29991231", + "key=value" + ] }), // update call 2 From 7863bb21ebf485f56c0a97bb28be70f5b97fcd31 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 21 Dec 2023 21:10:16 +0100 Subject: [PATCH 065/186] unit test added --- tests/system/component/index.js | 2 + tests/system/component/test.label.js | 39 ++++++++++++++++ tests/system/component/test.labels.js | 66 +++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 tests/system/component/test.label.js create mode 100644 tests/system/component/test.labels.js diff --git a/tests/system/component/index.js b/tests/system/component/index.js index a717d51..5990e00 100644 --- a/tests/system/component/index.js +++ b/tests/system/component/index.js @@ -2,6 +2,8 @@ const { describe } = require("mocha"); describe("system/component", function () { + require("./test.label.js"); + require("./test.labels.js"); require("./test.base.js"); require("./test.common.js"); require("./test.component.js"); diff --git a/tests/system/component/test.label.js b/tests/system/component/test.label.js new file mode 100644 index 0000000..363b4fb --- /dev/null +++ b/tests/system/component/test.label.js @@ -0,0 +1,39 @@ +const { describe, it } = require("mocha"); +const assert = require("assert"); + +const Label = require("../../../system/component/class.label.js"); + +describe("label", function () { + + let instance = new Label("hello=world"); + + it("should have a key property", () => { + assert(instance.key); + }); + + it("should have a value property", () => { + assert(instance.key); + }); + + it("should have a label property", () => { + assert(instance.label); + }); + + it(".key = hello", () => { + assert.equal(instance.key, "hello"); + }); + + it(".value = world", () => { + assert.equal(instance.value, "world"); + }); + + ["toJSON", "toString"].forEach((fnc) => { + + it(`should have method "${fnc}"`, () => { + assert(instance[fnc] instanceof Function); + }); + + }); + + +}); \ No newline at end of file diff --git a/tests/system/component/test.labels.js b/tests/system/component/test.labels.js new file mode 100644 index 0000000..b6be5ca --- /dev/null +++ b/tests/system/component/test.labels.js @@ -0,0 +1,66 @@ +const { describe, it } = require("mocha"); +const assert = require("assert"); + +const Labels = require("../../../system/component/class.labels.js"); +const Label = require("../../../system/component/class.label.js"); + +describe("labels", function () { + + let labels = [ + "foo=bar", + "baz=true", + "gen=1", + 'json={"key": "value"}', + "gen=3" + ].map((txt) => { + return new Label(txt); + }); + + let instance = new Labels(...labels); + + it("should be a instance of Array", () => { + assert(instance instanceof Array); + }); + + it("should have 4 items", () => { + assert.equal(instance.length, 5); + }); + + it("every item should be a instance of class.label.js", () => { + + let valid = instance.every((label) => { + return label instanceof Label; + }); + + assert(valid); + + }); + + [ + "key", "value", "has", + "filter", "toJSON" + ].forEach((fnc) => { + + it(`should have method "${fnc}"`, () => { + assert(instance[fnc] instanceof Function); + }); + + }); + + it('labels.key("bar") should return "foo"', () => { + assert.equal(instance.key("bar"), "foo"); + }); + + it('labels.value("baz") should return "foo"', () => { + assert.equal(instance.value("baz"), "true"); + }); + + it('labels.has("gen") should return true', () => { + assert.equal(instance.has("gen"), true); + }); + + it('labels.filter("gen=*") should return 2 items', () => { + assert.equal(instance.filter("gen=*").length, 2); + }); + +}); \ No newline at end of file From ba2df9159a761c77858331f80f29fd5cbc81ceaa Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 22 Dec 2023 11:04:21 +0100 Subject: [PATCH 066/186] refactor label array, fix #352 --- system/component/class.component.js | 19 ++++++++++- system/component/class.item.js | 38 +++++++++++++++++++++ system/component/class.label.js | 52 +++++++++++++++++++++++++++++ system/component/class.labels.js | 51 ++++++++++++++++++++++++++++ 4 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 system/component/class.label.js create mode 100644 system/component/class.labels.js diff --git a/system/component/class.component.js b/system/component/class.component.js index f6aa86f..3a393fa 100644 --- a/system/component/class.component.js +++ b/system/component/class.component.js @@ -5,6 +5,7 @@ const _extend = require("../../helper/extend"); const _merge = require("../../helper/merge"); const COMMON = require("./class.common.js"); +const Label = require("./class.label.js"); const PENDING_CHANGE_EVENTS = new Set(); @@ -98,7 +99,23 @@ module.exports = class COMPONENT extends COMMON { let baseSchema = Joi.object({ //labels: Joi.array().items(Joi.string().regex(/^[a-zA-Z0-9]+=[a-zA-Z0-9]+$/)).default([]) //labels: Joi.array().items(Joi.string().regex(/^[a-z0-9\.]+=[a-z0-9]+$/)).default([]), - labels: Joi.array().items(Joi.string().regex(/^.+?=.+|.+=.+$/i)).default([]), + //labels: Joi.array().items(Joi.string().regex(/^.+?=.+|.+=.+$/i)).default([]), + labels: Joi.array().items(Joi.alternatives().try( + Joi.string().regex(/^.+?=.+|.+=.+$/i), + Joi.object().custom((value, helpers) => { + if (value instanceof Label) { + + // convert to string + // otherwise the serialized object is saved into the database + return value.toString(); + + } else { + + return helpers.error("any.custom"); + + } + }, "Instance of class.label.js") + )).default([]), timestamps: Joi.object({ ...schema?.timestamps, created: Joi.number().allow(null).default(null), diff --git a/system/component/class.item.js b/system/component/class.item.js index efcba43..6fd8bee 100644 --- a/system/component/class.item.js +++ b/system/component/class.item.js @@ -1,3 +1,6 @@ +const Labels = require("./class.labels.js"); +const Label = require("./class.label.js"); + module.exports = class Item { constructor(obj) { @@ -11,6 +14,41 @@ module.exports = class Item { // see issue https://github.com/OpenHausIO/backend/issues/352 // this.labels = obj.labels.map(...); + obj.labels?.forEach((txt, i, arr) => { + if (!(txt instanceof Label)) { + arr[i] = new Label(txt); + } + }); + + let labels = new Labels(...obj.labels); + + Object.defineProperty(this, "labels", { + get() { + + //console.log("get called"); + return labels; + + }, + set(value) { + + // clear array + // needed when new array has fewer items than old one + // otherwise it contains old items & has wrong size + labels.splice(0, labels.length); + + value.forEach((txt, i) => { + if (!(txt instanceof Label)) { + labels[i] = new Label(txt); + } else { + labels[i] = txt; + } + }); + + }, + enumerable: true, + configurable: false + }); + } }; \ No newline at end of file diff --git a/system/component/class.label.js b/system/component/class.label.js new file mode 100644 index 0000000..cedc28e --- /dev/null +++ b/system/component/class.label.js @@ -0,0 +1,52 @@ +module.exports = class Label { + + constructor(label) { + + let [key, value] = label.split("="); + + Object.defineProperty(this, "key", { + set(val) { + key = val; + label = `${key}=${value}`; + }, + get() { + return key; + }, + enumerable: true + }); + + Object.defineProperty(this, "value", { + set(val) { + value = val; + label = `${key}=${value}`; + }, + get() { + return value; + }, + enumerable: true + }); + + Object.defineProperty(this, "label", { + set(val) { + let { k, v } = label.split("="); + label = val; + key = k; + value = v; + }, + get() { + return label; + }, + enumerable: true + }); + + } + + toJSON() { + return `${this.key}=${this.value}`; + } + + toString() { + return `${this.key}=${this.value}`; + } + +}; \ No newline at end of file diff --git a/system/component/class.labels.js b/system/component/class.labels.js new file mode 100644 index 0000000..51b5f05 --- /dev/null +++ b/system/component/class.labels.js @@ -0,0 +1,51 @@ +module.exports = class Labels extends Array { + + constructor(...args) { + super(...args); + } + + value(key) { + return this.find((label) => { + return label.key === key; + })?.value; + } + + key(value) { + return this.find((label) => { + return label.value === value; + })?.key; + } + + has(key) { + return !!this.find((label) => { + return label.key === key; + }); + } + + filter(query) { + + let [k, v] = query.split("="); + + return Array.prototype.filter.call(this, (label) => { + + if (k !== "*") { + return label.key === k; + } + + if (v !== "*") { + return label.value === v; + } + + return label.key === k && label.value === v; + + }); + + } + + toJSON() { + return this.map(({ key, value }) => { + return `${key}=${value}`; + }); + } + +}; \ No newline at end of file From fdced8039e15ac3f67e69f87dddbfdacffeb68e8 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 22 Dec 2023 11:08:56 +0100 Subject: [PATCH 067/186] fix #378 --- system/component/class.component.js | 7 +++++-- system/component/class.item.js | 31 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/system/component/class.component.js b/system/component/class.component.js index 3a393fa..e0bc134 100644 --- a/system/component/class.component.js +++ b/system/component/class.component.js @@ -1,11 +1,11 @@ const mongodb = require("mongodb"); -const Joi = require("joi"); +//const Joi = require("joi"); const _extend = require("../../helper/extend"); const _merge = require("../../helper/merge"); const COMMON = require("./class.common.js"); -const Label = require("./class.label.js"); +const Item = require("./class.item.js"); const PENDING_CHANGE_EVENTS = new Set(); @@ -95,7 +95,9 @@ module.exports = class COMPONENT extends COMMON { }); this.collection = mongodb.client.collection(name); + this.schema = Item.schema().concat(schema); + /* let baseSchema = Joi.object({ //labels: Joi.array().items(Joi.string().regex(/^[a-zA-Z0-9]+=[a-zA-Z0-9]+$/)).default([]) //labels: Joi.array().items(Joi.string().regex(/^[a-z0-9\.]+=[a-z0-9]+$/)).default([]), @@ -125,6 +127,7 @@ module.exports = class COMPONENT extends COMMON { // concat base schema with component specific this.schema = baseSchema.concat(schema); + */ if (process.env.DATABASE_WATCH_CHANGES === "true") { try { diff --git a/system/component/class.item.js b/system/component/class.item.js index 6fd8bee..3367abe 100644 --- a/system/component/class.item.js +++ b/system/component/class.item.js @@ -1,3 +1,5 @@ +const Joi = require("joi"); + const Labels = require("./class.labels.js"); const Label = require("./class.label.js"); @@ -51,4 +53,33 @@ module.exports = class Item { } + static schema() { + return Joi.object({ + labels: Joi.array().items(Joi.alternatives().try( + Joi.string().regex(/^.+?=.+|.+=.+$/i), + Joi.object().custom((value, helpers) => { + if (value instanceof Label) { + + // convert to string + // otherwise the serialized object is saved into the database + return value.toString(); + + } else { + + return helpers.error("any.custom"); + + } + }, "Instance of class.label.js") + )).default([]), + timestamps: Joi.object({ + created: Joi.number().allow(null).default(null), + updated: Joi.number().allow(null).default(null) + }) + }); + } + + static validate(data) { + return Item.schema().validate(data); + } + }; \ No newline at end of file From b6e6766f058475cfee11f0ca25c0c64d066c6b32 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 22 Dec 2023 11:09:42 +0100 Subject: [PATCH 068/186] labels added --- postman.json | 48 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/postman.json b/postman.json index e1a88f1..a619ad3 100644 --- a/postman.json +++ b/postman.json @@ -40,7 +40,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"_id\": \"65818753e275da05046aaa78\",\n \"name\": \"Livingroom\" \n}", + "raw": "{\n \"_id\": \"65818753e275da05046aaa78\",\n \"name\": \"Livingroom\",\n \"labels\": [\n \"foo=bar\",\n \"baz=true\"\n ]\n}", "options": { "raw": { "language": "json" @@ -854,7 +854,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"_id\": \"65818856464bebcf19ebec4c\",\n \"topic\": \"air-sensor/sensor/particulate_matter_25m_concentration\"\n}", + "raw": "{\n \"_id\": \"65818856464bebcf19ebec4c\",\n \"topic\": \"air-sensor/sensor/particulate_matter_25m_concentration\",\n \"labels\": [\n \"manufacturer=custom\",\n \"esp8266=true\"\n ]\n}", "options": { "raw": { "language": "json" @@ -982,7 +982,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"description\": \"Ikea VINDRIKTNING MQTT modd\"\n}", + "raw": "{\n \"description\": \"Ikea VINDRIKTNING MQTT mod\",\n \"labels\": [\n \"manufacturer=Ikea\",\n \"model=VINDRIKTNING\",\n \"esp8266=true\"\n ]\n}", "options": { "raw": { "language": "json" @@ -1342,7 +1342,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"_id\": \"658188a7aadfcc026a0e0131\",\n \"name\": \"Hans Hubert #3\",\n \"email\": \"hans.hubert3@example.com\",\n \"password\": \"Pa$$w0rd\"\n}", + "raw": "{\n \"_id\": \"658188a7aadfcc026a0e0131\",\n \"name\": \"Hans Hubert #3\",\n \"email\": \"hans.hubert3@example.com\",\n \"password\": \"Pa$$w0rd\",\n \"labels\": [\n \"expires=29991231\"\n ]\n}", "options": { "raw": { "language": "json" @@ -1571,7 +1571,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"_id\": \"658188e93cde9987c3228806\",\n \"name\": \"Plugin Boilerplate Demo\",\n \"enabled\": true,\n \"version\": 1,\n \"intents\": [\n \"devices\",\n \"endpoints\",\n \"plugins\",\n \"rooms\",\n \"ssdp\",\n \"store\",\n \"users\",\n \"vault\"\n ]\n}", + "raw": "{\n \"_id\": \"658188e93cde9987c3228806\",\n \"name\": \"Plugin Boilerplate Demo\",\n \"uuid\": \"6951dee2-8541-4a69-bd3e-629fdadf093a\",\n \"enabled\": true,\n \"version\": 1,\n \"intents\": [\n \"devices\",\n \"endpoints\",\n \"plugins\",\n \"rooms\",\n \"ssdp\",\n \"store\",\n \"users\",\n \"vault\"\n ]\n}", "options": { "raw": { "language": "json" @@ -1642,7 +1642,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"name\": \"New updated\",\n \"enabled\": true,\n \"autostart\": false\n}", + "raw": "{\n \"name\": \"New updated\",\n \"enabled\": true,\n \"autostart\": false,\n \"labels\": [\n \"worker_thread=false\",\n \"my_custom_label={\\\"json\\\":true, \\\"number\\\":0815420}\"\n ]\n}", "options": { "raw": { "language": "json" @@ -1667,6 +1667,26 @@ }, { "name": "Upload plugin *.tgz content", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], "request": { "method": "PUT", "header": [], @@ -1776,7 +1796,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"_id\": \"65818918d32dad8dab53e433\",\n \"name\": \"SmartMeter\",\n \"interfaces\": [{\n \"_id\": \"6581c55abc21a0a3122b9998\",\n \"type\": \"ETHERNET\",\n \"description\": \"WebSocket API\",\n \"settings\": {\n \"host\": \"192.168.2.155\",\n \"port\": 8080\n },\n \"adapter\": [\"raw\"]\n }],\n \"room\": \"62a4bc8bd9256b5e8d6988a0\",\n \"icon\": \"fa-solid fa-gauge-high\"\n}", + "raw": "{\n \"_id\": \"65818918d32dad8dab53e433\",\n \"name\": \"SmartMeter\",\n \"interfaces\": [{\n \"_id\": \"6581c55abc21a0a3122b9998\",\n \"type\": \"ETHERNET\",\n \"description\": \"WebSocket API\",\n \"settings\": {\n \"host\": \"192.168.2.155\",\n \"port\": 8080\n },\n \"adapter\": [\"raw\"]\n }],\n \"room\": \"62a4bc8bd9256b5e8d6988a0\",\n \"icon\": \"fa-solid fa-gauge-high\",\n \"labels\": [\n \"test=true\",\n \"protected=false\", \n \"foo=bar\"\n ]\n}", "options": { "raw": { "language": "json" @@ -1846,7 +1866,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"enabled\": true,\n \"name\": \"SaMsUnG FrIdGe\"\n}", + "raw": "{\n \"enabled\": true,\n \"name\": \"SaMsUnG FrIdGe\",\n \"labels\": [\n \"test=true\",\n \"protected=true\", \n \"foo=bar\"\n ]\n}", "options": { "raw": { "language": "json" @@ -2505,7 +2525,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"item\": \"6375343d0b555ccd42460a2e\"\n}", + "raw": "{\n \"item\": \"6375343d0b555ccd42460a2e\",\n \"labels\": [\n \"device=65818918d32dad8dab53e433\",\n \"endpoint=658189336fa19198939caa21\"\n ]\n}", "options": { "raw": { "language": "json" @@ -2599,11 +2619,6 @@ "}", "", "", - "pm.test(\"content-type = application/json\", () => {", - " pm.expect(pm.response.headers.get('Content-Type')).to.include('application/json');", - "});", - "", - "", "pm.test(\"Status code 200 || 202\", () => {", " pm.expect(pm.response.code).to.be.oneOf([", " 200,", @@ -2612,6 +2627,11 @@ "});", "", "", + "pm.test(\"content-type = application/json\", () => {", + " pm.expect(pm.response.headers.get('Content-Type')).to.include('application/json');", + "});", + "", + "", "pm.test(\"Response has no error field\", () => {", "", " let length = pm.response.headers.get(\"content-length\");", From a500662a27ce3b652d50f9324859fad1c908723c Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 22 Dec 2023 11:42:36 +0100 Subject: [PATCH 069/186] 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 070/186] 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 071/186] 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 072/186] 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 073/186] 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 074/186] 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 }); } From 5490860441acb0b79221bd774b96a1d893693404 Mon Sep 17 00:00:00 2001 From: mStirner Date: Fri, 29 Dec 2023 20:24:28 +0100 Subject: [PATCH 075/186] added `includes` method --- system/component/class.labels.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/system/component/class.labels.js b/system/component/class.labels.js index 51b5f05..697d5e5 100644 --- a/system/component/class.labels.js +++ b/system/component/class.labels.js @@ -48,4 +48,8 @@ module.exports = class Labels extends Array { }); } + includes(str) { + return Array.prototype.includes.call(this.toJSON(), str); + } + }; \ No newline at end of file From 5f4ebb4b2d52af8ab7ab1b3f95fa3eadb3646823 Mon Sep 17 00:00:00 2001 From: mStirner Date: Fri, 29 Dec 2023 20:24:42 +0100 Subject: [PATCH 076/186] fix #306 --- system/component/class.component.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/system/component/class.component.js b/system/component/class.component.js index 575bd31..2ea63bc 100644 --- a/system/component/class.component.js +++ b/system/component/class.component.js @@ -635,6 +635,12 @@ module.exports = class COMPONENT extends COMMON { let loop = (target, filter) => { return Object.keys(filter).every((key) => { + if (key === "labels" && Array.isArray(filter[key])) { + return filter[key].every((label) => { + return item.labels.includes(label); + }); + } + if (target[key] instanceof Object) { return loop(target[key], filter[key]); } else { From 5dfbb3f9233f6b2deefc3638e6243a3f11baad06 Mon Sep 17 00:00:00 2001 From: mStirner Date: Fri, 29 Dec 2023 21:53:27 +0100 Subject: [PATCH 077/186] fix #182 --- helper/map.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 helper/map.js diff --git a/helper/map.js b/helper/map.js new file mode 100644 index 0000000..7b6324e --- /dev/null +++ b/helper/map.js @@ -0,0 +1,28 @@ +/** + * @function map + * Maps a range to another range + * + * @param {Number} value + * @param {Number} low1 + * @param {Number} high1 + * @param {Number} low2 + * @param {Number} high2 + * + * @example + * ```js + * // convert hex to mb + * console.log(map(255, 0, 255, 0, 1024)); // 1024 + * ``` + * + * @example + * ```js + * console.log(map(128, 0, 255, 0, 1024)); // 512 + * ``` + * + * @returns {Number} Convert input number + */ +function map(value, low1, high1, low2, high2) { + return low2 + (high2 - low2) * (value - low1) / (high1 - low1); +} + +module.exports = map; \ No newline at end of file From c810790987f4ceba799b0b622c519a9e1de46e70 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sat, 30 Dec 2023 17:19:15 +0100 Subject: [PATCH 078/186] fix #388 --- system/component/class.item.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/component/class.item.js b/system/component/class.item.js index 3367abe..65b9258 100644 --- a/system/component/class.item.js +++ b/system/component/class.item.js @@ -22,7 +22,7 @@ module.exports = class Item { } }); - let labels = new Labels(...obj.labels); + let labels = new Labels(...obj.labels || []); Object.defineProperty(this, "labels", { get() { From 28108d52f357da0ebbf566c2b325750be8e8dae5 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sat, 30 Dec 2023 17:20:06 +0100 Subject: [PATCH 079/186] fix #389 --- components/endpoints/class.command.js | 7 ++++++- components/scenes/makro-types.js | 9 ++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/components/endpoints/class.command.js b/components/endpoints/class.command.js index 5aca593..f39f4e4 100644 --- a/components/endpoints/class.command.js +++ b/components/endpoints/class.command.js @@ -188,13 +188,18 @@ module.exports = class Command { * @param {Array} [params] Parameter array * @param {Function} [cb] Callback */ - trigger(params, cb = () => { }) { + trigger(params, cb) { if (!cb && params instanceof Function) { cb = params; params = []; } + if (!params && !cb) { + params = []; + cb = () => { }; + } + let worker = this.#privates.get("handler"); let iface = interfaces.get(this.interface); diff --git a/components/scenes/makro-types.js b/components/scenes/makro-types.js index 1175eb9..6db6c82 100644 --- a/components/scenes/makro-types.js +++ b/components/scenes/makro-types.js @@ -27,7 +27,14 @@ module.exports = { "component": "endpoints", "item": endpoint, "method": "trigger", - "args": [command] + "args": [command, () => { + + //console.log("Command executed adasdasdfasdfasdfasfdadsfasdf", err || success) + // how should this be catched? + // reject the makro execution if one command fails? + // or ignore it simple, and continue? + + }] }); resolve(_id); From 6a27f2ddf00f818a78ca274cb9a8aedb318fb743 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 2 Jan 2024 11:11:37 +0100 Subject: [PATCH 080/186] fix #392 --- components/scenes/class.scene.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/scenes/class.scene.js b/components/scenes/class.scene.js index 700f063..626a66c 100644 --- a/components/scenes/class.scene.js +++ b/components/scenes/class.scene.js @@ -80,7 +80,8 @@ module.exports = class Scene extends Item { name: Joi.string().required(), makros: Joi.array().items(Makro.schema()).default([]), triggers: Joi.array().items(Trigger.schema()).default([]), - visible: Joi.boolean().default(true) + visible: Joi.boolean().default(true), + icon: Joi.string().allow(null).default(null) }); } From fb56fec531b45fa97e380b12e7577f9abcde11ac Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 3 Jan 2024 12:46:24 +0100 Subject: [PATCH 081/186] fix #394 --- components/endpoints/class.command.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/endpoints/class.command.js b/components/endpoints/class.command.js index f39f4e4..77bfe26 100644 --- a/components/endpoints/class.command.js +++ b/components/endpoints/class.command.js @@ -273,7 +273,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(Param.schema()) + params: Joi.array().items(Param.schema()).default([]) }); } From 15590969c3f2aa9a6f2651be08f0b3193a494af7 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 3 Jan 2024 12:46:54 +0100 Subject: [PATCH 082/186] fix #392 --- components/scenes/class.scene.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/scenes/class.scene.js b/components/scenes/class.scene.js index 700f063..626a66c 100644 --- a/components/scenes/class.scene.js +++ b/components/scenes/class.scene.js @@ -80,7 +80,8 @@ module.exports = class Scene extends Item { name: Joi.string().required(), makros: Joi.array().items(Makro.schema()).default([]), triggers: Joi.array().items(Trigger.schema()).default([]), - visible: Joi.boolean().default(true) + visible: Joi.boolean().default(true), + icon: Joi.string().allow(null).default(null) }); } From e6c838c09add43eb40833c0575c3d72372d41634 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 3 Jan 2024 14:56:18 +0100 Subject: [PATCH 083/186] fix #395 --- components/store/class.store.js | 8 +++++--- components/store/class.value.js | 1 + components/store/index.js | 4 ++++ postman.json | 4 ++-- tests/components/store.js | 16 ++++++++-------- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/components/store/class.store.js b/components/store/class.store.js index b47b934..25848cf 100644 --- a/components/store/class.store.js +++ b/components/store/class.store.js @@ -67,11 +67,13 @@ module.exports = class Store extends Item { _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { return String(new mongodb.ObjectId()); }), + name: Joi.string().required(), + description: Joi.string().allow(null).default(null), config: Joi.array().min(1).items(Value.schema()).required(), - item: Joi.string().allow(null).default(null), - namespace: Joi.string().default(() => { + //item: Joi.string().allow(null).default(null), + uuid: Joi.string().default(() => { return uuid.v4(); - }), + }) }); } diff --git a/components/store/class.value.js b/components/store/class.value.js index 9a20df1..3daa0ff 100644 --- a/components/store/class.value.js +++ b/components/store/class.value.js @@ -60,6 +60,7 @@ class Value { _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => { return String(new mongodb.ObjectId()); }), + name: Joi.string().required(), key: Joi.string().required(), value: Joi.when("type", { is: "number", diff --git a/components/store/index.js b/components/store/index.js index 012c478..d49fb60 100644 --- a/components/store/index.js +++ b/components/store/index.js @@ -39,6 +39,10 @@ class C_STORE extends COMPONENT { next(null, new Store(data, this)); }); + this.collection.createIndex("uuid", { + unique: true + }); + } } diff --git a/postman.json b/postman.json index a619ad3..c5a51c6 100644 --- a/postman.json +++ b/postman.json @@ -2378,7 +2378,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"_id\": \"65818986ca5133d8de2bb4a1\",\n \"config\": [{\n \"_id\": \"6581a14f1c6d01f32129dabc\",\n \"key\": \"pairing\",\n \"type\": \"boolean\",\n \"value\": false,\n \"description\": \"Is the Gateway ready for pairing?\"\n }, {\n \"_id\": \"6581a1520bcb15659d48b207\",\n \"key\": \"interval\",\n \"type\": \"number\",\n \"value\": 3000,\n \"description\": \"Sync intervall for Endpoints\"\n }]\n}", + "raw": "{\n \"name\": \"Store item #1\",\n \"description\": \"Configuration settings for pluginx xyz\",\n \"_id\": \"65818986ca5133d8de2bb4a1\",\n \"config\": [{\n \"_id\": \"6581a14f1c6d01f32129dabc\",\n \"name\": \"Gateway Pairing\",\n \"key\": \"pairing\",\n \"type\": \"boolean\",\n \"value\": false,\n \"description\": \"Is the Gateway ready for pairing?\"\n }, {\n \"_id\": \"6581a1520bcb15659d48b207\",\n \"name\": \"Polling Interval\",\n \"key\": \"interval\",\n \"type\": \"number\",\n \"value\": 3000,\n \"description\": \"Sync intervall for Endpoints\"\n }]\n}", "options": { "raw": { "language": "json" @@ -2525,7 +2525,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"item\": \"6375343d0b555ccd42460a2e\",\n \"labels\": [\n \"device=65818918d32dad8dab53e433\",\n \"endpoint=658189336fa19198939caa21\"\n ]\n}", + "raw": "{\n \"labels\": [\n \"device=65818918d32dad8dab53e433\",\n \"endpoint=658189336fa19198939caa21\"\n ]\n}", "options": { "raw": { "language": "json" diff --git a/tests/components/store.js b/tests/components/store.js index 1677cb3..3e9e594 100644 --- a/tests/components/store.js +++ b/tests/components/store.js @@ -10,17 +10,20 @@ try { const workflow = require("./test.workflow.js"); let _id = String(new mongodb.ObjectId()); - let namespace = String(new mongodb.ObjectId()); + let uuid = uuidv4(); workflow(C_COMPONENT, "add", (done, { event }) => { C_COMPONENT.add({ _id, + name: "Test store", + description: "Test item for unit tests", config: [{ + name: "Test Key", key: "key", type: "string", description: "Test key" }], - namespace + uuid }, (err, item) => { // check event arguments @@ -57,16 +60,13 @@ try { workflow(C_COMPONENT, "update", (done) => { - let uuid = uuidv4(); - C_COMPONENT.update(_id, { - item: uuid + name: "Updated Name" }, (err, item) => { try { assert.ok(err === null); assert.equal(item instanceof Store, true); - assert.equal(item.item, uuid); done(err); @@ -85,12 +85,12 @@ try { // update call 1 C_COMPONENT.update(_id, { - item: uuidv4() + uuid: uuidv4() }), // update call 2 C_COMPONENT.update(_id, { - item: uuidv4() + name: "New config/store name" }) ]).then(() => { From 451fa5ebdc720e401704b81532515185e48404fc Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 4 Jan 2024 10:47:58 +0100 Subject: [PATCH 084/186] note added --- system/component/class.component.js | 1 + 1 file changed, 1 insertion(+) diff --git a/system/component/class.component.js b/system/component/class.component.js index 2ea63bc..d6359c4 100644 --- a/system/component/class.component.js +++ b/system/component/class.component.js @@ -340,6 +340,7 @@ module.exports = class COMPONENT extends COMMON { let item = this.items.find((item) => { + // NOTE: rename value to key return Object.keys(err.keyValue).every((value) => { // fixing "Duplicate unique key/index in database, but no matching item" From 6fe28fcbe0c9a0e3b88f61e56f99ecde9ea03172 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sun, 7 Jan 2024 21:52:47 +0100 Subject: [PATCH 085/186] fix #390 --- components/scenes/index.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/scenes/index.js b/components/scenes/index.js index 5d94cc5..77ce557 100644 --- a/components/scenes/index.js +++ b/components/scenes/index.js @@ -4,6 +4,7 @@ const COMPONENT = require("../../system/component/class.component.js"); const Scene = require("./class.scene.js"); const Makro = require("./class.makro.js"); +const Trigger = require("./class.trigger.js"); /** * @description @@ -33,6 +34,13 @@ class C_SCENES extends COMPONENT { } }); + // fix #390 + data.triggers.forEach((trigger, i, arr) => { + if (!(trigger instanceof Trigger)) { + arr[i] = new Trigger(trigger); + } + }); + next(); }); From e57526c9a6c83d24faa0f73c892a451269343bb3 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sun, 7 Jan 2024 21:55:51 +0100 Subject: [PATCH 086/186] fixed --- scripts/post-install.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/scripts/post-install.sh b/scripts/post-install.sh index c954c7e..466c867 100755 --- a/scripts/post-install.sh +++ b/scripts/post-install.sh @@ -1,11 +1,7 @@ #!/bin/bash -pwd=$(pwd); - #echo $pwd/scripts/hooks/; # rm -rf $pwd/.git/hooks # https://rjzaworski.com/2018/01/keeping-git-hooks-in-sync -if [[ ! -d $pwd/.git/hooks ]] -then - ln -s $pwd/scripts/hooks/ $pwd/.git/ -fi \ No newline at end of file +rm -rf $(pwd)/.git/hooks +ln -s $(pwd)/scripts/hooks $(pwd)/.git/ \ No newline at end of file From 0645228d9b7e51ac85606c65fd3ac4ae8ad190f0 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 10 Jan 2024 11:14:20 +0100 Subject: [PATCH 087/186] fix #401 --- components/endpoints/class.endpoint.js | 10 ++++++++-- components/endpoints/class.state.js | 14 ++++++++++++-- components/endpoints/index.js | 12 +++++++++--- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/components/endpoints/class.endpoint.js b/components/endpoints/class.endpoint.js index 45eeee4..be6ddb9 100644 --- a/components/endpoints/class.endpoint.js +++ b/components/endpoints/class.endpoint.js @@ -32,7 +32,7 @@ const _expose = require("../../helper/expose.js"); * @see InterfaceStream components/devices/class.interfaceStream.js */ module.exports = class Endpoint extends Item { - constructor(obj) { + constructor(obj, scope) { super(obj); @@ -44,7 +44,13 @@ module.exports = class Endpoint extends Item { //this.states = new States(obj.states); this.states = obj.states.map((item) => { - return new State(item); + return new State(item, async () => { + + // trigger update on endpoint item + // otherwise ui is not rendered/refreshed on state changed + await scope.update(this._id, this); + + }); }); this.commands = obj.commands.map((item) => { diff --git a/components/endpoints/class.state.js b/components/endpoints/class.state.js index 59b84a9..b1403a4 100644 --- a/components/endpoints/class.state.js +++ b/components/endpoints/class.state.js @@ -22,8 +22,7 @@ const mongodb = require("mongodb"); */ module.exports = class State { - - constructor(obj) { + constructor(obj, changed = () => { }) { Object.assign(this, obj); this._id = String(obj._id); @@ -46,11 +45,20 @@ module.exports = class State { // check for value type, but allow null value if (((typeof value) !== this.type) && (value !== null)) { + // TODO: uncomment & make active + //throw new TypeError(`Invalid type "${typeof (value)}"`); return; } // fix #251 if (this.type === "number" && !(value >= this.min && value <= this.max)) { + // TODO: uncomment & make active + //throw new RangeError(`Invalid value "${value}"`); + return; + } + + // prevent useles set/update + if (value === obj.value) { return; } @@ -58,6 +66,8 @@ module.exports = class State { this.timestamps.updated = Date.now(); + process.nextTick(changed, this); + }, configurable: false, enumerable: true diff --git a/components/endpoints/index.js b/components/endpoints/index.js index f296761..a810c2a 100644 --- a/components/endpoints/index.js +++ b/components/endpoints/index.js @@ -45,7 +45,7 @@ class C_ENDPOINTS extends COMPONENT { this.hooks.post("add", (data, next) => { - next(null, new Endpoint(data)); + next(null, new Endpoint(data, this)); }); @@ -54,7 +54,13 @@ class C_ENDPOINTS extends COMPONENT { // fix for #368 data.states.forEach((state, i, arr) => { if (!(state instanceof State)) { - arr[i] = new State(state); + arr[i] = new State(state, async () => { + + // trigger update on endpoint item + // otherwise ui is not rendered/refreshed on state changed + await this.update(this._id, this); + + }); } }); @@ -126,7 +132,7 @@ instance.init((scope, ready) => { } else { data = data.map((item) => { - return new Endpoint(item); + return new Endpoint(item, scope); }); scope.items.push(...data); From 4695f97f6ed0dfd644206873e9ffe2756cd962a8 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 10 Jan 2024 12:20:44 +0100 Subject: [PATCH 088/186] fix #401 --- routes/router.api.events.js | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/routes/router.api.events.js b/routes/router.api.events.js index c99af5f..0b3bfdb 100644 --- a/routes/router.api.events.js +++ b/routes/router.api.events.js @@ -1,4 +1,6 @@ const WebSocket = require("ws"); +const path = require("path"); +const fs = require("fs"); module.exports = (app, router) => { @@ -25,7 +27,7 @@ module.exports = (app, router) => { clearInterval(interval); }); - + /* const componentNames = [ "devices", "endpoints", @@ -35,6 +37,10 @@ module.exports = (app, router) => { "store", "vault" ]; + */ + + // fix #403 "Add missing components" + let componentNames = fs.readdirSync(path.resolve(process.cwd(), "components")); function reemit(event, component) { @@ -48,7 +54,8 @@ module.exports = (app, router) => { }); wss.clients.forEach((client) => { - if (client.readyState === WebSocket.OPEN) { + // fix #403 "Implement named subscriptions" + if (client.intents.includes(event) && client.readyState === WebSocket.OPEN) { client.send(obj); } }); @@ -99,6 +106,16 @@ module.exports = (app, router) => { ws.isAlive = true; }); + // monkey patch intents for "named subscriptions" + // see #403; get default everyhting + // NOTE: remove the "default everything" part? + ws.intents = req.query?.intents || [ + "add", + "get", + "update", + "remove" + ]; + wss.emit("connection", ws, req); }); From c085e5d0fb9f8cedfff2aad2f354802c9187fe55 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 12 Jan 2024 20:50:22 +0100 Subject: [PATCH 089/186] fix #408 --- routes/index.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/routes/index.js b/routes/index.js index cac8f27..01a391c 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,3 +1,4 @@ +const { ServerResponse } = require("http"); const express = require("express"); const bodyParser = require("body-parser"); @@ -220,4 +221,20 @@ module.exports = (server) => { // use express request handler server.on("request", app); + // fix #408, see: + // https://github.com/OpenHausIO/connector/issues/38 + // https://github.com/websockets/ws/issues/2193 + server.on("upgrade", (req, socket) => { + + let res = new ServerResponse(req); + res.assignSocket(socket); + + res.on("finish", () => { + res.socket.destroy(); + }); + + app(req, res); + + }); + }; \ No newline at end of file From 4f04704fabcd0c36b1c443aebd01aaecd01b18c5 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 12 Jan 2024 20:50:29 +0100 Subject: [PATCH 090/186] updated --- postman.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/postman.json b/postman.json index c5a51c6..fd64cc2 100644 --- a/postman.json +++ b/postman.json @@ -1,6 +1,6 @@ { "info": { - "_postman_id": "7b801daa-eb6a-407c-9c0c-66ac044ed8f3", + "_postman_id": "efc273f1-779c-4fce-a23e-82c17555ff65", "name": "OpenHaus", "description": "SmartHome/IoT application", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", @@ -2378,7 +2378,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"name\": \"Store item #1\",\n \"description\": \"Configuration settings for pluginx xyz\",\n \"_id\": \"65818986ca5133d8de2bb4a1\",\n \"config\": [{\n \"_id\": \"6581a14f1c6d01f32129dabc\",\n \"name\": \"Gateway Pairing\",\n \"key\": \"pairing\",\n \"type\": \"boolean\",\n \"value\": false,\n \"description\": \"Is the Gateway ready for pairing?\"\n }, {\n \"_id\": \"6581a1520bcb15659d48b207\",\n \"name\": \"Polling Interval\",\n \"key\": \"interval\",\n \"type\": \"number\",\n \"value\": 3000,\n \"description\": \"Sync intervall for Endpoints\"\n }]\n}", + "raw": "{\n \"_id\": \"65818986ca5133d8de2bb4a1\",\n \"name\": \"Store name\",\n \"config\": [{\n \"_id\": \"6581a14f1c6d01f32129dabc\",\n \"name\": \"Device Pairing\",\n \"key\": \"pairing\",\n \"type\": \"boolean\",\n \"value\": false,\n \"description\": \"Is the Gateway ready for pairing?\"\n }, {\n \"_id\": \"6581a1520bcb15659d48b207\",\n \"name\": \"Polling interval\",\n \"key\": \"interval\",\n \"type\": \"number\",\n \"value\": 3000,\n \"description\": \"Sync intervall for Endpoints\"\n }]\n}", "options": { "raw": { "language": "json" From cbda9e972efb99eee249163348e20308a5f31ebe Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 12 Jan 2024 20:50:51 +0100 Subject: [PATCH 091/186] error fix --- tests/http-api/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/http-api/index.js b/tests/http-api/index.js index 378babc..a1a5927 100644 --- a/tests/http-api/index.js +++ b/tests/http-api/index.js @@ -21,7 +21,7 @@ describe("HTTP API", function () { silent: true, env: Object.assign({}, process.env, { UUID: crypto.randomUUID(), - DATABASE_NAME: "/test", + DATABASE_NAME: "test", VAULT_MASTER_PASSWORD: crypto.randomBytes(24).toString("hex"), USERS_JWT_SECRET: crypto.randomBytes(24).toString("hex") }) From 057480554142f47bbfee03fa804c0ba89d89a019 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sat, 13 Jan 2024 11:49:35 +0100 Subject: [PATCH 092/186] fix #406 --- components/store/index.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/components/store/index.js b/components/store/index.js index d49fb60..393ca9b 100644 --- a/components/store/index.js +++ b/components/store/index.js @@ -3,6 +3,7 @@ const COMPONENT = require("../../system/component/class.component.js"); //const Value = require("./class.value.js"); //const Namespace = require("./class.namespace.js"); const Store = require("./class.store.js"); +const Value = require("./class.value.js"); /** * @description @@ -39,6 +40,19 @@ class C_STORE extends COMPONENT { next(null, new Store(data, this)); }); + // fix #406 + this.hooks.post("update", (data, next) => { + + data.config.forEach((value, i, arr) => { + if (!(value instanceof Value)) { + arr[i] = new Value(value); + } + }); + + next(); + + }); + this.collection.createIndex("uuid", { unique: true }); From 6489b7c8212da2dfd8d31c85adc68eaca9b033f7 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 16 Jan 2024 14:28:37 +0100 Subject: [PATCH 093/186] fix #411 --- components/devices/class.interface.js | 39 ++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/components/devices/class.interface.js b/components/devices/class.interface.js index dbf24bc..701d102 100644 --- a/components/devices/class.interface.js +++ b/components/devices/class.interface.js @@ -219,8 +219,23 @@ module.exports = class Interface { //let settings = this.settings; + /* + // added for testing a solution for #411 + // does nothing/not work, but feels like can be useful in the future + // see: + // - https://nodejs.org/docs/latest/api/http.html#agentkeepsocketalivesocket + // - https://nodejs.org/docs/latest/api/http.html#agentkeepsocketalivesocket + agent.keepSocketAlive = (socket) => { + console.log("agent.keepSocketAlive called"); + return true; + }; + + agent.reuseSocket = (socket, request) => { + console.log("agent.reuseSocket called"); + }; + */ - agent.createConnection = () => { + agent.createConnection = ({ headers = {} }) => { //console.log(`############## Create connection to tcp://${host}:${port}`); @@ -243,17 +258,33 @@ module.exports = class Interface { //let readable = new PassThrough(); //let writable = new PassThrough(); + // convert headers key/values to lowercase + // the string conversion prevents a error thrown for numbers + // this happens for websocket requests, where e.g. "sec-websocket-version=13" + // see snipp below "detect websocket connection with set headers" + headers = Object.keys(headers).reduce((obj, key) => { + obj[key.toLowerCase()] = `${headers[key]}`.toLowerCase(); + return obj; + }, {}); + + let readable = new Transform({ transform(chunk, enc, cb) { - //console.log("[incoming]", chunk.toString()); + //console.log("[incoming]", chunk); // temp fix for #343 // this is not the prefered fix for this issue // it should be handled on "stream/socket" level instead // the issue above occoured with a "shelly 1pm" and parallel requests to /status /ota /settings // NOTE: what if the body contains json that has a `connection: close` property/key/value? - chunk = chunk.toString().replace(/connection:\s?close\r\n/i, "connection: keep-alive\r\n"); + + // detect websocket connection with set headers, fix #411 + // agent.protocol is never "ws" regardless of the url used in requests + // temp solution, more like a hotfix than a final solution + if (agent.protocol === "http:" && !(headers?.upgrade === "websocket" && headers?.connection === "upgrade")) { + chunk = chunk.toString().replace(/connection:\s?close\r\n/i, "connection: keep-alive\r\n"); + } this.push(chunk); cb(); @@ -264,7 +295,7 @@ module.exports = class Interface { let writable = new Transform({ transform(chunk, enc, cb) { - //console.log("[outgoing]", chunk.toString()); + //console.log("[outgoing]", chunk); this.push(chunk); cb(); From a9c417fc8fece92687b1ffe10a67d6d74d15db0f Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 16 Jan 2024 14:29:17 +0100 Subject: [PATCH 094/186] fix #412 --- components/endpoints/class.state.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/components/endpoints/class.state.js b/components/endpoints/class.state.js index b1403a4..8fe1970 100644 --- a/components/endpoints/class.state.js +++ b/components/endpoints/class.state.js @@ -43,6 +43,10 @@ module.exports = class State { }, set: (value) => { + if (this.type === "number" && this.invert && value < 0) { + value = value * -1; + } + // check for value type, but allow null value if (((typeof value) !== this.type) && (value !== null)) { // TODO: uncomment & make active @@ -106,7 +110,8 @@ module.exports = class State { then: Joi.object({ value: Joi.number().default(null).allow(null), min: Joi.number().default(0), - max: Joi.number().default(100) + max: Joi.number().default(100), + invert: Joi.boolean().default(false) }) }, { is: "string", From 6a1ed51622302d9aa5c3dbc7954d557c8ea7deba Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 16 Jan 2024 15:12:40 +0100 Subject: [PATCH 095/186] fix #409 --- routes/index.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/routes/index.js b/routes/index.js index 01a391c..0beeae1 100644 --- a/routes/index.js +++ b/routes/index.js @@ -19,6 +19,10 @@ const C_MDNS = require("../components/mdns"); //const { encode } = require("../helper/sanitize"); //const iterate = require("../helper/iterate"); +// add logger for http, fix #409 +const logger = require("../system/logger/index.js"); +const log = logger.create("http"); + // copied from https://github.com/vkarpov15/mongo-sanitize function sanitize(v) { if (v instanceof Object) { @@ -49,6 +53,26 @@ module.exports = (server) => { "uniquelocal" ]); + // fix #409 + // add logging for http requests + app.use((req, res, next) => { + + // log basic http requests, do not reveal any senstive information + // thats why "req.path" is used instead of "req.url" + log.debug(`[${req.method}] ${req.socket.remoteAddress} - ${req.path}`); + + // log verbose requests + // this may reveal senstive informations like tokens or cookies + log.verbose(JSON.stringify({ + query: req.query, + params: req.params, + headers: req.headers + })); + + next(); + + }); + app.use(bodyParser.json({ limit: (Number(process.env.API_LIMIT_SIZE) * 1024) // default to 25, (=25mb) })); From b65819c320095d517945f65625e417a337a8aa8b Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 16 Jan 2024 15:24:20 +0100 Subject: [PATCH 096/186] log format changed --- routes/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/index.js b/routes/index.js index 0beeae1..50fe043 100644 --- a/routes/index.js +++ b/routes/index.js @@ -59,7 +59,7 @@ module.exports = (server) => { // log basic http requests, do not reveal any senstive information // thats why "req.path" is used instead of "req.url" - log.debug(`[${req.method}] ${req.socket.remoteAddress} - ${req.path}`); + log.debug(`${req.socket.remoteAddress} - [${req.method}] ${req.path}`); // log verbose requests // this may reveal senstive informations like tokens or cookies From da79aefe9eaed273fb305c55484948b32b541b6b Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 16 Jan 2024 16:41:53 +0100 Subject: [PATCH 097/186] fix #393 --- components/plugins/class.plugin.js | 54 +++++++++++++----------------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/components/plugins/class.plugin.js b/components/plugins/class.plugin.js index c7963e7..0e0c677 100644 --- a/components/plugins/class.plugin.js +++ b/components/plugins/class.plugin.js @@ -36,8 +36,6 @@ module.exports = class Plugin extends Item { //Object.assign(this, obj); //this._id = String(obj._id); - let json = {}; - Object.defineProperty(this, "logger", { value: logger.create(`plugins/${this.uuid}`), configurable: false, @@ -52,31 +50,6 @@ module.exports = class Plugin extends Item { writable: true }); - try { - - let file = path.resolve(process.cwd(), "plugins", this.uuid, "package.json"); - let content = fs.readFileSync(file); - json = JSON.parse(content); - - } catch (err) { - if (err.code === "ENOENT") { - - this.logger.warn(err, `package.json for plugin "${this.name}" not found.`); - - } else { - - this.logger.warn(err); - - } - } - - Object.defineProperty(this, "package", { - value: json, - configurable: false, - enumerable: false, - writable: false, - }); - } static schema() { @@ -111,13 +84,33 @@ module.exports = class Plugin extends Item { // feedback logger.debug(`Start plugin "${this.name}"...`); + let json = {}; let plugin = path.resolve(process.cwd(), "plugins", this.uuid); - let compatible = semver.satisfies(pkg.version, this.package?.backend); + let file = path.resolve(plugin, "package.json"); + + // 1) check if plugin is compatible + try { + + let content = fs.readFileSync(file); + json = JSON.parse(content); + + if (!semver.satisfies(pkg.version, json?.backend)) { + this.logger.warn(`Plugin "${this.name}" is incompatible. It may work not properly or break something!`); + } + + } catch (err) { + + this.logger.warn(err, `Could not check plugin compatibility for plugin "${this.name}"`); + + if (err.code === "ENOENT") { + this.logger.warn(`package.json for plugin "${this.name}" not found, try to start it anyway...`); + } else { + this.logger.error(err); + } - if (!compatible) { - logger.warn(`Starting incomptaible plugin "${this.name}". It may work not properly or break something!`); } + // 2) start plugin if (fs.existsSync(plugin)) { let init = (dependencies, cb) => { @@ -160,7 +153,6 @@ module.exports = class Plugin extends Item { }; init[Symbol.for("uuid")] = this.uuid; - init[Symbol.for("compatible")] = compatible; try { From ef4cab2b157f0308c59150bfaf2f77edad03c9b6 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 16 Jan 2024 20:34:21 +0100 Subject: [PATCH 098/186] removed `console.log` --- routes/auth-handler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/auth-handler.js b/routes/auth-handler.js index 008fdda..449799f 100644 --- a/routes/auth-handler.js +++ b/routes/auth-handler.js @@ -108,7 +108,7 @@ module.exports = (C_USERS, router) => { return; } - console.log("User request:", req.user, req.authenticated, process.env.API_AUTH_ENABLED, req.ip, req.socket.remoteAddress, req.method, req.url, req.headers); + //console.log("User request:", req.user, req.authenticated, process.env.API_AUTH_ENABLED, req.ip, req.socket.remoteAddress, req.method, req.url, req.headers); next(); From 6e54a6fcbaf303083c6e197fba9981aa0d88c9ae Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 16 Jan 2024 21:00:06 +0100 Subject: [PATCH 099/186] switched to husky foy git hooks, fix #398 --- .husky/pre-commit | 5 +++++ package-lock.json | 22 ++++++++++++++++++++++ package.json | 8 +++++--- 3 files changed, 32 insertions(+), 3 deletions(-) create mode 100755 .husky/pre-commit diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..6f27311 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,5 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +#npm test +npm run lint \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8f2bc2f..ade9ded 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,6 +32,7 @@ "grunt-contrib-uglify": "^5.0.1", "grunt-env": "^1.0.1", "grunt-run": "^0.8.1", + "husky": "^8.0.0", "minimist": "^1.2.6", "mocha": "^9.2.2", "mocha.parallel": "^0.15.6", @@ -3942,6 +3943,21 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/husky": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", + "dev": true, + "bin": { + "husky": "lib/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -10165,6 +10181,12 @@ } } }, + "husky": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", + "dev": true + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", diff --git a/package.json b/package.json index 99ae8a5..d89a1bf 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "db:export": "mongodump --db OpenHaus --archive=./demo-database.gz", "db:import": "mongorestore --db OpenHaus --archive=./demo-database.gz", "postinstall": "scripts/post-install.sh", - "publish": "grunt publish" + "publish": "grunt publish", + "prepare": "husky install" }, "engines": { "node": ">=0.16.0" @@ -55,6 +56,7 @@ "mocha.parallel": "^0.15.6", "newman": "^6.0.0", "nodemon": "^3.0.1", - "sinon": "^14.0.2" + "sinon": "^14.0.2", + "husky": "^8.0.0" } -} \ No newline at end of file +} From 6ab36f8668576e275da8619c86c29c2514a9b5ee Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 16 Jan 2024 21:01:32 +0100 Subject: [PATCH 100/186] remove post install script --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index d89a1bf..ea2ef18 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,6 @@ "release": "grunt release", "db:export": "mongodump --db OpenHaus --archive=./demo-database.gz", "db:import": "mongorestore --db OpenHaus --archive=./demo-database.gz", - "postinstall": "scripts/post-install.sh", "publish": "grunt publish", "prepare": "husky install" }, From 702a008154f7abcf660c2b1b4eaca93a84de9b86 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 16 Jan 2024 21:24:50 +0100 Subject: [PATCH 101/186] Revert "Switched to husky & removed `console.log`" --- .husky/pre-commit | 5 ----- package-lock.json | 22 ---------------------- package.json | 9 ++++----- routes/auth-handler.js | 2 +- 4 files changed, 5 insertions(+), 33 deletions(-) delete mode 100755 .husky/pre-commit diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index 6f27311..0000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - -#npm test -npm run lint \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index ade9ded..8f2bc2f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,6 @@ "grunt-contrib-uglify": "^5.0.1", "grunt-env": "^1.0.1", "grunt-run": "^0.8.1", - "husky": "^8.0.0", "minimist": "^1.2.6", "mocha": "^9.2.2", "mocha.parallel": "^0.15.6", @@ -3943,21 +3942,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/husky": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", - "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", - "dev": true, - "bin": { - "husky": "lib/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -10181,12 +10165,6 @@ } } }, - "husky": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", - "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", - "dev": true - }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", diff --git a/package.json b/package.json index ea2ef18..99ae8a5 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,8 @@ "release": "grunt release", "db:export": "mongodump --db OpenHaus --archive=./demo-database.gz", "db:import": "mongorestore --db OpenHaus --archive=./demo-database.gz", - "publish": "grunt publish", - "prepare": "husky install" + "postinstall": "scripts/post-install.sh", + "publish": "grunt publish" }, "engines": { "node": ">=0.16.0" @@ -55,7 +55,6 @@ "mocha.parallel": "^0.15.6", "newman": "^6.0.0", "nodemon": "^3.0.1", - "sinon": "^14.0.2", - "husky": "^8.0.0" + "sinon": "^14.0.2" } -} +} \ No newline at end of file diff --git a/routes/auth-handler.js b/routes/auth-handler.js index 449799f..008fdda 100644 --- a/routes/auth-handler.js +++ b/routes/auth-handler.js @@ -108,7 +108,7 @@ module.exports = (C_USERS, router) => { return; } - //console.log("User request:", req.user, req.authenticated, process.env.API_AUTH_ENABLED, req.ip, req.socket.remoteAddress, req.method, req.url, req.headers); + console.log("User request:", req.user, req.authenticated, process.env.API_AUTH_ENABLED, req.ip, req.socket.remoteAddress, req.method, req.url, req.headers); next(); From bf24ffe0e54425b8b785272c790d57dedb7cabe5 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 17 Jan 2024 09:37:18 +0100 Subject: [PATCH 102/186] removed due to moving to husky --- scripts/hooks/applypatch-msg.sample | 15 --- scripts/hooks/commit-msg.sample | 24 ---- scripts/hooks/fsmonitor-watchman.sample | 114 ---------------- scripts/hooks/post-update.sample | 8 -- scripts/hooks/pre-applypatch.sample | 14 -- scripts/hooks/pre-commit | 4 - scripts/hooks/pre-commit.sample | 49 ------- scripts/hooks/pre-push.sample | 53 -------- scripts/hooks/pre-rebase.sample | 169 ------------------------ scripts/hooks/pre-receive.sample | 24 ---- scripts/hooks/prepare-commit-msg.sample | 42 ------ scripts/hooks/update.sample | 128 ------------------ 12 files changed, 644 deletions(-) delete mode 100755 scripts/hooks/applypatch-msg.sample delete mode 100755 scripts/hooks/commit-msg.sample delete mode 100755 scripts/hooks/fsmonitor-watchman.sample delete mode 100755 scripts/hooks/post-update.sample delete mode 100755 scripts/hooks/pre-applypatch.sample delete mode 100755 scripts/hooks/pre-commit delete mode 100755 scripts/hooks/pre-commit.sample delete mode 100755 scripts/hooks/pre-push.sample delete mode 100755 scripts/hooks/pre-rebase.sample delete mode 100755 scripts/hooks/pre-receive.sample delete mode 100755 scripts/hooks/prepare-commit-msg.sample delete mode 100755 scripts/hooks/update.sample diff --git a/scripts/hooks/applypatch-msg.sample b/scripts/hooks/applypatch-msg.sample deleted file mode 100755 index a5d7b84..0000000 --- a/scripts/hooks/applypatch-msg.sample +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message taken by -# applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. The hook is -# allowed to edit the commit message file. -# -# To enable this hook, rename this file to "applypatch-msg". - -. git-sh-setup -commitmsg="$(git rev-parse --git-path hooks/commit-msg)" -test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} -: diff --git a/scripts/hooks/commit-msg.sample b/scripts/hooks/commit-msg.sample deleted file mode 100755 index b58d118..0000000 --- a/scripts/hooks/commit-msg.sample +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message. -# Called by "git commit" with one argument, the name of the file -# that has the commit message. The hook should exit with non-zero -# status after issuing an appropriate message if it wants to stop the -# commit. The hook is allowed to edit the commit message file. -# -# To enable this hook, rename this file to "commit-msg". - -# Uncomment the below to add a Signed-off-by line to the message. -# Doing this in a hook is a bad idea in general, but the prepare-commit-msg -# hook is more suited to it. -# -# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" - -# This example catches duplicate Signed-off-by lines. - -test "" = "$(grep '^Signed-off-by: ' "$1" | - sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { - echo >&2 Duplicate Signed-off-by lines. - exit 1 -} diff --git a/scripts/hooks/fsmonitor-watchman.sample b/scripts/hooks/fsmonitor-watchman.sample deleted file mode 100755 index e673bb3..0000000 --- a/scripts/hooks/fsmonitor-watchman.sample +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; -use IPC::Open2; - -# An example hook script to integrate Watchman -# (https://facebook.github.io/watchman/) with git to speed up detecting -# new and modified files. -# -# The hook is passed a version (currently 1) and a time in nanoseconds -# formatted as a string and outputs to stdout all files that have been -# modified since the given time. Paths must be relative to the root of -# the working tree and separated by a single NUL. -# -# To enable this hook, rename this file to "query-watchman" and set -# 'git config core.fsmonitor .git/hooks/query-watchman' -# -my ($version, $time) = @ARGV; - -# Check the hook interface version - -if ($version == 1) { - # convert nanoseconds to seconds - $time = int $time / 1000000000; -} else { - die "Unsupported query-fsmonitor hook version '$version'.\n" . - "Falling back to scanning...\n"; -} - -my $git_work_tree; -if ($^O =~ 'msys' || $^O =~ 'cygwin') { - $git_work_tree = Win32::GetCwd(); - $git_work_tree =~ tr/\\/\//; -} else { - require Cwd; - $git_work_tree = Cwd::cwd(); -} - -my $retry = 1; - -launch_watchman(); - -sub launch_watchman { - - my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') - or die "open2() failed: $!\n" . - "Falling back to scanning...\n"; - - # In the query expression below we're asking for names of files that - # changed since $time but were not transient (ie created after - # $time but no longer exist). - # - # To accomplish this, we're using the "since" generator to use the - # recency index to select candidate nodes and "fields" to limit the - # output to file names only. Then we're using the "expression" term to - # further constrain the results. - # - # The category of transient files that we want to ignore will have a - # creation clock (cclock) newer than $time_t value and will also not - # currently exist. - - my $query = <<" END"; - ["query", "$git_work_tree", { - "since": $time, - "fields": ["name"], - "expression": ["not", ["allof", ["since", $time, "cclock"], ["not", "exists"]]] - }] - END - - print CHLD_IN $query; - close CHLD_IN; - my $response = do {local $/; }; - - die "Watchman: command returned no output.\n" . - "Falling back to scanning...\n" if $response eq ""; - die "Watchman: command returned invalid output: $response\n" . - "Falling back to scanning...\n" unless $response =~ /^\{/; - - my $json_pkg; - eval { - require JSON::XS; - $json_pkg = "JSON::XS"; - 1; - } or do { - require JSON::PP; - $json_pkg = "JSON::PP"; - }; - - my $o = $json_pkg->new->utf8->decode($response); - - if ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) { - print STDERR "Adding '$git_work_tree' to watchman's watch list.\n"; - $retry--; - qx/watchman watch "$git_work_tree"/; - die "Failed to make watchman watch '$git_work_tree'.\n" . - "Falling back to scanning...\n" if $? != 0; - - # Watchman will always return all files on the first query so - # return the fast "everything is dirty" flag to git and do the - # Watchman query just to get it over with now so we won't pay - # the cost in git to look up each individual file. - print "/\0"; - eval { launch_watchman() }; - exit 0; - } - - die "Watchman: $o->{error}.\n" . - "Falling back to scanning...\n" if $o->{error}; - - binmode STDOUT, ":utf8"; - local $, = "\0"; - print @{$o->{files}}; -} diff --git a/scripts/hooks/post-update.sample b/scripts/hooks/post-update.sample deleted file mode 100755 index ec17ec1..0000000 --- a/scripts/hooks/post-update.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare a packed repository for use over -# dumb transports. -# -# To enable this hook, rename this file to "post-update". - -exec git update-server-info diff --git a/scripts/hooks/pre-applypatch.sample b/scripts/hooks/pre-applypatch.sample deleted file mode 100755 index 4142082..0000000 --- a/scripts/hooks/pre-applypatch.sample +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed -# by applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-applypatch". - -. git-sh-setup -precommit="$(git rev-parse --git-path hooks/pre-commit)" -test -x "$precommit" && exec "$precommit" ${1+"$@"} -: diff --git a/scripts/hooks/pre-commit b/scripts/hooks/pre-commit deleted file mode 100755 index 5ea1285..0000000 --- a/scripts/hooks/pre-commit +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -# ensure linting -npm run lint \ No newline at end of file diff --git a/scripts/hooks/pre-commit.sample b/scripts/hooks/pre-commit.sample deleted file mode 100755 index 68d62d5..0000000 --- a/scripts/hooks/pre-commit.sample +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed. -# Called by "git commit" with no arguments. The hook should -# exit with non-zero status after issuing an appropriate message if -# it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-commit". - -if git rev-parse --verify HEAD >/dev/null 2>&1 -then - against=HEAD -else - # Initial commit: diff against an empty tree object - against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 -fi - -# If you want to allow non-ASCII filenames set this variable to true. -allownonascii=$(git config --bool hooks.allownonascii) - -# Redirect output to stderr. -exec 1>&2 - -# Cross platform projects tend to avoid non-ASCII filenames; prevent -# them from being added to the repository. We exploit the fact that the -# printable range starts at the space character and ends with tilde. -if [ "$allownonascii" != "true" ] && - # Note that the use of brackets around a tr range is ok here, (it's - # even required, for portability to Solaris 10's /usr/bin/tr), since - # the square bracket bytes happen to fall in the designated range. - test $(git diff --cached --name-only --diff-filter=A -z $against | - LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 -then - cat <<\EOF -Error: Attempt to add a non-ASCII file name. - -This can cause problems if you want to work with people on other platforms. - -To be portable it is advisable to rename the file. - -If you know what you are doing you can disable this check using: - - git config hooks.allownonascii true -EOF - exit 1 -fi - -# If there are whitespace errors, print the offending file names and fail. -exec git diff-index --check --cached $against -- diff --git a/scripts/hooks/pre-push.sample b/scripts/hooks/pre-push.sample deleted file mode 100755 index 6187dbf..0000000 --- a/scripts/hooks/pre-push.sample +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/sh - -# An example hook script to verify what is about to be pushed. Called by "git -# push" after it has checked the remote status, but before anything has been -# pushed. If this script exits with a non-zero status nothing will be pushed. -# -# This hook is called with the following parameters: -# -# $1 -- Name of the remote to which the push is being done -# $2 -- URL to which the push is being done -# -# If pushing without using a named remote those arguments will be equal. -# -# Information about the commits which are being pushed is supplied as lines to -# the standard input in the form: -# -# -# -# This sample shows how to prevent push of commits where the log message starts -# with "WIP" (work in progress). - -remote="$1" -url="$2" - -z40=0000000000000000000000000000000000000000 - -while read local_ref local_sha remote_ref remote_sha -do - if [ "$local_sha" = $z40 ] - then - # Handle delete - : - else - if [ "$remote_sha" = $z40 ] - then - # New branch, examine all commits - range="$local_sha" - else - # Update to existing branch, examine new commits - range="$remote_sha..$local_sha" - fi - - # Check for WIP commit - commit=`git rev-list -n 1 --grep '^WIP' "$range"` - if [ -n "$commit" ] - then - echo >&2 "Found WIP commit in $local_ref, not pushing" - exit 1 - fi - fi -done - -exit 0 diff --git a/scripts/hooks/pre-rebase.sample b/scripts/hooks/pre-rebase.sample deleted file mode 100755 index 6cbef5c..0000000 --- a/scripts/hooks/pre-rebase.sample +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2006, 2008 Junio C Hamano -# -# The "pre-rebase" hook is run just before "git rebase" starts doing -# its job, and can prevent the command from running by exiting with -# non-zero status. -# -# The hook is called with the following parameters: -# -# $1 -- the upstream the series was forked from. -# $2 -- the branch being rebased (or empty when rebasing the current branch). -# -# This sample shows how to prevent topic branches that are already -# merged to 'next' branch from getting rebased, because allowing it -# would result in rebasing already published history. - -publish=next -basebranch="$1" -if test "$#" = 2 -then - topic="refs/heads/$2" -else - topic=`git symbolic-ref HEAD` || - exit 0 ;# we do not interrupt rebasing detached HEAD -fi - -case "$topic" in -refs/heads/??/*) - ;; -*) - exit 0 ;# we do not interrupt others. - ;; -esac - -# Now we are dealing with a topic branch being rebased -# on top of master. Is it OK to rebase it? - -# Does the topic really exist? -git show-ref -q "$topic" || { - echo >&2 "No such branch $topic" - exit 1 -} - -# Is topic fully merged to master? -not_in_master=`git rev-list --pretty=oneline ^master "$topic"` -if test -z "$not_in_master" -then - echo >&2 "$topic is fully merged to master; better remove it." - exit 1 ;# we could allow it, but there is no point. -fi - -# Is topic ever merged to next? If so you should not be rebasing it. -only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` -only_next_2=`git rev-list ^master ${publish} | sort` -if test "$only_next_1" = "$only_next_2" -then - not_in_topic=`git rev-list "^$topic" master` - if test -z "$not_in_topic" - then - echo >&2 "$topic is already up to date with master" - exit 1 ;# we could allow it, but there is no point. - else - exit 0 - fi -else - not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` - /usr/bin/perl -e ' - my $topic = $ARGV[0]; - my $msg = "* $topic has commits already merged to public branch:\n"; - my (%not_in_next) = map { - /^([0-9a-f]+) /; - ($1 => 1); - } split(/\n/, $ARGV[1]); - for my $elem (map { - /^([0-9a-f]+) (.*)$/; - [$1 => $2]; - } split(/\n/, $ARGV[2])) { - if (!exists $not_in_next{$elem->[0]}) { - if ($msg) { - print STDERR $msg; - undef $msg; - } - print STDERR " $elem->[1]\n"; - } - } - ' "$topic" "$not_in_next" "$not_in_master" - exit 1 -fi - -<<\DOC_END - -This sample hook safeguards topic branches that have been -published from being rewound. - -The workflow assumed here is: - - * Once a topic branch forks from "master", "master" is never - merged into it again (either directly or indirectly). - - * Once a topic branch is fully cooked and merged into "master", - it is deleted. If you need to build on top of it to correct - earlier mistakes, a new topic branch is created by forking at - the tip of the "master". This is not strictly necessary, but - it makes it easier to keep your history simple. - - * Whenever you need to test or publish your changes to topic - branches, merge them into "next" branch. - -The script, being an example, hardcodes the publish branch name -to be "next", but it is trivial to make it configurable via -$GIT_DIR/config mechanism. - -With this workflow, you would want to know: - -(1) ... if a topic branch has ever been merged to "next". Young - topic branches can have stupid mistakes you would rather - clean up before publishing, and things that have not been - merged into other branches can be easily rebased without - affecting other people. But once it is published, you would - not want to rewind it. - -(2) ... if a topic branch has been fully merged to "master". - Then you can delete it. More importantly, you should not - build on top of it -- other people may already want to - change things related to the topic as patches against your - "master", so if you need further changes, it is better to - fork the topic (perhaps with the same name) afresh from the - tip of "master". - -Let's look at this example: - - o---o---o---o---o---o---o---o---o---o "next" - / / / / - / a---a---b A / / - / / / / - / / c---c---c---c B / - / / / \ / - / / / b---b C \ / - / / / / \ / - ---o---o---o---o---o---o---o---o---o---o---o "master" - - -A, B and C are topic branches. - - * A has one fix since it was merged up to "next". - - * B has finished. It has been fully merged up to "master" and "next", - and is ready to be deleted. - - * C has not merged to "next" at all. - -We would want to allow C to be rebased, refuse A, and encourage -B to be deleted. - -To compute (1): - - git rev-list ^master ^topic next - git rev-list ^master next - - if these match, topic has not merged in next at all. - -To compute (2): - - git rev-list master..topic - - if this is empty, it is fully merged to "master". - -DOC_END diff --git a/scripts/hooks/pre-receive.sample b/scripts/hooks/pre-receive.sample deleted file mode 100755 index a1fd29e..0000000 --- a/scripts/hooks/pre-receive.sample +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# -# An example hook script to make use of push options. -# The example simply echoes all push options that start with 'echoback=' -# and rejects all pushes when the "reject" push option is used. -# -# To enable this hook, rename this file to "pre-receive". - -if test -n "$GIT_PUSH_OPTION_COUNT" -then - i=0 - while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" - do - eval "value=\$GIT_PUSH_OPTION_$i" - case "$value" in - echoback=*) - echo "echo from the pre-receive-hook: ${value#*=}" >&2 - ;; - reject) - exit 1 - esac - i=$((i + 1)) - done -fi diff --git a/scripts/hooks/prepare-commit-msg.sample b/scripts/hooks/prepare-commit-msg.sample deleted file mode 100755 index 10fa14c..0000000 --- a/scripts/hooks/prepare-commit-msg.sample +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare the commit log message. -# Called by "git commit" with the name of the file that has the -# commit message, followed by the description of the commit -# message's source. The hook's purpose is to edit the commit -# message file. If the hook fails with a non-zero status, -# the commit is aborted. -# -# To enable this hook, rename this file to "prepare-commit-msg". - -# This hook includes three examples. The first one removes the -# "# Please enter the commit message..." help message. -# -# The second includes the output of "git diff --name-status -r" -# into the message, just before the "git status" output. It is -# commented because it doesn't cope with --amend or with squashed -# commits. -# -# The third example adds a Signed-off-by line to the message, that can -# still be edited. This is rarely a good idea. - -COMMIT_MSG_FILE=$1 -COMMIT_SOURCE=$2 -SHA1=$3 - -/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" - -# case "$COMMIT_SOURCE,$SHA1" in -# ,|template,) -# /usr/bin/perl -i.bak -pe ' -# print "\n" . `git diff --cached --name-status -r` -# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; -# *) ;; -# esac - -# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" -# if test -z "$COMMIT_SOURCE" -# then -# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" -# fi diff --git a/scripts/hooks/update.sample b/scripts/hooks/update.sample deleted file mode 100755 index 80ba941..0000000 --- a/scripts/hooks/update.sample +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/sh -# -# An example hook script to block unannotated tags from entering. -# Called by "git receive-pack" with arguments: refname sha1-old sha1-new -# -# To enable this hook, rename this file to "update". -# -# Config -# ------ -# hooks.allowunannotated -# This boolean sets whether unannotated tags will be allowed into the -# repository. By default they won't be. -# hooks.allowdeletetag -# This boolean sets whether deleting tags will be allowed in the -# repository. By default they won't be. -# hooks.allowmodifytag -# This boolean sets whether a tag may be modified after creation. By default -# it won't be. -# hooks.allowdeletebranch -# This boolean sets whether deleting branches will be allowed in the -# repository. By default they won't be. -# hooks.denycreatebranch -# This boolean sets whether remotely creating branches will be denied -# in the repository. By default this is allowed. -# - -# --- Command line -refname="$1" -oldrev="$2" -newrev="$3" - -# --- Safety check -if [ -z "$GIT_DIR" ]; then - echo "Don't run this script from the command line." >&2 - echo " (if you want, you could supply GIT_DIR then run" >&2 - echo " $0 )" >&2 - exit 1 -fi - -if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then - echo "usage: $0 " >&2 - exit 1 -fi - -# --- Config -allowunannotated=$(git config --bool hooks.allowunannotated) -allowdeletebranch=$(git config --bool hooks.allowdeletebranch) -denycreatebranch=$(git config --bool hooks.denycreatebranch) -allowdeletetag=$(git config --bool hooks.allowdeletetag) -allowmodifytag=$(git config --bool hooks.allowmodifytag) - -# check for no description -projectdesc=$(sed -e '1q' "$GIT_DIR/description") -case "$projectdesc" in -"Unnamed repository"* | "") - echo "*** Project description file hasn't been set" >&2 - exit 1 - ;; -esac - -# --- Check types -# if $newrev is 0000...0000, it's a commit to delete a ref. -zero="0000000000000000000000000000000000000000" -if [ "$newrev" = "$zero" ]; then - newrev_type=delete -else - newrev_type=$(git cat-file -t $newrev) -fi - -case "$refname","$newrev_type" in - refs/tags/*,commit) - # un-annotated tag - short_refname=${refname##refs/tags/} - if [ "$allowunannotated" != "true" ]; then - echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 - echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 - exit 1 - fi - ;; - refs/tags/*,delete) - # delete tag - if [ "$allowdeletetag" != "true" ]; then - echo "*** Deleting a tag is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/tags/*,tag) - # annotated tag - if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 - then - echo "*** Tag '$refname' already exists." >&2 - echo "*** Modifying a tag is not allowed in this repository." >&2 - exit 1 - fi - ;; - refs/heads/*,commit) - # branch - if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then - echo "*** Creating a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/heads/*,delete) - # delete branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/remotes/*,commit) - # tracking branch - ;; - refs/remotes/*,delete) - # delete tracking branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a tracking branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - *) - # Anything else (is there anything else?) - echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 - exit 1 - ;; -esac - -# --- Finished -exit 0 From bd518d039e25785943f0c1a7823b50aad8c9537a Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 17 Jan 2024 09:39:08 +0100 Subject: [PATCH 103/186] husky added, fix #398 --- .husky/pre-commit | 4 ++++ package-lock.json | 22 ++++++++++++++++++++++ package.json | 3 ++- scripts/post-install.sh | 23 ++++++++++++++++++++--- 4 files changed, 48 insertions(+), 4 deletions(-) create mode 100755 .husky/pre-commit diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..251a23e --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +npm run lint \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8f2bc2f..ac1fe69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,6 +32,7 @@ "grunt-contrib-uglify": "^5.0.1", "grunt-env": "^1.0.1", "grunt-run": "^0.8.1", + "husky": "^8.0.3", "minimist": "^1.2.6", "mocha": "^9.2.2", "mocha.parallel": "^0.15.6", @@ -3942,6 +3943,21 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/husky": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", + "dev": true, + "bin": { + "husky": "lib/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -10165,6 +10181,12 @@ } } }, + "husky": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", + "dev": true + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", diff --git a/package.json b/package.json index 99ae8a5..5c67186 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "grunt-contrib-uglify": "^5.0.1", "grunt-env": "^1.0.1", "grunt-run": "^0.8.1", + "husky": "^8.0.3", "minimist": "^1.2.6", "mocha": "^9.2.2", "mocha.parallel": "^0.15.6", @@ -57,4 +58,4 @@ "nodemon": "^3.0.1", "sinon": "^14.0.2" } -} \ No newline at end of file +} diff --git a/scripts/post-install.sh b/scripts/post-install.sh index 466c867..821f5c3 100755 --- a/scripts/post-install.sh +++ b/scripts/post-install.sh @@ -1,7 +1,24 @@ -#!/bin/bash +#!/usr/bin/env sh #echo $pwd/scripts/hooks/; # rm -rf $pwd/.git/hooks # https://rjzaworski.com/2018/01/keeping-git-hooks-in-sync -rm -rf $(pwd)/.git/hooks -ln -s $(pwd)/scripts/hooks $(pwd)/.git/ \ No newline at end of file +#rm -rf $(pwd)/.git/hooks +#ln -s $(pwd)/scripts/hooks $(pwd)/.git/ + +if [ "$NODE_ENV" = "production" ]; then + + # production installation + # sudo cp ../backend.service /usr/lib/systemd/system/ + # sudo systemctl daemon-reload + + # the true is needed, because a empty if/else block + # throw in the shell a error + true + +else + + # test/development installation + npx husky install + +fi \ No newline at end of file From b9a4218a35e8f89960189b2916df20f4c2701db5 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 19 Jan 2024 16:15:31 +0100 Subject: [PATCH 104/186] removed `console.log` --- routes/auth-handler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/auth-handler.js b/routes/auth-handler.js index 008fdda..449799f 100644 --- a/routes/auth-handler.js +++ b/routes/auth-handler.js @@ -108,7 +108,7 @@ module.exports = (C_USERS, router) => { return; } - console.log("User request:", req.user, req.authenticated, process.env.API_AUTH_ENABLED, req.ip, req.socket.remoteAddress, req.method, req.url, req.headers); + //console.log("User request:", req.user, req.authenticated, process.env.API_AUTH_ENABLED, req.ip, req.socket.remoteAddress, req.method, req.url, req.headers); next(); From 01d8a6f979e6b2aa74b81db0156aef84bd4bdc6d Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 19 Jan 2024 16:29:15 +0100 Subject: [PATCH 105/186] fix #419 --- routes/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/index.js b/routes/index.js index 50fe043..15d7bab 100644 --- a/routes/index.js +++ b/routes/index.js @@ -59,7 +59,7 @@ module.exports = (server) => { // log basic http requests, do not reveal any senstive information // thats why "req.path" is used instead of "req.url" - log.debug(`${req.socket.remoteAddress} - [${req.method}] ${req.path}`); + log.debug(`${req.ip} - [${req.method}] ${req.path}`); // log verbose requests // this may reveal senstive informations like tokens or cookies From 30b80b8f9e6f30436d639de9bf5e2275f7c04514 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 19 Jan 2024 21:47:07 +0100 Subject: [PATCH 106/186] fix #407 & #420 --- components/endpoints/class.endpoint.js | 33 ++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/components/endpoints/class.endpoint.js b/components/endpoints/class.endpoint.js index be6ddb9..0e32e65 100644 --- a/components/endpoints/class.endpoint.js +++ b/components/endpoints/class.endpoint.js @@ -8,6 +8,7 @@ const State = require("./class.state.js"); const Item = require("../../system/component/class.item.js"); const _expose = require("../../helper/expose.js"); +const _debounce = require("../../helper/debounce.js"); /** * @description @@ -43,13 +44,41 @@ module.exports = class Endpoint extends Item { //this.commands = new Commands(obj.commands); //this.states = new States(obj.states); - this.states = obj.states.map((item) => { - return new State(item, async () => { + // see 407 & 420 + let updater = _debounce(async () => { + try { // trigger update on endpoint item // otherwise ui is not rendered/refreshed on state changed await scope.update(this._id, this); + // feedback + scope.logger.verbose("Endpoint states updated", this.states); + + } catch (err) { + + scope.logger.warn(err, "Could not update item states after debouncing"); + + } + }, 100); + + // see 407 & 420 + this.states = obj.states.map((item) => { + return new State(item, () => { + try { + + // feedback + scope.logger.verbose(`Value in endpoint ("${obj._id}") state ("${item._id}") changed: ${item.alias}=${item.value}`); + + // update item in database + //await scope.update(this._id, this); + updater(); + + } catch (err) { + + scope.logger.warn(err, `Could not update item (${obj._id}) state ("${item._id}") in database: ${item.alias}=${item.value}`); + + } }); }); From 59698367f873610b80ce9d843722dec11fb3930d Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sun, 21 Jan 2024 21:31:16 +0100 Subject: [PATCH 107/186] fix #345 --- system/init/init.http-server.js | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/system/init/init.http-server.js b/system/init/init.http-server.js index b6f8daf..5b5522a 100644 --- a/system/init/init.http-server.js +++ b/system/init/init.http-server.js @@ -7,6 +7,10 @@ module.exports = (logger) => { logger.debug("Init http server..."); + // store active sockets from requests + // see #345 + const sockets = new Set(); + const servers = [ // http server for ip/port @@ -15,6 +19,16 @@ module.exports = (logger) => { let server = http.createServer(); + server.on("connection", (socket) => { + + sockets.add(socket); + + socket.on("close", () => { + sockets.delete(socket); + }); + + }); + server.on("error", (err) => { logger.error(err, `Could not start http server: ${err.message}`); reject(err); @@ -49,6 +63,16 @@ module.exports = (logger) => { let server = http.createServer(); + server.on("connection", (socket) => { + + sockets.add(socket); + + socket.on("close", () => { + sockets.delete(socket); + }); + + }); + server.on("error", (err) => { logger.error(err, `Could not start http server: ${err.message}`); @@ -98,9 +122,17 @@ module.exports = (logger) => { Promise.all(servers).then((servers) => { process.once("SIGINT", () => { + + // see #345 + // close all active http sockets/requests + for (const socket of sockets.values()) { + socket.destroy(); + } + servers.forEach((server) => { server.close(); }); + }); resolve(); From c0094825c9ffa92d99f75d69d25812fbbee62722 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sun, 21 Jan 2024 21:31:43 +0100 Subject: [PATCH 108/186] note added --- system/init/init.http-server.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/system/init/init.http-server.js b/system/init/init.http-server.js index 5b5522a..5ae1689 100644 --- a/system/init/init.http-server.js +++ b/system/init/init.http-server.js @@ -47,6 +47,11 @@ module.exports = (logger) => { logger.info(`HTTP Server closed on http://${process.env.HTTP_ADDRESS}:${process.env.HTTP_PORT}`); }); + // NOTE: Route handler get required/create twice: + // instead, require router file global + // and pass/move the request handler here + // thus prevents to create 2 express apps for each server + // "routes/index.js" should export the express app require("../../routes/index.js")(server); // bind/start http server @@ -92,6 +97,11 @@ module.exports = (logger) => { logger.info(`HTTP Server closed on ${process.env.HTTP_SOCKET}`); }); + // NOTE: Route handler get required/create twice: + // instead, require router file global + // and pass/move the request handler here + // thus prevents to create 2 express apps for each server + // "routes/index.js" should export the express app require("../../routes/index.js")(server); try { From 79b5ffee2d849b50009e2d4e4010529b8c2f3917 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 25 Jan 2024 11:20:00 +0100 Subject: [PATCH 109/186] keep as backup --- components/mqtt/!message-handler.js | 151 ++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 components/mqtt/!message-handler.js diff --git a/components/mqtt/!message-handler.js b/components/mqtt/!message-handler.js new file mode 100644 index 0000000..7800041 --- /dev/null +++ b/components/mqtt/!message-handler.js @@ -0,0 +1,151 @@ +const crypto = require("crypto"); +const mqtt = require("mqtt-packet"); + +const VERSION = Number(process.env.MQTT_BROKER_VERSION); + +const parser = mqtt.parser({ + protocolVersion: VERSION +}); + +const exitCodes = require("./exit-codes.js")(VERSION); + +module.exports = (scope) => { + scope._ready(({ logger, events }) => { + + // ping timer + let interval = null; + + events.on("publish", (packet) => { + scope.items.forEach(({ topic, _subscriber }) => { + + if (String(packet.topic).startsWith(topic) || packet.topic === topic) { + _subscriber.forEach((cb) => { + cb(packet.payload, packet); + }); + } + + }); + }); + + + events.on("connected", (ws) => { + + logger.debug("TCP socket connected to broker"); + + events.once("disconnected", () => { + clearInterval(interval); + logger.trace("Ping interval cleared"); + }); + + // TODO make this object configurable + let data = mqtt.generate({ + cmd: "connect", + protocolId: "MQTT", // Or "MQIsdp" in MQTT 3.1 and 5.0 + protocolVersion: VERSION, // Or 3 in MQTT 3.1, or 5 in MQTT 5.0 + clean: true, // Can also be false + clientId: process.env.MQTT_CLIENT_ID, + keepalive: 10, // Seconds which can be any positive number, with 0 as the default setting + /* + will: { + topic: "mydevice/test", + payload: Buffer.from("2134f"), // Payloads are buffers + + } + */ + }); + + ws.send(data); + + events.once("connack", (packet) => { + if (packet.returnCode === 0) { + + events.once("suback", () => { + + logger.debug("Subscribed to topic #"); + + let ping = mqtt.generate({ + cmd: "pingreq" + }); + + interval = setInterval(() => { + ws.send(ping); + }, Number(process.env.MQTT_PING_INTERVAL)); + + // monkey patch publisher function + scope.items.forEach((item) => { + item._publisher = (payload) => { + + scope.logger.verbose(`Publish on topic ${item.topic}`, payload); + + let pub = mqtt.generate({ + cmd: "publish", + messageId: crypto.randomInt(0, 65535), + qos: 0, + dup: false, + topic: item.topic, + payload: Buffer.from(`${payload}`), + retain: false + }); + + ws.send(pub); + + }; + }); + + }); + + let sub = mqtt.generate({ + cmd: "subscribe", + messageId: crypto.randomInt(0, 65535), + /* + properties: { // MQTT 5.0 properties + subscriptionIdentifier: 145, + userProperties: { + test: "shellies" + } + }, + */ + subscriptions: [{ + topic: "#", + qos: 0, + nl: false, // no Local MQTT 5.0 flag + rap: true, // Retain as Published MQTT 5.0 flag + rh: 1 // Retain Handling MQTT 5.0 + }] + }); + + ws.send(sub); + + } + }); + + }); + + + parser.on("packet", (packet) => { + + logger.verbose("Packet received", packet); + + if (packet.cmd === "connack") { + if (packet.returnCode == 0) { + + logger.debug("Connected to broker"); + + } else { + + logger.warn(`Could not connecto to broker: "${exitCodes[packet.returnCode]}"`); + + } + } + + events.emit(packet.cmd, packet); + + }); + + + events.on("message", (message) => { + parser.parse(message); + }); + + }); +}; \ No newline at end of file From 72a122e28054246ec7178731509ef6ec315f8b50 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 25 Jan 2024 11:23:06 +0100 Subject: [PATCH 110/186] refactored, fix#424 --- components/mqtt/message-handler.js | 210 +++++++++++++++++------------ 1 file changed, 127 insertions(+), 83 deletions(-) diff --git a/components/mqtt/message-handler.js b/components/mqtt/message-handler.js index 7800041..53de2d8 100644 --- a/components/mqtt/message-handler.js +++ b/components/mqtt/message-handler.js @@ -2,111 +2,90 @@ const crypto = require("crypto"); const mqtt = require("mqtt-packet"); const VERSION = Number(process.env.MQTT_BROKER_VERSION); +const exitCodes = require("./exit-codes.js")(VERSION); const parser = mqtt.parser({ protocolVersion: VERSION }); -const exitCodes = require("./exit-codes.js")(VERSION); - module.exports = (scope) => { - scope._ready(({ logger, events }) => { + scope._ready(({ logger, events, items }) => { - // ping timer + // ping setTimeout timer let interval = null; + + // listen for published topics + // call publish handler on each mqtt item events.on("publish", (packet) => { - scope.items.forEach(({ topic, _subscriber }) => { + // feedback + logger.trace(`Published: ${packet.topic}=${packet.payload}`); + + items.forEach(({ topic, _subscriber }) => { if (String(packet.topic).startsWith(topic) || packet.topic === topic) { + _subscriber.forEach((cb) => { cb(packet.payload, packet); }); - } + } }); - }); + }); - events.on("connected", (ws) => { - logger.debug("TCP socket connected to broker"); + // "connected" fires every time a websocket connection is made, e.g. from a connector. + // So we need to react and create a new connection to the browker + events.on("connected", async (ws) => { + try { - events.once("disconnected", () => { - clearInterval(interval); - logger.trace("Ping interval cleared"); - }); + // connecto to broker + // TODO: Add here credentials for authentication + await new Promise((resolve, reject) => { - // TODO make this object configurable - let data = mqtt.generate({ - cmd: "connect", - protocolId: "MQTT", // Or "MQIsdp" in MQTT 3.1 and 5.0 - protocolVersion: VERSION, // Or 3 in MQTT 3.1, or 5 in MQTT 5.0 - clean: true, // Can also be false - clientId: process.env.MQTT_CLIENT_ID, - keepalive: 10, // Seconds which can be any positive number, with 0 as the default setting - /* - will: { - topic: "mydevice/test", - payload: Buffer.from("2134f"), // Payloads are buffers - - } - */ - }); + logger.verbose("Connect to broker..."); - ws.send(data); + let data = mqtt.generate({ + cmd: "connect", + protocolId: "MQTT", + protocolVersion: VERSION, + clean: true, + clientId: process.env.MQTT_CLIENT_ID, + keepalive: 10, + }); - events.once("connack", (packet) => { - if (packet.returnCode === 0) { + ws.send(data, () => { + parser.once("packet", ({ cmd, returnCode }) => { + if (cmd === "connack" && returnCode === 0) { - events.once("suback", () => { + // feedback + logger.debug("Connected to broker"); - logger.debug("Subscribed to topic #"); + resolve(); - let ping = mqtt.generate({ - cmd: "pingreq" + } else { + reject(new Error(exitCodes[returnCode])); + } }); + }); - interval = setInterval(() => { - ws.send(ping); - }, Number(process.env.MQTT_PING_INTERVAL)); - - // monkey patch publisher function - scope.items.forEach((item) => { - item._publisher = (payload) => { - - scope.logger.verbose(`Publish on topic ${item.topic}`, payload); + }); - let pub = mqtt.generate({ - cmd: "publish", - messageId: crypto.randomInt(0, 65535), - qos: 0, - dup: false, - topic: item.topic, - payload: Buffer.from(`${payload}`), - retain: false - }); - ws.send(pub); + // subscribe to # topic + // so we can handle all topics + await new Promise((resolve, reject) => { - }; - }); + // feedback + logger.verbose("[MQTT] Subscribe to # topic..."); - }); - - let sub = mqtt.generate({ + let data = mqtt.generate({ cmd: "subscribe", messageId: crypto.randomInt(0, 65535), - /* - properties: { // MQTT 5.0 properties - subscriptionIdentifier: 145, - userProperties: { - test: "shellies" - } - }, - */ subscriptions: [{ topic: "#", + //topic: "#", qos: 0, nl: false, // no Local MQTT 5.0 flag rap: true, // Retain as Published MQTT 5.0 flag @@ -114,37 +93,102 @@ module.exports = (scope) => { }] }); - ws.send(sub); + ws.send(data, () => { + parser.once("packet", ({ cmd, granted }) => { + if (cmd === "suback" && granted[0] === 0) { - } - }); + // feedback + logger.debug("Subscribed to # topic"); - }); + resolve(); + } else { + reject(new Error("Subscription not granted")); + } + }); + }); - parser.on("packet", (packet) => { + }); - logger.verbose("Packet received", packet); - if (packet.cmd === "connack") { - if (packet.returnCode == 0) { + // monkey patch/override publisher function + // on mqtt item topics with current connection + await new Promise((resolve) => { - logger.debug("Connected to broker"); + items.forEach((item) => { + item._publisher = (payload, options = {}) => { - } else { + // feedback + logger.verbose(`Publish on topic ${item.topic}`, payload); - logger.warn(`Could not connecto to broker: "${exitCodes[packet.returnCode]}"`); + let pub = mqtt.generate({ + cmd: "publish", + messageId: crypto.randomInt(0, 65535), + qos: 0, + dup: false, + topic: item.topic, + payload: Buffer.from(payload), + retain: false, + ...options + }); + + ws.send(pub, () => { + + // feedback + // log self send published messages for debugging + logger.trace(`Send publish: ${item.topic}=${payload}`); + + }); + + }; + }); + + resolve(); + + }); + + + // listen for publishes and other packates + // send ping requests regulary to broker + await new Promise((resolve) => { + + let ping = mqtt.generate({ + cmd: "pingreq" + }); + + interval = setInterval(() => { + ws.send(ping); + }, Number(process.env.MQTT_PING_INTERVAL)); + + resolve(); + + }); + + } catch (err) { + + // feedback + logger.error(err, "Could not setup MQTT broker handling"); - } } + }); + + + // listen for disconnects from the connector + // clear the ping requests intveral, cant reach broker + events.once("disconnected", () => { + clearInterval(interval); + }); - events.emit(packet.cmd, packet); + // re-emit events on component scope/events + parser.on("packet", (packet) => { + scope.events.emit(packet.cmd, packet); }); - events.on("message", (message) => { - parser.parse(message); + // handle messages from the websockt as mqtt packets + events.on("message", (msg) => { + parser.parse(msg); }); }); From 18cc96246c500fef30970d4502bf05aec8d25d76 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 25 Jan 2024 11:24:38 +0100 Subject: [PATCH 111/186] remove unecessary `console.log(...)` --- routes/router.api.mqtt.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/routes/router.api.mqtt.js b/routes/router.api.mqtt.js index 20a46a6..8f8fad3 100644 --- a/routes/router.api.mqtt.js +++ b/routes/router.api.mqtt.js @@ -36,8 +36,6 @@ module.exports = (app, router) => { // http route handler router.get("/", (req, res, next) => { - console.log("Request to /ai/mqtt"); - // check if connection is a simple get request or ws client if ((!req.headers["upgrade"] || !req.headers["connection"])) { //return res.status(403).end(); @@ -56,7 +54,6 @@ module.exports = (app, router) => { }); ws.on("close", () => { - console.log("MQTT Client disconnected disolaskjdflaskjfdasdf"); C_MQTT.events.emit("disconnected", ws); }); From 5f56aaf853239a975ee2bdf48d5254b2d71c03ef Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 25 Jan 2024 14:28:20 +0100 Subject: [PATCH 112/186] fix #425 --- routes/router.api.mqtt.js | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/routes/router.api.mqtt.js b/routes/router.api.mqtt.js index 8f8fad3..da3323a 100644 --- a/routes/router.api.mqtt.js +++ b/routes/router.api.mqtt.js @@ -33,6 +33,23 @@ module.exports = (app, router) => { }); + // listen for websockt clients + // forward messages between component & ws client + wss.once("connection", (ws) => { + + C_MQTT.events.emit("connected", ws); + + ws.on("message", (msg) => { + C_MQTT.events.emit("message", msg); + }); + + ws.on("close", () => { + C_MQTT.events.emit("disconnected", ws); + }); + + }); + + // http route handler router.get("/", (req, res, next) => { @@ -43,22 +60,6 @@ module.exports = (app, router) => { return; } - // listen for websockt clients - // keep sending new log entrys to client - wss.once("connection", (ws) => { - - C_MQTT.events.emit("connected", ws); - - ws.on("message", (msg) => { - C_MQTT.events.emit("message", msg); - }); - - ws.on("close", () => { - C_MQTT.events.emit("disconnected", ws); - }); - - }); - // handle request as websocket // perform websocket handshake wss.handleUpgrade(req, req.socket, req.headers, (ws) => { From 35852a62e7fd8165e9c086d86eb4cff12a86affa Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 25 Jan 2024 16:55:52 +0100 Subject: [PATCH 113/186] `console.log(...)` removed --- routes/router.auth.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/routes/router.auth.js b/routes/router.auth.js index e9d9cce..6c3f485 100644 --- a/routes/router.auth.js +++ b/routes/router.auth.js @@ -4,9 +4,6 @@ const C_USERS = require("../components/users"); module.exports = (app, router) => { router.get("/", (req, res) => { - - console.log("/auth request from:", req.ip); - if (process.env.API_AUTH_ENABLED === "true") { // override header header token with query token @@ -41,7 +38,6 @@ module.exports = (app, router) => { res.status(200).end(); } - }); router.post("/login", (req, res) => { From 5d3160377f5036823d7129843de7f2422b1cb21a Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 25 Jan 2024 17:14:37 +0100 Subject: [PATCH 114/186] fix #423 --- components/devices/class.device.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/devices/class.device.js b/components/devices/class.device.js index 230c467..0205f8c 100644 --- a/components/devices/class.device.js +++ b/components/devices/class.device.js @@ -78,7 +78,7 @@ module.exports = class Device extends Item { room: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).allow(null).default(null), enabled: Joi.boolean().default(true), //interfaces: Joi.array().items(Interface.schema()).min(1).required() - interfaces: Joi.array().min(1).items(Interface.schema()).required(), + interfaces: Joi.array().items(Interface.schema()).default([]), meta: { manufacturer: Joi.string().allow(null).default(null), model: Joi.string().allow(null).default(null), From 786008fca5e4755dbf1ec72f9171b50c04596a0d Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 30 Jan 2024 08:40:15 +0100 Subject: [PATCH 115/186] removed `console.log(...)` --- routes/router.api.mdns.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/routes/router.api.mdns.js b/routes/router.api.mdns.js index 60774b4..0a14b6e 100644 --- a/routes/router.api.mdns.js +++ b/routes/router.api.mdns.js @@ -50,8 +50,6 @@ module.exports = (app, router) => { // TODO: Reformat to match router.api.mdns.js code style/if-else router.get("/", (req, res, next) => { - console.log("Request to /api/mdns"); - // check if connection is a simple get request or ws client if ((!req.headers["upgrade"] || !req.headers["connection"])) { //return res.status(403).end(); @@ -63,18 +61,12 @@ module.exports = (app, router) => { // keep sending new log entrys to client wss.once("connection", (ws) => { - console.log("Clien connected to mdns"); - C_MDNS.events.emit("connected", ws); ws.on("message", (msg) => { C_MDNS.events.emit("message", decode(msg), msg); }); - ws.on("close", () => { - console.log("Client disconnected disolaskjdflaskjfdasdf"); - }); - // QUERY LOCAL DNS /* From 197ad4c0e480b29f8a26206b8c7f1bb15326cd4a Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 30 Jan 2024 18:03:36 +0100 Subject: [PATCH 116/186] fix #430 --- .github/workflows/node-js.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/node-js.yml b/.github/workflows/node-js.yml index 75a0112..71ac8c0 100644 --- a/.github/workflows/node-js.yml +++ b/.github/workflows/node-js.yml @@ -27,7 +27,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - node-version: [16.x, 17.x, 18.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + node-version: [18.x, 20x], # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ mongodb-version: ["4.2", "4.4", "5.0"] steps: From 95be13ad5ffa25b296653a0d52041a5ae2906399 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 30 Jan 2024 18:04:54 +0100 Subject: [PATCH 117/186] fix workflow file syntax --- .github/workflows/node-js.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/node-js.yml b/.github/workflows/node-js.yml index 71ac8c0..0180628 100644 --- a/.github/workflows/node-js.yml +++ b/.github/workflows/node-js.yml @@ -27,7 +27,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - node-version: [18.x, 20x], # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + node-version: [18.x, 20.x], # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ mongodb-version: ["4.2", "4.4", "5.0"] steps: From d0668c24cb7e8f7413dac6cf4e1c8af784deac67 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 30 Jan 2024 18:06:04 +0100 Subject: [PATCH 118/186] fix workflow file --- .github/workflows/node-js.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/node-js.yml b/.github/workflows/node-js.yml index 0180628..0b92e2e 100644 --- a/.github/workflows/node-js.yml +++ b/.github/workflows/node-js.yml @@ -27,7 +27,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - node-version: [18.x, 20.x], # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + node-version: [18.x, 20.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ mongodb-version: ["4.2", "4.4", "5.0"] steps: From bb86465809084e0f49f88224be223c7740447a86 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 30 Jan 2024 18:11:50 +0100 Subject: [PATCH 119/186] fix #430 --- .github/workflows/docker-nightly.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-nightly.yml b/.github/workflows/docker-nightly.yml index 90d4c50..751847c 100644 --- a/.github/workflows/docker-nightly.yml +++ b/.github/workflows/docker-nightly.yml @@ -13,10 +13,10 @@ jobs: - name: Check out the repo uses: actions/checkout@v3 - - name: Use Node.js 16.x + - name: Use Node.js 18.x uses: actions/setup-node@v3 with: - node-version: 16.x + node-version: 18.x - run: npm ci - run: npm run build From 9a8ac0e0b7fc421482681fdc3a5b06ff9ddb6d90 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 31 Jan 2024 10:24:10 +0100 Subject: [PATCH 120/186] `TODO` added, see #426 --- routes/router.api.mdns.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/routes/router.api.mdns.js b/routes/router.api.mdns.js index 0a14b6e..9c76e87 100644 --- a/routes/router.api.mdns.js +++ b/routes/router.api.mdns.js @@ -59,6 +59,8 @@ module.exports = (app, router) => { // listen for websockt clients // keep sending new log entrys to client + // TODO: Move this outside the get handler + // see: #426 wss.once("connection", (ws) => { C_MDNS.events.emit("connected", ws); @@ -69,6 +71,7 @@ module.exports = (app, router) => { // QUERY LOCAL DNS + // TODO: Move this into the mdns component /* setInterval(() => { From 9502638f2d0479825bfdcd1ad317587d6527d5ac Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 31 Jan 2024 10:24:49 +0100 Subject: [PATCH 121/186] Signal handling and error message improved --- index.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index ce61883..682f7b5 100644 --- a/index.js +++ b/index.js @@ -54,7 +54,7 @@ process.env = Object.assign({ USERS_BCRYPT_SALT_ROUNDS: "12", USERS_JWT_SECRET: "", USERS_JWT_ALGORITHM: "HS384", - MQTT_BROKER_VERSION: "3", + MQTT_BROKER_VERSION: "4", MQTT_CLIENT_ID: "OpenHaus", MQTT_PING_INTERVAL: "5000" }, env.parsed, process.env); @@ -253,7 +253,7 @@ const starter = new Promise((resolve) => { } catch (err) { - logger.warn(`Could not boot plugin "${plugin.name}" (${plugin.uuid})`); + logger.error(err, `Could not boot plugin "${plugin.name}" (${plugin.uuid})`); } }); @@ -266,8 +266,12 @@ const starter = new Promise((resolve) => { logger.info("Startup complete"); - process.once("SIGINT", () => { - logger.warn("Shuting down..."); + ["SIGINT", "SIGTERM", "SIGQUIT"].forEach((signal) => { + process.once(signal, () => { + + logger.warn("Shuting down..."); + + }); }); }); From 666a90d08cc4a181111be0840a07de56cc02c5aa Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 31 Jan 2024 10:26:12 +0100 Subject: [PATCH 122/186] note for #331 added --- system/logger/class.logger.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/system/logger/class.logger.js b/system/logger/class.logger.js index da11f45..e5fec58 100644 --- a/system/logger/class.logger.js +++ b/system/logger/class.logger.js @@ -62,6 +62,21 @@ module.exports = class Logger { } else { + // fix #331 + // NOTE: here could be a level specific options + // e.g. for "verbose", set "showProxy" or "getters" + // https://nodejs.org/docs/latest/api/util.html#utilinspectobject-showhidden-depth-colors + // optinal configurable with environment variable like "LOGGER_INSPECT_OPTIONS" or so... + /* + args = args.map((arg) => { + //return JSON.stringify(arg, null, 2); + return util.inspect(arg, { + depth: null, + colors: true, + }); + }); + */ + //obj.message = args.shift(); obj.message = util.format(...args); //obj.fields = args; From c016972afb2e23bada33f3454adffbd53c144819 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 31 Jan 2024 10:35:23 +0100 Subject: [PATCH 123/186] improve router/signal handling --- routes/index.js | 393 +++++++++++++++----------------- system/init/init.http-server.js | 48 +++- 2 files changed, 222 insertions(+), 219 deletions(-) diff --git a/routes/index.js b/routes/index.js index 15d7bab..a3b42ac 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,4 +1,3 @@ -const { ServerResponse } = require("http"); const express = require("express"); const bodyParser = require("body-parser"); @@ -37,228 +36,204 @@ function sanitize(v) { return v; } -module.exports = (server) => { - const app = express(); - const auth = express.Router(); - const api = express.Router(); - const logs = express.Router(); - const about = express.Router(); - //const system = express.Router(); - - // https://expressjs.com/en/guide/behind-proxies.html - app.set("trust proxy", [ - "loopback", - "linklocal", - "uniquelocal" - ]); - - // fix #409 - // add logging for http requests - app.use((req, res, next) => { - - // log basic http requests, do not reveal any senstive information - // thats why "req.path" is used instead of "req.url" - log.debug(`${req.ip} - [${req.method}] ${req.path}`); - - // log verbose requests - // this may reveal senstive informations like tokens or cookies - log.verbose(JSON.stringify({ - query: req.query, - params: req.params, - headers: req.headers - })); +const app = express(); +const auth = express.Router(); +const api = express.Router(); +const logs = express.Router(); +const about = express.Router(); +//const system = express.Router(); + +// https://expressjs.com/en/guide/behind-proxies.html +app.set("trust proxy", [ + "loopback", + "linklocal", + "uniquelocal" +]); + +// fix #409 +// add logging for http requests +app.use((req, res, next) => { + + // log basic http requests, do not reveal any senstive information + // thats why "req.path" is used instead of "req.url" + log.debug(`${req.ip} - [${req.method}] ${req.path}`); + + // log verbose requests + // this may reveal senstive informations like tokens or cookies + log.verbose(JSON.stringify({ + query: req.query, + params: req.params, + headers: req.headers + })); - next(); + next(); - }); +}); - app.use(bodyParser.json({ - limit: (Number(process.env.API_LIMIT_SIZE) * 1024) // default to 25, (=25mb) - })); +app.use(bodyParser.json({ + limit: (Number(process.env.API_LIMIT_SIZE) * 1024) // default to 25, (=25mb) +})); - // mount api router - app.use("/api", api); +// mount api router +app.use("/api", api); - // mount auth router - app.use("/auth", auth); - require("./router.auth.js")(app, auth); +// mount auth router +app.use("/auth", auth); +require("./router.auth.js")(app, auth); - // mount logs router under /api - // TODO move to /system/logs - api.use("/logs", logs); - require("./router.api.logs.js")(app, logs); +// mount logs router under /api +// TODO move to /system/logs +api.use("/logs", logs); +require("./router.api.logs.js")(app, logs); - // mount logs router under /api - // TODO remove - api.use("/about", about); - require("./router.api.about.js")(app, about); +// mount logs router under /api +// TODO remove +api.use("/about", about); +require("./router.api.about.js")(app, about); - //app.use("/system", system); - //require("./router.system.notifications.js")(app, system); +//app.use("/system", system); +//require("./router.system.notifications.js")(app, system); - // /api routes - (() => { - // ensure that all requests to /api are authenticated - // req.user = User item from component user - require("./auth-handler.js")(C_USERS, api); +// ensure that all requests to /api are authenticated +// req.user = User item from component user +require("./auth-handler.js")(C_USERS, api); - // serailize api input fields - api.use((req, res, next) => { +// serailize api input fields +api.use((req, res, next) => { - /* - // HTTP header should be set only for PUT and POST requests. So it can be ignored completly?! - if (!req.headers["content-type"]?.includes("application/json")) { - return res.status(415).end(); - } - */ - - // strip out any keys that start with "$" - req.body = sanitize(req.body); + /* + // HTTP header should be set only for PUT and POST requests. So it can be ignored completly?! + if (!req.headers["content-type"]?.includes("application/json")) { + return res.status(415).end(); + } + */ - // sanitze api input fields? - /* - // removed, breaks endpoints command payload - // see #273 - if (!(process.env.API_SANITIZE_INPUT === "true" && req.body)) { - return next(); - } - */ - - // patch/override sanitized object - /* - // removed, breaks endpoints command payload - // see #273 - req.body = iterate(req.body, (key, value, type) => { - // ignore device key in settings - // see #127, currently i have no petter idea - // be sure that we only ignore the device properety in the settings object - if (type === "string" && !(key === "device" && req.body?.interfaces?.some(o => o?.settings?.device === value))) { - return encode(value); - } else { - return value; - } - }); - */ - - next(); - - }); - - - // https://learning.postman.com/docs/writing-scripts/test-scripts/ - - - // define sub router for api/component routes - const pluginsRouter = express.Router(); - const roomsRouter = express.Router(); - const devicesRouter = express.Router(); - const endpointsRouter = express.Router(); - const vaultRouter = express.Router(); - const scenesRouter = express.Router(); - const eventsRouter = express.Router(); - const ssdpRouter = express.Router(); - const storeRouter = express.Router(); - const usersRouter = express.Router(); - const webhooksRouter = express.Router(); - const mqttRouter = express.Router(); - const mdnsRouter = express.Router(); - - // http://127.0.0.1/api/plugins - api.use("/plugins", pluginsRouter); - require("./rest-handler.js")(C_PLUGINS, pluginsRouter); - require("./router.api.plugins.js")(app, pluginsRouter); - - // http://127.0.0.1/api/rooms - api.use("/rooms", roomsRouter); - require("./rest-handler.js")(C_ROOMS, roomsRouter); - - // http://127.0.0.1/api/devices - api.use("/devices", devicesRouter); - require("./rest-handler.js")(C_DEVICES, devicesRouter); - require("./router.api.devices.js")(app, devicesRouter); - - // http://127.0.0.1/api/endpoints - api.use("/endpoints", endpointsRouter); - require("./rest-handler.js")(C_ENDPOINTS, endpointsRouter); - require("./router.api.endpoints.js")(app, endpointsRouter); - - // http://127.0.0.1/api/vaults - api.use("/vault", vaultRouter); - require("./rest-handler.js")(C_VAULT, vaultRouter); - require("./router.api.vault.js")(app, vaultRouter); - - // http://127.0.0.1/api/scenes - api.use("/scenes", scenesRouter); - require("./rest-handler.js")(C_SCENES, scenesRouter); - require("./router.api.scenes.js")(app, scenesRouter); - - // http://127.0.0.1/api/events - api.use("/events", eventsRouter); - require("./router.api.events.js")(app, eventsRouter); - - // http://127.0.0.1/api/ssdp - api.use("/ssdp", ssdpRouter); - require("./router.api.ssdp.js")(app, ssdpRouter); - require("./rest-handler.js")(C_SSDP, ssdpRouter); - - // http://127.0.0.1/api/store - api.use("/store", storeRouter); - require("./rest-handler.js")(C_STORE, storeRouter); - require("./router.api.store.js")(app, storeRouter); - - // http://127.0.0.1/api/users - api.use("/users", usersRouter); - require("./rest-handler.js")(C_USERS, usersRouter); - //require("./router.api.users.js")(app, vaultRouter); - - // http://127.0.0.1/api/webhooks - api.use("/webhooks", webhooksRouter); - require("./router.api.webhooks.js")(app, webhooksRouter); - require("./rest-handler.js")(C_WEBHOOKS, webhooksRouter); - - // http://127.0.0.1/api/mqtt - api.use("/mqtt", mqttRouter); - require("./router.api.mqtt.js")(app, mqttRouter); - require("./rest-handler.js")(C_MQTT, mqttRouter); - - // http://127.0.0.1/api/mdns - api.use("/mdns", mdnsRouter); - require("./router.api.mdns.js")(app, mdnsRouter); - require("./rest-handler.js")(C_MDNS, mdnsRouter); - - // NOTE: Drop this?! - api.use((req, res) => { - res.status(404).end(); - /* - res.status(404).json({ - error: "Hmm... :/ This looks not right.", - message: `Url/endpoint "${req.url}" not found"` - }); - */ - }); - - - })(); - - // use express request handler - server.on("request", app); - - // fix #408, see: - // https://github.com/OpenHausIO/connector/issues/38 - // https://github.com/websockets/ws/issues/2193 - server.on("upgrade", (req, socket) => { - - let res = new ServerResponse(req); - res.assignSocket(socket); - - res.on("finish", () => { - res.socket.destroy(); - }); - - app(req, res); + // strip out any keys that start with "$" + req.body = sanitize(req.body); + // sanitze api input fields? + /* + // removed, breaks endpoints command payload + // see #273 + if (!(process.env.API_SANITIZE_INPUT === "true" && req.body)) { + return next(); + } + */ + + // patch/override sanitized object + /* + // removed, breaks endpoints command payload + // see #273 + req.body = iterate(req.body, (key, value, type) => { + // ignore device key in settings + // see #127, currently i have no petter idea + // be sure that we only ignore the device properety in the settings object + if (type === "string" && !(key === "device" && req.body?.interfaces?.some(o => o?.settings?.device === value))) { + return encode(value); + } else { + return value; + } + }); + */ + + next(); + +}); + + +// https://learning.postman.com/docs/writing-scripts/test-scripts/ + + +// define sub router for api/component routes +const pluginsRouter = express.Router(); +const roomsRouter = express.Router(); +const devicesRouter = express.Router(); +const endpointsRouter = express.Router(); +const vaultRouter = express.Router(); +const scenesRouter = express.Router(); +const eventsRouter = express.Router(); +const ssdpRouter = express.Router(); +const storeRouter = express.Router(); +const usersRouter = express.Router(); +const webhooksRouter = express.Router(); +const mqttRouter = express.Router(); +const mdnsRouter = express.Router(); + +// http://127.0.0.1/api/plugins +api.use("/plugins", pluginsRouter); +require("./rest-handler.js")(C_PLUGINS, pluginsRouter); +require("./router.api.plugins.js")(app, pluginsRouter); + +// http://127.0.0.1/api/rooms +api.use("/rooms", roomsRouter); +require("./rest-handler.js")(C_ROOMS, roomsRouter); + +// http://127.0.0.1/api/devices +api.use("/devices", devicesRouter); +require("./rest-handler.js")(C_DEVICES, devicesRouter); +require("./router.api.devices.js")(app, devicesRouter); + +// http://127.0.0.1/api/endpoints +api.use("/endpoints", endpointsRouter); +require("./rest-handler.js")(C_ENDPOINTS, endpointsRouter); +require("./router.api.endpoints.js")(app, endpointsRouter); + +// http://127.0.0.1/api/vaults +api.use("/vault", vaultRouter); +require("./rest-handler.js")(C_VAULT, vaultRouter); +require("./router.api.vault.js")(app, vaultRouter); + +// http://127.0.0.1/api/scenes +api.use("/scenes", scenesRouter); +require("./rest-handler.js")(C_SCENES, scenesRouter); +require("./router.api.scenes.js")(app, scenesRouter); + +// http://127.0.0.1/api/events +api.use("/events", eventsRouter); +require("./router.api.events.js")(app, eventsRouter); + +// http://127.0.0.1/api/ssdp +api.use("/ssdp", ssdpRouter); +require("./router.api.ssdp.js")(app, ssdpRouter); +require("./rest-handler.js")(C_SSDP, ssdpRouter); + +// http://127.0.0.1/api/store +api.use("/store", storeRouter); +require("./rest-handler.js")(C_STORE, storeRouter); +require("./router.api.store.js")(app, storeRouter); + +// http://127.0.0.1/api/users +api.use("/users", usersRouter); +require("./rest-handler.js")(C_USERS, usersRouter); +//require("./router.api.users.js")(app, vaultRouter); + +// http://127.0.0.1/api/webhooks +api.use("/webhooks", webhooksRouter); +require("./router.api.webhooks.js")(app, webhooksRouter); +require("./rest-handler.js")(C_WEBHOOKS, webhooksRouter); + +// http://127.0.0.1/api/mqtt +api.use("/mqtt", mqttRouter); +require("./router.api.mqtt.js")(app, mqttRouter); +require("./rest-handler.js")(C_MQTT, mqttRouter); + +// http://127.0.0.1/api/mdns +api.use("/mdns", mdnsRouter); +require("./router.api.mdns.js")(app, mdnsRouter); +require("./rest-handler.js")(C_MDNS, mdnsRouter); + +// NOTE: Drop this?! +api.use((req, res) => { + res.status(404).end(); + /* + res.status(404).json({ + error: "Hmm... :/ This looks not right.", + message: `Url/endpoint "${req.url}" not found"` }); + */ +}); + -}; \ No newline at end of file +module.exports = app; \ No newline at end of file diff --git a/system/init/init.http-server.js b/system/init/init.http-server.js index 5ae1689..a1a4260 100644 --- a/system/init/init.http-server.js +++ b/system/init/init.http-server.js @@ -52,7 +52,7 @@ module.exports = (logger) => { // and pass/move the request handler here // thus prevents to create 2 express apps for each server // "routes/index.js" should export the express app - require("../../routes/index.js")(server); + //require("../../routes/index.js")(server); // bind/start http server server.listen(Number(process.env.HTTP_PORT), process.env.HTTP_ADDRESS); @@ -102,7 +102,7 @@ module.exports = (logger) => { // and pass/move the request handler here // thus prevents to create 2 express apps for each server // "routes/index.js" should export the express app - require("../../routes/index.js")(server); + //require("../../routes/index.js")(server); try { @@ -131,16 +131,44 @@ module.exports = (logger) => { Promise.all(servers).then((servers) => { - process.once("SIGINT", () => { + // require express main router + let app = require("../../routes/index.js"); - // see #345 - // close all active http sockets/requests - for (const socket of sockets.values()) { - socket.destroy(); - } + ["SIGINT", "SIGTERM", "SIGQUIT"].forEach((signal) => { + process.once(signal, () => { + + // see #345 + // close all active http sockets/requests + for (const socket of sockets.values()) { + socket.destroy(); + } + + servers.forEach((server) => { + server.close(); + }); + + }); + }); + + servers.forEach((server) => { + + // use express request handler + server.on("request", app); + + // fix #408, see: + // https://github.com/OpenHausIO/connector/issues/38 + // https://github.com/websockets/ws/issues/2193 + server.on("upgrade", (req, socket) => { + + let res = new http.ServerResponse(req); + res.assignSocket(socket); + + res.on("finish", () => { + res.socket.destroy(); + }); + + app(req, res); - servers.forEach((server) => { - server.close(); }); }); From 6acdc25654f43f574b6250df7fb17af1d1884c5b Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 31 Jan 2024 11:23:48 +0100 Subject: [PATCH 124/186] version updated --- .github/workflows/docker-nightly.yml | 10 +++++----- .github/workflows/node-js.yml | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/docker-nightly.yml b/.github/workflows/docker-nightly.yml index 751847c..c8b8494 100644 --- a/.github/workflows/docker-nightly.yml +++ b/.github/workflows/docker-nightly.yml @@ -11,29 +11,29 @@ jobs: if: github.repository == 'OpenHausIO/backend' steps: - name: Check out the repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Use Node.js 18.x - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 18.x - run: npm ci - run: npm run build - name: Log in to Docker Hub - uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a + uses: docker/login-action@v3.0.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta - uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + uses: docker/metadata-action@v5.5.0 with: images: openhaus/backend - name: Build and push Docker image - uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 + uses: docker/build-push-action@v5.1.0 with: context: . file: ./Dockerfile diff --git a/.github/workflows/node-js.yml b/.github/workflows/node-js.yml index 0b92e2e..73183a7 100644 --- a/.github/workflows/node-js.yml +++ b/.github/workflows/node-js.yml @@ -27,11 +27,11 @@ jobs: strategy: matrix: os: [ubuntu-latest] - node-version: [18.x, 20.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + node-version: [16.x, 18.x, 20.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ mongodb-version: ["4.2", "4.4", "5.0"] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 # mongodb setup - name: Start MongoDB @@ -41,7 +41,7 @@ jobs: # node.js setup - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: "npm" From 3e5f9b83e99fc5ad2174839671a7beff2b340875 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 1 Feb 2024 14:59:44 +0100 Subject: [PATCH 125/186] restored, see #434 --- .github/workflows/node-js.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/node-js.yml b/.github/workflows/node-js.yml index 73183a7..b3f6f95 100644 --- a/.github/workflows/node-js.yml +++ b/.github/workflows/node-js.yml @@ -27,11 +27,11 @@ jobs: strategy: matrix: os: [ubuntu-latest] - node-version: [16.x, 18.x, 20.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + node-version: [16.x, 17.x, 18.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ mongodb-version: ["4.2", "4.4", "5.0"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v2 # mongodb setup - name: Start MongoDB @@ -41,7 +41,7 @@ jobs: # node.js setup - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 + uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} cache: "npm" @@ -49,3 +49,4 @@ jobs: - run: npm run build --if-present - run: npm run lint - run: npm test + \ No newline at end of file From a4271ea912ecc325d63c999545a687c2144307bc Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 1 Feb 2024 15:17:22 +0100 Subject: [PATCH 126/186] updated --- .github/workflows/node-js.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/node-js.yml b/.github/workflows/node-js.yml index b3f6f95..73183a7 100644 --- a/.github/workflows/node-js.yml +++ b/.github/workflows/node-js.yml @@ -27,11 +27,11 @@ jobs: strategy: matrix: os: [ubuntu-latest] - node-version: [16.x, 17.x, 18.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + node-version: [16.x, 18.x, 20.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ mongodb-version: ["4.2", "4.4", "5.0"] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 # mongodb setup - name: Start MongoDB @@ -41,7 +41,7 @@ jobs: # node.js setup - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: "npm" @@ -49,4 +49,3 @@ jobs: - run: npm run build --if-present - run: npm run lint - run: npm test - \ No newline at end of file From 8f61a16bf30086cac1e86c31e27fd67414efa7e0 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 1 Feb 2024 15:17:42 +0100 Subject: [PATCH 127/186] fix #435 --- index.js | 3 ++- system/init/init.http-server.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 682f7b5..ff4aadf 100644 --- a/index.js +++ b/index.js @@ -266,7 +266,8 @@ const starter = new Promise((resolve) => { logger.info("Startup complete"); - ["SIGINT", "SIGTERM", "SIGQUIT"].forEach((signal) => { + // fix #435 + ["SIGINT", /*"SIGTERM", "SIGQUIT"*/].forEach((signal) => { process.once(signal, () => { logger.warn("Shuting down..."); diff --git a/system/init/init.http-server.js b/system/init/init.http-server.js index a1a4260..153e7c1 100644 --- a/system/init/init.http-server.js +++ b/system/init/init.http-server.js @@ -134,7 +134,8 @@ module.exports = (logger) => { // require express main router let app = require("../../routes/index.js"); - ["SIGINT", "SIGTERM", "SIGQUIT"].forEach((signal) => { + // fix #435 + ["SIGINT", /*"SIGTERM", "SIGQUIT"*/].forEach((signal) => { process.once(signal, () => { // see #345 From 3a9b5245502400dd3600f11a2cbaf75e59815bc3 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 13 Feb 2024 13:13:32 +0100 Subject: [PATCH 128/186] fix #387 --- components/endpoints/class.command.js | 3 ++- components/endpoints/class.params.js | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 components/endpoints/class.params.js diff --git a/components/endpoints/class.command.js b/components/endpoints/class.command.js index 77bfe26..02814f4 100644 --- a/components/endpoints/class.command.js +++ b/components/endpoints/class.command.js @@ -5,6 +5,7 @@ const _timeout = require("../../helper/timeout.js"); const { interfaces } = require("../../system/shared.js"); const Param = require("./class.param.js"); +const Params = require("./class.params.js"); /** * @description @@ -248,7 +249,7 @@ module.exports = class Command { // handle timeout stuff here? // when so, timeout applys to custom functions too! - worker.call(this, this, iface, params, timer); + worker.call(this, this, iface, new Params(...params), timer); } diff --git a/components/endpoints/class.params.js b/components/endpoints/class.params.js new file mode 100644 index 0000000..489cbe6 --- /dev/null +++ b/components/endpoints/class.params.js @@ -0,0 +1,14 @@ +module.exports = class Params extends Array { + + constructor(...args) { + super(...args); + } + + lean() { + return this.reduce((obj, { key, value }) => { + obj[key] = value; + return obj; + }, {}); + } + +}; \ No newline at end of file From a94e94ac4042fe7f6521b285e6e491d21ea20fe0 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 13 Feb 2024 13:15:41 +0100 Subject: [PATCH 129/186] improved param type handling --- components/endpoints/class.command.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/components/endpoints/class.command.js b/components/endpoints/class.command.js index 02814f4..f66caa8 100644 --- a/components/endpoints/class.command.js +++ b/components/endpoints/class.command.js @@ -212,6 +212,10 @@ module.exports = class Command { return param.key === key; }); + if (!param) { + return false; + } + // auto convert "123" to 123 if (param.type === "number") { value = Number(value); @@ -228,8 +232,8 @@ module.exports = class Command { } if (!valid) { - let err = new Error(`Invalid params type`); - err.code = "INVALID_PARAMETER_TYPE"; + let err = new Error(`Invalid parameter`); + err.code = "INVALID_PARAMETER"; return cb(err); } From 80fd549aaddb008ae20f87db0fecf17787170289 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 13 Feb 2024 13:34:13 +0100 Subject: [PATCH 130/186] todo note added --- components/endpoints/class.command.js | 1 + 1 file changed, 1 insertion(+) diff --git a/components/endpoints/class.command.js b/components/endpoints/class.command.js index f66caa8..d68010f 100644 --- a/components/endpoints/class.command.js +++ b/components/endpoints/class.command.js @@ -234,6 +234,7 @@ module.exports = class Command { if (!valid) { let err = new Error(`Invalid parameter`); err.code = "INVALID_PARAMETER"; + // TODO: Should not be as second argument passed "false"?! return cb(err); } From 0b2c0d6a944329650e31e1ab7bcadce204b8cf05 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 13 Feb 2024 13:38:57 +0100 Subject: [PATCH 131/186] note added --- helper/timeout.js | 1 + 1 file changed, 1 insertion(+) diff --git a/helper/timeout.js b/helper/timeout.js index c55af87..2a84b87 100644 --- a/helper/timeout.js +++ b/helper/timeout.js @@ -58,6 +58,7 @@ function timeout(time, cb) { if (!called) { called = true; + // NOTE: Deconstructing/array recreating needed?! cb(false, Date.now() - start, [...args]); } From 77b6d544818e22d922c2c75e5a5a3872a8ac4ea4 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 13 Feb 2024 14:17:57 +0100 Subject: [PATCH 132/186] added "description" field to schema. see #429 --- components/vault/class.vault.js | 1 + 1 file changed, 1 insertion(+) diff --git a/components/vault/class.vault.js b/components/vault/class.vault.js index ba5477a..38443aa 100644 --- a/components/vault/class.vault.js +++ b/components/vault/class.vault.js @@ -85,6 +85,7 @@ module.exports = class Vault extends Item { }), name: Joi.string().required(), identifier: Joi.string().required(), + description: Joi.string().allow(null).default(null), secrets: Joi.array().items(Secret.schema()).default([]) }); } From c7946a56cc9bf6ef540182158ced1e26e77743c7 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 13 Feb 2024 14:40:06 +0100 Subject: [PATCH 133/186] see #426 --- routes/router.api.mdns.js | 73 +++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/routes/router.api.mdns.js b/routes/router.api.mdns.js index 9c76e87..93411be 100644 --- a/routes/router.api.mdns.js +++ b/routes/router.api.mdns.js @@ -46,54 +46,53 @@ module.exports = (app, router) => { }); - // http route handler - // TODO: Reformat to match router.api.mdns.js code style/if-else - router.get("/", (req, res, next) => { + // listen for websockt clients + // keep sending new log entrys to client + wss.once("connection", (ws) => { - // check if connection is a simple get request or ws client - if ((!req.headers["upgrade"] || !req.headers["connection"])) { - //return res.status(403).end(); - next(); // let the rest-handler.js do its job - return; - } + C_MDNS.events.emit("connected", ws); - // listen for websockt clients - // keep sending new log entrys to client - // TODO: Move this outside the get handler - // see: #426 - wss.once("connection", (ws) => { + ws.on("message", (msg) => { + C_MDNS.events.emit("message", decode(msg), msg); + }); - C_MDNS.events.emit("connected", ws); - ws.on("message", (msg) => { - C_MDNS.events.emit("message", decode(msg), msg); - }); + // QUERY LOCAL DNS + // TODO: Move this into the mdns component + /* + setInterval(() => { + + console.log("Query for HTTP Server"); + let msg = encode({ + type: "query", + id: 1, + flags: RECURSION_DESIRED, + questions: [{ + type: "A", + //name: '_http._tcp.local' + name: "*" + }] + }); - // QUERY LOCAL DNS - // TODO: Move this into the mdns component - /* - setInterval(() => { + ws.send(msg); - console.log("Query for HTTP Server"); + }, 30_000); + */ - let msg = encode({ - type: "query", - id: 1, - flags: RECURSION_DESIRED, - questions: [{ - type: "A", - //name: '_http._tcp.local' - name: "*" - }] - }); + }); - ws.send(msg); - }, 30_000); - */ + // http route handler + // TODO: Reformat to match router.api.mdns.js code style/if-else + router.get("/", (req, res, next) => { - }); + // check if connection is a simple get request or ws client + if ((!req.headers["upgrade"] || !req.headers["connection"])) { + //return res.status(403).end(); + next(); // let the rest-handler.js do its job + return; + } // handle request as websocket // perform websocket handshake From 949e356683f16494b73b6c2e927b751a59037b38 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 13 Feb 2024 14:57:05 +0100 Subject: [PATCH 134/186] `TODO` added, see #426 --- routes/router.api.devices.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/routes/router.api.devices.js b/routes/router.api.devices.js index 9b66b31..5ac6738 100644 --- a/routes/router.api.devices.js +++ b/routes/router.api.devices.js @@ -37,7 +37,12 @@ module.exports = (app, router) => { } else { - + // TODO: This should be moved into the device component + // A websocket server should be created in the class.interface.js file + // Static method can return them e.g. Interface.servers() = returns array of wss + // Goal should be: + // - to eliminate the need of "shared.js" + // - handle in router.get only ws handshake: "wss.handleUpgrade(...)" if (!interfaceServer.has(req.params._iid)) { let wss = new WebSocket.Server({ From 11b1fbd69fdc99a09c102149a288af236a1607a5 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 29 Feb 2024 12:29:21 +0100 Subject: [PATCH 135/186] run only on merged pr's --- .github/workflows/docker-nightly.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-nightly.yml b/.github/workflows/docker-nightly.yml index c8b8494..bf93b7e 100644 --- a/.github/workflows/docker-nightly.yml +++ b/.github/workflows/docker-nightly.yml @@ -1,14 +1,14 @@ name: Publish Docker nightly image on: - push: + pull_request: branches: [dev] jobs: push_to_registry: name: Push Docker image to Docker Hub runs-on: ubuntu-latest - if: github.repository == 'OpenHausIO/backend' + if: github.repository == 'OpenHausIO/backend' && github.event.pull_request.merged == true steps: - name: Check out the repo uses: actions/checkout@v4 From b05a5080e8915eb2e42dd8808a4126732c234a93 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 29 Feb 2024 12:40:02 +0100 Subject: [PATCH 136/186] trigger changed --- .github/workflows/docker-nightly.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-nightly.yml b/.github/workflows/docker-nightly.yml index bf93b7e..a4be7b7 100644 --- a/.github/workflows/docker-nightly.yml +++ b/.github/workflows/docker-nightly.yml @@ -1,8 +1,11 @@ name: Publish Docker nightly image on: - pull_request: - branches: [dev] + pull_request: + types: + - closed + branches: + - dev jobs: push_to_registry: From 7b9b80e3075d81db586d923d7e013fd042dffb38 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sat, 13 Apr 2024 21:23:44 +0200 Subject: [PATCH 137/186] fix #403 (remaining tasks) --- routes/router.api.events.js | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/routes/router.api.events.js b/routes/router.api.events.js index 0b3bfdb..38503e7 100644 --- a/routes/router.api.events.js +++ b/routes/router.api.events.js @@ -55,9 +55,19 @@ module.exports = (app, router) => { wss.clients.forEach((client) => { // fix #403 "Implement named subscriptions" - if (client.intents.includes(event) && client.readyState === WebSocket.OPEN) { + // added component name intents + /* + if (client.intents.includes(event) /*&& client.components.includes(component)* && client.readyState === WebSocket.OPEN) { client.send(obj); } + */ + + let { readyState, filter } = client; + + if (readyState === WebSocket.OPEN && filter.events.includes(event) && filter.components.includes(component)) { + client.send(obj); + } + }); }; @@ -109,6 +119,7 @@ module.exports = (app, router) => { // monkey patch intents for "named subscriptions" // see #403; get default everyhting // NOTE: remove the "default everything" part? + /* ws.intents = req.query?.intents || [ "add", "get", @@ -116,6 +127,20 @@ module.exports = (app, router) => { "remove" ]; + // return all components on default + //ws.components = req.query?.components || componentNames; + */ + + ws.filter = { + events: req.query.events || req.query.intents || [ + "add", + "get", + "update", + "remove" + ], + components: req.query.components || componentNames + }; + wss.emit("connection", ws, req); }); From d37fbb9d423ab0c4854e849e8e854fc32a4079a4 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sat, 13 Apr 2024 22:27:00 +0200 Subject: [PATCH 138/186] fix #445 --- backend.service | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/backend.service b/backend.service index 6d163d2..4024039 100644 --- a/backend.service +++ b/backend.service @@ -1,17 +1,20 @@ [Unit] Description=OpenHaus Backend +Documentation=https://docs.open-haus.io Wants=network-online.target After=network-online.target [Service] ExecStart=/usr/bin/node /opt/OpenHaus/backend/index.js WorkingDirectory=/opt/OpenHaus/backend -Restart=always +EnvironmentFile=/opt/OpenHaus/backend/.env +Restart=on-failure RestartSec=10 -Environment=NODE_ENV=production -Environment=VAULT_MASTER_PASSWORD=Pa$$w0rd -Environment=USERS_JWT_SECRET=Pa$$w0rd -Environment=UUID=00000000-0000-0000-0000-000000000000 +Type=simple +#Environment=NODE_ENV=production +#Environment=VAULT_MASTER_PASSWORD=Pa$$w0rd +#Environment=USERS_JWT_SECRET=Pa$$w0rd +#Environment=UUID=00000000-0000-0000-0000-000000000000 [Install] WantedBy=multi-user.target \ No newline at end of file From 646eea788054714c6cb8d8aca3d1367fae5ee1ff Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 18 Apr 2024 18:06:01 +0200 Subject: [PATCH 139/186] note added see --- routes/router.api.ssdp.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/routes/router.api.ssdp.js b/routes/router.api.ssdp.js index f0f5ee7..d0406d1 100644 --- a/routes/router.api.ssdp.js +++ b/routes/router.api.ssdp.js @@ -15,6 +15,9 @@ const C_SSDP = require("../components/ssdp"); // Error: unknown ssdp message type cache-control: max-age=100 // Seems like the line handling works not perfect +// simple ssdp monitor +// nc -ulvv 239.255.255.250 1900 + async function parseMessage(msg) { From 36d48770b95d135f37fd6dc2db2ef58fe074d809 Mon Sep 17 00:00:00 2001 From: Marc Date: Thu, 25 Apr 2024 13:32:42 +0200 Subject: [PATCH 140/186] `/system` route draft - see #347 --- routes/index.js | 7 ++ routes/router.system.events.js | 9 +++ routes/router.system.info.js | 129 +++++++++++++++++++++++++++++++++ routes/router.system.js | 36 +++++++++ 4 files changed, 181 insertions(+) create mode 100644 routes/router.system.events.js create mode 100644 routes/router.system.info.js create mode 100644 routes/router.system.js diff --git a/routes/index.js b/routes/index.js index a3b42ac..ed7a9d8 100644 --- a/routes/index.js +++ b/routes/index.js @@ -92,7 +92,9 @@ require("./router.api.logs.js")(app, logs); api.use("/about", about); require("./router.api.about.js")(app, about); +// mount /system under /api //app.use("/system", system); +//require("./router.system.js")(api); //require("./router.system.notifications.js")(app, system); @@ -160,6 +162,7 @@ const usersRouter = express.Router(); const webhooksRouter = express.Router(); const mqttRouter = express.Router(); const mdnsRouter = express.Router(); +const systemRouter = express.Router(); // http://127.0.0.1/api/plugins api.use("/plugins", pluginsRouter); @@ -224,6 +227,10 @@ api.use("/mdns", mdnsRouter); require("./router.api.mdns.js")(app, mdnsRouter); require("./rest-handler.js")(C_MDNS, mdnsRouter); +// http://127.0.0.1/api/system +api.use("/system", systemRouter); +require("./router.system.js")(systemRouter); + // NOTE: Drop this?! api.use((req, res) => { res.status(404).end(); diff --git a/routes/router.system.events.js b/routes/router.system.events.js new file mode 100644 index 0000000..58d103b --- /dev/null +++ b/routes/router.system.events.js @@ -0,0 +1,9 @@ +module.exports = (router) => { + + // NOTE: this is for compatibility reasons + // NOTICE: This would break reactiviness of user (non admin) UIs + // When a new device is added, a user would not see before refreshing the UI + // in v4 the content from router.api.events.js is moved here + require("./router.api.events.js")(null, router); + +}; \ No newline at end of file diff --git a/routes/router.system.info.js b/routes/router.system.info.js new file mode 100644 index 0000000..2b35de4 --- /dev/null +++ b/routes/router.system.info.js @@ -0,0 +1,129 @@ +const process = require("process"); +const { exec } = require("child_process"); +const os = require("os"); +//const mongodb = require("mongodb"); + +module.exports = (router) => { + + router.get("/", (req, res) => { + Promise.all([ + + // get npm version + new Promise((resolve, reject) => { + exec("npm -v", (err, stdout, stderr) => { + if (err || stderr) { + + reject(err || stderr); + + } else { + + resolve(stdout); + + } + }); + }), + + // get tar version + // TODO: use explicit path to binary + // see: https://github.com/OpenHausIO/backend/issues/432 "Add config for bin pathes" + new Promise((resolve, reject) => { + exec("tar --version", (err, stdout, stderr) => { + if (err || stderr) { + + reject(err || stdout); + + } else { + + // extract version number from output + // `tar (GNU tar) 1.34` + let matches = stdout.match(/(\d+\.\d+)/); + resolve(matches && matches[0] || "undefined"); + + } + }); + }), + + // get mongodb version + // TODO: before enable this, check if this works with authentication + /* + new Promise((resolve, reject) => { + + let db = mongodb.client.admin(); + + db.serverStatus((err, info) => { + if (err) { + reject(err); + } else { + resolve(info.version); + } + }); + + }), + */ + + // calculate cpu usage + new Promise((resolve, reject) => { + try { + + const perc = os.cpus().map(cpu => cpu.times).reduce((acc, times) => { + const totalCPUTime = Object.values(times).reduce((total, time) => total + time, 0); + const idleCPUTime = times.idle; + const cpuUsagePercentage = ((totalCPUTime - idleCPUTime) / totalCPUTime) * 100; + return acc + cpuUsagePercentage; + }, 0) / os.cpus().length; + + resolve(perc.toFixed(2)); + + } catch (err) { + reject(err); + } + }), + + // calculate ram usage + new Promise((resolve, reject) => { + try { + + let totalMemory = os.totalmem(); + let usedMemory = totalMemory - os.freemem(); + let perc = (usedMemory / totalMemory) * 100; + + process.nextTick(() => { + resolve(perc.toFixed(2)); + }); + + } catch (err) { + reject(err); + } + }) + + ]).then((results) => { + + // remove whitespaces & convert to string + let [npm, tar, /*mongodb,*/ cpu, ram] = results.map((result) => { + return String(result).trim(); + }); + + res.json({ + versions: { + node: process.versions.node, + npm, + tar, + //mongodb + }, + // ore move this into a /usage route? + usage: { + cpu, + ram + } + }); + + }).catch((err) => { + + res.status(500).json({ + error: err + }); + + }); + }); + +}; \ No newline at end of file diff --git a/routes/router.system.js b/routes/router.system.js new file mode 100644 index 0000000..71bcf87 --- /dev/null +++ b/routes/router.system.js @@ -0,0 +1,36 @@ +const { Router } = require("express"); + +module.exports = (router) => { + + // protect system route(r|s) + router.use((req, res, next) => { + + // protect system routes here + // - could check here if a user is admin + // - src ip = whitelisted + // - etc. pp. + // if(!req.user.admin){ return res.status(403).end(); } + + next(); + + }); + + // create sub router + let infoRouter = Router(); + let eventsRouter = Router(); + let notificationsRouter = Router(); + + // http://127.0.0.1/api/system/info + // FIXME: what does this work with "eventsRouter/notificationsRouter"?! + router.use("/info", infoRouter); + require("./router.system.info.js")(infoRouter); + + // http://127.0.0.1/api/system/events + router.use("/events", eventsRouter); + require("./router.system.events.js")(eventsRouter); + + // http://127.0.0.1/api/system/notifications + router.use("/notifications", notificationsRouter); + //require("./router.system.notifications.js")(notificationsRouter); + +}; \ No newline at end of file From 497bdf16389f768b841e3156bf61b8300d7f639a Mon Sep 17 00:00:00 2001 From: Marc Date: Thu, 25 Apr 2024 14:19:57 +0200 Subject: [PATCH 141/186] depreaction notice added --- routes/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/routes/index.js b/routes/index.js index ed7a9d8..9af604e 100644 --- a/routes/index.js +++ b/routes/index.js @@ -97,6 +97,9 @@ require("./router.api.about.js")(app, about); //require("./router.system.js")(api); //require("./router.system.notifications.js")(app, system); +[/*"events",*/ "about", "logs"].forEach((route) => { + logger.warn(`http://${process.env.HTTP_ADDRESS}:${process.env.HTTP_PORT}/api/${route} is derpecated and will be removed in v4`); +}); // ensure that all requests to /api are authenticated // req.user = User item from component user From c1f66a74b5be01a8cc30f36f369d5b20fd1e3242 Mon Sep 17 00:00:00 2001 From: Marc Date: Thu, 25 Apr 2024 14:21:18 +0200 Subject: [PATCH 142/186] moved `/api/logs` to `/api/system/logs` --- routes/router.system.js | 5 +++++ routes/router.system.logs.js | 7 +++++++ 2 files changed, 12 insertions(+) create mode 100644 routes/router.system.logs.js diff --git a/routes/router.system.js b/routes/router.system.js index 71bcf87..c519330 100644 --- a/routes/router.system.js +++ b/routes/router.system.js @@ -19,6 +19,7 @@ module.exports = (router) => { let infoRouter = Router(); let eventsRouter = Router(); let notificationsRouter = Router(); + let logsRouter = Router(); // http://127.0.0.1/api/system/info // FIXME: what does this work with "eventsRouter/notificationsRouter"?! @@ -33,4 +34,8 @@ module.exports = (router) => { router.use("/notifications", notificationsRouter); //require("./router.system.notifications.js")(notificationsRouter); + // http://127.0.0.1/api/system/logs + router.use("/logs", logsRouter); + require("./router.system.logs.js")(logsRouter); + }; \ No newline at end of file diff --git a/routes/router.system.logs.js b/routes/router.system.logs.js new file mode 100644 index 0000000..8fbf18b --- /dev/null +++ b/routes/router.system.logs.js @@ -0,0 +1,7 @@ +module.exports = (router) => { + + // NOTE: this is for compatibility reasons + // in v4 the content from router.api.logs.js is moved here + require("./router.api.logs.js")(null, router); + +}; \ No newline at end of file From ee80f25f80bfca43132fa20f87511f95ea6648b3 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sun, 28 Apr 2024 16:00:55 +0200 Subject: [PATCH 143/186] fix #354, see #347 --- routes/router.system.logs.js | 297 ++++++++++++++++++++++++++++++++++- 1 file changed, 296 insertions(+), 1 deletion(-) diff --git a/routes/router.system.logs.js b/routes/router.system.logs.js index 8fbf18b..d25295b 100644 --- a/routes/router.system.logs.js +++ b/routes/router.system.logs.js @@ -1,7 +1,302 @@ +const path = require("path"); +const fs = require("fs"); +const { exec } = require("child_process"); +const { WebSocket } = require("ws"); +const { Readable } = require("stream"); +const { createInterface } = require("readline"); + +const { + LOG_PATH +} = process.env; + +const LOGFILE = path.resolve(LOG_PATH, "combined.log"); + +const logger = require("../system/logger"); + +// websocket server +const wss = new WebSocket.Server({ + noServer: true +}); + +// detect broken connections +const interval = setInterval(() => { + wss.clients.forEach((ws) => { + + if (!ws.isAlive) { + ws.terminate(); + return; + } + + ws.isAlive = false; + ws.ping(); + + }); +}, Number(process.env.API_WEBSOCKET_TIMEOUT)); + + +// if the server closes +// clear the interval +wss.on("close", () => { + clearInterval(interval); +}); + + module.exports = (router) => { // NOTE: this is for compatibility reasons // in v4 the content from router.api.logs.js is moved here - require("./router.api.logs.js")(null, router); + //require("./router.api.logs.js")(null, router); + + router.get("/", (req, res) => { + if ((!req.headers["upgrade"] || !req.headers["connection"])) { + + let { + limit = 0, + offset = 0 + } = req.query; + + let output = []; + let lines = 0; + + let readable = fs.createReadStream(LOGFILE); + let rl = createInterface({ + input: readable + }); + + rl.on("line", (line) => { + + // count lines + lines += 1; + + if (output.length >= limit && limit > 0) { + rl.close(); + return; + } + + if (offset < lines) { + output.push(JSON.parse(line)); + } + + }); + + rl.on("close", () => { + res.json(output); + }); + + + } else { + + // listen for websockt clients + // keep sending new log entrys to client + wss.once("connection", (ws) => { + + let controller = new AbortController(); // used to stop watcher + let { signal } = controller; + + let input = new Readable({ + read() { } + }); + + let rl = createInterface({ + input + }); + + rl.on("line", (line) => { + ws.send(line); + }); + + // cleanup when ws connection is closed + // everything triggers ws.terminate(); + // whitch results in emitting close + ws.once("close", () => { + controller.abort(); // stop fs.watch() + rl.close(); // stop readline + input.destroy(); // destory readable + }); + + fs.open(LOGFILE, "r", (err, fd) => { + + if (err) { + ws.terminate(); + return; + } + + let position = 0; + let prev_stats = null; + + fs.stat(LOGFILE, (err, stats) => { + if (err) { + + console.error(err); + ws.terminate(); + + } else { + + // set position to end of file + // receive only new messages + prev_stats = stats; + position = stats.size; + + } + }); + + let watcher = fs.watch(LOGFILE, { + signal + }); + + watcher.once("error", () => { + ws.terminate(); + }); + + watcher.on("change", () => { + + // could be possible that changes happens before stats are available + // this would break and flood everything from the log file + if (!prev_stats) { + return; + } + + fs.stat(LOGFILE, (err, stats) => { + if (err) { + + console.error(err); + ws.terminate(); + + } else { + + if (prev_stats.size > stats.size) { + position = 0; + } + + prev_stats = stats; + + } + }); + + fs.read(fd, { + position, + encoding: "utf8" + }, (err, bytesRead, buffer) => { + if (err) { + + console.error(err); + ws.terminate(); + + } else { + + position += bytesRead; + input.push(buffer.slice(0, bytesRead)); + + } + }); + + }); + + // close event loop + watcher.unref(); + + }); + + }); + + // handle request as websocket + // perform websocket handshake + wss.handleUpgrade(req, req.socket, req.headers, (ws) => { + + ws.isAlive = true; + + ws.on("pong", () => { + ws.isAlive = true; + }); + + wss.emit("connection", ws, req); + + }); + + } + }); + + router.delete("/", (req, res) => { + fs.readdir(LOG_PATH, { + recursive: true + }, (err, files) => { + if (err) { + + res.status(500).json({ + error: err + }); + + } else { + try { + + // build absolute paths + let logfiles = files.filter((name) => { + return name !== ".gitkeep"; + }).map((name) => { + return path.join(LOG_PATH, name); + }).filter((file) => { + return !fs.statSync(file).isDirectory(); + }); + + for (let file of logfiles) { + if (req.query.delete === "true") { + fs.rmSync(file); + } else { + fs.truncateSync(file); + } + } + + // feedback + logger.warn(`Logfiles ${req.query.delete === "true" ? "deleted" : "truncated"}!`); + + res.json(logfiles); + + } catch (err) { + + res.status(500).json({ + error: err + }); + + } + } + }); + }); + + router.post("/export", (req, res) => { + try { + + // TODO: Ensure that only admins can download logs + // a logfile may contain sensitive information! + + // TODO: use absolute path to tar + // see: https://github.com/OpenHausIO/backend/issues/432 + let tar = exec(`tar -czv *`, { + cwd: LOG_PATH, + encoding: "buffer" + }); + + if (process.env.NODE_ENV === "development") { + tar.stderr.pipe(process.stderr); + } + + res.setHeader("content-type", "application/tar+gzip"); + + tar.once("exit", (code) => { + console.log("exit code", code); + res.end(); + }); + + tar.stdout.pipe(res); + + } catch (err) { + + console.log(err); + + res.status(500).json({ + error: err + }); + + } + }); }; \ No newline at end of file From b5682ed52a81124249afe701c5dc90419a782b3f Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sun, 28 Apr 2024 16:02:13 +0200 Subject: [PATCH 144/186] fix #451 --- Gruntfile.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Gruntfile.js b/Gruntfile.js index 2de66d2..ee0c707 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -100,10 +100,18 @@ module.exports = function (grunt) { stdio: "inherit" }); + // remove build, use taggin. see: #451 + /* cp.execSync(`docker build . -t openhaus/${pkg.name}:latest ${buildArgs}`, { env: process.env, stdio: "inherit" }); + */ + + cp.execSync(`docker image tag openhaus/${pkg.name}:${pkg.version} openhaus/${pkg.name}:latest`, { + env: process.env, + stdio: "inherit" + }); }); From 4022b75717ff0b5ff25d232a84aa04f21c45bd90 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sun, 28 Apr 2024 16:07:53 +0200 Subject: [PATCH 145/186] added, see #347 --- routes/router.system.notifications.js | 77 ++++++++++++ system/notifications/class.notifications.js | 123 ++++++++++++++++++++ system/notifications/index.js | 8 ++ 3 files changed, 208 insertions(+) create mode 100644 routes/router.system.notifications.js create mode 100644 system/notifications/class.notifications.js create mode 100644 system/notifications/index.js diff --git a/routes/router.system.notifications.js b/routes/router.system.notifications.js new file mode 100644 index 0000000..c6f228d --- /dev/null +++ b/routes/router.system.notifications.js @@ -0,0 +1,77 @@ +const WebSocket = require("ws"); + +const Notification = require("../system/notifications/class.notifications.js"); +const events = Notification.events(); + +module.exports = (router) => { + + // websocket server + let wss = new WebSocket.Server({ + noServer: true + }); + + // detect broken connections + let interval = setInterval(() => { + wss.clients.forEach((ws) => { + + if (!ws.isAlive) { + ws.terminate(); + return; + } + + ws.isAlive = false; + ws.ping(); + + }); + }, Number(process.env.API_WEBSOCKET_TIMEOUT)); + + + // if the server closes + // clear the interval + wss.on("close", () => { + clearInterval(interval); + }); + + + events.on("publish", (event) => { + wss.clients.forEach((ws) => { + ws.send(JSON.stringify(event)); + }); + }); + + + router.get("/", (req, res) => { + if ((!req.headers["upgrade"] || !req.headers["connection"])) { + + res.json(Notification.notifications()); + + } else { + wss.handleUpgrade(req, req.socket, req.headers, (ws) => { + + ws.isAlive = true; + + ws.on("pong", () => { + ws.isAlive = true; + }); + + wss.emit("connection", ws, req); + + }); + } + }); + + + router.put("/", (req, res) => { + + let { title, message } = req.body; + let notification = new Notification(title, message); + + notification.publish(); + res.json(notification); + + }); + + + return router; + +}; \ No newline at end of file diff --git a/system/notifications/class.notifications.js b/system/notifications/class.notifications.js new file mode 100644 index 0000000..bba40e6 --- /dev/null +++ b/system/notifications/class.notifications.js @@ -0,0 +1,123 @@ +const { randomUUID } = require("crypto"); +const { EventEmitter } = require("events"); +const Joi = require("joi"); + + +const events = new EventEmitter(); +const notifications = []; + + +// `new Set()` would be better, but its not proxyable +// TypeError: Method Set.prototype.add called on incompatible receiver # +// try it with prop.bind(set/receiver)? +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Called_on_incompatible_type +// > why event the proxy trap? emit the added event when a new notificaiton instance is created +// TODO: test/switch to - with new Set(); +/* +const notifications = new Proxy([], { + set(target, prop, val, receiver) { + + events.emit("added", val); + return Reflect.set(target, prop, val, receiver); + //receiver.add(val); + + } +}); +*/ + + +module.exports = class Notification { + + constructor(title, message) { + + let { error, value } = Notification.validate({ + title, + message + }); + + if (error) { + throw error; + } + + // set/merge default values + // TODO: check how to set defaults form schema definition! + Object.assign(this, { + timestamps: { + created: Date.now(), + published: false + } + }, value); + + // hidden property + Object.defineProperty(this, "published", { + value: false, + writable: true + }); + + // add notification + //notifications.add(this); + notifications.push(this); + events.emit("added", this); + + } + + publish() { + if (!this.published) { + + this.published = true; + this.timestamps.published = Date.now(); + + //if (!this.retain) { + process.nextTick(() => { + + events.emit("publish", this); + //notifications.delete(this); + + let index = notifications.find(({ uuid }) => { + return this.uuid === uuid; + }); + + notifications.splice(index, 1); + + }); + //} + + } + } + + static schema() { + return Joi.object({ + title: Joi.string().required(), + message: Joi.string().required(), + uuid: Joi.string().default(() => { + return randomUUID(); + }), + type: Joi.string().valid("info", "warn", "error").default("info"), + //actions: Joi.array().items().default([]), + //retain: Joi.boolean().default(false), + timestamps: Joi.object({ + created: Joi.number().allow(null).default(() => { + return Date.now(); + }), + published: Joi.number().allow(null).default(null) + }) + }); + } + + static validate(data) { + return Notification.schema().validate(data); + } + + static events() { + return events; + } + + static notifications(convert = false) { + if (convert) { + return Array.from(notifications); + } else { + return notifications; + } + } + +}; \ No newline at end of file diff --git a/system/notifications/index.js b/system/notifications/index.js new file mode 100644 index 0000000..8dbe7bd --- /dev/null +++ b/system/notifications/index.js @@ -0,0 +1,8 @@ +const Notification = require("./class.notifications.js"); + + +module.exports = { + Notification, + events: Notification.events(), + notifications: Notification.notifications() +}; \ No newline at end of file From e90711b4249b921edb0321ef6e0aa10437abe592 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sun, 28 Apr 2024 16:08:19 +0200 Subject: [PATCH 146/186] `/api/system/notifications` added --- routes/router.system.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/router.system.js b/routes/router.system.js index c519330..a4de93c 100644 --- a/routes/router.system.js +++ b/routes/router.system.js @@ -32,7 +32,7 @@ module.exports = (router) => { // http://127.0.0.1/api/system/notifications router.use("/notifications", notificationsRouter); - //require("./router.system.notifications.js")(notificationsRouter); + require("./router.system.notifications.js")(notificationsRouter); // http://127.0.0.1/api/system/logs router.use("/logs", logsRouter); From cb37c85bacd8ac58e7510ed240216de19d583562 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sun, 28 Apr 2024 16:08:41 +0200 Subject: [PATCH 147/186] comment added --- components/ssdp/class.ssdp.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/ssdp/class.ssdp.js b/components/ssdp/class.ssdp.js index f4551b6..2ebc564 100644 --- a/components/ssdp/class.ssdp.js +++ b/components/ssdp/class.ssdp.js @@ -3,6 +3,9 @@ const mongodb = require("mongodb"); const Item = require("../../system/component/class.item.js"); +// simple ssdp monitor: +// nc -ulvv 239.255.255.250 1900 +// TODO: Add documentation for class module.exports = class SSDP extends Item { constructor(obj) { From 2236c3033cf73e6fdc3e5af27e78f3ce3bcade2a Mon Sep 17 00:00:00 2001 From: Marc Date: Mon, 29 Apr 2024 08:58:15 +0200 Subject: [PATCH 148/186] comment added --- routes/router.system.logs.js | 1 + 1 file changed, 1 insertion(+) diff --git a/routes/router.system.logs.js b/routes/router.system.logs.js index d25295b..40786d2 100644 --- a/routes/router.system.logs.js +++ b/routes/router.system.logs.js @@ -114,6 +114,7 @@ module.exports = (router) => { input.destroy(); // destory readable }); + // https://gist.github.com/fkowal/3447400 fs.open(LOGFILE, "r", (err, fd) => { if (err) { From 320158a4c0f0999abc047b642bc5d06c1ec13ac1 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 30 Apr 2024 21:17:01 +0200 Subject: [PATCH 149/186] added "exporter" stream --- routes/router.system.logs.js | 138 ++++++++++------------------------ system/logger/class.logger.js | 24 ++++++ system/logger/index.js | 11 ++- 3 files changed, 71 insertions(+), 102 deletions(-) diff --git a/routes/router.system.logs.js b/routes/router.system.logs.js index d25295b..5937e77 100644 --- a/routes/router.system.logs.js +++ b/routes/router.system.logs.js @@ -2,7 +2,7 @@ const path = require("path"); const fs = require("fs"); const { exec } = require("child_process"); const { WebSocket } = require("ws"); -const { Readable } = require("stream"); +const { PassThrough } = require("stream"); const { createInterface } = require("readline"); const { @@ -11,7 +11,9 @@ const { const LOGFILE = path.resolve(LOG_PATH, "combined.log"); -const logger = require("../system/logger"); +const logger = require("../system/logger/index.js"); +const Logger = require("../system/logger/class.logger.js"); +const exporter = Logger.exporter(); // websocket server const wss = new WebSocket.Server({ @@ -90,115 +92,32 @@ module.exports = (router) => { // keep sending new log entrys to client wss.once("connection", (ws) => { - let controller = new AbortController(); // used to stop watcher - let { signal } = controller; + // a intermediate stream is needed, for cleanup and pipeing + // directly in createrInterface({input}), it does not work + let input = new PassThrough(); + exporter.pipe(input); + + ws.once("close", () => { + + // prevent memeory/event emitter leak + // wihtout unpipe, after 10 connections a memeory leak warning is printed + exporter.unpipe(input); + + rl.close(); - let input = new Readable({ - read() { } }); let rl = createInterface({ - input + input: exporter }); rl.on("line", (line) => { ws.send(line); }); - // cleanup when ws connection is closed - // everything triggers ws.terminate(); - // whitch results in emitting close - ws.once("close", () => { - controller.abort(); // stop fs.watch() - rl.close(); // stop readline - input.destroy(); // destory readable - }); - - fs.open(LOGFILE, "r", (err, fd) => { - - if (err) { - ws.terminate(); - return; - } - - let position = 0; - let prev_stats = null; - - fs.stat(LOGFILE, (err, stats) => { - if (err) { - - console.error(err); - ws.terminate(); - - } else { - - // set position to end of file - // receive only new messages - prev_stats = stats; - position = stats.size; - - } - }); - - let watcher = fs.watch(LOGFILE, { - signal - }); - - watcher.once("error", () => { - ws.terminate(); - }); - - watcher.on("change", () => { - - // could be possible that changes happens before stats are available - // this would break and flood everything from the log file - if (!prev_stats) { - return; - } - - fs.stat(LOGFILE, (err, stats) => { - if (err) { - - console.error(err); - ws.terminate(); - - } else { - - if (prev_stats.size > stats.size) { - position = 0; - } - - prev_stats = stats; - - } - }); - - fs.read(fd, { - position, - encoding: "utf8" - }, (err, bytesRead, buffer) => { - if (err) { - - console.error(err); - ws.terminate(); - - } else { - - position += bytesRead; - input.push(buffer.slice(0, bytesRead)); - - } - }); - - }); - - // close event loop - watcher.unref(); - - }); - }); + // handle request as websocket // perform websocket handshake wss.handleUpgrade(req, req.socket, req.headers, (ws) => { @@ -216,6 +135,27 @@ module.exports = (router) => { } }); + router.put("/", (req, res) => { + + let { + level = "debug", + message = "Hello World" + } = req.body; + + if (Object.hasOwnProperty.call(logger, level)) { + + logger[level](message); + res.status(200).end(); + + } else { + + // wrong logger level + res.status(400).end(); + + } + + }); + router.delete("/", (req, res) => { fs.readdir(LOG_PATH, { recursive: true diff --git a/system/logger/class.logger.js b/system/logger/class.logger.js index e5fec58..9e26f08 100644 --- a/system/logger/class.logger.js +++ b/system/logger/class.logger.js @@ -1,6 +1,24 @@ const { EOL } = require("os"); const util = require("util"); +const { Transform } = require("stream"); +//const exporter = new PassThrough(); +const exporter = new Transform({ + transform(chunk, encoding, cb) { + + // ignore & drop every message if no pipe/consumer + // otherwise this jams up the stream + // TODO: check if a event listener is used to consume data + // if event listener is used, this approach drops the chunk + if (this._readableState.pipes.length > 0) { + this.push(chunk); + } + + cb(); + + } +}); + const levels = require("./levels"); /** @@ -55,6 +73,8 @@ module.exports = class Logger { let err = args.shift(); + // NOTE: `Object.getOwnPropertyNames(err)` makes no sense here + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify obj.error = JSON.stringify(err, Object.getOwnPropertyNames(err)); obj.message = util.format(...args); @@ -151,4 +171,8 @@ module.exports = class Logger { } + static exporter() { + return exporter; + } + }; \ No newline at end of file diff --git a/system/logger/index.js b/system/logger/index.js index fedf82b..1e3f5e9 100644 --- a/system/logger/index.js +++ b/system/logger/index.js @@ -60,7 +60,10 @@ const combined = createWriteStream(path.resolve(process.env.LOG_PATH, "combined. flags: "a" }); -[system, combined].forEach((stream) => { +const exporter = Logger.exporter(); + + +[system, combined, exporter].forEach((stream) => { stream.on("error", (err) => { console.error(err); process.exit(1); @@ -92,7 +95,8 @@ const options = { streams: [ stdout, system, - combined + combined, + exporter ], level: process.env.LOG_LEVEL }; @@ -126,7 +130,8 @@ Object.defineProperty(logger, "create", { streams: [ stdout, stream, - combined + combined, + exporter ] }); From e103c37dfaec2387f251761ad81a2b6d5eb72c82 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Tue, 30 Apr 2024 21:17:39 +0200 Subject: [PATCH 150/186] splittet &added `/versions/ & `/usage` routes --- routes/router.system.info.js | 57 +++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/routes/router.system.info.js b/routes/router.system.info.js index 2b35de4..14d03a6 100644 --- a/routes/router.system.info.js +++ b/routes/router.system.info.js @@ -5,7 +5,7 @@ const os = require("os"); module.exports = (router) => { - router.get("/", (req, res) => { + router.get(["/versions", "/"], (req, res) => { Promise.all([ // get npm version @@ -126,4 +126,59 @@ module.exports = (router) => { }); }); + + router.get("/usage", (req, res) => { + + Promise.all([ + + // calculate cpu usage + new Promise((resolve, reject) => { + try { + + const perc = os.cpus().map(cpu => cpu.times).reduce((acc, times) => { + const totalCPUTime = Object.values(times).reduce((total, time) => total + time, 0); + const idleCPUTime = times.idle; + const cpuUsagePercentage = ((totalCPUTime - idleCPUTime) / totalCPUTime) * 100; + return acc + cpuUsagePercentage; + }, 0) / os.cpus().length; + + resolve(perc.toFixed(2)); + + } catch (err) { + reject(err); + } + }), + + // calculate ram usage + new Promise((resolve, reject) => { + try { + + let totalMemory = os.totalmem(); + let usedMemory = totalMemory - os.freemem(); + let perc = (usedMemory / totalMemory) * 100; + + process.nextTick(() => { + resolve(perc.toFixed(2)); + }); + + } catch (err) { + reject(err); + } + }) + ]).then(([cpu, ram]) => { + + res.json({ + cpu, + ram + }); + + }).catch((err) => { + + res.status(500).json({ + error: err + }); + + }); + }); + }; \ No newline at end of file From 33c3a4e350599190a60ed1ea6ba5cb67fa93650a Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 1 May 2024 22:16:38 +0200 Subject: [PATCH 151/186] refactored/improved, see #347 --- routes/router.system.logs.js | 45 +++++++++++++++++++++++++++++++---- system/logger/class.logger.js | 6 ++++- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/routes/router.system.logs.js b/routes/router.system.logs.js index 5937e77..9f09d60 100644 --- a/routes/router.system.logs.js +++ b/routes/router.system.logs.js @@ -15,6 +15,35 @@ const logger = require("../system/logger/index.js"); const Logger = require("../system/logger/class.logger.js"); const exporter = Logger.exporter(); + +/* +// works like charm with netcat +// `nc open-haus.lan 8123` +const { createServer } = require("net"); +const server = createServer(); + +server.listen(8123, "0.0.0.0", () => { + + console.log("Logfile tcp socket listening on tcp://0.0.0.0:8123") + + server.on("connection", (socket) => { + + console.log("net socket conneceted") + exporter.pipe(socket); + + socket.once("close", () => { + console.log("net socket closed"); + exporter.unpipe(socket); + }); + + }); + +}); +*/ + + + + // websocket server const wss = new WebSocket.Server({ noServer: true @@ -90,13 +119,23 @@ module.exports = (router) => { // listen for websockt clients // keep sending new log entrys to client + // NOTE: This websocket/stream/readline logging reporter is buggy + // when the exporter stream was directly used input, it worked only 5 min + // today using the intermediate stream, works like expected (like above over a tcp socket) + // when changing back to directly use "exporter" stream, the problem was not reproducable... wss.once("connection", (ws) => { // a intermediate stream is needed, for cleanup and pipeing - // directly in createrInterface({input}), it does not work + // directly in createrInterface({input}) does not work + // jams up the output, event emitter leak let input = new PassThrough(); exporter.pipe(input); + let rl = createInterface({ + input, + terminal: false + }); + ws.once("close", () => { // prevent memeory/event emitter leak @@ -107,10 +146,6 @@ module.exports = (router) => { }); - let rl = createInterface({ - input: exporter - }); - rl.on("line", (line) => { ws.send(line); }); diff --git a/system/logger/class.logger.js b/system/logger/class.logger.js index 9e26f08..0c15b3d 100644 --- a/system/logger/class.logger.js +++ b/system/logger/class.logger.js @@ -6,15 +6,19 @@ const { Transform } = require("stream"); const exporter = new Transform({ transform(chunk, encoding, cb) { + console.log("exporter stream is piped:", this._readableState.pipes.length > 0); + // ignore & drop every message if no pipe/consumer // otherwise this jams up the stream // TODO: check if a event listener is used to consume data + // try with: this.listenerCount('data'|'readable') // if event listener is used, this approach drops the chunk if (this._readableState.pipes.length > 0) { this.push(chunk); } - cb(); + //cb(); + process.nextTick(cb); } }); From 18214daefb2f3e4a22cbc05a236d501572047841 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 3 May 2024 17:39:07 +0200 Subject: [PATCH 152/186] remove 'console.log' & added "consumer" check for stream --- system/logger/class.logger.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/system/logger/class.logger.js b/system/logger/class.logger.js index 0c15b3d..a4d8cf6 100644 --- a/system/logger/class.logger.js +++ b/system/logger/class.logger.js @@ -6,14 +6,9 @@ const { Transform } = require("stream"); const exporter = new Transform({ transform(chunk, encoding, cb) { - console.log("exporter stream is piped:", this._readableState.pipes.length > 0); - - // ignore & drop every message if no pipe/consumer - // otherwise this jams up the stream - // TODO: check if a event listener is used to consume data - // try with: this.listenerCount('data'|'readable') - // if event listener is used, this approach drops the chunk - if (this._readableState.pipes.length > 0) { + // ignore & drop every message if no pipe/consumer. Otherwise this jams up the stream + // TODO: check with this.listenerCount('data'|'readable')? + if (this._readableState.pipes.length > 0 || this._events.data instanceof Function) { this.push(chunk); } From 2524cc6ac11fc665f7a07b4bcbcc3021d93e91df Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 3 May 2024 17:58:12 +0200 Subject: [PATCH 153/186] websocket endpont improved --- routes/router.system.logs.js | 277 +++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 routes/router.system.logs.js diff --git a/routes/router.system.logs.js b/routes/router.system.logs.js new file mode 100644 index 0000000..9f09d60 --- /dev/null +++ b/routes/router.system.logs.js @@ -0,0 +1,277 @@ +const path = require("path"); +const fs = require("fs"); +const { exec } = require("child_process"); +const { WebSocket } = require("ws"); +const { PassThrough } = require("stream"); +const { createInterface } = require("readline"); + +const { + LOG_PATH +} = process.env; + +const LOGFILE = path.resolve(LOG_PATH, "combined.log"); + +const logger = require("../system/logger/index.js"); +const Logger = require("../system/logger/class.logger.js"); +const exporter = Logger.exporter(); + + +/* +// works like charm with netcat +// `nc open-haus.lan 8123` +const { createServer } = require("net"); +const server = createServer(); + +server.listen(8123, "0.0.0.0", () => { + + console.log("Logfile tcp socket listening on tcp://0.0.0.0:8123") + + server.on("connection", (socket) => { + + console.log("net socket conneceted") + exporter.pipe(socket); + + socket.once("close", () => { + console.log("net socket closed"); + exporter.unpipe(socket); + }); + + }); + +}); +*/ + + + + +// websocket server +const wss = new WebSocket.Server({ + noServer: true +}); + +// detect broken connections +const interval = setInterval(() => { + wss.clients.forEach((ws) => { + + if (!ws.isAlive) { + ws.terminate(); + return; + } + + ws.isAlive = false; + ws.ping(); + + }); +}, Number(process.env.API_WEBSOCKET_TIMEOUT)); + + +// if the server closes +// clear the interval +wss.on("close", () => { + clearInterval(interval); +}); + + +module.exports = (router) => { + + // NOTE: this is for compatibility reasons + // in v4 the content from router.api.logs.js is moved here + //require("./router.api.logs.js")(null, router); + + router.get("/", (req, res) => { + if ((!req.headers["upgrade"] || !req.headers["connection"])) { + + let { + limit = 0, + offset = 0 + } = req.query; + + let output = []; + let lines = 0; + + let readable = fs.createReadStream(LOGFILE); + let rl = createInterface({ + input: readable + }); + + rl.on("line", (line) => { + + // count lines + lines += 1; + + if (output.length >= limit && limit > 0) { + rl.close(); + return; + } + + if (offset < lines) { + output.push(JSON.parse(line)); + } + + }); + + rl.on("close", () => { + res.json(output); + }); + + + } else { + + // listen for websockt clients + // keep sending new log entrys to client + // NOTE: This websocket/stream/readline logging reporter is buggy + // when the exporter stream was directly used input, it worked only 5 min + // today using the intermediate stream, works like expected (like above over a tcp socket) + // when changing back to directly use "exporter" stream, the problem was not reproducable... + wss.once("connection", (ws) => { + + // a intermediate stream is needed, for cleanup and pipeing + // directly in createrInterface({input}) does not work + // jams up the output, event emitter leak + let input = new PassThrough(); + exporter.pipe(input); + + let rl = createInterface({ + input, + terminal: false + }); + + ws.once("close", () => { + + // prevent memeory/event emitter leak + // wihtout unpipe, after 10 connections a memeory leak warning is printed + exporter.unpipe(input); + + rl.close(); + + }); + + rl.on("line", (line) => { + ws.send(line); + }); + + }); + + + // handle request as websocket + // perform websocket handshake + wss.handleUpgrade(req, req.socket, req.headers, (ws) => { + + ws.isAlive = true; + + ws.on("pong", () => { + ws.isAlive = true; + }); + + wss.emit("connection", ws, req); + + }); + + } + }); + + router.put("/", (req, res) => { + + let { + level = "debug", + message = "Hello World" + } = req.body; + + if (Object.hasOwnProperty.call(logger, level)) { + + logger[level](message); + res.status(200).end(); + + } else { + + // wrong logger level + res.status(400).end(); + + } + + }); + + router.delete("/", (req, res) => { + fs.readdir(LOG_PATH, { + recursive: true + }, (err, files) => { + if (err) { + + res.status(500).json({ + error: err + }); + + } else { + try { + + // build absolute paths + let logfiles = files.filter((name) => { + return name !== ".gitkeep"; + }).map((name) => { + return path.join(LOG_PATH, name); + }).filter((file) => { + return !fs.statSync(file).isDirectory(); + }); + + for (let file of logfiles) { + if (req.query.delete === "true") { + fs.rmSync(file); + } else { + fs.truncateSync(file); + } + } + + // feedback + logger.warn(`Logfiles ${req.query.delete === "true" ? "deleted" : "truncated"}!`); + + res.json(logfiles); + + } catch (err) { + + res.status(500).json({ + error: err + }); + + } + } + }); + }); + + router.post("/export", (req, res) => { + try { + + // TODO: Ensure that only admins can download logs + // a logfile may contain sensitive information! + + // TODO: use absolute path to tar + // see: https://github.com/OpenHausIO/backend/issues/432 + let tar = exec(`tar -czv *`, { + cwd: LOG_PATH, + encoding: "buffer" + }); + + if (process.env.NODE_ENV === "development") { + tar.stderr.pipe(process.stderr); + } + + res.setHeader("content-type", "application/tar+gzip"); + + tar.once("exit", (code) => { + console.log("exit code", code); + res.end(); + }); + + tar.stdout.pipe(res); + + } catch (err) { + + console.log(err); + + res.status(500).json({ + error: err + }); + + } + }); + +}; \ No newline at end of file From ca3468b6f4dd650d012fcd2b23d9a25add32d03f Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sat, 4 May 2024 21:10:08 +0200 Subject: [PATCH 154/186] note added --- components/plugins/index.js | 2 ++ routes/router.api.webhooks.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/components/plugins/index.js b/components/plugins/index.js index 791ed47..a1c0192 100644 --- a/components/plugins/index.js +++ b/components/plugins/index.js @@ -34,6 +34,7 @@ class C_PLUGINS extends COMPONENT { super("plugins", Plugin.schema(), module); this.hooks.post("add", (data, next) => { + // NOTE: use path to plugins set via env, see #432 fs.mkdir(path.resolve(process.cwd(), "plugins", data.uuid), (err) => { // ignore when folder exists @@ -53,6 +54,7 @@ class C_PLUGINS extends COMPONENT { }); this.hooks.post("remove", (item, result, _id, next) => { + // NOTE: use path to plugins set via env, see #432 fs.rm(path.resolve(process.cwd(), "plugins", item.uuid), { recursive: true }, (err) => { diff --git a/routes/router.api.webhooks.js b/routes/router.api.webhooks.js index 1c0681c..2a34257 100644 --- a/routes/router.api.webhooks.js +++ b/routes/router.api.webhooks.js @@ -3,6 +3,8 @@ const C_SCENES = require("../components/scenes"); module.exports = (app, router) => { + // NOTE: Why is this needed? + // if _id is found, `req.item` should be allready set router.param("_id", (req, res, next, _id) => { C_WEBHOOKS.get(_id, (err, obj) => { if (err) { From 4f5afb6602ba6b06104af05269e4a0f900d76f28 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sat, 4 May 2024 21:16:12 +0200 Subject: [PATCH 155/186] fix #444 & fix #436 --- routes/router.api.plugins.js | 144 ++++++++++++++++++++++++++--------- 1 file changed, 110 insertions(+), 34 deletions(-) diff --git a/routes/router.api.plugins.js b/routes/router.api.plugins.js index e51edea..434b65a 100644 --- a/routes/router.api.plugins.js +++ b/routes/router.api.plugins.js @@ -1,12 +1,48 @@ const path = require("path"); const { pipeline } = require("stream"); const { exec } = require("child_process"); +const process = require("process"); const fs = require("fs/promises"); -const readline = require("readline"); +const { statSync } = require("fs"); + +//const C_PLUGINS = require("../components/plugins"); module.exports = (app, router) => { - router.put("/:_id/files", (req, res) => { + // this router gets executed before the rest-handler.js params handler + // but why when this middleware is defined after the rest-handler stuff?! + // execution order: + // 1) the router middleware wehre `req.install` & `req.folder` are set below + // 2) rest-handler.js req.prams("_id") middleware + // 3) router handler below like "/start", "/<_id>/files" + // Outcommented, see issue #444: https://github.com/OpenHausIO/backend/issues/444#issuecomment-2094341348 + // > looks like its not possible to archive the functionality above with a middleware function on all routes + /* + router.use((req, res, next) => { + + console.log("2) plugin middleware", C_PLUGINS.items, req.item, req.params); + + req.install = req.params?.install === "true" || false; + req.folder = path.join(process.cwd(), "plugins", req.item?.uuid || ""); + + console.log("Install:", req.install); + console.log("Folder", req.folder); + + next(); + + }); + */ + + const variables = (req, res, next) => { + + req.install = req.query?.install === "true" || false; + req.folder = path.join(process.cwd(), "plugins", req.item.uuid); + + next(); + + }; + + router.put("/:_id/files", variables, (req, res) => { if (Number(req.headers["content-length"]) <= 0) { return res.status(400).json({ @@ -14,8 +50,8 @@ module.exports = (app, router) => { }); } - let p = path.resolve(process.cwd(), "plugins", req.item.uuid); - let tar = exec(`tar vzxf - -C ${p}`); + //let p = path.resolve(process.cwd(), "plugins", req.item.uuid); + let tar = exec(`tar vzxf - -C ${req.folder}`); tar.once("exit", (code) => { @@ -28,56 +64,93 @@ module.exports = (app, router) => { }); } - } + } else { - // trigger closing pipeline below - tar.stdin.end(); + // skip installation step below + if (!req.install) { + res.json(req.item); + return; + } - }); + try { - let rl = readline.createInterface({ - input: tar.stdout, - //output: process.stdout - }); + // check if package.json exists before executing npm + // otherwise it walks the directorys up till a package.json is found + // in the "worst case" this is the one from backend + statSync(path.join(req.folder, "package.json")); - if (process.env.NODE_ENV === "development") { - rl.on("line", (line) => { + } catch (err) { - console.log("Extract file:", line); - //console.log("Extract file:", path.join(p, line)); + if (err.code === "ENOENT") { + res.json(req.item); + } else { + res.status(500).json({ + error: err.message + }); + } - }); - } + return; - pipeline(req, tar.stdin, (err) => { + } - if (!res.headersSent) { - if (err) { + let npm = exec(`npm install --omit=dev`, { + env: { + ...process.env, + NODE_ENV: "production", + }, + cwd: req.folder + }); - res.status(500).json({ - error: err.message - }); + if (process.env.NODE_ENV === "development") { + npm.stdout.pipe(process.stdout); + npm.stderr.pipe(process.stderr); + } - } else { + npm.once("exit", (code) => { + if (code === 0 || code === 254) { - res.json(req.item); + res.json(req.item); + + } else { + + res.status(400).json({ + error: "npm could not install dependencies", + details: `npm exit code ${code}` + }); + + } + }); - } } - rl.close(); + // trigger closing pipeline below + tar.stdin.end(); + + }); + + if (process.env.NODE_ENV === "development") { + tar.stdout.pipe(process.stdout); + tar.stderr.pipe(process.stderr); + } + + pipeline(req, tar.stdin, (err) => { + if (err && !res.headersSent) { + + res.status(500).json({ + error: err.message + }); + } }); }); - router.delete("/:_id/files", async (req, res) => { + router.delete("/:_id/files", variables, async (req, res) => { try { - let p = path.resolve(process.cwd(), "plugins", req.item.uuid); - - for (let file of await fs.readdir(p)) { - await fs.rm(path.join(p, file), { + //let p = path.resolve(process.cwd(), "plugins", req.item.uuid); + for (let file of await fs.readdir(req.folder)) { + await fs.rm(path.join(req.folder, file), { recursive: true }); } @@ -86,7 +159,10 @@ module.exports = (app, router) => { } catch (err) { - res.status(500).end(err.message); + res.status(500).json({ + error: err.message, + stack: err.stack + }); } }); From 641640c9c9af30fe9114ea0dffad68d4d3cc1238 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Mon, 6 May 2024 17:43:54 +0200 Subject: [PATCH 156/186] renamed --- .../{class.notifications.js => class.notification.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename system/notifications/{class.notifications.js => class.notification.js} (100%) diff --git a/system/notifications/class.notifications.js b/system/notifications/class.notification.js similarity index 100% rename from system/notifications/class.notifications.js rename to system/notifications/class.notification.js From 5bd8e97a1ae1ce290b27d6e41384a2445c595c82 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Mon, 6 May 2024 17:44:30 +0200 Subject: [PATCH 157/186] updated import --- routes/router.system.notifications.js | 2 +- system/notifications/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/routes/router.system.notifications.js b/routes/router.system.notifications.js index c6f228d..89b13db 100644 --- a/routes/router.system.notifications.js +++ b/routes/router.system.notifications.js @@ -1,6 +1,6 @@ const WebSocket = require("ws"); -const Notification = require("../system/notifications/class.notifications.js"); +const { Notification } = require("../system/notifications/index.js"); const events = Notification.events(); module.exports = (router) => { diff --git a/system/notifications/index.js b/system/notifications/index.js index 8dbe7bd..d4a70cb 100644 --- a/system/notifications/index.js +++ b/system/notifications/index.js @@ -1,4 +1,4 @@ -const Notification = require("./class.notifications.js"); +const Notification = require("./class.notification.js"); module.exports = { From 07245e272aee9c6016d7e9ee3407c53f3a48bd72 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Wed, 8 May 2024 19:28:01 +0200 Subject: [PATCH 158/186] note added --- components/plugins/class.plugin.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/components/plugins/class.plugin.js b/components/plugins/class.plugin.js index 0e0c677..8e5d188 100644 --- a/components/plugins/class.plugin.js +++ b/components/plugins/class.plugin.js @@ -116,6 +116,15 @@ module.exports = class Plugin extends Item { let init = (dependencies, cb) => { try { + // NOTE: Monkey patch ready/abort method to init? + // A plugin could siganlize if its ready or needs to be restarted + /* + let init = new Promise((resolve, reject) => { + init.ready = resolve; + init.abort = reject; + }); + */ + const granted = dependencies.every((c) => { if (this.intents.includes(c)) { From 02ed8934de35a7e55fe4d61436ec38b68a6ef673 Mon Sep 17 00:00:00 2001 From: Marc Date: Thu, 23 May 2024 09:53:20 +0200 Subject: [PATCH 159/186] fix #443 --- helper/request.js | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/helper/request.js b/helper/request.js index 6a06e1f..212a4ee 100644 --- a/helper/request.js +++ b/helper/request.js @@ -1,5 +1,7 @@ const url = require("url"); +const promisify = require("./promisify.js"); + /** * Does a http request * @param {*} uri @@ -51,7 +53,8 @@ function perform(uri, options, cb) { cb(null, { headers: res.headers, status: res.statusCode, - body + body, + res }); }); @@ -84,17 +87,13 @@ function perform(uri, options, cb) { * @returns {http.ClientRequest} https://nodejs.org/dist/latest-v16.x/docs/api/http.html#class-httpclientrequest */ -module.exports = function request(uri, options, cb) { +function request(uri, options, cb) { if (!cb && options instanceof Function) { cb = options; options = {}; } - if (!cb) { - cb = () => { }; - } - options = Object.assign({ method: "GET", body: "", @@ -103,25 +102,26 @@ module.exports = function request(uri, options, cb) { setKeepAliveHeader: true }, options); + return promisify((done) => { + perform(uri, options, (err, result) => { + if (err) { - return perform(uri, options, (err, result) => { - if (err) { - - cb(err); - - } else { - - if (options.followRedirects && result.status >= 300 && result.status < 400) { - - perform(result.headers.location, options, cb); + done(err); } else { - cb(null, result); + if (options.followRedirects && result.status >= 300 && result.status < 400 && result.headers?.location) { + perform(result.headers.location, options, done); + } else { + done(null, result); + } } + }); + }, cb); - } - }); +} -}; \ No newline at end of file +module.exports = Object.assign(request, { + perform +}); \ No newline at end of file From 422136c7482d4f4a54747c3e3d33def959caf265 Mon Sep 17 00:00:00 2001 From: Marc Date: Thu, 23 May 2024 10:09:26 +0200 Subject: [PATCH 160/186] improved --- helper/request.js | 8 +++++++- tests/helper/test.request.js | 25 +++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/helper/request.js b/helper/request.js index 212a4ee..206ef3b 100644 --- a/helper/request.js +++ b/helper/request.js @@ -14,6 +14,11 @@ const promisify = require("./promisify.js"); */ function perform(uri, options, cb) { + if(!options && !cb){ + options = {}; + cb = () => {}; + } + let { protocol } = new url.URL(uri); if (!["http:", "https:"].includes(protocol)) { @@ -54,7 +59,8 @@ function perform(uri, options, cb) { headers: res.headers, status: res.statusCode, body, - res + res, + req: request }); }); diff --git a/tests/helper/test.request.js b/tests/helper/test.request.js index cfd64d2..763bd4c 100644 --- a/tests/helper/test.request.js +++ b/tests/helper/test.request.js @@ -44,9 +44,30 @@ describe("helper/request", () => { }); }); - it("- returns a http request object", () => { + it("- returns a promise if no callback provided", () => { - let req = request("http://127.0.0.1/"); + let rtrn = request("http://127.0.0.1/"); + + assert(rtrn instanceof Promise); + + }); + + it("- returns undefined if a callback is provided", (done) => { + + let rtrn = request("http://127.0.0.1/", (err) => { + assert(rtrn === undefined); + done(err); + }); + + }); + + it('- should have a ".perform" method patched', () => { + assert(request.perform instanceof Function); + }); + + it("- perform method should return instanceof ClientRequest", () => { + + let req = request.perform("http://127.0.0.1"); assert(req instanceof ClientRequest); From 3d6bd39509fd093ae231715e5e5ed6e29ff87adb Mon Sep 17 00:00:00 2001 From: Marc Date: Thu, 23 May 2024 10:47:12 +0200 Subject: [PATCH 161/186] version pumped from `v16` to `v20` --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2143f07..b360ac9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ # https://medium.com/@kahana.hagai/docker-compose-with-node-js-and-mongodb-dbdadab5ce0a # The instructions for the first stage -FROM node:16-alpine as builder +FROM node:20-alpine as builder ARG NODE_ENV=production ENV NODE_ENV=${NODE_ENV} @@ -22,7 +22,7 @@ RUN npm install # The instructions for second stage -FROM node:16-alpine +FROM node:20-alpine WORKDIR /opt/OpenHaus/backend COPY --from=builder node_modules node_modules From 2c643fb0facb52908fab6345ea73b7c11dc9b39a Mon Sep 17 00:00:00 2001 From: Marc Date: Thu, 23 May 2024 10:49:17 +0200 Subject: [PATCH 162/186] version pumped from `v16` to `v20`, see #459 --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2143f07..b360ac9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ # https://medium.com/@kahana.hagai/docker-compose-with-node-js-and-mongodb-dbdadab5ce0a # The instructions for the first stage -FROM node:16-alpine as builder +FROM node:20-alpine as builder ARG NODE_ENV=production ENV NODE_ENV=${NODE_ENV} @@ -22,7 +22,7 @@ RUN npm install # The instructions for second stage -FROM node:16-alpine +FROM node:20-alpine WORKDIR /opt/OpenHaus/backend COPY --from=builder node_modules node_modules From c9fc8af0525db541541f7e5ee4e041834ffd44b9 Mon Sep 17 00:00:00 2001 From: Marc Date: Fri, 24 May 2024 11:21:21 +0200 Subject: [PATCH 163/186] `injectMethod` added, see #463 --- helper/injectMethod.js | 33 ++++++++++++++ tests/helper/index.js | 1 + tests/helper/test.injectMethod.js | 76 +++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 helper/injectMethod.js create mode 100644 tests/helper/test.injectMethod.js diff --git a/helper/injectMethod.js b/helper/injectMethod.js new file mode 100644 index 0000000..0d16f35 --- /dev/null +++ b/helper/injectMethod.js @@ -0,0 +1,33 @@ +/** + * @function injectMethod + * Add a method to a given object into the prototype + * Default values are set to the exact same values when the method would be defined in the object/class body + * + * @param {Object} obj Object to add property to + * @param {String} prop The property name + * @param {*} value Value of the property + * @param {Object} [options={}] Property descriptor options + * @param {Boolean} [options.writable=true] + * @param {Boolean} [options.enumerable=false] + * @param {Boolean} [options.configurable=true] + * + * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#description + */ + +function injectMethod(obj, prop, value, options = {}){ + + if(!(value instanceof Function)){ + throw new TypeError(`Value must be a function, received ${typeof value}`); + } + + Object.defineProperty(Object.getPrototypeOf(obj), prop, { + value, + writable: true, + enumerable: false, + configurable: true, + ...options + }); + +} + +module.exports = injectMethod; \ No newline at end of file diff --git a/tests/helper/index.js b/tests/helper/index.js index adae309..73edb45 100644 --- a/tests/helper/index.js +++ b/tests/helper/index.js @@ -8,6 +8,7 @@ describe("Helper functions", function () { require("./test.extend.js"); //require("./test.filter.js"); // todo or remove?! see #19 require("./test.infinity.js"); + require("./test.injectMethod.js"); require("./test.iterate.js"); require("./test.mixins.js"); require("./test.observe.js"); diff --git a/tests/helper/test.injectMethod.js b/tests/helper/test.injectMethod.js new file mode 100644 index 0000000..20d06b0 --- /dev/null +++ b/tests/helper/test.injectMethod.js @@ -0,0 +1,76 @@ +const assert = require("assert"); +const { describe, it } = require("mocha"); + +const injectMethod = require("../../helper/injectMethod"); + +class Item{ + + constructor(){ + this.boolean = true; + } + + ping(){ + return this; + } + +} + +describe("helper/injectMethod", () => { + + it(`Define method on class protoype`, (done) => { + + let item = new Item(); + + injectMethod(item, "pong", function pong(){ + return this; + }); + + let proto = Object.getPrototypeOf(item); + let props = Object.getOwnPropertyNames(proto); + + assert.ok(props.includes("ping")); + assert.ok(props.includes("pong")); + + done(); + + }); + + + it(`Compare prototype descriptors of methods ping/pong`, (done) => { + + let item = new Item(); + + injectMethod(item, "pong", function(){ + return this; + }); + + let proto = Object.getPrototypeOf(item); + let ping = Object.getOwnPropertyDescriptor(proto, "ping"); + let pong = Object.getOwnPropertyDescriptor(proto, "pong"); + + // remove function (want only the descriptors); + delete ping.value; + delete pong.value; + + assert.deepEqual(ping, pong); + + done(); + + }); + + + it(`Check if "this" scope is set correctly for method`, (done) => { + + let item = new Item(); + + injectMethod(item, "pong", function(){ + return this; + }); + + assert.deepEqual(item.ping(), item.pong()); + + done(); + + }); + +}); \ No newline at end of file From 0e65d1c9f4acaf0932da7a0454ed40f1f85c8cc2 Mon Sep 17 00:00:00 2001 From: Marc Date: Fri, 24 May 2024 15:11:30 +0200 Subject: [PATCH 164/186] check added --- tests/helper/test.injectMethod.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/helper/test.injectMethod.js b/tests/helper/test.injectMethod.js index 20d06b0..913edef 100644 --- a/tests/helper/test.injectMethod.js +++ b/tests/helper/test.injectMethod.js @@ -68,6 +68,7 @@ describe("helper/injectMethod", () => { }); assert.deepEqual(item.ping(), item.pong()); + assert.ok(item.ping() === item.pong()); done(); From 5783cc6974e10c07c062ffe11bff7759c122867e Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sat, 25 May 2024 22:40:03 +0200 Subject: [PATCH 165/186] header & note added --- routes/router.system.logs.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/routes/router.system.logs.js b/routes/router.system.logs.js index 9f09d60..76f2cf3 100644 --- a/routes/router.system.logs.js +++ b/routes/router.system.logs.js @@ -237,6 +237,7 @@ module.exports = (router) => { }); }); + // NOTE: switch to GET method? router.post("/export", (req, res) => { try { @@ -255,6 +256,7 @@ module.exports = (router) => { } res.setHeader("content-type", "application/tar+gzip"); + res.setHeader("Content-Disposition", 'attachment; filename="logfiles.tgz"'); tar.once("exit", (code) => { console.log("exit code", code); From 57c730ff960536dbedc5ed92f108ac28fbacc7c4 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sat, 25 May 2024 22:59:46 +0200 Subject: [PATCH 166/186] comment/note added --- helper/injectMethod.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/helper/injectMethod.js b/helper/injectMethod.js index 0d16f35..03250d0 100644 --- a/helper/injectMethod.js +++ b/helper/injectMethod.js @@ -14,13 +14,15 @@ * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#description */ -function injectMethod(obj, prop, value, options = {}){ +function injectMethod(obj, prop, value, options = {}) { - if(!(value instanceof Function)){ + if (!(value instanceof Function)) { throw new TypeError(`Value must be a function, received ${typeof value}`); } - Object.defineProperty(Object.getPrototypeOf(obj), prop, { + // NOTE: Setting on prototype of given object, breaks iface.bridge()... + // Object.defineProperty(Object.getPrototypeOf(obj), prop, { + Object.defineProperty(obj, prop, { value, writable: true, enumerable: false, From fe8c2a94b920d7a09d62e65aa956ad13e1c9b4b2 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sat, 25 May 2024 23:01:46 +0200 Subject: [PATCH 167/186] fix #460 --- components/devices/class.device.js | 25 ++++++++- components/devices/class.interface.js | 79 +++++++++++++++++++++++++++ routes/router.api.devices.js | 69 ++++++++++++++--------- routes/router.system.connector.js | 72 ++++++++++++++++++++++++ routes/router.system.js | 5 ++ 5 files changed, 224 insertions(+), 26 deletions(-) create mode 100644 routes/router.system.connector.js diff --git a/components/devices/class.device.js b/components/devices/class.device.js index 0205f8c..3cf52d1 100644 --- a/components/devices/class.device.js +++ b/components/devices/class.device.js @@ -6,6 +6,9 @@ const Interface = require("./class.interface.js"); const Item = require("../../system/component/class.item.js"); const mixins = require("../../helper/mixins.js"); +const injectMethod = require("../../helper/injectMethod.js"); + +//const { parse, calculateChecksum } = require("./net-helper.js"); /** * @description @@ -25,7 +28,7 @@ const mixins = require("../../helper/mixins.js"); * @see interfaceStream components/devices/class.interfaceStream.js */ module.exports = class Device extends Item { - constructor(props) { + constructor(props, scope) { super(props); @@ -38,6 +41,11 @@ module.exports = class Device extends Item { // for each interface class, create a interface stream this.interfaces = props.interfaces.map((obj) => { + + // NOTE: refactor interfaceStream in v4 + // move .bridge method there and pass device instance? + // > Would this also create a ciruclar reference in Interface class + // > since its stored via `Object.defineProperty(this, "stream",...);` let stream = new InterfaceStream({ // duplex stream options emitClose: false @@ -50,6 +58,21 @@ module.exports = class Device extends Item { let iface = new Interface(obj, stream); + // inject bridge method into interface instance + // passing deivce instance into Interface class, creates a ciruclar reference + // TODO: Move this into "interfaceStream" (needs to be refactored) + // NOTE: remove "device" for bridging requests (only needed in connector)? + // > See: https://github.com/OpenHausIO/connector/issues/54 + // > When done, "device" property can be removed, and the `.bridge()` method can be moved into Interface class + injectMethod(iface, "bridge", (cb) => { + return Interface._bridge({ + events: scope.events, + interface: iface, + device: this._id + }, cb); + }); + + // "hide" stream behind iface object // so we can use the interface object // as duplex stream diff --git a/components/devices/class.interface.js b/components/devices/class.interface.js index 701d102..f95a6a8 100644 --- a/components/devices/class.interface.js +++ b/components/devices/class.interface.js @@ -2,6 +2,15 @@ const Joi = require("joi"); const { Agent } = require("http"); const mongodb = require("mongodb"); const { Transform, Duplex } = require("stream"); +const { randomUUID } = require("crypto"); +//const path = require("path"); + +//const Adapter = require("./class.adapter.js"); + + +const timeout = require("../../helper/timeout.js"); +const promisfy = require("../../helper/promisify.js"); + /** * @description @@ -372,5 +381,75 @@ module.exports = class Interface { } + // bridge methods connects adapter with the underlaying network socket + // create a `.socket()` method that returns the palin websocket stream + static _bridge({ device, interface: iface, events }, cb) { + return promisfy((done) => { + + console.log("Bridge request, iface", iface, device); + + // create a random uuid + // used as identifier for responses + let uuid = randomUUID(); + //let uuid = "4c6de542-f89f-42ac-a2b5-1c26f9e68d73"; + + + // timeout after certain time + // no connector available, not mocks or whatever reaseon + let caller = timeout(5000, (timedout, duration, args) => { + if (timedout) { + done(new Error("TIMEDOUT")); + } else { + done(null, args[0]); + } + }); + + + // socket response handler + // listen for uuid and compare it with generated + let handler = ({ stream, type, uuid: id, socket }) => { + if (uuid === id && type === "response" && socket) { + + console.log("adapter", iface.adapter); + + /* + // create adapter stack here + // pass adapter stack as caller argument + //caller(stack); + let stack = iface.adapter.map((name) => { + try { + return require(path.join(process.cwd(), "adapter", `${name}.js`))(); + } catch (err) { + console.error(`Error in adapter "${name}" `, err); + } + }); + + console.log("stack", stack); + + stream = new Adapter(stack, stream, { + emitClose: false, + end: false + }); + + console.log("stream", stream) + */ + + caller(stream); + + } + }; + + events.on("socket", handler); + + events.emit("socket", { + uuid, + device, + interface: iface._id, + type: "request" + }); + + }, cb); + } + }; \ No newline at end of file diff --git a/routes/router.api.devices.js b/routes/router.api.devices.js index 5ac6738..1bf2f11 100644 --- a/routes/router.api.devices.js +++ b/routes/router.api.devices.js @@ -1,5 +1,6 @@ const WebSocket = require("ws"); const { finished } = require("stream"); +const C_DEVICES = require("../components/devices"); //const iface_locked = new Map(); @@ -21,11 +22,12 @@ module.exports = (app, router) => { return String(iface._id) === String(req.params._iid); }); - if (!iface) { + if (!iface && !req.query?.socket) { return res.status(404).end(); } - if (iface.upstream) { + // allow multipel connections to new connection handling below + if (iface.upstream && !req.query?.socket) { return res.status(423).end(); } @@ -53,41 +55,50 @@ module.exports = (app, router) => { // listen only once to connectoin event // gets fired every time websocket client hit this url/route - wss.on("connection", (ws) => { + wss.on("connection", (ws, req) => { + if (req.query?.uuid && req.query?.socket === "true" && req.query?.type === "response") { - // set connection to "alive" - // see #148 - ws.isAlive = true; + // new bridge/connector practice + // see https://github.com/OpenHausIO/backend/issues/460 - let upstream = WebSocket.createWebSocketStream(ws); + let stream = WebSocket.createWebSocketStream(ws); - // Cleanup: https://nodejs.org/dist/latest-v16.x/docs/api/stream.html#streamfinishedstream-options-callback - let cleanup = finished(upstream, () => { - iface.detach(() => { - cleanup(); + C_DEVICES.events.emit("socket", { + uuid: req.query.uuid, + type: "response", + socket: true, + stream }); - }); + } else { - iface.attach(upstream); + // old/legacy connection mechanism + // TODO: Remove this in future versions + let upstream = WebSocket.createWebSocketStream(ws); - //https://github.com/websockets/ws#how-to-detect-and-close-broken-connections - ["close", "error"].forEach((event) => { - upstream.once(event, () => { + // Cleanup: https://nodejs.org/dist/latest-v16.x/docs/api/stream.html#streamfinishedstream-options-callback + let cleanup = finished(upstream, () => { + iface.detach(() => { + cleanup(); + }); + }); - upstream.destroy(); - iface.detach(); - }); - }); + iface.attach(upstream); - // detect broken connection - ws.on("pong", () => { - //console.log("pong", Date.now(), "\r\n\r\n") - ws.isAlive = true; - }); + //https://github.com/websockets/ws#how-to-detect-and-close-broken-connections + ["close", "error"].forEach((event) => { + upstream.once(event, () => { + + upstream.destroy(); + iface.detach(); + + }); + }); + + } }); @@ -119,7 +130,15 @@ module.exports = (app, router) => { wss.handleUpgrade(req, req.socket, req.headers, (ws) => { + + ws.isAlive = true; + + ws.on("pong", () => { + ws.isAlive = true; + }); + wss.emit("connection", ws, req); + }); } diff --git a/routes/router.system.connector.js b/routes/router.system.connector.js new file mode 100644 index 0000000..3dad200 --- /dev/null +++ b/routes/router.system.connector.js @@ -0,0 +1,72 @@ +const C_DEVICES = require("../components/devices"); + +// external modules +const WebSocket = require("ws"); + +module.exports = (router) => { + + // websocket server + let wss = new WebSocket.Server({ + noServer: true + }); + + // detect broken connections + let interval = setInterval(() => { + wss.clients.forEach((ws) => { + + if (!ws.isAlive) { + ws.terminate(); + return; + } + + ws.isAlive = false; + ws.ping(); + + }); + }, Number(process.env.API_WEBSOCKET_TIMEOUT)); + + + // if the server closes + // clear the interval + wss.on("close", () => { + clearInterval(interval); + }); + + + C_DEVICES.events.on("socket", (obj) => { + if (obj.type === "request") { + wss.clients.forEach((ws) => { + ws.send(JSON.stringify(obj)); + }); + } + }); + + + // http route handler + // TODO: Reformat to match router.api.mdns.js code style/if-else + router.get("/", (req, res, next) => { + + // check if connection is a simple get request or ws client + if ((!req.headers["upgrade"] || !req.headers["connection"])) { + //return res.status(403).end(); + next(); // let the rest-handler.js do its job + return; + } + + // handle request as websocket + // perform websocket handshake + wss.handleUpgrade(req, req.socket, req.headers, (ws) => { + + ws.isAlive = true; + + ws.on("pong", () => { + ws.isAlive = true; + }); + + wss.emit("connection", ws, req); + + }); + + }); + +}; \ No newline at end of file diff --git a/routes/router.system.js b/routes/router.system.js index a4de93c..8e332f0 100644 --- a/routes/router.system.js +++ b/routes/router.system.js @@ -20,6 +20,7 @@ module.exports = (router) => { let eventsRouter = Router(); let notificationsRouter = Router(); let logsRouter = Router(); + let connectorRouter = Router(); // http://127.0.0.1/api/system/info // FIXME: what does this work with "eventsRouter/notificationsRouter"?! @@ -38,4 +39,8 @@ module.exports = (router) => { router.use("/logs", logsRouter); require("./router.system.logs.js")(logsRouter); + // http://127.0.0.1/api/system/connector + router.use("/connector", connectorRouter); + require("./router.system.connector.js")(connectorRouter); + }; \ No newline at end of file From 4c32a6f23947d721e7c6e8a8203c64f122cef54f Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sat, 25 May 2024 23:01:54 +0200 Subject: [PATCH 168/186] note added --- routes/router.api.events.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/routes/router.api.events.js b/routes/router.api.events.js index 38503e7..83c0494 100644 --- a/routes/router.api.events.js +++ b/routes/router.api.events.js @@ -89,6 +89,9 @@ module.exports = (app, router) => { component.events.on(method, reemit(method, name)); }); + // NOTE: handle also custom events like "socket" & ssdp/mqtt events? + //component.events.on("socket", reemit("socket", name)); + } catch (err) { console.error("Failure in events http api", err); From 72fcfb66d832b6dd08ef82446ad8767ab5e3d56a Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sat, 25 May 2024 23:08:44 +0200 Subject: [PATCH 169/186] removed test --- tests/helper/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/helper/index.js b/tests/helper/index.js index 73edb45..8032d91 100644 --- a/tests/helper/index.js +++ b/tests/helper/index.js @@ -8,7 +8,7 @@ describe("Helper functions", function () { require("./test.extend.js"); //require("./test.filter.js"); // todo or remove?! see #19 require("./test.infinity.js"); - require("./test.injectMethod.js"); + //require("./test.injectMethod.js"); // removed due to problems on `interface.bridge()`, see https://github.com/OpenHausIO/backend/issues/463#issuecomment-2131411981 require("./test.iterate.js"); require("./test.mixins.js"); require("./test.observe.js"); From 9b0de28411945a3d6f672fd48172668e0d7248bc Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sat, 25 May 2024 23:14:37 +0200 Subject: [PATCH 170/186] fix #462 --- postman.json | 302 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 299 insertions(+), 3 deletions(-) diff --git a/postman.json b/postman.json index fd64cc2..2bfb08d 100644 --- a/postman.json +++ b/postman.json @@ -1674,7 +1674,8 @@ "exec": [ "" ], - "type": "text/javascript" + "type": "text/javascript", + "packages": {} } }, { @@ -1683,7 +1684,8 @@ "exec": [ "" ], - "type": "text/javascript" + "type": "text/javascript", + "packages": {} } } ], @@ -1697,7 +1699,7 @@ } }, "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/plugins/658188e93cde9987c3228806/files", + "raw": "http://{{HOST}}:{{PORT}}/api/plugins/658188e93cde9987c3228806/files?install=true", "protocol": "http", "host": [ "{{HOST}}" @@ -1708,6 +1710,13 @@ "plugins", "658188e93cde9987c3228806", "files" + ], + "query": [ + { + "key": "install", + "value": "true", + "description": "Install npm dependenys" + } ] } }, @@ -2743,6 +2752,293 @@ "response": [] } ] + }, + { + "name": "System", + "item": [ + { + "name": "Notifications", + "item": [ + { + "name": "Create notification", + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"Title\",\n \"message\": \"Hello World\",\n \"uuid\": \"83d2087a-d901-4eb5-ac05-f7980893df64\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/system/notifications?publish=false", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "system", + "notifications" + ], + "query": [ + { + "key": "publish", + "value": "false", + "description": "Publish notifications instantly?" + } + ] + } + }, + "response": [] + }, + { + "name": "Publish notification", + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/system/notifications/83d2087a-d901-4eb5-ac05-f7980893df64/publish", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "system", + "notifications", + "83d2087a-d901-4eb5-ac05-f7980893df64", + "publish" + ] + } + }, + "response": [] + }, + { + "name": "Delete notification", + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"Title\",\n \"message\": \"Hello World\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/system/notifications/83d2087a-d901-4eb5-ac05-f7980893df64", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "system", + "notifications", + "83d2087a-d901-4eb5-ac05-f7980893df64" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Logging", + "item": [ + { + "name": "Get log entrys", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/system/logs?offset=0&limit=10", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "system", + "logs" + ], + "query": [ + { + "key": "offset", + "value": "0" + }, + { + "key": "limit", + "value": "10" + } + ] + } + }, + "response": [] + }, + { + "name": "Create log entry", + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"message\": \"Hello World\", \n \"level\": \"error\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/system/logs", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "system", + "logs" + ] + } + }, + "response": [] + }, + { + "name": "Delete/Truncate logs", + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/system/logs?delete=false", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "system", + "logs" + ], + "query": [ + { + "key": "delete", + "value": "false", + "description": "Delete files or just truncate them?" + } + ] + } + }, + "response": [] + }, + { + "name": "Export (Download) logfiles as tar.gz", + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/system/logs/export", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "system", + "logs", + "export" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Information", + "item": [ + { + "name": "Software versions", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/system/info/versions", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "system", + "info", + "versions" + ] + } + }, + "response": [] + }, + { + "name": "System usage", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/system/info/usage", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "system", + "info", + "usage" + ] + } + }, + "response": [] + } + ] + } + ] } ], "event": [ From a4f381f711e3e6221c7a50974f6eae9efb2f90b1 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sun, 26 May 2024 12:27:42 +0200 Subject: [PATCH 171/186] fix #464 --- routes/router.system.notifications.js | 8 +++++--- system/notifications/class.notification.js | 7 ++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/routes/router.system.notifications.js b/routes/router.system.notifications.js index 89b13db..de17975 100644 --- a/routes/router.system.notifications.js +++ b/routes/router.system.notifications.js @@ -63,10 +63,12 @@ module.exports = (router) => { router.put("/", (req, res) => { - let { title, message } = req.body; - let notification = new Notification(title, message); + let notification = new Notification(req.body); + + if (req.query?.publish === "true") { + notification.publish(); + } - notification.publish(); res.json(notification); }); diff --git a/system/notifications/class.notification.js b/system/notifications/class.notification.js index bba40e6..9786940 100644 --- a/system/notifications/class.notification.js +++ b/system/notifications/class.notification.js @@ -28,12 +28,9 @@ const notifications = new Proxy([], { module.exports = class Notification { - constructor(title, message) { + constructor(data) { - let { error, value } = Notification.validate({ - title, - message - }); + let { error, value } = Notification.validate(data); if (error) { throw error; From 518bf50b7f11ba5a3958a45b7ba15061f0ae6ebd Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sun, 26 May 2024 12:36:34 +0200 Subject: [PATCH 172/186] improved --- routes/router.system.notifications.js | 34 ++++++++++++++++++++++ system/notifications/class.notification.js | 14 ++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/routes/router.system.notifications.js b/routes/router.system.notifications.js index de17975..4f2e6ac 100644 --- a/routes/router.system.notifications.js +++ b/routes/router.system.notifications.js @@ -40,6 +40,25 @@ module.exports = (router) => { }); + router.param("uuid", (req, res, next, uid) => { + + let notifications = Notification.notifications(); + + let notification = notifications.find(({ uuid }) => { + return uuid === uid; + }); + + if (!notification) { + return res.status(404).end(); + } + + req.item = notification; + + next(); + + }); + + router.get("/", (req, res) => { if ((!req.headers["upgrade"] || !req.headers["connection"])) { @@ -74,6 +93,21 @@ module.exports = (router) => { }); + router.post("/:uuid/publish", (req, res) => { + + req.item.publish(); + res.json(req.item); + + }); + + + router.delete("/:uuid", (req, res) => { + + req.item.detain(); + res.json(req.item); + + }); + return router; }; \ No newline at end of file diff --git a/system/notifications/class.notification.js b/system/notifications/class.notification.js index 9786940..6dd30c4 100644 --- a/system/notifications/class.notification.js +++ b/system/notifications/class.notification.js @@ -41,11 +41,13 @@ module.exports = class Notification { Object.assign(this, { timestamps: { created: Date.now(), - published: false + published: null } }, value); // hidden property + // move into schema definition? + // why keep this secret? Object.defineProperty(this, "published", { value: false, writable: true @@ -82,6 +84,16 @@ module.exports = class Notification { } } + detain() { + + let index = notifications.find(({ uuid }) => { + return this.uuid === uuid; + }); + + notifications.splice(index, 1); + + } + static schema() { return Joi.object({ title: Joi.string().required(), From 60cde33c9ed861ac28faa542768e72c06f95b0d2 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sun, 26 May 2024 12:37:34 +0200 Subject: [PATCH 173/186] updated --- postman.json | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/postman.json b/postman.json index 2bfb08d..135105d 100644 --- a/postman.json +++ b/postman.json @@ -2766,7 +2766,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"title\": \"Title\",\n \"message\": \"Hello World\",\n \"uuid\": \"83d2087a-d901-4eb5-ac05-f7980893df64\"\n}", + "raw": "{\n \"title\": \"Title\",\n \"message\": \"Hello World\",\n \"type\": \"error\",\n \"uuid\": \"83d2087a-d901-4eb5-ac05-f7980893df64\"\n}", "options": { "raw": { "language": "json" @@ -2796,6 +2796,39 @@ }, "response": [] }, + { + "name": "Get notifications", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"Title\",\n \"message\": \"Hello World\",\n \"type\": \"error\",\n \"uuid\": \"83d2087a-d901-4eb5-ac05-f7980893df64\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/system/notifications", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "system", + "notifications" + ] + } + }, + "response": [] + }, { "name": "Publish notification", "request": { From fc1eb7ba157fdc8dd9716ba2b719d7ee5bada09e Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sun, 26 May 2024 13:38:02 +0200 Subject: [PATCH 174/186] fix #462 --- postman.json | 296 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) diff --git a/postman.json b/postman.json index 135105d..d52d0e4 100644 --- a/postman.json +++ b/postman.json @@ -2579,6 +2579,302 @@ "response": [] } ] + }, + { + "name": "Webhooks", + "item": [ + { + "name": "Create new webhook", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"_id\": \"647c29cb62ad0449380f0abe\",\n \"name\": \"Test Webhook as trigger for scenes\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/webhooks", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "webhooks" + ] + } + }, + "response": [] + }, + { + "name": "Get all webhooks", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "x-auth-token", + "value": "eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImhhbnMuaHViZXJ0QGV4YW1wbGUuY29tIiwidXVpZCI6ImM3N2E3NjJkLWM4ODYtNGQ2My1iNGM1LWU0MDJhZGNmYTdiZSIsImlhdCI6MTY1NDI2ODI4NX0.w4mkvTuJ-OXzTcmvWhwIT84oOmo2399hSEfWGbA-9SUWndMWUiHvly1A7-kSV93e", + "type": "text", + "disabled": true + } + ], + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/webhooks", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "webhooks" + ] + } + }, + "response": [] + }, + { + "name": "Get sinlge webhook", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/webhooks/647c29cb62ad0449380f0abe", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "webhooks", + "647c29cb62ad0449380f0abe" + ] + } + }, + "response": [] + }, + { + "name": "Update existing webhook", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"Trigger scene \"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/webhooks/647c29cb62ad0449380f0abe", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "webhooks", + "647c29cb62ad0449380f0abe" + ] + } + }, + "response": [] + }, + { + "name": "Update existing webhook", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/webhooks/647c29cb62ad0449380f0abe/trigger", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "webhooks", + "647c29cb62ad0449380f0abe", + "trigger" + ] + } + }, + "response": [] + }, + { + "name": "Delete exisiting room", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/webhooks/647c29cb62ad0449380f0abe", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "webhooks", + "647c29cb62ad0449380f0abe" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] } ], "auth": { From 4472b5c25a252cd9c93f65af7fe78fc8b2072c2e Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sun, 26 May 2024 13:38:15 +0200 Subject: [PATCH 175/186] minor bug fix --- routes/router.api.webhooks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/router.api.webhooks.js b/routes/router.api.webhooks.js index 2a34257..06a752d 100644 --- a/routes/router.api.webhooks.js +++ b/routes/router.api.webhooks.js @@ -49,7 +49,7 @@ module.exports = (app, router) => { req.item._trigger(req.body, req.query, req); } - res.status(202).end(); + res.status(202).json(req.item); }); From 154d144099824577ef9974d8ebfd23b1a8c67eac Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Thu, 30 May 2024 22:28:33 +0200 Subject: [PATCH 176/186] fix #468 --- package-lock.json | 175 +++++++++++++++------ package.json | 1 + routes/router.system.backup.js | 280 +++++++++++++++++++++++++++++++++ routes/router.system.js | 5 + 4 files changed, 416 insertions(+), 45 deletions(-) create mode 100644 routes/router.system.backup.js diff --git a/package-lock.json b/package-lock.json index ac1fe69..aa307e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "mongodb": "^4.11.0", "mqtt-packet": "^8.1.2", "semver": "^7.5.4", + "tar-stream": "^3.1.7", "uuid": "^9.0.0", "ws": "^8.10.0" }, @@ -1768,6 +1769,33 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/archiver/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/archiver/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/are-we-there-yet": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", @@ -1863,11 +1891,22 @@ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", "dev": true }, + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/bare-events": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.3.1.tgz", + "integrity": "sha512-sJnSOTVESURZ61XgEleqmP255T6zTYwHPwE4r6SssIh0U9/uDvfpdoJYpVUerJJZH2fueO+CdT8ZT+OC/7aZDA==", + "optional": true + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -2925,6 +2964,11 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, "node_modules/fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", @@ -5971,6 +6015,11 @@ } ] }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -6495,6 +6544,18 @@ "bluebird": "^2.6.2" } }, + "node_modules/streamx": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.17.0.tgz", + "integrity": "sha512-mzRXEeafEA0skX5XLiDht/zdIqEVs4kgayUTFHDoMjiaZ2kC7DoFsQDJVXRILI2Qme/kWXxLpuU6P0B+xcXpFA==", + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -6586,30 +6647,13 @@ } }, "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar-stream/node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" } }, "node_modules/teleport-javascript": { @@ -8498,6 +8542,32 @@ "readdir-glob": "^1.0.0", "tar-stream": "^2.2.0", "zip-stream": "^4.1.0" + }, + "dependencies": { + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + } } }, "archiver-utils": { @@ -8627,11 +8697,22 @@ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", "dev": true }, + "b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==" + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "bare-events": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.3.1.tgz", + "integrity": "sha512-sJnSOTVESURZ61XgEleqmP255T6zTYwHPwE4r6SssIh0U9/uDvfpdoJYpVUerJJZH2fueO+CdT8ZT+OC/7aZDA==", + "optional": true + }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -9417,6 +9498,11 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, "fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", @@ -11746,6 +11832,11 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -12133,6 +12224,16 @@ "bluebird": "^2.6.2" } }, + "streamx": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.17.0.tgz", + "integrity": "sha512-mzRXEeafEA0skX5XLiDht/zdIqEVs4kgayUTFHDoMjiaZ2kC7DoFsQDJVXRILI2Qme/kWXxLpuU6P0B+xcXpFA==", + "requires": { + "bare-events": "^2.2.0", + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -12200,29 +12301,13 @@ } }, "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "requires": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - } + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" } }, "teleport-javascript": { diff --git a/package.json b/package.json index 5c67186..207659d 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "mongodb": "^4.11.0", "mqtt-packet": "^8.1.2", "semver": "^7.5.4", + "tar-stream": "^3.1.7", "uuid": "^9.0.0", "ws": "^8.10.0" }, diff --git a/routes/router.system.backup.js b/routes/router.system.backup.js new file mode 100644 index 0000000..9837513 --- /dev/null +++ b/routes/router.system.backup.js @@ -0,0 +1,280 @@ +const crypto = require("crypto"); +const zlib = require("zlib"); +const path = require("path"); +const fs = require("fs"); +const { Writable, pipeline } = require("stream"); +const { createInterface } = require("readline"); +const { EOL } = require("os"); + +const { client } = require("mongodb"); +const tar = require("tar-stream"); + + +const BASE_PATH = path.join(process.cwd(), "./plugins"); +const ALGORITHM = "aes-256-cbc"; + + +module.exports = (router) => { + + router.post("/export", async (req, res) => { + + const pack = tar.pack(); + + res.setHeader("content-type", "application/tar+gzip"); + res.setHeader("dontent-disposition", `attachment; filename="backend-${Date.now()}.tgz"`); + + if (req.query.encrypt == "true") { + + const key = crypto.randomBytes(32); + const iv = crypto.randomBytes(16); + + res.setHeader("X-ENCRYPTION-KEY", key.toString("hex")); + res.setHeader("X-ENCRYPTION-IV", iv.toString("hex")); + + const cipher = crypto.createCipheriv(ALGORITHM, key, iv); + pack.pipe(zlib.createGzip()).pipe(cipher).pipe(res); + + } else { + + pack.pipe(zlib.createGzip()).pipe(res); + + } + + + if ((req.query?.includes?.includes("database") || (!req.query?.includes && true))) { + for await (let collection of client.listCollections()) { + + // TODO: check/handle binary (serialized buffer objects) + // > endpoint commands payload + // > _id's should be mongodb object id's + let data = (await client.collection(collection.name).find().toArray()); + pack.entry({ name: `database/${collection.name}.json` }, JSON.stringify(data)); + + } + } + + if ((req.query?.includes?.includes("plugins") || (!req.query?.includes && true))) { + fs.readdirSync(BASE_PATH, { + recursive: true + }).filter((entry) => { + + // TODO: ignore .gitkeep file + return !fs.statSync(path.join(BASE_PATH, entry)).isDirectory(); + + }).map((entry) => { + + return [entry, fs.readFileSync(path.join(BASE_PATH, entry), "utf8")]; + + }).forEach(([file, content]) => { + + pack.entry({ name: `plugins/${file}` }, content); + + }); + } + + + if ((req.query?.includes?.includes("env") || (!req.query?.includes && true))) { + + // encode .env value as base64, so the are not human readable + let content = fs.readFileSync(path.join(process.cwd(), ".env"), "utf8").split(EOL).map((line) => { + + if (req.query?.encode !== "true") { + return line; + } + + let [key, value] = line.split("="); + + if (!value) { + return line; + } + + return `${key}=${Buffer.from(value).toString("base64")}`; + + }); + + pack.entry({ name: `.env` }, content.join(EOL)); + + } + + pack.finalize(); + + }); + + + router.post("/import", async (req, res) => { + + const extract = tar.extract(); + + + extract.on("error", (err) => { + + res.status(500).json({ + error: err.message, + details: err, + success: false + }); + + console.log("Terrible error", err); + //process.exit(1); + + }); + + + extract.on("finish", () => { + + console.log("tar-stream finished"); + + res.json({ + success: true, + message: "Restart to apply changes!" + }); + + }); + + + if (req.query.encrypt == "true") { + + const key = Buffer.from(req.headers["x-encryption-key"], "hex"); + const iv = Buffer.from(req.headers["x-encryption-iv"], "hex"); + const decipher = crypto.createDecipheriv(ALGORITHM, key, iv); + + pipeline(req, decipher, zlib.createGunzip(), extract, (err) => { + if (err) { + + console.error("encrypted", err); + + } + }); + + } else { + + pipeline(req, zlib.createGunzip(), extract, (err) => { + if (err) { + + console.error("uncrypted", err); + + } + }); + + } + + + extract.on("entry", async (header, stream, next) => { + if (header.name.startsWith("database/")) { + + console.log("restartoe database collection", header); + + let chunks = []; + let name = header.name.replace("database/", ""); + + let writeable = new Writable({ + write(chunk, enc, cb) { + chunks.push(chunk); + cb(null); + } + }); + + stream.pipe(writeable).on("close", async () => { + + // TODO: check/handle binary (serialized buffer objects) + // > endpoint commands payload + // > _id's should be mongodb object id's + let documents = JSON.parse(Buffer.concat(chunks).toString()); + + // prevents bulk write error + // MongoInvalidArgumentError: Invalid BulkOperation, Batch cannot be empty + if (documents.length === 0) { + next(); + return; + } + + console.log("collection name", path.basename(name, ".json")); + + let collection = client.collection(path.basename(name, ".json")); + + if (req.query?.truncate === "true") { + await collection.deleteMany({}); + } + + collection.insertMany(documents).catch((err) => { + if (err?.code === 11000 && req.query?.skipDuplicates === "true") { + next(); + } else { + next(err); + } + }).then(() => { + next(); + }); + + }); + + } else if (header.name.startsWith("plugins/")) { + + console.log("restroe plugin file", header); + + // NOTE: this also deletes .gitkeep + if (req.query?.truncate === "true") { + for (let file of await fs.promises.readdir(BASE_PATH)) { + await fs.promises.rm(path.join(BASE_PATH, file), { + recursive: true, + force: true + }); + } + } + + let name = header.name.replace("plugins/", ""); + + fs.mkdirSync(path.dirname(path.join(BASE_PATH, name)), { + recursive: true + }); + + stream.pipe(fs.createWriteStream(path.join(BASE_PATH, name))).once("error", (err) => { + next(err); + }).once("close", () => { + next(); + }); + + } else if (header.name === ".env") { + + if (req.query?.truncate === "true") { + fs.truncateSync(path.join(process.cwd(), ".env")); + } + + let rl = createInterface({ + input: stream + }); + + rl.once("error", (err) => { + next(err); + }); + + rl.once("close", () => { + next(); + }); + + rl.on("line", (line) => { + + let [key, value] = line.split("="); + + if (!key || !value || req.query?.decode !== "true") { + return fs.appendFileSync(path.join(process.cwd(), ".env"), line + EOL); + } + + line = `${key}=${Buffer.from(value, "base64").toString()}`; + fs.appendFileSync(path.join(process.cwd(), ".env"), line + EOL); + + }); + + } else { + + console.log("unknown file prefix/name", header); + + } + }); + + + + + }); + +}; \ No newline at end of file diff --git a/routes/router.system.js b/routes/router.system.js index 8e332f0..a7f2fbc 100644 --- a/routes/router.system.js +++ b/routes/router.system.js @@ -21,6 +21,7 @@ module.exports = (router) => { let notificationsRouter = Router(); let logsRouter = Router(); let connectorRouter = Router(); + let backupRouter = Router(); // http://127.0.0.1/api/system/info // FIXME: what does this work with "eventsRouter/notificationsRouter"?! @@ -43,4 +44,8 @@ module.exports = (router) => { router.use("/connector", connectorRouter); require("./router.system.connector.js")(connectorRouter); + // http://127.0.0.1/api/system/backup + router.use("/backup", backupRouter); + require("./router.system.backup.js")(backupRouter); + }; \ No newline at end of file From d7f88044ef2fab9f6011f049a11e407061355744 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 31 May 2024 20:19:35 +0200 Subject: [PATCH 177/186] note added --- routes/router.system.backup.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/routes/router.system.backup.js b/routes/router.system.backup.js index 9837513..6800007 100644 --- a/routes/router.system.backup.js +++ b/routes/router.system.backup.js @@ -20,6 +20,8 @@ module.exports = (router) => { const pack = tar.pack(); + // NOTE: add error listener here? + res.setHeader("content-type", "application/tar+gzip"); res.setHeader("dontent-disposition", `attachment; filename="backend-${Date.now()}.tgz"`); @@ -105,7 +107,7 @@ module.exports = (router) => { const extract = tar.extract(); - + // NOTE: switch to `.once`? extract.on("error", (err) => { res.status(500).json({ @@ -120,6 +122,7 @@ module.exports = (router) => { }); + // NOTE: switch to `.once`? extract.on("finish", () => { console.log("tar-stream finished"); From f48f85b52403baf69b8e1fa924f51a69f71b4603 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 31 May 2024 20:23:01 +0200 Subject: [PATCH 178/186] typo fixed --- routes/router.system.backup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/router.system.backup.js b/routes/router.system.backup.js index 6800007..dad9b84 100644 --- a/routes/router.system.backup.js +++ b/routes/router.system.backup.js @@ -23,7 +23,7 @@ module.exports = (router) => { // NOTE: add error listener here? res.setHeader("content-type", "application/tar+gzip"); - res.setHeader("dontent-disposition", `attachment; filename="backend-${Date.now()}.tgz"`); + res.setHeader("content-disposition", `attachment; filename="backend-${Date.now()}.tgz"`); if (req.query.encrypt == "true") { From 2d02fc92a9fb1414d1298c4be5d0eec6c2dbaba0 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 31 May 2024 20:57:41 +0200 Subject: [PATCH 179/186] fix #472 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 207659d..d4438fc 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "publish": "grunt publish" }, "engines": { - "node": ">=0.16.0" + "node": ">=18.0.0" }, "author": "Marc Stirner ", "license": "ISC", From a8b119246132e787d7549c402519ac7c29567207 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 31 May 2024 21:00:51 +0200 Subject: [PATCH 180/186] fix #471 --- index.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/index.js b/index.js index ff4aadf..c1cea04 100644 --- a/index.js +++ b/index.js @@ -4,6 +4,7 @@ const process = require("process"); const pkg = require("./package.json"); const { exec } = require("child_process"); const uuid = require("uuid"); +const semver = require("semver"); const env = require("dotenv").config({ @@ -120,6 +121,12 @@ if (process.env.NODE_ENV !== "production") { } +// see #471 +if (!semver.satisfies(process.versions.node, pkg.engines.node)) { + logger.warn(`> OpenHaus runs not on supported node.js version! (got: "%s", needed: "%s")`, process.versions.node, pkg.engines.node); +} + + if (process.env.GC_INTERVAL !== null && global.gc) { setInterval(() => { try { From 1702bdeb5303049d2634aee8c674095a562efa67 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 31 May 2024 22:21:10 +0200 Subject: [PATCH 181/186] updated --- postman.json | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/postman.json b/postman.json index d52d0e4..330f685 100644 --- a/postman.json +++ b/postman.json @@ -3366,6 +3366,130 @@ "response": [] } ] + }, + { + "name": "Backup", + "item": [ + { + "name": "Export Backup", + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/system/backup/export?encode=false", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "system", + "backup", + "export" + ], + "query": [ + { + "key": "encrypt", + "value": "false", + "description": "Should the .tgz (.tar.gz) file be encrypted?", + "disabled": true + }, + { + "key": "includes[]", + "value": "database", + "description": "Should include database dump?", + "disabled": true + }, + { + "key": "includes[]", + "value": "plugins", + "description": "Should include plugins folder?", + "disabled": true + }, + { + "key": "includes[]", + "value": "env", + "description": "Should indlude .env file?", + "disabled": true + }, + { + "key": "encode", + "value": "false", + "description": "Encode .env values as base64? (makes them not human readable, do this at least when you dont encrypt the backup)" + } + ] + } + }, + "response": [] + }, + { + "name": "Import Backup", + "request": { + "method": "POST", + "header": [ + { + "key": "X-ENCRYPTION-KEY", + "value": "1e3665f8a687da2d0869ff524c10e64ee1cb600df8228c6dfcc37fbec3359846", + "description": "Header value from export (If backup is encrpyted)", + "type": "text" + }, + { + "key": "X-ENCRYPTION-IV", + "value": "186cfe92205c578a7f7199d3c973b8bd", + "description": "Header value from export (If backup is encrpyted)", + "type": "text" + } + ], + "body": { + "mode": "file", + "file": { + "src": "/home/marc/projects/OpenHaus/tmp/backup-staging.tgz" + } + }, + "url": { + "raw": "http://{{HOST}}:{{PORT}}/api/system/backup/import?truncate=true", + "protocol": "http", + "host": [ + "{{HOST}}" + ], + "port": "{{PORT}}", + "path": [ + "api", + "system", + "backup", + "import" + ], + "query": [ + { + "key": "encrypt", + "value": "true", + "description": "Is the uploading file encrypted?", + "disabled": true + }, + { + "key": "skipDuplicates", + "value": "true", + "description": "Skip same databse _id items", + "disabled": true + }, + { + "key": "truncate", + "value": "true", + "description": "Truncate/clear database & plugin folder before restore" + }, + { + "key": "decode", + "value": "true", + "description": "Decode base64 .env values", + "disabled": true + } + ] + } + }, + "response": [] + } + ] } ] } From fd9c3891a3162a4b5ca712a41074a37647cf07e9 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 31 May 2024 22:56:21 +0200 Subject: [PATCH 182/186] test updates --- postman.json | 86 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 32 deletions(-) diff --git a/postman.json b/postman.json index 330f685..d91cf58 100644 --- a/postman.json +++ b/postman.json @@ -2895,35 +2895,6 @@ "script": { "type": "text/javascript", "exec": [ - "let IGNORE = {", - " \"PUT\": [", - " \"/api/plugins/658188e93cde9987c3228806/files\"", - " ],", - " \"POST\": [", - " \"/api/plugins/658188e93cde9987c3228806/start\",", - " \"/api/endpoints/658189336fa19198939caa21/commands/6581fc8ac20cb522e02868ff\"", - " ]", - "};", - "", - "", - "console.log(\"Check ignore object\", pm.request.method, pm.request.url.toString());", - "", - "", - "if(Object.prototype.hasOwnProperty.call(IGNORE, pm.request.method)){", - "", - " let skip = IGNORE[pm.request.method].some((url) => {", - " return pm.request.url.toString().includes(url);", - " });", - "", - " console.log(\"Ignore\", pm.request.url.toString(), skip);", - "", - " if(skip){", - " return;", - " }", - "", - "}", - "", - "", "pm.test(\"Status code 200 || 202\", () => {", " pm.expect(pm.response.code).to.be.oneOf([", " 200,", @@ -3376,7 +3347,7 @@ "method": "POST", "header": [], "url": { - "raw": "http://{{HOST}}:{{PORT}}/api/system/backup/export?encode=false", + "raw": "http://{{HOST}}:{{PORT}}/api/system/backup/export", "protocol": "http", "host": [ "{{HOST}}" @@ -3416,7 +3387,8 @@ { "key": "encode", "value": "false", - "description": "Encode .env values as base64? (makes them not human readable, do this at least when you dont encrypt the backup)" + "description": "Encode .env values as base64? (makes them not human readable, do this at least when you dont encrypt the backup)", + "disabled": true } ] } @@ -3491,6 +3463,28 @@ } ] } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "packages": {}, + "exec": [ + "postman.setNextRequest()" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "packages": {}, + "exec": [ + "" + ] + } + } ] } ], @@ -3509,7 +3503,35 @@ "script": { "type": "text/javascript", "exec": [ - "" + "let IGNORE = {", + " \"PUT\": [", + " \"/api/plugins/658188e93cde9987c3228806/files\"", + " ],", + " \"POST\": [", + " \"/api/plugins/658188e93cde9987c3228806/start\",", + " \"/api/endpoints/658189336fa19198939caa21/commands/6581fc8ac20cb522e02868ff\",", + " \"/api/system\"", + " ]", + "};", + "", + "", + "console.log(\"Check ignore object\", pm.request.method, pm.request.url.toString());", + "", + "", + "if(Object.prototype.hasOwnProperty.call(IGNORE, pm.request.method)){", + "", + " let skip = IGNORE[pm.request.method].some((url) => {", + " return pm.request.url.toString().includes(url);", + " });", + "", + " console.log(\"Ignore\", pm.request.url.toString(), skip);", + "", + " if(skip){", + " postman.setNextRequest(null);", + " return;", + " }", + "", + "}" ] } } From 0901574a1512de67a67725db371e6d900571db5b Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 31 May 2024 23:01:02 +0200 Subject: [PATCH 183/186] removed http tests --- tests/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/index.js b/tests/index.js index 8e91993..672eb9e 100644 --- a/tests/index.js +++ b/tests/index.js @@ -67,7 +67,7 @@ describe("Database", () => { require("./helper/index.js"); require("./system/index.js"); require("./components/index.js"); - require("./http-api/index.js"); + //require("./http-api/index.js"); }); }); From 4b7cdaabcfe70d83199cc8658d87fa3f0cb4bb95 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Mon, 3 Jun 2024 22:18:52 +0200 Subject: [PATCH 184/186] fix #455 --- components/plugins/class.plugin.js | 12 +++- postman.json | 92 ++++++++++++++++++------------ tests/components/plugins.js | 8 +-- 3 files changed, 70 insertions(+), 42 deletions(-) diff --git a/components/plugins/class.plugin.js b/components/plugins/class.plugin.js index 8e5d188..f11e1d7 100644 --- a/components/plugins/class.plugin.js +++ b/components/plugins/class.plugin.js @@ -61,7 +61,17 @@ module.exports = class Plugin extends Item { uuid: Joi.string().default(() => { return uuid.v4(); }), - version: Joi.number().required(), + version: Joi.string().required().messages({ + "any.invalid": `{{#label}} needs to be a valid semver version` + }).custom((value, helpers) => { + + if (semver.valid(value) === null) { + return helpers.error("any.invalid"); + } + + return semver.clean(value); + + }), //runlevel: Joi.number().min(0).max(2).default(0), autostart: Joi.boolean().default(true), enabled: Joi.boolean().default(true), diff --git a/postman.json b/postman.json index d91cf58..73ca0b8 100644 --- a/postman.json +++ b/postman.json @@ -1,6 +1,6 @@ { "info": { - "_postman_id": "efc273f1-779c-4fce-a23e-82c17555ff65", + "_postman_id": "af00c0a1-994e-4e2c-aac9-422c102b70f1", "name": "OpenHaus", "description": "SmartHome/IoT application", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", @@ -1571,7 +1571,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"_id\": \"658188e93cde9987c3228806\",\n \"name\": \"Plugin Boilerplate Demo\",\n \"uuid\": \"6951dee2-8541-4a69-bd3e-629fdadf093a\",\n \"enabled\": true,\n \"version\": 1,\n \"intents\": [\n \"devices\",\n \"endpoints\",\n \"plugins\",\n \"rooms\",\n \"ssdp\",\n \"store\",\n \"users\",\n \"vault\"\n ]\n}", + "raw": "{\n \"_id\": \"658188e93cde9987c3228806\",\n \"name\": \"Plugin Boilerplate Demo\",\n \"uuid\": \"6951dee2-8541-4a69-bd3e-629fdadf093a\",\n \"enabled\": true,\n \"version\": \"1.0.0\",\n \"intents\": [\n \"devices\",\n \"endpoints\",\n \"plugins\",\n \"rooms\",\n \"ssdp\",\n \"store\",\n \"users\",\n \"vault\"\n ]\n}", "options": { "raw": { "language": "json" @@ -1642,7 +1642,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"name\": \"New updated\",\n \"enabled\": true,\n \"autostart\": false,\n \"labels\": [\n \"worker_thread=false\",\n \"my_custom_label={\\\"json\\\":true, \\\"number\\\":0815420}\"\n ]\n}", + "raw": "{\n \"name\": \"New updated\",\n \"enabled\": true,\n \"autostart\": false,\n \"version\": \"9.2.5\",\n \"labels\": [\n \"worker_thread=false\",\n \"my_custom_label={\\\"json\\\":true, \\\"number\\\":0815420}\"\n ]\n}", "options": { "raw": { "language": "json" @@ -2895,32 +2895,7 @@ "script": { "type": "text/javascript", "exec": [ - "pm.test(\"Status code 200 || 202\", () => {", - " pm.expect(pm.response.code).to.be.oneOf([", - " 200,", - " 202", - " ]);", - "});", - "", - "", - "pm.test(\"content-type = application/json\", () => {", - " pm.expect(pm.response.headers.get('Content-Type')).to.include('application/json');", - "});", - "", - "", - "pm.test(\"Response has no error field\", () => {", - "", - " let length = pm.response.headers.get(\"content-length\");", - "", - " // ignore empty response/no body", - " if(!length || Number(length) === 0){", - " return;", - " }", - "", - " let json = pm.response.json();", - " pm.expect(!json.error, true);", - "", - "});" + "" ] } } @@ -3494,7 +3469,12 @@ "script": { "type": "text/javascript", "exec": [ - "" + "console.log(\"Check if /system route\", pm.request.url.toString().includes(\"/system\"), pm.request.url.toString().includes(\"/auth\"))", + "", + "if(pm.request.url.toString().includes(\"/system\") || pm.request.url.toString().includes(\"/auth\")){", + " postman.setNextRequest(null);", + " return;", + "}" ] } }, @@ -3509,29 +3489,67 @@ " ],", " \"POST\": [", " \"/api/plugins/658188e93cde9987c3228806/start\",", - " \"/api/endpoints/658189336fa19198939caa21/commands/6581fc8ac20cb522e02868ff\",", - " \"/api/system\"", + " \"/api/endpoints/658189336fa19198939caa21/commands/6581fc8ac20cb522e02868ff\"", + " ],", + " \"GET\": [", + " \"/auth\"", " ]", "};", "", + "let URLS = [", + " \"auth\",", + " \"system\"", + "]", "", "console.log(\"Check ignore object\", pm.request.method, pm.request.url.toString());", "", "", "if(Object.prototype.hasOwnProperty.call(IGNORE, pm.request.method)){", "", - " let skip = IGNORE[pm.request.method].some((url) => {", + " let skip1 = IGNORE[pm.request.method].some((url) => {", " return pm.request.url.toString().includes(url);", " });", "", - " console.log(\"Ignore\", pm.request.url.toString(), skip);", + " let skip2 = URLS.some((url) => {", + " return pm.request.url.toString().includes(url);", + " });", "", - " if(skip){", - " postman.setNextRequest(null);", + "", + " console.log(\"Ignore\", pm.request.url.toString(), skip1 || skip2);", + "", + " if(skip1 || skip2){", " return;", " }", "", - "}" + "}", + "", + "", + "pm.test(\"Status code 200 || 202\", () => {", + " pm.expect(pm.response.code).to.be.oneOf([", + " 200,", + " 202", + " ]);", + "});", + "", + "", + "pm.test(\"content-type = application/json\", () => {", + " pm.expect(pm.response.headers.get('Content-Type')).to.include('application/json');", + "});", + "", + "", + "pm.test(\"Response has no error field\", () => {", + "", + " let length = pm.response.headers.get(\"content-length\");", + "", + " // ignore empty response/no body", + " if(!length || Number(length) === 0){", + " return;", + " }", + "", + " let json = pm.response.json();", + " pm.expect(!json.error, true);", + "", + "});" ] } } diff --git a/tests/components/plugins.js b/tests/components/plugins.js index 7c08e3b..3c54233 100644 --- a/tests/components/plugins.js +++ b/tests/components/plugins.js @@ -15,7 +15,7 @@ try { C_COMPONENT.add({ _id, name: "Plugin #1", - version: 1, + version: "1.2.3", intents: ["devices", "endpoints", "plugins", "rooms", "ssdp", "store", "users", "vault"] }, (err, item) => { try { @@ -59,13 +59,13 @@ try { workflow(C_COMPONENT, "update", (done) => { C_COMPONENT.update(_id, { - version: 2 + version: "2.3.8" }, (err, item) => { try { assert.ok(err === null); assert.equal(item instanceof Plugin, true); - assert.equal(item.version, 2); + assert.equal(item.version, "2.3.8"); done(err); @@ -83,7 +83,7 @@ try { // update call 1 C_COMPONENT.update(_id, { - version: 3 + version: "87.65.4321" }), // update call 2 From be3a8477f92ff95bac6e12cdeff0c19675e339df Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sat, 15 Jun 2024 20:22:31 +0200 Subject: [PATCH 185/186] comment added --- components/plugins/class.plugin.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/plugins/class.plugin.js b/components/plugins/class.plugin.js index f11e1d7..26ba9ca 100644 --- a/components/plugins/class.plugin.js +++ b/components/plugins/class.plugin.js @@ -104,6 +104,9 @@ module.exports = class Plugin extends Item { let content = fs.readFileSync(file); json = JSON.parse(content); + // check in further version: + // json?.openhaus?.backend || json?.openhaus?.versions?.backend + // when a plugin provides frontend stuff or store data about itself in openhaus.plugin/openhaus.intents if (!semver.satisfies(pkg.version, json?.backend)) { this.logger.warn(`Plugin "${this.name}" is incompatible. It may work not properly or break something!`); } From 2d5deeed8177550b82bbfef1298a21ee0955b816 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sun, 16 Jun 2024 12:29:11 +0200 Subject: [PATCH 186/186] Bumped version to `3.0.0` --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d4438fc..f1cf1d6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "backend", "private": true, - "version": "2.2.0", + "version": "3.0.0", "description": "", "main": "index.js", "scripts": {