From c6a139b8bd8dc2101dc26f7e6a3567778a353f99 Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Mon, 1 Jul 2024 09:58:57 +0100 Subject: [PATCH 01/58] Add copy of Influx Ingester as UNS Ingester --- acs-uns-ingester/.gitignore | 19 + acs-uns-ingester/Dockerfile | 67 + acs-uns-ingester/LICENSE | 21 + acs-uns-ingester/Makefile | 7 + acs-uns-ingester/README.md | 5 + acs-uns-ingester/SECURITY.md | 15 + acs-uns-ingester/bin/ingester.js | 28 + acs-uns-ingester/bin/ingester.ts | 52 + acs-uns-ingester/lib/mqttclient.js | 182 ++ acs-uns-ingester/lib/mqttclient.ts | 533 ++++ acs-uns-ingester/package-lock.json | 3791 ++++++++++++++++++++++++ acs-uns-ingester/package.json | 41 + acs-uns-ingester/run-dev.sh | 10 + acs-uns-ingester/tsconfig.json | 32 + influxdb-sparkplug-ingester/.gitignore | 2 + 15 files changed, 4805 insertions(+) create mode 100644 acs-uns-ingester/.gitignore create mode 100644 acs-uns-ingester/Dockerfile create mode 100644 acs-uns-ingester/LICENSE create mode 100644 acs-uns-ingester/Makefile create mode 100644 acs-uns-ingester/README.md create mode 100644 acs-uns-ingester/SECURITY.md create mode 100644 acs-uns-ingester/bin/ingester.js create mode 100644 acs-uns-ingester/bin/ingester.ts create mode 100644 acs-uns-ingester/lib/mqttclient.js create mode 100644 acs-uns-ingester/lib/mqttclient.ts create mode 100644 acs-uns-ingester/package-lock.json create mode 100644 acs-uns-ingester/package.json create mode 100644 acs-uns-ingester/run-dev.sh create mode 100644 acs-uns-ingester/tsconfig.json diff --git a/acs-uns-ingester/.gitignore b/acs-uns-ingester/.gitignore new file mode 100644 index 00000000..de52c1cc --- /dev/null +++ b/acs-uns-ingester/.gitignore @@ -0,0 +1,19 @@ +/node_modules/ + +# Vim swap +*.swp + +# Environment +.env +dist/ + +dist/ + +# Secrets +/keytabs/ +/volumes/ + +# IDE +.idea/ + +*keytab* \ No newline at end of file diff --git a/acs-uns-ingester/Dockerfile b/acs-uns-ingester/Dockerfile new file mode 100644 index 00000000..2ff683bf --- /dev/null +++ b/acs-uns-ingester/Dockerfile @@ -0,0 +1,67 @@ +# syntax=docker/dockerfile:1 +# The line above must be the first line in the file! + +ARG base_version +ARG base_prefix=ghcr.io/amrc-factoryplus/acs-base + +ARG acs_build=${base_prefix}-js-build:${base_version} +ARG acs_run=${base_prefix}-js-run:${base_version} + +FROM ${acs_build} as ts-compiler +# This ARG must go here, in the image that uses it, or it isn't +# available to the shell scripts. Don't ask me why... +ARG acs_npm=NO +ARG revision=unknown + +USER root +RUN <<'SHELL' + install -d -o node /home/node /usr/app +SHELL +USER node +WORKDIR /usr/app +COPY --chown=node . ./ +RUN <<'SHELL' + touch /home/node/.npmrc + if [ "${acs_npm}" != NO ] + then + echo "SETTING NPM REGISTRY TO ${acs_npm}" >&2 + npm config set @amrc-factoryplus:registry "${acs_npm}" + fi + npm install --save=false + + echo "export const GIT_VERSION=\"$revision\";" > ./lib/git-version.js + + npm run clean + echo tsc -v + npm run build +SHELL + +FROM ${acs_build} as util-build +USER root +RUN <<'SHELL' + # Are these necessary? + apk upgrade --update-cache --available + apk add openssl + rm -rf /var/cache/apk/* + install -d -o node /home/node /usr/app +SHELL +USER node +WORKDIR /usr/app +COPY --chown=node --from=ts-compiler /usr/app/package*.json ./ +COPY --chown=node --from=ts-compiler /usr/app/dist ./ +COPY --chown=node --from=ts-compiler /home/node/.npmrc /home/node +RUN npm install --save=false --only=production + +FROM ${acs_run} +USER root +RUN <<'SHELL' + apk upgrade --update-cache --available + apk add openssl + rm -rf /var/cache/apk/* +SHELL +WORKDIR /usr/app +# This copy leaves the app files owned as root, i.e. read-only to the +# running application. This is a Good Thing. +COPY --from=util-build /usr/app ./ +USER node +CMD [ "node", "--es-module-specifier-resolution=node", "bin/ingester.js" ] diff --git a/acs-uns-ingester/LICENSE b/acs-uns-ingester/LICENSE new file mode 100644 index 00000000..cdb7bae2 --- /dev/null +++ b/acs-uns-ingester/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 AMRC-FactoryPlus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/acs-uns-ingester/Makefile b/acs-uns-ingester/Makefile new file mode 100644 index 00000000..bf4d70ab --- /dev/null +++ b/acs-uns-ingester/Makefile @@ -0,0 +1,7 @@ +top=.. +include ${top}/mk/acs.init.mk + +repo?=influxdb-sparkplug-ingester +k8s.deployment?=influxdb-ingester + +include ${mk}/acs.js.mk diff --git a/acs-uns-ingester/README.md b/acs-uns-ingester/README.md new file mode 100644 index 00000000..5d24db65 --- /dev/null +++ b/acs-uns-ingester/README.md @@ -0,0 +1,5 @@ +# InfluxDB Sparkplug Ingester + +A component that allows InfluxDB to function as a comprehensive Sparkplug-based data historian. It was developed for the [AMRC Connectiviy Stack](https://github.com/AMRC-FactoryPlus/amrc-connectivity-stack), the AMRC's open-source implementation of the Factory+ framework. + +See the [ACS Helm chart](https://github.com/AMRC-FactoryPlus/amrc-connectivity-stack) for information on how to deploy this component. diff --git a/acs-uns-ingester/SECURITY.md b/acs-uns-ingester/SECURITY.md new file mode 100644 index 00000000..91a8ba7e --- /dev/null +++ b/acs-uns-ingester/SECURITY.md @@ -0,0 +1,15 @@ +## Reporting a Vulnerability + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please register a new advisory from the Security tab in Github. + +Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: + +- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) +- Full paths of source file(s) related to the manifestation of the issue +- The location of the affected source code (tag/branch/commit or direct URL) +- Any special configuration required to reproduce the issue +- Step-by-step instructions to reproduce the issue +- Proof-of-concept or exploit code (if possible) +- Impact of the issue, including how an attacker might exploit the issue diff --git a/acs-uns-ingester/bin/ingester.js b/acs-uns-ingester/bin/ingester.js new file mode 100644 index 00000000..7ae99c60 --- /dev/null +++ b/acs-uns-ingester/bin/ingester.js @@ -0,0 +1,28 @@ +import { Debug, ServiceClient } from "@amrc-factoryplus/utilities"; +import MQTTClient from "../lib/mqttclient"; +const deviceUUID = process.env.DEVICE_UUID; +const MQTTURL = process.env.MQTT_URL; +const sparkplugAddress = process.env.SPARKPLUG_ADDRESS; +if (!deviceUUID) { + throw new Error("Device UUID not set"); +} +if (!MQTTURL) { + throw new Error("MQTT URL not set"); +} +if (!sparkplugAddress) { + throw new Error("Sparkplug Address not set"); +} +const debug = new Debug(); +const client = await new ServiceClient({ + directory_url: process.env.DIRECTORY_URL, + root_principal: process.env.ROOT_PRINCIPAL, +}).init(); +const mqtt = await new MQTTClient({ + e: { + serviceClient: client, + deviceUUID: deviceUUID, + url: MQTTURL, + sparkplugAddress: sparkplugAddress + } +}).init(); +mqtt.run(); diff --git a/acs-uns-ingester/bin/ingester.ts b/acs-uns-ingester/bin/ingester.ts new file mode 100644 index 00000000..136b2ac6 --- /dev/null +++ b/acs-uns-ingester/bin/ingester.ts @@ -0,0 +1,52 @@ +/* + * AMRC InfluxDB Sparkplug Ingester + * Copyright "2023" AMRC + */ + +import {ServiceClient, UUIDs} from "@amrc-factoryplus/utilities"; +import pino from "pino"; +import pretty from 'pino-pretty'; +import MQTTClient from "@lib/mqttclient.js"; +let dotenv: any = null; +try {dotenv = await import ('dotenv')} catch (e) {} + +const stream = pretty({ + colorize: true +}) + +dotenv?.config(); + +const directoryUrl = process.env.DIRECTORY_URL; +if (!directoryUrl) { + throw new Error("DIRECTORY_URL environment variable is not set"); +} + +export const logger = pino({ + name: 'InfluxDB Sparkplug Ingester', + level: process.env.LOG_LEVEL || 'info', +}, stream); + + +const client = await new ServiceClient({ + directory_url: directoryUrl, +}).init(); + +// Overwrite MQTT server if specified in environment +if (process.env.MQTT_URL) { + client.Discovery.set_service_url(UUIDs.Service.MQTT, process.env.MQTT_URL); +} + +// Overwrite Command Escalation server if specified in environment +if (process.env.CMD_ESC_URL) { + client.Discovery.set_service_url(UUIDs.Service.Command_Escalation, process.env.CMD_ESC_URL); +} + +logger.info(client.service_urls('feb27ba3-bd2c-4916-9269-79a61ebc4a47')); + +const mqtt = await new MQTTClient({ + e: { + serviceClient: client, + } +}).init(); + +mqtt.run(); diff --git a/acs-uns-ingester/lib/mqttclient.js b/acs-uns-ingester/lib/mqttclient.js new file mode 100644 index 00000000..30be1af7 --- /dev/null +++ b/acs-uns-ingester/lib/mqttclient.js @@ -0,0 +1,182 @@ +import { Address, Debug, MetricBuilder, SpB, Topic } from "@amrc-factoryplus/utilities"; +const debug = new Debug(); +export default class MQTTClient { + serviceClient; + deviceUUID; + url; + address; + seq; + mqtt; + constructor({ e }) { + this.serviceClient = e.serviceClient; + this.deviceUUID = e.deviceUUID; + this.url = e.url; + this.address = Address.parse(e.sparkplugAddress); + this.seq = 0; + } + async init() { + return this; + } + will() { + const nDeath = { + timestamp: Date.now(), + metrics: MetricBuilder.death.node([]), + }; + // @ts-ignore + const will = SpB.encodePayload(nDeath); + return { + topic: this.address.topic("DEATH"), + payload: will, + qos: 0, + retain: false, + }; + } + async run() { + const mqtt = await this.serviceClient.mqtt_client({ + verbose: true, + // @ts-ignore + will: this.will(), + }); + this.mqtt = mqtt; + mqtt.on("gssconnect", this.on_connect.bind(this)); + mqtt.on("error", this.on_error.bind(this)); + mqtt.on("message", this.on_message.bind(this)); + // We subscribe to the whole Sparkplug namespace + mqtt.subscribe('spBv1.0/#'); + } + // encode_metrics(metrics, with_uuid) { + // const payload = { + // timestamp: Date.now(), + // metrics: metrics, + // seq: this.seq, + // }; + // this.seq = (this.seq < 255) ? (this.seq + 1) : 0; + // if (with_uuid) + // payload.uuid = UUIDs.FactoryPlus; + // + // return SpB.encodePayload(payload); + // } + // publish(kind, metrics, with_uuid) { + // if (!this.mqtt) { + // debug.log("mqtt", "Can't publish without an MQTT connection."); + // return; + // } + // + // const topic = this.address.topic(kind); + // const payload = this.encode_metrics(metrics, with_uuid); + // + // this.mqtt.publish(topic, payload); + // } + on_connect() { + debug.log("mqtt", "Connected to MQTT broker."); + // this.rebirth(); + } + // rebirth() { + // + // this.seq = 0; + // const Birth = MetricBuilder.birth; + // const metrics = Birth.node([]); + // //Birth.command_escalation(metrics); + // metrics.push.apply(metrics, [ + // {name: "Device_Information/Manufacturer", type: "String", value: Device_Info.Manufacturer}, + // {name: "Device_Information/Model", type: "String", value: Device_Info.Model}, + // {name: "Device_Information/Serial", type: "String", value: Device_Info.Serial}, + // + // {name: "Schema_UUID", type: "UUID", value: Schema.Service}, + // {name: "Instance_UUID", type: "UUID", value: this.device_uuid}, + // {name: "Service_UUID", type: "UUID", value: Service.Registry}, + // {name: "Service_URL", type: "String", value: this.url}, + // ]); + // metrics.push.apply(metrics, + // Object.values(Changed).map(v => + // ({name: `Last_Changed/${v}`, type: "UUID", value: ""}))); + // + // debug.log("mqtt", `Publishing birth certificate`); + // this.publish("BIRTH", metrics, true); + // } + // publish_changed(changes) { + // const metrics = []; + // for (let [to, uuid] of Object.entries(changes)) { + // if (!(to in Changed)) + // continue; + // metrics.push({ + // name: `Last_Changed/${Changed[to]}`, + // type: "UUID", + // value: uuid, + // }); + // } + // this.publish("DATA", metrics); + // } + on_error(error) { + debug.log("mqtt", "MQTT error: %o", error); + } + async on_message(topicString, message) { + let topic = Topic.parse(topicString); + if (!topic) { + debug.log("mqtt", `Bad topic: ${topicString}`); + return; + } + let address = topic.address; + let payload; + try { + // @ts-ignore + payload = SpB.decodePayload(message); + } + catch { + debug.log("mqtt", `Bad payload on topic ${topicString}`); + return; + } + switch (topic.type) { + case "BIRTH": + //await this.on_birth(address, payload); + break; + case "DEATH": + //await this.on_death(address, payload); + break; + case "DATA": + await this.on_data(address, payload); + break; + case "CMD": + await this.on_command(address, payload); + break; + default: + debug.log("mqtt", `Unknown Sparkplug message type ${topic.type}!`); + } + } + async on_data(addr, payload) { + if (!payload.metrics) { + debug.log("mqtt", `Received DATA with no metrics!`); + return; + } + // for (let m of payload.metrics) { + // switch (m.name) { + // // case "Node Control/Rebirth": + // // await this.rebirth(); + // // break; + // default: + // debug.log("mqtt", `Received unknown CMD: ${m.name}`); + // /* Ignore for now */ + // } + // } + } + async on_command(addr, payload) { + if (!addr.equals(this.address)) { + //console.log(`Received CMD for ${addr}`); + return; + } + if (!payload.metrics) { + debug.log("mqtt", `Received CMD with no metrics!`); + return; + } + for (let m of payload.metrics) { + switch (m.name) { + // case "Node Control/Rebirth": + // await this.rebirth(); + // break; + default: + debug.log("mqtt", `Received unknown CMD: ${m.name}`); + /* Ignore for now */ + } + } + } +} diff --git a/acs-uns-ingester/lib/mqttclient.ts b/acs-uns-ingester/lib/mqttclient.ts new file mode 100644 index 00000000..854811c1 --- /dev/null +++ b/acs-uns-ingester/lib/mqttclient.ts @@ -0,0 +1,533 @@ +/* + * AMRC InfluxDB Sparkplug Ingester + * Copyright "2024" AMRC + */ + +import {ServiceClient, SpB, Topic, UUIDs} from "@amrc-factoryplus/utilities"; +import {Reader} from "protobufjs"; +import {logger} from "../bin/ingester.js"; +import Long from "long"; +import {InfluxDB, Point} from '@influxdata/influxdb-client' +import {Agent} from 'http' + +let dotenv: any = null; +try { + dotenv = await import ('dotenv') +} catch (e) { +} + +dotenv?.config() + +const influxURL: string = process.env.INFLUX_URL; +if (!influxURL) { + throw new Error("INFLUX_URL environment variable is not set"); +} + +const influxToken: string = process.env.INFLUX_TOKEN +if (!influxToken) { + throw new Error("INFLUX_TOKEN environment variable is not set"); +} + +const influxOrganisation: string = process.env.INFLUX_ORG +if (!influxOrganisation) { + throw new Error("INFLUX_ORG environment variable is not set"); +} + +const batchSize: number = Number.parseInt(process.env.BATCH_SIZE); +if (!batchSize) { + throw new Error("BATCH_SIZE environment variable is not set"); +} + +const flushInterval: number = Number.parseInt(process.env.FLUSH_INTERVAL); +if (!flushInterval) { + throw new Error("FLUSH_INTERVAL environment variable is not set"); +} + +let i = 0; + +// Node.js HTTP client OOTB does not reuse established TCP connections, a custom node HTTP agent +// can be used to reuse them and thus reduce the count of newly established networking sockets +const keepAliveAgent = new Agent({ + keepAlive: true, // reuse existing connections + keepAliveMsecs: 20 * 1000, // 20 seconds keep alive +}) + +const influxDB = new InfluxDB({ + url: influxURL, token: influxToken, transportOptions: { + agent: keepAliveAgent, + } +}) + +let interval: any; + +/* points/lines are batched in order to minimize networking and increase performance */ + +const writeApi = influxDB.getWriteApi(influxOrganisation, process.env.INFLUX_BUCKET || 'default', 'ns', { + /* the maximum points/lines to send in a single batch to InfluxDB server */ + batchSize: batchSize + 1, // don't let automatically flush data + /* maximum time in millis to keep points in an unflushed batch, 0 means don't periodically flush */ + flushInterval: 0, // Never allow the package to flush: we'll flush manually + /* maximum size of the retry buffer - it contains items that could not be sent for the first time */ + maxBufferLines: 30_000, /* the count of internally-scheduled retries upon write failure, the delays between write attempts follow an exponential backoff strategy if there is no Retry-After HTTP header */ + maxRetries: 0, // do not retry writes + // ... there are more write options that can be customized, see + // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeoptions.html and + // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeretryoptions.html +}); + +interface MQTTClientConstructorParams { + e: { + serviceClient: ServiceClient; + } +} + +export default class MQTTClient { + private serviceClient: ServiceClient; + private mqtt: any; + private aliasResolver = {}; + private birthDebounce = {}; + + constructor({e}: MQTTClientConstructorParams) { + this.serviceClient = e.serviceClient; + } + + async init() { + + process.on('exit', () => { + this.flushBuffer('EXIT'); + keepAliveAgent.destroy(); + }) + + return this; + } + + private flushBuffer(source: string) { + let bufferSize = i; + i = 0; + writeApi.flush().then(() => { + logger.info(`🚀 Flushed ${bufferSize} points to InfluxDB [${source}]`); + // Reset the interval + this.resetInterval(); + }) + } + + async run() { + + const mqtt = await this.serviceClient.mqtt_client(); + this.mqtt = mqtt; + + mqtt.on("authenticated", this.on_connect.bind(this)); + mqtt.on("error", this.on_error.bind(this)); + mqtt.on("message", this.on_message.bind(this)); + mqtt.on("close", this.on_close.bind(this)); + mqtt.on("reconnect", this.on_reconnect.bind(this)); + + logger.info("Connecting to Factory+ broker..."); + } + + on_connect() { + logger.info("🔌 Connected to Factory+ broker"); + logger.info("👂 Subscribing to entire Factory+ namespace"); + this.mqtt.subscribe('spBv1.0/#'); + this.resetInterval(); + } + + private resetInterval() { + clearInterval(interval); + interval = setInterval(() => { + this.flushBuffer(`${flushInterval}ms INTERVAL`); + }, flushInterval); + } + + on_close() { + logger.warn(`❌ Disconnected from Factory+ broker`); + + // Flush any remaining data + this.flushBuffer('CONN_CLOSE'); + } + + on_reconnect() { + logger.warn(`⚠️ Reconnecting to Factory+ broker...`); + } + + on_error(error: any) { + logger.error("🚨 MQTT error: %o", error); + // Flush any remaining data + this.flushBuffer('MQTT_ERROR'); + } + + async on_message(topicString: string, message: Uint8Array | Reader) { + let topic = Topic.parse(topicString); + let payload; + + try { + payload = SpB.decodePayload(message); + } catch { + logger.error(`🚨 Bad payload on topic ${topicString}`); + return; + } + + if (!topic) { + logger.error(`🚨 Bad topic: ${topicString}`); + return; + } + + switch (topic.type) { + case "BIRTH": + + // Don't handle Node births + if (!topic.address.isDevice()) return; + + let topLevelSchema = null; + let schemaUUIDMapping = {}; + + let topLevelInstance = null; + let instanceUUIDMapping = {}; + + // If we have a Factory+ payload then process the Schema UUIDs and Instance UUIDs + if (payload.uuid === UUIDs.FactoryPlus) { + + // Schema_UUIDs + payload.metrics.forEach((metric) => { + // If the name ends in Schema_UUID (e.g. Phases/1/Schema_UUID) + if (metric.name.endsWith("Schema_UUID")) { + // Then get the entire string before the /Schema_UUID + let schemaPath = metric.name.split("/").slice(0, -1).join("/"); + + // If the schemaPath is empty then this is the top level Schema_UUID + if (schemaPath === "") { + // So set the topLevelSchema to this value + topLevelSchema = metric.value; + } else { + // Add this mapping to the schemaUUIDMapping array. This means + // that all metrics that contain this schema path in their name + // will have + schemaUUIDMapping[schemaPath] = metric.value; + } + } + }) + + // Instance_UUIDs + payload.metrics.forEach((metric) => { + // If the name ends in Instance_UUID (e.g. Phases/1/Instance_UUID) + if (metric.name.endsWith("Instance_UUID")) { + // Then get the entire string before the /Instance_UUID + let instancePath = metric.name.split("/").slice(0, -1).join("/"); + + // If the instancePath is empty then this is the top level Instance_UUID + if (instancePath === "") { + // So set the topLevelInstance to this value + topLevelInstance = metric.value; + } else { + // Add this mapping to the instanceUUIDMapping array. This means + // that all metrics that contain this instance path in their name + // will have + instanceUUIDMapping[instancePath] = metric.value; + } + } + }) + } + + if (this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { + logger.info(`🔄 Received updated birth certificate for ${topic.address.group}/${topic.address.node}/${topic.address.device} with Instance_UUID ${topLevelInstance} using Schema_UUID ${topLevelSchema}`); + } else { + logger.info(`👶 Received birth certificate for ${topic.address.group}/${topic.address.node}/${topic.address.device} with Instance_UUID ${topLevelInstance} using Schema_UUID ${topLevelSchema}`); + } + + // Store the birth certificate mapping in the alias resolver. This uses the alias as the key and a simplified object containing the name and type as the value. + this.setNestedValue(this.aliasResolver, [topic.address.group, topic.address.node, topic.address.device], payload.metrics.reduce(function (acc, obj) { + let alias = Long.isLong(obj.alias) ? obj.alias.toNumber() : obj.alias; + + // Work out all schemas that are involved in this metric. + // + // e.g. Assume the current metric is CNC/Axes/1/BaseAxis/Position/Actual + // + // The schemaUUIDMapping object will contain the following (non-relevant emitted): + // - Axes/1: e39007e9-1427-4867-9d72-1c00c663db15 + // - Axes/1/BaseAxis: 777dd941-f426-4355-8130-e144530b1376 + // - Axes/1/BaseAxis/Position: 1a2c3594-d311-4f6b-865b-b97db3fa6d42 + + // Schema_UUIDs + + let schemas = []; + // Get all entries in the schemaUUIDMapping object that have keys that fit in the current obj.name + Object.entries(schemaUUIDMapping).forEach(([schemaPath, schemaUUID]) => { + // If the current obj.name contains the schemaPath then add the schemaUUID to the schemas array + if (obj.name.includes(schemaPath)) { + schemas.push(schemaUUID); + } + }); + + // Get the bottom level schema by finding the the entry in the schemaUUIDMapping object that has + // the key with the most slashes that fits in the current obj.name + let bottomLevelSchema = Object.entries(schemaUUIDMapping).reduce((acc, [schemaPath, schemaUUID]) => { + if (obj.name.includes(schemaPath) && schemaPath.split("/").length > acc.split("/").length) { + return schemaUUID; + } else { + return acc; + } + }, ""); + + // Instance_UUIDs + + let instances = []; + // Get all entries in the instanceUUIDMapping object that have keys that fit in the current obj.name + Object.entries(instanceUUIDMapping).forEach(([instancePath, instanceUUID]) => { + // If the current obj.name contains the instancePath then add the instanceUUID to the instances array + if (obj.name.includes(instancePath)) { + instances.push(instanceUUID); + } + }); + + // Get the bottom level instance by finding the the entry in the instanceUUIDMapping object that has + // the key with the most slashes that fits in the current obj.name + let bottomLevelInstance = Object.entries(instanceUUIDMapping).reduce((acc, [instancePath, instanceUUID]) => { + if (obj.name.includes(instancePath) && instancePath.split("/").length > acc.split("/").length) { + return instanceUUID; + } else { + return acc; + } + }, ""); + + acc[alias] = { + instance: { + // The top level instance for this device + top: topLevelInstance, + + // The last instance before this metric + bottom: bottomLevelInstance, + + // All instances between the top and bottom, inclusive + full: instances, + }, + schema: { + // The top level schema for this device + top: topLevelSchema, + + // The last schema before this metric + bottom: bottomLevelSchema, + + // All schemas between the top and bottom, inclusive + full: schemas, + }, + name: obj.name, + type: obj.type, + alias: alias, + unit: obj.properties?.engUnit?.value, + transient: obj.isTransient + }; + return acc; + }, {})); + + // Clear the debounce + delete this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]; + + // Store the default values in InfluxDB + this.writeMetrics(payload, topic); + + break; + case "DEATH": + + // If the death certificate is for a device then remove it from the known devices, otherwise remove the entire node + if (topic.address.isDevice()) { + logger.info(`💀 Received death certificate for ${topic.address.group}/${topic.address.node}/${topic.address.device}. Removing from known devices.`); + delete this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device] + delete this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device] + break; + } else { + logger.info(`💀💀💀 Received death certificate for entire node ${topic.address.group}/${topic.address.node}. Removing from known nodes.`); + delete this.birthDebounce?.[topic.address.group]?.[topic.address.node] + delete this.aliasResolver?.[topic.address.group]?.[topic.address.node] + break; + } + case "DATA": + + // Don't handle Node data + if (!topic.address.isDevice()) return; + + // Check if we have a birth certificate for the device + if (this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { + + // Device is known, resolve aliases and write to InfluxDB + this.writeMetrics(payload, topic); + + } else { + + // Check that we don't already have an active debounce for this device + if (this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { + logger.info(`⏳ Device ${topic.address.group}/${topic.address.node}/${topic.address.device} is unknown but has pending birth certificate request. Ignoring.`); + return; + } + + logger.info(`✨ Device ${topic.address.group}/${topic.address.node}/${topic.address.device} is unknown, requesting birth certificate`); + + // Create debounce timout for this device + this.setNestedValue(this.birthDebounce, [topic.address.group, topic.address.node, topic.address.device], true); + setTimeout(() => { + delete this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]; + }, Math.floor(Math.random() * (10000 - 5000 + 1) + 5000)); + + // Request birth certificate + let response = await this.serviceClient.fetch({ + service: UUIDs.Service.Command_Escalation, + url: `/v1/address/${topic.address.group}/${topic.address.node}/${topic.address.device}`, + method: "POST", + headers: { + "content-type": "application/json" + }, + body: JSON.stringify({ + "name": "Device Control/Rebirth", "value": "true" + }) + }) + + logger.info('📣 Birth certificate request sent for %s. Status: %s', topic.address, response.status); + + } + break; + } + + return; + } + + private writeMetrics(payload, topic: Topic) { + payload.metrics.forEach((metric) => { + let birth = this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]?.[metric.alias]; + + if (!birth) { + logger.error(`Metric ${metric.alias} is unknown for ${topic.address.group}/${topic.address.node}/${topic.address.device}`); + } + + let metricTimestamp: Date + if (metric.timestamp) { + metricTimestamp = new Date(metric.timestamp); + } else if (payload.timestamp) { + // Metrics might not have a timestamp so use the packet timestamp if we have it. + metricTimestamp = new Date(payload.timestamp); + } else { + // No timestamp can be found on the metric or the payload, just use the current time instead. + metricTimestamp = new Date(); + } + // Send each metric to InfluxDB + this.writeToInfluxDB(birth, topic, metric.value, metricTimestamp) + }); + } + + /** + * Writes metric values to InfluxDB using the metric timestamp. + * @param birth Birth certificate for device. + * @param topic Topic the metric was published on. + * @param value Metric value to write to InfluxDB. + * @param timestamp Timestamp from the metric to write to influx. + */ + writeToInfluxDB(birth, topic: Topic, value, timestamp: Date) { + if (value === null) return; + if (birth.transient) { + logger.debug(`Metric ${birth.name} is transient, not writing to InfluxDB`); + return; + } + + // Get the value after the last / + let metricName = birth.name.split('/').pop(); + + // Get the path as everything behind the last / + let path = birth.name.substring(0, birth.name.lastIndexOf("/")); + + writeApi.useDefaultTags({ + topLevelInstance: birth.instance.top, + bottomLevelInstance: birth.instance.bottom, + usesInstances: birth.instance.top + ':' + birth.instance.full.join(':'), + topLevelSchema: birth.schema.top, + bottomLevelSchema: birth.schema.bottom, + usesSchemas: birth.schema.top + ':' + birth.schema.full.join(':'), + group: topic.address.group, + node: topic.address.node, + device: topic.address.device, + path: path, + unit: birth.unit + }); + + let numVal = null; + + switch (birth.type) { + case "Int8": + case "Int16": + case "Int32": + case "Int64": + // Validate + numVal = Number(value); + if (!Number.isInteger(numVal)) { + logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${numVal}. Not recording.`); + return; + } + writeApi.writePoint( + new Point(`${metricName}:i`) + .intField('value', numVal) + .timestamp(timestamp) + ); + break; + case "UInt8": + case "UInt16": + case "UInt32": + case "UInt64": + // Validate + numVal = Number(value); + if (!Number.isInteger(numVal)) { + logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${numVal}. Not recording.`); + return; + } + writeApi.writePoint( + new Point(`${metricName}:u`) + .uintField('value', numVal) + .timestamp(timestamp) + ); + break; + case "Float": + case "Double": + // Validate + numVal = Number(value); + if (isNaN(parseFloat(numVal))) { + logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${numVal}. Not recording.`); + return; + } + writeApi.writePoint( + new Point(`${metricName}:d`) + .floatField('value', numVal) + .timestamp(timestamp) + ); + break; + case "Boolean": + if (typeof value != "boolean") { + logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${value}. Not recording.`); + return; + } + writeApi.writePoint( + new Point(`${metricName}:b`) + .booleanField('value', value) + .timestamp(timestamp)); + break; + default: + writeApi.writePoint( + new Point(`${metricName}:s`) + .stringField('value', value) + .timestamp(timestamp)); + break; + + } + + i++; + + logger.debug(`Added to write buffer (${i}/${batchSize}): [${birth.type}] ${topic.address}/${path}/${metricName} = ${value}`); + + if (i >= batchSize) { + this.flushBuffer(`${batchSize} point BATCH`); + } + } + + setNestedValue(obj, path, value) { + for (let k = 0; k < path.length - 1; k++) { + obj = obj[path[k]] = obj[path[k]] || {}; + } + obj[path[path.length - 1]] = value; + return obj; + } +} diff --git a/acs-uns-ingester/package-lock.json b/acs-uns-ingester/package-lock.json new file mode 100644 index 00000000..82e755f5 --- /dev/null +++ b/acs-uns-ingester/package-lock.json @@ -0,0 +1,3791 @@ +{ + "name": "influxdb-sparkplug-ingester", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "influxdb-sparkplug-ingester", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@amrc-factoryplus/utilities": "^1.0.8", + "@influxdata/influxdb-client": "^1.33.2", + "@influxdata/influxdb-client-apis": "^1.33.2", + "async": "^3.2.4", + "long": "^5.2.3", + "pino": "^8.11.0", + "pino-pretty": "^10.0.0" + }, + "devDependencies": { + "cross-env": "^7.0.3", + "dotenv": "^16.0.3", + "ts-node": "^10.9.1", + "tsc-alias": "^1.7.0" + } + }, + "node_modules/@amrc-factoryplus/utilities": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@amrc-factoryplus/utilities/-/utilities-1.0.8.tgz", + "integrity": "sha512-pSnakabCRTs7AlRtjYPNM47BQLsN2XR7xrNXuKmBDf+iytsCU1m0pCmQXuUM8/yvk80PxabMLm7dIlG405r5Bg==", + "dependencies": { + "@types/express": "4", + "@types/long": "^4.0.0", + "@types/node": ">=13.7.0", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "express": "^4.18.1", + "find-package-json": "^1.2.0", + "got-fetch": "^5.1.1", + "http-errors": "^2.0.0", + "mqtt": "^4.3.5", + "optional-js": "^2.3.0", + "path-to-regexp": "^6.2.1", + "pg": "^8.7.3", + "protobufjs": "^6.11.3", + "semver": "^7.5.1", + "sparkplug-payload": "^1.0.1", + "typescript": "^4.8.4" + }, + "optionalDependencies": { + "gssapi.js": "^2.0.1", + "pg-native": "^3.0.0" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/semver": { + "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" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@influxdata/influxdb-client": { + "version": "1.33.2", + "resolved": "https://registry.npmjs.org/@influxdata/influxdb-client/-/influxdb-client-1.33.2.tgz", + "integrity": "sha512-RT5SxH+grHAazo/YK3UTuWK/frPWRM0N7vkrCUyqVprDgQzlLP+bSK4ak2Jv3QVF/pazTnsxWjvtKZdwskV5Xw==" + }, + "node_modules/@influxdata/influxdb-client-apis": { + "version": "1.33.2", + "resolved": "https://registry.npmjs.org/@influxdata/influxdb-client-apis/-/influxdb-client-apis-1.33.2.tgz", + "integrity": "sha512-W6x9TOAQ3AUx0RBCrCibDhSvMqN50lxJmElc3rHn7+R/9Zi35oczu8r9YMkyNlzWnksu+dcyKr8/xLv28Ot4hw==", + "peerDependencies": { + "@influxdata/influxdb-client": "*" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "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": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "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_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/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "node_modules/@sindresorhus/is": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", + "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "peer": true, + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.33", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", + "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "peer": true + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, + "node_modules/@types/mime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" + }, + "node_modules/@types/node": { + "version": "18.15.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", + "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==" + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, + "node_modules/@types/serve-static": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", + "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", + "dependencies": { + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", + "integrity": "sha512-iFY7JCgHbepc0b82yLaw4IMortylNb6wG4kL+4R0C3iv6i+RHGHux/yUX5BTiRvSX/shMnngjR1YyNMnXEFh5A==", + "optional": true + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/are-we-there-yet": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.0.6.tgz", + "integrity": "sha512-Zfw6bteqM9gQXZ1BIWOgM8xEwMrUGoyL8nW13+O+OOgNX3YhuDN1GDgg1NzdTlmm3j+9sHy7uBZ12r+z9lXnZQ==", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.0 || ^1.1.13" + } + }, + "node_modules/are-we-there-yet/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "optional": true + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/are-we-there-yet/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "optional": true, + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "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/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", + "optional": true, + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bl/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "optional": true + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "optional": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g==", + "optional": true + }, + "node_modules/buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", + "optional": true, + "engines": { + "node": ">=0.2.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "peer": true, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.9", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.9.tgz", + "integrity": "sha512-CaAMr53AS1Tb9evO1BIWFnZjSr8A4pbXofpsNVWPMDZZj3ZQKHwsQG9BrTqQ4x5ZYJXz1T2b8LLtTZODxSpzbg==", + "peer": true, + "dependencies": { + "@types/http-cache-semantics": "^4.0.1", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.2", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", + "optional": true, + "dependencies": { + "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "optional": true + }, + "node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", + "optional": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/cmake-js": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/cmake-js/-/cmake-js-6.3.2.tgz", + "integrity": "sha512-7MfiQ/ijzeE2kO+WFB9bv4QP5Dn2yVaAP2acFJr4NIFy2hT4w6O4EpOTLNcohR5IPX7M4wNf/5taIqMj7UA9ug==", + "optional": true, + "dependencies": { + "axios": "^0.21.1", + "bluebird": "^3", + "debug": "^4", + "fs-extra": "^5.0.0", + "is-iojs": "^1.0.1", + "lodash": "^4", + "memory-stream": "0", + "npmlog": "^1.2.0", + "rc": "^1.2.7", + "semver": "^5.0.3", + "splitargs": "0", + "tar": "^4", + "unzipper": "^0.8.13", + "url-join": "0", + "which": "^1.0.9", + "yargs": "^3.6.0" + }, + "bin": { + "cmake-js": "bin/cmake-js" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/cmake-js/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "optional": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/cmake-js/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==", + "optional": true + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" + }, + "node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/commist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", + "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", + "dependencies": { + "leven": "^2.1.0", + "minimist": "^1.1.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "optional": true + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "peer": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "optional": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "optional": true + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/duplexify/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/duplexify/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fast-copy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.1.tgz", + "integrity": "sha512-Knr7NOtK3HWRYGtHoJrjkaWepqT8thIVGAwt0p0aUs1zqkAzXZV4vo9fFNwyb5fcqK1GKYFYxldQdIDVKhUAfA==" + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-redact": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.1.2.tgz", + "integrity": "sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-package-json": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/find-package-json/-/find-package-json-1.2.0.tgz", + "integrity": "sha512-+SOGcLGYDJHtyqHd87ysBhmaeQ95oWspDKnMXBrnQ9Eq4OkLNqejgoaD8xVWu6GPa0B6roa6KinCMEMcVeqONw==" + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "optional": true, + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "peer": true, + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", + "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "optional": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "optional": true, + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "optional": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/gauge": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", + "integrity": "sha512-fVbU2wRE91yDvKUnrIaQlHKAWKY5e08PmztCrwuH5YVQ+Z/p3d0ny2T48o6uvAAXHIUnfaQdHkmxYbQft1eHVA==", + "optional": true, + "dependencies": { + "ansi": "^0.3.0", + "has-unicode": "^2.0.0", + "lodash.pad": "^4.1.0", + "lodash.padend": "^4.1.0", + "lodash.padstart": "^4.1.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.0.tgz", + "integrity": "sha512-WTcaQ963xV97MN3x0/CbAriXFZcXCfgxVp91I+Ze6pawQOa7SgzwSx2zIJJsX+kTajMnVs0xcFD1TxZKFqhdnQ==", + "peer": true, + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got-fetch": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/got-fetch/-/got-fetch-5.1.4.tgz", + "integrity": "sha512-Pdv+SSgtTCDZbNuGkOf0c0FZy5Syqf225JEgG/vKt13HAe8r2vNJ11DxKKODsmr7L7/6ff3lf+AxpBtD5k/dRQ==", + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "got": "^12.0.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "optional": true + }, + "node_modules/gssapi.js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gssapi.js/-/gssapi.js-2.0.1.tgz", + "integrity": "sha512-5D+qylV8uIKMaxTTKhpzvfGRz5+okr/rpwC6YlaCoDVBpvkuNgL8pM7+r7aTzZ2oT5dA4w2WoZTV82opGj+RZQ==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "bindings": "^1.5.0", + "cmake-js": "^6.1.0", + "node-addon-api": "^1.7.2" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "optional": true + }, + "node_modules/help-me": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", + "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", + "dependencies": { + "glob": "^7.1.6", + "readable-stream": "^3.6.0" + } + }, + "node_modules/help-me/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/help-me/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "peer": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http2-wrapper": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz", + "integrity": "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==", + "peer": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "optional": true + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-iojs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-iojs/-/is-iojs-1.1.0.tgz", + "integrity": "sha512-tLn1j3wYSL6DkvEI+V/j0pKohpa5jk+ER74v6S4SgCXnjS0WA+DoZbwZBrrhgwksMvtuwndyGeG5F8YMsoBzSA==", + "optional": true + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "optional": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "devOptional": true + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "peer": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optional": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", + "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", + "peer": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", + "optional": true, + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/libpq": { + "version": "1.8.12", + "resolved": "https://registry.npmjs.org/libpq/-/libpq-1.8.12.tgz", + "integrity": "sha512-4lUY9BD9suz76mVS0kH4rRgRy620g/c9YZH5GYC3smfIpjtj6KiPuQ4IwQSHSZMMMhMM3tBFrYUrw8mHOOZVeg==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "bindings": "1.5.0", + "nan": "^2.14.0" + } + }, + "node_modules/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==", + "optional": true + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "optional": true + }, + "node_modules/lodash.pad": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", + "integrity": "sha512-mvUHifnLqM+03YNzeTBS1/Gr6JRFjd3rRx88FHWUvamVaT9k2O/kXha3yBSOwB9/DTQrSTLJNHvLBBt2FdX7Mg==", + "optional": true + }, + "node_modules/lodash.padend": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "integrity": "sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw==", + "optional": true + }, + "node_modules/lodash.padstart": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", + "integrity": "sha512-sW73O6S8+Tg66eY56DBk85aQzzUJDtpoXFBgELMd5P/SotAguo+1kYO6RuYgXxA4HJH3LFTFPASX6ET6bjfriw==", + "optional": true + }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memory-stream": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/memory-stream/-/memory-stream-0.0.3.tgz", + "integrity": "sha512-q0D3m846qY6ZkIt+19ZemU5vH56lpOZZwoJc3AICARKh/menBuayQUjAGPrqtHQQMUYERSdOrej92J9kz7LgYA==", + "optional": true, + "dependencies": { + "readable-stream": "~1.0.26-2" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "optional": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/minipass/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "optional": true + }, + "node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "optional": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "optional": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mqtt": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.7.tgz", + "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==", + "dependencies": { + "commist": "^1.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.1.1", + "duplexify": "^4.1.1", + "help-me": "^3.0.0", + "inherits": "^2.0.3", + "lru-cache": "^6.0.0", + "minimist": "^1.2.5", + "mqtt-packet": "^6.8.0", + "number-allocator": "^1.0.9", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^3.1.0", + "ws": "^7.5.5", + "xtend": "^4.0.2" + }, + "bin": { + "mqtt": "bin/mqtt.js", + "mqtt_pub": "bin/pub.js", + "mqtt_sub": "bin/sub.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mqtt-packet": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", + "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "dependencies": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + }, + "node_modules/mqtt-packet/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mqtt-packet/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==" + }, + "node_modules/mqtt/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mqtt/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==" + }, + "node_modules/mqtt/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/mqtt/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/mylas": { + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/mylas/-/mylas-2.1.13.tgz", + "integrity": "sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/raouldeheer" + } + }, + "node_modules/nan": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", + "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", + "optional": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "optional": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", + "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npmlog": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-1.2.1.tgz", + "integrity": "sha512-1J5KqSRvESP6XbjPaXt2H6qDzgizLTM7x0y1cXIjP2PpvdCqyNC7TO3cPRKsuYlElbi/DwkzRRdG2zpmE0IktQ==", + "optional": true, + "dependencies": { + "ansi": "~0.3.0", + "are-we-there-yet": "~1.0.0", + "gauge": "~1.2.0" + } + }, + "node_modules/number-allocator": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz", + "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==", + "dependencies": { + "debug": "^4.3.1", + "js-sdsl": "4.3.0" + } + }, + "node_modules/number-allocator/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/number-allocator/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==" + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", + "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optional-js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/optional-js/-/optional-js-2.3.0.tgz", + "integrity": "sha512-B0LLi+Vg+eko++0z/b8zIv57kp7HKEzaPJo7LowJXMUKYdf+3XJGu/cw03h/JhIOsLnP+cG5QnTHAuicjA5fMw==" + }, + "node_modules/os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", + "optional": true, + "dependencies": { + "lcid": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "peer": true, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pg": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.10.0.tgz", + "integrity": "sha512-ke7o7qSTMb47iwzOSaZMfeR7xToFdkE71ifIipOAAaLIM0DYzfOAXlgFFmYUIE2BcJtvnVlGCID84ZzCegE8CQ==", + "dependencies": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.5.0", + "pg-pool": "^3.6.0", + "pg-protocol": "^1.6.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-native": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pg-native/-/pg-native-3.0.1.tgz", + "integrity": "sha512-LBVNWkNh0fVx/cienARRP2y22J5OpUsKBe0TpxzAx3arEUUdIs77aLSAHS3scS7SMaqc+OkG40CEu5fN0/cjIw==", + "optional": true, + "dependencies": { + "libpq": "^1.8.10", + "pg-types": "^1.12.1", + "readable-stream": "1.0.31" + } + }, + "node_modules/pg-native/node_modules/pg-types": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-1.13.0.tgz", + "integrity": "sha512-lfKli0Gkl/+za/+b6lzENajczwZHc7D5kiUCZfgm914jipD2kIOIvEkAhZ8GrW3/TUoP9w8FHjwpPObBye5KQQ==", + "optional": true, + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~1.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.0", + "postgres-interval": "^1.1.0" + } + }, + "node_modules/pg-native/node_modules/postgres-array": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.3.tgz", + "integrity": "sha512-5wClXrAP0+78mcsNX3/ithQ5exKvCyK5lr5NEEEeGwwM6NJdQgzIJBVxLvRW+huFpX92F2QnZ5CcokH0VhK2qQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pg-native/node_modules/readable-stream": { + "version": "1.0.31", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.31.tgz", + "integrity": "sha512-tco/Dwv1f/sgIgN6CWdj/restacPKNskK6yps1981ivH2ZmLYcs5o5rVzL3qaO/cSkhN8hYOMWs7+glzOLSgRg==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/pg-pool": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.0.tgz", + "integrity": "sha512-clFRf2ksqd+F497kWFyM21tMjeikn60oGDmqMT8UBrynEwVEX/5R5xd2sdvdo1cZCFlguORNpVuqxIj+aK4cfQ==", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", + "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/pgpass/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pino": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.11.0.tgz", + "integrity": "sha512-Z2eKSvlrl2rH8p5eveNUnTdd4AjJk8tAsLkHYZQKGHP4WTh2Gi1cOSOs3eWPqaj+niS3gj4UkoreoaWgF3ZWYg==", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "v1.0.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.1.0", + "thread-stream": "^2.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz", + "integrity": "sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==", + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/pino-abstract-transport/node_modules/readable-stream": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz", + "integrity": "sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/pino-pretty": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.0.0.tgz", + "integrity": "sha512-zKFjYXBzLaLTEAN1ayKpHXtL5UeRQC7R3lvhKe7fWs7hIVEjKGG/qIXwQt9HmeUp71ogUd/YcW+LmMwRp4KT6Q==", + "dependencies": { + "colorette": "^2.0.7", + "dateformat": "^4.6.3", + "fast-copy": "^3.0.0", + "fast-safe-stringify": "^2.1.1", + "help-me": "^4.0.1", + "joycon": "^3.1.1", + "minimist": "^1.2.6", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.0.0", + "pump": "^3.0.0", + "readable-stream": "^4.0.0", + "secure-json-parse": "^2.4.0", + "sonic-boom": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "pino-pretty": "bin.js" + } + }, + "node_modules/pino-pretty/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/pino-pretty/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/pino-pretty/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/pino-pretty/node_modules/help-me": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-4.2.0.tgz", + "integrity": "sha512-TAOnTB8Tz5Dw8penUuzHVrKNKlCIbwwbHnXraNJxPwf8LRtE2HlM84RYuezMFcwOJmoYOCWVDyJ8TQGxn9PgxA==", + "dependencies": { + "glob": "^8.0.0", + "readable-stream": "^3.6.0" + } + }, + "node_modules/pino-pretty/node_modules/help-me/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pino-pretty/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pino-pretty/node_modules/readable-stream": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz", + "integrity": "sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-pretty/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/pino-pretty/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pino-std-serializers": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.0.tgz", + "integrity": "sha512-IWgSzUL8X1w4BIWTwErRgtV8PyOGOOi60uqv0oKuS/fOA8Nco/OeI6lBuc4dyP8MMfdFwyHqTMcBIA7nDiqEqA==" + }, + "node_modules/plimit-lit": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/plimit-lit/-/plimit-lit-1.5.0.tgz", + "integrity": "sha512-Eb/MqCb1Iv/ok4m1FqIXqvUKPISufcjZ605hl3KM/n8GaX8zfhtgdLwZU3vKjuHGh2O9Rjog/bHTq8ofIShdng==", + "dev": true, + "dependencies": { + "queue-lit": "^1.5.0" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/process-warning": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", + "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==" + }, + "node_modules/protobufjs": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/protobufjs/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-lit": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-1.5.0.tgz", + "integrity": "sha512-IslToJ4eiCEE9xwMzq3viOO5nH8sUWUCwoElrhNMozzr9IIt2qqvB4I+uHu/zJTQVqc9R5DFwok4ijNK1pU3fA==", + "dev": true + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "optional": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "peer": true + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "peer": true, + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "optional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "optional": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sonic-boom": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz", + "integrity": "sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/sparkplug-payload": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkplug-payload/-/sparkplug-payload-1.0.1.tgz", + "integrity": "sha512-N4i++SFY7ECH7NB2bi1zmL9uPRKXF5cXQRxudUqZi9sribVZB7TZWvMIcTTakqqs1WkryYgpuV34CwEYm7I0Cg==", + "dependencies": { + "protobufjs": "^6.8.0" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/split2/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/split2/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/splitargs": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/splitargs/-/splitargs-0.0.7.tgz", + "integrity": "sha512-UUFYD2oWbNwULH6WoVtLUOw8ch586B+HUqcsAjjjeoBQAM1bD4wZRXu01koaxyd8UeYpybWqW4h+lO1Okv40Tg==", + "optional": true + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "optional": true + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "optional": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "optional": true, + "dependencies": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "optional": true + }, + "node_modules/thread-stream": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.3.0.tgz", + "integrity": "sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==", + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tsc-alias": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/tsc-alias/-/tsc-alias-1.8.5.tgz", + "integrity": "sha512-Y3ka0olwSRdbHPyX5kXhYY2aoBKuT53DFdeY+PpQUR4hg5M/b8eIRmC8dL4FBdd0wT366iWc6iDUUGe6QwI7mg==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.3", + "commander": "^9.0.0", + "globby": "^11.0.4", + "mylas": "^2.1.9", + "normalize-path": "^3.0.0", + "plimit-lit": "^1.2.6" + }, + "bin": { + "tsc-alias": "dist/bin/index.js" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "optional": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unzipper": { + "version": "0.8.14", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.8.14.tgz", + "integrity": "sha512-8rFtE7EP5ssOwGpN2dt1Q4njl0N1hUXJ7sSPz0leU2hRdq6+pra57z4YPBlVqm40vcgv6ooKZEAx48fMTv9x4w==", + "optional": true, + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "~1.0.10", + "listenercount": "~1.0.1", + "readable-stream": "~2.1.5", + "setimmediate": "~1.0.4" + } + }, + "node_modules/unzipper/node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==", + "optional": true + }, + "node_modules/unzipper/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "optional": true + }, + "node_modules/unzipper/node_modules/process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==", + "optional": true + }, + "node_modules/unzipper/node_modules/readable-stream": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", + "integrity": "sha512-NkXT2AER7VKXeXtJNSaWLpWIhmtSE3K2PguaLEeWr4JILghcIKqoLt1A3wHrnpDC5+ekf8gfk1GKWkFXe4odMw==", + "optional": true, + "dependencies": { + "buffer-shims": "^1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/url-join": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz", + "integrity": "sha512-H6dnQ/yPAAVzMQRvEvyz01hhfQL5qRWSEt7BX8t9DqnPw9BjMb64fjIRq76Uvf1hkHp+mTZvEVJ5guXOT0Xqaw==", + "optional": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "optional": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/window-size": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "integrity": "sha512-2thx4pB0cV3h+Bw7QmMXcEbdmOzv9t0HFplJH/Lz6yu60hXYy5RT8rUu+wlIreVxWsGN20mo+MHeCSfUpQBwPw==", + "optional": true, + "bin": { + "window-size": "cli.js" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", + "optional": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", + "optional": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yargs": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "integrity": "sha512-ONJZiimStfZzhKamYvR/xvmgW3uEkAUFSP91y2caTEPhzF6uP2JfPiVZcq66b/YR0C3uitxSV7+T1x8p5bkmMg==", + "optional": true, + "dependencies": { + "camelcase": "^2.0.1", + "cliui": "^3.0.3", + "decamelize": "^1.1.1", + "os-locale": "^1.4.0", + "string-width": "^1.0.1", + "window-size": "^0.1.4", + "y18n": "^3.2.0" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + } +} diff --git a/acs-uns-ingester/package.json b/acs-uns-ingester/package.json new file mode 100644 index 00000000..70c93948 --- /dev/null +++ b/acs-uns-ingester/package.json @@ -0,0 +1,41 @@ +{ + "name": "influxdb-sparkplug-ingester", + "version": "1.0.0", + "description": "An ingestion engine to enable InfluxDB to be a fully-featured Sparkplug historian", + "author": "AMRC", + "license": "MIT", + "keywords": [ + "amrc", + "factory-plus", + "factoryplus", + "acs", + "amrc-connectivity-stack", + "mqtt", + "sparkplug" + ], + "type": "module", + "scripts": { + "start": "node --trace-warnings dist/bin/ingester.js", + "start:shell": "k5start -Uf $CLIENT_KEYTAB npm run start", + "dev": " npm run build && npm run start:dev", + "build": "tsc && tsc-alias", + "clean": "tsc --build --clean", + "lint": "eslint --ignore-path .gitignore --ext .ts src/", + "lint:fix": "npm run lint -- --fix" + }, + "dependencies": { + "@amrc-factoryplus/utilities": "^1.0.8", + "@influxdata/influxdb-client": "^1.33.2", + "@influxdata/influxdb-client-apis": "^1.33.2", + "async": "^3.2.4", + "long": "^5.2.3", + "pino": "^8.11.0", + "pino-pretty": "^10.0.0" + }, + "devDependencies": { + "cross-env": "^7.0.3", + "dotenv": "^16.0.3", + "ts-node": "^10.9.1", + "tsc-alias": "^1.7.0" + } +} diff --git a/acs-uns-ingester/run-dev.sh b/acs-uns-ingester/run-dev.sh new file mode 100644 index 00000000..cbd64e40 --- /dev/null +++ b/acs-uns-ingester/run-dev.sh @@ -0,0 +1,10 @@ +# +# AMRC InfluxDB Sparkplug Ingester +# Copyright "2023" AMRC +# + +# bin/bash +tmpfile=$(mktemp) +export CLIENT_KEYTAB="$(kubectl --kubeconfig ~/.kube/fplus get -n factory-plus secret krb5-keytabs -o jsonpath="{.data.sv1warehouse}" | base64 -d >"$tmpfile" && echo "$tmpfile")" +echo $CLIENT_KEYTAB +npm run start:shell diff --git a/acs-uns-ingester/tsconfig.json b/acs-uns-ingester/tsconfig.json new file mode 100644 index 00000000..a3a2f0a7 --- /dev/null +++ b/acs-uns-ingester/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "target": "es2017", + "lib": ["es2017", "esnext.asynciterable", "dom"], + "typeRoots": ["node_modules/@types"], + "allowSyntheticDefaultImports": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node", + "module": "es2022", + "pretty": true, + "sourceMap": true, + "declaration": true, + "outDir": "dist", + "allowJs": true, + "noEmit": false, + "esModuleInterop": true, + "resolveJsonModule": true, + "importHelpers": true, + "skipLibCheck": true, + "baseUrl": "src", + "paths": { + "@/*": ["*"], + "@bin/*": ["../bin/*"], + "@lib/*": ["../lib/*"] + } + }, + "include": ["bin/**/*.ts", "lib/**/*.json", ".env"], + "exclude": ["node_modules"] +} diff --git a/influxdb-sparkplug-ingester/.gitignore b/influxdb-sparkplug-ingester/.gitignore index eed26523..de52c1cc 100644 --- a/influxdb-sparkplug-ingester/.gitignore +++ b/influxdb-sparkplug-ingester/.gitignore @@ -15,3 +15,5 @@ dist/ # IDE .idea/ + +*keytab* \ No newline at end of file From 6ec5c66c43587b73b8d8b11624981e33467225b8 Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Tue, 2 Jul 2024 15:13:17 +0100 Subject: [PATCH 02/58] Add metric republishing to local mqtt namespace --- acs-uns-ingester/bin/ingester.ts | 10 +- acs-uns-ingester/example.env | 10 + acs-uns-ingester/lib/mqttclient.ts | 111 +++--- acs-uns-ingester/package-lock.json | 527 +++++++++++++++++++---------- acs-uns-ingester/package.json | 3 +- 5 files changed, 427 insertions(+), 234 deletions(-) create mode 100644 acs-uns-ingester/example.env diff --git a/acs-uns-ingester/bin/ingester.ts b/acs-uns-ingester/bin/ingester.ts index 136b2ac6..36edad14 100644 --- a/acs-uns-ingester/bin/ingester.ts +++ b/acs-uns-ingester/bin/ingester.ts @@ -7,8 +7,12 @@ import {ServiceClient, UUIDs} from "@amrc-factoryplus/utilities"; import pino from "pino"; import pretty from 'pino-pretty'; import MQTTClient from "@lib/mqttclient.js"; + let dotenv: any = null; -try {dotenv = await import ('dotenv')} catch (e) {} +try { + dotenv = await import ('dotenv') +} catch (e) { +} const stream = pretty({ colorize: true @@ -22,7 +26,7 @@ if (!directoryUrl) { } export const logger = pino({ - name: 'InfluxDB Sparkplug Ingester', + name: 'ACS UNS Ingester', level: process.env.LOG_LEVEL || 'info', }, stream); @@ -47,6 +51,6 @@ const mqtt = await new MQTTClient({ e: { serviceClient: client, } -}).init(); +}); mqtt.run(); diff --git a/acs-uns-ingester/example.env b/acs-uns-ingester/example.env new file mode 100644 index 00000000..bef798de --- /dev/null +++ b/acs-uns-ingester/example.env @@ -0,0 +1,10 @@ +DIRECTORY_URL=https://directory.domain.co.uk +INFLUX_URL=http://influx.domain.co.uk +INFLUX_TOKEN=XXXXXX +MQTT_URL=mqtt://mqtt.domain.co.uk +INFLUX_ORG=default +INFLUX_BUCKET=default +LOG_LEVEL=info +BATCH_SIZE=5000 +FLUSH_INTERVAL=10000 +CMD_ESC_URL=https://cmdesc.domain.co.uk \ No newline at end of file diff --git a/acs-uns-ingester/lib/mqttclient.ts b/acs-uns-ingester/lib/mqttclient.ts index 854811c1..f1ecb4fb 100644 --- a/acs-uns-ingester/lib/mqttclient.ts +++ b/acs-uns-ingester/lib/mqttclient.ts @@ -10,6 +10,8 @@ import Long from "long"; import {InfluxDB, Point} from '@influxdata/influxdb-client' import {Agent} from 'http' +import * as mqtt_dev from "mqtt"; + let dotenv: any = null; try { dotenv = await import ('dotenv') @@ -43,6 +45,12 @@ if (!flushInterval) { throw new Error("FLUSH_INTERVAL environment variable is not set"); } +const unsMqttUrl: string = process.env.UNS_MQTT_URL; +if (!unsMqttUrl) { + throw new Error("UNS_MQTT_URL environment variable is not set"); +} + +/* let i = 0; // Node.js HTTP client OOTB does not reuse established TCP connections, a custom node HTTP agent @@ -62,19 +70,20 @@ let interval: any; /* points/lines are batched in order to minimize networking and increase performance */ +/* const writeApi = influxDB.getWriteApi(influxOrganisation, process.env.INFLUX_BUCKET || 'default', 'ns', { - /* the maximum points/lines to send in a single batch to InfluxDB server */ + // the maximum points/lines to send in a single batch to InfluxDB server batchSize: batchSize + 1, // don't let automatically flush data - /* maximum time in millis to keep points in an unflushed batch, 0 means don't periodically flush */ + // maximum time in millis to keep points in an unflushed batch, 0 means don't periodically flush flushInterval: 0, // Never allow the package to flush: we'll flush manually - /* maximum size of the retry buffer - it contains items that could not be sent for the first time */ - maxBufferLines: 30_000, /* the count of internally-scheduled retries upon write failure, the delays between write attempts follow an exponential backoff strategy if there is no Retry-After HTTP header */ + // maximum size of the retry buffer - it contains items that could not be sent for the first time + maxBufferLines: 30_000, // the count of internally-scheduled retries upon write failure, the delays between write attempts follow an exponential backoff strategy if there is no Retry-After HTTP header maxRetries: 0, // do not retry writes // ... there are more write options that can be customized, see // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeoptions.html and // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeretryoptions.html }); - +*/ interface MQTTClientConstructorParams { e: { serviceClient: ServiceClient; @@ -86,33 +95,21 @@ export default class MQTTClient { private mqtt: any; private aliasResolver = {}; private birthDebounce = {}; + private local_mqtt: any; constructor({e}: MQTTClientConstructorParams) { this.serviceClient = e.serviceClient; } - async init() { - - process.on('exit', () => { - this.flushBuffer('EXIT'); - keepAliveAgent.destroy(); - }) - - return this; - } - - private flushBuffer(source: string) { - let bufferSize = i; - i = 0; - writeApi.flush().then(() => { - logger.info(`🚀 Flushed ${bufferSize} points to InfluxDB [${source}]`); - // Reset the interval - this.resetInterval(); - }) - } - async run() { + this.local_mqtt = mqtt_dev.connect(unsMqttUrl); + this.local_mqtt.on("connect", () => { + logger.info("😁 Connected to local mqtt broker!"); + }); + this.local_mqtt.on("error", (error) => { + logger.error(`🔥 Error from broker: ${error}`); + }) const mqtt = await this.serviceClient.mqtt_client(); this.mqtt = mqtt; @@ -129,21 +126,10 @@ export default class MQTTClient { logger.info("🔌 Connected to Factory+ broker"); logger.info("👂 Subscribing to entire Factory+ namespace"); this.mqtt.subscribe('spBv1.0/#'); - this.resetInterval(); - } - - private resetInterval() { - clearInterval(interval); - interval = setInterval(() => { - this.flushBuffer(`${flushInterval}ms INTERVAL`); - }, flushInterval); } on_close() { logger.warn(`❌ Disconnected from Factory+ broker`); - - // Flush any remaining data - this.flushBuffer('CONN_CLOSE'); } on_reconnect() { @@ -152,8 +138,6 @@ export default class MQTTClient { on_error(error: any) { logger.error("🚨 MQTT error: %o", error); - // Flush any remaining data - this.flushBuffer('MQTT_ERROR'); } async on_message(topicString: string, message: Uint8Array | Reader) { @@ -323,7 +307,7 @@ export default class MQTTClient { delete this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]; // Store the default values in InfluxDB - this.writeMetrics(payload, topic); + this.publishToUNS(payload, topic); break; case "DEATH": @@ -349,7 +333,8 @@ export default class MQTTClient { if (this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { // Device is known, resolve aliases and write to InfluxDB - this.writeMetrics(payload, topic); + //this.writeMetrics(payload, topic); + this.publishToUNS(payload, topic) } else { @@ -389,6 +374,46 @@ export default class MQTTClient { return; } + /** + * Publishes received values from the Sparkplug namespace to the UNS with a topic structured to values schema path + * @param payload Received payload. + * @param topic Topic the payload was received on. + */ + private publishToUNS(payload, topic) { + payload.metrics.forEach((metric) => { + if (metric.value === null) return; + let birth = this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]?.[metric.alias]; + + if (!birth) { + return; + } + + if (birth.transient) { + logger.debug(`Metric ${birth.name} is transient, not writing to InfluxDB`); + return; + } + + const metricName = birth.name.split('/').pop() as string; + const path = birth.name.substring(0, birth.name.lastIndexOf("/")) as string; + + if ( + metricName === "Schema_UUID" || + metricName === "Instance_UUID" || + path.includes("Device Control") || + path.includes("Device Information") + ) { + return; + } + + if (path) { + this.local_mqtt.publish(`AMRC/Sheffield/F2050/${topic.address.device}/${path}/${metricName}`, `${metric.value}`); + } else { + this.local_mqtt.publish(`AMRC/Sheffield/F2050/${topic.address.device}/${metricName}`, `${metric.value}`); + } + }); + } + + /* private writeMetrics(payload, topic: Topic) { payload.metrics.forEach((metric) => { let birth = this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]?.[metric.alias]; @@ -411,7 +436,7 @@ export default class MQTTClient { this.writeToInfluxDB(birth, topic, metric.value, metricTimestamp) }); } - + */ /** * Writes metric values to InfluxDB using the metric timestamp. * @param birth Birth certificate for device. @@ -419,6 +444,8 @@ export default class MQTTClient { * @param value Metric value to write to InfluxDB. * @param timestamp Timestamp from the metric to write to influx. */ + + /* writeToInfluxDB(birth, topic: Topic, value, timestamp: Date) { if (value === null) return; if (birth.transient) { @@ -521,7 +548,7 @@ export default class MQTTClient { if (i >= batchSize) { this.flushBuffer(`${batchSize} point BATCH`); } - } + }*/ setNestedValue(obj, path, value) { for (let k = 0; k < path.length - 1; k++) { diff --git a/acs-uns-ingester/package-lock.json b/acs-uns-ingester/package-lock.json index 82e755f5..778ab7a3 100644 --- a/acs-uns-ingester/package-lock.json +++ b/acs-uns-ingester/package-lock.json @@ -1,11 +1,11 @@ { - "name": "influxdb-sparkplug-ingester", + "name": "acs-uns-ingester", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "influxdb-sparkplug-ingester", + "name": "acs-uns-ingester", "version": "1.0.0", "license": "MIT", "dependencies": { @@ -14,6 +14,7 @@ "@influxdata/influxdb-client-apis": "^1.33.2", "async": "^3.2.4", "long": "^5.2.3", + "mqtt": "^5.7.3", "pino": "^8.11.0", "pino-pretty": "^10.0.0" }, @@ -52,11 +53,138 @@ "pg-native": "^3.0.0" } }, + "node_modules/@amrc-factoryplus/utilities/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/commist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", + "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", + "dependencies": { + "leven": "^2.1.0", + "minimist": "^1.1.0" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/help-me": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", + "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", + "dependencies": { + "glob": "^7.1.6", + "readable-stream": "^3.6.0" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/mqtt": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.8.tgz", + "integrity": "sha512-2xT75uYa0kiPEF/PE0VPdavmEkoBzMT/UL9moid0rAvlCtV48qBwxD62m7Ld/4j8tSkIO1E/iqRl/S72SEOhOw==", + "dependencies": { + "commist": "^1.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.1.1", + "duplexify": "^4.1.1", + "help-me": "^3.0.0", + "inherits": "^2.0.3", + "lru-cache": "^6.0.0", + "minimist": "^1.2.5", + "mqtt-packet": "^6.8.0", + "number-allocator": "^1.0.9", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^3.1.0", + "ws": "^7.5.5", + "xtend": "^4.0.2" + }, + "bin": { + "mqtt": "bin/mqtt.js", + "mqtt_pub": "bin/pub.js", + "mqtt_sub": "bin/sub.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/mqtt-packet": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", + "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "dependencies": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + }, + "node_modules/@amrc-factoryplus/utilities/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==" + }, "node_modules/@amrc-factoryplus/utilities/node_modules/path-to-regexp": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" }, + "node_modules/@amrc-factoryplus/utilities/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/@amrc-factoryplus/utilities/node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -71,6 +199,53 @@ "node": ">=10" } }, + "node_modules/@amrc-factoryplus/utilities/node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -327,6 +502,20 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, + "node_modules/@types/readable-stream": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.14.tgz", + "integrity": "sha512-xZn/AuUbCMShGsqH/ehZtGDwQtbx00M9rZ2ENLe4tOjFZ/JFeWMhEZkk2fEe1jAUqqEAURIkFJ7Az/go8mM1/w==", + "dependencies": { + "@types/node": "*", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/@types/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "node_modules/@types/serve-static": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", @@ -336,6 +525,14 @@ "@types/node": "*" } }, + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -561,26 +758,29 @@ } }, "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/bl/-/bl-6.0.13.tgz", + "integrity": "sha512-tMncAcpsyjZgAVbVFupVIaB2xud13xxT59fdHkuszY2jdZkqIWfpQdmII1fOe3kOGAz0mNLTIHEm+KxpYsQKKg==", "dependencies": { - "buffer": "^5.5.0", + "@types/readable-stream": "^4.0.0", + "buffer": "^6.0.3", "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "readable-stream": "^4.2.0" } }, "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { - "node": ">= 6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/bl/node_modules/string_decoder": { @@ -642,9 +842,9 @@ } }, "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { "type": "github", @@ -661,7 +861,7 @@ ], "dependencies": { "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "ieee754": "^1.2.1" } }, "node_modules/buffer-from": { @@ -890,13 +1090,9 @@ } }, "node_modules/commist": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", - "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", - "dependencies": { - "leven": "^2.1.0", - "minimist": "^1.1.0" - } + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz", + "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==" }, "node_modules/concat-map": { "version": "0.0.1", @@ -1210,14 +1406,14 @@ } }, "node_modules/duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", "dependencies": { "end-of-stream": "^1.4.1", "inherits": "^2.0.3", "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" + "stream-shift": "^1.0.2" } }, "node_modules/duplexify/node_modules/readable-stream": { @@ -1366,6 +1562,18 @@ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, + "node_modules/fast-unique-numbers": { + "version": "8.0.13", + "resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-8.0.13.tgz", + "integrity": "sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g==", + "dependencies": { + "@babel/runtime": "^7.23.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.1.0" + } + }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -1691,34 +1899,9 @@ "optional": true }, "node_modules/help-me": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", - "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", - "dependencies": { - "glob": "^7.1.6", - "readable-stream": "^3.6.0" - } - }, - "node_modules/help-me/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/help-me/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==" }, "node_modules/http-cache-semantics": { "version": "4.1.1", @@ -2189,51 +2372,51 @@ } }, "node_modules/mqtt": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.7.tgz", - "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.7.3.tgz", + "integrity": "sha512-v+5la6Q6zjl0AWsI7ICDA/K3hclkNj7CMa0khMugCC+LKPLrQF+sSQb/9ckezZLMvcBC1tXhRzqmcagQoDl9fQ==", "dependencies": { - "commist": "^1.0.0", + "@types/readable-stream": "^4.0.5", + "@types/ws": "^8.5.9", + "commist": "^3.2.0", "concat-stream": "^2.0.0", - "debug": "^4.1.1", - "duplexify": "^4.1.1", - "help-me": "^3.0.0", - "inherits": "^2.0.3", - "lru-cache": "^6.0.0", - "minimist": "^1.2.5", - "mqtt-packet": "^6.8.0", - "number-allocator": "^1.0.9", - "pump": "^3.0.0", - "readable-stream": "^3.6.0", + "debug": "^4.3.4", + "help-me": "^5.0.0", + "lru-cache": "^10.0.1", + "minimist": "^1.2.8", + "mqtt": "^5.2.0", + "mqtt-packet": "^9.0.0", + "number-allocator": "^1.0.14", + "readable-stream": "^4.4.2", "reinterval": "^1.1.0", "rfdc": "^1.3.0", - "split2": "^3.1.0", - "ws": "^7.5.5", - "xtend": "^4.0.2" + "split2": "^4.2.0", + "worker-timers": "^7.1.4", + "ws": "^8.17.1" }, "bin": { - "mqtt": "bin/mqtt.js", - "mqtt_pub": "bin/pub.js", - "mqtt_sub": "bin/sub.js" + "mqtt": "build/bin/mqtt.js", + "mqtt_pub": "build/bin/pub.js", + "mqtt_sub": "build/bin/sub.js" }, "engines": { - "node": ">=10.0.0" + "node": ">=16.0.0" } }, "node_modules/mqtt-packet": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", - "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-9.0.0.tgz", + "integrity": "sha512-8v+HkX+fwbodsWAZIZTI074XIoxVBOmPeggQuDFCGg1SqNcC+uoRMWu7J6QlJPqIUIJXmjNYYHxBBLr1Y/Df4w==", "dependencies": { - "bl": "^4.0.2", - "debug": "^4.1.1", + "bl": "^6.0.8", + "debug": "^4.3.4", "process-nextick-args": "^2.0.1" } }, "node_modules/mqtt-packet/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dependencies": { "ms": "2.1.2" }, @@ -2267,22 +2450,32 @@ } } }, + "node_modules/mqtt/node_modules/lru-cache": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", + "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==", + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/mqtt/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==" }, "node_modules/mqtt/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { - "node": ">= 6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/mqtt/node_modules/string_decoder": { @@ -2631,14 +2824,6 @@ "split2": "^4.1.0" } }, - "node_modules/pgpass/node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "engines": { - "node": ">= 10.x" - } - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -2681,29 +2866,6 @@ "split2": "^4.0.0" } }, - "node_modules/pino-abstract-transport/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/pino-abstract-transport/node_modules/readable-stream": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz", @@ -2718,14 +2880,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/pino-abstract-transport/node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "engines": { - "node": ">= 10.x" - } - }, "node_modules/pino-pretty": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.0.0.tgz", @@ -2758,29 +2912,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/pino-pretty/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/pino-pretty/node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -3109,6 +3240,11 @@ "node": ">= 12.13.0" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, "node_modules/reinterval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", @@ -3344,32 +3480,11 @@ } }, "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", - "dependencies": { - "readable-stream": "^3.0.0" - } - }, - "node_modules/split2/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "engines": { - "node": ">= 6" - } - }, - "node_modules/split2/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" + "node": ">= 10.x" } }, "node_modules/splitargs": { @@ -3387,9 +3502,9 @@ } }, "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==" }, "node_modules/string_decoder": { "version": "0.10.31", @@ -3553,6 +3668,11 @@ "tsc-alias": "dist/bin/index.js" } }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -3706,6 +3826,37 @@ "node": ">= 0.10.0" } }, + "node_modules/worker-timers": { + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-7.1.8.tgz", + "integrity": "sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw==", + "dependencies": { + "@babel/runtime": "^7.24.5", + "tslib": "^2.6.2", + "worker-timers-broker": "^6.1.8", + "worker-timers-worker": "^7.0.71" + } + }, + "node_modules/worker-timers-broker": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-6.1.8.tgz", + "integrity": "sha512-FUCJu9jlK3A8WqLTKXM9E6kAmI/dR1vAJ8dHYLMisLNB/n3GuaFIjJ7pn16ZcD1zCOf7P6H62lWIEBi+yz/zQQ==", + "dependencies": { + "@babel/runtime": "^7.24.5", + "fast-unique-numbers": "^8.0.13", + "tslib": "^2.6.2", + "worker-timers-worker": "^7.0.71" + } + }, + "node_modules/worker-timers-worker": { + "version": "7.0.71", + "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-7.0.71.tgz", + "integrity": "sha512-ks/5YKwZsto1c2vmljroppOKCivB/ma97g9y77MAAz2TBBjPPgpoOiS1qYQKIgvGTr2QYPT3XhJWIB6Rj2MVPQ==", + "dependencies": { + "@babel/runtime": "^7.24.5", + "tslib": "^2.6.2" + } + }, "node_modules/wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", @@ -3725,15 +3876,15 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "engines": { - "node": ">=8.3.0" + "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { diff --git a/acs-uns-ingester/package.json b/acs-uns-ingester/package.json index 70c93948..7c32517e 100644 --- a/acs-uns-ingester/package.json +++ b/acs-uns-ingester/package.json @@ -1,5 +1,5 @@ { - "name": "influxdb-sparkplug-ingester", + "name": "acs-uns-ingester", "version": "1.0.0", "description": "An ingestion engine to enable InfluxDB to be a fully-featured Sparkplug historian", "author": "AMRC", @@ -29,6 +29,7 @@ "@influxdata/influxdb-client-apis": "^1.33.2", "async": "^3.2.4", "long": "^5.2.3", + "mqtt": "^5.7.3", "pino": "^8.11.0", "pino-pretty": "^10.0.0" }, From 69112557957cb3fc50a3330cc7791f1b543138be Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Mon, 15 Jul 2024 08:48:13 +0100 Subject: [PATCH 03/58] Add new payload formatting --- acs-uns-ingester/bin/ingester.ts | 2 +- acs-uns-ingester/example.env | 2 +- acs-uns-ingester/lib/mqttclient.ts | 68 +++++++++++++++++++++++------- acs-uns-ingester/run-dev.sh | 2 +- 4 files changed, 56 insertions(+), 18 deletions(-) diff --git a/acs-uns-ingester/bin/ingester.ts b/acs-uns-ingester/bin/ingester.ts index 36edad14..624a8b52 100644 --- a/acs-uns-ingester/bin/ingester.ts +++ b/acs-uns-ingester/bin/ingester.ts @@ -1,5 +1,5 @@ /* - * AMRC InfluxDB Sparkplug Ingester + * AMRC ACS UNS Ingester * Copyright "2023" AMRC */ diff --git a/acs-uns-ingester/example.env b/acs-uns-ingester/example.env index bef798de..139296ff 100644 --- a/acs-uns-ingester/example.env +++ b/acs-uns-ingester/example.env @@ -1,7 +1,7 @@ DIRECTORY_URL=https://directory.domain.co.uk INFLUX_URL=http://influx.domain.co.uk INFLUX_TOKEN=XXXXXX -MQTT_URL=mqtt://mqtt.domain.co.uk +UNS_MQTT_URL=mqtt://mqtt.domain.co.uk INFLUX_ORG=default INFLUX_BUCKET=default LOG_LEVEL=info diff --git a/acs-uns-ingester/lib/mqttclient.ts b/acs-uns-ingester/lib/mqttclient.ts index f1ecb4fb..5ed0b0b7 100644 --- a/acs-uns-ingester/lib/mqttclient.ts +++ b/acs-uns-ingester/lib/mqttclient.ts @@ -1,5 +1,5 @@ /* - * AMRC InfluxDB Sparkplug Ingester + * AMRC ACS UNS Ingester * Copyright "2024" AMRC */ @@ -12,6 +12,15 @@ import {Agent} from 'http' import * as mqtt_dev from "mqtt"; +interface UnsMetric { + value: string, + timestamp: Date, +} + +interface BatchedUnsMetric extends UnsMetric { + batch?: UnsMetric[] +} + let dotenv: any = null; try { dotenv = await import ('dotenv') @@ -20,6 +29,7 @@ try { dotenv?.config() +/* const influxURL: string = process.env.INFLUX_URL; if (!influxURL) { throw new Error("INFLUX_URL environment variable is not set"); @@ -44,7 +54,7 @@ const flushInterval: number = Number.parseInt(process.env.FLUSH_INTERVAL); if (!flushInterval) { throw new Error("FLUSH_INTERVAL environment variable is not set"); } - +*/ const unsMqttUrl: string = process.env.UNS_MQTT_URL; if (!unsMqttUrl) { throw new Error("UNS_MQTT_URL environment variable is not set"); @@ -104,7 +114,7 @@ export default class MQTTClient { async run() { this.local_mqtt = mqtt_dev.connect(unsMqttUrl); this.local_mqtt.on("connect", () => { - logger.info("😁 Connected to local mqtt broker!"); + logger.info("✔ Connected to local mqtt broker!"); }); this.local_mqtt.on("error", (error) => { @@ -306,7 +316,7 @@ export default class MQTTClient { // Clear the debounce delete this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]; - // Store the default values in InfluxDB + // Publish values to UNS this.publishToUNS(payload, topic); break; @@ -332,7 +342,7 @@ export default class MQTTClient { // Check if we have a birth certificate for the device if (this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { - // Device is known, resolve aliases and write to InfluxDB + // Device is known, resolve aliases and publish to UNS //this.writeMetrics(payload, topic); this.publishToUNS(payload, topic) @@ -380,6 +390,8 @@ export default class MQTTClient { * @param topic Topic the payload was received on. */ private publishToUNS(payload, topic) { + const metricsToPublish: { [metricPath: string]: any[] } = {}; + //resolve metric aliases payload.metrics.forEach((metric) => { if (metric.value === null) return; let birth = this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]?.[metric.alias]; @@ -389,28 +401,54 @@ export default class MQTTClient { } if (birth.transient) { - logger.debug(`Metric ${birth.name} is transient, not writing to InfluxDB`); + logger.debug(`Metric ${birth.name} is transient, publishing to UNS`); return; } const metricName = birth.name.split('/').pop() as string; const path = birth.name.substring(0, birth.name.lastIndexOf("/")) as string; - - if ( - metricName === "Schema_UUID" || - metricName === "Instance_UUID" || - path.includes("Device Control") || - path.includes("Device Information") - ) { + if (path.includes("Device Control")) { return; } + let unsTopic: string; + if (path) { - this.local_mqtt.publish(`AMRC/Sheffield/F2050/${topic.address.device}/${path}/${metricName}`, `${metric.value}`); + // enterprise, site, area, cell, device? namespace where edge is the raw data from the device edge. + unsTopic = `AMRC/F2050/MK1/${topic.address.device}/Edge/${path}/${metricName}`; } else { - this.local_mqtt.publish(`AMRC/Sheffield/F2050/${topic.address.device}/${metricName}`, `${metric.value}`); + unsTopic = `AMRC/F2050/MK1/${topic.address.device}/Edge/${metricName}`; } + + if (!(unsTopic in metricsToPublish)) { + metricsToPublish[unsTopic] = [metric] + } else { + metricsToPublish[unsTopic].push(metric); + } + }); + + // format payload to publish to uns. + Object.entries(metricsToPublish).forEach(([key, value]) => { + // if theirs more than one of the same metric from the same sparkplug payload, add the values to the batch array. + if (value.length > 1) { + const sortedMetrics = value.sort((a, b) => b.timestamp - a.timestamp); + let payload: BatchedUnsMetric = { + timestamp: new Date(sortedMetrics[0].timestamp), + value: sortedMetrics[0].value, + batch: [] + } + //remove the first element, that's our newest and will be the value outside the batch array. + sortedMetrics.shift(); + sortedMetrics.forEach(metric => { + payload.batch.push({timestamp: metric.timestamp, value: metric.value}); + }); + this.local_mqtt.publish(key, payload); + } else { + const payload: UnsMetric = {timestamp: new Date(value[0].timestamp), value: value[0].value}; + this.local_mqtt.publish(key, payload); + } + }) } /* diff --git a/acs-uns-ingester/run-dev.sh b/acs-uns-ingester/run-dev.sh index cbd64e40..2f90906d 100644 --- a/acs-uns-ingester/run-dev.sh +++ b/acs-uns-ingester/run-dev.sh @@ -1,5 +1,5 @@ # -# AMRC InfluxDB Sparkplug Ingester +# AMRC ACS UNS Ingester # Copyright "2023" AMRC # From bb0ea62139930b58a96d59315bdcb9c269bf7fa1 Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Mon, 1 Jul 2024 09:58:57 +0100 Subject: [PATCH 04/58] Add copy of Influx Ingester as UNS Ingester --- acs-uns-ingester/.gitignore | 19 + acs-uns-ingester/Dockerfile | 67 + acs-uns-ingester/LICENSE | 21 + acs-uns-ingester/Makefile | 7 + acs-uns-ingester/README.md | 5 + acs-uns-ingester/SECURITY.md | 15 + acs-uns-ingester/bin/ingester.js | 28 + acs-uns-ingester/bin/ingester.ts | 52 + acs-uns-ingester/lib/mqttclient.js | 182 ++ acs-uns-ingester/lib/mqttclient.ts | 533 ++++ acs-uns-ingester/package-lock.json | 3791 ++++++++++++++++++++++++ acs-uns-ingester/package.json | 41 + acs-uns-ingester/run-dev.sh | 10 + acs-uns-ingester/tsconfig.json | 32 + influxdb-sparkplug-ingester/.gitignore | 2 + 15 files changed, 4805 insertions(+) create mode 100644 acs-uns-ingester/.gitignore create mode 100644 acs-uns-ingester/Dockerfile create mode 100644 acs-uns-ingester/LICENSE create mode 100644 acs-uns-ingester/Makefile create mode 100644 acs-uns-ingester/README.md create mode 100644 acs-uns-ingester/SECURITY.md create mode 100644 acs-uns-ingester/bin/ingester.js create mode 100644 acs-uns-ingester/bin/ingester.ts create mode 100644 acs-uns-ingester/lib/mqttclient.js create mode 100644 acs-uns-ingester/lib/mqttclient.ts create mode 100644 acs-uns-ingester/package-lock.json create mode 100644 acs-uns-ingester/package.json create mode 100644 acs-uns-ingester/run-dev.sh create mode 100644 acs-uns-ingester/tsconfig.json diff --git a/acs-uns-ingester/.gitignore b/acs-uns-ingester/.gitignore new file mode 100644 index 00000000..de52c1cc --- /dev/null +++ b/acs-uns-ingester/.gitignore @@ -0,0 +1,19 @@ +/node_modules/ + +# Vim swap +*.swp + +# Environment +.env +dist/ + +dist/ + +# Secrets +/keytabs/ +/volumes/ + +# IDE +.idea/ + +*keytab* \ No newline at end of file diff --git a/acs-uns-ingester/Dockerfile b/acs-uns-ingester/Dockerfile new file mode 100644 index 00000000..2ff683bf --- /dev/null +++ b/acs-uns-ingester/Dockerfile @@ -0,0 +1,67 @@ +# syntax=docker/dockerfile:1 +# The line above must be the first line in the file! + +ARG base_version +ARG base_prefix=ghcr.io/amrc-factoryplus/acs-base + +ARG acs_build=${base_prefix}-js-build:${base_version} +ARG acs_run=${base_prefix}-js-run:${base_version} + +FROM ${acs_build} as ts-compiler +# This ARG must go here, in the image that uses it, or it isn't +# available to the shell scripts. Don't ask me why... +ARG acs_npm=NO +ARG revision=unknown + +USER root +RUN <<'SHELL' + install -d -o node /home/node /usr/app +SHELL +USER node +WORKDIR /usr/app +COPY --chown=node . ./ +RUN <<'SHELL' + touch /home/node/.npmrc + if [ "${acs_npm}" != NO ] + then + echo "SETTING NPM REGISTRY TO ${acs_npm}" >&2 + npm config set @amrc-factoryplus:registry "${acs_npm}" + fi + npm install --save=false + + echo "export const GIT_VERSION=\"$revision\";" > ./lib/git-version.js + + npm run clean + echo tsc -v + npm run build +SHELL + +FROM ${acs_build} as util-build +USER root +RUN <<'SHELL' + # Are these necessary? + apk upgrade --update-cache --available + apk add openssl + rm -rf /var/cache/apk/* + install -d -o node /home/node /usr/app +SHELL +USER node +WORKDIR /usr/app +COPY --chown=node --from=ts-compiler /usr/app/package*.json ./ +COPY --chown=node --from=ts-compiler /usr/app/dist ./ +COPY --chown=node --from=ts-compiler /home/node/.npmrc /home/node +RUN npm install --save=false --only=production + +FROM ${acs_run} +USER root +RUN <<'SHELL' + apk upgrade --update-cache --available + apk add openssl + rm -rf /var/cache/apk/* +SHELL +WORKDIR /usr/app +# This copy leaves the app files owned as root, i.e. read-only to the +# running application. This is a Good Thing. +COPY --from=util-build /usr/app ./ +USER node +CMD [ "node", "--es-module-specifier-resolution=node", "bin/ingester.js" ] diff --git a/acs-uns-ingester/LICENSE b/acs-uns-ingester/LICENSE new file mode 100644 index 00000000..cdb7bae2 --- /dev/null +++ b/acs-uns-ingester/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 AMRC-FactoryPlus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/acs-uns-ingester/Makefile b/acs-uns-ingester/Makefile new file mode 100644 index 00000000..bf4d70ab --- /dev/null +++ b/acs-uns-ingester/Makefile @@ -0,0 +1,7 @@ +top=.. +include ${top}/mk/acs.init.mk + +repo?=influxdb-sparkplug-ingester +k8s.deployment?=influxdb-ingester + +include ${mk}/acs.js.mk diff --git a/acs-uns-ingester/README.md b/acs-uns-ingester/README.md new file mode 100644 index 00000000..5d24db65 --- /dev/null +++ b/acs-uns-ingester/README.md @@ -0,0 +1,5 @@ +# InfluxDB Sparkplug Ingester + +A component that allows InfluxDB to function as a comprehensive Sparkplug-based data historian. It was developed for the [AMRC Connectiviy Stack](https://github.com/AMRC-FactoryPlus/amrc-connectivity-stack), the AMRC's open-source implementation of the Factory+ framework. + +See the [ACS Helm chart](https://github.com/AMRC-FactoryPlus/amrc-connectivity-stack) for information on how to deploy this component. diff --git a/acs-uns-ingester/SECURITY.md b/acs-uns-ingester/SECURITY.md new file mode 100644 index 00000000..91a8ba7e --- /dev/null +++ b/acs-uns-ingester/SECURITY.md @@ -0,0 +1,15 @@ +## Reporting a Vulnerability + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please register a new advisory from the Security tab in Github. + +Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: + +- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) +- Full paths of source file(s) related to the manifestation of the issue +- The location of the affected source code (tag/branch/commit or direct URL) +- Any special configuration required to reproduce the issue +- Step-by-step instructions to reproduce the issue +- Proof-of-concept or exploit code (if possible) +- Impact of the issue, including how an attacker might exploit the issue diff --git a/acs-uns-ingester/bin/ingester.js b/acs-uns-ingester/bin/ingester.js new file mode 100644 index 00000000..7ae99c60 --- /dev/null +++ b/acs-uns-ingester/bin/ingester.js @@ -0,0 +1,28 @@ +import { Debug, ServiceClient } from "@amrc-factoryplus/utilities"; +import MQTTClient from "../lib/mqttclient"; +const deviceUUID = process.env.DEVICE_UUID; +const MQTTURL = process.env.MQTT_URL; +const sparkplugAddress = process.env.SPARKPLUG_ADDRESS; +if (!deviceUUID) { + throw new Error("Device UUID not set"); +} +if (!MQTTURL) { + throw new Error("MQTT URL not set"); +} +if (!sparkplugAddress) { + throw new Error("Sparkplug Address not set"); +} +const debug = new Debug(); +const client = await new ServiceClient({ + directory_url: process.env.DIRECTORY_URL, + root_principal: process.env.ROOT_PRINCIPAL, +}).init(); +const mqtt = await new MQTTClient({ + e: { + serviceClient: client, + deviceUUID: deviceUUID, + url: MQTTURL, + sparkplugAddress: sparkplugAddress + } +}).init(); +mqtt.run(); diff --git a/acs-uns-ingester/bin/ingester.ts b/acs-uns-ingester/bin/ingester.ts new file mode 100644 index 00000000..136b2ac6 --- /dev/null +++ b/acs-uns-ingester/bin/ingester.ts @@ -0,0 +1,52 @@ +/* + * AMRC InfluxDB Sparkplug Ingester + * Copyright "2023" AMRC + */ + +import {ServiceClient, UUIDs} from "@amrc-factoryplus/utilities"; +import pino from "pino"; +import pretty from 'pino-pretty'; +import MQTTClient from "@lib/mqttclient.js"; +let dotenv: any = null; +try {dotenv = await import ('dotenv')} catch (e) {} + +const stream = pretty({ + colorize: true +}) + +dotenv?.config(); + +const directoryUrl = process.env.DIRECTORY_URL; +if (!directoryUrl) { + throw new Error("DIRECTORY_URL environment variable is not set"); +} + +export const logger = pino({ + name: 'InfluxDB Sparkplug Ingester', + level: process.env.LOG_LEVEL || 'info', +}, stream); + + +const client = await new ServiceClient({ + directory_url: directoryUrl, +}).init(); + +// Overwrite MQTT server if specified in environment +if (process.env.MQTT_URL) { + client.Discovery.set_service_url(UUIDs.Service.MQTT, process.env.MQTT_URL); +} + +// Overwrite Command Escalation server if specified in environment +if (process.env.CMD_ESC_URL) { + client.Discovery.set_service_url(UUIDs.Service.Command_Escalation, process.env.CMD_ESC_URL); +} + +logger.info(client.service_urls('feb27ba3-bd2c-4916-9269-79a61ebc4a47')); + +const mqtt = await new MQTTClient({ + e: { + serviceClient: client, + } +}).init(); + +mqtt.run(); diff --git a/acs-uns-ingester/lib/mqttclient.js b/acs-uns-ingester/lib/mqttclient.js new file mode 100644 index 00000000..30be1af7 --- /dev/null +++ b/acs-uns-ingester/lib/mqttclient.js @@ -0,0 +1,182 @@ +import { Address, Debug, MetricBuilder, SpB, Topic } from "@amrc-factoryplus/utilities"; +const debug = new Debug(); +export default class MQTTClient { + serviceClient; + deviceUUID; + url; + address; + seq; + mqtt; + constructor({ e }) { + this.serviceClient = e.serviceClient; + this.deviceUUID = e.deviceUUID; + this.url = e.url; + this.address = Address.parse(e.sparkplugAddress); + this.seq = 0; + } + async init() { + return this; + } + will() { + const nDeath = { + timestamp: Date.now(), + metrics: MetricBuilder.death.node([]), + }; + // @ts-ignore + const will = SpB.encodePayload(nDeath); + return { + topic: this.address.topic("DEATH"), + payload: will, + qos: 0, + retain: false, + }; + } + async run() { + const mqtt = await this.serviceClient.mqtt_client({ + verbose: true, + // @ts-ignore + will: this.will(), + }); + this.mqtt = mqtt; + mqtt.on("gssconnect", this.on_connect.bind(this)); + mqtt.on("error", this.on_error.bind(this)); + mqtt.on("message", this.on_message.bind(this)); + // We subscribe to the whole Sparkplug namespace + mqtt.subscribe('spBv1.0/#'); + } + // encode_metrics(metrics, with_uuid) { + // const payload = { + // timestamp: Date.now(), + // metrics: metrics, + // seq: this.seq, + // }; + // this.seq = (this.seq < 255) ? (this.seq + 1) : 0; + // if (with_uuid) + // payload.uuid = UUIDs.FactoryPlus; + // + // return SpB.encodePayload(payload); + // } + // publish(kind, metrics, with_uuid) { + // if (!this.mqtt) { + // debug.log("mqtt", "Can't publish without an MQTT connection."); + // return; + // } + // + // const topic = this.address.topic(kind); + // const payload = this.encode_metrics(metrics, with_uuid); + // + // this.mqtt.publish(topic, payload); + // } + on_connect() { + debug.log("mqtt", "Connected to MQTT broker."); + // this.rebirth(); + } + // rebirth() { + // + // this.seq = 0; + // const Birth = MetricBuilder.birth; + // const metrics = Birth.node([]); + // //Birth.command_escalation(metrics); + // metrics.push.apply(metrics, [ + // {name: "Device_Information/Manufacturer", type: "String", value: Device_Info.Manufacturer}, + // {name: "Device_Information/Model", type: "String", value: Device_Info.Model}, + // {name: "Device_Information/Serial", type: "String", value: Device_Info.Serial}, + // + // {name: "Schema_UUID", type: "UUID", value: Schema.Service}, + // {name: "Instance_UUID", type: "UUID", value: this.device_uuid}, + // {name: "Service_UUID", type: "UUID", value: Service.Registry}, + // {name: "Service_URL", type: "String", value: this.url}, + // ]); + // metrics.push.apply(metrics, + // Object.values(Changed).map(v => + // ({name: `Last_Changed/${v}`, type: "UUID", value: ""}))); + // + // debug.log("mqtt", `Publishing birth certificate`); + // this.publish("BIRTH", metrics, true); + // } + // publish_changed(changes) { + // const metrics = []; + // for (let [to, uuid] of Object.entries(changes)) { + // if (!(to in Changed)) + // continue; + // metrics.push({ + // name: `Last_Changed/${Changed[to]}`, + // type: "UUID", + // value: uuid, + // }); + // } + // this.publish("DATA", metrics); + // } + on_error(error) { + debug.log("mqtt", "MQTT error: %o", error); + } + async on_message(topicString, message) { + let topic = Topic.parse(topicString); + if (!topic) { + debug.log("mqtt", `Bad topic: ${topicString}`); + return; + } + let address = topic.address; + let payload; + try { + // @ts-ignore + payload = SpB.decodePayload(message); + } + catch { + debug.log("mqtt", `Bad payload on topic ${topicString}`); + return; + } + switch (topic.type) { + case "BIRTH": + //await this.on_birth(address, payload); + break; + case "DEATH": + //await this.on_death(address, payload); + break; + case "DATA": + await this.on_data(address, payload); + break; + case "CMD": + await this.on_command(address, payload); + break; + default: + debug.log("mqtt", `Unknown Sparkplug message type ${topic.type}!`); + } + } + async on_data(addr, payload) { + if (!payload.metrics) { + debug.log("mqtt", `Received DATA with no metrics!`); + return; + } + // for (let m of payload.metrics) { + // switch (m.name) { + // // case "Node Control/Rebirth": + // // await this.rebirth(); + // // break; + // default: + // debug.log("mqtt", `Received unknown CMD: ${m.name}`); + // /* Ignore for now */ + // } + // } + } + async on_command(addr, payload) { + if (!addr.equals(this.address)) { + //console.log(`Received CMD for ${addr}`); + return; + } + if (!payload.metrics) { + debug.log("mqtt", `Received CMD with no metrics!`); + return; + } + for (let m of payload.metrics) { + switch (m.name) { + // case "Node Control/Rebirth": + // await this.rebirth(); + // break; + default: + debug.log("mqtt", `Received unknown CMD: ${m.name}`); + /* Ignore for now */ + } + } + } +} diff --git a/acs-uns-ingester/lib/mqttclient.ts b/acs-uns-ingester/lib/mqttclient.ts new file mode 100644 index 00000000..854811c1 --- /dev/null +++ b/acs-uns-ingester/lib/mqttclient.ts @@ -0,0 +1,533 @@ +/* + * AMRC InfluxDB Sparkplug Ingester + * Copyright "2024" AMRC + */ + +import {ServiceClient, SpB, Topic, UUIDs} from "@amrc-factoryplus/utilities"; +import {Reader} from "protobufjs"; +import {logger} from "../bin/ingester.js"; +import Long from "long"; +import {InfluxDB, Point} from '@influxdata/influxdb-client' +import {Agent} from 'http' + +let dotenv: any = null; +try { + dotenv = await import ('dotenv') +} catch (e) { +} + +dotenv?.config() + +const influxURL: string = process.env.INFLUX_URL; +if (!influxURL) { + throw new Error("INFLUX_URL environment variable is not set"); +} + +const influxToken: string = process.env.INFLUX_TOKEN +if (!influxToken) { + throw new Error("INFLUX_TOKEN environment variable is not set"); +} + +const influxOrganisation: string = process.env.INFLUX_ORG +if (!influxOrganisation) { + throw new Error("INFLUX_ORG environment variable is not set"); +} + +const batchSize: number = Number.parseInt(process.env.BATCH_SIZE); +if (!batchSize) { + throw new Error("BATCH_SIZE environment variable is not set"); +} + +const flushInterval: number = Number.parseInt(process.env.FLUSH_INTERVAL); +if (!flushInterval) { + throw new Error("FLUSH_INTERVAL environment variable is not set"); +} + +let i = 0; + +// Node.js HTTP client OOTB does not reuse established TCP connections, a custom node HTTP agent +// can be used to reuse them and thus reduce the count of newly established networking sockets +const keepAliveAgent = new Agent({ + keepAlive: true, // reuse existing connections + keepAliveMsecs: 20 * 1000, // 20 seconds keep alive +}) + +const influxDB = new InfluxDB({ + url: influxURL, token: influxToken, transportOptions: { + agent: keepAliveAgent, + } +}) + +let interval: any; + +/* points/lines are batched in order to minimize networking and increase performance */ + +const writeApi = influxDB.getWriteApi(influxOrganisation, process.env.INFLUX_BUCKET || 'default', 'ns', { + /* the maximum points/lines to send in a single batch to InfluxDB server */ + batchSize: batchSize + 1, // don't let automatically flush data + /* maximum time in millis to keep points in an unflushed batch, 0 means don't periodically flush */ + flushInterval: 0, // Never allow the package to flush: we'll flush manually + /* maximum size of the retry buffer - it contains items that could not be sent for the first time */ + maxBufferLines: 30_000, /* the count of internally-scheduled retries upon write failure, the delays between write attempts follow an exponential backoff strategy if there is no Retry-After HTTP header */ + maxRetries: 0, // do not retry writes + // ... there are more write options that can be customized, see + // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeoptions.html and + // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeretryoptions.html +}); + +interface MQTTClientConstructorParams { + e: { + serviceClient: ServiceClient; + } +} + +export default class MQTTClient { + private serviceClient: ServiceClient; + private mqtt: any; + private aliasResolver = {}; + private birthDebounce = {}; + + constructor({e}: MQTTClientConstructorParams) { + this.serviceClient = e.serviceClient; + } + + async init() { + + process.on('exit', () => { + this.flushBuffer('EXIT'); + keepAliveAgent.destroy(); + }) + + return this; + } + + private flushBuffer(source: string) { + let bufferSize = i; + i = 0; + writeApi.flush().then(() => { + logger.info(`🚀 Flushed ${bufferSize} points to InfluxDB [${source}]`); + // Reset the interval + this.resetInterval(); + }) + } + + async run() { + + const mqtt = await this.serviceClient.mqtt_client(); + this.mqtt = mqtt; + + mqtt.on("authenticated", this.on_connect.bind(this)); + mqtt.on("error", this.on_error.bind(this)); + mqtt.on("message", this.on_message.bind(this)); + mqtt.on("close", this.on_close.bind(this)); + mqtt.on("reconnect", this.on_reconnect.bind(this)); + + logger.info("Connecting to Factory+ broker..."); + } + + on_connect() { + logger.info("🔌 Connected to Factory+ broker"); + logger.info("👂 Subscribing to entire Factory+ namespace"); + this.mqtt.subscribe('spBv1.0/#'); + this.resetInterval(); + } + + private resetInterval() { + clearInterval(interval); + interval = setInterval(() => { + this.flushBuffer(`${flushInterval}ms INTERVAL`); + }, flushInterval); + } + + on_close() { + logger.warn(`❌ Disconnected from Factory+ broker`); + + // Flush any remaining data + this.flushBuffer('CONN_CLOSE'); + } + + on_reconnect() { + logger.warn(`⚠️ Reconnecting to Factory+ broker...`); + } + + on_error(error: any) { + logger.error("🚨 MQTT error: %o", error); + // Flush any remaining data + this.flushBuffer('MQTT_ERROR'); + } + + async on_message(topicString: string, message: Uint8Array | Reader) { + let topic = Topic.parse(topicString); + let payload; + + try { + payload = SpB.decodePayload(message); + } catch { + logger.error(`🚨 Bad payload on topic ${topicString}`); + return; + } + + if (!topic) { + logger.error(`🚨 Bad topic: ${topicString}`); + return; + } + + switch (topic.type) { + case "BIRTH": + + // Don't handle Node births + if (!topic.address.isDevice()) return; + + let topLevelSchema = null; + let schemaUUIDMapping = {}; + + let topLevelInstance = null; + let instanceUUIDMapping = {}; + + // If we have a Factory+ payload then process the Schema UUIDs and Instance UUIDs + if (payload.uuid === UUIDs.FactoryPlus) { + + // Schema_UUIDs + payload.metrics.forEach((metric) => { + // If the name ends in Schema_UUID (e.g. Phases/1/Schema_UUID) + if (metric.name.endsWith("Schema_UUID")) { + // Then get the entire string before the /Schema_UUID + let schemaPath = metric.name.split("/").slice(0, -1).join("/"); + + // If the schemaPath is empty then this is the top level Schema_UUID + if (schemaPath === "") { + // So set the topLevelSchema to this value + topLevelSchema = metric.value; + } else { + // Add this mapping to the schemaUUIDMapping array. This means + // that all metrics that contain this schema path in their name + // will have + schemaUUIDMapping[schemaPath] = metric.value; + } + } + }) + + // Instance_UUIDs + payload.metrics.forEach((metric) => { + // If the name ends in Instance_UUID (e.g. Phases/1/Instance_UUID) + if (metric.name.endsWith("Instance_UUID")) { + // Then get the entire string before the /Instance_UUID + let instancePath = metric.name.split("/").slice(0, -1).join("/"); + + // If the instancePath is empty then this is the top level Instance_UUID + if (instancePath === "") { + // So set the topLevelInstance to this value + topLevelInstance = metric.value; + } else { + // Add this mapping to the instanceUUIDMapping array. This means + // that all metrics that contain this instance path in their name + // will have + instanceUUIDMapping[instancePath] = metric.value; + } + } + }) + } + + if (this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { + logger.info(`🔄 Received updated birth certificate for ${topic.address.group}/${topic.address.node}/${topic.address.device} with Instance_UUID ${topLevelInstance} using Schema_UUID ${topLevelSchema}`); + } else { + logger.info(`👶 Received birth certificate for ${topic.address.group}/${topic.address.node}/${topic.address.device} with Instance_UUID ${topLevelInstance} using Schema_UUID ${topLevelSchema}`); + } + + // Store the birth certificate mapping in the alias resolver. This uses the alias as the key and a simplified object containing the name and type as the value. + this.setNestedValue(this.aliasResolver, [topic.address.group, topic.address.node, topic.address.device], payload.metrics.reduce(function (acc, obj) { + let alias = Long.isLong(obj.alias) ? obj.alias.toNumber() : obj.alias; + + // Work out all schemas that are involved in this metric. + // + // e.g. Assume the current metric is CNC/Axes/1/BaseAxis/Position/Actual + // + // The schemaUUIDMapping object will contain the following (non-relevant emitted): + // - Axes/1: e39007e9-1427-4867-9d72-1c00c663db15 + // - Axes/1/BaseAxis: 777dd941-f426-4355-8130-e144530b1376 + // - Axes/1/BaseAxis/Position: 1a2c3594-d311-4f6b-865b-b97db3fa6d42 + + // Schema_UUIDs + + let schemas = []; + // Get all entries in the schemaUUIDMapping object that have keys that fit in the current obj.name + Object.entries(schemaUUIDMapping).forEach(([schemaPath, schemaUUID]) => { + // If the current obj.name contains the schemaPath then add the schemaUUID to the schemas array + if (obj.name.includes(schemaPath)) { + schemas.push(schemaUUID); + } + }); + + // Get the bottom level schema by finding the the entry in the schemaUUIDMapping object that has + // the key with the most slashes that fits in the current obj.name + let bottomLevelSchema = Object.entries(schemaUUIDMapping).reduce((acc, [schemaPath, schemaUUID]) => { + if (obj.name.includes(schemaPath) && schemaPath.split("/").length > acc.split("/").length) { + return schemaUUID; + } else { + return acc; + } + }, ""); + + // Instance_UUIDs + + let instances = []; + // Get all entries in the instanceUUIDMapping object that have keys that fit in the current obj.name + Object.entries(instanceUUIDMapping).forEach(([instancePath, instanceUUID]) => { + // If the current obj.name contains the instancePath then add the instanceUUID to the instances array + if (obj.name.includes(instancePath)) { + instances.push(instanceUUID); + } + }); + + // Get the bottom level instance by finding the the entry in the instanceUUIDMapping object that has + // the key with the most slashes that fits in the current obj.name + let bottomLevelInstance = Object.entries(instanceUUIDMapping).reduce((acc, [instancePath, instanceUUID]) => { + if (obj.name.includes(instancePath) && instancePath.split("/").length > acc.split("/").length) { + return instanceUUID; + } else { + return acc; + } + }, ""); + + acc[alias] = { + instance: { + // The top level instance for this device + top: topLevelInstance, + + // The last instance before this metric + bottom: bottomLevelInstance, + + // All instances between the top and bottom, inclusive + full: instances, + }, + schema: { + // The top level schema for this device + top: topLevelSchema, + + // The last schema before this metric + bottom: bottomLevelSchema, + + // All schemas between the top and bottom, inclusive + full: schemas, + }, + name: obj.name, + type: obj.type, + alias: alias, + unit: obj.properties?.engUnit?.value, + transient: obj.isTransient + }; + return acc; + }, {})); + + // Clear the debounce + delete this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]; + + // Store the default values in InfluxDB + this.writeMetrics(payload, topic); + + break; + case "DEATH": + + // If the death certificate is for a device then remove it from the known devices, otherwise remove the entire node + if (topic.address.isDevice()) { + logger.info(`💀 Received death certificate for ${topic.address.group}/${topic.address.node}/${topic.address.device}. Removing from known devices.`); + delete this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device] + delete this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device] + break; + } else { + logger.info(`💀💀💀 Received death certificate for entire node ${topic.address.group}/${topic.address.node}. Removing from known nodes.`); + delete this.birthDebounce?.[topic.address.group]?.[topic.address.node] + delete this.aliasResolver?.[topic.address.group]?.[topic.address.node] + break; + } + case "DATA": + + // Don't handle Node data + if (!topic.address.isDevice()) return; + + // Check if we have a birth certificate for the device + if (this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { + + // Device is known, resolve aliases and write to InfluxDB + this.writeMetrics(payload, topic); + + } else { + + // Check that we don't already have an active debounce for this device + if (this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { + logger.info(`⏳ Device ${topic.address.group}/${topic.address.node}/${topic.address.device} is unknown but has pending birth certificate request. Ignoring.`); + return; + } + + logger.info(`✨ Device ${topic.address.group}/${topic.address.node}/${topic.address.device} is unknown, requesting birth certificate`); + + // Create debounce timout for this device + this.setNestedValue(this.birthDebounce, [topic.address.group, topic.address.node, topic.address.device], true); + setTimeout(() => { + delete this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]; + }, Math.floor(Math.random() * (10000 - 5000 + 1) + 5000)); + + // Request birth certificate + let response = await this.serviceClient.fetch({ + service: UUIDs.Service.Command_Escalation, + url: `/v1/address/${topic.address.group}/${topic.address.node}/${topic.address.device}`, + method: "POST", + headers: { + "content-type": "application/json" + }, + body: JSON.stringify({ + "name": "Device Control/Rebirth", "value": "true" + }) + }) + + logger.info('📣 Birth certificate request sent for %s. Status: %s', topic.address, response.status); + + } + break; + } + + return; + } + + private writeMetrics(payload, topic: Topic) { + payload.metrics.forEach((metric) => { + let birth = this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]?.[metric.alias]; + + if (!birth) { + logger.error(`Metric ${metric.alias} is unknown for ${topic.address.group}/${topic.address.node}/${topic.address.device}`); + } + + let metricTimestamp: Date + if (metric.timestamp) { + metricTimestamp = new Date(metric.timestamp); + } else if (payload.timestamp) { + // Metrics might not have a timestamp so use the packet timestamp if we have it. + metricTimestamp = new Date(payload.timestamp); + } else { + // No timestamp can be found on the metric or the payload, just use the current time instead. + metricTimestamp = new Date(); + } + // Send each metric to InfluxDB + this.writeToInfluxDB(birth, topic, metric.value, metricTimestamp) + }); + } + + /** + * Writes metric values to InfluxDB using the metric timestamp. + * @param birth Birth certificate for device. + * @param topic Topic the metric was published on. + * @param value Metric value to write to InfluxDB. + * @param timestamp Timestamp from the metric to write to influx. + */ + writeToInfluxDB(birth, topic: Topic, value, timestamp: Date) { + if (value === null) return; + if (birth.transient) { + logger.debug(`Metric ${birth.name} is transient, not writing to InfluxDB`); + return; + } + + // Get the value after the last / + let metricName = birth.name.split('/').pop(); + + // Get the path as everything behind the last / + let path = birth.name.substring(0, birth.name.lastIndexOf("/")); + + writeApi.useDefaultTags({ + topLevelInstance: birth.instance.top, + bottomLevelInstance: birth.instance.bottom, + usesInstances: birth.instance.top + ':' + birth.instance.full.join(':'), + topLevelSchema: birth.schema.top, + bottomLevelSchema: birth.schema.bottom, + usesSchemas: birth.schema.top + ':' + birth.schema.full.join(':'), + group: topic.address.group, + node: topic.address.node, + device: topic.address.device, + path: path, + unit: birth.unit + }); + + let numVal = null; + + switch (birth.type) { + case "Int8": + case "Int16": + case "Int32": + case "Int64": + // Validate + numVal = Number(value); + if (!Number.isInteger(numVal)) { + logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${numVal}. Not recording.`); + return; + } + writeApi.writePoint( + new Point(`${metricName}:i`) + .intField('value', numVal) + .timestamp(timestamp) + ); + break; + case "UInt8": + case "UInt16": + case "UInt32": + case "UInt64": + // Validate + numVal = Number(value); + if (!Number.isInteger(numVal)) { + logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${numVal}. Not recording.`); + return; + } + writeApi.writePoint( + new Point(`${metricName}:u`) + .uintField('value', numVal) + .timestamp(timestamp) + ); + break; + case "Float": + case "Double": + // Validate + numVal = Number(value); + if (isNaN(parseFloat(numVal))) { + logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${numVal}. Not recording.`); + return; + } + writeApi.writePoint( + new Point(`${metricName}:d`) + .floatField('value', numVal) + .timestamp(timestamp) + ); + break; + case "Boolean": + if (typeof value != "boolean") { + logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${value}. Not recording.`); + return; + } + writeApi.writePoint( + new Point(`${metricName}:b`) + .booleanField('value', value) + .timestamp(timestamp)); + break; + default: + writeApi.writePoint( + new Point(`${metricName}:s`) + .stringField('value', value) + .timestamp(timestamp)); + break; + + } + + i++; + + logger.debug(`Added to write buffer (${i}/${batchSize}): [${birth.type}] ${topic.address}/${path}/${metricName} = ${value}`); + + if (i >= batchSize) { + this.flushBuffer(`${batchSize} point BATCH`); + } + } + + setNestedValue(obj, path, value) { + for (let k = 0; k < path.length - 1; k++) { + obj = obj[path[k]] = obj[path[k]] || {}; + } + obj[path[path.length - 1]] = value; + return obj; + } +} diff --git a/acs-uns-ingester/package-lock.json b/acs-uns-ingester/package-lock.json new file mode 100644 index 00000000..82e755f5 --- /dev/null +++ b/acs-uns-ingester/package-lock.json @@ -0,0 +1,3791 @@ +{ + "name": "influxdb-sparkplug-ingester", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "influxdb-sparkplug-ingester", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@amrc-factoryplus/utilities": "^1.0.8", + "@influxdata/influxdb-client": "^1.33.2", + "@influxdata/influxdb-client-apis": "^1.33.2", + "async": "^3.2.4", + "long": "^5.2.3", + "pino": "^8.11.0", + "pino-pretty": "^10.0.0" + }, + "devDependencies": { + "cross-env": "^7.0.3", + "dotenv": "^16.0.3", + "ts-node": "^10.9.1", + "tsc-alias": "^1.7.0" + } + }, + "node_modules/@amrc-factoryplus/utilities": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@amrc-factoryplus/utilities/-/utilities-1.0.8.tgz", + "integrity": "sha512-pSnakabCRTs7AlRtjYPNM47BQLsN2XR7xrNXuKmBDf+iytsCU1m0pCmQXuUM8/yvk80PxabMLm7dIlG405r5Bg==", + "dependencies": { + "@types/express": "4", + "@types/long": "^4.0.0", + "@types/node": ">=13.7.0", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "express": "^4.18.1", + "find-package-json": "^1.2.0", + "got-fetch": "^5.1.1", + "http-errors": "^2.0.0", + "mqtt": "^4.3.5", + "optional-js": "^2.3.0", + "path-to-regexp": "^6.2.1", + "pg": "^8.7.3", + "protobufjs": "^6.11.3", + "semver": "^7.5.1", + "sparkplug-payload": "^1.0.1", + "typescript": "^4.8.4" + }, + "optionalDependencies": { + "gssapi.js": "^2.0.1", + "pg-native": "^3.0.0" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/semver": { + "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" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@influxdata/influxdb-client": { + "version": "1.33.2", + "resolved": "https://registry.npmjs.org/@influxdata/influxdb-client/-/influxdb-client-1.33.2.tgz", + "integrity": "sha512-RT5SxH+grHAazo/YK3UTuWK/frPWRM0N7vkrCUyqVprDgQzlLP+bSK4ak2Jv3QVF/pazTnsxWjvtKZdwskV5Xw==" + }, + "node_modules/@influxdata/influxdb-client-apis": { + "version": "1.33.2", + "resolved": "https://registry.npmjs.org/@influxdata/influxdb-client-apis/-/influxdb-client-apis-1.33.2.tgz", + "integrity": "sha512-W6x9TOAQ3AUx0RBCrCibDhSvMqN50lxJmElc3rHn7+R/9Zi35oczu8r9YMkyNlzWnksu+dcyKr8/xLv28Ot4hw==", + "peerDependencies": { + "@influxdata/influxdb-client": "*" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "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": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "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_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/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "node_modules/@sindresorhus/is": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", + "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "peer": true, + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.33", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", + "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "peer": true + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, + "node_modules/@types/mime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" + }, + "node_modules/@types/node": { + "version": "18.15.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", + "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==" + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, + "node_modules/@types/serve-static": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", + "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", + "dependencies": { + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", + "integrity": "sha512-iFY7JCgHbepc0b82yLaw4IMortylNb6wG4kL+4R0C3iv6i+RHGHux/yUX5BTiRvSX/shMnngjR1YyNMnXEFh5A==", + "optional": true + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/are-we-there-yet": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.0.6.tgz", + "integrity": "sha512-Zfw6bteqM9gQXZ1BIWOgM8xEwMrUGoyL8nW13+O+OOgNX3YhuDN1GDgg1NzdTlmm3j+9sHy7uBZ12r+z9lXnZQ==", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.0 || ^1.1.13" + } + }, + "node_modules/are-we-there-yet/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "optional": true + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/are-we-there-yet/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "optional": true, + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "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/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", + "optional": true, + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bl/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "optional": true + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "optional": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g==", + "optional": true + }, + "node_modules/buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", + "optional": true, + "engines": { + "node": ">=0.2.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "peer": true, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.9", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.9.tgz", + "integrity": "sha512-CaAMr53AS1Tb9evO1BIWFnZjSr8A4pbXofpsNVWPMDZZj3ZQKHwsQG9BrTqQ4x5ZYJXz1T2b8LLtTZODxSpzbg==", + "peer": true, + "dependencies": { + "@types/http-cache-semantics": "^4.0.1", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.2", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", + "optional": true, + "dependencies": { + "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "optional": true + }, + "node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", + "optional": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/cmake-js": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/cmake-js/-/cmake-js-6.3.2.tgz", + "integrity": "sha512-7MfiQ/ijzeE2kO+WFB9bv4QP5Dn2yVaAP2acFJr4NIFy2hT4w6O4EpOTLNcohR5IPX7M4wNf/5taIqMj7UA9ug==", + "optional": true, + "dependencies": { + "axios": "^0.21.1", + "bluebird": "^3", + "debug": "^4", + "fs-extra": "^5.0.0", + "is-iojs": "^1.0.1", + "lodash": "^4", + "memory-stream": "0", + "npmlog": "^1.2.0", + "rc": "^1.2.7", + "semver": "^5.0.3", + "splitargs": "0", + "tar": "^4", + "unzipper": "^0.8.13", + "url-join": "0", + "which": "^1.0.9", + "yargs": "^3.6.0" + }, + "bin": { + "cmake-js": "bin/cmake-js" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/cmake-js/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "optional": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/cmake-js/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==", + "optional": true + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" + }, + "node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/commist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", + "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", + "dependencies": { + "leven": "^2.1.0", + "minimist": "^1.1.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "optional": true + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "peer": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "optional": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "optional": true + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/duplexify/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/duplexify/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fast-copy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.1.tgz", + "integrity": "sha512-Knr7NOtK3HWRYGtHoJrjkaWepqT8thIVGAwt0p0aUs1zqkAzXZV4vo9fFNwyb5fcqK1GKYFYxldQdIDVKhUAfA==" + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-redact": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.1.2.tgz", + "integrity": "sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-package-json": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/find-package-json/-/find-package-json-1.2.0.tgz", + "integrity": "sha512-+SOGcLGYDJHtyqHd87ysBhmaeQ95oWspDKnMXBrnQ9Eq4OkLNqejgoaD8xVWu6GPa0B6roa6KinCMEMcVeqONw==" + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "optional": true, + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "peer": true, + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", + "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "optional": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "optional": true, + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "optional": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/gauge": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", + "integrity": "sha512-fVbU2wRE91yDvKUnrIaQlHKAWKY5e08PmztCrwuH5YVQ+Z/p3d0ny2T48o6uvAAXHIUnfaQdHkmxYbQft1eHVA==", + "optional": true, + "dependencies": { + "ansi": "^0.3.0", + "has-unicode": "^2.0.0", + "lodash.pad": "^4.1.0", + "lodash.padend": "^4.1.0", + "lodash.padstart": "^4.1.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.0.tgz", + "integrity": "sha512-WTcaQ963xV97MN3x0/CbAriXFZcXCfgxVp91I+Ze6pawQOa7SgzwSx2zIJJsX+kTajMnVs0xcFD1TxZKFqhdnQ==", + "peer": true, + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got-fetch": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/got-fetch/-/got-fetch-5.1.4.tgz", + "integrity": "sha512-Pdv+SSgtTCDZbNuGkOf0c0FZy5Syqf225JEgG/vKt13HAe8r2vNJ11DxKKODsmr7L7/6ff3lf+AxpBtD5k/dRQ==", + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "got": "^12.0.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "optional": true + }, + "node_modules/gssapi.js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gssapi.js/-/gssapi.js-2.0.1.tgz", + "integrity": "sha512-5D+qylV8uIKMaxTTKhpzvfGRz5+okr/rpwC6YlaCoDVBpvkuNgL8pM7+r7aTzZ2oT5dA4w2WoZTV82opGj+RZQ==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "bindings": "^1.5.0", + "cmake-js": "^6.1.0", + "node-addon-api": "^1.7.2" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "optional": true + }, + "node_modules/help-me": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", + "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", + "dependencies": { + "glob": "^7.1.6", + "readable-stream": "^3.6.0" + } + }, + "node_modules/help-me/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/help-me/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "peer": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http2-wrapper": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz", + "integrity": "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==", + "peer": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "optional": true + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-iojs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-iojs/-/is-iojs-1.1.0.tgz", + "integrity": "sha512-tLn1j3wYSL6DkvEI+V/j0pKohpa5jk+ER74v6S4SgCXnjS0WA+DoZbwZBrrhgwksMvtuwndyGeG5F8YMsoBzSA==", + "optional": true + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "optional": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "devOptional": true + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "peer": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optional": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", + "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", + "peer": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", + "optional": true, + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/libpq": { + "version": "1.8.12", + "resolved": "https://registry.npmjs.org/libpq/-/libpq-1.8.12.tgz", + "integrity": "sha512-4lUY9BD9suz76mVS0kH4rRgRy620g/c9YZH5GYC3smfIpjtj6KiPuQ4IwQSHSZMMMhMM3tBFrYUrw8mHOOZVeg==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "bindings": "1.5.0", + "nan": "^2.14.0" + } + }, + "node_modules/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==", + "optional": true + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "optional": true + }, + "node_modules/lodash.pad": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", + "integrity": "sha512-mvUHifnLqM+03YNzeTBS1/Gr6JRFjd3rRx88FHWUvamVaT9k2O/kXha3yBSOwB9/DTQrSTLJNHvLBBt2FdX7Mg==", + "optional": true + }, + "node_modules/lodash.padend": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "integrity": "sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw==", + "optional": true + }, + "node_modules/lodash.padstart": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", + "integrity": "sha512-sW73O6S8+Tg66eY56DBk85aQzzUJDtpoXFBgELMd5P/SotAguo+1kYO6RuYgXxA4HJH3LFTFPASX6ET6bjfriw==", + "optional": true + }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memory-stream": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/memory-stream/-/memory-stream-0.0.3.tgz", + "integrity": "sha512-q0D3m846qY6ZkIt+19ZemU5vH56lpOZZwoJc3AICARKh/menBuayQUjAGPrqtHQQMUYERSdOrej92J9kz7LgYA==", + "optional": true, + "dependencies": { + "readable-stream": "~1.0.26-2" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "optional": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/minipass/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "optional": true + }, + "node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "optional": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "optional": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mqtt": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.7.tgz", + "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==", + "dependencies": { + "commist": "^1.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.1.1", + "duplexify": "^4.1.1", + "help-me": "^3.0.0", + "inherits": "^2.0.3", + "lru-cache": "^6.0.0", + "minimist": "^1.2.5", + "mqtt-packet": "^6.8.0", + "number-allocator": "^1.0.9", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^3.1.0", + "ws": "^7.5.5", + "xtend": "^4.0.2" + }, + "bin": { + "mqtt": "bin/mqtt.js", + "mqtt_pub": "bin/pub.js", + "mqtt_sub": "bin/sub.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mqtt-packet": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", + "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "dependencies": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + }, + "node_modules/mqtt-packet/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mqtt-packet/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==" + }, + "node_modules/mqtt/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mqtt/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==" + }, + "node_modules/mqtt/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/mqtt/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/mylas": { + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/mylas/-/mylas-2.1.13.tgz", + "integrity": "sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/raouldeheer" + } + }, + "node_modules/nan": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", + "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", + "optional": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "optional": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", + "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npmlog": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-1.2.1.tgz", + "integrity": "sha512-1J5KqSRvESP6XbjPaXt2H6qDzgizLTM7x0y1cXIjP2PpvdCqyNC7TO3cPRKsuYlElbi/DwkzRRdG2zpmE0IktQ==", + "optional": true, + "dependencies": { + "ansi": "~0.3.0", + "are-we-there-yet": "~1.0.0", + "gauge": "~1.2.0" + } + }, + "node_modules/number-allocator": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz", + "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==", + "dependencies": { + "debug": "^4.3.1", + "js-sdsl": "4.3.0" + } + }, + "node_modules/number-allocator/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/number-allocator/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==" + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", + "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optional-js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/optional-js/-/optional-js-2.3.0.tgz", + "integrity": "sha512-B0LLi+Vg+eko++0z/b8zIv57kp7HKEzaPJo7LowJXMUKYdf+3XJGu/cw03h/JhIOsLnP+cG5QnTHAuicjA5fMw==" + }, + "node_modules/os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", + "optional": true, + "dependencies": { + "lcid": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "peer": true, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pg": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.10.0.tgz", + "integrity": "sha512-ke7o7qSTMb47iwzOSaZMfeR7xToFdkE71ifIipOAAaLIM0DYzfOAXlgFFmYUIE2BcJtvnVlGCID84ZzCegE8CQ==", + "dependencies": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.5.0", + "pg-pool": "^3.6.0", + "pg-protocol": "^1.6.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-native": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pg-native/-/pg-native-3.0.1.tgz", + "integrity": "sha512-LBVNWkNh0fVx/cienARRP2y22J5OpUsKBe0TpxzAx3arEUUdIs77aLSAHS3scS7SMaqc+OkG40CEu5fN0/cjIw==", + "optional": true, + "dependencies": { + "libpq": "^1.8.10", + "pg-types": "^1.12.1", + "readable-stream": "1.0.31" + } + }, + "node_modules/pg-native/node_modules/pg-types": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-1.13.0.tgz", + "integrity": "sha512-lfKli0Gkl/+za/+b6lzENajczwZHc7D5kiUCZfgm914jipD2kIOIvEkAhZ8GrW3/TUoP9w8FHjwpPObBye5KQQ==", + "optional": true, + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~1.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.0", + "postgres-interval": "^1.1.0" + } + }, + "node_modules/pg-native/node_modules/postgres-array": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.3.tgz", + "integrity": "sha512-5wClXrAP0+78mcsNX3/ithQ5exKvCyK5lr5NEEEeGwwM6NJdQgzIJBVxLvRW+huFpX92F2QnZ5CcokH0VhK2qQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pg-native/node_modules/readable-stream": { + "version": "1.0.31", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.31.tgz", + "integrity": "sha512-tco/Dwv1f/sgIgN6CWdj/restacPKNskK6yps1981ivH2ZmLYcs5o5rVzL3qaO/cSkhN8hYOMWs7+glzOLSgRg==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/pg-pool": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.0.tgz", + "integrity": "sha512-clFRf2ksqd+F497kWFyM21tMjeikn60oGDmqMT8UBrynEwVEX/5R5xd2sdvdo1cZCFlguORNpVuqxIj+aK4cfQ==", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", + "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/pgpass/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pino": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.11.0.tgz", + "integrity": "sha512-Z2eKSvlrl2rH8p5eveNUnTdd4AjJk8tAsLkHYZQKGHP4WTh2Gi1cOSOs3eWPqaj+niS3gj4UkoreoaWgF3ZWYg==", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "v1.0.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.1.0", + "thread-stream": "^2.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz", + "integrity": "sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==", + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/pino-abstract-transport/node_modules/readable-stream": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz", + "integrity": "sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/pino-pretty": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.0.0.tgz", + "integrity": "sha512-zKFjYXBzLaLTEAN1ayKpHXtL5UeRQC7R3lvhKe7fWs7hIVEjKGG/qIXwQt9HmeUp71ogUd/YcW+LmMwRp4KT6Q==", + "dependencies": { + "colorette": "^2.0.7", + "dateformat": "^4.6.3", + "fast-copy": "^3.0.0", + "fast-safe-stringify": "^2.1.1", + "help-me": "^4.0.1", + "joycon": "^3.1.1", + "minimist": "^1.2.6", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.0.0", + "pump": "^3.0.0", + "readable-stream": "^4.0.0", + "secure-json-parse": "^2.4.0", + "sonic-boom": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "pino-pretty": "bin.js" + } + }, + "node_modules/pino-pretty/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/pino-pretty/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/pino-pretty/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/pino-pretty/node_modules/help-me": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-4.2.0.tgz", + "integrity": "sha512-TAOnTB8Tz5Dw8penUuzHVrKNKlCIbwwbHnXraNJxPwf8LRtE2HlM84RYuezMFcwOJmoYOCWVDyJ8TQGxn9PgxA==", + "dependencies": { + "glob": "^8.0.0", + "readable-stream": "^3.6.0" + } + }, + "node_modules/pino-pretty/node_modules/help-me/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pino-pretty/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pino-pretty/node_modules/readable-stream": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz", + "integrity": "sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-pretty/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/pino-pretty/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pino-std-serializers": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.0.tgz", + "integrity": "sha512-IWgSzUL8X1w4BIWTwErRgtV8PyOGOOi60uqv0oKuS/fOA8Nco/OeI6lBuc4dyP8MMfdFwyHqTMcBIA7nDiqEqA==" + }, + "node_modules/plimit-lit": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/plimit-lit/-/plimit-lit-1.5.0.tgz", + "integrity": "sha512-Eb/MqCb1Iv/ok4m1FqIXqvUKPISufcjZ605hl3KM/n8GaX8zfhtgdLwZU3vKjuHGh2O9Rjog/bHTq8ofIShdng==", + "dev": true, + "dependencies": { + "queue-lit": "^1.5.0" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/process-warning": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", + "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==" + }, + "node_modules/protobufjs": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/protobufjs/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-lit": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-1.5.0.tgz", + "integrity": "sha512-IslToJ4eiCEE9xwMzq3viOO5nH8sUWUCwoElrhNMozzr9IIt2qqvB4I+uHu/zJTQVqc9R5DFwok4ijNK1pU3fA==", + "dev": true + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "optional": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "peer": true + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "peer": true, + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "optional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "optional": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sonic-boom": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz", + "integrity": "sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/sparkplug-payload": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkplug-payload/-/sparkplug-payload-1.0.1.tgz", + "integrity": "sha512-N4i++SFY7ECH7NB2bi1zmL9uPRKXF5cXQRxudUqZi9sribVZB7TZWvMIcTTakqqs1WkryYgpuV34CwEYm7I0Cg==", + "dependencies": { + "protobufjs": "^6.8.0" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/split2/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/split2/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/splitargs": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/splitargs/-/splitargs-0.0.7.tgz", + "integrity": "sha512-UUFYD2oWbNwULH6WoVtLUOw8ch586B+HUqcsAjjjeoBQAM1bD4wZRXu01koaxyd8UeYpybWqW4h+lO1Okv40Tg==", + "optional": true + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "optional": true + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "optional": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "optional": true, + "dependencies": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "optional": true + }, + "node_modules/thread-stream": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.3.0.tgz", + "integrity": "sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==", + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tsc-alias": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/tsc-alias/-/tsc-alias-1.8.5.tgz", + "integrity": "sha512-Y3ka0olwSRdbHPyX5kXhYY2aoBKuT53DFdeY+PpQUR4hg5M/b8eIRmC8dL4FBdd0wT366iWc6iDUUGe6QwI7mg==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.3", + "commander": "^9.0.0", + "globby": "^11.0.4", + "mylas": "^2.1.9", + "normalize-path": "^3.0.0", + "plimit-lit": "^1.2.6" + }, + "bin": { + "tsc-alias": "dist/bin/index.js" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "optional": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unzipper": { + "version": "0.8.14", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.8.14.tgz", + "integrity": "sha512-8rFtE7EP5ssOwGpN2dt1Q4njl0N1hUXJ7sSPz0leU2hRdq6+pra57z4YPBlVqm40vcgv6ooKZEAx48fMTv9x4w==", + "optional": true, + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "~1.0.10", + "listenercount": "~1.0.1", + "readable-stream": "~2.1.5", + "setimmediate": "~1.0.4" + } + }, + "node_modules/unzipper/node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==", + "optional": true + }, + "node_modules/unzipper/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "optional": true + }, + "node_modules/unzipper/node_modules/process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==", + "optional": true + }, + "node_modules/unzipper/node_modules/readable-stream": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", + "integrity": "sha512-NkXT2AER7VKXeXtJNSaWLpWIhmtSE3K2PguaLEeWr4JILghcIKqoLt1A3wHrnpDC5+ekf8gfk1GKWkFXe4odMw==", + "optional": true, + "dependencies": { + "buffer-shims": "^1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/url-join": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz", + "integrity": "sha512-H6dnQ/yPAAVzMQRvEvyz01hhfQL5qRWSEt7BX8t9DqnPw9BjMb64fjIRq76Uvf1hkHp+mTZvEVJ5guXOT0Xqaw==", + "optional": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "optional": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/window-size": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "integrity": "sha512-2thx4pB0cV3h+Bw7QmMXcEbdmOzv9t0HFplJH/Lz6yu60hXYy5RT8rUu+wlIreVxWsGN20mo+MHeCSfUpQBwPw==", + "optional": true, + "bin": { + "window-size": "cli.js" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", + "optional": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", + "optional": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yargs": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "integrity": "sha512-ONJZiimStfZzhKamYvR/xvmgW3uEkAUFSP91y2caTEPhzF6uP2JfPiVZcq66b/YR0C3uitxSV7+T1x8p5bkmMg==", + "optional": true, + "dependencies": { + "camelcase": "^2.0.1", + "cliui": "^3.0.3", + "decamelize": "^1.1.1", + "os-locale": "^1.4.0", + "string-width": "^1.0.1", + "window-size": "^0.1.4", + "y18n": "^3.2.0" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + } +} diff --git a/acs-uns-ingester/package.json b/acs-uns-ingester/package.json new file mode 100644 index 00000000..70c93948 --- /dev/null +++ b/acs-uns-ingester/package.json @@ -0,0 +1,41 @@ +{ + "name": "influxdb-sparkplug-ingester", + "version": "1.0.0", + "description": "An ingestion engine to enable InfluxDB to be a fully-featured Sparkplug historian", + "author": "AMRC", + "license": "MIT", + "keywords": [ + "amrc", + "factory-plus", + "factoryplus", + "acs", + "amrc-connectivity-stack", + "mqtt", + "sparkplug" + ], + "type": "module", + "scripts": { + "start": "node --trace-warnings dist/bin/ingester.js", + "start:shell": "k5start -Uf $CLIENT_KEYTAB npm run start", + "dev": " npm run build && npm run start:dev", + "build": "tsc && tsc-alias", + "clean": "tsc --build --clean", + "lint": "eslint --ignore-path .gitignore --ext .ts src/", + "lint:fix": "npm run lint -- --fix" + }, + "dependencies": { + "@amrc-factoryplus/utilities": "^1.0.8", + "@influxdata/influxdb-client": "^1.33.2", + "@influxdata/influxdb-client-apis": "^1.33.2", + "async": "^3.2.4", + "long": "^5.2.3", + "pino": "^8.11.0", + "pino-pretty": "^10.0.0" + }, + "devDependencies": { + "cross-env": "^7.0.3", + "dotenv": "^16.0.3", + "ts-node": "^10.9.1", + "tsc-alias": "^1.7.0" + } +} diff --git a/acs-uns-ingester/run-dev.sh b/acs-uns-ingester/run-dev.sh new file mode 100644 index 00000000..cbd64e40 --- /dev/null +++ b/acs-uns-ingester/run-dev.sh @@ -0,0 +1,10 @@ +# +# AMRC InfluxDB Sparkplug Ingester +# Copyright "2023" AMRC +# + +# bin/bash +tmpfile=$(mktemp) +export CLIENT_KEYTAB="$(kubectl --kubeconfig ~/.kube/fplus get -n factory-plus secret krb5-keytabs -o jsonpath="{.data.sv1warehouse}" | base64 -d >"$tmpfile" && echo "$tmpfile")" +echo $CLIENT_KEYTAB +npm run start:shell diff --git a/acs-uns-ingester/tsconfig.json b/acs-uns-ingester/tsconfig.json new file mode 100644 index 00000000..a3a2f0a7 --- /dev/null +++ b/acs-uns-ingester/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "target": "es2017", + "lib": ["es2017", "esnext.asynciterable", "dom"], + "typeRoots": ["node_modules/@types"], + "allowSyntheticDefaultImports": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node", + "module": "es2022", + "pretty": true, + "sourceMap": true, + "declaration": true, + "outDir": "dist", + "allowJs": true, + "noEmit": false, + "esModuleInterop": true, + "resolveJsonModule": true, + "importHelpers": true, + "skipLibCheck": true, + "baseUrl": "src", + "paths": { + "@/*": ["*"], + "@bin/*": ["../bin/*"], + "@lib/*": ["../lib/*"] + } + }, + "include": ["bin/**/*.ts", "lib/**/*.json", ".env"], + "exclude": ["node_modules"] +} diff --git a/influxdb-sparkplug-ingester/.gitignore b/influxdb-sparkplug-ingester/.gitignore index eed26523..de52c1cc 100644 --- a/influxdb-sparkplug-ingester/.gitignore +++ b/influxdb-sparkplug-ingester/.gitignore @@ -15,3 +15,5 @@ dist/ # IDE .idea/ + +*keytab* \ No newline at end of file From 66b47a1b4c6b3dfbdc4eeb586fbf9dad279d3a06 Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Tue, 2 Jul 2024 15:13:17 +0100 Subject: [PATCH 05/58] Add metric republishing to local mqtt namespace --- acs-uns-ingester/bin/ingester.ts | 10 +- acs-uns-ingester/example.env | 10 + acs-uns-ingester/lib/mqttclient.ts | 111 +++--- acs-uns-ingester/package-lock.json | 527 +++++++++++++++++++---------- acs-uns-ingester/package.json | 3 +- 5 files changed, 427 insertions(+), 234 deletions(-) create mode 100644 acs-uns-ingester/example.env diff --git a/acs-uns-ingester/bin/ingester.ts b/acs-uns-ingester/bin/ingester.ts index 136b2ac6..36edad14 100644 --- a/acs-uns-ingester/bin/ingester.ts +++ b/acs-uns-ingester/bin/ingester.ts @@ -7,8 +7,12 @@ import {ServiceClient, UUIDs} from "@amrc-factoryplus/utilities"; import pino from "pino"; import pretty from 'pino-pretty'; import MQTTClient from "@lib/mqttclient.js"; + let dotenv: any = null; -try {dotenv = await import ('dotenv')} catch (e) {} +try { + dotenv = await import ('dotenv') +} catch (e) { +} const stream = pretty({ colorize: true @@ -22,7 +26,7 @@ if (!directoryUrl) { } export const logger = pino({ - name: 'InfluxDB Sparkplug Ingester', + name: 'ACS UNS Ingester', level: process.env.LOG_LEVEL || 'info', }, stream); @@ -47,6 +51,6 @@ const mqtt = await new MQTTClient({ e: { serviceClient: client, } -}).init(); +}); mqtt.run(); diff --git a/acs-uns-ingester/example.env b/acs-uns-ingester/example.env new file mode 100644 index 00000000..bef798de --- /dev/null +++ b/acs-uns-ingester/example.env @@ -0,0 +1,10 @@ +DIRECTORY_URL=https://directory.domain.co.uk +INFLUX_URL=http://influx.domain.co.uk +INFLUX_TOKEN=XXXXXX +MQTT_URL=mqtt://mqtt.domain.co.uk +INFLUX_ORG=default +INFLUX_BUCKET=default +LOG_LEVEL=info +BATCH_SIZE=5000 +FLUSH_INTERVAL=10000 +CMD_ESC_URL=https://cmdesc.domain.co.uk \ No newline at end of file diff --git a/acs-uns-ingester/lib/mqttclient.ts b/acs-uns-ingester/lib/mqttclient.ts index 854811c1..f1ecb4fb 100644 --- a/acs-uns-ingester/lib/mqttclient.ts +++ b/acs-uns-ingester/lib/mqttclient.ts @@ -10,6 +10,8 @@ import Long from "long"; import {InfluxDB, Point} from '@influxdata/influxdb-client' import {Agent} from 'http' +import * as mqtt_dev from "mqtt"; + let dotenv: any = null; try { dotenv = await import ('dotenv') @@ -43,6 +45,12 @@ if (!flushInterval) { throw new Error("FLUSH_INTERVAL environment variable is not set"); } +const unsMqttUrl: string = process.env.UNS_MQTT_URL; +if (!unsMqttUrl) { + throw new Error("UNS_MQTT_URL environment variable is not set"); +} + +/* let i = 0; // Node.js HTTP client OOTB does not reuse established TCP connections, a custom node HTTP agent @@ -62,19 +70,20 @@ let interval: any; /* points/lines are batched in order to minimize networking and increase performance */ +/* const writeApi = influxDB.getWriteApi(influxOrganisation, process.env.INFLUX_BUCKET || 'default', 'ns', { - /* the maximum points/lines to send in a single batch to InfluxDB server */ + // the maximum points/lines to send in a single batch to InfluxDB server batchSize: batchSize + 1, // don't let automatically flush data - /* maximum time in millis to keep points in an unflushed batch, 0 means don't periodically flush */ + // maximum time in millis to keep points in an unflushed batch, 0 means don't periodically flush flushInterval: 0, // Never allow the package to flush: we'll flush manually - /* maximum size of the retry buffer - it contains items that could not be sent for the first time */ - maxBufferLines: 30_000, /* the count of internally-scheduled retries upon write failure, the delays between write attempts follow an exponential backoff strategy if there is no Retry-After HTTP header */ + // maximum size of the retry buffer - it contains items that could not be sent for the first time + maxBufferLines: 30_000, // the count of internally-scheduled retries upon write failure, the delays between write attempts follow an exponential backoff strategy if there is no Retry-After HTTP header maxRetries: 0, // do not retry writes // ... there are more write options that can be customized, see // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeoptions.html and // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeretryoptions.html }); - +*/ interface MQTTClientConstructorParams { e: { serviceClient: ServiceClient; @@ -86,33 +95,21 @@ export default class MQTTClient { private mqtt: any; private aliasResolver = {}; private birthDebounce = {}; + private local_mqtt: any; constructor({e}: MQTTClientConstructorParams) { this.serviceClient = e.serviceClient; } - async init() { - - process.on('exit', () => { - this.flushBuffer('EXIT'); - keepAliveAgent.destroy(); - }) - - return this; - } - - private flushBuffer(source: string) { - let bufferSize = i; - i = 0; - writeApi.flush().then(() => { - logger.info(`🚀 Flushed ${bufferSize} points to InfluxDB [${source}]`); - // Reset the interval - this.resetInterval(); - }) - } - async run() { + this.local_mqtt = mqtt_dev.connect(unsMqttUrl); + this.local_mqtt.on("connect", () => { + logger.info("😁 Connected to local mqtt broker!"); + }); + this.local_mqtt.on("error", (error) => { + logger.error(`🔥 Error from broker: ${error}`); + }) const mqtt = await this.serviceClient.mqtt_client(); this.mqtt = mqtt; @@ -129,21 +126,10 @@ export default class MQTTClient { logger.info("🔌 Connected to Factory+ broker"); logger.info("👂 Subscribing to entire Factory+ namespace"); this.mqtt.subscribe('spBv1.0/#'); - this.resetInterval(); - } - - private resetInterval() { - clearInterval(interval); - interval = setInterval(() => { - this.flushBuffer(`${flushInterval}ms INTERVAL`); - }, flushInterval); } on_close() { logger.warn(`❌ Disconnected from Factory+ broker`); - - // Flush any remaining data - this.flushBuffer('CONN_CLOSE'); } on_reconnect() { @@ -152,8 +138,6 @@ export default class MQTTClient { on_error(error: any) { logger.error("🚨 MQTT error: %o", error); - // Flush any remaining data - this.flushBuffer('MQTT_ERROR'); } async on_message(topicString: string, message: Uint8Array | Reader) { @@ -323,7 +307,7 @@ export default class MQTTClient { delete this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]; // Store the default values in InfluxDB - this.writeMetrics(payload, topic); + this.publishToUNS(payload, topic); break; case "DEATH": @@ -349,7 +333,8 @@ export default class MQTTClient { if (this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { // Device is known, resolve aliases and write to InfluxDB - this.writeMetrics(payload, topic); + //this.writeMetrics(payload, topic); + this.publishToUNS(payload, topic) } else { @@ -389,6 +374,46 @@ export default class MQTTClient { return; } + /** + * Publishes received values from the Sparkplug namespace to the UNS with a topic structured to values schema path + * @param payload Received payload. + * @param topic Topic the payload was received on. + */ + private publishToUNS(payload, topic) { + payload.metrics.forEach((metric) => { + if (metric.value === null) return; + let birth = this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]?.[metric.alias]; + + if (!birth) { + return; + } + + if (birth.transient) { + logger.debug(`Metric ${birth.name} is transient, not writing to InfluxDB`); + return; + } + + const metricName = birth.name.split('/').pop() as string; + const path = birth.name.substring(0, birth.name.lastIndexOf("/")) as string; + + if ( + metricName === "Schema_UUID" || + metricName === "Instance_UUID" || + path.includes("Device Control") || + path.includes("Device Information") + ) { + return; + } + + if (path) { + this.local_mqtt.publish(`AMRC/Sheffield/F2050/${topic.address.device}/${path}/${metricName}`, `${metric.value}`); + } else { + this.local_mqtt.publish(`AMRC/Sheffield/F2050/${topic.address.device}/${metricName}`, `${metric.value}`); + } + }); + } + + /* private writeMetrics(payload, topic: Topic) { payload.metrics.forEach((metric) => { let birth = this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]?.[metric.alias]; @@ -411,7 +436,7 @@ export default class MQTTClient { this.writeToInfluxDB(birth, topic, metric.value, metricTimestamp) }); } - + */ /** * Writes metric values to InfluxDB using the metric timestamp. * @param birth Birth certificate for device. @@ -419,6 +444,8 @@ export default class MQTTClient { * @param value Metric value to write to InfluxDB. * @param timestamp Timestamp from the metric to write to influx. */ + + /* writeToInfluxDB(birth, topic: Topic, value, timestamp: Date) { if (value === null) return; if (birth.transient) { @@ -521,7 +548,7 @@ export default class MQTTClient { if (i >= batchSize) { this.flushBuffer(`${batchSize} point BATCH`); } - } + }*/ setNestedValue(obj, path, value) { for (let k = 0; k < path.length - 1; k++) { diff --git a/acs-uns-ingester/package-lock.json b/acs-uns-ingester/package-lock.json index 82e755f5..778ab7a3 100644 --- a/acs-uns-ingester/package-lock.json +++ b/acs-uns-ingester/package-lock.json @@ -1,11 +1,11 @@ { - "name": "influxdb-sparkplug-ingester", + "name": "acs-uns-ingester", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "influxdb-sparkplug-ingester", + "name": "acs-uns-ingester", "version": "1.0.0", "license": "MIT", "dependencies": { @@ -14,6 +14,7 @@ "@influxdata/influxdb-client-apis": "^1.33.2", "async": "^3.2.4", "long": "^5.2.3", + "mqtt": "^5.7.3", "pino": "^8.11.0", "pino-pretty": "^10.0.0" }, @@ -52,11 +53,138 @@ "pg-native": "^3.0.0" } }, + "node_modules/@amrc-factoryplus/utilities/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/commist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", + "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", + "dependencies": { + "leven": "^2.1.0", + "minimist": "^1.1.0" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/help-me": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", + "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", + "dependencies": { + "glob": "^7.1.6", + "readable-stream": "^3.6.0" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/mqtt": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.8.tgz", + "integrity": "sha512-2xT75uYa0kiPEF/PE0VPdavmEkoBzMT/UL9moid0rAvlCtV48qBwxD62m7Ld/4j8tSkIO1E/iqRl/S72SEOhOw==", + "dependencies": { + "commist": "^1.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.1.1", + "duplexify": "^4.1.1", + "help-me": "^3.0.0", + "inherits": "^2.0.3", + "lru-cache": "^6.0.0", + "minimist": "^1.2.5", + "mqtt-packet": "^6.8.0", + "number-allocator": "^1.0.9", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^3.1.0", + "ws": "^7.5.5", + "xtend": "^4.0.2" + }, + "bin": { + "mqtt": "bin/mqtt.js", + "mqtt_pub": "bin/pub.js", + "mqtt_sub": "bin/sub.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/mqtt-packet": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", + "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "dependencies": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + }, + "node_modules/@amrc-factoryplus/utilities/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==" + }, "node_modules/@amrc-factoryplus/utilities/node_modules/path-to-regexp": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" }, + "node_modules/@amrc-factoryplus/utilities/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/@amrc-factoryplus/utilities/node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -71,6 +199,53 @@ "node": ">=10" } }, + "node_modules/@amrc-factoryplus/utilities/node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -327,6 +502,20 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, + "node_modules/@types/readable-stream": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.14.tgz", + "integrity": "sha512-xZn/AuUbCMShGsqH/ehZtGDwQtbx00M9rZ2ENLe4tOjFZ/JFeWMhEZkk2fEe1jAUqqEAURIkFJ7Az/go8mM1/w==", + "dependencies": { + "@types/node": "*", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/@types/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "node_modules/@types/serve-static": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", @@ -336,6 +525,14 @@ "@types/node": "*" } }, + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -561,26 +758,29 @@ } }, "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/bl/-/bl-6.0.13.tgz", + "integrity": "sha512-tMncAcpsyjZgAVbVFupVIaB2xud13xxT59fdHkuszY2jdZkqIWfpQdmII1fOe3kOGAz0mNLTIHEm+KxpYsQKKg==", "dependencies": { - "buffer": "^5.5.0", + "@types/readable-stream": "^4.0.0", + "buffer": "^6.0.3", "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "readable-stream": "^4.2.0" } }, "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { - "node": ">= 6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/bl/node_modules/string_decoder": { @@ -642,9 +842,9 @@ } }, "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { "type": "github", @@ -661,7 +861,7 @@ ], "dependencies": { "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "ieee754": "^1.2.1" } }, "node_modules/buffer-from": { @@ -890,13 +1090,9 @@ } }, "node_modules/commist": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", - "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", - "dependencies": { - "leven": "^2.1.0", - "minimist": "^1.1.0" - } + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz", + "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==" }, "node_modules/concat-map": { "version": "0.0.1", @@ -1210,14 +1406,14 @@ } }, "node_modules/duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", "dependencies": { "end-of-stream": "^1.4.1", "inherits": "^2.0.3", "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" + "stream-shift": "^1.0.2" } }, "node_modules/duplexify/node_modules/readable-stream": { @@ -1366,6 +1562,18 @@ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, + "node_modules/fast-unique-numbers": { + "version": "8.0.13", + "resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-8.0.13.tgz", + "integrity": "sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g==", + "dependencies": { + "@babel/runtime": "^7.23.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.1.0" + } + }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -1691,34 +1899,9 @@ "optional": true }, "node_modules/help-me": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", - "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", - "dependencies": { - "glob": "^7.1.6", - "readable-stream": "^3.6.0" - } - }, - "node_modules/help-me/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/help-me/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==" }, "node_modules/http-cache-semantics": { "version": "4.1.1", @@ -2189,51 +2372,51 @@ } }, "node_modules/mqtt": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.7.tgz", - "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.7.3.tgz", + "integrity": "sha512-v+5la6Q6zjl0AWsI7ICDA/K3hclkNj7CMa0khMugCC+LKPLrQF+sSQb/9ckezZLMvcBC1tXhRzqmcagQoDl9fQ==", "dependencies": { - "commist": "^1.0.0", + "@types/readable-stream": "^4.0.5", + "@types/ws": "^8.5.9", + "commist": "^3.2.0", "concat-stream": "^2.0.0", - "debug": "^4.1.1", - "duplexify": "^4.1.1", - "help-me": "^3.0.0", - "inherits": "^2.0.3", - "lru-cache": "^6.0.0", - "minimist": "^1.2.5", - "mqtt-packet": "^6.8.0", - "number-allocator": "^1.0.9", - "pump": "^3.0.0", - "readable-stream": "^3.6.0", + "debug": "^4.3.4", + "help-me": "^5.0.0", + "lru-cache": "^10.0.1", + "minimist": "^1.2.8", + "mqtt": "^5.2.0", + "mqtt-packet": "^9.0.0", + "number-allocator": "^1.0.14", + "readable-stream": "^4.4.2", "reinterval": "^1.1.0", "rfdc": "^1.3.0", - "split2": "^3.1.0", - "ws": "^7.5.5", - "xtend": "^4.0.2" + "split2": "^4.2.0", + "worker-timers": "^7.1.4", + "ws": "^8.17.1" }, "bin": { - "mqtt": "bin/mqtt.js", - "mqtt_pub": "bin/pub.js", - "mqtt_sub": "bin/sub.js" + "mqtt": "build/bin/mqtt.js", + "mqtt_pub": "build/bin/pub.js", + "mqtt_sub": "build/bin/sub.js" }, "engines": { - "node": ">=10.0.0" + "node": ">=16.0.0" } }, "node_modules/mqtt-packet": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", - "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-9.0.0.tgz", + "integrity": "sha512-8v+HkX+fwbodsWAZIZTI074XIoxVBOmPeggQuDFCGg1SqNcC+uoRMWu7J6QlJPqIUIJXmjNYYHxBBLr1Y/Df4w==", "dependencies": { - "bl": "^4.0.2", - "debug": "^4.1.1", + "bl": "^6.0.8", + "debug": "^4.3.4", "process-nextick-args": "^2.0.1" } }, "node_modules/mqtt-packet/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dependencies": { "ms": "2.1.2" }, @@ -2267,22 +2450,32 @@ } } }, + "node_modules/mqtt/node_modules/lru-cache": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", + "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==", + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/mqtt/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==" }, "node_modules/mqtt/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { - "node": ">= 6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/mqtt/node_modules/string_decoder": { @@ -2631,14 +2824,6 @@ "split2": "^4.1.0" } }, - "node_modules/pgpass/node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "engines": { - "node": ">= 10.x" - } - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -2681,29 +2866,6 @@ "split2": "^4.0.0" } }, - "node_modules/pino-abstract-transport/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/pino-abstract-transport/node_modules/readable-stream": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz", @@ -2718,14 +2880,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/pino-abstract-transport/node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "engines": { - "node": ">= 10.x" - } - }, "node_modules/pino-pretty": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.0.0.tgz", @@ -2758,29 +2912,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/pino-pretty/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/pino-pretty/node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -3109,6 +3240,11 @@ "node": ">= 12.13.0" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, "node_modules/reinterval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", @@ -3344,32 +3480,11 @@ } }, "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", - "dependencies": { - "readable-stream": "^3.0.0" - } - }, - "node_modules/split2/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "engines": { - "node": ">= 6" - } - }, - "node_modules/split2/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" + "node": ">= 10.x" } }, "node_modules/splitargs": { @@ -3387,9 +3502,9 @@ } }, "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==" }, "node_modules/string_decoder": { "version": "0.10.31", @@ -3553,6 +3668,11 @@ "tsc-alias": "dist/bin/index.js" } }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -3706,6 +3826,37 @@ "node": ">= 0.10.0" } }, + "node_modules/worker-timers": { + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-7.1.8.tgz", + "integrity": "sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw==", + "dependencies": { + "@babel/runtime": "^7.24.5", + "tslib": "^2.6.2", + "worker-timers-broker": "^6.1.8", + "worker-timers-worker": "^7.0.71" + } + }, + "node_modules/worker-timers-broker": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-6.1.8.tgz", + "integrity": "sha512-FUCJu9jlK3A8WqLTKXM9E6kAmI/dR1vAJ8dHYLMisLNB/n3GuaFIjJ7pn16ZcD1zCOf7P6H62lWIEBi+yz/zQQ==", + "dependencies": { + "@babel/runtime": "^7.24.5", + "fast-unique-numbers": "^8.0.13", + "tslib": "^2.6.2", + "worker-timers-worker": "^7.0.71" + } + }, + "node_modules/worker-timers-worker": { + "version": "7.0.71", + "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-7.0.71.tgz", + "integrity": "sha512-ks/5YKwZsto1c2vmljroppOKCivB/ma97g9y77MAAz2TBBjPPgpoOiS1qYQKIgvGTr2QYPT3XhJWIB6Rj2MVPQ==", + "dependencies": { + "@babel/runtime": "^7.24.5", + "tslib": "^2.6.2" + } + }, "node_modules/wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", @@ -3725,15 +3876,15 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "engines": { - "node": ">=8.3.0" + "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { diff --git a/acs-uns-ingester/package.json b/acs-uns-ingester/package.json index 70c93948..7c32517e 100644 --- a/acs-uns-ingester/package.json +++ b/acs-uns-ingester/package.json @@ -1,5 +1,5 @@ { - "name": "influxdb-sparkplug-ingester", + "name": "acs-uns-ingester", "version": "1.0.0", "description": "An ingestion engine to enable InfluxDB to be a fully-featured Sparkplug historian", "author": "AMRC", @@ -29,6 +29,7 @@ "@influxdata/influxdb-client-apis": "^1.33.2", "async": "^3.2.4", "long": "^5.2.3", + "mqtt": "^5.7.3", "pino": "^8.11.0", "pino-pretty": "^10.0.0" }, From b90d4348dab8e14165515aa528056599a3750175 Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Mon, 15 Jul 2024 08:48:13 +0100 Subject: [PATCH 06/58] Add new payload formatting --- acs-uns-ingester/bin/ingester.ts | 2 +- acs-uns-ingester/example.env | 2 +- acs-uns-ingester/lib/mqttclient.ts | 68 +++++++++++++++++++++++------- acs-uns-ingester/run-dev.sh | 2 +- 4 files changed, 56 insertions(+), 18 deletions(-) diff --git a/acs-uns-ingester/bin/ingester.ts b/acs-uns-ingester/bin/ingester.ts index 36edad14..624a8b52 100644 --- a/acs-uns-ingester/bin/ingester.ts +++ b/acs-uns-ingester/bin/ingester.ts @@ -1,5 +1,5 @@ /* - * AMRC InfluxDB Sparkplug Ingester + * AMRC ACS UNS Ingester * Copyright "2023" AMRC */ diff --git a/acs-uns-ingester/example.env b/acs-uns-ingester/example.env index bef798de..139296ff 100644 --- a/acs-uns-ingester/example.env +++ b/acs-uns-ingester/example.env @@ -1,7 +1,7 @@ DIRECTORY_URL=https://directory.domain.co.uk INFLUX_URL=http://influx.domain.co.uk INFLUX_TOKEN=XXXXXX -MQTT_URL=mqtt://mqtt.domain.co.uk +UNS_MQTT_URL=mqtt://mqtt.domain.co.uk INFLUX_ORG=default INFLUX_BUCKET=default LOG_LEVEL=info diff --git a/acs-uns-ingester/lib/mqttclient.ts b/acs-uns-ingester/lib/mqttclient.ts index f1ecb4fb..5ed0b0b7 100644 --- a/acs-uns-ingester/lib/mqttclient.ts +++ b/acs-uns-ingester/lib/mqttclient.ts @@ -1,5 +1,5 @@ /* - * AMRC InfluxDB Sparkplug Ingester + * AMRC ACS UNS Ingester * Copyright "2024" AMRC */ @@ -12,6 +12,15 @@ import {Agent} from 'http' import * as mqtt_dev from "mqtt"; +interface UnsMetric { + value: string, + timestamp: Date, +} + +interface BatchedUnsMetric extends UnsMetric { + batch?: UnsMetric[] +} + let dotenv: any = null; try { dotenv = await import ('dotenv') @@ -20,6 +29,7 @@ try { dotenv?.config() +/* const influxURL: string = process.env.INFLUX_URL; if (!influxURL) { throw new Error("INFLUX_URL environment variable is not set"); @@ -44,7 +54,7 @@ const flushInterval: number = Number.parseInt(process.env.FLUSH_INTERVAL); if (!flushInterval) { throw new Error("FLUSH_INTERVAL environment variable is not set"); } - +*/ const unsMqttUrl: string = process.env.UNS_MQTT_URL; if (!unsMqttUrl) { throw new Error("UNS_MQTT_URL environment variable is not set"); @@ -104,7 +114,7 @@ export default class MQTTClient { async run() { this.local_mqtt = mqtt_dev.connect(unsMqttUrl); this.local_mqtt.on("connect", () => { - logger.info("😁 Connected to local mqtt broker!"); + logger.info("✔ Connected to local mqtt broker!"); }); this.local_mqtt.on("error", (error) => { @@ -306,7 +316,7 @@ export default class MQTTClient { // Clear the debounce delete this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]; - // Store the default values in InfluxDB + // Publish values to UNS this.publishToUNS(payload, topic); break; @@ -332,7 +342,7 @@ export default class MQTTClient { // Check if we have a birth certificate for the device if (this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { - // Device is known, resolve aliases and write to InfluxDB + // Device is known, resolve aliases and publish to UNS //this.writeMetrics(payload, topic); this.publishToUNS(payload, topic) @@ -380,6 +390,8 @@ export default class MQTTClient { * @param topic Topic the payload was received on. */ private publishToUNS(payload, topic) { + const metricsToPublish: { [metricPath: string]: any[] } = {}; + //resolve metric aliases payload.metrics.forEach((metric) => { if (metric.value === null) return; let birth = this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]?.[metric.alias]; @@ -389,28 +401,54 @@ export default class MQTTClient { } if (birth.transient) { - logger.debug(`Metric ${birth.name} is transient, not writing to InfluxDB`); + logger.debug(`Metric ${birth.name} is transient, publishing to UNS`); return; } const metricName = birth.name.split('/').pop() as string; const path = birth.name.substring(0, birth.name.lastIndexOf("/")) as string; - - if ( - metricName === "Schema_UUID" || - metricName === "Instance_UUID" || - path.includes("Device Control") || - path.includes("Device Information") - ) { + if (path.includes("Device Control")) { return; } + let unsTopic: string; + if (path) { - this.local_mqtt.publish(`AMRC/Sheffield/F2050/${topic.address.device}/${path}/${metricName}`, `${metric.value}`); + // enterprise, site, area, cell, device? namespace where edge is the raw data from the device edge. + unsTopic = `AMRC/F2050/MK1/${topic.address.device}/Edge/${path}/${metricName}`; } else { - this.local_mqtt.publish(`AMRC/Sheffield/F2050/${topic.address.device}/${metricName}`, `${metric.value}`); + unsTopic = `AMRC/F2050/MK1/${topic.address.device}/Edge/${metricName}`; } + + if (!(unsTopic in metricsToPublish)) { + metricsToPublish[unsTopic] = [metric] + } else { + metricsToPublish[unsTopic].push(metric); + } + }); + + // format payload to publish to uns. + Object.entries(metricsToPublish).forEach(([key, value]) => { + // if theirs more than one of the same metric from the same sparkplug payload, add the values to the batch array. + if (value.length > 1) { + const sortedMetrics = value.sort((a, b) => b.timestamp - a.timestamp); + let payload: BatchedUnsMetric = { + timestamp: new Date(sortedMetrics[0].timestamp), + value: sortedMetrics[0].value, + batch: [] + } + //remove the first element, that's our newest and will be the value outside the batch array. + sortedMetrics.shift(); + sortedMetrics.forEach(metric => { + payload.batch.push({timestamp: metric.timestamp, value: metric.value}); + }); + this.local_mqtt.publish(key, payload); + } else { + const payload: UnsMetric = {timestamp: new Date(value[0].timestamp), value: value[0].value}; + this.local_mqtt.publish(key, payload); + } + }) } /* diff --git a/acs-uns-ingester/run-dev.sh b/acs-uns-ingester/run-dev.sh index cbd64e40..2f90906d 100644 --- a/acs-uns-ingester/run-dev.sh +++ b/acs-uns-ingester/run-dev.sh @@ -1,5 +1,5 @@ # -# AMRC InfluxDB Sparkplug Ingester +# AMRC ACS UNS Ingester # Copyright "2023" AMRC # From f0a1c358e9fc6391b6c3be1dbd6b965d928b7866 Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Mon, 15 Jul 2024 09:02:15 +0100 Subject: [PATCH 07/58] sparkplug-ingester: Move to `ingesters` directory --- acs-uns-ingester/Makefile | 7 - acs-uns-ingester/package-lock.json | 3942 ----------------- .../sparkplug}/.gitignore | 0 .../sparkplug}/Dockerfile | 0 .../sparkplug}/LICENSE | 0 .../sparkplug}/README.md | 0 .../sparkplug}/SECURITY.md | 0 .../sparkplug}/bin/ingester.js | 0 .../sparkplug}/bin/ingester.ts | 0 ingesters/sparkplug/bun.lockb | Bin 0 -> 128108 bytes .../sparkplug}/example.env | 0 .../sparkplug}/lib/mqttclient.js | 0 .../sparkplug}/lib/mqttclient.ts | 0 .../sparkplug}/package.json | 4 +- .../sparkplug}/run-dev.sh | 0 .../sparkplug}/tsconfig.json | 0 16 files changed, 1 insertion(+), 3952 deletions(-) delete mode 100644 acs-uns-ingester/Makefile delete mode 100644 acs-uns-ingester/package-lock.json rename {acs-uns-ingester => ingesters/sparkplug}/.gitignore (100%) rename {acs-uns-ingester => ingesters/sparkplug}/Dockerfile (100%) rename {acs-uns-ingester => ingesters/sparkplug}/LICENSE (100%) rename {acs-uns-ingester => ingesters/sparkplug}/README.md (100%) rename {acs-uns-ingester => ingesters/sparkplug}/SECURITY.md (100%) rename {acs-uns-ingester => ingesters/sparkplug}/bin/ingester.js (100%) rename {acs-uns-ingester => ingesters/sparkplug}/bin/ingester.ts (100%) create mode 100755 ingesters/sparkplug/bun.lockb rename {acs-uns-ingester => ingesters/sparkplug}/example.env (100%) rename {acs-uns-ingester => ingesters/sparkplug}/lib/mqttclient.js (100%) rename {acs-uns-ingester => ingesters/sparkplug}/lib/mqttclient.ts (100%) rename {acs-uns-ingester => ingesters/sparkplug}/package.json (88%) rename {acs-uns-ingester => ingesters/sparkplug}/run-dev.sh (100%) rename {acs-uns-ingester => ingesters/sparkplug}/tsconfig.json (100%) diff --git a/acs-uns-ingester/Makefile b/acs-uns-ingester/Makefile deleted file mode 100644 index bf4d70ab..00000000 --- a/acs-uns-ingester/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -top=.. -include ${top}/mk/acs.init.mk - -repo?=influxdb-sparkplug-ingester -k8s.deployment?=influxdb-ingester - -include ${mk}/acs.js.mk diff --git a/acs-uns-ingester/package-lock.json b/acs-uns-ingester/package-lock.json deleted file mode 100644 index 778ab7a3..00000000 --- a/acs-uns-ingester/package-lock.json +++ /dev/null @@ -1,3942 +0,0 @@ -{ - "name": "acs-uns-ingester", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "acs-uns-ingester", - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "@amrc-factoryplus/utilities": "^1.0.8", - "@influxdata/influxdb-client": "^1.33.2", - "@influxdata/influxdb-client-apis": "^1.33.2", - "async": "^3.2.4", - "long": "^5.2.3", - "mqtt": "^5.7.3", - "pino": "^8.11.0", - "pino-pretty": "^10.0.0" - }, - "devDependencies": { - "cross-env": "^7.0.3", - "dotenv": "^16.0.3", - "ts-node": "^10.9.1", - "tsc-alias": "^1.7.0" - } - }, - "node_modules/@amrc-factoryplus/utilities": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@amrc-factoryplus/utilities/-/utilities-1.0.8.tgz", - "integrity": "sha512-pSnakabCRTs7AlRtjYPNM47BQLsN2XR7xrNXuKmBDf+iytsCU1m0pCmQXuUM8/yvk80PxabMLm7dIlG405r5Bg==", - "dependencies": { - "@types/express": "4", - "@types/long": "^4.0.0", - "@types/node": ">=13.7.0", - "content-type": "^1.0.5", - "cors": "^2.8.5", - "express": "^4.18.1", - "find-package-json": "^1.2.0", - "got-fetch": "^5.1.1", - "http-errors": "^2.0.0", - "mqtt": "^4.3.5", - "optional-js": "^2.3.0", - "path-to-regexp": "^6.2.1", - "pg": "^8.7.3", - "protobufjs": "^6.11.3", - "semver": "^7.5.1", - "sparkplug-payload": "^1.0.1", - "typescript": "^4.8.4" - }, - "optionalDependencies": { - "gssapi.js": "^2.0.1", - "pg-native": "^3.0.0" - } - }, - "node_modules/@amrc-factoryplus/utilities/node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/@amrc-factoryplus/utilities/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/@amrc-factoryplus/utilities/node_modules/commist": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", - "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", - "dependencies": { - "leven": "^2.1.0", - "minimist": "^1.1.0" - } - }, - "node_modules/@amrc-factoryplus/utilities/node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@amrc-factoryplus/utilities/node_modules/help-me": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", - "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", - "dependencies": { - "glob": "^7.1.6", - "readable-stream": "^3.6.0" - } - }, - "node_modules/@amrc-factoryplus/utilities/node_modules/mqtt": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.8.tgz", - "integrity": "sha512-2xT75uYa0kiPEF/PE0VPdavmEkoBzMT/UL9moid0rAvlCtV48qBwxD62m7Ld/4j8tSkIO1E/iqRl/S72SEOhOw==", - "dependencies": { - "commist": "^1.0.0", - "concat-stream": "^2.0.0", - "debug": "^4.1.1", - "duplexify": "^4.1.1", - "help-me": "^3.0.0", - "inherits": "^2.0.3", - "lru-cache": "^6.0.0", - "minimist": "^1.2.5", - "mqtt-packet": "^6.8.0", - "number-allocator": "^1.0.9", - "pump": "^3.0.0", - "readable-stream": "^3.6.0", - "reinterval": "^1.1.0", - "rfdc": "^1.3.0", - "split2": "^3.1.0", - "ws": "^7.5.5", - "xtend": "^4.0.2" - }, - "bin": { - "mqtt": "bin/mqtt.js", - "mqtt_pub": "bin/pub.js", - "mqtt_sub": "bin/sub.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@amrc-factoryplus/utilities/node_modules/mqtt-packet": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", - "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", - "dependencies": { - "bl": "^4.0.2", - "debug": "^4.1.1", - "process-nextick-args": "^2.0.1" - } - }, - "node_modules/@amrc-factoryplus/utilities/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==" - }, - "node_modules/@amrc-factoryplus/utilities/node_modules/path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" - }, - "node_modules/@amrc-factoryplus/utilities/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@amrc-factoryplus/utilities/node_modules/semver": { - "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" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@amrc-factoryplus/utilities/node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", - "dependencies": { - "readable-stream": "^3.0.0" - } - }, - "node_modules/@amrc-factoryplus/utilities/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/@amrc-factoryplus/utilities/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@babel/runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@influxdata/influxdb-client": { - "version": "1.33.2", - "resolved": "https://registry.npmjs.org/@influxdata/influxdb-client/-/influxdb-client-1.33.2.tgz", - "integrity": "sha512-RT5SxH+grHAazo/YK3UTuWK/frPWRM0N7vkrCUyqVprDgQzlLP+bSK4ak2Jv3QVF/pazTnsxWjvtKZdwskV5Xw==" - }, - "node_modules/@influxdata/influxdb-client-apis": { - "version": "1.33.2", - "resolved": "https://registry.npmjs.org/@influxdata/influxdb-client-apis/-/influxdb-client-apis-1.33.2.tgz", - "integrity": "sha512-W6x9TOAQ3AUx0RBCrCibDhSvMqN50lxJmElc3rHn7+R/9Zi35oczu8r9YMkyNlzWnksu+dcyKr8/xLv28Ot4hw==", - "peerDependencies": { - "@influxdata/influxdb-client": "*" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "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": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "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_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/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "node_modules/@sindresorhus/is": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", - "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", - "peer": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "peer": true, - "dependencies": { - "defer-to-connect": "^2.0.1" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true - }, - "node_modules/@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.17", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", - "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.33", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", - "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", - "peer": true - }, - "node_modules/@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" - }, - "node_modules/@types/mime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", - "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" - }, - "node_modules/@types/node": { - "version": "18.15.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", - "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==" - }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" - }, - "node_modules/@types/readable-stream": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.14.tgz", - "integrity": "sha512-xZn/AuUbCMShGsqH/ehZtGDwQtbx00M9rZ2ENLe4tOjFZ/JFeWMhEZkk2fEe1jAUqqEAURIkFJ7Az/go8mM1/w==", - "dependencies": { - "@types/node": "*", - "safe-buffer": "~5.1.1" - } - }, - "node_modules/@types/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/@types/serve-static": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", - "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", - "dependencies": { - "@types/mime": "*", - "@types/node": "*" - } - }, - "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ansi": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", - "integrity": "sha512-iFY7JCgHbepc0b82yLaw4IMortylNb6wG4kL+4R0C3iv6i+RHGHux/yUX5BTiRvSX/shMnngjR1YyNMnXEFh5A==", - "optional": true - }, - "node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/are-we-there-yet": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.0.6.tgz", - "integrity": "sha512-Zfw6bteqM9gQXZ1BIWOgM8xEwMrUGoyL8nW13+O+OOgNX3YhuDN1GDgg1NzdTlmm3j+9sHy7uBZ12r+z9lXnZQ==", - "optional": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.0 || ^1.1.13" - } - }, - "node_modules/are-we-there-yet/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "optional": true - }, - "node_modules/are-we-there-yet/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "optional": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/are-we-there-yet/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - }, - "node_modules/are-we-there-yet/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, - "node_modules/atomic-sleep": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", - "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "optional": true, - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "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/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/big-integer": { - "version": "1.6.51", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", - "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", - "optional": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/binary": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", - "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", - "optional": true, - "dependencies": { - "buffers": "~0.1.1", - "chainsaw": "~0.1.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bl": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/bl/-/bl-6.0.13.tgz", - "integrity": "sha512-tMncAcpsyjZgAVbVFupVIaB2xud13xxT59fdHkuszY2jdZkqIWfpQdmII1fOe3kOGAz0mNLTIHEm+KxpYsQKKg==", - "dependencies": { - "@types/readable-stream": "^4.0.0", - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^4.2.0" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", - "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/bl/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "optional": true - }, - "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/buffer-indexof-polyfill": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", - "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", - "optional": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/buffer-shims": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g==", - "optional": true - }, - "node_modules/buffer-writer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", - "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/buffers": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", - "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", - "optional": true, - "engines": { - "node": ">=0.2.0" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", - "peer": true, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/cacheable-request": { - "version": "10.2.9", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.9.tgz", - "integrity": "sha512-CaAMr53AS1Tb9evO1BIWFnZjSr8A4pbXofpsNVWPMDZZj3ZQKHwsQG9BrTqQ4x5ZYJXz1T2b8LLtTZODxSpzbg==", - "peer": true, - "dependencies": { - "@types/http-cache-semantics": "^4.0.1", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.2", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/chainsaw": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", - "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", - "optional": true, - "dependencies": { - "traverse": ">=0.3.0 <0.4" - }, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "optional": true - }, - "node_modules/cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", - "optional": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "node_modules/cmake-js": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/cmake-js/-/cmake-js-6.3.2.tgz", - "integrity": "sha512-7MfiQ/ijzeE2kO+WFB9bv4QP5Dn2yVaAP2acFJr4NIFy2hT4w6O4EpOTLNcohR5IPX7M4wNf/5taIqMj7UA9ug==", - "optional": true, - "dependencies": { - "axios": "^0.21.1", - "bluebird": "^3", - "debug": "^4", - "fs-extra": "^5.0.0", - "is-iojs": "^1.0.1", - "lodash": "^4", - "memory-stream": "0", - "npmlog": "^1.2.0", - "rc": "^1.2.7", - "semver": "^5.0.3", - "splitargs": "0", - "tar": "^4", - "unzipper": "^0.8.13", - "url-join": "0", - "which": "^1.0.9", - "yargs": "^3.6.0" - }, - "bin": { - "cmake-js": "bin/cmake-js" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/cmake-js/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "optional": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/cmake-js/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==", - "optional": true - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" - }, - "node_modules/commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || >=14" - } - }, - "node_modules/commist": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz", - "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "engines": [ - "node >= 6.0" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "optional": true - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cross-spawn/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/dateformat": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", - "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", - "engines": { - "node": "*" - } - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "peer": true, - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "optional": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "peer": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "optional": true - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dotenv": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", - "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "optional": true, - "dependencies": { - "readable-stream": "^2.0.2" - } - }, - "node_modules/duplexer2/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "optional": true - }, - "node_modules/duplexer2/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "optional": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/duplexer2/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - }, - "node_modules/duplexer2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/duplexify": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", - "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.2" - } - }, - "node_modules/duplexify/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/duplexify/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/fast-copy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.1.tgz", - "integrity": "sha512-Knr7NOtK3HWRYGtHoJrjkaWepqT8thIVGAwt0p0aUs1zqkAzXZV4vo9fFNwyb5fcqK1GKYFYxldQdIDVKhUAfA==" - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-redact": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.1.2.tgz", - "integrity": "sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" - }, - "node_modules/fast-unique-numbers": { - "version": "8.0.13", - "resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-8.0.13.tgz", - "integrity": "sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g==", - "dependencies": { - "@babel/runtime": "^7.23.8", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.1.0" - } - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/find-package-json": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/find-package-json/-/find-package-json-1.2.0.tgz", - "integrity": "sha512-+SOGcLGYDJHtyqHd87ysBhmaeQ95oWspDKnMXBrnQ9Eq4OkLNqejgoaD8xVWu6GPa0B6roa6KinCMEMcVeqONw==" - }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "optional": true, - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data-encoder": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", - "peer": true, - "engines": { - "node": ">= 14.17" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-extra": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", - "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "node_modules/fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "optional": true, - "dependencies": { - "minipass": "^2.6.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - }, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/gauge": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", - "integrity": "sha512-fVbU2wRE91yDvKUnrIaQlHKAWKY5e08PmztCrwuH5YVQ+Z/p3d0ny2T48o6uvAAXHIUnfaQdHkmxYbQft1eHVA==", - "optional": true, - "dependencies": { - "ansi": "^0.3.0", - "has-unicode": "^2.0.0", - "lodash.pad": "^4.1.0", - "lodash.padend": "^4.1.0", - "lodash.padstart": "^4.1.0" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/got": { - "version": "12.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.0.tgz", - "integrity": "sha512-WTcaQ963xV97MN3x0/CbAriXFZcXCfgxVp91I+Ze6pawQOa7SgzwSx2zIJJsX+kTajMnVs0xcFD1TxZKFqhdnQ==", - "peer": true, - "dependencies": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/got-fetch": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/got-fetch/-/got-fetch-5.1.4.tgz", - "integrity": "sha512-Pdv+SSgtTCDZbNuGkOf0c0FZy5Syqf225JEgG/vKt13HAe8r2vNJ11DxKKODsmr7L7/6ff3lf+AxpBtD5k/dRQ==", - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "got": "^12.0.0" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "optional": true - }, - "node_modules/gssapi.js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gssapi.js/-/gssapi.js-2.0.1.tgz", - "integrity": "sha512-5D+qylV8uIKMaxTTKhpzvfGRz5+okr/rpwC6YlaCoDVBpvkuNgL8pM7+r7aTzZ2oT5dA4w2WoZTV82opGj+RZQ==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "bindings": "^1.5.0", - "cmake-js": "^6.1.0", - "node-addon-api": "^1.7.2" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "optional": true - }, - "node_modules/help-me": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", - "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==" - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "peer": true - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http2-wrapper": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz", - "integrity": "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==", - "peer": true, - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "optional": true - }, - "node_modules/invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "optional": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-iojs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-iojs/-/is-iojs-1.1.0.tgz", - "integrity": "sha512-tLn1j3wYSL6DkvEI+V/j0pKohpa5jk+ER74v6S4SgCXnjS0WA+DoZbwZBrrhgwksMvtuwndyGeG5F8YMsoBzSA==", - "optional": true - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "optional": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "devOptional": true - }, - "node_modules/joycon": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", - "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/js-sdsl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", - "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "peer": true - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "optional": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/keyv": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", - "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", - "peer": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", - "optional": true, - "dependencies": { - "invert-kv": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/libpq": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/libpq/-/libpq-1.8.12.tgz", - "integrity": "sha512-4lUY9BD9suz76mVS0kH4rRgRy620g/c9YZH5GYC3smfIpjtj6KiPuQ4IwQSHSZMMMhMM3tBFrYUrw8mHOOZVeg==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "bindings": "1.5.0", - "nan": "^2.14.0" - } - }, - "node_modules/listenercount": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", - "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==", - "optional": true - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "optional": true - }, - "node_modules/lodash.pad": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", - "integrity": "sha512-mvUHifnLqM+03YNzeTBS1/Gr6JRFjd3rRx88FHWUvamVaT9k2O/kXha3yBSOwB9/DTQrSTLJNHvLBBt2FdX7Mg==", - "optional": true - }, - "node_modules/lodash.padend": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", - "integrity": "sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw==", - "optional": true - }, - "node_modules/lodash.padstart": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", - "integrity": "sha512-sW73O6S8+Tg66eY56DBk85aQzzUJDtpoXFBgELMd5P/SotAguo+1kYO6RuYgXxA4HJH3LFTFPASX6ET6bjfriw==", - "optional": true - }, - "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" - }, - "node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "peer": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memory-stream": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/memory-stream/-/memory-stream-0.0.3.tgz", - "integrity": "sha512-q0D3m846qY6ZkIt+19ZemU5vH56lpOZZwoJc3AICARKh/menBuayQUjAGPrqtHQQMUYERSdOrej92J9kz7LgYA==", - "optional": true, - "dependencies": { - "readable-stream": "~1.0.26-2" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "peer": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "optional": true, - "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "node_modules/minipass/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "optional": true - }, - "node_modules/minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "optional": true, - "dependencies": { - "minipass": "^2.9.0" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "optional": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mqtt": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.7.3.tgz", - "integrity": "sha512-v+5la6Q6zjl0AWsI7ICDA/K3hclkNj7CMa0khMugCC+LKPLrQF+sSQb/9ckezZLMvcBC1tXhRzqmcagQoDl9fQ==", - "dependencies": { - "@types/readable-stream": "^4.0.5", - "@types/ws": "^8.5.9", - "commist": "^3.2.0", - "concat-stream": "^2.0.0", - "debug": "^4.3.4", - "help-me": "^5.0.0", - "lru-cache": "^10.0.1", - "minimist": "^1.2.8", - "mqtt": "^5.2.0", - "mqtt-packet": "^9.0.0", - "number-allocator": "^1.0.14", - "readable-stream": "^4.4.2", - "reinterval": "^1.1.0", - "rfdc": "^1.3.0", - "split2": "^4.2.0", - "worker-timers": "^7.1.4", - "ws": "^8.17.1" - }, - "bin": { - "mqtt": "build/bin/mqtt.js", - "mqtt_pub": "build/bin/pub.js", - "mqtt_sub": "build/bin/sub.js" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/mqtt-packet": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-9.0.0.tgz", - "integrity": "sha512-8v+HkX+fwbodsWAZIZTI074XIoxVBOmPeggQuDFCGg1SqNcC+uoRMWu7J6QlJPqIUIJXmjNYYHxBBLr1Y/Df4w==", - "dependencies": { - "bl": "^6.0.8", - "debug": "^4.3.4", - "process-nextick-args": "^2.0.1" - } - }, - "node_modules/mqtt-packet/node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/mqtt-packet/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==" - }, - "node_modules/mqtt/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/mqtt/node_modules/lru-cache": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", - "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==", - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/mqtt/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==" - }, - "node_modules/mqtt/node_modules/readable-stream": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", - "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/mqtt/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/mylas": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/mylas/-/mylas-2.1.13.tgz", - "integrity": "sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==", - "dev": true, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/raouldeheer" - } - }, - "node_modules/nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "optional": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-addon-api": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", - "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", - "optional": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", - "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", - "peer": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npmlog": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-1.2.1.tgz", - "integrity": "sha512-1J5KqSRvESP6XbjPaXt2H6qDzgizLTM7x0y1cXIjP2PpvdCqyNC7TO3cPRKsuYlElbi/DwkzRRdG2zpmE0IktQ==", - "optional": true, - "dependencies": { - "ansi": "~0.3.0", - "are-we-there-yet": "~1.0.0", - "gauge": "~1.2.0" - } - }, - "node_modules/number-allocator": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz", - "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==", - "dependencies": { - "debug": "^4.3.1", - "js-sdsl": "4.3.0" - } - }, - "node_modules/number-allocator/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/number-allocator/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==" - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-exit-leak-free": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", - "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==" - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optional-js": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/optional-js/-/optional-js-2.3.0.tgz", - "integrity": "sha512-B0LLi+Vg+eko++0z/b8zIv57kp7HKEzaPJo7LowJXMUKYdf+3XJGu/cw03h/JhIOsLnP+cG5QnTHAuicjA5fMw==" - }, - "node_modules/os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", - "optional": true, - "dependencies": { - "lcid": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "peer": true, - "engines": { - "node": ">=12.20" - } - }, - "node_modules/packet-reader": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", - "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pg": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.10.0.tgz", - "integrity": "sha512-ke7o7qSTMb47iwzOSaZMfeR7xToFdkE71ifIipOAAaLIM0DYzfOAXlgFFmYUIE2BcJtvnVlGCID84ZzCegE8CQ==", - "dependencies": { - "buffer-writer": "2.0.0", - "packet-reader": "1.0.0", - "pg-connection-string": "^2.5.0", - "pg-pool": "^3.6.0", - "pg-protocol": "^1.6.0", - "pg-types": "^2.1.0", - "pgpass": "1.x" - }, - "engines": { - "node": ">= 8.0.0" - }, - "peerDependencies": { - "pg-native": ">=3.0.1" - }, - "peerDependenciesMeta": { - "pg-native": { - "optional": true - } - } - }, - "node_modules/pg-connection-string": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", - "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" - }, - "node_modules/pg-int8": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/pg-native": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/pg-native/-/pg-native-3.0.1.tgz", - "integrity": "sha512-LBVNWkNh0fVx/cienARRP2y22J5OpUsKBe0TpxzAx3arEUUdIs77aLSAHS3scS7SMaqc+OkG40CEu5fN0/cjIw==", - "optional": true, - "dependencies": { - "libpq": "^1.8.10", - "pg-types": "^1.12.1", - "readable-stream": "1.0.31" - } - }, - "node_modules/pg-native/node_modules/pg-types": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-1.13.0.tgz", - "integrity": "sha512-lfKli0Gkl/+za/+b6lzENajczwZHc7D5kiUCZfgm914jipD2kIOIvEkAhZ8GrW3/TUoP9w8FHjwpPObBye5KQQ==", - "optional": true, - "dependencies": { - "pg-int8": "1.0.1", - "postgres-array": "~1.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.0", - "postgres-interval": "^1.1.0" - } - }, - "node_modules/pg-native/node_modules/postgres-array": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.3.tgz", - "integrity": "sha512-5wClXrAP0+78mcsNX3/ithQ5exKvCyK5lr5NEEEeGwwM6NJdQgzIJBVxLvRW+huFpX92F2QnZ5CcokH0VhK2qQ==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pg-native/node_modules/readable-stream": { - "version": "1.0.31", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.31.tgz", - "integrity": "sha512-tco/Dwv1f/sgIgN6CWdj/restacPKNskK6yps1981ivH2ZmLYcs5o5rVzL3qaO/cSkhN8hYOMWs7+glzOLSgRg==", - "optional": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/pg-pool": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.0.tgz", - "integrity": "sha512-clFRf2ksqd+F497kWFyM21tMjeikn60oGDmqMT8UBrynEwVEX/5R5xd2sdvdo1cZCFlguORNpVuqxIj+aK4cfQ==", - "peerDependencies": { - "pg": ">=8.0" - } - }, - "node_modules/pg-protocol": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", - "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" - }, - "node_modules/pg-types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", - "dependencies": { - "pg-int8": "1.0.1", - "postgres-array": "~2.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.4", - "postgres-interval": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pgpass": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", - "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", - "dependencies": { - "split2": "^4.1.0" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pino": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-8.11.0.tgz", - "integrity": "sha512-Z2eKSvlrl2rH8p5eveNUnTdd4AjJk8tAsLkHYZQKGHP4WTh2Gi1cOSOs3eWPqaj+niS3gj4UkoreoaWgF3ZWYg==", - "dependencies": { - "atomic-sleep": "^1.0.0", - "fast-redact": "^3.1.1", - "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "v1.0.0", - "pino-std-serializers": "^6.0.0", - "process-warning": "^2.0.0", - "quick-format-unescaped": "^4.0.3", - "real-require": "^0.2.0", - "safe-stable-stringify": "^2.3.1", - "sonic-boom": "^3.1.0", - "thread-stream": "^2.0.0" - }, - "bin": { - "pino": "bin.js" - } - }, - "node_modules/pino-abstract-transport": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz", - "integrity": "sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==", - "dependencies": { - "readable-stream": "^4.0.0", - "split2": "^4.0.0" - } - }, - "node_modules/pino-abstract-transport/node_modules/readable-stream": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz", - "integrity": "sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/pino-pretty": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.0.0.tgz", - "integrity": "sha512-zKFjYXBzLaLTEAN1ayKpHXtL5UeRQC7R3lvhKe7fWs7hIVEjKGG/qIXwQt9HmeUp71ogUd/YcW+LmMwRp4KT6Q==", - "dependencies": { - "colorette": "^2.0.7", - "dateformat": "^4.6.3", - "fast-copy": "^3.0.0", - "fast-safe-stringify": "^2.1.1", - "help-me": "^4.0.1", - "joycon": "^3.1.1", - "minimist": "^1.2.6", - "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "^1.0.0", - "pump": "^3.0.0", - "readable-stream": "^4.0.0", - "secure-json-parse": "^2.4.0", - "sonic-boom": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "bin": { - "pino-pretty": "bin.js" - } - }, - "node_modules/pino-pretty/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/pino-pretty/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/pino-pretty/node_modules/help-me": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/help-me/-/help-me-4.2.0.tgz", - "integrity": "sha512-TAOnTB8Tz5Dw8penUuzHVrKNKlCIbwwbHnXraNJxPwf8LRtE2HlM84RYuezMFcwOJmoYOCWVDyJ8TQGxn9PgxA==", - "dependencies": { - "glob": "^8.0.0", - "readable-stream": "^3.6.0" - } - }, - "node_modules/pino-pretty/node_modules/help-me/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pino-pretty/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pino-pretty/node_modules/readable-stream": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz", - "integrity": "sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/pino-pretty/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/pino-pretty/node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pino-std-serializers": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.0.tgz", - "integrity": "sha512-IWgSzUL8X1w4BIWTwErRgtV8PyOGOOi60uqv0oKuS/fOA8Nco/OeI6lBuc4dyP8MMfdFwyHqTMcBIA7nDiqEqA==" - }, - "node_modules/plimit-lit": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/plimit-lit/-/plimit-lit-1.5.0.tgz", - "integrity": "sha512-Eb/MqCb1Iv/ok4m1FqIXqvUKPISufcjZ605hl3KM/n8GaX8zfhtgdLwZU3vKjuHGh2O9Rjog/bHTq8ofIShdng==", - "dev": true, - "dependencies": { - "queue-lit": "^1.5.0" - } - }, - "node_modules/postgres-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/postgres-bytea": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-date": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-interval": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "dependencies": { - "xtend": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/process-warning": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", - "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==" - }, - "node_modules/protobufjs": { - "version": "6.11.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", - "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/protobufjs/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-lit": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-1.5.0.tgz", - "integrity": "sha512-IslToJ4eiCEE9xwMzq3viOO5nH8sUWUCwoElrhNMozzr9IIt2qqvB4I+uHu/zJTQVqc9R5DFwok4ijNK1pU3fA==", - "dev": true - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/quick-format-unescaped": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", - "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "optional": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "optional": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/real-require": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", - "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - }, - "node_modules/reinterval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", - "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" - }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "peer": true - }, - "node_modules/responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "peer": true, - "dependencies": { - "lowercase-keys": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" - }, - "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "optional": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", - "engines": { - "node": ">=10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/secure-json-parse": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", - "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" - }, - "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "optional": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "optional": true - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/sonic-boom": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz", - "integrity": "sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==", - "dependencies": { - "atomic-sleep": "^1.0.0" - } - }, - "node_modules/sparkplug-payload": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkplug-payload/-/sparkplug-payload-1.0.1.tgz", - "integrity": "sha512-N4i++SFY7ECH7NB2bi1zmL9uPRKXF5cXQRxudUqZi9sribVZB7TZWvMIcTTakqqs1WkryYgpuV34CwEYm7I0Cg==", - "dependencies": { - "protobufjs": "^6.8.0" - } - }, - "node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "engines": { - "node": ">= 10.x" - } - }, - "node_modules/splitargs": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/splitargs/-/splitargs-0.0.7.tgz", - "integrity": "sha512-UUFYD2oWbNwULH6WoVtLUOw8ch586B+HUqcsAjjjeoBQAM1bD4wZRXu01koaxyd8UeYpybWqW4h+lO1Okv40Tg==", - "optional": true - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/stream-shift": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==" - }, - "node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "optional": true - }, - "node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "optional": true, - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "optional": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "optional": true, - "dependencies": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, - "engines": { - "node": ">=4.5" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "optional": true - }, - "node_modules/thread-stream": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.3.0.tgz", - "integrity": "sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==", - "dependencies": { - "real-require": "^0.2.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/traverse": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", - "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", - "optional": true, - "engines": { - "node": "*" - } - }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/tsc-alias": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/tsc-alias/-/tsc-alias-1.8.5.tgz", - "integrity": "sha512-Y3ka0olwSRdbHPyX5kXhYY2aoBKuT53DFdeY+PpQUR4hg5M/b8eIRmC8dL4FBdd0wT366iWc6iDUUGe6QwI7mg==", - "dev": true, - "dependencies": { - "chokidar": "^3.5.3", - "commander": "^9.0.0", - "globby": "^11.0.4", - "mylas": "^2.1.9", - "normalize-path": "^3.0.0", - "plimit-lit": "^1.2.6" - }, - "bin": { - "tsc-alias": "dist/bin/index.js" - } - }, - "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "optional": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unzipper": { - "version": "0.8.14", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.8.14.tgz", - "integrity": "sha512-8rFtE7EP5ssOwGpN2dt1Q4njl0N1hUXJ7sSPz0leU2hRdq6+pra57z4YPBlVqm40vcgv6ooKZEAx48fMTv9x4w==", - "optional": true, - "dependencies": { - "big-integer": "^1.6.17", - "binary": "~0.3.0", - "bluebird": "~3.4.1", - "buffer-indexof-polyfill": "~1.0.0", - "duplexer2": "~0.1.4", - "fstream": "~1.0.10", - "listenercount": "~1.0.1", - "readable-stream": "~2.1.5", - "setimmediate": "~1.0.4" - } - }, - "node_modules/unzipper/node_modules/bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==", - "optional": true - }, - "node_modules/unzipper/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "optional": true - }, - "node_modules/unzipper/node_modules/process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==", - "optional": true - }, - "node_modules/unzipper/node_modules/readable-stream": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", - "integrity": "sha512-NkXT2AER7VKXeXtJNSaWLpWIhmtSE3K2PguaLEeWr4JILghcIKqoLt1A3wHrnpDC5+ekf8gfk1GKWkFXe4odMw==", - "optional": true, - "dependencies": { - "buffer-shims": "^1.0.0", - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/url-join": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz", - "integrity": "sha512-H6dnQ/yPAAVzMQRvEvyz01hhfQL5qRWSEt7BX8t9DqnPw9BjMb64fjIRq76Uvf1hkHp+mTZvEVJ5guXOT0Xqaw==", - "optional": true - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "optional": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha512-2thx4pB0cV3h+Bw7QmMXcEbdmOzv9t0HFplJH/Lz6yu60hXYy5RT8rUu+wlIreVxWsGN20mo+MHeCSfUpQBwPw==", - "optional": true, - "bin": { - "window-size": "cli.js" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/worker-timers": { - "version": "7.1.8", - "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-7.1.8.tgz", - "integrity": "sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw==", - "dependencies": { - "@babel/runtime": "^7.24.5", - "tslib": "^2.6.2", - "worker-timers-broker": "^6.1.8", - "worker-timers-worker": "^7.0.71" - } - }, - "node_modules/worker-timers-broker": { - "version": "6.1.8", - "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-6.1.8.tgz", - "integrity": "sha512-FUCJu9jlK3A8WqLTKXM9E6kAmI/dR1vAJ8dHYLMisLNB/n3GuaFIjJ7pn16ZcD1zCOf7P6H62lWIEBi+yz/zQQ==", - "dependencies": { - "@babel/runtime": "^7.24.5", - "fast-unique-numbers": "^8.0.13", - "tslib": "^2.6.2", - "worker-timers-worker": "^7.0.71" - } - }, - "node_modules/worker-timers-worker": { - "version": "7.0.71", - "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-7.0.71.tgz", - "integrity": "sha512-ks/5YKwZsto1c2vmljroppOKCivB/ma97g9y77MAAz2TBBjPPgpoOiS1qYQKIgvGTr2QYPT3XhJWIB6Rj2MVPQ==", - "dependencies": { - "@babel/runtime": "^7.24.5", - "tslib": "^2.6.2" - } - }, - "node_modules/wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "optional": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "optional": true - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha512-ONJZiimStfZzhKamYvR/xvmgW3uEkAUFSP91y2caTEPhzF6uP2JfPiVZcq66b/YR0C3uitxSV7+T1x8p5bkmMg==", - "optional": true, - "dependencies": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - } - } -} diff --git a/acs-uns-ingester/.gitignore b/ingesters/sparkplug/.gitignore similarity index 100% rename from acs-uns-ingester/.gitignore rename to ingesters/sparkplug/.gitignore diff --git a/acs-uns-ingester/Dockerfile b/ingesters/sparkplug/Dockerfile similarity index 100% rename from acs-uns-ingester/Dockerfile rename to ingesters/sparkplug/Dockerfile diff --git a/acs-uns-ingester/LICENSE b/ingesters/sparkplug/LICENSE similarity index 100% rename from acs-uns-ingester/LICENSE rename to ingesters/sparkplug/LICENSE diff --git a/acs-uns-ingester/README.md b/ingesters/sparkplug/README.md similarity index 100% rename from acs-uns-ingester/README.md rename to ingesters/sparkplug/README.md diff --git a/acs-uns-ingester/SECURITY.md b/ingesters/sparkplug/SECURITY.md similarity index 100% rename from acs-uns-ingester/SECURITY.md rename to ingesters/sparkplug/SECURITY.md diff --git a/acs-uns-ingester/bin/ingester.js b/ingesters/sparkplug/bin/ingester.js similarity index 100% rename from acs-uns-ingester/bin/ingester.js rename to ingesters/sparkplug/bin/ingester.js diff --git a/acs-uns-ingester/bin/ingester.ts b/ingesters/sparkplug/bin/ingester.ts similarity index 100% rename from acs-uns-ingester/bin/ingester.ts rename to ingesters/sparkplug/bin/ingester.ts diff --git a/ingesters/sparkplug/bun.lockb b/ingesters/sparkplug/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..e7d28b4bcd2760292766dda37d1228edfa37298a GIT binary patch literal 128108 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¥obwo;gYi4|u8{Yxb2gW~D@LOTJy&yPKc!&Bn}kG$$U;Nz#=bEz3A7yMv1+ z%JYEvz>Xut-zgj*@=mTD?rImWo2wQap`D}R*mq=nnbMlMVCePOT zdfv9LVZUQ{G*e-L=Zjq#;#d70eazeA+0N$?;yp;@?F>7;X>j2>i?Xl|)s&(SLNTei zhJ(j=-nz4E*!JtRoU52vlhk!x)oDK|W0}v56)~3+oy@5@RjBxQco+^JmM5Nn4-t72 zIwB@36feezExyM=U)CR7U2}Q;-C=>Gf_V`ppEW7<=oTDNXLS24E-^=H*LK2_xnd~b6jvdWaI@|ctC z3Gp5w@_xB8z@!%MJ|BsyhgK~;hVE%v$T$=TyM>+ zIv;tl*W5*Ro&2&Bm#-`9s=eP)*KHDFsubSb&2Y*r{7}Nw5}8xZ(u8;;h`f=PRwn3f zQ1K~PlKCoKV)rQZX!of+UZ;_$h4Nh7A2`Qkg@QYj#XgSQvGRGe&XRd+)z0PbEW1{w zRw`(^RCwt75_lttyw0vG*&6Pha=2bkGW&S)Q)ZKR2k)-KP0y)5*os~VK0Ufg)|%yp zYGC3`rk)OtH-Y=ucdba;U>M?Xbx|naN;64g0&f(Ncd2dsYAdgL^; zI^Y#sboYtfzRUJE)ZCbP&rJ#m?;U&9%#pA2uGi4iFS+$djA&Et(t__#0@XJXc%zBD zw>esmv6=)HOfjfF{jtVe+bmGu;d!)J*ZGY*G>-<^w3WR7Qugj{rvJC$#e!Q77GGw4 z?8PA%`?Fii)az2r$rGQ3n1<$Y}-YdBe#Iaj&R zPJ_y}LZ+siGp7iF%Uw01S|wtOHPzrJ~{(#1a425CJhQoR=Qt0qr+wI2 z_H^}4N7K#=T}xVGX57$hbh*alMD83DLcFm=-py)eta}!_ykr*+KAB~{VbcdiFRp#> zxx=^Q2vf=R1ch!QJuqjDS*o@7`V)Q5du#S>ekWL0lxH3hoH%G0KP6>I;QfE>y#-tr z-P`X=N=YLip&%hjw}6C5E25-GcSx5YsVJd{5`vUSE8Qt2A(GOflr#bo7NEkp2Ibwe z&;CDqe?EJk&pH41J*?;XI&-gU)^FBav+AC?S?dv6*NI_1iBu&lK6m!%*_1=cHYtfkD2AgnhNrf zzBg}HG@o*MzhN>bEqvX_qypooz4dIS1*{EyMP15Z_6usV{nY#UVe*m!#!&kpRyFX0xHczvg zY_axjcH7&Uiz}m&6uDKQa*r$PNeKkyX%s$)TT;rhmZ9<+gVwe9CGIesE%=ViAn6>l z*)zdTxrX)uy0H5j?qw6xb!QfcjXanu1>I@SFb#~3UDC}Qm#!`Jsi~xPe_vnnU27iw z{vsBwYd>~>sh%g)m{RaXm6evO5Hlx>=M=rfO$N)eV(M5W4+vxnUSm{zXzR1glE=0^ zM>`dD*m{hpBcA;iqZZ3<5&FI96SS_c_5i#%{-GcEGUH@!(4%OVfUB8e-fE-?60!wE z!LxTSZzV5|jh*Z;-`oh#e~CfEaQCEdI^!|rB9qeN6*|G_b}|mFTjcOVBK_so8S%wA zu?0T!FENjLgb7IATkBsoCM#i_+3ibx%T)caEF!R4VUEd&>*-dL6g{=SW-RPZ7^}jN0@_j+4T}fDP@KFxvwhDGZ&}7Y*TkGzNjI@_|De%a3%BH1(a?AT6dl1w^>&gE=^c6BNGkZS=P`;7@XV$ccU|P zUJw^JXTIbsx5lwJ=N7zK)xsqHA+hn-gP#=dmm68(q0)L|W(XTfHxaEH{|zs6tK)f3 z=~$qv7oYm@dd@<${DZM2#p7qG+@ot>JhqWGf44egNL|rJ72a^%pIC@fS>TP3cLxr= z$C1IG=;z8wXx$KP304j~`%n74^&)NMg_D6C`J)-ab%peyL_hDi5qTDT;*DT1`TY7< zw9zAtQ2IWjpUeVYlMfiLw)LOXKW8$7%I{OOZjQ{4gl_Q{;c<`d`wb5n#$9qe{xliK;K-l6l(+EvU9x#k@g(}WXEIv1-Ugfe zv-jh9%4+Sv6Vn>f+`SzkM6^%i23A%nbvbW&sOC3IacQ

T5k{=_xVnxLdAubY6yi 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 literal 0 HcmV?d00001 diff --git a/acs-uns-ingester/example.env b/ingesters/sparkplug/example.env similarity index 100% rename from acs-uns-ingester/example.env rename to ingesters/sparkplug/example.env diff --git a/acs-uns-ingester/lib/mqttclient.js b/ingesters/sparkplug/lib/mqttclient.js similarity index 100% rename from acs-uns-ingester/lib/mqttclient.js rename to ingesters/sparkplug/lib/mqttclient.js diff --git a/acs-uns-ingester/lib/mqttclient.ts b/ingesters/sparkplug/lib/mqttclient.ts similarity index 100% rename from acs-uns-ingester/lib/mqttclient.ts rename to ingesters/sparkplug/lib/mqttclient.ts diff --git a/acs-uns-ingester/package.json b/ingesters/sparkplug/package.json similarity index 88% rename from acs-uns-ingester/package.json rename to ingesters/sparkplug/package.json index 7c32517e..66acf63d 100644 --- a/acs-uns-ingester/package.json +++ b/ingesters/sparkplug/package.json @@ -1,5 +1,5 @@ { - "name": "acs-uns-ingester", + "name": "sparkplug-ingester", "version": "1.0.0", "description": "An ingestion engine to enable InfluxDB to be a fully-featured Sparkplug historian", "author": "AMRC", @@ -25,8 +25,6 @@ }, "dependencies": { "@amrc-factoryplus/utilities": "^1.0.8", - "@influxdata/influxdb-client": "^1.33.2", - "@influxdata/influxdb-client-apis": "^1.33.2", "async": "^3.2.4", "long": "^5.2.3", "mqtt": "^5.7.3", diff --git a/acs-uns-ingester/run-dev.sh b/ingesters/sparkplug/run-dev.sh similarity index 100% rename from acs-uns-ingester/run-dev.sh rename to ingesters/sparkplug/run-dev.sh diff --git a/acs-uns-ingester/tsconfig.json b/ingesters/sparkplug/tsconfig.json similarity index 100% rename from acs-uns-ingester/tsconfig.json rename to ingesters/sparkplug/tsconfig.json From fd07d985acf441da44ac8384624d40bd16ed978d Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Mon, 15 Jul 2024 09:03:06 +0100 Subject: [PATCH 08/58] sparkplug-ingester: Remove references to InfluxDB --- ingesters/sparkplug/lib/mqttclient.ts | 62 --------------------------- 1 file changed, 62 deletions(-) diff --git a/ingesters/sparkplug/lib/mqttclient.ts b/ingesters/sparkplug/lib/mqttclient.ts index 5ed0b0b7..2612a9de 100644 --- a/ingesters/sparkplug/lib/mqttclient.ts +++ b/ingesters/sparkplug/lib/mqttclient.ts @@ -7,8 +7,6 @@ import {ServiceClient, SpB, Topic, UUIDs} from "@amrc-factoryplus/utilities"; import {Reader} from "protobufjs"; import {logger} from "../bin/ingester.js"; import Long from "long"; -import {InfluxDB, Point} from '@influxdata/influxdb-client' -import {Agent} from 'http' import * as mqtt_dev from "mqtt"; @@ -29,71 +27,11 @@ try { dotenv?.config() -/* -const influxURL: string = process.env.INFLUX_URL; -if (!influxURL) { - throw new Error("INFLUX_URL environment variable is not set"); -} - -const influxToken: string = process.env.INFLUX_TOKEN -if (!influxToken) { - throw new Error("INFLUX_TOKEN environment variable is not set"); -} - -const influxOrganisation: string = process.env.INFLUX_ORG -if (!influxOrganisation) { - throw new Error("INFLUX_ORG environment variable is not set"); -} - -const batchSize: number = Number.parseInt(process.env.BATCH_SIZE); -if (!batchSize) { - throw new Error("BATCH_SIZE environment variable is not set"); -} - -const flushInterval: number = Number.parseInt(process.env.FLUSH_INTERVAL); -if (!flushInterval) { - throw new Error("FLUSH_INTERVAL environment variable is not set"); -} -*/ const unsMqttUrl: string = process.env.UNS_MQTT_URL; if (!unsMqttUrl) { throw new Error("UNS_MQTT_URL environment variable is not set"); } -/* -let i = 0; - -// Node.js HTTP client OOTB does not reuse established TCP connections, a custom node HTTP agent -// can be used to reuse them and thus reduce the count of newly established networking sockets -const keepAliveAgent = new Agent({ - keepAlive: true, // reuse existing connections - keepAliveMsecs: 20 * 1000, // 20 seconds keep alive -}) - -const influxDB = new InfluxDB({ - url: influxURL, token: influxToken, transportOptions: { - agent: keepAliveAgent, - } -}) - -let interval: any; - -/* points/lines are batched in order to minimize networking and increase performance */ - -/* -const writeApi = influxDB.getWriteApi(influxOrganisation, process.env.INFLUX_BUCKET || 'default', 'ns', { - // the maximum points/lines to send in a single batch to InfluxDB server - batchSize: batchSize + 1, // don't let automatically flush data - // maximum time in millis to keep points in an unflushed batch, 0 means don't periodically flush - flushInterval: 0, // Never allow the package to flush: we'll flush manually - // maximum size of the retry buffer - it contains items that could not be sent for the first time - maxBufferLines: 30_000, // the count of internally-scheduled retries upon write failure, the delays between write attempts follow an exponential backoff strategy if there is no Retry-After HTTP header - maxRetries: 0, // do not retry writes - // ... there are more write options that can be customized, see - // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeoptions.html and - // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeretryoptions.html -}); -*/ interface MQTTClientConstructorParams { e: { serviceClient: ServiceClient; From 66f55a12b2321e915e7dfa1a80d0f11fa5fe00f4 Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Mon, 15 Jul 2024 09:03:42 +0100 Subject: [PATCH 09/58] sparkplug-ingester: Rename local_mqtt --- ingesters/sparkplug/lib/mqttclient.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ingesters/sparkplug/lib/mqttclient.ts b/ingesters/sparkplug/lib/mqttclient.ts index 2612a9de..2c74fddc 100644 --- a/ingesters/sparkplug/lib/mqttclient.ts +++ b/ingesters/sparkplug/lib/mqttclient.ts @@ -43,19 +43,19 @@ export default class MQTTClient { private mqtt: any; private aliasResolver = {}; private birthDebounce = {}; - private local_mqtt: any; + private unsBroker: any; constructor({e}: MQTTClientConstructorParams) { this.serviceClient = e.serviceClient; } async run() { - this.local_mqtt = mqtt_dev.connect(unsMqttUrl); - this.local_mqtt.on("connect", () => { + this.unsBroker = mqtt_dev.connect(unsMqttUrl); + this.unsBroker.on("connect", () => { logger.info("✔ Connected to local mqtt broker!"); }); - this.local_mqtt.on("error", (error) => { + this.unsBroker.on("error", (error) => { logger.error(`🔥 Error from broker: ${error}`); }) const mqtt = await this.serviceClient.mqtt_client(); @@ -381,10 +381,10 @@ export default class MQTTClient { sortedMetrics.forEach(metric => { payload.batch.push({timestamp: metric.timestamp, value: metric.value}); }); - this.local_mqtt.publish(key, payload); + this.unsBroker.publish(key, payload); } else { const payload: UnsMetric = {timestamp: new Date(value[0].timestamp), value: value[0].value}; - this.local_mqtt.publish(key, payload); + this.unsBroker.publish(key, payload); } }) } From 2660d688ff41e1457472ef520f5fb194ceb9e52e Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Mon, 15 Jul 2024 09:06:39 +0100 Subject: [PATCH 10/58] sparkplug-ingester: Rename sparkplug MQTT client --- ingesters/sparkplug/lib/mqttclient.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/ingesters/sparkplug/lib/mqttclient.ts b/ingesters/sparkplug/lib/mqttclient.ts index 2c74fddc..bc85c370 100644 --- a/ingesters/sparkplug/lib/mqttclient.ts +++ b/ingesters/sparkplug/lib/mqttclient.ts @@ -8,7 +8,7 @@ import {Reader} from "protobufjs"; import {logger} from "../bin/ingester.js"; import Long from "long"; -import * as mqtt_dev from "mqtt"; +import * as mqttjs from "mqtt"; interface UnsMetric { value: string, @@ -40,17 +40,17 @@ interface MQTTClientConstructorParams { export default class MQTTClient { private serviceClient: ServiceClient; - private mqtt: any; private aliasResolver = {}; private birthDebounce = {}; private unsBroker: any; + private sparkplugBroker: any; constructor({e}: MQTTClientConstructorParams) { this.serviceClient = e.serviceClient; } async run() { - this.unsBroker = mqtt_dev.connect(unsMqttUrl); + this.unsBroker = mqttjs.connect(unsMqttUrl); this.unsBroker.on("connect", () => { logger.info("✔ Connected to local mqtt broker!"); }); @@ -58,14 +58,14 @@ export default class MQTTClient { this.unsBroker.on("error", (error) => { logger.error(`🔥 Error from broker: ${error}`); }) - const mqtt = await this.serviceClient.mqtt_client(); - this.mqtt = mqtt; + const sparkplugBroker = await this.serviceClient.mqtt_client(); + this.sparkplugBroker = sparkplugBroker; - mqtt.on("authenticated", this.on_connect.bind(this)); - mqtt.on("error", this.on_error.bind(this)); - mqtt.on("message", this.on_message.bind(this)); - mqtt.on("close", this.on_close.bind(this)); - mqtt.on("reconnect", this.on_reconnect.bind(this)); + sparkplugBroker.on("authenticated", this.on_connect.bind(this)); + sparkplugBroker.on("error", this.on_error.bind(this)); + sparkplugBroker.on("message", this.on_message.bind(this)); + sparkplugBroker.on("close", this.on_close.bind(this)); + sparkplugBroker.on("reconnect", this.on_reconnect.bind(this)); logger.info("Connecting to Factory+ broker..."); } @@ -73,7 +73,7 @@ export default class MQTTClient { on_connect() { logger.info("🔌 Connected to Factory+ broker"); logger.info("👂 Subscribing to entire Factory+ namespace"); - this.mqtt.subscribe('spBv1.0/#'); + this.sparkplugBroker.subscribe('spBv1.0/#'); } on_close() { From 40f3daaaa0f8267f11eccd30426f4d489290b4fe Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Mon, 15 Jul 2024 10:36:28 +0100 Subject: [PATCH 11/58] sparkplug-ingester: Move from Bun to NPM Bun does not support Node-API for GSSAPI.js --- ingesters/sparkplug/bun.lockb | Bin 128108 -> 0 bytes ingesters/sparkplug/package-lock.json | 2800 +++++++++++++++++++++++++ ingesters/sparkplug/package.json | 1 + 3 files changed, 2801 insertions(+) delete mode 100755 ingesters/sparkplug/bun.lockb create mode 100644 ingesters/sparkplug/package-lock.json diff --git a/ingesters/sparkplug/bun.lockb b/ingesters/sparkplug/bun.lockb deleted file mode 100755 index e7d28b4bcd2760292766dda37d1228edfa37298a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 128108 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¥obwo;gYi4|u8{Yxb2gW~D@LOTJy&yPKc!&Bn}kG$$U;Nz#=bEz3A7yMv1+ z%JYEvz>Xut-zgj*@=mTD?rImWo2wQap`D}R*mq=nnbMlMVCePOT zdfv9LVZUQ{G*e-L=Zjq#;#d70eazeA+0N$?;yp;@?F>7;X>j2>i?Xl|)s&(SLNTei zhJ(j=-nz4E*!JtRoU52vlhk!x)oDK|W0}v56)~3+oy@5@RjBxQco+^JmM5Nn4-t72 zIwB@36feezExyM=U)CR7U2}Q;-C=>Gf_V`ppEW7<=oTDNXLS24E-^=H*LK2_xnd~b6jvdWaI@|ctC z3Gp5w@_xB8z@!%MJ|BsyhgK~;hVE%v$T$=TyM>+ zIv;tl*W5*Ro&2&Bm#-`9s=eP)*KHDFsubSb&2Y*r{7}Nw5}8xZ(u8;;h`f=PRwn3f zQ1K~PlKCoKV)rQZX!of+UZ;_$h4Nh7A2`Qkg@QYj#XgSQvGRGe&XRd+)z0PbEW1{w zRw`(^RCwt75_lttyw0vG*&6Pha=2bkGW&S)Q)ZKR2k)-KP0y)5*os~VK0Ufg)|%yp zYGC3`rk)OtH-Y=ucdba;U>M?Xbx|naN;64g0&f(Ncd2dsYAdgL^; zI^Y#sboYtfzRUJE)ZCbP&rJ#m?;U&9%#pA2uGi4iFS+$djA&Et(t__#0@XJXc%zBD zw>esmv6=)HOfjfF{jtVe+bmGu;d!)J*ZGY*G>-<^w3WR7Qugj{rvJC$#e!Q77GGw4 z?8PA%`?Fii)az2r$rGQ3n1<$Y}-YdBe#Iaj&R zPJ_y}LZ+siGp7iF%Uw01S|wtOHPzrJ~{(#1a425CJhQoR=Qt0qr+wI2 z_H^}4N7K#=T}xVGX57$hbh*alMD83DLcFm=-py)eta}!_ykr*+KAB~{VbcdiFRp#> zxx=^Q2vf=R1ch!QJuqjDS*o@7`V)Q5du#S>ekWL0lxH3hoH%G0KP6>I;QfE>y#-tr z-P`X=N=YLip&%hjw}6C5E25-GcSx5YsVJd{5`vUSE8Qt2A(GOflr#bo7NEkp2Ibwe z&;CDqe?EJk&pH41J*?;XI&-gU)^FBav+AC?S?dv6*NI_1iBu&lK6m!%*_1=cHYtfkD2AgnhNrf zzBg}HG@o*MzhN>bEqvX_qypooz4dIS1*{EyMP15Z_6usV{nY#UVe*m!#!&kpRyFX0xHczvg zY_axjcH7&Uiz}m&6uDKQa*r$PNeKkyX%s$)TT;rhmZ9<+gVwe9CGIesE%=ViAn6>l z*)zdTxrX)uy0H5j?qw6xb!QfcjXanu1>I@SFb#~3UDC}Qm#!`Jsi~xPe_vnnU27iw z{vsBwYd>~>sh%g)m{RaXm6evO5Hlx>=M=rfO$N)eV(M5W4+vxnUSm{zXzR1glE=0^ zM>`dD*m{hpBcA;iqZZ3<5&FI96SS_c_5i#%{-GcEGUH@!(4%OVfUB8e-fE-?60!wE z!LxTSZzV5|jh*Z;-`oh#e~CfEaQCEdI^!|rB9qeN6*|G_b}|mFTjcOVBK_so8S%wA zu?0T!FENjLgb7IATkBsoCM#i_+3ibx%T)caEF!R4VUEd&>*-dL6g{=SW-RPZ7^}jN0@_j+4T}fDP@KFxvwhDGZ&}7Y*TkGzNjI@_|De%a3%BH1(a?AT6dl1w^>&gE=^c6BNGkZS=P`;7@XV$ccU|P zUJw^JXTIbsx5lwJ=N7zK)xsqHA+hn-gP#=dmm68(q0)L|W(XTfHxaEH{|zs6tK)f3 z=~$qv7oYm@dd@<${DZM2#p7qG+@ot>JhqWGf44egNL|rJ72a^%pIC@fS>TP3cLxr= z$C1IG=;z8wXx$KP304j~`%n74^&)NMg_D6C`J)-ab%peyL_hDi5qTDT;*DT1`TY7< zw9zAtQ2IWjpUeVYlMfiLw)LOXKW8$7%I{OOZjQ{4gl_Q{;c<`d`wb5n#$9qe{xliK;K-l6l(+EvU9x#k@g(}WXEIv1-Ugfe zv-jh9%4+Sv6Vn>f+`SzkM6^%i23A%nbvbW&sOC3IacQ

T5k{=_xVnxLdAubY6yi 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 diff --git a/ingesters/sparkplug/package-lock.json b/ingesters/sparkplug/package-lock.json new file mode 100644 index 00000000..a7ecf9d2 --- /dev/null +++ b/ingesters/sparkplug/package-lock.json @@ -0,0 +1,2800 @@ +{ + "name": "sparkplug-ingester", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "sparkplug-ingester", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@amrc-factoryplus/service-client": "^1.3.6", + "async": "^3.2.4", + "gssapi.js": "^2.0.1", + "long": "^5.2.3", + "mqtt": "^5.7.3", + "pino": "^8.11.0", + "pino-pretty": "^10.0.0" + }, + "devDependencies": { + "cross-env": "^7.0.3", + "dotenv": "^16.0.3", + "ts-node": "^10.9.1", + "tsc-alias": "^1.7.0" + } + }, + "node_modules/@amrc-factoryplus/service-client": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@amrc-factoryplus/service-client/-/service-client-1.3.6.tgz", + "integrity": "sha512-4t+/SDJwoqdY+5D2DIiF/xnB2RGjG3IIzy7qxewHVCBIJ8Q2CUEZlwt5ayts9mGmM/LHsQw9NHKes664tPqyYQ==", + "dependencies": { + "content-type": "^1.0.5", + "mqtt": "^5.3.6", + "optional-js": "^2.3.0", + "semver": "^7.6.0", + "sparkplug-payload": "^1.0.3" + }, + "optionalDependencies": { + "got-fetch": "^5.1.8", + "gssapi.js": "^2.0.1" + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", + "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "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": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "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_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/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "node_modules/@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "optional": true, + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "optional": true, + "peer": true, + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "optional": true, + "peer": true + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, + "node_modules/@types/node": { + "version": "20.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", + "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/readable-stream": { + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.15.tgz", + "integrity": "sha512-oAZ3kw+kJFkEqyh7xORZOku1YAKvsFTogRY8kVl4vHpEKiDkfnSA/My8haRE7fvmix5Zyy+1pwzOi7yycGLBJw==", + "dependencies": { + "@types/node": "*", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/@types/ws": { + "version": "8.5.11", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.11.tgz", + "integrity": "sha512-4+q7P5h3SpJxaBft0Dzpbr6lmMaqh0Jr2tbhJZ/luAwvD7ohSCniYkwz/pLxuT2h0EOa6QADgJj1Ko+TzRfZ+w==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", + "integrity": "sha512-iFY7JCgHbepc0b82yLaw4IMortylNb6wG4kL+4R0C3iv6i+RHGHux/yUX5BTiRvSX/shMnngjR1YyNMnXEFh5A==" + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/are-we-there-yet": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.0.6.tgz", + "integrity": "sha512-Zfw6bteqM9gQXZ1BIWOgM8xEwMrUGoyL8nW13+O+OOgNX3YhuDN1GDgg1NzdTlmm3j+9sHy7uBZ12r+z9lXnZQ==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.0 || ^1.1.13" + } + }, + "node_modules/are-we-there-yet/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "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/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/bl/-/bl-6.0.14.tgz", + "integrity": "sha512-TJfbvGdL7KFGxTsEbsED7avqpFdY56q9IW0/aiytyheJzxST/+Io6cx/4Qx0K2/u0BPRDs65mjaQzYvMZeNocQ==", + "dependencies": { + "@types/readable-stream": "^4.0.0", + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^4.2.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/bl/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bl/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g==" + }, + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", + "engines": { + "node": ">=0.2.0" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "optional": true, + "peer": true, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "optional": true, + "peer": true, + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", + "dependencies": { + "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/cmake-js": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/cmake-js/-/cmake-js-6.3.2.tgz", + "integrity": "sha512-7MfiQ/ijzeE2kO+WFB9bv4QP5Dn2yVaAP2acFJr4NIFy2hT4w6O4EpOTLNcohR5IPX7M4wNf/5taIqMj7UA9ug==", + "dependencies": { + "axios": "^0.21.1", + "bluebird": "^3", + "debug": "^4", + "fs-extra": "^5.0.0", + "is-iojs": "^1.0.1", + "lodash": "^4", + "memory-stream": "0", + "npmlog": "^1.2.0", + "rc": "^1.2.7", + "semver": "^5.0.3", + "splitargs": "0", + "tar": "^4", + "unzipper": "^0.8.13", + "url-join": "0", + "which": "^1.0.9", + "yargs": "^3.6.0" + }, + "bin": { + "cmake-js": "bin/cmake-js" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/cmake-js/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/cmake-js/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" + }, + "node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/commist": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz", + "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "optional": true, + "peer": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-copy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz", + "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-redact": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + }, + "node_modules/fast-unique-numbers": { + "version": "8.0.13", + "resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-8.0.13.tgz", + "integrity": "sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g==", + "dependencies": { + "@babel/runtime": "^7.23.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.1.0" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/fs-extra": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", + "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/gauge": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", + "integrity": "sha512-fVbU2wRE91yDvKUnrIaQlHKAWKY5e08PmztCrwuH5YVQ+Z/p3d0ny2T48o6uvAAXHIUnfaQdHkmxYbQft1eHVA==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "ansi": "^0.3.0", + "has-unicode": "^2.0.0", + "lodash.pad": "^4.1.0", + "lodash.padend": "^4.1.0", + "lodash.padstart": "^4.1.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "optional": true, + "peer": true, + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got-fetch": { + "version": "5.1.10", + "resolved": "https://registry.npmjs.org/got-fetch/-/got-fetch-5.1.10.tgz", + "integrity": "sha512-Gwj/A2htjvLEcY07PKDItv0WCPEs3dV2vWeZ+9TVBSKSTuWEZ4oXaMD0ZAOsajwx2orahQWN4HI0MfRyWSZsbg==", + "optional": true, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "got": "^12.0.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/gssapi.js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gssapi.js/-/gssapi.js-2.0.1.tgz", + "integrity": "sha512-5D+qylV8uIKMaxTTKhpzvfGRz5+okr/rpwC6YlaCoDVBpvkuNgL8pM7+r7aTzZ2oT5dA4w2WoZTV82opGj+RZQ==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.5.0", + "cmake-js": "^6.1.0", + "node-addon-api": "^1.7.2" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, + "node_modules/help-me": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==" + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "optional": true, + "peer": true + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "optional": true, + "peer": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-iojs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-iojs/-/is-iojs-1.1.0.tgz", + "integrity": "sha512-tLn1j3wYSL6DkvEI+V/j0pKohpa5jk+ER74v6S4SgCXnjS0WA+DoZbwZBrrhgwksMvtuwndyGeG5F8YMsoBzSA==" + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "optional": true, + "peer": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "optional": true, + "peer": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==" + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.pad": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", + "integrity": "sha512-mvUHifnLqM+03YNzeTBS1/Gr6JRFjd3rRx88FHWUvamVaT9k2O/kXha3yBSOwB9/DTQrSTLJNHvLBBt2FdX7Mg==" + }, + "node_modules/lodash.padend": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "integrity": "sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw==" + }, + "node_modules/lodash.padstart": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", + "integrity": "sha512-sW73O6S8+Tg66eY56DBk85aQzzUJDtpoXFBgELMd5P/SotAguo+1kYO6RuYgXxA4HJH3LFTFPASX6ET6bjfriw==" + }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/memory-stream": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/memory-stream/-/memory-stream-0.0.3.tgz", + "integrity": "sha512-q0D3m846qY6ZkIt+19ZemU5vH56lpOZZwoJc3AICARKh/menBuayQUjAGPrqtHQQMUYERSdOrej92J9kz7LgYA==", + "dependencies": { + "readable-stream": "~1.0.26-2" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mqtt": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.8.0.tgz", + "integrity": "sha512-/+H04mv6goy6K5gHMNH3uS0icBzXapS+4uUf4yZyQWXi72APPZNb81bQhvkm99poEQettXVT8XETB0mPxl5Wjg==", + "dependencies": { + "@types/readable-stream": "^4.0.5", + "@types/ws": "^8.5.9", + "commist": "^3.2.0", + "concat-stream": "^2.0.0", + "debug": "^4.3.4", + "help-me": "^5.0.0", + "lru-cache": "^10.0.1", + "minimist": "^1.2.8", + "mqtt": "^5.2.0", + "mqtt-packet": "^9.0.0", + "number-allocator": "^1.0.14", + "readable-stream": "^4.4.2", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^4.2.0", + "worker-timers": "^7.1.4", + "ws": "^8.17.1" + }, + "bin": { + "mqtt": "build/bin/mqtt.js", + "mqtt_pub": "build/bin/pub.js", + "mqtt_sub": "build/bin/sub.js" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/mqtt-packet": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-9.0.0.tgz", + "integrity": "sha512-8v+HkX+fwbodsWAZIZTI074XIoxVBOmPeggQuDFCGg1SqNcC+uoRMWu7J6QlJPqIUIJXmjNYYHxBBLr1Y/Df4w==", + "dependencies": { + "bl": "^6.0.8", + "debug": "^4.3.4", + "process-nextick-args": "^2.0.1" + } + }, + "node_modules/mqtt/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/mqtt/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/mqtt/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "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==" + }, + "node_modules/mylas": { + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/mylas/-/mylas-2.1.13.tgz", + "integrity": "sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/raouldeheer" + } + }, + "node_modules/node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", + "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", + "optional": true, + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npmlog": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-1.2.1.tgz", + "integrity": "sha512-1J5KqSRvESP6XbjPaXt2H6qDzgizLTM7x0y1cXIjP2PpvdCqyNC7TO3cPRKsuYlElbi/DwkzRRdG2zpmE0IktQ==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "ansi": "~0.3.0", + "are-we-there-yet": "~1.0.0", + "gauge": "~1.2.0" + } + }, + "node_modules/number-allocator": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz", + "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==", + "dependencies": { + "debug": "^4.3.1", + "js-sdsl": "4.3.0" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optional-js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/optional-js/-/optional-js-2.3.0.tgz", + "integrity": "sha512-B0LLi+Vg+eko++0z/b8zIv57kp7HKEzaPJo7LowJXMUKYdf+3XJGu/cw03h/JhIOsLnP+cG5QnTHAuicjA5fMw==" + }, + "node_modules/os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", + "dependencies": { + "lcid": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "optional": true, + "peer": true, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pino": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.21.0.tgz", + "integrity": "sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q==", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.2.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^3.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.7.0", + "thread-stream": "^2.6.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", + "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/pino-abstract-transport/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/pino-pretty": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.3.1.tgz", + "integrity": "sha512-az8JbIYeN/1iLj2t0jR9DV48/LQ3RC6hZPpapKPkb84Q+yTidMCpgWxIT3N0flnBDilyBQ1luWNpOeJptjdp/g==", + "dependencies": { + "colorette": "^2.0.7", + "dateformat": "^4.6.3", + "fast-copy": "^3.0.0", + "fast-safe-stringify": "^2.1.1", + "help-me": "^5.0.0", + "joycon": "^3.1.1", + "minimist": "^1.2.6", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.0.0", + "pump": "^3.0.0", + "readable-stream": "^4.0.0", + "secure-json-parse": "^2.4.0", + "sonic-boom": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "pino-pretty": "bin.js" + } + }, + "node_modules/pino-pretty/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-pretty/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/pino-pretty/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", + "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==" + }, + "node_modules/plimit-lit": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/plimit-lit/-/plimit-lit-1.6.1.tgz", + "integrity": "sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==", + "dev": true, + "dependencies": { + "queue-lit": "^1.5.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/process-warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==" + }, + "node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/protobufjs/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/queue-lit": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-1.5.2.tgz", + "integrity": "sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "optional": true, + "peer": true + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "optional": true, + "peer": true, + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" + }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sonic-boom": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.1.tgz", + "integrity": "sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/sparkplug-payload": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sparkplug-payload/-/sparkplug-payload-1.0.3.tgz", + "integrity": "sha512-JAQSyuHVQQe/LzIlJdcIaD1F1c+rbXoolII3H1whQkhuZ96+G53RoPWqP9zCPZYFjvfSMHnQNIedGIZw/zjHJw==", + "dependencies": { + "@types/long": "^4.0.0", + "long": "^4.0.0", + "protobufjs": "^6.11.3" + } + }, + "node_modules/sparkplug-payload/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/splitargs": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/splitargs/-/splitargs-0.0.7.tgz", + "integrity": "sha512-UUFYD2oWbNwULH6WoVtLUOw8ch586B+HUqcsAjjjeoBQAM1bD4wZRXu01koaxyd8UeYpybWqW4h+lO1Okv40Tg==" + }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "dependencies": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/tar/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/thread-stream": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.7.0.tgz", + "integrity": "sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==", + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", + "engines": { + "node": "*" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tsc-alias": { + "version": "1.8.10", + "resolved": "https://registry.npmjs.org/tsc-alias/-/tsc-alias-1.8.10.tgz", + "integrity": "sha512-Ibv4KAWfFkFdKJxnWfVtdOmB0Zi1RJVxcbPGiCDsFpCQSsmpWyuzHG3rQyI5YkobWwxFPEyQfu1hdo4qLG2zPw==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.3", + "commander": "^9.0.0", + "globby": "^11.0.4", + "mylas": "^2.1.9", + "normalize-path": "^3.0.0", + "plimit-lit": "^1.2.6" + }, + "bin": { + "tsc-alias": "dist/bin/index.js" + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "node_modules/typescript": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unzipper": { + "version": "0.8.14", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.8.14.tgz", + "integrity": "sha512-8rFtE7EP5ssOwGpN2dt1Q4njl0N1hUXJ7sSPz0leU2hRdq6+pra57z4YPBlVqm40vcgv6ooKZEAx48fMTv9x4w==", + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "~1.0.10", + "listenercount": "~1.0.1", + "readable-stream": "~2.1.5", + "setimmediate": "~1.0.4" + } + }, + "node_modules/unzipper/node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==" + }, + "node_modules/unzipper/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/unzipper/node_modules/process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==" + }, + "node_modules/unzipper/node_modules/readable-stream": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", + "integrity": "sha512-NkXT2AER7VKXeXtJNSaWLpWIhmtSE3K2PguaLEeWr4JILghcIKqoLt1A3wHrnpDC5+ekf8gfk1GKWkFXe4odMw==", + "dependencies": { + "buffer-shims": "^1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/url-join": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz", + "integrity": "sha512-H6dnQ/yPAAVzMQRvEvyz01hhfQL5qRWSEt7BX8t9DqnPw9BjMb64fjIRq76Uvf1hkHp+mTZvEVJ5guXOT0Xqaw==" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/window-size": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "integrity": "sha512-2thx4pB0cV3h+Bw7QmMXcEbdmOzv9t0HFplJH/Lz6yu60hXYy5RT8rUu+wlIreVxWsGN20mo+MHeCSfUpQBwPw==", + "bin": { + "window-size": "cli.js" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/worker-timers": { + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-7.1.8.tgz", + "integrity": "sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw==", + "dependencies": { + "@babel/runtime": "^7.24.5", + "tslib": "^2.6.2", + "worker-timers-broker": "^6.1.8", + "worker-timers-worker": "^7.0.71" + } + }, + "node_modules/worker-timers-broker": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-6.1.8.tgz", + "integrity": "sha512-FUCJu9jlK3A8WqLTKXM9E6kAmI/dR1vAJ8dHYLMisLNB/n3GuaFIjJ7pn16ZcD1zCOf7P6H62lWIEBi+yz/zQQ==", + "dependencies": { + "@babel/runtime": "^7.24.5", + "fast-unique-numbers": "^8.0.13", + "tslib": "^2.6.2", + "worker-timers-worker": "^7.0.71" + } + }, + "node_modules/worker-timers-worker": { + "version": "7.0.71", + "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-7.0.71.tgz", + "integrity": "sha512-ks/5YKwZsto1c2vmljroppOKCivB/ma97g9y77MAAz2TBBjPPgpoOiS1qYQKIgvGTr2QYPT3XhJWIB6Rj2MVPQ==", + "dependencies": { + "@babel/runtime": "^7.24.5", + "tslib": "^2.6.2" + } + }, + "node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==" + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/yargs": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "integrity": "sha512-ONJZiimStfZzhKamYvR/xvmgW3uEkAUFSP91y2caTEPhzF6uP2JfPiVZcq66b/YR0C3uitxSV7+T1x8p5bkmMg==", + "dependencies": { + "camelcase": "^2.0.1", + "cliui": "^3.0.3", + "decamelize": "^1.1.1", + "os-locale": "^1.4.0", + "string-width": "^1.0.1", + "window-size": "^0.1.4", + "y18n": "^3.2.0" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + } +} diff --git a/ingesters/sparkplug/package.json b/ingesters/sparkplug/package.json index 66acf63d..f0a4edb7 100644 --- a/ingesters/sparkplug/package.json +++ b/ingesters/sparkplug/package.json @@ -26,6 +26,7 @@ "dependencies": { "@amrc-factoryplus/utilities": "^1.0.8", "async": "^3.2.4", + "gssapi.js": "^2.0.1", "long": "^5.2.3", "mqtt": "^5.7.3", "pino": "^8.11.0", From 2b120980867a20c689018057162945401554f251 Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Mon, 15 Jul 2024 10:36:48 +0100 Subject: [PATCH 12/58] sparkplug-ingester: Add example .env file A new .env.example file has been added to the ingesters/sparkplug directory. This example file contains placeholder environment variables necessary for the function of the Sparkplug Ingester. --- ingesters/sparkplug/.env.example | 4 ++++ ingesters/sparkplug/example.env | 10 ---------- 2 files changed, 4 insertions(+), 10 deletions(-) create mode 100644 ingesters/sparkplug/.env.example delete mode 100644 ingesters/sparkplug/example.env diff --git a/ingesters/sparkplug/.env.example b/ingesters/sparkplug/.env.example new file mode 100644 index 00000000..1a3e236e --- /dev/null +++ b/ingesters/sparkplug/.env.example @@ -0,0 +1,4 @@ +DIRECTORY_URL=https://directory.domain.co.uk +UNS_MQTT_URL=mqtt://localhost:1883 +LOG_LEVEL=debug +CMD_ESC_URL=https://cmdesc.domain.co.uk diff --git a/ingesters/sparkplug/example.env b/ingesters/sparkplug/example.env deleted file mode 100644 index 139296ff..00000000 --- a/ingesters/sparkplug/example.env +++ /dev/null @@ -1,10 +0,0 @@ -DIRECTORY_URL=https://directory.domain.co.uk -INFLUX_URL=http://influx.domain.co.uk -INFLUX_TOKEN=XXXXXX -UNS_MQTT_URL=mqtt://mqtt.domain.co.uk -INFLUX_ORG=default -INFLUX_BUCKET=default -LOG_LEVEL=info -BATCH_SIZE=5000 -FLUSH_INTERVAL=10000 -CMD_ESC_URL=https://cmdesc.domain.co.uk \ No newline at end of file From 6fab6c57bcd1404aec56523faae7481c0b959950 Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Mon, 15 Jul 2024 10:37:37 +0100 Subject: [PATCH 13/58] sparkplug-ingester: Move to @amrc-factoryplus/service-client The import statements in ingester.ts and mqttclient.ts have been changed to import ServiceClient and UUIDs from "@amrc-factoryplus/service-client" instead of "@amrc-factoryplus/utilities". The dependence in package.json was also updated accordingly. Additionally, the environment variable 'env' is now being used in ServiceClient's initialization. --- ingesters/sparkplug/bin/ingester.ts | 4 ++-- ingesters/sparkplug/lib/mqttclient.ts | 2 +- ingesters/sparkplug/package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ingesters/sparkplug/bin/ingester.ts b/ingesters/sparkplug/bin/ingester.ts index 624a8b52..6d3bc7dd 100644 --- a/ingesters/sparkplug/bin/ingester.ts +++ b/ingesters/sparkplug/bin/ingester.ts @@ -3,7 +3,7 @@ * Copyright "2023" AMRC */ -import {ServiceClient, UUIDs} from "@amrc-factoryplus/utilities"; +import {ServiceClient, UUIDs} from "@amrc-factoryplus/service-client"; import pino from "pino"; import pretty from 'pino-pretty'; import MQTTClient from "@lib/mqttclient.js"; @@ -32,7 +32,7 @@ export const logger = pino({ const client = await new ServiceClient({ - directory_url: directoryUrl, + env: process.env }).init(); // Overwrite MQTT server if specified in environment diff --git a/ingesters/sparkplug/lib/mqttclient.ts b/ingesters/sparkplug/lib/mqttclient.ts index bc85c370..efa3d67b 100644 --- a/ingesters/sparkplug/lib/mqttclient.ts +++ b/ingesters/sparkplug/lib/mqttclient.ts @@ -3,7 +3,7 @@ * Copyright "2024" AMRC */ -import {ServiceClient, SpB, Topic, UUIDs} from "@amrc-factoryplus/utilities"; +import {ServiceClient, SpB, Topic, UUIDs} from "@amrc-factoryplus/service-client"; import {Reader} from "protobufjs"; import {logger} from "../bin/ingester.js"; import Long from "long"; diff --git a/ingesters/sparkplug/package.json b/ingesters/sparkplug/package.json index f0a4edb7..4fdff77c 100644 --- a/ingesters/sparkplug/package.json +++ b/ingesters/sparkplug/package.json @@ -24,7 +24,7 @@ "lint:fix": "npm run lint -- --fix" }, "dependencies": { - "@amrc-factoryplus/utilities": "^1.0.8", + "@amrc-factoryplus/service-client": "^1.3.6", "async": "^3.2.4", "gssapi.js": "^2.0.1", "long": "^5.2.3", From 04c9ad7f771ff4261b6b30a0e72d52abb793c1d8 Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Mon, 15 Jul 2024 10:39:32 +0100 Subject: [PATCH 14/58] sparkplug-ingester: Clean up POC --- ingesters/sparkplug/lib/mqttclient.ts | 62 ++++++++++++++------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/ingesters/sparkplug/lib/mqttclient.ts b/ingesters/sparkplug/lib/mqttclient.ts index efa3d67b..482dce9c 100644 --- a/ingesters/sparkplug/lib/mqttclient.ts +++ b/ingesters/sparkplug/lib/mqttclient.ts @@ -61,34 +61,34 @@ export default class MQTTClient { const sparkplugBroker = await this.serviceClient.mqtt_client(); this.sparkplugBroker = sparkplugBroker; - sparkplugBroker.on("authenticated", this.on_connect.bind(this)); - sparkplugBroker.on("error", this.on_error.bind(this)); - sparkplugBroker.on("message", this.on_message.bind(this)); - sparkplugBroker.on("close", this.on_close.bind(this)); - sparkplugBroker.on("reconnect", this.on_reconnect.bind(this)); + sparkplugBroker.on("connect", this.onConnect.bind(this)); + sparkplugBroker.on("error", this.onError.bind(this)); + sparkplugBroker.on("message", this.onMessage.bind(this)); + sparkplugBroker.on("close", this.onClose.bind(this)); + sparkplugBroker.on("reconnect", this.onReconnect.bind(this)); - logger.info("Connecting to Factory+ broker..."); + logger.info("Connecting to Sparkplug channel..."); } - on_connect() { - logger.info("🔌 Connected to Factory+ broker"); + onConnect() { + logger.info("🔌 Connected to Sparkplug channel"); logger.info("👂 Subscribing to entire Factory+ namespace"); this.sparkplugBroker.subscribe('spBv1.0/#'); } - on_close() { - logger.warn(`❌ Disconnected from Factory+ broker`); + onClose() { + logger.warn(`❌ Disconnected from Sparkplug channel`); } - on_reconnect() { - logger.warn(`⚠️ Reconnecting to Factory+ broker...`); + onReconnect() { + logger.warn(`⚠️ Reconnecting to Sparkplug channel...`); } - on_error(error: any) { + onError(error: any) { logger.error("🚨 MQTT error: %o", error); } - async on_message(topicString: string, message: Uint8Array | Reader) { + async onMessage(topicString: string, message: Uint8Array | Reader) { let topic = Topic.parse(topicString); let payload; @@ -119,6 +119,8 @@ export default class MQTTClient { // If we have a Factory+ payload then process the Schema UUIDs and Instance UUIDs if (payload.uuid === UUIDs.FactoryPlus) { + // TODO: Raise alert if the payload doesn't contain the Device_Information-v1/Heirarchy-v1 schema + // Schema_UUIDs payload.metrics.forEach((metric) => { // If the name ends in Schema_UUID (e.g. Phases/1/Schema_UUID) @@ -329,18 +331,22 @@ export default class MQTTClient { */ private publishToUNS(payload, topic) { const metricsToPublish: { [metricPath: string]: any[] } = {}; + //resolve metric aliases payload.metrics.forEach((metric) => { if (metric.value === null) return; let birth = this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]?.[metric.alias]; if (!birth) { + logger.error(`❓ Metric ${metric.alias} is unknown for ${topic.address.group}/${topic.address.node}/${topic.address.device}`); return; } + // TODO: Build custom properties object + if (birth.transient) { + // TODO: Add transient to custom properties if needed logger.debug(`Metric ${birth.name} is transient, publishing to UNS`); - return; } const metricName = birth.name.split('/').pop() as string; @@ -349,14 +355,9 @@ export default class MQTTClient { return; } - let unsTopic: string; + // TODO: Get enterprise information from the Device_Information-v1/Hierarchy-v1 schema - if (path) { - // enterprise, site, area, cell, device? namespace where edge is the raw data from the device edge. - unsTopic = `AMRC/F2050/MK1/${topic.address.device}/Edge/${path}/${metricName}`; - } else { - unsTopic = `AMRC/F2050/MK1/${topic.address.device}/Edge/${metricName}`; - } + let unsTopic = `AMRC/F2050/MK1/${topic.address.device}/Edge/${path ? (path + '/') : ''}${metricName}`; if (!(unsTopic in metricsToPublish)) { metricsToPublish[unsTopic] = [metric] @@ -367,24 +368,27 @@ export default class MQTTClient { }); // format payload to publish to uns. - Object.entries(metricsToPublish).forEach(([key, value]) => { + Object.entries(metricsToPublish).forEach(([topic, value]) => { + + // TODO: Add custom properties before sending + // if theirs more than one of the same metric from the same sparkplug payload, add the values to the batch array. if (value.length > 1) { - const sortedMetrics = value.sort((a, b) => b.timestamp - a.timestamp); + const sortedMetrics = value.sort((a, b) => b.timestamp.toNumber() - a.timestamp.toNumber()); let payload: BatchedUnsMetric = { - timestamp: new Date(sortedMetrics[0].timestamp), + timestamp: new Date(sortedMetrics[0].timestamp.toNumber()), value: sortedMetrics[0].value, batch: [] } //remove the first element, that's our newest and will be the value outside the batch array. sortedMetrics.shift(); sortedMetrics.forEach(metric => { - payload.batch.push({timestamp: metric.timestamp, value: metric.value}); + payload.batch.push({timestamp: metric.timestamp.toNumber(), value: metric.value}); }); - this.unsBroker.publish(key, payload); + this.unsBroker.publish(topic, JSON.stringify(payload)); } else { - const payload: UnsMetric = {timestamp: new Date(value[0].timestamp), value: value[0].value}; - this.unsBroker.publish(key, payload); + const payload: UnsMetric = {timestamp: new Date(value[0].timestamp.toNumber()), value: value[0].value}; + this.unsBroker.publish(topic, JSON.stringify(payload)); } }) } From 098f14fa87407f968ab6efa60c643b9c59ae6aea Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Mon, 15 Jul 2024 10:45:38 +0100 Subject: [PATCH 15/58] sparkplug-ingester: Add ticket links --- ingesters/sparkplug/lib/mqttclient.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ingesters/sparkplug/lib/mqttclient.ts b/ingesters/sparkplug/lib/mqttclient.ts index 482dce9c..a010ca4a 100644 --- a/ingesters/sparkplug/lib/mqttclient.ts +++ b/ingesters/sparkplug/lib/mqttclient.ts @@ -342,7 +342,7 @@ export default class MQTTClient { return; } - // TODO: Build custom properties object + // TODO: Build custom properties object - SFIP2-57 if (birth.transient) { // TODO: Add transient to custom properties if needed @@ -355,7 +355,7 @@ export default class MQTTClient { return; } - // TODO: Get enterprise information from the Device_Information-v1/Hierarchy-v1 schema + // TODO: Get enterprise information from the Device_Information-v1/Hierarchy-v1 schema - SFIP2-58 let unsTopic = `AMRC/F2050/MK1/${topic.address.device}/Edge/${path ? (path + '/') : ''}${metricName}`; @@ -370,7 +370,7 @@ export default class MQTTClient { // format payload to publish to uns. Object.entries(metricsToPublish).forEach(([topic, value]) => { - // TODO: Add custom properties before sending + // TODO: Add custom properties before sending - SFIP2-57 // if theirs more than one of the same metric from the same sparkplug payload, add the values to the batch array. if (value.length > 1) { From 84b6bc7a9ba9b1c3630acab4453efddffebf847a Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Mon, 15 Jul 2024 11:32:21 +0100 Subject: [PATCH 16/58] sparkplug-ingester: Publish Instance_UUID and Schema_UUID as custom properties --- ingesters/sparkplug/lib/mqttclient.ts | 103 +++++++++++++++++++------- 1 file changed, 76 insertions(+), 27 deletions(-) diff --git a/ingesters/sparkplug/lib/mqttclient.ts b/ingesters/sparkplug/lib/mqttclient.ts index a010ca4a..f427abce 100644 --- a/ingesters/sparkplug/lib/mqttclient.ts +++ b/ingesters/sparkplug/lib/mqttclient.ts @@ -13,10 +13,18 @@ import * as mqttjs from "mqtt"; interface UnsMetric { value: string, timestamp: Date, + batch?: UnsMetric[] } -interface BatchedUnsMetric extends UnsMetric { - batch?: UnsMetric[] +interface UnsMetricCustomProperties { + Instance_UUID: string, + Schema_UUID: string, + Transient: boolean, +} + +interface MetricContainer { + metric: any, + customProperties: UnsMetricCustomProperties } let dotenv: any = null; @@ -50,7 +58,9 @@ export default class MQTTClient { } async run() { - this.unsBroker = mqttjs.connect(unsMqttUrl); + this.unsBroker = mqttjs.connect(unsMqttUrl, { + protocolVersion: 5, + }); this.unsBroker.on("connect", () => { logger.info("✔ Connected to local mqtt broker!"); }); @@ -330,11 +340,14 @@ export default class MQTTClient { * @param topic Topic the payload was received on. */ private publishToUNS(payload, topic) { - const metricsToPublish: { [metricPath: string]: any[] } = {}; + + const metricsToPublish: { [metricPath: string]: MetricContainer[] } = {}; //resolve metric aliases payload.metrics.forEach((metric) => { if (metric.value === null) return; + + let birth = this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]?.[metric.alias]; if (!birth) { @@ -342,54 +355,90 @@ export default class MQTTClient { return; } - // TODO: Build custom properties object - SFIP2-57 - - if (birth.transient) { - // TODO: Add transient to custom properties if needed - logger.debug(`Metric ${birth.name} is transient, publishing to UNS`); - } - const metricName = birth.name.split('/').pop() as string; const path = birth.name.substring(0, birth.name.lastIndexOf("/")) as string; if (path.includes("Device Control")) { return; } + // We don't want to publish Instance_UUID or Schema_UUID metrics + if (metricName === "Instance_UUID" || metricName === "Schema_UUID") { + return; + } + + // Build custom properties object + + let customProperties: UnsMetricCustomProperties = { + Instance_UUID: birth.instance.top, + Schema_UUID: birth.schema.top, + Transient: birth.transient, + } + // TODO: Get enterprise information from the Device_Information-v1/Hierarchy-v1 schema - SFIP2-58 let unsTopic = `AMRC/F2050/MK1/${topic.address.device}/Edge/${path ? (path + '/') : ''}${metricName}`; if (!(unsTopic in metricsToPublish)) { - metricsToPublish[unsTopic] = [metric] + metricsToPublish[unsTopic] = [{ + metric: metric, + customProperties: customProperties + }] } else { - metricsToPublish[unsTopic].push(metric); + metricsToPublish[unsTopic].push({ + metric: metric, + customProperties: customProperties + }); } }); // format payload to publish to uns. - Object.entries(metricsToPublish).forEach(([topic, value]) => { - - // TODO: Add custom properties before sending - SFIP2-57 + Object.entries(metricsToPublish).forEach(([topic, metricContainers]) => { + let payload: UnsMetric; // if theirs more than one of the same metric from the same sparkplug payload, add the values to the batch array. - if (value.length > 1) { - const sortedMetrics = value.sort((a, b) => b.timestamp.toNumber() - a.timestamp.toNumber()); - let payload: BatchedUnsMetric = { - timestamp: new Date(sortedMetrics[0].timestamp.toNumber()), - value: sortedMetrics[0].value, + if (metricContainers.length > 1) { + const sortedMetricContainers = metricContainers.sort((a, b) => b.metric.timestamp.toNumber() - a.metric.timestamp.toNumber()); + payload = { + timestamp: new Date(sortedMetricContainers[0].metric.timestamp.toNumber()), + value: sortedMetricContainers[0].metric.value, batch: [] } //remove the first element, that's our newest and will be the value outside the batch array. - sortedMetrics.shift(); - sortedMetrics.forEach(metric => { - payload.batch.push({timestamp: metric.timestamp.toNumber(), value: metric.value}); + sortedMetricContainers.shift(); + sortedMetricContainers.forEach(metricContainer => { + payload.batch.push({ + timestamp: metricContainer.metric.timestamp.toNumber(), + value: metricContainer.metric.value + }); }); - this.unsBroker.publish(topic, JSON.stringify(payload)); } else { - const payload: UnsMetric = {timestamp: new Date(value[0].timestamp.toNumber()), value: value[0].value}; - this.unsBroker.publish(topic, JSON.stringify(payload)); + payload = { + timestamp: new Date(metricContainers[0].metric.timestamp.toNumber()), + value: metricContainers[0].metric.value + }; + } + + if (!metricContainers[0]?.customProperties.Instance_UUID) { + logger.warn(`${topic} is not broadcasting an Instance_UUID. Not publishing to UNS.`); + return; + } + + if (!metricContainers[0]?.customProperties.Schema_UUID) { + logger.warn(`${topic} is not broadcasting a Schema_UUID. Not publishing to UNS.`); + return; } + + this.unsBroker.publish(topic, JSON.stringify(payload), { + properties: { + // Assume that all metrics have the same custom properties + userProperties: { + Instance_UUID: metricContainers[0]?.customProperties.Instance_UUID, + Schema_UUID: metricContainers[0].customProperties.Schema_UUID, + Transient: metricContainers[0].customProperties.Transient ?? false + } + } + }); }) } From 93dcc6bcda96368e518011e56f7426069be62469 Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Mon, 15 Jul 2024 11:36:02 +0100 Subject: [PATCH 17/58] sparkplug-ingester: Add UNS/v1 namespace --- ingesters/sparkplug/lib/mqttclient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ingesters/sparkplug/lib/mqttclient.ts b/ingesters/sparkplug/lib/mqttclient.ts index f427abce..170c55ed 100644 --- a/ingesters/sparkplug/lib/mqttclient.ts +++ b/ingesters/sparkplug/lib/mqttclient.ts @@ -376,7 +376,7 @@ export default class MQTTClient { // TODO: Get enterprise information from the Device_Information-v1/Hierarchy-v1 schema - SFIP2-58 - let unsTopic = `AMRC/F2050/MK1/${topic.address.device}/Edge/${path ? (path + '/') : ''}${metricName}`; + let unsTopic = `UNS/v1/AMRC/F2050/MK1/${topic.address.device}/Edge/${path ? (path + '/') : ''}${metricName}`; if (!(unsTopic in metricsToPublish)) { metricsToPublish[unsTopic] = [{ From 519c9fc6662c639da4b94410443aa86624bed4b7 Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Tue, 16 Jul 2024 12:12:40 +0100 Subject: [PATCH 18/58] Resolve ISA-95 hierarchy information from birth This update works out where to publish metrics based on their specified values in Device_Information-v1/Hierarchy-v1. If this doesn't exist, or it's not in the correct location it will be ignored. --- ingesters/sparkplug/lib/mqttclient.ts | 88 +++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/ingesters/sparkplug/lib/mqttclient.ts b/ingesters/sparkplug/lib/mqttclient.ts index 170c55ed..1e4b2b43 100644 --- a/ingesters/sparkplug/lib/mqttclient.ts +++ b/ingesters/sparkplug/lib/mqttclient.ts @@ -126,6 +126,12 @@ export default class MQTTClient { let topLevelInstance = null; let instanceUUIDMapping = {}; + let enterprise = null; + let site = null; + let area = null; + let workCenter = null; + let workUnit = null; + // If we have a Factory+ payload then process the Schema UUIDs and Instance UUIDs if (payload.uuid === UUIDs.FactoryPlus) { @@ -148,6 +154,25 @@ export default class MQTTClient { // will have schemaUUIDMapping[schemaPath] = metric.value; } + + // Check if this Schema_UUID is the Hierarchy-v1 schema + if (metric.value === "84ac3397-f3a2-440a-99e5-5bb9f6a75091") { + + // If the Hierarchy-v1 schema is not in Device_Information/ISA95_Hierarchy then ignore + // it - we expect it to be here + + if (!schemaPath.includes("Device_Information/ISA95_Hierarchy")) { + logger.warn(`🔎 Hierarchy-v1 schema not found in expected location for ${topic.address.group}/${topic.address.node}/${topic.address.device}. This device will not be published to UNS.`); + return; + } + // Use the path to this location to view the actual information + // Extract the actual schema initial value information using the location of the Hierarchy-v1 schema + enterprise = payload.metrics.find((metric) => metric.name === schemaPath + "/Enterprise")?.value; + site = payload.metrics.find((metric) => metric.name === schemaPath + "/Site")?.value; + area = payload.metrics.find((metric) => metric.name === schemaPath + "/Area")?.value; + workCenter = payload.metrics.find((metric) => metric.name === schemaPath + "/Work Center")?.value; + workUnit = payload.metrics.find((metric) => metric.name === schemaPath + "/Work Unit")?.value; + } } }) @@ -172,6 +197,10 @@ export default class MQTTClient { }) } + if (!enterprise) { + logger.warn(`🚨 No ISA-95 hierarchy information found in birth certificate for ${topic.address.group}/${topic.address.node}/${topic.address.device}. This device will not be published to UNS.`); + } + if (this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { logger.info(`🔄 Received updated birth certificate for ${topic.address.group}/${topic.address.node}/${topic.address.device} with Instance_UUID ${topLevelInstance} using Schema_UUID ${topLevelSchema}`); } else { @@ -254,6 +283,13 @@ export default class MQTTClient { // All schemas between the top and bottom, inclusive full: schemas, }, + isa95: { + enterprise: enterprise, + site: site, + area: area, + workCenter: workCenter, + workUnit: workUnit, + }, name: obj.name, type: obj.type, alias: alias, @@ -293,7 +329,6 @@ export default class MQTTClient { if (this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { // Device is known, resolve aliases and publish to UNS - //this.writeMetrics(payload, topic); this.publishToUNS(payload, topic) } else { @@ -347,7 +382,6 @@ export default class MQTTClient { payload.metrics.forEach((metric) => { if (metric.value === null) return; - let birth = this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]?.[metric.alias]; if (!birth) { @@ -355,6 +389,11 @@ export default class MQTTClient { return; } + // Don't handle data for devices that have not published ISA-95 hierarchy information + if (!birth.isa95.enterprise) { + return; + } + const metricName = birth.name.split('/').pop() as string; const path = birth.name.substring(0, birth.name.lastIndexOf("/")) as string; if (path.includes("Device Control")) { @@ -367,16 +406,55 @@ export default class MQTTClient { } // Build custom properties object - let customProperties: UnsMetricCustomProperties = { Instance_UUID: birth.instance.top, Schema_UUID: birth.schema.top, Transient: birth.transient, } - // TODO: Get enterprise information from the Device_Information-v1/Hierarchy-v1 schema - SFIP2-58 + // Here we can access the ISA95 hierarchy information from the birth.isa95 object. This object contains the following keys: + + // - enterprise + // - site + // - area + // - workCenter + // - workUnit + // + // enterprise is mandatory, but the remaining are optional but must form an unbroken chain from the top to + // the bottom. I.e. you may not have a workCenter without an area, or a workUnit without a workCenter. As + // soon as we see a break in the chain publish what we have. + + let unsTopic = null; - let unsTopic = `UNS/v1/AMRC/F2050/MK1/${topic.address.device}/Edge/${path ? (path + '/') : ''}${metricName}`; + // We must have an enterprise or we can't publish. It should never get to this point. + if (birth.isa95.enterprise === null) { + return; + } + + // If we don't have a site then we publish to the enterprise + if (birth.isa95.site === null) { + unsTopic = `UNS/v1/${birth.isa95.enterprise}/Edge/${topic.address.device}/${path ? (path + '/') : ''}${metricName}`; + } + + // If we have a site but no area then we publish to the site + else if (birth.isa95.area === null) { + unsTopic = `UNS/v1/${birth.isa95.enterprise}/${birth.isa95.site}/Edge/${topic.address.device}/${path ? (path + '/') : ''}${metricName}`; + } + + // If we have a site and an area but no workCenter then we publish to the area + else if (birth.isa95.workCenter === null) { + unsTopic = `UNS/v1/${birth.isa95.enterprise}/${birth.isa95.site}/${birth.isa95.area}/Edge/${topic.address.device}/${path ? (path + '/') : ''}${metricName}`; + } + + // If we have a site, an area and a workCenter but no workUnit then we publish to the workCenter + else if (birth.isa95.workUnit === null) { + unsTopic = `UNS/v1/${birth.isa95.enterprise}/${birth.isa95.site}/${birth.isa95.area}/${birth.isa95.workCenter}/Edge/${topic.address.device}/${path ? (path + '/') : ''}${metricName}`; + } + + // If we have a site, an area, a workCenter and a workUnit then we publish to the workUnit + else { + unsTopic = `UNS/v1/${birth.isa95.enterprise}/${birth.isa95.site}/${birth.isa95.area}/${birth.isa95.workCenter}/${birth.isa95.workUnit}/Edge/${topic.address.device}/${path ? (path + '/') : ''}${metricName}`; + } if (!(unsTopic in metricsToPublish)) { metricsToPublish[unsTopic] = [{ From 7b1015f469349d65ba317c83ba788a806b49678c Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Tue, 16 Jul 2024 13:22:34 +0100 Subject: [PATCH 19/58] Fix strict ISA-95 metric checks --- ingesters/sparkplug/lib/mqttclient.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ingesters/sparkplug/lib/mqttclient.ts b/ingesters/sparkplug/lib/mqttclient.ts index 1e4b2b43..f2459468 100644 --- a/ingesters/sparkplug/lib/mqttclient.ts +++ b/ingesters/sparkplug/lib/mqttclient.ts @@ -427,27 +427,27 @@ export default class MQTTClient { let unsTopic = null; // We must have an enterprise or we can't publish. It should never get to this point. - if (birth.isa95.enterprise === null) { + if (birth.isa95.enterprise == null) { return; } // If we don't have a site then we publish to the enterprise - if (birth.isa95.site === null) { + if (birth.isa95.site == null) { unsTopic = `UNS/v1/${birth.isa95.enterprise}/Edge/${topic.address.device}/${path ? (path + '/') : ''}${metricName}`; } // If we have a site but no area then we publish to the site - else if (birth.isa95.area === null) { + else if (birth.isa95.area == null) { unsTopic = `UNS/v1/${birth.isa95.enterprise}/${birth.isa95.site}/Edge/${topic.address.device}/${path ? (path + '/') : ''}${metricName}`; } // If we have a site and an area but no workCenter then we publish to the area - else if (birth.isa95.workCenter === null) { + else if (birth.isa95.workCenter == null) { unsTopic = `UNS/v1/${birth.isa95.enterprise}/${birth.isa95.site}/${birth.isa95.area}/Edge/${topic.address.device}/${path ? (path + '/') : ''}${metricName}`; } // If we have a site, an area and a workCenter but no workUnit then we publish to the workCenter - else if (birth.isa95.workUnit === null) { + else if (birth.isa95.workUnit == null) { unsTopic = `UNS/v1/${birth.isa95.enterprise}/${birth.isa95.site}/${birth.isa95.area}/${birth.isa95.workCenter}/Edge/${topic.address.device}/${path ? (path + '/') : ''}${metricName}`; } From 153e1231f9a0706c4e833329df69f97f2537673b Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Mon, 5 Aug 2024 15:57:57 +0100 Subject: [PATCH 20/58] Influx-Injector: Rename Influx-sparkplug-injector --- {influxdb-sparkplug-ingester => influxdb-injector}/.gitignore | 0 {influxdb-sparkplug-ingester => influxdb-injector}/Dockerfile | 0 {influxdb-sparkplug-ingester => influxdb-injector}/LICENSE | 0 {influxdb-sparkplug-ingester => influxdb-injector}/Makefile | 0 {influxdb-sparkplug-ingester => influxdb-injector}/README.md | 0 {influxdb-sparkplug-ingester => influxdb-injector}/SECURITY.md | 0 .../bin/ingester.js | 0 .../bin/ingester.ts | 0 .../lib/mqttclient.js | 0 .../lib/mqttclient.ts | 0 .../package-lock.json | 0 {influxdb-sparkplug-ingester => influxdb-injector}/package.json | 0 {influxdb-sparkplug-ingester => influxdb-injector}/run-dev.sh | 0 {influxdb-sparkplug-ingester => influxdb-injector}/tsconfig.json | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename {influxdb-sparkplug-ingester => influxdb-injector}/.gitignore (100%) rename {influxdb-sparkplug-ingester => influxdb-injector}/Dockerfile (100%) rename {influxdb-sparkplug-ingester => influxdb-injector}/LICENSE (100%) rename {influxdb-sparkplug-ingester => influxdb-injector}/Makefile (100%) rename {influxdb-sparkplug-ingester => influxdb-injector}/README.md (100%) rename {influxdb-sparkplug-ingester => influxdb-injector}/SECURITY.md (100%) rename {influxdb-sparkplug-ingester => influxdb-injector}/bin/ingester.js (100%) rename {influxdb-sparkplug-ingester => influxdb-injector}/bin/ingester.ts (100%) rename {influxdb-sparkplug-ingester => influxdb-injector}/lib/mqttclient.js (100%) rename {influxdb-sparkplug-ingester => influxdb-injector}/lib/mqttclient.ts (100%) rename {influxdb-sparkplug-ingester => influxdb-injector}/package-lock.json (100%) rename {influxdb-sparkplug-ingester => influxdb-injector}/package.json (100%) rename {influxdb-sparkplug-ingester => influxdb-injector}/run-dev.sh (100%) mode change 100755 => 100644 rename {influxdb-sparkplug-ingester => influxdb-injector}/tsconfig.json (100%) diff --git a/influxdb-sparkplug-ingester/.gitignore b/influxdb-injector/.gitignore similarity index 100% rename from influxdb-sparkplug-ingester/.gitignore rename to influxdb-injector/.gitignore diff --git a/influxdb-sparkplug-ingester/Dockerfile b/influxdb-injector/Dockerfile similarity index 100% rename from influxdb-sparkplug-ingester/Dockerfile rename to influxdb-injector/Dockerfile diff --git a/influxdb-sparkplug-ingester/LICENSE b/influxdb-injector/LICENSE similarity index 100% rename from influxdb-sparkplug-ingester/LICENSE rename to influxdb-injector/LICENSE diff --git a/influxdb-sparkplug-ingester/Makefile b/influxdb-injector/Makefile similarity index 100% rename from influxdb-sparkplug-ingester/Makefile rename to influxdb-injector/Makefile diff --git a/influxdb-sparkplug-ingester/README.md b/influxdb-injector/README.md similarity index 100% rename from influxdb-sparkplug-ingester/README.md rename to influxdb-injector/README.md diff --git a/influxdb-sparkplug-ingester/SECURITY.md b/influxdb-injector/SECURITY.md similarity index 100% rename from influxdb-sparkplug-ingester/SECURITY.md rename to influxdb-injector/SECURITY.md diff --git a/influxdb-sparkplug-ingester/bin/ingester.js b/influxdb-injector/bin/ingester.js similarity index 100% rename from influxdb-sparkplug-ingester/bin/ingester.js rename to influxdb-injector/bin/ingester.js diff --git a/influxdb-sparkplug-ingester/bin/ingester.ts b/influxdb-injector/bin/ingester.ts similarity index 100% rename from influxdb-sparkplug-ingester/bin/ingester.ts rename to influxdb-injector/bin/ingester.ts diff --git a/influxdb-sparkplug-ingester/lib/mqttclient.js b/influxdb-injector/lib/mqttclient.js similarity index 100% rename from influxdb-sparkplug-ingester/lib/mqttclient.js rename to influxdb-injector/lib/mqttclient.js diff --git a/influxdb-sparkplug-ingester/lib/mqttclient.ts b/influxdb-injector/lib/mqttclient.ts similarity index 100% rename from influxdb-sparkplug-ingester/lib/mqttclient.ts rename to influxdb-injector/lib/mqttclient.ts diff --git a/influxdb-sparkplug-ingester/package-lock.json b/influxdb-injector/package-lock.json similarity index 100% rename from influxdb-sparkplug-ingester/package-lock.json rename to influxdb-injector/package-lock.json diff --git a/influxdb-sparkplug-ingester/package.json b/influxdb-injector/package.json similarity index 100% rename from influxdb-sparkplug-ingester/package.json rename to influxdb-injector/package.json diff --git a/influxdb-sparkplug-ingester/run-dev.sh b/influxdb-injector/run-dev.sh old mode 100755 new mode 100644 similarity index 100% rename from influxdb-sparkplug-ingester/run-dev.sh rename to influxdb-injector/run-dev.sh diff --git a/influxdb-sparkplug-ingester/tsconfig.json b/influxdb-injector/tsconfig.json similarity index 100% rename from influxdb-sparkplug-ingester/tsconfig.json rename to influxdb-injector/tsconfig.json From 122443454a964e2aa26d91e8689ca8ebbdae8079 Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Wed, 7 Aug 2024 11:09:03 +0100 Subject: [PATCH 21/58] Influx-Injector: Add data consumption from UNS --- influxdb-injector/.env.example | 8 + influxdb-injector/Dockerfile | 4 +- influxdb-injector/bin/ingester.js | 28 - influxdb-injector/bin/ingester.ts | 52 - influxdb-injector/lib/mqttclient.js | 182 -- influxdb-injector/lib/mqttclient.ts | 533 ------ influxdb-injector/package-lock.json | 2554 ++------------------------- influxdb-injector/package.json | 12 +- influxdb-injector/run-dev.sh | 5 +- influxdb-injector/src/UnsTopic.ts | 95 + influxdb-injector/src/app.ts | 11 + influxdb-injector/src/logger.ts | 19 + influxdb-injector/src/mqttclient.ts | 292 +++ influxdb-injector/tsconfig.json | 27 +- ingesters/sparkplug/run-dev.sh | 4 +- 15 files changed, 626 insertions(+), 3200 deletions(-) create mode 100644 influxdb-injector/.env.example delete mode 100644 influxdb-injector/bin/ingester.js delete mode 100644 influxdb-injector/bin/ingester.ts delete mode 100644 influxdb-injector/lib/mqttclient.js delete mode 100644 influxdb-injector/lib/mqttclient.ts create mode 100644 influxdb-injector/src/UnsTopic.ts create mode 100644 influxdb-injector/src/app.ts create mode 100644 influxdb-injector/src/logger.ts create mode 100644 influxdb-injector/src/mqttclient.ts diff --git a/influxdb-injector/.env.example b/influxdb-injector/.env.example new file mode 100644 index 00000000..0c28356b --- /dev/null +++ b/influxdb-injector/.env.example @@ -0,0 +1,8 @@ +INFLUX_URL=http://localhost:8086/ +INFLUX_TOKEN=WLUvPm_7qJ7vV4ARpR9v86sbEUFEGXS_YPCxSLYhWjbq_hRLGrGMxHqeyzMmVPLIGzWNUpfRbhXCXwp5PxhwSA== +INFLUX_ORG=default +INFLUX_BUCKET=default +LOG_LEVEL=info +BATCH_SIZE=5000 +FLUSH_INTERVAL=10000 +MQTT_URL=mqtt.local.acs.app.amrc.co.uk:1883 \ No newline at end of file diff --git a/influxdb-injector/Dockerfile b/influxdb-injector/Dockerfile index 2ff683bf..f87def5a 100644 --- a/influxdb-injector/Dockerfile +++ b/influxdb-injector/Dockerfile @@ -29,7 +29,7 @@ RUN <<'SHELL' fi npm install --save=false - echo "export const GIT_VERSION=\"$revision\";" > ./lib/git-version.js + echo "export const GIT_VERSION=\"$revision\";" > ./src/git-version.js npm run clean echo tsc -v @@ -64,4 +64,4 @@ WORKDIR /usr/app # running application. This is a Good Thing. COPY --from=util-build /usr/app ./ USER node -CMD [ "node", "--es-module-specifier-resolution=node", "bin/ingester.js" ] +CMD [ "node", "--es-module-specifier-resolution=node", "bin/app.js" ] diff --git a/influxdb-injector/bin/ingester.js b/influxdb-injector/bin/ingester.js deleted file mode 100644 index 7ae99c60..00000000 --- a/influxdb-injector/bin/ingester.js +++ /dev/null @@ -1,28 +0,0 @@ -import { Debug, ServiceClient } from "@amrc-factoryplus/utilities"; -import MQTTClient from "../lib/mqttclient"; -const deviceUUID = process.env.DEVICE_UUID; -const MQTTURL = process.env.MQTT_URL; -const sparkplugAddress = process.env.SPARKPLUG_ADDRESS; -if (!deviceUUID) { - throw new Error("Device UUID not set"); -} -if (!MQTTURL) { - throw new Error("MQTT URL not set"); -} -if (!sparkplugAddress) { - throw new Error("Sparkplug Address not set"); -} -const debug = new Debug(); -const client = await new ServiceClient({ - directory_url: process.env.DIRECTORY_URL, - root_principal: process.env.ROOT_PRINCIPAL, -}).init(); -const mqtt = await new MQTTClient({ - e: { - serviceClient: client, - deviceUUID: deviceUUID, - url: MQTTURL, - sparkplugAddress: sparkplugAddress - } -}).init(); -mqtt.run(); diff --git a/influxdb-injector/bin/ingester.ts b/influxdb-injector/bin/ingester.ts deleted file mode 100644 index 136b2ac6..00000000 --- a/influxdb-injector/bin/ingester.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * AMRC InfluxDB Sparkplug Ingester - * Copyright "2023" AMRC - */ - -import {ServiceClient, UUIDs} from "@amrc-factoryplus/utilities"; -import pino from "pino"; -import pretty from 'pino-pretty'; -import MQTTClient from "@lib/mqttclient.js"; -let dotenv: any = null; -try {dotenv = await import ('dotenv')} catch (e) {} - -const stream = pretty({ - colorize: true -}) - -dotenv?.config(); - -const directoryUrl = process.env.DIRECTORY_URL; -if (!directoryUrl) { - throw new Error("DIRECTORY_URL environment variable is not set"); -} - -export const logger = pino({ - name: 'InfluxDB Sparkplug Ingester', - level: process.env.LOG_LEVEL || 'info', -}, stream); - - -const client = await new ServiceClient({ - directory_url: directoryUrl, -}).init(); - -// Overwrite MQTT server if specified in environment -if (process.env.MQTT_URL) { - client.Discovery.set_service_url(UUIDs.Service.MQTT, process.env.MQTT_URL); -} - -// Overwrite Command Escalation server if specified in environment -if (process.env.CMD_ESC_URL) { - client.Discovery.set_service_url(UUIDs.Service.Command_Escalation, process.env.CMD_ESC_URL); -} - -logger.info(client.service_urls('feb27ba3-bd2c-4916-9269-79a61ebc4a47')); - -const mqtt = await new MQTTClient({ - e: { - serviceClient: client, - } -}).init(); - -mqtt.run(); diff --git a/influxdb-injector/lib/mqttclient.js b/influxdb-injector/lib/mqttclient.js deleted file mode 100644 index 30be1af7..00000000 --- a/influxdb-injector/lib/mqttclient.js +++ /dev/null @@ -1,182 +0,0 @@ -import { Address, Debug, MetricBuilder, SpB, Topic } from "@amrc-factoryplus/utilities"; -const debug = new Debug(); -export default class MQTTClient { - serviceClient; - deviceUUID; - url; - address; - seq; - mqtt; - constructor({ e }) { - this.serviceClient = e.serviceClient; - this.deviceUUID = e.deviceUUID; - this.url = e.url; - this.address = Address.parse(e.sparkplugAddress); - this.seq = 0; - } - async init() { - return this; - } - will() { - const nDeath = { - timestamp: Date.now(), - metrics: MetricBuilder.death.node([]), - }; - // @ts-ignore - const will = SpB.encodePayload(nDeath); - return { - topic: this.address.topic("DEATH"), - payload: will, - qos: 0, - retain: false, - }; - } - async run() { - const mqtt = await this.serviceClient.mqtt_client({ - verbose: true, - // @ts-ignore - will: this.will(), - }); - this.mqtt = mqtt; - mqtt.on("gssconnect", this.on_connect.bind(this)); - mqtt.on("error", this.on_error.bind(this)); - mqtt.on("message", this.on_message.bind(this)); - // We subscribe to the whole Sparkplug namespace - mqtt.subscribe('spBv1.0/#'); - } - // encode_metrics(metrics, with_uuid) { - // const payload = { - // timestamp: Date.now(), - // metrics: metrics, - // seq: this.seq, - // }; - // this.seq = (this.seq < 255) ? (this.seq + 1) : 0; - // if (with_uuid) - // payload.uuid = UUIDs.FactoryPlus; - // - // return SpB.encodePayload(payload); - // } - // publish(kind, metrics, with_uuid) { - // if (!this.mqtt) { - // debug.log("mqtt", "Can't publish without an MQTT connection."); - // return; - // } - // - // const topic = this.address.topic(kind); - // const payload = this.encode_metrics(metrics, with_uuid); - // - // this.mqtt.publish(topic, payload); - // } - on_connect() { - debug.log("mqtt", "Connected to MQTT broker."); - // this.rebirth(); - } - // rebirth() { - // - // this.seq = 0; - // const Birth = MetricBuilder.birth; - // const metrics = Birth.node([]); - // //Birth.command_escalation(metrics); - // metrics.push.apply(metrics, [ - // {name: "Device_Information/Manufacturer", type: "String", value: Device_Info.Manufacturer}, - // {name: "Device_Information/Model", type: "String", value: Device_Info.Model}, - // {name: "Device_Information/Serial", type: "String", value: Device_Info.Serial}, - // - // {name: "Schema_UUID", type: "UUID", value: Schema.Service}, - // {name: "Instance_UUID", type: "UUID", value: this.device_uuid}, - // {name: "Service_UUID", type: "UUID", value: Service.Registry}, - // {name: "Service_URL", type: "String", value: this.url}, - // ]); - // metrics.push.apply(metrics, - // Object.values(Changed).map(v => - // ({name: `Last_Changed/${v}`, type: "UUID", value: ""}))); - // - // debug.log("mqtt", `Publishing birth certificate`); - // this.publish("BIRTH", metrics, true); - // } - // publish_changed(changes) { - // const metrics = []; - // for (let [to, uuid] of Object.entries(changes)) { - // if (!(to in Changed)) - // continue; - // metrics.push({ - // name: `Last_Changed/${Changed[to]}`, - // type: "UUID", - // value: uuid, - // }); - // } - // this.publish("DATA", metrics); - // } - on_error(error) { - debug.log("mqtt", "MQTT error: %o", error); - } - async on_message(topicString, message) { - let topic = Topic.parse(topicString); - if (!topic) { - debug.log("mqtt", `Bad topic: ${topicString}`); - return; - } - let address = topic.address; - let payload; - try { - // @ts-ignore - payload = SpB.decodePayload(message); - } - catch { - debug.log("mqtt", `Bad payload on topic ${topicString}`); - return; - } - switch (topic.type) { - case "BIRTH": - //await this.on_birth(address, payload); - break; - case "DEATH": - //await this.on_death(address, payload); - break; - case "DATA": - await this.on_data(address, payload); - break; - case "CMD": - await this.on_command(address, payload); - break; - default: - debug.log("mqtt", `Unknown Sparkplug message type ${topic.type}!`); - } - } - async on_data(addr, payload) { - if (!payload.metrics) { - debug.log("mqtt", `Received DATA with no metrics!`); - return; - } - // for (let m of payload.metrics) { - // switch (m.name) { - // // case "Node Control/Rebirth": - // // await this.rebirth(); - // // break; - // default: - // debug.log("mqtt", `Received unknown CMD: ${m.name}`); - // /* Ignore for now */ - // } - // } - } - async on_command(addr, payload) { - if (!addr.equals(this.address)) { - //console.log(`Received CMD for ${addr}`); - return; - } - if (!payload.metrics) { - debug.log("mqtt", `Received CMD with no metrics!`); - return; - } - for (let m of payload.metrics) { - switch (m.name) { - // case "Node Control/Rebirth": - // await this.rebirth(); - // break; - default: - debug.log("mqtt", `Received unknown CMD: ${m.name}`); - /* Ignore for now */ - } - } - } -} diff --git a/influxdb-injector/lib/mqttclient.ts b/influxdb-injector/lib/mqttclient.ts deleted file mode 100644 index 854811c1..00000000 --- a/influxdb-injector/lib/mqttclient.ts +++ /dev/null @@ -1,533 +0,0 @@ -/* - * AMRC InfluxDB Sparkplug Ingester - * Copyright "2024" AMRC - */ - -import {ServiceClient, SpB, Topic, UUIDs} from "@amrc-factoryplus/utilities"; -import {Reader} from "protobufjs"; -import {logger} from "../bin/ingester.js"; -import Long from "long"; -import {InfluxDB, Point} from '@influxdata/influxdb-client' -import {Agent} from 'http' - -let dotenv: any = null; -try { - dotenv = await import ('dotenv') -} catch (e) { -} - -dotenv?.config() - -const influxURL: string = process.env.INFLUX_URL; -if (!influxURL) { - throw new Error("INFLUX_URL environment variable is not set"); -} - -const influxToken: string = process.env.INFLUX_TOKEN -if (!influxToken) { - throw new Error("INFLUX_TOKEN environment variable is not set"); -} - -const influxOrganisation: string = process.env.INFLUX_ORG -if (!influxOrganisation) { - throw new Error("INFLUX_ORG environment variable is not set"); -} - -const batchSize: number = Number.parseInt(process.env.BATCH_SIZE); -if (!batchSize) { - throw new Error("BATCH_SIZE environment variable is not set"); -} - -const flushInterval: number = Number.parseInt(process.env.FLUSH_INTERVAL); -if (!flushInterval) { - throw new Error("FLUSH_INTERVAL environment variable is not set"); -} - -let i = 0; - -// Node.js HTTP client OOTB does not reuse established TCP connections, a custom node HTTP agent -// can be used to reuse them and thus reduce the count of newly established networking sockets -const keepAliveAgent = new Agent({ - keepAlive: true, // reuse existing connections - keepAliveMsecs: 20 * 1000, // 20 seconds keep alive -}) - -const influxDB = new InfluxDB({ - url: influxURL, token: influxToken, transportOptions: { - agent: keepAliveAgent, - } -}) - -let interval: any; - -/* points/lines are batched in order to minimize networking and increase performance */ - -const writeApi = influxDB.getWriteApi(influxOrganisation, process.env.INFLUX_BUCKET || 'default', 'ns', { - /* the maximum points/lines to send in a single batch to InfluxDB server */ - batchSize: batchSize + 1, // don't let automatically flush data - /* maximum time in millis to keep points in an unflushed batch, 0 means don't periodically flush */ - flushInterval: 0, // Never allow the package to flush: we'll flush manually - /* maximum size of the retry buffer - it contains items that could not be sent for the first time */ - maxBufferLines: 30_000, /* the count of internally-scheduled retries upon write failure, the delays between write attempts follow an exponential backoff strategy if there is no Retry-After HTTP header */ - maxRetries: 0, // do not retry writes - // ... there are more write options that can be customized, see - // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeoptions.html and - // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeretryoptions.html -}); - -interface MQTTClientConstructorParams { - e: { - serviceClient: ServiceClient; - } -} - -export default class MQTTClient { - private serviceClient: ServiceClient; - private mqtt: any; - private aliasResolver = {}; - private birthDebounce = {}; - - constructor({e}: MQTTClientConstructorParams) { - this.serviceClient = e.serviceClient; - } - - async init() { - - process.on('exit', () => { - this.flushBuffer('EXIT'); - keepAliveAgent.destroy(); - }) - - return this; - } - - private flushBuffer(source: string) { - let bufferSize = i; - i = 0; - writeApi.flush().then(() => { - logger.info(`🚀 Flushed ${bufferSize} points to InfluxDB [${source}]`); - // Reset the interval - this.resetInterval(); - }) - } - - async run() { - - const mqtt = await this.serviceClient.mqtt_client(); - this.mqtt = mqtt; - - mqtt.on("authenticated", this.on_connect.bind(this)); - mqtt.on("error", this.on_error.bind(this)); - mqtt.on("message", this.on_message.bind(this)); - mqtt.on("close", this.on_close.bind(this)); - mqtt.on("reconnect", this.on_reconnect.bind(this)); - - logger.info("Connecting to Factory+ broker..."); - } - - on_connect() { - logger.info("🔌 Connected to Factory+ broker"); - logger.info("👂 Subscribing to entire Factory+ namespace"); - this.mqtt.subscribe('spBv1.0/#'); - this.resetInterval(); - } - - private resetInterval() { - clearInterval(interval); - interval = setInterval(() => { - this.flushBuffer(`${flushInterval}ms INTERVAL`); - }, flushInterval); - } - - on_close() { - logger.warn(`❌ Disconnected from Factory+ broker`); - - // Flush any remaining data - this.flushBuffer('CONN_CLOSE'); - } - - on_reconnect() { - logger.warn(`⚠️ Reconnecting to Factory+ broker...`); - } - - on_error(error: any) { - logger.error("🚨 MQTT error: %o", error); - // Flush any remaining data - this.flushBuffer('MQTT_ERROR'); - } - - async on_message(topicString: string, message: Uint8Array | Reader) { - let topic = Topic.parse(topicString); - let payload; - - try { - payload = SpB.decodePayload(message); - } catch { - logger.error(`🚨 Bad payload on topic ${topicString}`); - return; - } - - if (!topic) { - logger.error(`🚨 Bad topic: ${topicString}`); - return; - } - - switch (topic.type) { - case "BIRTH": - - // Don't handle Node births - if (!topic.address.isDevice()) return; - - let topLevelSchema = null; - let schemaUUIDMapping = {}; - - let topLevelInstance = null; - let instanceUUIDMapping = {}; - - // If we have a Factory+ payload then process the Schema UUIDs and Instance UUIDs - if (payload.uuid === UUIDs.FactoryPlus) { - - // Schema_UUIDs - payload.metrics.forEach((metric) => { - // If the name ends in Schema_UUID (e.g. Phases/1/Schema_UUID) - if (metric.name.endsWith("Schema_UUID")) { - // Then get the entire string before the /Schema_UUID - let schemaPath = metric.name.split("/").slice(0, -1).join("/"); - - // If the schemaPath is empty then this is the top level Schema_UUID - if (schemaPath === "") { - // So set the topLevelSchema to this value - topLevelSchema = metric.value; - } else { - // Add this mapping to the schemaUUIDMapping array. This means - // that all metrics that contain this schema path in their name - // will have - schemaUUIDMapping[schemaPath] = metric.value; - } - } - }) - - // Instance_UUIDs - payload.metrics.forEach((metric) => { - // If the name ends in Instance_UUID (e.g. Phases/1/Instance_UUID) - if (metric.name.endsWith("Instance_UUID")) { - // Then get the entire string before the /Instance_UUID - let instancePath = metric.name.split("/").slice(0, -1).join("/"); - - // If the instancePath is empty then this is the top level Instance_UUID - if (instancePath === "") { - // So set the topLevelInstance to this value - topLevelInstance = metric.value; - } else { - // Add this mapping to the instanceUUIDMapping array. This means - // that all metrics that contain this instance path in their name - // will have - instanceUUIDMapping[instancePath] = metric.value; - } - } - }) - } - - if (this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { - logger.info(`🔄 Received updated birth certificate for ${topic.address.group}/${topic.address.node}/${topic.address.device} with Instance_UUID ${topLevelInstance} using Schema_UUID ${topLevelSchema}`); - } else { - logger.info(`👶 Received birth certificate for ${topic.address.group}/${topic.address.node}/${topic.address.device} with Instance_UUID ${topLevelInstance} using Schema_UUID ${topLevelSchema}`); - } - - // Store the birth certificate mapping in the alias resolver. This uses the alias as the key and a simplified object containing the name and type as the value. - this.setNestedValue(this.aliasResolver, [topic.address.group, topic.address.node, topic.address.device], payload.metrics.reduce(function (acc, obj) { - let alias = Long.isLong(obj.alias) ? obj.alias.toNumber() : obj.alias; - - // Work out all schemas that are involved in this metric. - // - // e.g. Assume the current metric is CNC/Axes/1/BaseAxis/Position/Actual - // - // The schemaUUIDMapping object will contain the following (non-relevant emitted): - // - Axes/1: e39007e9-1427-4867-9d72-1c00c663db15 - // - Axes/1/BaseAxis: 777dd941-f426-4355-8130-e144530b1376 - // - Axes/1/BaseAxis/Position: 1a2c3594-d311-4f6b-865b-b97db3fa6d42 - - // Schema_UUIDs - - let schemas = []; - // Get all entries in the schemaUUIDMapping object that have keys that fit in the current obj.name - Object.entries(schemaUUIDMapping).forEach(([schemaPath, schemaUUID]) => { - // If the current obj.name contains the schemaPath then add the schemaUUID to the schemas array - if (obj.name.includes(schemaPath)) { - schemas.push(schemaUUID); - } - }); - - // Get the bottom level schema by finding the the entry in the schemaUUIDMapping object that has - // the key with the most slashes that fits in the current obj.name - let bottomLevelSchema = Object.entries(schemaUUIDMapping).reduce((acc, [schemaPath, schemaUUID]) => { - if (obj.name.includes(schemaPath) && schemaPath.split("/").length > acc.split("/").length) { - return schemaUUID; - } else { - return acc; - } - }, ""); - - // Instance_UUIDs - - let instances = []; - // Get all entries in the instanceUUIDMapping object that have keys that fit in the current obj.name - Object.entries(instanceUUIDMapping).forEach(([instancePath, instanceUUID]) => { - // If the current obj.name contains the instancePath then add the instanceUUID to the instances array - if (obj.name.includes(instancePath)) { - instances.push(instanceUUID); - } - }); - - // Get the bottom level instance by finding the the entry in the instanceUUIDMapping object that has - // the key with the most slashes that fits in the current obj.name - let bottomLevelInstance = Object.entries(instanceUUIDMapping).reduce((acc, [instancePath, instanceUUID]) => { - if (obj.name.includes(instancePath) && instancePath.split("/").length > acc.split("/").length) { - return instanceUUID; - } else { - return acc; - } - }, ""); - - acc[alias] = { - instance: { - // The top level instance for this device - top: topLevelInstance, - - // The last instance before this metric - bottom: bottomLevelInstance, - - // All instances between the top and bottom, inclusive - full: instances, - }, - schema: { - // The top level schema for this device - top: topLevelSchema, - - // The last schema before this metric - bottom: bottomLevelSchema, - - // All schemas between the top and bottom, inclusive - full: schemas, - }, - name: obj.name, - type: obj.type, - alias: alias, - unit: obj.properties?.engUnit?.value, - transient: obj.isTransient - }; - return acc; - }, {})); - - // Clear the debounce - delete this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]; - - // Store the default values in InfluxDB - this.writeMetrics(payload, topic); - - break; - case "DEATH": - - // If the death certificate is for a device then remove it from the known devices, otherwise remove the entire node - if (topic.address.isDevice()) { - logger.info(`💀 Received death certificate for ${topic.address.group}/${topic.address.node}/${topic.address.device}. Removing from known devices.`); - delete this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device] - delete this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device] - break; - } else { - logger.info(`💀💀💀 Received death certificate for entire node ${topic.address.group}/${topic.address.node}. Removing from known nodes.`); - delete this.birthDebounce?.[topic.address.group]?.[topic.address.node] - delete this.aliasResolver?.[topic.address.group]?.[topic.address.node] - break; - } - case "DATA": - - // Don't handle Node data - if (!topic.address.isDevice()) return; - - // Check if we have a birth certificate for the device - if (this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { - - // Device is known, resolve aliases and write to InfluxDB - this.writeMetrics(payload, topic); - - } else { - - // Check that we don't already have an active debounce for this device - if (this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { - logger.info(`⏳ Device ${topic.address.group}/${topic.address.node}/${topic.address.device} is unknown but has pending birth certificate request. Ignoring.`); - return; - } - - logger.info(`✨ Device ${topic.address.group}/${topic.address.node}/${topic.address.device} is unknown, requesting birth certificate`); - - // Create debounce timout for this device - this.setNestedValue(this.birthDebounce, [topic.address.group, topic.address.node, topic.address.device], true); - setTimeout(() => { - delete this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]; - }, Math.floor(Math.random() * (10000 - 5000 + 1) + 5000)); - - // Request birth certificate - let response = await this.serviceClient.fetch({ - service: UUIDs.Service.Command_Escalation, - url: `/v1/address/${topic.address.group}/${topic.address.node}/${topic.address.device}`, - method: "POST", - headers: { - "content-type": "application/json" - }, - body: JSON.stringify({ - "name": "Device Control/Rebirth", "value": "true" - }) - }) - - logger.info('📣 Birth certificate request sent for %s. Status: %s', topic.address, response.status); - - } - break; - } - - return; - } - - private writeMetrics(payload, topic: Topic) { - payload.metrics.forEach((metric) => { - let birth = this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]?.[metric.alias]; - - if (!birth) { - logger.error(`Metric ${metric.alias} is unknown for ${topic.address.group}/${topic.address.node}/${topic.address.device}`); - } - - let metricTimestamp: Date - if (metric.timestamp) { - metricTimestamp = new Date(metric.timestamp); - } else if (payload.timestamp) { - // Metrics might not have a timestamp so use the packet timestamp if we have it. - metricTimestamp = new Date(payload.timestamp); - } else { - // No timestamp can be found on the metric or the payload, just use the current time instead. - metricTimestamp = new Date(); - } - // Send each metric to InfluxDB - this.writeToInfluxDB(birth, topic, metric.value, metricTimestamp) - }); - } - - /** - * Writes metric values to InfluxDB using the metric timestamp. - * @param birth Birth certificate for device. - * @param topic Topic the metric was published on. - * @param value Metric value to write to InfluxDB. - * @param timestamp Timestamp from the metric to write to influx. - */ - writeToInfluxDB(birth, topic: Topic, value, timestamp: Date) { - if (value === null) return; - if (birth.transient) { - logger.debug(`Metric ${birth.name} is transient, not writing to InfluxDB`); - return; - } - - // Get the value after the last / - let metricName = birth.name.split('/').pop(); - - // Get the path as everything behind the last / - let path = birth.name.substring(0, birth.name.lastIndexOf("/")); - - writeApi.useDefaultTags({ - topLevelInstance: birth.instance.top, - bottomLevelInstance: birth.instance.bottom, - usesInstances: birth.instance.top + ':' + birth.instance.full.join(':'), - topLevelSchema: birth.schema.top, - bottomLevelSchema: birth.schema.bottom, - usesSchemas: birth.schema.top + ':' + birth.schema.full.join(':'), - group: topic.address.group, - node: topic.address.node, - device: topic.address.device, - path: path, - unit: birth.unit - }); - - let numVal = null; - - switch (birth.type) { - case "Int8": - case "Int16": - case "Int32": - case "Int64": - // Validate - numVal = Number(value); - if (!Number.isInteger(numVal)) { - logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${numVal}. Not recording.`); - return; - } - writeApi.writePoint( - new Point(`${metricName}:i`) - .intField('value', numVal) - .timestamp(timestamp) - ); - break; - case "UInt8": - case "UInt16": - case "UInt32": - case "UInt64": - // Validate - numVal = Number(value); - if (!Number.isInteger(numVal)) { - logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${numVal}. Not recording.`); - return; - } - writeApi.writePoint( - new Point(`${metricName}:u`) - .uintField('value', numVal) - .timestamp(timestamp) - ); - break; - case "Float": - case "Double": - // Validate - numVal = Number(value); - if (isNaN(parseFloat(numVal))) { - logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${numVal}. Not recording.`); - return; - } - writeApi.writePoint( - new Point(`${metricName}:d`) - .floatField('value', numVal) - .timestamp(timestamp) - ); - break; - case "Boolean": - if (typeof value != "boolean") { - logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${value}. Not recording.`); - return; - } - writeApi.writePoint( - new Point(`${metricName}:b`) - .booleanField('value', value) - .timestamp(timestamp)); - break; - default: - writeApi.writePoint( - new Point(`${metricName}:s`) - .stringField('value', value) - .timestamp(timestamp)); - break; - - } - - i++; - - logger.debug(`Added to write buffer (${i}/${batchSize}): [${birth.type}] ${topic.address}/${path}/${metricName} = ${value}`); - - if (i >= batchSize) { - this.flushBuffer(`${batchSize} point BATCH`); - } - } - - setNestedValue(obj, path, value) { - for (let k = 0; k < path.length - 1; k++) { - obj = obj[path[k]] = obj[path[k]] || {}; - } - obj[path[path.length - 1]] = value; - return obj; - } -} diff --git a/influxdb-injector/package-lock.json b/influxdb-injector/package-lock.json index 82e755f5..af150b6b 100644 --- a/influxdb-injector/package-lock.json +++ b/influxdb-injector/package-lock.json @@ -9,11 +9,11 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "@amrc-factoryplus/utilities": "^1.0.8", "@influxdata/influxdb-client": "^1.33.2", "@influxdata/influxdb-client-apis": "^1.33.2", "async": "^3.2.4", "long": "^5.2.3", + "mqtt": "^5.9.1", "pino": "^8.11.0", "pino-pretty": "^10.0.0" }, @@ -24,51 +24,15 @@ "tsc-alias": "^1.7.0" } }, - "node_modules/@amrc-factoryplus/utilities": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@amrc-factoryplus/utilities/-/utilities-1.0.8.tgz", - "integrity": "sha512-pSnakabCRTs7AlRtjYPNM47BQLsN2XR7xrNXuKmBDf+iytsCU1m0pCmQXuUM8/yvk80PxabMLm7dIlG405r5Bg==", - "dependencies": { - "@types/express": "4", - "@types/long": "^4.0.0", - "@types/node": ">=13.7.0", - "content-type": "^1.0.5", - "cors": "^2.8.5", - "express": "^4.18.1", - "find-package-json": "^1.2.0", - "got-fetch": "^5.1.1", - "http-errors": "^2.0.0", - "mqtt": "^4.3.5", - "optional-js": "^2.3.0", - "path-to-regexp": "^6.2.1", - "pg": "^8.7.3", - "protobufjs": "^6.11.3", - "semver": "^7.5.1", - "sparkplug-payload": "^1.0.1", - "typescript": "^4.8.4" - }, - "optionalDependencies": { - "gssapi.js": "^2.0.1", - "pg-native": "^3.0.0" - } - }, - "node_modules/@amrc-factoryplus/utilities/node_modules/path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" - }, - "node_modules/@amrc-factoryplus/utilities/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/@babel/runtime": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", + "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "regenerator-runtime": "^0.14.0" }, "engines": { - "node": ">=10" + "node": ">=6.9.0" } }, "node_modules/@cspotcode/source-map-support": { @@ -156,84 +120,6 @@ "node": ">= 8" } }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "node_modules/@sindresorhus/is": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", - "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", - "peer": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "peer": true, - "dependencies": { - "defer-to-connect": "^2.0.1" - }, - "engines": { - "node": ">=14.16" - } - }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -258,81 +144,30 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, - "node_modules/@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.17", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", - "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.33", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", - "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", - "peer": true - }, - "node_modules/@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" - }, - "node_modules/@types/mime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", - "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" - }, "node_modules/@types/node": { "version": "18.15.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==" }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + "node_modules/@types/readable-stream": { + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.15.tgz", + "integrity": "sha512-oAZ3kw+kJFkEqyh7xORZOku1YAKvsFTogRY8kVl4vHpEKiDkfnSA/My8haRE7fvmix5Zyy+1pwzOi7yycGLBJw==", + "dependencies": { + "@types/node": "*", + "safe-buffer": "~5.1.1" + } }, - "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + "node_modules/@types/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, - "node_modules/@types/serve-static": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", - "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", + "node_modules/@types/ws": { + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", "dependencies": { - "@types/mime": "*", "@types/node": "*" } }, @@ -347,18 +182,6 @@ "node": ">=6.5" } }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/acorn": { "version": "8.8.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", @@ -380,21 +203,6 @@ "node": ">=0.4.0" } }, - "node_modules/ansi": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", - "integrity": "sha512-iFY7JCgHbepc0b82yLaw4IMortylNb6wG4kL+4R0C3iv6i+RHGHux/yUX5BTiRvSX/shMnngjR1YyNMnXEFh5A==", - "optional": true - }, - "node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -408,63 +216,12 @@ "node": ">= 8" } }, - "node_modules/are-we-there-yet": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.0.6.tgz", - "integrity": "sha512-Zfw6bteqM9gQXZ1BIWOgM8xEwMrUGoyL8nW13+O+OOgNX3YhuDN1GDgg1NzdTlmm3j+9sHy7uBZ12r+z9lXnZQ==", - "optional": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.0 || ^1.1.13" - } - }, - "node_modules/are-we-there-yet/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "optional": true - }, - "node_modules/are-we-there-yet/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "optional": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/are-we-there-yet/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - }, - "node_modules/are-we-there-yet/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -487,15 +244,6 @@ "node": ">=8.0.0" } }, - "node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "optional": true, - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -520,28 +268,6 @@ } ] }, - "node_modules/big-integer": { - "version": "1.6.51", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", - "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", - "optional": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/binary": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", - "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", - "optional": true, - "dependencies": { - "buffers": "~0.1.1", - "chainsaw": "~0.1.0" - }, - "engines": { - "node": "*" - } - }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -551,36 +277,30 @@ "node": ">=8" } }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/bl/-/bl-6.0.14.tgz", + "integrity": "sha512-TJfbvGdL7KFGxTsEbsED7avqpFdY56q9IW0/aiytyheJzxST/+Io6cx/4Qx0K2/u0BPRDs65mjaQzYvMZeNocQ==", "dependencies": { - "buffer": "^5.5.0", + "@types/readable-stream": "^4.0.0", + "buffer": "^6.0.3", "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "readable-stream": "^4.2.0" } }, "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { - "node": ">= 6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/bl/node_modules/string_decoder": { @@ -591,44 +311,6 @@ "safe-buffer": "~5.2.0" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "optional": true - }, - "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -642,9 +324,9 @@ } }, "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { "type": "github", @@ -661,7 +343,7 @@ ], "dependencies": { "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "ieee754": "^1.2.1" } }, "node_modules/buffer-from": { @@ -669,106 +351,6 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, - "node_modules/buffer-indexof-polyfill": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", - "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", - "optional": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/buffer-shims": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g==", - "optional": true - }, - "node_modules/buffer-writer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", - "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/buffers": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", - "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", - "optional": true, - "engines": { - "node": ">=0.2.0" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", - "peer": true, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/cacheable-request": { - "version": "10.2.9", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.9.tgz", - "integrity": "sha512-CaAMr53AS1Tb9evO1BIWFnZjSr8A4pbXofpsNVWPMDZZj3ZQKHwsQG9BrTqQ4x5ZYJXz1T2b8LLtTZODxSpzbg==", - "peer": true, - "dependencies": { - "@types/http-cache-semantics": "^4.0.1", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.2", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/chainsaw": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", - "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", - "optional": true, - "dependencies": { - "traverse": ">=0.3.0 <0.4" - }, - "engines": { - "node": "*" - } - }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -796,85 +378,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "optional": true - }, - "node_modules/cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", - "optional": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "node_modules/cmake-js": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/cmake-js/-/cmake-js-6.3.2.tgz", - "integrity": "sha512-7MfiQ/ijzeE2kO+WFB9bv4QP5Dn2yVaAP2acFJr4NIFy2hT4w6O4EpOTLNcohR5IPX7M4wNf/5taIqMj7UA9ug==", - "optional": true, - "dependencies": { - "axios": "^0.21.1", - "bluebird": "^3", - "debug": "^4", - "fs-extra": "^5.0.0", - "is-iojs": "^1.0.1", - "lodash": "^4", - "memory-stream": "0", - "npmlog": "^1.2.0", - "rc": "^1.2.7", - "semver": "^5.0.3", - "splitargs": "0", - "tar": "^4", - "unzipper": "^0.8.13", - "url-join": "0", - "which": "^1.0.9", - "yargs": "^3.6.0" - }, - "bin": { - "cmake-js": "bin/cmake-js" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/cmake-js/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "optional": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/cmake-js/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==", - "optional": true - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/colorette": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", @@ -890,18 +393,9 @@ } }, "node_modules/commist": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", - "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", - "dependencies": { - "leven": "^2.1.0", - "minimist": "^1.1.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz", + "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==" }, "node_modules/concat-stream": { "version": "2.0.0", @@ -938,73 +432,23 @@ "safe-buffer": "~5.2.0" } }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "optional": true - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" }, "engines": { "node": ">=10.14", @@ -1049,91 +493,6 @@ "node": "*" } }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "peer": true, - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "optional": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "peer": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "optional": true - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -1164,96 +523,6 @@ "node": ">=12" } }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "optional": true, - "dependencies": { - "readable-stream": "^2.0.2" - } - }, - "node_modules/duplexer2/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "optional": true - }, - "node_modules/duplexer2/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "optional": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/duplexer2/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - }, - "node_modules/duplexer2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "node_modules/duplexify/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/duplexify/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -1262,19 +531,6 @@ "once": "^1.4.0" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", @@ -1291,47 +547,6 @@ "node": ">=0.8.x" } }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, "node_modules/fast-copy": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.1.tgz", @@ -1366,6 +581,18 @@ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, + "node_modules/fast-unique-numbers": { + "version": "8.0.13", + "resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-8.0.13.tgz", + "integrity": "sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g==", + "dependencies": { + "@babel/runtime": "^7.23.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.1.0" + } + }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -1375,12 +602,6 @@ "reusify": "^1.0.4" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1393,93 +614,6 @@ "node": ">=8" } }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/find-package-json": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/find-package-json/-/find-package-json-1.2.0.tgz", - "integrity": "sha512-+SOGcLGYDJHtyqHd87ysBhmaeQ95oWspDKnMXBrnQ9Eq4OkLNqejgoaD8xVWu6GPa0B6roa6KinCMEMcVeqONw==" - }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "optional": true, - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data-encoder": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", - "peer": true, - "engines": { - "node": ">= 14.17" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-extra": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", - "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "node_modules/fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "optional": true, - "dependencies": { - "minipass": "^2.6.0" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1499,83 +633,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - }, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/gauge": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", - "integrity": "sha512-fVbU2wRE91yDvKUnrIaQlHKAWKY5e08PmztCrwuH5YVQ+Z/p3d0ny2T48o6uvAAXHIUnfaQdHkmxYbQft1eHVA==", - "optional": true, - "dependencies": { - "ansi": "^0.3.0", - "has-unicode": "^2.0.0", - "lodash.pad": "^4.1.0", - "lodash.padend": "^4.1.0", - "lodash.padstart": "^4.1.0" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -1608,162 +665,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/got": { - "version": "12.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.0.tgz", - "integrity": "sha512-WTcaQ963xV97MN3x0/CbAriXFZcXCfgxVp91I+Ze6pawQOa7SgzwSx2zIJJsX+kTajMnVs0xcFD1TxZKFqhdnQ==", - "peer": true, - "dependencies": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/got-fetch": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/got-fetch/-/got-fetch-5.1.4.tgz", - "integrity": "sha512-Pdv+SSgtTCDZbNuGkOf0c0FZy5Syqf225JEgG/vKt13HAe8r2vNJ11DxKKODsmr7L7/6ff3lf+AxpBtD5k/dRQ==", - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "got": "^12.0.0" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "optional": true - }, - "node_modules/gssapi.js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gssapi.js/-/gssapi.js-2.0.1.tgz", - "integrity": "sha512-5D+qylV8uIKMaxTTKhpzvfGRz5+okr/rpwC6YlaCoDVBpvkuNgL8pM7+r7aTzZ2oT5dA4w2WoZTV82opGj+RZQ==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "bindings": "^1.5.0", - "cmake-js": "^6.1.0", - "node-addon-api": "^1.7.2" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "optional": true - }, "node_modules/help-me": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", - "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", - "dependencies": { - "glob": "^7.1.6", - "readable-stream": "^3.6.0" - } - }, - "node_modules/help-me/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/help-me/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "peer": true - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http2-wrapper": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz", - "integrity": "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==", - "peer": true, - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==" }, "node_modules/ieee754": { "version": "1.2.1", @@ -1807,29 +712,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "optional": true - }, - "node_modules/invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -1851,18 +733,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "optional": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -1875,12 +745,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-iojs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-iojs/-/is-iojs-1.1.0.tgz", - "integrity": "sha512-tLn1j3wYSL6DkvEI+V/j0pKohpa5jk+ER74v6S4SgCXnjS0WA+DoZbwZBrrhgwksMvtuwndyGeG5F8YMsoBzSA==", - "optional": true - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -1890,17 +754,11 @@ "node": ">=0.12.0" } }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "optional": true - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "devOptional": true + "dev": true }, "node_modules/joycon": { "version": "3.1.1", @@ -1919,118 +777,10 @@ "url": "https://opencollective.com/js-sdsl" } }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "peer": true - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "optional": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/keyv": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", - "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", - "peer": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", - "optional": true, - "dependencies": { - "invert-kv": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/libpq": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/libpq/-/libpq-1.8.12.tgz", - "integrity": "sha512-4lUY9BD9suz76mVS0kH4rRgRy620g/c9YZH5GYC3smfIpjtj6KiPuQ4IwQSHSZMMMhMM3tBFrYUrw8mHOOZVeg==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "bindings": "1.5.0", - "nan": "^2.14.0" - } - }, - "node_modules/listenercount": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", - "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==", - "optional": true - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "optional": true - }, - "node_modules/lodash.pad": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", - "integrity": "sha512-mvUHifnLqM+03YNzeTBS1/Gr6JRFjd3rRx88FHWUvamVaT9k2O/kXha3yBSOwB9/DTQrSTLJNHvLBBt2FdX7Mg==", - "optional": true - }, - "node_modules/lodash.padend": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", - "integrity": "sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw==", - "optional": true - }, - "node_modules/lodash.padstart": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", - "integrity": "sha512-sW73O6S8+Tg66eY56DBk85aQzzUJDtpoXFBgELMd5P/SotAguo+1kYO6RuYgXxA4HJH3LFTFPASX6ET6bjfriw==", - "optional": true - }, - "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" - }, - "node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "peer": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "node_modules/make-error": { "version": "1.3.6", @@ -2038,28 +788,6 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memory-stream": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/memory-stream/-/memory-stream-0.0.3.tgz", - "integrity": "sha512-q0D3m846qY6ZkIt+19ZemU5vH56lpOZZwoJc3AICARKh/menBuayQUjAGPrqtHQQMUYERSdOrej92J9kz7LgYA==", - "optional": true, - "dependencies": { - "readable-stream": "~1.0.26-2" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -2069,14 +797,6 @@ "node": ">= 8" } }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -2090,59 +810,6 @@ "node": ">=8.6" } }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "peer": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", @@ -2151,89 +818,52 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "optional": true, - "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "node_modules/minipass/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "optional": true - }, - "node_modules/minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "optional": true, - "dependencies": { - "minipass": "^2.9.0" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "optional": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/mqtt": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.7.tgz", - "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==", + "version": "5.9.1", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.9.1.tgz", + "integrity": "sha512-FMENfSUMfCSUCnkuUVAL4U01795SUEfrX0NZ53HNr1r2VNpwKhR5Au9viq9WCFGtgrDAmsll4fkloqFCFgStYA==", "dependencies": { - "commist": "^1.0.0", + "@types/readable-stream": "^4.0.5", + "@types/ws": "^8.5.9", + "commist": "^3.2.0", "concat-stream": "^2.0.0", - "debug": "^4.1.1", - "duplexify": "^4.1.1", - "help-me": "^3.0.0", - "inherits": "^2.0.3", - "lru-cache": "^6.0.0", - "minimist": "^1.2.5", - "mqtt-packet": "^6.8.0", - "number-allocator": "^1.0.9", - "pump": "^3.0.0", - "readable-stream": "^3.6.0", + "debug": "^4.3.4", + "help-me": "^5.0.0", + "lru-cache": "^10.0.1", + "minimist": "^1.2.8", + "mqtt": "^5.2.0", + "mqtt-packet": "^9.0.0", + "number-allocator": "^1.0.14", + "readable-stream": "^4.4.2", "reinterval": "^1.1.0", "rfdc": "^1.3.0", - "split2": "^3.1.0", - "ws": "^7.5.5", - "xtend": "^4.0.2" + "split2": "^4.2.0", + "worker-timers": "^7.1.4", + "ws": "^8.17.1" }, "bin": { - "mqtt": "bin/mqtt.js", - "mqtt_pub": "bin/pub.js", - "mqtt_sub": "bin/sub.js" + "mqtt": "build/bin/mqtt.js", + "mqtt_pub": "build/bin/pub.js", + "mqtt_sub": "build/bin/sub.js" }, "engines": { - "node": ">=10.0.0" + "node": ">=16.0.0" } }, "node_modules/mqtt-packet": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", - "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-9.0.0.tgz", + "integrity": "sha512-8v+HkX+fwbodsWAZIZTI074XIoxVBOmPeggQuDFCGg1SqNcC+uoRMWu7J6QlJPqIUIJXmjNYYHxBBLr1Y/Df4w==", "dependencies": { - "bl": "^4.0.2", - "debug": "^4.1.1", + "bl": "^6.0.8", + "debug": "^4.3.4", "process-nextick-args": "^2.0.1" } }, "node_modules/mqtt-packet/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "dependencies": { "ms": "2.1.2" }, @@ -2267,22 +897,29 @@ } } }, + "node_modules/mqtt/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, "node_modules/mqtt/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==" }, "node_modules/mqtt/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { - "node": ">= 6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/mqtt/node_modules/string_decoder": { @@ -2293,11 +930,6 @@ "safe-buffer": "~5.2.0" } }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, "node_modules/mylas": { "version": "2.1.13", "resolved": "https://registry.npmjs.org/mylas/-/mylas-2.1.13.tgz", @@ -2311,26 +943,6 @@ "url": "https://github.com/sponsors/raouldeheer" } }, - "node_modules/nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "optional": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-addon-api": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", - "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", - "optional": true - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -2340,29 +952,6 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", - "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", - "peer": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npmlog": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-1.2.1.tgz", - "integrity": "sha512-1J5KqSRvESP6XbjPaXt2H6qDzgizLTM7x0y1cXIjP2PpvdCqyNC7TO3cPRKsuYlElbi/DwkzRRdG2zpmE0IktQ==", - "optional": true, - "dependencies": { - "ansi": "~0.3.0", - "are-we-there-yet": "~1.0.0", - "gauge": "~1.2.0" - } - }, "node_modules/number-allocator": { "version": "1.0.14", "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz", @@ -2393,47 +982,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/on-exit-leak-free": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==" }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2442,53 +995,6 @@ "wrappy": "1" } }, - "node_modules/optional-js": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/optional-js/-/optional-js-2.3.0.tgz", - "integrity": "sha512-B0LLi+Vg+eko++0z/b8zIv57kp7HKEzaPJo7LowJXMUKYdf+3XJGu/cw03h/JhIOsLnP+cG5QnTHAuicjA5fMw==" - }, - "node_modules/os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", - "optional": true, - "dependencies": { - "lcid": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "peer": true, - "engines": { - "node": ">=12.20" - } - }, - "node_modules/packet-reader": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", - "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -2498,11 +1004,6 @@ "node": ">=8" } }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -2512,133 +1013,6 @@ "node": ">=8" } }, - "node_modules/pg": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.10.0.tgz", - "integrity": "sha512-ke7o7qSTMb47iwzOSaZMfeR7xToFdkE71ifIipOAAaLIM0DYzfOAXlgFFmYUIE2BcJtvnVlGCID84ZzCegE8CQ==", - "dependencies": { - "buffer-writer": "2.0.0", - "packet-reader": "1.0.0", - "pg-connection-string": "^2.5.0", - "pg-pool": "^3.6.0", - "pg-protocol": "^1.6.0", - "pg-types": "^2.1.0", - "pgpass": "1.x" - }, - "engines": { - "node": ">= 8.0.0" - }, - "peerDependencies": { - "pg-native": ">=3.0.1" - }, - "peerDependenciesMeta": { - "pg-native": { - "optional": true - } - } - }, - "node_modules/pg-connection-string": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", - "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" - }, - "node_modules/pg-int8": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/pg-native": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/pg-native/-/pg-native-3.0.1.tgz", - "integrity": "sha512-LBVNWkNh0fVx/cienARRP2y22J5OpUsKBe0TpxzAx3arEUUdIs77aLSAHS3scS7SMaqc+OkG40CEu5fN0/cjIw==", - "optional": true, - "dependencies": { - "libpq": "^1.8.10", - "pg-types": "^1.12.1", - "readable-stream": "1.0.31" - } - }, - "node_modules/pg-native/node_modules/pg-types": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-1.13.0.tgz", - "integrity": "sha512-lfKli0Gkl/+za/+b6lzENajczwZHc7D5kiUCZfgm914jipD2kIOIvEkAhZ8GrW3/TUoP9w8FHjwpPObBye5KQQ==", - "optional": true, - "dependencies": { - "pg-int8": "1.0.1", - "postgres-array": "~1.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.0", - "postgres-interval": "^1.1.0" - } - }, - "node_modules/pg-native/node_modules/postgres-array": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.3.tgz", - "integrity": "sha512-5wClXrAP0+78mcsNX3/ithQ5exKvCyK5lr5NEEEeGwwM6NJdQgzIJBVxLvRW+huFpX92F2QnZ5CcokH0VhK2qQ==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pg-native/node_modules/readable-stream": { - "version": "1.0.31", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.31.tgz", - "integrity": "sha512-tco/Dwv1f/sgIgN6CWdj/restacPKNskK6yps1981ivH2ZmLYcs5o5rVzL3qaO/cSkhN8hYOMWs7+glzOLSgRg==", - "optional": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/pg-pool": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.0.tgz", - "integrity": "sha512-clFRf2ksqd+F497kWFyM21tMjeikn60oGDmqMT8UBrynEwVEX/5R5xd2sdvdo1cZCFlguORNpVuqxIj+aK4cfQ==", - "peerDependencies": { - "pg": ">=8.0" - } - }, - "node_modules/pg-protocol": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", - "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" - }, - "node_modules/pg-types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", - "dependencies": { - "pg-int8": "1.0.1", - "postgres-array": "~2.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.4", - "postgres-interval": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pgpass": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", - "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", - "dependencies": { - "split2": "^4.1.0" - } - }, - "node_modules/pgpass/node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "engines": { - "node": ">= 10.x" - } - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -2681,29 +1055,6 @@ "split2": "^4.0.0" } }, - "node_modules/pino-abstract-transport/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/pino-abstract-transport/node_modules/readable-stream": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz", @@ -2718,14 +1069,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/pino-abstract-transport/node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "engines": { - "node": ">= 10.x" - } - }, "node_modules/pino-pretty": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.0.0.tgz", @@ -2747,38 +1090,15 @@ "strip-json-comments": "^3.1.1" }, "bin": { - "pino-pretty": "bin.js" - } - }, - "node_modules/pino-pretty/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/pino-pretty/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "pino-pretty": "bin.js" + } + }, + "node_modules/pino-pretty/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" + "balanced-match": "^1.0.0" } }, "node_modules/pino-pretty/node_modules/glob": { @@ -2879,41 +1199,6 @@ "queue-lit": "^1.5.0" } }, - "node_modules/postgres-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/postgres-bytea": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-date": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-interval": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "dependencies": { - "xtend": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -2932,48 +1217,6 @@ "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==" }, - "node_modules/protobufjs": { - "version": "6.11.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", - "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/protobufjs/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -2983,20 +1226,6 @@ "once": "^1.3.1" } }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/queue-lit": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-1.5.0.tgz", @@ -3028,67 +1257,6 @@ "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "optional": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "optional": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -3109,32 +1277,16 @@ "node": ">= 12.13.0" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, "node_modules/reinterval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "peer": true - }, - "node_modules/responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "peer": true, - "dependencies": { - "lowercase-keys": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -3150,18 +1302,6 @@ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" }, - "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "optional": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -3212,78 +1352,11 @@ "node": ">=10" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, "node_modules/secure-json-parse": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" }, - "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "optional": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "optional": true - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -3305,19 +1378,6 @@ "node": ">=8" } }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -3335,127 +1395,14 @@ "atomic-sleep": "^1.0.0" } }, - "node_modules/sparkplug-payload": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkplug-payload/-/sparkplug-payload-1.0.1.tgz", - "integrity": "sha512-N4i++SFY7ECH7NB2bi1zmL9uPRKXF5cXQRxudUqZi9sribVZB7TZWvMIcTTakqqs1WkryYgpuV34CwEYm7I0Cg==", - "dependencies": { - "protobufjs": "^6.8.0" - } - }, "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", - "dependencies": { - "readable-stream": "^3.0.0" - } - }, - "node_modules/split2/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/split2/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/splitargs": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/splitargs/-/splitargs-0.0.7.tgz", - "integrity": "sha512-UUFYD2oWbNwULH6WoVtLUOw8ch586B+HUqcsAjjjeoBQAM1bD4wZRXu01koaxyd8UeYpybWqW4h+lO1Okv40Tg==", - "optional": true - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" - }, - "node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "optional": true - }, - "node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "optional": true, - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "optional": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "optional": true, - "dependencies": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "engines": { - "node": ">=4.5" + "node": ">= 10.x" } }, - "node_modules/tar/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "optional": true - }, "node_modules/thread-stream": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.3.0.tgz", @@ -3476,23 +1423,6 @@ "node": ">=8.0" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/traverse": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", - "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", - "optional": true, - "engines": { - "node": "*" - } - }, "node_modules/ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", @@ -3553,17 +1483,10 @@ "tsc-alias": "dist/bin/index.js" } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/typedarray": { "version": "0.0.6", @@ -3574,6 +1497,8 @@ "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3582,141 +1507,46 @@ "node": ">=4.2.0" } }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "optional": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unzipper": { - "version": "0.8.14", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.8.14.tgz", - "integrity": "sha512-8rFtE7EP5ssOwGpN2dt1Q4njl0N1hUXJ7sSPz0leU2hRdq6+pra57z4YPBlVqm40vcgv6ooKZEAx48fMTv9x4w==", - "optional": true, - "dependencies": { - "big-integer": "^1.6.17", - "binary": "~0.3.0", - "bluebird": "~3.4.1", - "buffer-indexof-polyfill": "~1.0.0", - "duplexer2": "~0.1.4", - "fstream": "~1.0.10", - "listenercount": "~1.0.1", - "readable-stream": "~2.1.5", - "setimmediate": "~1.0.4" - } - }, - "node_modules/unzipper/node_modules/bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==", - "optional": true - }, - "node_modules/unzipper/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "optional": true - }, - "node_modules/unzipper/node_modules/process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==", - "optional": true - }, - "node_modules/unzipper/node_modules/readable-stream": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", - "integrity": "sha512-NkXT2AER7VKXeXtJNSaWLpWIhmtSE3K2PguaLEeWr4JILghcIKqoLt1A3wHrnpDC5+ekf8gfk1GKWkFXe4odMw==", - "optional": true, - "dependencies": { - "buffer-shims": "^1.0.0", - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/url-join": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz", - "integrity": "sha512-H6dnQ/yPAAVzMQRvEvyz01hhfQL5qRWSEt7BX8t9DqnPw9BjMb64fjIRq76Uvf1hkHp+mTZvEVJ5guXOT0Xqaw==", - "optional": true - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "optional": true, + "node_modules/worker-timers": { + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-7.1.8.tgz", + "integrity": "sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw==", "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" + "@babel/runtime": "^7.24.5", + "tslib": "^2.6.2", + "worker-timers-broker": "^6.1.8", + "worker-timers-worker": "^7.0.71" } }, - "node_modules/window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha512-2thx4pB0cV3h+Bw7QmMXcEbdmOzv9t0HFplJH/Lz6yu60hXYy5RT8rUu+wlIreVxWsGN20mo+MHeCSfUpQBwPw==", - "optional": true, - "bin": { - "window-size": "cli.js" - }, - "engines": { - "node": ">= 0.10.0" + "node_modules/worker-timers-broker": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-6.1.8.tgz", + "integrity": "sha512-FUCJu9jlK3A8WqLTKXM9E6kAmI/dR1vAJ8dHYLMisLNB/n3GuaFIjJ7pn16ZcD1zCOf7P6H62lWIEBi+yz/zQQ==", + "dependencies": { + "@babel/runtime": "^7.24.5", + "fast-unique-numbers": "^8.0.13", + "tslib": "^2.6.2", + "worker-timers-worker": "^7.0.71" } }, - "node_modules/wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "optional": true, + "node_modules/worker-timers-worker": { + "version": "7.0.71", + "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-7.0.71.tgz", + "integrity": "sha512-ks/5YKwZsto1c2vmljroppOKCivB/ma97g9y77MAAz2TBBjPPgpoOiS1qYQKIgvGTr2QYPT3XhJWIB6Rj2MVPQ==", "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "@babel/runtime": "^7.24.5", + "tslib": "^2.6.2" } }, "node_modules/wrappy": { @@ -3725,15 +1555,15 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "engines": { - "node": ">=8.3.0" + "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -3744,40 +1574,6 @@ } } }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "optional": true - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha512-ONJZiimStfZzhKamYvR/xvmgW3uEkAUFSP91y2caTEPhzF6uP2JfPiVZcq66b/YR0C3uitxSV7+T1x8p5bkmMg==", - "optional": true, - "dependencies": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/influxdb-injector/package.json b/influxdb-injector/package.json index 70c93948..ad57d631 100644 --- a/influxdb-injector/package.json +++ b/influxdb-injector/package.json @@ -4,6 +4,8 @@ "description": "An ingestion engine to enable InfluxDB to be a fully-featured Sparkplug historian", "author": "AMRC", "license": "MIT", + "main": "./src/app.js", + "type": "module", "keywords": [ "amrc", "factory-plus", @@ -13,22 +15,20 @@ "mqtt", "sparkplug" ], - "type": "module", "scripts": { - "start": "node --trace-warnings dist/bin/ingester.js", - "start:shell": "k5start -Uf $CLIENT_KEYTAB npm run start", - "dev": " npm run build && npm run start:dev", - "build": "tsc && tsc-alias", + "start": "node dist/app.js", + "dev": " npm run build && npm run start", + "build": "tsc", "clean": "tsc --build --clean", "lint": "eslint --ignore-path .gitignore --ext .ts src/", "lint:fix": "npm run lint -- --fix" }, "dependencies": { - "@amrc-factoryplus/utilities": "^1.0.8", "@influxdata/influxdb-client": "^1.33.2", "@influxdata/influxdb-client-apis": "^1.33.2", "async": "^3.2.4", "long": "^5.2.3", + "mqtt": "^5.9.1", "pino": "^8.11.0", "pino-pretty": "^10.0.0" }, diff --git a/influxdb-injector/run-dev.sh b/influxdb-injector/run-dev.sh index cbd64e40..0dafe58b 100644 --- a/influxdb-injector/run-dev.sh +++ b/influxdb-injector/run-dev.sh @@ -4,7 +4,4 @@ # # bin/bash -tmpfile=$(mktemp) -export CLIENT_KEYTAB="$(kubectl --kubeconfig ~/.kube/fplus get -n factory-plus secret krb5-keytabs -o jsonpath="{.data.sv1warehouse}" | base64 -d >"$tmpfile" && echo "$tmpfile")" -echo $CLIENT_KEYTAB -npm run start:shell +npm run start diff --git a/influxdb-injector/src/UnsTopic.ts b/influxdb-injector/src/UnsTopic.ts new file mode 100644 index 00000000..33e2a468 --- /dev/null +++ b/influxdb-injector/src/UnsTopic.ts @@ -0,0 +1,95 @@ +import {logger} from "./logger.js"; + +interface ISA95Schema { + Enterprise?: string, + Site?: string, + Area?: string, + WorkCenter?: string, + WorkUnit?: string +} + +export class UnsTopic { + private readonly TopicString: string; + private readonly TopicArray: string[]; + private readonly EdgeIndex: number; + public ISA95Schema: ISA95Schema; + public SchemaPath: string; + public TopLevelSchema: string; + public BottomLevelSchema: string; + public MetricName: string; + public Path: string; + + constructor(topic: string) { + this.TopicString = topic; + this.TopicArray = topic.split("/"); + this.Path = topic; + this.EdgeIndex = this.TopicArray.indexOf("Edge"); + this.ISA95Schema = this.GetISA95Schema(); + this.TopLevelSchema = this.GetTopLevelSchema(); + this.BottomLevelSchema = this.GetBottomLevelSchema(); + this.SchemaPath = this.GetSchemaPath(); + this.MetricName = this.GetMetricName(); + } + + /** + * Return ISA 95 section of the topic path + */ + private GetISA95Schema(): ISA95Schema | null { + let schema: ISA95Schema = {}; + if (this.EdgeIndex === null) { + logger.error("Unable to find Edge in topic path"); + return null; + } + // our isa 95 part of the topic is between the uns version and the edge. + const ISA95TopicSlice = this.TopicArray.slice(2, this.EdgeIndex); + for (let i: number = 0; i < ISA95TopicSlice.length; i++) { + switch (i) { + case 0: + schema.Enterprise = ISA95TopicSlice[0] + break; + case 1: + schema.Site = ISA95TopicSlice[1]; + break; + case 2: + schema.Area = ISA95TopicSlice[2]; + break; + case 3: + schema.WorkCenter = ISA95TopicSlice[3]; + break; + case 4: + schema.WorkUnit = ISA95TopicSlice[4]; + break; + } + } + return schema; + } + + /** + * + */ + private GetTopLevelSchema(): string { + // the metric schema is from the edge node to the last item of the path + const schemaSlice = this.TopicArray.slice(this.EdgeIndex + 1, -1); + return schemaSlice[0]; + } + + /** + * + */ + public GetBottomLevelSchema(): string { + return this.TopicArray[-1]; + } + + /** + * + */ + private GetSchemaPath() { + return this.TopicArray.slice(this.EdgeIndex, -1).join("/"); + } + + private GetMetricName() { + return this.TopicArray[-1]; + } + + +} \ No newline at end of file diff --git a/influxdb-injector/src/app.ts b/influxdb-injector/src/app.ts new file mode 100644 index 00000000..88c4f43b --- /dev/null +++ b/influxdb-injector/src/app.ts @@ -0,0 +1,11 @@ +/* + * AMRC InfluxDB Sparkplug Ingester + * Copyright "2023" AMRC + */ + +import MQTTClient from "./mqttclient.js"; + + +const mqtt = await new MQTTClient().init(); + +mqtt.run(); diff --git a/influxdb-injector/src/logger.ts b/influxdb-injector/src/logger.ts new file mode 100644 index 00000000..7ae2176e --- /dev/null +++ b/influxdb-injector/src/logger.ts @@ -0,0 +1,19 @@ +import pretty from "pino-pretty"; +import pino from "pino"; + +let dotenv: any = null; +try { + dotenv = await import ('dotenv') +} catch (e) { +} + +const stream = pretty({ + colorize: true +}) + +dotenv?.config(); + +export const logger = pino({ + name: 'InfluxDB Sparkplug Ingester', + level: process.env.LOG_LEVEL || 'info', +}, stream); \ No newline at end of file diff --git a/influxdb-injector/src/mqttclient.ts b/influxdb-injector/src/mqttclient.ts new file mode 100644 index 00000000..240ebcf8 --- /dev/null +++ b/influxdb-injector/src/mqttclient.ts @@ -0,0 +1,292 @@ +/* + * AMRC InfluxDB Sparkplug Ingester + * Copyright "2024" AMRC + */ + +import {logger} from "./logger.js"; +import {InfluxDB, Point} from '@influxdata/influxdb-client' +import {Agent} from 'http' +import mqtt from "mqtt"; +import {UnsTopic} from "./UnsTopic.js"; + +let dotenv: any = null; +try { + dotenv = await import ('dotenv') +} catch (e) { +} + +dotenv?.config() + +const influxURL: string = process.env.INFLUX_URL; +if (!influxURL) { + throw new Error("INFLUX_URL environment variable is not set"); +} + +const influxToken: string = process.env.INFLUX_TOKEN +if (!influxToken) { + throw new Error("INFLUX_TOKEN environment variable is not set"); +} + +const influxOrganisation: string = process.env.INFLUX_ORG +if (!influxOrganisation) { + throw new Error("INFLUX_ORG environment variable is not set"); +} + +const batchSize: number = Number.parseInt(process.env.BATCH_SIZE); +if (!batchSize) { + throw new Error("BATCH_SIZE environment variable is not set"); +} + +const flushInterval: number = Number.parseInt(process.env.FLUSH_INTERVAL); +if (!flushInterval) { + throw new Error("FLUSH_INTERVAL environment variable is not set"); +} + +const mqttURL: string = process.env.MQTT_URL; +if (!mqttURL) { + throw new Error("Mqtt URL not set!"); +} + +let i = 0; + +// Node.js HTTP client OOTB does not reuse established TCP connections, a custom node HTTP agent +// can be used to reuse them and thus reduce the count of newly established networking sockets +const keepAliveAgent = new Agent({ + keepAlive: true, // reuse existing connections + keepAliveMsecs: 20 * 1000, // 20 seconds keep alive +}) + +const influxDB = new InfluxDB({ + url: influxURL, token: influxToken, transportOptions: { + agent: keepAliveAgent, + } +}) + +let interval: any; + +/* points/lines are batched in order to minimize networking and increase performance */ + +const writeApi = influxDB.getWriteApi(influxOrganisation, process.env.INFLUX_BUCKET || 'default', 'ns', { + /* the maximum points/lines to send in a single batch to InfluxDB server */ + batchSize: batchSize + 1, // don't let automatically flush data + /* maximum time in millis to keep points in an unflushed batch, 0 means don't periodically flush */ + flushInterval: 0, // Never allow the package to flush: we'll flush manually + /* maximum size of the retry buffer - it contains items that could not be sent for the first time */ + maxBufferLines: 30_000, /* the count of internally-scheduled retries upon write failure, the delays between write attempts follow an exponential backoff strategy if there is no Retry-After HTTP header */ + maxRetries: 0, // do not retry writes + // ... there are more write options that can be customized, see + // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeoptions.html and + // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeretryoptions.html +}); + +export default class MQTTClient { + private mqtt: any; + + async init() { + + process.on('exit', () => { + this.flushBuffer('EXIT'); + keepAliveAgent.destroy(); + }) + + return this; + } + + private flushBuffer(source: string) { + let bufferSize = i; + i = 0; + writeApi.flush().then(() => { + logger.info(`🚀 Flushed ${bufferSize} points to InfluxDB [${source}]`); + // Reset the interval + this.resetInterval(); + }) + } + + async run() { + this.mqtt = mqtt.connect(mqttURL); + this.mqtt.on("authenticated", this.on_connect.bind(this)); + this.mqtt.on("error", this.on_error.bind(this)); + this.mqtt.on("message", this.on_message.bind(this)); + this.mqtt.on("close", this.on_close.bind(this)); + this.mqtt.on("reconnect", this.on_reconnect.bind(this)); + logger.info("Connecting to UNS broker..."); + } + + on_connect() { + logger.info("🔌 Connected to Factory+ broker"); + logger.info("👂 Subscribing to entire UNS namespace"); + this.mqtt.subscribe('UNS/v1//#'); + this.resetInterval(); + } + + private resetInterval() { + clearInterval(interval); + interval = setInterval(() => { + this.flushBuffer(`${flushInterval}ms INTERVAL`); + }, flushInterval); + } + + on_close() { + logger.warn(`❌ Disconnected from Factory+ broker`); + + // Flush any remaining data + this.flushBuffer('CONN_CLOSE'); + } + + on_reconnect() { + logger.warn(`⚠️ Reconnecting to Factory+ broker...`); + } + + on_error(error: any) { + logger.error("🚨 MQTT error: %o", error); + // Flush any remaining data + this.flushBuffer('MQTT_ERROR'); + } + + async on_message(topicString: string, message: string) { + let payload = JSON.parse(message); + + if (!topicString) { + logger.error(`🚨 Bad topic: ${topicString}`); + return; + } + + // write metrics to influx + this.writeMetrics(payload, topicString); + return; + } + + /** + * + * @param payload + * @param topic + */ + private writeMetrics(payload, topic: string) { + const unsTopic = new UnsTopic(topic); + payload.metrics.forEach((metric) => { + let metricTimestamp: Date + if (metric.timestamp) { + metricTimestamp = new Date(metric.timestamp); + } else if (payload.timestamp) { + // Metrics might not have a timestamp so use the packet timestamp if we have it. + metricTimestamp = new Date(payload.timestamp); + } else { + // No timestamp can be found on the metric or the payload, just use the current time instead. + metricTimestamp = new Date(); + } + + const unit = "test"; + const type = "test"; + // Send each metric to InfluxDB + this.writeToInfluxDB(unsTopic, metric.value, metricTimestamp, unit, type) + }); + } + + /** + * Writes metric values to InfluxDB using the metric timestamp. + * @param topic Topic the metric was published on. + * @param value Metric value to write to InfluxDB. + * @param timestamp Timestamp from the metric to write to influx. + */ + writeToInfluxDB(topic: UnsTopic, value, timestamp: Date, unit: string, type: string) { + if (value === null) { + return; + } + let path: string = ""; + let topLevelInstance: string = ""; + let bottomLevelInstance: string = ""; + let instanceFull: string[] = []; + + writeApi.useDefaultTags({ + topLevelInstance, + bottomLevelInstance, + usesInstances: topLevelInstance + ':' + instanceFull.join(':'), + topLevelSchema: topic.TopLevelSchema, + bottomLevelSchema: topic.BottomLevelSchema, + usesSchemas: topic.TopLevelSchema + ':' + topic.SchemaPath.split("/").join(':'), + enterprise: topic.ISA95Schema.Enterprise, + site: topic.ISA95Schema.Site, + area: topic.ISA95Schema.Area, + workCenter: topic.ISA95Schema.WorkCenter, + workUnit: topic.ISA95Schema.WorkUnit, + path: topic.SchemaPath, + unit: unit + }); + + let numVal = null; + + switch (type) { + case "Int8": + case "Int16": + case "Int32": + case "Int64": + // Validate + numVal = Number(value); + if (!Number.isInteger(numVal)) { + logger.warn(`${topic.SchemaPath} should be a ${type} but received ${numVal}. Not recording.`); + return; + } + writeApi.writePoint( + new Point(`${topic.MetricName}:i`) + .intField('value', numVal) + .timestamp(timestamp) + ); + break; + case "UInt8": + case "UInt16": + case "UInt32": + case "UInt64": + // Validate + numVal = Number(value); + if (!Number.isInteger(numVal)) { + logger.warn(`${topic.Path} should be a ${type} but received ${numVal}. Not recording.`); + return; + } + writeApi.writePoint( + new Point(`${topic.MetricName}:u`) + .uintField('value', numVal) + .timestamp(timestamp) + ); + break; + case "Float": + case "Double": + // Validate + numVal = Number(value); + if (isNaN(parseFloat(numVal))) { + logger.warn(`${topic.Path} should be a ${type} but received ${numVal}. Not recording.`); + return; + } + writeApi.writePoint( + new Point(`${topic.MetricName}:d`) + .floatField('value', numVal) + .timestamp(timestamp) + ); + break; + case "Boolean": + if (typeof value != "boolean") { + logger.warn(`${topic.Path} should be a ${type} but received ${value}. Not recording.`); + return; + } + writeApi.writePoint( + new Point(`${topic.MetricName}:b`) + .booleanField('value', value) + .timestamp(timestamp)); + break; + default: + writeApi.writePoint( + new Point(`${topic.MetricName}:s`) + .stringField('value', value) + .timestamp(timestamp)); + break; + + } + + i++; + + logger.debug(`Added to write buffer (${i}/${batchSize}): [${type}] ${topic.Path} = ${value}`); + + if (i >= batchSize) { + this.flushBuffer(`${batchSize} point BATCH`); + } + } +} diff --git a/influxdb-injector/tsconfig.json b/influxdb-injector/tsconfig.json index a3a2f0a7..d8b795ae 100644 --- a/influxdb-injector/tsconfig.json +++ b/influxdb-injector/tsconfig.json @@ -2,8 +2,14 @@ "compileOnSave": false, "compilerOptions": { "target": "es2017", - "lib": ["es2017", "esnext.asynciterable", "dom"], - "typeRoots": ["node_modules/@types"], + "lib": [ + "es2017", + "esnext.asynciterable", + "dom" + ], + "typeRoots": [ + "node_modules/@types" + ], "allowSyntheticDefaultImports": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, @@ -13,20 +19,19 @@ "pretty": true, "sourceMap": true, "declaration": true, - "outDir": "dist", + "outDir": "./dist", "allowJs": true, "noEmit": false, "esModuleInterop": true, "resolveJsonModule": true, "importHelpers": true, "skipLibCheck": true, - "baseUrl": "src", - "paths": { - "@/*": ["*"], - "@bin/*": ["../bin/*"], - "@lib/*": ["../lib/*"] - } + "rootDir": "./src" }, - "include": ["bin/**/*.ts", "lib/**/*.json", ".env"], - "exclude": ["node_modules"] + "exclude": [ + "node_modules" + ], + "include": [ + "src/**/*" + ] } diff --git a/ingesters/sparkplug/run-dev.sh b/ingesters/sparkplug/run-dev.sh index 2f90906d..7665707a 100644 --- a/ingesters/sparkplug/run-dev.sh +++ b/ingesters/sparkplug/run-dev.sh @@ -4,7 +4,5 @@ # # bin/bash -tmpfile=$(mktemp) -export CLIENT_KEYTAB="$(kubectl --kubeconfig ~/.kube/fplus get -n factory-plus secret krb5-keytabs -o jsonpath="{.data.sv1warehouse}" | base64 -d >"$tmpfile" && echo "$tmpfile")" -echo $CLIENT_KEYTAB +export CLIENT_KEYTAB=keytab npm run start:shell From 32d19805e7d8ae5cf57ee9ddca56378fdb6ca741 Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Wed, 7 Aug 2024 14:06:14 +0100 Subject: [PATCH 22/58] Influx-Injector: Add parsing custom properties --- influxdb-injector/src/Types/index.d.ts | 30 +++++++ influxdb-injector/src/{ => Utils}/UnsTopic.ts | 8 -- influxdb-injector/src/{ => Utils}/logger.ts | 0 influxdb-injector/src/mqttclient.ts | 86 ++++++++++++------- 4 files changed, 87 insertions(+), 37 deletions(-) create mode 100644 influxdb-injector/src/Types/index.d.ts rename influxdb-injector/src/{ => Utils}/UnsTopic.ts (94%) rename influxdb-injector/src/{ => Utils}/logger.ts (100%) diff --git a/influxdb-injector/src/Types/index.d.ts b/influxdb-injector/src/Types/index.d.ts new file mode 100644 index 00000000..bd8c7890 --- /dev/null +++ b/influxdb-injector/src/Types/index.d.ts @@ -0,0 +1,30 @@ +/** + * UNS payload body + */ +interface MetricPayload { + timestamp: string, + value: string + batch?: MetricPayload[] +} + +/** + * MQTTV5 custom properties + */ +interface UnsMetricCustomProperties { + Instance_UUID: string, + Schema_UUID: string, + Transient: boolean, + Unit: string, + Type: string +} + +/** + * ISA95 information for a device + */ +interface ISA95Schema { + Enterprise?: string, + Site?: string, + Area?: string, + WorkCenter?: string, + WorkUnit?: string +} \ No newline at end of file diff --git a/influxdb-injector/src/UnsTopic.ts b/influxdb-injector/src/Utils/UnsTopic.ts similarity index 94% rename from influxdb-injector/src/UnsTopic.ts rename to influxdb-injector/src/Utils/UnsTopic.ts index 33e2a468..e2bbe99b 100644 --- a/influxdb-injector/src/UnsTopic.ts +++ b/influxdb-injector/src/Utils/UnsTopic.ts @@ -1,13 +1,5 @@ import {logger} from "./logger.js"; -interface ISA95Schema { - Enterprise?: string, - Site?: string, - Area?: string, - WorkCenter?: string, - WorkUnit?: string -} - export class UnsTopic { private readonly TopicString: string; private readonly TopicArray: string[]; diff --git a/influxdb-injector/src/logger.ts b/influxdb-injector/src/Utils/logger.ts similarity index 100% rename from influxdb-injector/src/logger.ts rename to influxdb-injector/src/Utils/logger.ts diff --git a/influxdb-injector/src/mqttclient.ts b/influxdb-injector/src/mqttclient.ts index 240ebcf8..051c457f 100644 --- a/influxdb-injector/src/mqttclient.ts +++ b/influxdb-injector/src/mqttclient.ts @@ -3,11 +3,11 @@ * Copyright "2024" AMRC */ -import {logger} from "./logger.js"; +import {logger} from "./Utils/logger.js"; import {InfluxDB, Point} from '@influxdata/influxdb-client' import {Agent} from 'http' import mqtt from "mqtt"; -import {UnsTopic} from "./UnsTopic.js"; +import {UnsTopic} from "./Utils/UnsTopic.js"; let dotenv: any = null; try { @@ -66,21 +66,25 @@ let interval: any; /* points/lines are batched in order to minimize networking and increase performance */ -const writeApi = influxDB.getWriteApi(influxOrganisation, process.env.INFLUX_BUCKET || 'default', 'ns', { - /* the maximum points/lines to send in a single batch to InfluxDB server */ - batchSize: batchSize + 1, // don't let automatically flush data - /* maximum time in millis to keep points in an unflushed batch, 0 means don't periodically flush */ - flushInterval: 0, // Never allow the package to flush: we'll flush manually - /* maximum size of the retry buffer - it contains items that could not be sent for the first time */ - maxBufferLines: 30_000, /* the count of internally-scheduled retries upon write failure, the delays between write attempts follow an exponential backoff strategy if there is no Retry-After HTTP header */ - maxRetries: 0, // do not retry writes - // ... there are more write options that can be customized, see - // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeoptions.html and - // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeretryoptions.html -}); +const writeApi = influxDB.getWriteApi(influxOrganisation, + process.env.INFLUX_BUCKET || 'default', + 'ns', + { + /* the maximum points/lines to send in a single batch to InfluxDB server */ + batchSize: batchSize + 1, // don't let automatically flush data + /* maximum time in millis to keep points in an unflushed batch, 0 means don't periodically flush */ + flushInterval: 0, // Never allow the package to flush: we'll flush manually + /* maximum size of the retry buffer - it contains items that could not be sent for the first time */ + maxBufferLines: 30_000, /* the count of internally-scheduled retries upon write failure, the delays between write attempts follow an exponential backoff strategy if there is no Retry-After HTTP header */ + maxRetries: 0, // do not retry writes + // ... there are more write options that can be customized, see + // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeoptions.html and + // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeretryoptions.html + } +); export default class MQTTClient { - private mqtt: any; + private mqtt: mqtt.MqttClient; async init() { @@ -103,8 +107,10 @@ export default class MQTTClient { } async run() { - this.mqtt = mqtt.connect(mqttURL); - this.mqtt.on("authenticated", this.on_connect.bind(this)); + this.mqtt = mqtt.connect(mqttURL, { + protocolVersion: 5 + }); + this.mqtt.on("connect", this.on_connect.bind(this)); this.mqtt.on("error", this.on_error.bind(this)); this.mqtt.on("message", this.on_message.bind(this)); this.mqtt.on("close", this.on_close.bind(this)); @@ -115,7 +121,7 @@ export default class MQTTClient { on_connect() { logger.info("🔌 Connected to Factory+ broker"); logger.info("👂 Subscribing to entire UNS namespace"); - this.mqtt.subscribe('UNS/v1//#'); + this.mqtt.subscribe("UNS/v1/#"); this.resetInterval(); } @@ -143,16 +149,25 @@ export default class MQTTClient { this.flushBuffer('MQTT_ERROR'); } - async on_message(topicString: string, message: string) { - let payload = JSON.parse(message); + async on_message(topicString: string, payload: Buffer, packet: mqtt.IPublishPacket) { + const messageString = payload.toString(); + if (!packet.properties.userProperties) { + logger.error(`⁉ Can't find custom properties for topic ${topicString}! Not writing to Influx.`); + return + } + + const customProperties = + packet.properties.userProperties as unknown as UnsMetricCustomProperties; + const metricPayload: MetricPayload = JSON.parse(messageString); + logger.info(`🎉 Received ${messageString} from topic ${topicString}`); if (!topicString) { logger.error(`🚨 Bad topic: ${topicString}`); return; } // write metrics to influx - this.writeMetrics(payload, topicString); + this.writeMetrics(metricPayload, topicString, customProperties); return; } @@ -160,10 +175,25 @@ export default class MQTTClient { * * @param payload * @param topic + * @param customProperties */ - private writeMetrics(payload, topic: string) { + private writeMetrics(payload: MetricPayload, topic: string, customProperties: UnsMetricCustomProperties) { const unsTopic = new UnsTopic(topic); - payload.metrics.forEach((metric) => { + let metricTimestamp: Date + if (payload.timestamp) { + metricTimestamp = new Date(payload.timestamp); + } else if (payload.timestamp) { + // Metrics might not have a timestamp so use the packet timestamp if we have it. + metricTimestamp = new Date(payload.timestamp); + } else { + // No timestamp can be found on the metric or the payload, just use the current time instead. + metricTimestamp = new Date(); + } + + this.writeToInfluxDB(unsTopic, payload.value, metricTimestamp, customProperties.Unit, customProperties.Type); + + // Handle the batched metrics + payload.batch?.forEach((metric) => { let metricTimestamp: Date if (metric.timestamp) { metricTimestamp = new Date(metric.timestamp); @@ -174,11 +204,8 @@ export default class MQTTClient { // No timestamp can be found on the metric or the payload, just use the current time instead. metricTimestamp = new Date(); } - - const unit = "test"; - const type = "test"; // Send each metric to InfluxDB - this.writeToInfluxDB(unsTopic, metric.value, metricTimestamp, unit, type) + this.writeToInfluxDB(unsTopic, metric.value, metricTimestamp, customProperties.Unit, customProperties.Type); }); } @@ -187,12 +214,13 @@ export default class MQTTClient { * @param topic Topic the metric was published on. * @param value Metric value to write to InfluxDB. * @param timestamp Timestamp from the metric to write to influx. + * @param unit + * @param type */ - writeToInfluxDB(topic: UnsTopic, value, timestamp: Date, unit: string, type: string) { + writeToInfluxDB(topic: UnsTopic, value: string, timestamp: Date, unit: string, type: string) { if (value === null) { return; } - let path: string = ""; let topLevelInstance: string = ""; let bottomLevelInstance: string = ""; let instanceFull: string[] = []; From dc377c7dfc7d3b0e314ad01912c4f8f8d66c2f9a Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Wed, 7 Aug 2024 14:15:48 +0100 Subject: [PATCH 23/58] ingester/sparkplug: Add new custom properties --- ingesters/sparkplug/lib/mqttclient.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ingesters/sparkplug/lib/mqttclient.ts b/ingesters/sparkplug/lib/mqttclient.ts index f2459468..ed83db77 100644 --- a/ingesters/sparkplug/lib/mqttclient.ts +++ b/ingesters/sparkplug/lib/mqttclient.ts @@ -20,6 +20,8 @@ interface UnsMetricCustomProperties { Instance_UUID: string, Schema_UUID: string, Transient: boolean, + Unit: string, + Type: string } interface MetricContainer { @@ -406,10 +408,12 @@ export default class MQTTClient { } // Build custom properties object - let customProperties: UnsMetricCustomProperties = { + const customProperties: UnsMetricCustomProperties = { + Type: birth.type, + Unit: birth.unit, Instance_UUID: birth.instance.top, Schema_UUID: birth.schema.top, - Transient: birth.transient, + Transient: birth.transient } // Here we can access the ISA95 hierarchy information from the birth.isa95 object. This object contains the following keys: From ccd949f23484444520bbb380433661f2c4475a0a Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Wed, 7 Aug 2024 16:36:37 +0100 Subject: [PATCH 24/58] Add additional user properties to payload --- ingesters/sparkplug/lib/mqttclient.ts | 4 +++- ingesters/sparkplug/run-dev.sh | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) mode change 100644 => 100755 ingesters/sparkplug/run-dev.sh diff --git a/ingesters/sparkplug/lib/mqttclient.ts b/ingesters/sparkplug/lib/mqttclient.ts index ed83db77..e752c6cd 100644 --- a/ingesters/sparkplug/lib/mqttclient.ts +++ b/ingesters/sparkplug/lib/mqttclient.ts @@ -517,7 +517,9 @@ export default class MQTTClient { userProperties: { Instance_UUID: metricContainers[0]?.customProperties.Instance_UUID, Schema_UUID: metricContainers[0].customProperties.Schema_UUID, - Transient: metricContainers[0].customProperties.Transient ?? false + Transient: metricContainers[0].customProperties.Transient ?? false, + Unit: metricContainers[0].customProperties.Unit ?? '', + Type: metricContainers[0].customProperties.Type ?? 'undefined' } } }); diff --git a/ingesters/sparkplug/run-dev.sh b/ingesters/sparkplug/run-dev.sh old mode 100644 new mode 100755 index 7665707a..ab43a959 --- a/ingesters/sparkplug/run-dev.sh +++ b/ingesters/sparkplug/run-dev.sh @@ -4,5 +4,6 @@ # # bin/bash -export CLIENT_KEYTAB=keytab +tmpfile=$(mktemp) +export CLIENT_KEYTAB="$(kubectl --kubeconfig ~/.kube/p2.yaml get -n factory-plus secret krb5-keytabs -o jsonpath="{.data.sv1warehouse}" | base64 -d >"$tmpfile" && echo "$tmpfile")" npm run start:shell From 6c0e391ea030a23190afef4c9e4aae491a22a86a Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Wed, 7 Aug 2024 16:54:01 +0100 Subject: [PATCH 25/58] Influx_Injector: Fixed null metric name --- influxdb-injector/src/Utils/UnsTopic.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/influxdb-injector/src/Utils/UnsTopic.ts b/influxdb-injector/src/Utils/UnsTopic.ts index e2bbe99b..f4d093e8 100644 --- a/influxdb-injector/src/Utils/UnsTopic.ts +++ b/influxdb-injector/src/Utils/UnsTopic.ts @@ -79,8 +79,11 @@ export class UnsTopic { return this.TopicArray.slice(this.EdgeIndex, -1).join("/"); } + /** + * + */ private GetMetricName() { - return this.TopicArray[-1]; + return this.TopicArray[this.TopicArray.length - 1]; } From a5ec38566e2dc31c09617114630f45e5d40a3685 Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Thu, 8 Aug 2024 14:45:38 +0100 Subject: [PATCH 26/58] Ingesters/Sparkplug: Add custom properties for instance and schema --- ingesters/sparkplug/lib/mqttclient.ts | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/ingesters/sparkplug/lib/mqttclient.ts b/ingesters/sparkplug/lib/mqttclient.ts index e752c6cd..dbad9092 100644 --- a/ingesters/sparkplug/lib/mqttclient.ts +++ b/ingesters/sparkplug/lib/mqttclient.ts @@ -17,11 +17,13 @@ interface UnsMetric { } interface UnsMetricCustomProperties { - Instance_UUID: string, - Schema_UUID: string, + InstanceUUID: string, + SchemaUUID: string, Transient: boolean, Unit: string, - Type: string + Type: string, + InstanceUUIDPath: string, + SchemaUUIDPath: string } interface MetricContainer { @@ -406,13 +408,14 @@ export default class MQTTClient { if (metricName === "Instance_UUID" || metricName === "Schema_UUID") { return; } - // Build custom properties object const customProperties: UnsMetricCustomProperties = { + InstanceUUIDPath: birth.instance.top + ':' + birth.instance.full.join(':'), + SchemaUUIDPath: birth.schema.top + ':' + birth.schema.full.join(':'), Type: birth.type, Unit: birth.unit, - Instance_UUID: birth.instance.top, - Schema_UUID: birth.schema.top, + InstanceUUID: birth.instance.top, + SchemaUUID: birth.schema.top, Transient: birth.transient } @@ -501,12 +504,12 @@ export default class MQTTClient { }; } - if (!metricContainers[0]?.customProperties.Instance_UUID) { + if (!metricContainers[0]?.customProperties.InstanceUUID) { logger.warn(`${topic} is not broadcasting an Instance_UUID. Not publishing to UNS.`); return; } - if (!metricContainers[0]?.customProperties.Schema_UUID) { + if (!metricContainers[0]?.customProperties.SchemaUUID) { logger.warn(`${topic} is not broadcasting a Schema_UUID. Not publishing to UNS.`); return; } @@ -515,11 +518,13 @@ export default class MQTTClient { properties: { // Assume that all metrics have the same custom properties userProperties: { - Instance_UUID: metricContainers[0]?.customProperties.Instance_UUID, - Schema_UUID: metricContainers[0].customProperties.Schema_UUID, + InstanceUUID: metricContainers[0]?.customProperties.InstanceUUID, + SchemaUUID: metricContainers[0].customProperties.SchemaUUID, Transient: metricContainers[0].customProperties.Transient ?? false, Unit: metricContainers[0].customProperties.Unit ?? '', - Type: metricContainers[0].customProperties.Type ?? 'undefined' + Type: metricContainers[0].customProperties.Type ?? 'undefined', + InstanceUUIDPath: metricContainers[0].customProperties.InstanceUUIDPath ?? "", + SchemaUUIDPath: metricContainers[0].customProperties.SchemaUUIDPath ?? "", } } }); From 1936d3aa580c4529fe8c0a19a18ccff60e1d9584 Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Thu, 8 Aug 2024 14:46:07 +0100 Subject: [PATCH 27/58] Influx-Injector: Add custom properties for schema and instance --- influxdb-injector/src/Types/index.d.ts | 8 +- influxdb-injector/src/Utils/UnsTopic.ts | 122 ++++++++++++++++++------ influxdb-injector/src/mqttclient.ts | 50 +++++----- 3 files changed, 122 insertions(+), 58 deletions(-) diff --git a/influxdb-injector/src/Types/index.d.ts b/influxdb-injector/src/Types/index.d.ts index bd8c7890..bcd9fbab 100644 --- a/influxdb-injector/src/Types/index.d.ts +++ b/influxdb-injector/src/Types/index.d.ts @@ -11,11 +11,13 @@ interface MetricPayload { * MQTTV5 custom properties */ interface UnsMetricCustomProperties { - Instance_UUID: string, - Schema_UUID: string, + InstanceUUID: string, + SchemaUUID: string, Transient: boolean, Unit: string, - Type: string + Type: string, + InstanceUUIDPath: string, + SchemaUUIDPath: string } /** diff --git a/influxdb-injector/src/Utils/UnsTopic.ts b/influxdb-injector/src/Utils/UnsTopic.ts index f4d093e8..2eb9add2 100644 --- a/influxdb-injector/src/Utils/UnsTopic.ts +++ b/influxdb-injector/src/Utils/UnsTopic.ts @@ -1,38 +1,44 @@ import {logger} from "./logger.js"; +/** + * Creates a new topic to extract data from the topic path and custom properties. + */ export class UnsTopic { private readonly TopicString: string; private readonly TopicArray: string[]; private readonly EdgeIndex: number; - public ISA95Schema: ISA95Schema; - public SchemaPath: string; - public TopLevelSchema: string; - public BottomLevelSchema: string; - public MetricName: string; - public Path: string; + private readonly SchemaUUIDPath: string[]; + private readonly InstanceUUIDPath: string[]; + private ISA95Schema: ISA95Schema; - constructor(topic: string) { + /** + * Creates a new topic to extract data from the topic path and custom properties. + * @param topic UNS topic the metric was published on. + * @param properties The MQTTv5 user properties on the metric payload. + */ + constructor(topic: string, properties: UnsMetricCustomProperties) { this.TopicString = topic; this.TopicArray = topic.split("/"); - this.Path = topic; this.EdgeIndex = this.TopicArray.indexOf("Edge"); - this.ISA95Schema = this.GetISA95Schema(); - this.TopLevelSchema = this.GetTopLevelSchema(); - this.BottomLevelSchema = this.GetBottomLevelSchema(); - this.SchemaPath = this.GetSchemaPath(); - this.MetricName = this.GetMetricName(); + this.SchemaUUIDPath = properties.SchemaUUIDPath.split(':'); + this.InstanceUUIDPath = properties.InstanceUUIDPath.split(':'); } /** - * Return ISA 95 section of the topic path + * Returns ISA 95 section of the topic path. */ - private GetISA95Schema(): ISA95Schema | null { + public GetISA95Schema(): ISA95Schema | null { + // check if its already cached. + if (this.ISA95Schema) { + return this.ISA95Schema; + } + let schema: ISA95Schema = {}; if (this.EdgeIndex === null) { logger.error("Unable to find Edge in topic path"); return null; } - // our isa 95 part of the topic is between the uns version and the edge. + // our ISA95 part of the topic is between the uns version and the edge. const ISA95TopicSlice = this.TopicArray.slice(2, this.EdgeIndex); for (let i: number = 0; i < ISA95TopicSlice.length; i++) { switch (i) { @@ -53,38 +59,96 @@ export class UnsTopic { break; } } + // cache the schema to we don't have to create it again. + this.ISA95Schema = schema; return schema; } /** - * + * Gets the full UUID path of the schema, this does **NOT** include the top level schema UUID. */ - private GetTopLevelSchema(): string { - // the metric schema is from the edge node to the last item of the path - const schemaSlice = this.TopicArray.slice(this.EdgeIndex + 1, -1); - return schemaSlice[0]; + public GetSchemaFull(): string { + const schemaUUIDArray = [...this.SchemaUUIDPath]; + // The schema full property can only have a value if the path has greater than 1 element + if (!this.SchemaUUIDPath || schemaUUIDArray.length <= 1) { + return ""; + } + schemaUUIDArray.shift() + return schemaUUIDArray.join(":"); } /** - * + * Gets the Top level of the schema UUID path. This is the UUID from the root schema. + */ + public GetTopLevelSchema(): string { + // the top level is always the first element in this path. All schema uuid path's should have + // at least one element. + if (!this.SchemaUUIDPath || this.SchemaUUIDPath.length === 0) { + logger.warn("🔥 Schema UUID path has no elements.") + return ""; + } + return this.SchemaUUIDPath[0] + } + + /** + * Gets the bottom level schema UUID. This is the last schema UUID in the schema path. */ public GetBottomLevelSchema(): string { - return this.TopicArray[-1]; + // a bottom level schema will only be populated if we have more than two items in the schema path. + if (!this.SchemaUUIDPath || this.SchemaUUIDPath.length <= 2) { + return ""; + } + return this.SchemaUUIDPath[this.SchemaUUIDPath.length - 1]; } /** - * + * Gets the full UUID instance path, this does **NOT** include the top level instance UUID. */ - private GetSchemaPath() { - return this.TopicArray.slice(this.EdgeIndex, -1).join("/"); + public GetInstanceFull(): string { + const instanceUUIDArray = [...this.InstanceUUIDPath]; + // The instance full property can only have a value if the path has greater than one element. + if (!this.InstanceUUIDPath || instanceUUIDArray.length <= 1) { + return ""; + } + instanceUUIDArray.shift() + return instanceUUIDArray.join(":"); } /** - * + * Gets the Top level of the instance UUID path. This is the UUID from the root instance. */ - private GetMetricName() { - return this.TopicArray[this.TopicArray.length - 1]; + public GetTopLevelInstance(): string { + // the top level is always the first element in this path. All instance uuid path should have + // at least one element. + if (!this.InstanceUUIDPath || this.InstanceUUIDPath.length === 0) { + logger.warn("🔥 Schema UUID path has no elements.") + return ""; + } + return this.InstanceUUIDPath[0] } + /** + * Gets the bottom level instance UUID. This is the last instance UUID in the instance path. + */ + public GetBottomLevelInstance(): string { + // a bottom level instance will only be populated if we have more than two items in the schema path. + if (!this.InstanceUUIDPath || this.InstanceUUIDPath.length <= 2) { + return ""; + } + return this.InstanceUUIDPath[this.InstanceUUIDPath.length - 1]; + } + /** + * Gets the full path of the metric, excluding the ISA95 portion of the topic. + */ + public GetMetricPath() { + return this.TopicArray.slice(this.EdgeIndex + 1, -1).join("/"); + } + + /** + * Gets the name of the metric which is the last element in the schema path. + */ + public GetMetricName() { + return this.TopicArray[this.TopicArray.length - 1]; + } } \ No newline at end of file diff --git a/influxdb-injector/src/mqttclient.ts b/influxdb-injector/src/mqttclient.ts index 051c457f..2f42d403 100644 --- a/influxdb-injector/src/mqttclient.ts +++ b/influxdb-injector/src/mqttclient.ts @@ -8,6 +8,7 @@ import {InfluxDB, Point} from '@influxdata/influxdb-client' import {Agent} from 'http' import mqtt from "mqtt"; import {UnsTopic} from "./Utils/UnsTopic.js"; +import * as path from "node:path"; let dotenv: any = null; try { @@ -178,7 +179,7 @@ export default class MQTTClient { * @param customProperties */ private writeMetrics(payload: MetricPayload, topic: string, customProperties: UnsMetricCustomProperties) { - const unsTopic = new UnsTopic(topic); + const unsTopic = new UnsTopic(topic, customProperties); let metricTimestamp: Date if (payload.timestamp) { metricTimestamp = new Date(payload.timestamp); @@ -221,23 +222,20 @@ export default class MQTTClient { if (value === null) { return; } - let topLevelInstance: string = ""; - let bottomLevelInstance: string = ""; - let instanceFull: string[] = []; writeApi.useDefaultTags({ - topLevelInstance, - bottomLevelInstance, - usesInstances: topLevelInstance + ':' + instanceFull.join(':'), - topLevelSchema: topic.TopLevelSchema, - bottomLevelSchema: topic.BottomLevelSchema, - usesSchemas: topic.TopLevelSchema + ':' + topic.SchemaPath.split("/").join(':'), - enterprise: topic.ISA95Schema.Enterprise, - site: topic.ISA95Schema.Site, - area: topic.ISA95Schema.Area, - workCenter: topic.ISA95Schema.WorkCenter, - workUnit: topic.ISA95Schema.WorkUnit, - path: topic.SchemaPath, + topLevelInstance: topic.GetTopLevelInstance(), + bottomLevelInstance: topic.GetBottomLevelInstance(), + usesInstances: `${topic.GetTopLevelInstance()}:${topic.GetInstanceFull()}`, + topLevelSchema: topic.GetTopLevelSchema(), + bottomLevelSchema: topic.GetBottomLevelSchema(), + usesSchemas: `${topic.GetTopLevelSchema()}:${topic.GetSchemaFull()}`, + enterprise: topic.GetISA95Schema().Enterprise ?? "", + site: topic.GetISA95Schema().Site ?? "", + area: topic.GetISA95Schema().Area ?? "", + workCenter: topic.GetISA95Schema().WorkCenter ?? "", + workUnit: topic.GetISA95Schema().WorkUnit ?? "", + path: topic.GetMetricPath(), unit: unit }); @@ -251,11 +249,11 @@ export default class MQTTClient { // Validate numVal = Number(value); if (!Number.isInteger(numVal)) { - logger.warn(`${topic.SchemaPath} should be a ${type} but received ${numVal}. Not recording.`); + logger.warn(`${topic.GetMetricPath()} should be a ${type} but received ${numVal}. Not recording.`); return; } writeApi.writePoint( - new Point(`${topic.MetricName}:i`) + new Point(`${topic.GetMetricName()}:i`) .intField('value', numVal) .timestamp(timestamp) ); @@ -267,11 +265,11 @@ export default class MQTTClient { // Validate numVal = Number(value); if (!Number.isInteger(numVal)) { - logger.warn(`${topic.Path} should be a ${type} but received ${numVal}. Not recording.`); + logger.warn(`${topic.GetMetricPath()} should be a ${type} but received ${numVal}. Not recording.`); return; } writeApi.writePoint( - new Point(`${topic.MetricName}:u`) + new Point(`${topic.GetMetricName()}:u`) .uintField('value', numVal) .timestamp(timestamp) ); @@ -281,28 +279,28 @@ export default class MQTTClient { // Validate numVal = Number(value); if (isNaN(parseFloat(numVal))) { - logger.warn(`${topic.Path} should be a ${type} but received ${numVal}. Not recording.`); + logger.warn(`${topic.GetMetricPath()} should be a ${type} but received ${numVal}. Not recording.`); return; } writeApi.writePoint( - new Point(`${topic.MetricName}:d`) + new Point(`${topic.GetMetricName()}:d`) .floatField('value', numVal) .timestamp(timestamp) ); break; case "Boolean": if (typeof value != "boolean") { - logger.warn(`${topic.Path} should be a ${type} but received ${value}. Not recording.`); + logger.warn(`${topic.GetMetricPath()} should be a ${type} but received ${value}. Not recording.`); return; } writeApi.writePoint( - new Point(`${topic.MetricName}:b`) + new Point(`${topic.GetMetricName()}:b`) .booleanField('value', value) .timestamp(timestamp)); break; default: writeApi.writePoint( - new Point(`${topic.MetricName}:s`) + new Point(`${topic.GetMetricName()}:s`) .stringField('value', value) .timestamp(timestamp)); break; @@ -311,7 +309,7 @@ export default class MQTTClient { i++; - logger.debug(`Added to write buffer (${i}/${batchSize}): [${type}] ${topic.Path} = ${value}`); + logger.debug(`Added to write buffer (${i}/${batchSize}): [${type}] ${topic.GetMetricPath()} = ${value}`); if (i >= batchSize) { this.flushBuffer(`${batchSize} point BATCH`); From 7a7e829855da6e6b8505b507aade832fcf317cb5 Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Thu, 8 Aug 2024 14:58:35 +0100 Subject: [PATCH 28/58] influx-injector: Add missing UnsTopic comment --- influxdb-injector/src/Utils/UnsTopic.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/influxdb-injector/src/Utils/UnsTopic.ts b/influxdb-injector/src/Utils/UnsTopic.ts index 2eb9add2..eb4d26d4 100644 --- a/influxdb-injector/src/Utils/UnsTopic.ts +++ b/influxdb-injector/src/Utils/UnsTopic.ts @@ -1,7 +1,11 @@ import {logger} from "./logger.js"; /** - * Creates a new topic to extract data from the topic path and custom properties. + * The UnsTopic class is designed to parse UNS MQTT topics and extract relevant information from + * them. UNS topics follow a structured NAMESAPCE_VERSION/ISA95_STRUCTURE/METRIC_PATH. + * This class provides methods to dissect these topics and retrieve specific data, such as + * device location, metric path and schema and instance UUID paths, based on the predefined structure of + * the topic string and MQTTv5 custom properties. */ export class UnsTopic { private readonly TopicString: string; From 2595f95163c2e1a95f27cb9f6440ea9d4d95f4e2 Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Fri, 9 Aug 2024 11:56:45 +0100 Subject: [PATCH 29/58] Migrate to single broker --- ingesters/sparkplug/lib/mqttclient.ts | 40 ++++++++------------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/ingesters/sparkplug/lib/mqttclient.ts b/ingesters/sparkplug/lib/mqttclient.ts index dbad9092..59015410 100644 --- a/ingesters/sparkplug/lib/mqttclient.ts +++ b/ingesters/sparkplug/lib/mqttclient.ts @@ -8,8 +8,6 @@ import {Reader} from "protobufjs"; import {logger} from "../bin/ingester.js"; import Long from "long"; -import * as mqttjs from "mqtt"; - interface UnsMetric { value: string, timestamp: Date, @@ -39,11 +37,6 @@ try { dotenv?.config() -const unsMqttUrl: string = process.env.UNS_MQTT_URL; -if (!unsMqttUrl) { - throw new Error("UNS_MQTT_URL environment variable is not set"); -} - interface MQTTClientConstructorParams { e: { serviceClient: ServiceClient; @@ -54,7 +47,6 @@ export default class MQTTClient { private serviceClient: ServiceClient; private aliasResolver = {}; private birthDebounce = {}; - private unsBroker: any; private sparkplugBroker: any; constructor({e}: MQTTClientConstructorParams) { @@ -62,40 +54,30 @@ export default class MQTTClient { } async run() { - this.unsBroker = mqttjs.connect(unsMqttUrl, { - protocolVersion: 5, - }); - this.unsBroker.on("connect", () => { - logger.info("✔ Connected to local mqtt broker!"); - }); - this.unsBroker.on("error", (error) => { - logger.error(`🔥 Error from broker: ${error}`); - }) - const sparkplugBroker = await this.serviceClient.mqtt_client(); - this.sparkplugBroker = sparkplugBroker; + this.sparkplugBroker = await this.serviceClient.mqtt_client(); - sparkplugBroker.on("connect", this.onConnect.bind(this)); - sparkplugBroker.on("error", this.onError.bind(this)); - sparkplugBroker.on("message", this.onMessage.bind(this)); - sparkplugBroker.on("close", this.onClose.bind(this)); - sparkplugBroker.on("reconnect", this.onReconnect.bind(this)); + this.sparkplugBroker.on("connect", this.onConnect.bind(this)); + this.sparkplugBroker.on("error", this.onError.bind(this)); + this.sparkplugBroker.on("message", this.onMessage.bind(this)); + this.sparkplugBroker.on("close", this.onClose.bind(this)); + this.sparkplugBroker.on("reconnect", this.onReconnect.bind(this)); - logger.info("Connecting to Sparkplug channel..."); + logger.info("Connecting to MQTT Broker..."); } onConnect() { - logger.info("🔌 Connected to Sparkplug channel"); + logger.info("🔌 Connected to MQTT Broker"); logger.info("👂 Subscribing to entire Factory+ namespace"); this.sparkplugBroker.subscribe('spBv1.0/#'); } onClose() { - logger.warn(`❌ Disconnected from Sparkplug channel`); + logger.warn(`❌ Disconnected from MQTT Broker`); } onReconnect() { - logger.warn(`⚠️ Reconnecting to Sparkplug channel...`); + logger.warn(`⚠️ Reconnecting to MQTT Broker...`); } onError(error: any) { @@ -514,7 +496,7 @@ export default class MQTTClient { return; } - this.unsBroker.publish(topic, JSON.stringify(payload), { + this.sparkplugBroker.publish(topic, JSON.stringify(payload), { properties: { // Assume that all metrics have the same custom properties userProperties: { From 48fe3e191e490139bbcb28954b0c6c5da86097b8 Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Fri, 9 Aug 2024 13:53:21 +0100 Subject: [PATCH 30/58] InfluxDB-Injector: Add F+ service client --- influxdb-injector/.env.example | 2 +- influxdb-injector/package-lock.json | 1292 +++++++++++++++++++++-- influxdb-injector/package.json | 3 + influxdb-injector/run-dev.sh | 4 +- influxdb-injector/src/Types/index.d.ts | 9 + influxdb-injector/src/Utils/UnsTopic.ts | 2 +- influxdb-injector/src/app.ts | 49 +- influxdb-injector/src/mqttclient.ts | 44 +- 8 files changed, 1315 insertions(+), 90 deletions(-) diff --git a/influxdb-injector/.env.example b/influxdb-injector/.env.example index 0c28356b..07dbd492 100644 --- a/influxdb-injector/.env.example +++ b/influxdb-injector/.env.example @@ -5,4 +5,4 @@ INFLUX_BUCKET=default LOG_LEVEL=info BATCH_SIZE=5000 FLUSH_INTERVAL=10000 -MQTT_URL=mqtt.local.acs.app.amrc.co.uk:1883 \ No newline at end of file +DIRECTORY_URL=http://directory.factoryplusdomain.com diff --git a/influxdb-injector/package-lock.json b/influxdb-injector/package-lock.json index af150b6b..9bfc0058 100644 --- a/influxdb-injector/package-lock.json +++ b/influxdb-injector/package-lock.json @@ -9,9 +9,11 @@ "version": "1.0.0", "license": "MIT", "dependencies": { + "@amrc-factoryplus/service-client": "^1.3.6", "@influxdata/influxdb-client": "^1.33.2", "@influxdata/influxdb-client-apis": "^1.33.2", "async": "^3.2.4", + "gssapi.js": "^2.0.1", "long": "^5.2.3", "mqtt": "^5.9.1", "pino": "^8.11.0", @@ -24,6 +26,22 @@ "tsc-alias": "^1.7.0" } }, + "node_modules/@amrc-factoryplus/service-client": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@amrc-factoryplus/service-client/-/service-client-1.3.6.tgz", + "integrity": "sha512-4t+/SDJwoqdY+5D2DIiF/xnB2RGjG3IIzy7qxewHVCBIJ8Q2CUEZlwt5ayts9mGmM/LHsQw9NHKes664tPqyYQ==", + "dependencies": { + "content-type": "^1.0.5", + "mqtt": "^5.3.6", + "optional-js": "^2.3.0", + "semver": "^7.6.0", + "sparkplug-payload": "^1.0.3" + }, + "optionalDependencies": { + "got-fetch": "^5.1.8", + "gssapi.js": "^2.0.1" + } + }, "node_modules/@babel/runtime": { "version": "7.25.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", @@ -120,6 +138,86 @@ "node": ">= 8" } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "node_modules/@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "optional": true, + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "optional": true, + "peer": true, + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -144,6 +242,18 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "optional": true, + "peer": true + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, "node_modules/@types/node": { "version": "18.15.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", @@ -203,6 +313,19 @@ "node": ">=0.4.0" } }, + "node_modules/ansi": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", + "integrity": "sha512-iFY7JCgHbepc0b82yLaw4IMortylNb6wG4kL+4R0C3iv6i+RHGHux/yUX5BTiRvSX/shMnngjR1YyNMnXEFh5A==" + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -216,6 +339,48 @@ "node": ">= 8" } }, + "node_modules/are-we-there-yet": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.0.6.tgz", + "integrity": "sha512-Zfw6bteqM9gQXZ1BIWOgM8xEwMrUGoyL8nW13+O+OOgNX3YhuDN1GDgg1NzdTlmm3j+9sHy7uBZ12r+z9lXnZQ==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.0 || ^1.1.13" + } + }, + "node_modules/are-we-there-yet/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/are-we-there-yet/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -244,6 +409,14 @@ "node": ">=8.0.0" } }, + "node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -268,6 +441,26 @@ } ] }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -277,6 +470,14 @@ "node": ">=8" } }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, "node_modules/bl": { "version": "6.0.14", "resolved": "https://registry.npmjs.org/bl/-/bl-6.0.14.tgz", @@ -311,6 +512,20 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -351,6 +566,75 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g==" + }, + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", + "engines": { + "node": ">=0.2.0" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "optional": true, + "peer": true, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "optional": true, + "peer": true, + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", + "dependencies": { + "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" + } + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -378,6 +662,66 @@ "fsevents": "~2.3.2" } }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/cmake-js": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/cmake-js/-/cmake-js-6.3.2.tgz", + "integrity": "sha512-7MfiQ/ijzeE2kO+WFB9bv4QP5Dn2yVaAP2acFJr4NIFy2hT4w6O4EpOTLNcohR5IPX7M4wNf/5taIqMj7UA9ug==", + "dependencies": { + "axios": "^0.21.1", + "bluebird": "^3", + "debug": "^4", + "fs-extra": "^5.0.0", + "is-iojs": "^1.0.1", + "lodash": "^4", + "memory-stream": "0", + "npmlog": "^1.2.0", + "rc": "^1.2.7", + "semver": "^5.0.3", + "splitargs": "0", + "tar": "^4", + "unzipper": "^0.8.13", + "url-join": "0", + "which": "^1.0.9", + "yargs": "^3.6.0" + }, + "bin": { + "cmake-js": "bin/cmake-js" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/cmake-js/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/colorette": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", @@ -397,6 +741,11 @@ "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz", "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==" }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, "node_modules/concat-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", @@ -432,6 +781,19 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -493,6 +855,82 @@ "node": "*" } }, + "node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "optional": true, + "peer": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -523,6 +961,46 @@ "node": ">=12" } }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -602,6 +1080,11 @@ "reusify": "^1.0.4" } }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -614,6 +1097,53 @@ "node": ">=8" } }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/fs-extra": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", + "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dependencies": { + "minipass": "^2.6.0" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -633,6 +1163,67 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/gauge": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", + "integrity": "sha512-fVbU2wRE91yDvKUnrIaQlHKAWKY5e08PmztCrwuH5YVQ+Z/p3d0ny2T48o6uvAAXHIUnfaQdHkmxYbQft1eHVA==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "ansi": "^0.3.0", + "has-unicode": "^2.0.0", + "lodash.pad": "^4.1.0", + "lodash.padend": "^4.1.0", + "lodash.padstart": "^4.1.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -665,11 +1256,91 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/got": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "optional": true, + "peer": true, + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got-fetch": { + "version": "5.1.10", + "resolved": "https://registry.npmjs.org/got-fetch/-/got-fetch-5.1.10.tgz", + "integrity": "sha512-Gwj/A2htjvLEcY07PKDItv0WCPEs3dV2vWeZ+9TVBSKSTuWEZ4oXaMD0ZAOsajwx2orahQWN4HI0MfRyWSZsbg==", + "optional": true, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "got": "^12.0.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/gssapi.js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gssapi.js/-/gssapi.js-2.0.1.tgz", + "integrity": "sha512-5D+qylV8uIKMaxTTKhpzvfGRz5+okr/rpwC6YlaCoDVBpvkuNgL8pM7+r7aTzZ2oT5dA4w2WoZTV82opGj+RZQ==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.5.0", + "cmake-js": "^6.1.0", + "node-addon-api": "^1.7.2" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, "node_modules/help-me": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==" }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "optional": true, + "peer": true + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "optional": true, + "peer": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -712,6 +1383,19 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -733,6 +1417,17 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -745,6 +1440,11 @@ "node": ">=0.10.0" } }, + "node_modules/is-iojs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-iojs/-/is-iojs-1.1.0.tgz", + "integrity": "sha512-tLn1j3wYSL6DkvEI+V/j0pKohpa5jk+ER74v6S4SgCXnjS0WA+DoZbwZBrrhgwksMvtuwndyGeG5F8YMsoBzSA==" + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -754,11 +1454,15 @@ "node": ">=0.12.0" } }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/joycon": { "version": "3.1.1", @@ -777,17 +1481,99 @@ "url": "https://opencollective.com/js-sdsl" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "optional": true, + "peer": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "optional": true, + "peer": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==" + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.pad": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", + "integrity": "sha512-mvUHifnLqM+03YNzeTBS1/Gr6JRFjd3rRx88FHWUvamVaT9k2O/kXha3yBSOwB9/DTQrSTLJNHvLBBt2FdX7Mg==" + }, + "node_modules/lodash.padend": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "integrity": "sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw==" + }, + "node_modules/lodash.padstart": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", + "integrity": "sha512-sW73O6S8+Tg66eY56DBk85aQzzUJDtpoXFBgELMd5P/SotAguo+1kYO6RuYgXxA4HJH3LFTFPASX6ET6bjfriw==" + }, "node_modules/long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "node_modules/memory-stream": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/memory-stream/-/memory-stream-0.0.3.tgz", + "integrity": "sha512-q0D3m846qY6ZkIt+19ZemU5vH56lpOZZwoJc3AICARKh/menBuayQUjAGPrqtHQQMUYERSdOrej92J9kz7LgYA==", + "dependencies": { + "readable-stream": "~1.0.26-2" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -810,6 +1596,30 @@ "node": ">=8.6" } }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", @@ -818,6 +1628,34 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/mqtt": { "version": "5.9.1", "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.9.1.tgz", @@ -860,53 +1698,11 @@ "process-nextick-args": "^2.0.1" } }, - "node_modules/mqtt-packet/node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/mqtt-packet/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==" - }, - "node_modules/mqtt/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/mqtt/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" }, - "node_modules/mqtt/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==" - }, "node_modules/mqtt/node_modules/readable-stream": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", @@ -930,6 +1726,11 @@ "safe-buffer": "~5.2.0" } }, + "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==" + }, "node_modules/mylas": { "version": "2.1.13", "resolved": "https://registry.npmjs.org/mylas/-/mylas-2.1.13.tgz", @@ -943,6 +1744,11 @@ "url": "https://github.com/sponsors/raouldeheer" } }, + "node_modules/node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==" + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -952,6 +1758,30 @@ "node": ">=0.10.0" } }, + "node_modules/normalize-url": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", + "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", + "optional": true, + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npmlog": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-1.2.1.tgz", + "integrity": "sha512-1J5KqSRvESP6XbjPaXt2H6qDzgizLTM7x0y1cXIjP2PpvdCqyNC7TO3cPRKsuYlElbi/DwkzRRdG2zpmE0IktQ==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "ansi": "~0.3.0", + "are-we-there-yet": "~1.0.0", + "gauge": "~1.2.0" + } + }, "node_modules/number-allocator": { "version": "1.0.14", "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz", @@ -961,27 +1791,14 @@ "js-sdsl": "4.3.0" } }, - "node_modules/number-allocator/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=0.10.0" } }, - "node_modules/number-allocator/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==" - }, "node_modules/on-exit-leak-free": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", @@ -995,6 +1812,40 @@ "wrappy": "1" } }, + "node_modules/optional-js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/optional-js/-/optional-js-2.3.0.tgz", + "integrity": "sha512-B0LLi+Vg+eko++0z/b8zIv57kp7HKEzaPJo7LowJXMUKYdf+3XJGu/cw03h/JhIOsLnP+cG5QnTHAuicjA5fMw==" + }, + "node_modules/os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", + "dependencies": { + "lcid": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "optional": true, + "peer": true, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -1217,6 +2068,36 @@ "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==" }, + "node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/protobufjs/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -1257,6 +2138,44 @@ "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -1287,6 +2206,29 @@ "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "optional": true, + "peer": true + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "optional": true, + "peer": true, + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -1302,6 +2244,18 @@ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -1357,6 +2311,22 @@ "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -1395,6 +2365,21 @@ "atomic-sleep": "^1.0.0" } }, + "node_modules/sparkplug-payload": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sparkplug-payload/-/sparkplug-payload-1.0.3.tgz", + "integrity": "sha512-JAQSyuHVQQe/LzIlJdcIaD1F1c+rbXoolII3H1whQkhuZ96+G53RoPWqP9zCPZYFjvfSMHnQNIedGIZw/zjHJw==", + "dependencies": { + "@types/long": "^4.0.0", + "long": "^4.0.0", + "protobufjs": "^6.11.3" + } + }, + "node_modules/sparkplug-payload/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "node_modules/split2": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", @@ -1403,6 +2388,65 @@ "node": ">= 10.x" } }, + "node_modules/splitargs": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/splitargs/-/splitargs-0.0.7.tgz", + "integrity": "sha512-UUFYD2oWbNwULH6WoVtLUOw8ch586B+HUqcsAjjjeoBQAM1bD4wZRXu01koaxyd8UeYpybWqW4h+lO1Okv40Tg==" + }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "dependencies": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "engines": { + "node": ">=4.5" + } + }, "node_modules/thread-stream": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.3.0.tgz", @@ -1423,6 +2467,14 @@ "node": ">=8.0" } }, + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", + "engines": { + "node": "*" + } + }, "node_modules/ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", @@ -1507,6 +2559,64 @@ "node": ">=4.2.0" } }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unzipper": { + "version": "0.8.14", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.8.14.tgz", + "integrity": "sha512-8rFtE7EP5ssOwGpN2dt1Q4njl0N1hUXJ7sSPz0leU2hRdq6+pra57z4YPBlVqm40vcgv6ooKZEAx48fMTv9x4w==", + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "~1.0.10", + "listenercount": "~1.0.1", + "readable-stream": "~2.1.5", + "setimmediate": "~1.0.4" + } + }, + "node_modules/unzipper/node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==" + }, + "node_modules/unzipper/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/unzipper/node_modules/process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==" + }, + "node_modules/unzipper/node_modules/readable-stream": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", + "integrity": "sha512-NkXT2AER7VKXeXtJNSaWLpWIhmtSE3K2PguaLEeWr4JILghcIKqoLt1A3wHrnpDC5+ekf8gfk1GKWkFXe4odMw==", + "dependencies": { + "buffer-shims": "^1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/url-join": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz", + "integrity": "sha512-H6dnQ/yPAAVzMQRvEvyz01hhfQL5qRWSEt7BX8t9DqnPw9BjMb64fjIRq76Uvf1hkHp+mTZvEVJ5guXOT0Xqaw==" + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -1518,6 +2628,28 @@ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/window-size": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "integrity": "sha512-2thx4pB0cV3h+Bw7QmMXcEbdmOzv9t0HFplJH/Lz6yu60hXYy5RT8rUu+wlIreVxWsGN20mo+MHeCSfUpQBwPw==", + "bin": { + "window-size": "cli.js" + }, + "engines": { + "node": ">= 0.10.0" + } + }, "node_modules/worker-timers": { "version": "7.1.8", "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-7.1.8.tgz", @@ -1549,6 +2681,18 @@ "tslib": "^2.6.2" } }, + "node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -1574,6 +2718,30 @@ } } }, + "node_modules/y18n": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==" + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/yargs": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "integrity": "sha512-ONJZiimStfZzhKamYvR/xvmgW3uEkAUFSP91y2caTEPhzF6uP2JfPiVZcq66b/YR0C3uitxSV7+T1x8p5bkmMg==", + "dependencies": { + "camelcase": "^2.0.1", + "cliui": "^3.0.3", + "decamelize": "^1.1.1", + "os-locale": "^1.4.0", + "string-width": "^1.0.1", + "window-size": "^0.1.4", + "y18n": "^3.2.0" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/influxdb-injector/package.json b/influxdb-injector/package.json index ad57d631..73373a78 100644 --- a/influxdb-injector/package.json +++ b/influxdb-injector/package.json @@ -17,6 +17,7 @@ ], "scripts": { "start": "node dist/app.js", + "start:shell": "k5start -Uf $CLIENT_KEYTAB npm run start", "dev": " npm run build && npm run start", "build": "tsc", "clean": "tsc --build --clean", @@ -26,6 +27,8 @@ "dependencies": { "@influxdata/influxdb-client": "^1.33.2", "@influxdata/influxdb-client-apis": "^1.33.2", + "@amrc-factoryplus/service-client": "^1.3.6", + "gssapi.js": "^2.0.1", "async": "^3.2.4", "long": "^5.2.3", "mqtt": "^5.9.1", diff --git a/influxdb-injector/run-dev.sh b/influxdb-injector/run-dev.sh index 0dafe58b..900f6b30 100644 --- a/influxdb-injector/run-dev.sh +++ b/influxdb-injector/run-dev.sh @@ -4,4 +4,6 @@ # # bin/bash -npm run start +tmpfile=$(mktemp) +export CLIENT_KEYTAB="$(kubectl --kubeconfig get -n factory-plus secret krb5-keytabs -o jsonpath="{.data.sv1warehouse}" | base64 -d >"$tmpfile" && echo "$tmpfile")" +npm run start:shell \ No newline at end of file diff --git a/influxdb-injector/src/Types/index.d.ts b/influxdb-injector/src/Types/index.d.ts index bcd9fbab..d494642c 100644 --- a/influxdb-injector/src/Types/index.d.ts +++ b/influxdb-injector/src/Types/index.d.ts @@ -29,4 +29,13 @@ interface ISA95Schema { Area?: string, WorkCenter?: string, WorkUnit?: string +} + +/** + * Params for creating the factory+ service client + */ +interface MQTTClientConstructorParams { + e: { + serviceClient: ServiceClient; + } } \ No newline at end of file diff --git a/influxdb-injector/src/Utils/UnsTopic.ts b/influxdb-injector/src/Utils/UnsTopic.ts index eb4d26d4..811a4c6c 100644 --- a/influxdb-injector/src/Utils/UnsTopic.ts +++ b/influxdb-injector/src/Utils/UnsTopic.ts @@ -4,7 +4,7 @@ import {logger} from "./logger.js"; * The UnsTopic class is designed to parse UNS MQTT topics and extract relevant information from * them. UNS topics follow a structured NAMESAPCE_VERSION/ISA95_STRUCTURE/METRIC_PATH. * This class provides methods to dissect these topics and retrieve specific data, such as - * device location, metric path and schema and instance UUID paths, based on the predefined structure of + * ISA95 device location, metric path and schema and instance UUID paths, based on the predefined structure of * the topic string and MQTTv5 custom properties. */ export class UnsTopic { diff --git a/influxdb-injector/src/app.ts b/influxdb-injector/src/app.ts index 88c4f43b..6afa059e 100644 --- a/influxdb-injector/src/app.ts +++ b/influxdb-injector/src/app.ts @@ -2,10 +2,55 @@ * AMRC InfluxDB Sparkplug Ingester * Copyright "2023" AMRC */ - +import {ServiceClient, UUIDs} from "@amrc-factoryplus/service-client"; import MQTTClient from "./mqttclient.js"; +import pretty from "pino-pretty"; +import pino from "pino"; + +let dotenv: any = null; +try { + dotenv = await import ('dotenv') +} catch (e) { +} + +const stream = pretty({ + colorize: true +}) + +dotenv?.config(); + +const directoryUrl = process.env.DIRECTORY_URL; +if (!directoryUrl) { + throw new Error("DIRECTORY_URL environment variable is not set"); +} + +export const logger = pino({ + name: 'ACS UNS Ingester', + level: process.env.LOG_LEVEL || 'info', +}, stream); + + +const client = await new ServiceClient({ + env: process.env +}).init(); + +// Overwrite MQTT server if specified in environment +if (process.env.MQTT_URL) { + client.Discovery.set_service_url(UUIDs.Service.MQTT, process.env.MQTT_URL); +} + +// Overwrite Command Escalation server if specified in environment +if (process.env.CMD_ESC_URL) { + client.Discovery.set_service_url(UUIDs.Service.Command_Escalation, process.env.CMD_ESC_URL); +} +// Well known UUID for MQTT Component service function (see: https://factoryplus.app.amrc.co.uk/docs/framework-components/core-components/mqtt) +logger.info(client.service_urls('feb27ba3-bd2c-4916-9269-79a61ebc4a47')); -const mqtt = await new MQTTClient().init(); +const mqtt = await new MQTTClient({ + e: { + serviceClient: client, + } +}).init(); mqtt.run(); diff --git a/influxdb-injector/src/mqttclient.ts b/influxdb-injector/src/mqttclient.ts index 2f42d403..910adb2f 100644 --- a/influxdb-injector/src/mqttclient.ts +++ b/influxdb-injector/src/mqttclient.ts @@ -2,13 +2,12 @@ * AMRC InfluxDB Sparkplug Ingester * Copyright "2024" AMRC */ - +import {ServiceClient} from "@amrc-factoryplus/service-client"; import {logger} from "./Utils/logger.js"; import {InfluxDB, Point} from '@influxdata/influxdb-client' import {Agent} from 'http' import mqtt from "mqtt"; import {UnsTopic} from "./Utils/UnsTopic.js"; -import * as path from "node:path"; let dotenv: any = null; try { @@ -43,11 +42,6 @@ if (!flushInterval) { throw new Error("FLUSH_INTERVAL environment variable is not set"); } -const mqttURL: string = process.env.MQTT_URL; -if (!mqttURL) { - throw new Error("Mqtt URL not set!"); -} - let i = 0; // Node.js HTTP client OOTB does not reuse established TCP connections, a custom node HTTP agent @@ -85,7 +79,12 @@ const writeApi = influxDB.getWriteApi(influxOrganisation, ); export default class MQTTClient { - private mqtt: mqtt.MqttClient; + private sparkplugBroker: any; + private serviceClient: ServiceClient; + + constructor({e}: MQTTClientConstructorParams) { + this.serviceClient = e.serviceClient; + } async init() { @@ -108,21 +107,20 @@ export default class MQTTClient { } async run() { - this.mqtt = mqtt.connect(mqttURL, { - protocolVersion: 5 - }); - this.mqtt.on("connect", this.on_connect.bind(this)); - this.mqtt.on("error", this.on_error.bind(this)); - this.mqtt.on("message", this.on_message.bind(this)); - this.mqtt.on("close", this.on_close.bind(this)); - this.mqtt.on("reconnect", this.on_reconnect.bind(this)); + this.sparkplugBroker = await this.serviceClient.mqtt_client(); + + this.sparkplugBroker.on("connect", this.on_connect.bind(this)); + this.sparkplugBroker.on("error", this.on_error.bind(this)); + this.sparkplugBroker.on("message", this.on_message.bind(this)); + this.sparkplugBroker.on("close", this.on_close.bind(this)); + this.sparkplugBroker.on("reconnect", this.on_reconnect.bind(this)); logger.info("Connecting to UNS broker..."); } on_connect() { logger.info("🔌 Connected to Factory+ broker"); logger.info("👂 Subscribing to entire UNS namespace"); - this.mqtt.subscribe("UNS/v1/#"); + this.sparkplugBroker.subscribe("UNS/v1/#"); this.resetInterval(); } @@ -173,10 +171,10 @@ export default class MQTTClient { } /** - * - * @param payload - * @param topic - * @param customProperties + * Writes all metrics in a UNS MQTT payload to InfluxDB + * @param payload The payload from the MQTT packet. + * @param topic The topic the payload was received on. + * @param customProperties The custom properties from the MQTTv5 payload. */ private writeMetrics(payload: MetricPayload, topic: string, customProperties: UnsMetricCustomProperties) { const unsTopic = new UnsTopic(topic, customProperties); @@ -215,8 +213,8 @@ export default class MQTTClient { * @param topic Topic the metric was published on. * @param value Metric value to write to InfluxDB. * @param timestamp Timestamp from the metric to write to influx. - * @param unit - * @param type + * @param unit The metric unit from the MQTTv5 custom properties. + * @param type The Metric type from the MQTTv5 custom properties. */ writeToInfluxDB(topic: UnsTopic, value: string, timestamp: Date, unit: string, type: string) { if (value === null) { From b096f7e168627f37ceb46cbd47a28d86b918e08d Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Tue, 27 Aug 2024 16:36:25 +0100 Subject: [PATCH 31/58] Removed redundant code --- ingesters/sparkplug/bin/ingester.ts | 1 + ingesters/sparkplug/lib/mqttclient.ts | 142 +------------------------- 2 files changed, 3 insertions(+), 140 deletions(-) diff --git a/ingesters/sparkplug/bin/ingester.ts b/ingesters/sparkplug/bin/ingester.ts index 6d3bc7dd..177334ba 100644 --- a/ingesters/sparkplug/bin/ingester.ts +++ b/ingesters/sparkplug/bin/ingester.ts @@ -45,6 +45,7 @@ if (process.env.CMD_ESC_URL) { client.Discovery.set_service_url(UUIDs.Service.Command_Escalation, process.env.CMD_ESC_URL); } +// Well known UUID for MQTT Component service function (see: https://factoryplus.app.amrc.co.uk/docs/framework-components/core-components/mqtt) logger.info(client.service_urls('feb27ba3-bd2c-4916-9269-79a61ebc4a47')); const mqtt = await new MQTTClient({ diff --git a/ingesters/sparkplug/lib/mqttclient.ts b/ingesters/sparkplug/lib/mqttclient.ts index 59015410..54cc557a 100644 --- a/ingesters/sparkplug/lib/mqttclient.ts +++ b/ingesters/sparkplug/lib/mqttclient.ts @@ -461,11 +461,10 @@ export default class MQTTClient { // format payload to publish to uns. Object.entries(metricsToPublish).forEach(([topic, metricContainers]) => { - let payload: UnsMetric; // if theirs more than one of the same metric from the same sparkplug payload, add the values to the batch array. if (metricContainers.length > 1) { - const sortedMetricContainers = metricContainers.sort((a, b) => b.metric.timestamp.toNumber() - a.metric.timestamp.toNumber()); + const sortedMetricContainers = metricContainers.sort((a, b) => a.metric.timestamp.toNumber() - b.metric.timestamp.toNumber()); payload = { timestamp: new Date(sortedMetricContainers[0].metric.timestamp.toNumber()), value: sortedMetricContainers[0].metric.value, @@ -475,7 +474,7 @@ export default class MQTTClient { sortedMetricContainers.shift(); sortedMetricContainers.forEach(metricContainer => { payload.batch.push({ - timestamp: metricContainer.metric.timestamp.toNumber(), + timestamp: new Date(metricContainer.metric.timestamp.toNumber()), value: metricContainer.metric.value }); }); @@ -513,143 +512,6 @@ export default class MQTTClient { }) } - /* - private writeMetrics(payload, topic: Topic) { - payload.metrics.forEach((metric) => { - let birth = this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]?.[metric.alias]; - - if (!birth) { - logger.error(`Metric ${metric.alias} is unknown for ${topic.address.group}/${topic.address.node}/${topic.address.device}`); - } - - let metricTimestamp: Date - if (metric.timestamp) { - metricTimestamp = new Date(metric.timestamp); - } else if (payload.timestamp) { - // Metrics might not have a timestamp so use the packet timestamp if we have it. - metricTimestamp = new Date(payload.timestamp); - } else { - // No timestamp can be found on the metric or the payload, just use the current time instead. - metricTimestamp = new Date(); - } - // Send each metric to InfluxDB - this.writeToInfluxDB(birth, topic, metric.value, metricTimestamp) - }); - } - */ - /** - * Writes metric values to InfluxDB using the metric timestamp. - * @param birth Birth certificate for device. - * @param topic Topic the metric was published on. - * @param value Metric value to write to InfluxDB. - * @param timestamp Timestamp from the metric to write to influx. - */ - - /* - writeToInfluxDB(birth, topic: Topic, value, timestamp: Date) { - if (value === null) return; - if (birth.transient) { - logger.debug(`Metric ${birth.name} is transient, not writing to InfluxDB`); - return; - } - - // Get the value after the last / - let metricName = birth.name.split('/').pop(); - - // Get the path as everything behind the last / - let path = birth.name.substring(0, birth.name.lastIndexOf("/")); - - writeApi.useDefaultTags({ - topLevelInstance: birth.instance.top, - bottomLevelInstance: birth.instance.bottom, - usesInstances: birth.instance.top + ':' + birth.instance.full.join(':'), - topLevelSchema: birth.schema.top, - bottomLevelSchema: birth.schema.bottom, - usesSchemas: birth.schema.top + ':' + birth.schema.full.join(':'), - group: topic.address.group, - node: topic.address.node, - device: topic.address.device, - path: path, - unit: birth.unit - }); - - let numVal = null; - - switch (birth.type) { - case "Int8": - case "Int16": - case "Int32": - case "Int64": - // Validate - numVal = Number(value); - if (!Number.isInteger(numVal)) { - logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${numVal}. Not recording.`); - return; - } - writeApi.writePoint( - new Point(`${metricName}:i`) - .intField('value', numVal) - .timestamp(timestamp) - ); - break; - case "UInt8": - case "UInt16": - case "UInt32": - case "UInt64": - // Validate - numVal = Number(value); - if (!Number.isInteger(numVal)) { - logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${numVal}. Not recording.`); - return; - } - writeApi.writePoint( - new Point(`${metricName}:u`) - .uintField('value', numVal) - .timestamp(timestamp) - ); - break; - case "Float": - case "Double": - // Validate - numVal = Number(value); - if (isNaN(parseFloat(numVal))) { - logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${numVal}. Not recording.`); - return; - } - writeApi.writePoint( - new Point(`${metricName}:d`) - .floatField('value', numVal) - .timestamp(timestamp) - ); - break; - case "Boolean": - if (typeof value != "boolean") { - logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${value}. Not recording.`); - return; - } - writeApi.writePoint( - new Point(`${metricName}:b`) - .booleanField('value', value) - .timestamp(timestamp)); - break; - default: - writeApi.writePoint( - new Point(`${metricName}:s`) - .stringField('value', value) - .timestamp(timestamp)); - break; - - } - - i++; - - logger.debug(`Added to write buffer (${i}/${batchSize}): [${birth.type}] ${topic.address}/${path}/${metricName} = ${value}`); - - if (i >= batchSize) { - this.flushBuffer(`${batchSize} point BATCH`); - } - }*/ - setNestedValue(obj, path, value) { for (let k = 0; k < path.length - 1; k++) { obj = obj[path[k]] = obj[path[k]] || {}; From d59ac4a0350645b31f4736c3a962624a9a766c83 Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Tue, 27 Aug 2024 16:36:52 +0100 Subject: [PATCH 32/58] add uns permissions to deployment --- deploy/templates/dumps.yaml | 298 +++++++++++++++++++----------------- 1 file changed, 159 insertions(+), 139 deletions(-) diff --git a/deploy/templates/dumps.yaml b/deploy/templates/dumps.yaml index 95f3fbf7..de6b54e0 100644 --- a/deploy/templates/dumps.yaml +++ b/deploy/templates/dumps.yaml @@ -1,144 +1,146 @@ # ==================================================== # Ensure that well-known UUIDs are used where required -# ---------------------------------------------------- -# ⚠ Do not change these! -# ==================================================== - -{{$classDef_classDefinition := "04a1c90d-2295-4cbe-b33a-74eded62cbf1" | quote}} -{{$classDef_application := "d319bd87-f42b-4b66-be4f-f82ff48b93f0" | quote}} -{{$classDef_serviceFunction := "265d481f-87a7-4f93-8fc6-53fa64dc11bb" | quote}} -{{$classDef_serviceAccount := "e463b4ae-a322-46cc-8976-4ba76838e908" | quote}} -{{$classDef_permission := "8ae784bb-c4b5-4995-9bf6-799b3c7f21ad" | quote}} -{{$classDef_permissionGroup := "ac0d5288-6136-4ced-a372-325fbbcdd70d" | quote}} -{{$classDef_clientRole := "1c567e3c-5519-4418-8682-6086f22fbc13" | quote}} -{{$classDef_userAccount := "8b3e8f35-78e5-4f93-bf21-7238bcb2ba9d" | quote}} -{{$classDef_userGroup := "f1fabdd1-de90-4399-b3da-ccf6c2b2c08b" | quote}} -{{$classDef_cellGateway := "00da3c0b-f62b-4761-a689-39ad0c33f864" | quote}} -{{$classDef_softGateway := "5bee4d24-32e1-44f8-b953-1f86ff4b3e87" | quote}} -{{$classDef_serviceRequirement := "b419cbc2-ab0f-4311-bd9e-f0591f7e88cb" | quote}} -{{$classDef_gitRepo := "d25f2afc-1ab8-4d27-b51b-d02314624e3e" | quote}} -{{$classDef_edgeClusterAccount := "97756c9a-38e6-4238-b78c-3df6f227a6c9" | quote}} -{{$classDef_edgeCluster := "f24d354d-abc1-4e32-98e1-0667b3e40b61" | quote}} -{{$classDef_metricSchema := "83ee28d4-023e-4c2c-ab86-12c24e86372c" | quote}} - -{{$special_wildcard := "00000000-0000-0000-0000-000000000000" | quote}} -{{$special_self := "5855a1cc-46d8-4b16-84f8-ab3916ecb230" | quote}} - -{{$application_objectRegistration := "cb40bed5-49ad-4443-a7f5-08c75009da8f" | quote}} -{{$application_generalObjectInformation := "64a8bfa9-7772-45c4-9d1a-9e6290690957" | quote}} -{{$application_applicationConfigSchema := "dbd8a535-52ba-4f6e-b4f8-9b71aefe09d3" | quote}} -{{$application_mqttPermissionTemplate := "1266ddf1-156c-4266-9808-d6949418b185" | quote}} -{{$application_sparkplugAddressInformation := "8e32801b-f35a-4cbf-a5c3-2af64d3debd7" | quote}} -{{$application_commandEscalation := "60e99f28-67fe-4344-a6ab-b1edb8b8e810" | quote}} -{{$application_gitRepoConfiguration := "38d62a93-b6b4-4f63-bad4-d433e3eaff29" | quote}} -{{$application_edgeClusterConfiguration := "bdb13634-0b3d-4e38-a065-9d88c12ee78d" | quote}} -{{$application_edgeClusterStatus := "747a62c9-1b66-4a2e-8dd9-0b70a91b6b75" | quote}} -{{$application_edgeDeployment := "f2b9417a-ef7f-421f-b387-bb8183a48cdb" | quote}} -{{$application_helmChartTemplate := "729fe070-5e67-4bc7-94b5-afd75cb42b03" | quote}} -{{$application_serviceSetup := "5b47881c-b012-4040-945c-eacafca539b2" | quote}} -{{$application_edgeAgentConfig := "aac6f843-cfee-4683-b121-6943bfdf9173" | quote }} -{{$application_serviceConfig := "5b47881c-b012-4040-945c-eacafca539b2" | quote}} -{{$application_schemaIcon := "65c0ccba-151d-48d3-97b4-d0026a811900" | quote}} - -{{$service_configStore := "af15f175-78a0-4e05-97c0-2a0bb82b9f3b" | quote}} -{{$service_commandEscalation := "78ea7071-24ac-4916-8351-aa3e549d8ccd" | quote}} -{{$service_directory := "af4a1d66-e6f7-43c4-8a67-0fa3be2b1cf9" | quote}} -{{$service_authorisation := "cab2642a-f7d9-42e5-8845-8f35affe1fd4" | quote}} -{{$service_mqtt := "feb27ba3-bd2c-4916-9269-79a61ebc4a47" | quote}} -{{$service_warehouse := "a8e5a73f-2dd1-4cda-8e46-bc6cedb14269" | quote}} -{{$service_git := "7adf4db0-2e7b-4a68-ab9d-376f4c5ce14b" | quote}} -{{$service_manager := "619eecab-742d-4824-8b97-bcae472e5c04" | quote}} - -{{$serviceRequirement_gitServiceAccount := "a461ef62-0560-4be2-8d97-1a56916ce4f8" | quote}} -{{$serviceRequirement_edgeDeploymentServiceAccount := "26d192cf-73c1-4c14-93cf-1e63743bab08" | quote}} -{{$serviceRequirement_edgeClusterRepositories := "3a58340c-d4ec-453d-99c3-0cf6ab7d8fa9" | quote}} - -{{$permission_auth_manageKerberosMappings := "327c4cc8-9c46-4e1e-bb6b-257ace37b0f6" | quote}} -{{$permission_auth_readEffectivePermissions := "35252562-51e5-4dd8-84cd-ba0fafa62669" | quote}} -{{$permission_auth_manageACLsPerPermission := "3a41f5ce-fc08-4669-9762-ec9e71061168" | quote}} -{{$permission_auth_readACLEntry := "ba566181-0e8a-405b-b16e-3fb89130fbee" | quote}} -{{$permission_auth_manageGroups := "be9b6d47-c845-49b2-b9d5-d87b83f11c3b" | quote}} -{{$permission_auth_readKerberosMapping := "e8c9c0f7-0d54-4db2-b8d6-cd80c45f6a5c" | quote}} - -{{$permission_configStore_readConfigForApp := "4a339562-cd57-408d-9d1a-6529a383ea4b" | quote}} -{{$permission_configStore_writeConfigForApp := "6c799ccb-d2ad-4715-a2a7-3c8728d6c0bf" | quote}} -{{$permission_configStore_manageAppSchema := "95c7cbcb-ce60-49ed-aa81-2fe3eec4559d" | quote}} -{{$permission_configStore_manageObjects := "f0b7917b-d475-4888-9d5a-2af96b3c26b6" | quote}} -{{$permission_configStore_deleteObjects := "6957174b-7b08-45ca-ac5c-c03ab6928a6e" | quote}} - -{{$permission_mqtt_subscribeReadNode := "046d6603-fa62-4208-9400-65d61f8b1ec4" | quote}} -{{$permission_mqtt_subscribeToWholeNamespace := "21000098-3a53-48da-8d3e-cc0650603d8e" | quote}} -{{$permission_mqtt_subscribeReadWholeNamespace := "81833dbb-1150-4078-b1db-978c646ba73e" | quote}} -{{$permission_mqtt_issueGlobalCommands := "50f1e694-7e18-4930-aa59-97cc90a6a1ec" | quote}} -{{$permission_mqtt_publishAllFromGroup := "64c019f8-6754-4270-8917-6659a5628b86" | quote}} -{{$permission_mqtt_subscribeReadAllStates := "8790cf3d-b793-423c-b373-8cfcf9f63529" | quote}} -{{$permission_mqtt_updateGroupState := "9a32f195-a8cc-4562-a87a-d4653279474f" | quote}} -{{$permission_mqtt_participateAsNode := "a1314953-8226-44f4-8a3e-e87b09310579" | quote}} -{{$permission_mqtt_updateOwnState := "bdc96a3e-d6fb-48ed-b790-0aa95cf826f0" | quote}} -{{$permission_mqtt_issueGroupCommands := "cff45682-f2f0-4c72-91f3-7dda20d43509" | quote}} -{{$permission_mqtt_subscribeReadOwnGroup := "d617e37c-3908-41b1-8820-d3f8d41a4280" | quote}} -{{$permission_mqtt_representDevices := "e82456b3-a7d9-4971-9d8c-fd0be4545ab4" | quote}} -{{$permission_mqtt_readAllBirthMessages := "67dc4dd0-0939-42b1-b1f9-9049f4d91d40" | quote}} - -{{$permission_directory_overrideServiceAdvertisementPermissions := "3bda2ab2-4128-463d-83c9-16b976a8d83e" | quote}} -{{$permission_directory_advertiseService := "4db4c39a-f18d-4e83-aeb0-5af2c14ddc2b" | quote}} -{{$permission_directory_manageServiceAdvertisementForOwner := "97dcf2a1-7f4b-476c-b561-e40fc42440ee" | quote}} - -{{$permission_ccl_rebirth := "fbb9c25d-386d-4966-a325-f16471d9f7be" | quote}} -{{$permission_ccl_reloadEdgeAgentConfig := "6335f100-e68e-4e4d-b46d-85b42f85a036" | quote}} - -{{$permission_git_createRepo := "3668660f-f949-4657-be76-21967144c1a2" | quote}} -{{$permission_git_pullFromRepo := "12ecb694-b4b9-4d2a-927e-d100019f7ebe" | quote}} -{{$permission_git_pushToRepo := "b2d8d437-5060-4202-bcc2-bd2beda09651" | quote}} + # ---------------------------------------------------- + # ⚠ Do not change these! + # ==================================================== -{{$permission_clusterManager_manageClusters := "a40acff8-0c61-4251-bef3-d8d53e50cdd0" | quote}} -{{$permission_clusterManager_manageSecrets := "07fba27a-0d01-4c07-875b-d25345261d3a" | quote}} + {{$classDef_classDefinition := "04a1c90d-2295-4cbe-b33a-74eded62cbf1" | quote}} + {{$classDef_application := "d319bd87-f42b-4b66-be4f-f82ff48b93f0" | quote}} + {{$classDef_serviceFunction := "265d481f-87a7-4f93-8fc6-53fa64dc11bb" | quote}} + {{$classDef_serviceAccount := "e463b4ae-a322-46cc-8976-4ba76838e908" | quote}} + {{$classDef_permission := "8ae784bb-c4b5-4995-9bf6-799b3c7f21ad" | quote}} + {{$classDef_permissionGroup := "ac0d5288-6136-4ced-a372-325fbbcdd70d" | quote}} + {{$classDef_clientRole := "1c567e3c-5519-4418-8682-6086f22fbc13" | quote}} + {{$classDef_userAccount := "8b3e8f35-78e5-4f93-bf21-7238bcb2ba9d" | quote}} + {{$classDef_userGroup := "f1fabdd1-de90-4399-b3da-ccf6c2b2c08b" | quote}} + {{$classDef_cellGateway := "00da3c0b-f62b-4761-a689-39ad0c33f864" | quote}} + {{$classDef_softGateway := "5bee4d24-32e1-44f8-b953-1f86ff4b3e87" | quote}} + {{$classDef_serviceRequirement := "b419cbc2-ab0f-4311-bd9e-f0591f7e88cb" | quote}} + {{$classDef_gitRepo := "d25f2afc-1ab8-4d27-b51b-d02314624e3e" | quote}} + {{$classDef_edgeClusterAccount := "97756c9a-38e6-4238-b78c-3df6f227a6c9" | quote}} + {{$classDef_edgeCluster := "f24d354d-abc1-4e32-98e1-0667b3e40b61" | quote}} + {{$classDef_metricSchema := "83ee28d4-023e-4c2c-ab86-12c24e86372c" | quote}} + + {{$special_wildcard := "00000000-0000-0000-0000-000000000000" | quote}} + {{$special_self := "5855a1cc-46d8-4b16-84f8-ab3916ecb230" | quote}} + + {{$application_objectRegistration := "cb40bed5-49ad-4443-a7f5-08c75009da8f" | quote}} + {{$application_generalObjectInformation := "64a8bfa9-7772-45c4-9d1a-9e6290690957" | quote}} + {{$application_applicationConfigSchema := "dbd8a535-52ba-4f6e-b4f8-9b71aefe09d3" | quote}} + {{$application_mqttPermissionTemplate := "1266ddf1-156c-4266-9808-d6949418b185" | quote}} + {{$application_sparkplugAddressInformation := "8e32801b-f35a-4cbf-a5c3-2af64d3debd7" | quote}} + {{$application_commandEscalation := "60e99f28-67fe-4344-a6ab-b1edb8b8e810" | quote}} + {{$application_gitRepoConfiguration := "38d62a93-b6b4-4f63-bad4-d433e3eaff29" | quote}} + {{$application_edgeClusterConfiguration := "bdb13634-0b3d-4e38-a065-9d88c12ee78d" | quote}} + {{$application_edgeClusterStatus := "747a62c9-1b66-4a2e-8dd9-0b70a91b6b75" | quote}} + {{$application_edgeDeployment := "f2b9417a-ef7f-421f-b387-bb8183a48cdb" | quote}} + {{$application_helmChartTemplate := "729fe070-5e67-4bc7-94b5-afd75cb42b03" | quote}} + {{$application_serviceSetup := "5b47881c-b012-4040-945c-eacafca539b2" | quote}} + {{$application_edgeAgentConfig := "aac6f843-cfee-4683-b121-6943bfdf9173" | quote }} + {{$application_serviceConfig := "5b47881c-b012-4040-945c-eacafca539b2" | quote}} + {{$application_schemaIcon := "65c0ccba-151d-48d3-97b4-d0026a811900" | quote}} + + {{$service_configStore := "af15f175-78a0-4e05-97c0-2a0bb82b9f3b" | quote}} + {{$service_commandEscalation := "78ea7071-24ac-4916-8351-aa3e549d8ccd" | quote}} + {{$service_directory := "af4a1d66-e6f7-43c4-8a67-0fa3be2b1cf9" | quote}} + {{$service_authorisation := "cab2642a-f7d9-42e5-8845-8f35affe1fd4" | quote}} + {{$service_mqtt := "feb27ba3-bd2c-4916-9269-79a61ebc4a47" | quote}} + {{$service_warehouse := "a8e5a73f-2dd1-4cda-8e46-bc6cedb14269" | quote}} + {{$service_git := "7adf4db0-2e7b-4a68-ab9d-376f4c5ce14b" | quote}} + {{$service_manager := "619eecab-742d-4824-8b97-bcae472e5c04" | quote}} + + {{$serviceRequirement_gitServiceAccount := "a461ef62-0560-4be2-8d97-1a56916ce4f8" | quote}} + {{$serviceRequirement_edgeDeploymentServiceAccount := "26d192cf-73c1-4c14-93cf-1e63743bab08" | quote}} + {{$serviceRequirement_edgeClusterRepositories := "3a58340c-d4ec-453d-99c3-0cf6ab7d8fa9" | quote}} + + {{$permission_auth_manageKerberosMappings := "327c4cc8-9c46-4e1e-bb6b-257ace37b0f6" | quote}} + {{$permission_auth_readEffectivePermissions := "35252562-51e5-4dd8-84cd-ba0fafa62669" | quote}} + {{$permission_auth_manageACLsPerPermission := "3a41f5ce-fc08-4669-9762-ec9e71061168" | quote}} + {{$permission_auth_readACLEntry := "ba566181-0e8a-405b-b16e-3fb89130fbee" | quote}} + {{$permission_auth_manageGroups := "be9b6d47-c845-49b2-b9d5-d87b83f11c3b" | quote}} + {{$permission_auth_readKerberosMapping := "e8c9c0f7-0d54-4db2-b8d6-cd80c45f6a5c" | quote}} + + {{$permission_configStore_readConfigForApp := "4a339562-cd57-408d-9d1a-6529a383ea4b" | quote}} + {{$permission_configStore_writeConfigForApp := "6c799ccb-d2ad-4715-a2a7-3c8728d6c0bf" | quote}} + {{$permission_configStore_manageAppSchema := "95c7cbcb-ce60-49ed-aa81-2fe3eec4559d" | quote}} + {{$permission_configStore_manageObjects := "f0b7917b-d475-4888-9d5a-2af96b3c26b6" | quote}} + {{$permission_configStore_deleteObjects := "6957174b-7b08-45ca-ac5c-c03ab6928a6e" | quote}} + + {{$permission_mqtt_subscribeReadNode := "046d6603-fa62-4208-9400-65d61f8b1ec4" | quote}} + {{$permission_mqtt_subscribeToWholeNamespace := "21000098-3a53-48da-8d3e-cc0650603d8e" | quote}} + {{$permission_mqtt_subscribeReadWholeNamespace := "81833dbb-1150-4078-b1db-978c646ba73e" | quote}} + {{$permission_mqtt_issueGlobalCommands := "50f1e694-7e18-4930-aa59-97cc90a6a1ec" | quote}} + {{$permission_mqtt_publishAllFromGroup := "64c019f8-6754-4270-8917-6659a5628b86" | quote}} + {{$permission_mqtt_subscribeReadAllStates := "8790cf3d-b793-423c-b373-8cfcf9f63529" | quote}} + {{$permission_mqtt_updateGroupState := "9a32f195-a8cc-4562-a87a-d4653279474f" | quote}} + {{$permission_mqtt_participateAsNode := "a1314953-8226-44f4-8a3e-e87b09310579" | quote}} + {{$permission_mqtt_updateOwnState := "bdc96a3e-d6fb-48ed-b790-0aa95cf826f0" | quote}} + {{$permission_mqtt_issueGroupCommands := "cff45682-f2f0-4c72-91f3-7dda20d43509" | quote}} + {{$permission_mqtt_subscribeReadOwnGroup := "d617e37c-3908-41b1-8820-d3f8d41a4280" | quote}} + {{$permission_mqtt_representDevices := "e82456b3-a7d9-4971-9d8c-fd0be4545ab4" | quote}} + {{$permission_mqtt_readAllBirthMessages := "67dc4dd0-0939-42b1-b1f9-9049f4d91d40" | quote}} + {{$permission_mqtt_subscribeReadWholeUNSNamespace := "034b38e1-00f4-41bf-be2d-1d41e829526a" | quote}} + {{$permission_mqtt_writeToUNSNamespace := "1e737a42-03df-486c-89bb-78242c4b9099" | quote}} + + {{$permission_directory_overrideServiceAdvertisementPermissions := "3bda2ab2-4128-463d-83c9-16b976a8d83e" | quote}} + {{$permission_directory_advertiseService := "4db4c39a-f18d-4e83-aeb0-5af2c14ddc2b" | quote}} + {{$permission_directory_manageServiceAdvertisementForOwner := "97dcf2a1-7f4b-476c-b561-e40fc42440ee" | quote}} + + {{$permission_ccl_rebirth := "fbb9c25d-386d-4966-a325-f16471d9f7be" | quote}} + {{$permission_ccl_reloadEdgeAgentConfig := "6335f100-e68e-4e4d-b46d-85b42f85a036" | quote}} + + {{$permission_git_createRepo := "3668660f-f949-4657-be76-21967144c1a2" | quote}} + {{$permission_git_pullFromRepo := "12ecb694-b4b9-4d2a-927e-d100019f7ebe" | quote}} + {{$permission_git_pushToRepo := "b2d8d437-5060-4202-bcc2-bd2beda09651" | quote}} + + {{$permission_clusterManager_manageClusters := "a40acff8-0c61-4251-bef3-d8d53e50cdd0" | quote}} + {{$permission_clusterManager_manageSecrets := "07fba27a-0d01-4c07-875b-d25345261d3a" | quote}} + + {{$permissionGroup_authorisation := "50b727d4-3faa-40dc-b347-01c99a226c58" | quote}} + {{$permissionGroup_configStore := "c43c7157-a50b-4d2a-ac1a-86ff8e8e88c1" | quote}} + {{$permissionGroup_mqtt := "a637134a-d06b-41e7-ad86-4bf62fde914a" | quote}} + {{$permissionGroup_directory := "58b5da47-d098-44f7-8c1d-6e4bd800e718" | quote}} + {{$permissionGroup_commands := "9584ee09-a35a-4278-bc13-21a8be1f007c" | quote}} + {{$permissionGroup_git := "c0c55c78-116e-4526-8ff4-e4595251f76c" | quote}} + {{$permissionGroup_clusterManager := "9e07fd33-6400-4662-92c4-4dff1f61f990" | quote}} + + {{$role_commandEscalation := "dbd0c099-6c59-4bc6-aa92-4ba8a9b543f4" | quote}} + {{$role_edgeNode := "87e4a5b7-9a89-4796-a216-39666a47b9d2" | quote}} + {{$role_edgeNodeConsumer := "17a64293-b82d-4db4-af4d-63359bb62934" | quote}} + {{$role_globalPrimaryApplication := "c0d17bcf-2a90-40e5-b244-07bf631f7417" | quote}} + {{$role_warehouse := "6958c812-fbe2-4e6c-b997-6f850b89f679" | quote}} + + {{$schema_serviceV1 := "05688a03-730e-4cda-9932-172e2c62e45c" | quote}} + {{$schema_threePhaseCircuitV1 := "0d3dbae6-3195-4249-9ca1-897221db016f" | quote}} + {{$schema_directCurrentCircuitV1 := "462a55a1-d942-4fe8-83ff-63f66bf069d4" | quote}} + {{$schema_powerMonitoringV1 := "481dbce2-cabc-4fb1-b402-ee51f49f62b0" | quote}} + {{$schema_powerMonitoringV2 := "b6253da7-8d95-455c-bc42-23693ca95d46" | quote}} + {{$schema_singlePhaseCircuitV1 := "d6de8765-bfbe-4f6b-b5d8-822dbd7f3a49" | quote}} + + # XXX These are currently all fixed UUIDs which will end up identical + # between installations. This is incorrect: these represent the accounts + # created in the local realm, and different accounts in different realms + # should have different UUIDs. There was originally logic here in the + # Helm chart to generate these unique UUIDs, but this turned out to be + # difficult to manage across ACS upgrades. + {{$serviceAccount_authorisation := "1e1989ab-14e4-42bd-8171-495230acc406" | quote}} + {{$serviceAccount_commandEscalation := "23d4e8f9-76c0-49d5-addc-00b6ac05ee58" | quote}} + {{$serviceAccount_configStore := "36861e8d-9152-40c4-8f08-f51c2d7e3c25" | quote}} + {{$serviceAccount_dataWarehouse := "388ddbdc-4eb4-4ae8-bbd0-9be32f3c31e8" | quote}} + {{$serviceAccount_directory := "5cc3b068-938f-4bb2-8ceb-64338a02fbeb" | quote}} + {{$serviceAccount_manager := "2340e706-1280-420c-84a6-016547b55e95" | quote}} + {{$serviceAccount_mqtt := "2f42daeb-4521-4522-8e19-85dfb73db88e" | quote}} + {{$serviceAccount_krbkeys := "a04b4195-7db4-4480-b3f3-4d22c08b96ea" | quote}} + {{$serviceAccount_git := "626df296-8156-4c67-8aed-aac70161aa8b" | quote}} + {{$serviceAccount_clusterManager := "127cde3c-773a-4f61-b0ba-7412a2695253" | quote}} + {{$userGroup_sparkplugNode := "1d3121a0-aade-4376-8fa3-57ba1460ba76" | quote}} -{{$permissionGroup_authorisation := "50b727d4-3faa-40dc-b347-01c99a226c58" | quote}} -{{$permissionGroup_configStore := "c43c7157-a50b-4d2a-ac1a-86ff8e8e88c1" | quote}} -{{$permissionGroup_mqtt := "a637134a-d06b-41e7-ad86-4bf62fde914a" | quote}} -{{$permissionGroup_directory := "58b5da47-d098-44f7-8c1d-6e4bd800e718" | quote}} -{{$permissionGroup_commands := "9584ee09-a35a-4278-bc13-21a8be1f007c" | quote}} -{{$permissionGroup_git := "c0c55c78-116e-4526-8ff4-e4595251f76c" | quote}} -{{$permissionGroup_clusterManager := "9e07fd33-6400-4662-92c4-4dff1f61f990" | quote}} - -{{$role_commandEscalation := "dbd0c099-6c59-4bc6-aa92-4ba8a9b543f4" | quote}} -{{$role_edgeNode := "87e4a5b7-9a89-4796-a216-39666a47b9d2" | quote}} -{{$role_edgeNodeConsumer := "17a64293-b82d-4db4-af4d-63359bb62934" | quote}} -{{$role_globalPrimaryApplication := "c0d17bcf-2a90-40e5-b244-07bf631f7417" | quote}} -{{$role_warehouse := "6958c812-fbe2-4e6c-b997-6f850b89f679" | quote}} - -{{$schema_serviceV1 := "05688a03-730e-4cda-9932-172e2c62e45c" | quote}} -{{$schema_threePhaseCircuitV1 := "0d3dbae6-3195-4249-9ca1-897221db016f" | quote}} -{{$schema_directCurrentCircuitV1 := "462a55a1-d942-4fe8-83ff-63f66bf069d4" | quote}} -{{$schema_powerMonitoringV1 := "481dbce2-cabc-4fb1-b402-ee51f49f62b0" | quote}} -{{$schema_powerMonitoringV2 := "b6253da7-8d95-455c-bc42-23693ca95d46" | quote}} -{{$schema_singlePhaseCircuitV1 := "d6de8765-bfbe-4f6b-b5d8-822dbd7f3a49" | quote}} - -# XXX These are currently all fixed UUIDs which will end up identical -# between installations. This is incorrect: these represent the accounts -# created in the local realm, and different accounts in different realms -# should have different UUIDs. There was originally logic here in the -# Helm chart to generate these unique UUIDs, but this turned out to be -# difficult to manage across ACS upgrades. -{{$serviceAccount_authorisation := "1e1989ab-14e4-42bd-8171-495230acc406" | quote}} -{{$serviceAccount_commandEscalation := "23d4e8f9-76c0-49d5-addc-00b6ac05ee58" | quote}} -{{$serviceAccount_configStore := "36861e8d-9152-40c4-8f08-f51c2d7e3c25" | quote}} -{{$serviceAccount_dataWarehouse := "388ddbdc-4eb4-4ae8-bbd0-9be32f3c31e8" | quote}} -{{$serviceAccount_directory := "5cc3b068-938f-4bb2-8ceb-64338a02fbeb" | quote}} -{{$serviceAccount_manager := "2340e706-1280-420c-84a6-016547b55e95" | quote}} -{{$serviceAccount_mqtt := "2f42daeb-4521-4522-8e19-85dfb73db88e" | quote}} -{{$serviceAccount_krbkeys := "a04b4195-7db4-4480-b3f3-4d22c08b96ea" | quote}} -{{$serviceAccount_git := "626df296-8156-4c67-8aed-aac70161aa8b" | quote}} -{{$serviceAccount_clusterManager := "127cde3c-773a-4f61-b0ba-7412a2695253" | quote}} -{{$userGroup_sparkplugNode := "1d3121a0-aade-4376-8fa3-57ba1460ba76" | quote}} - -{{ if .Values.configdb.enabled }} + { { if .Values.configdb.enabled } } apiVersion: v1 kind: ConfigMap metadata: name: configdb-json-dumps - namespace: {{ .Release.Namespace }} + namespace: { { .Release.Namespace } } labels: component: configdb data: @@ -208,6 +210,8 @@ data: {{$permission_mqtt_issueGroupCommands}}, {{$permission_mqtt_subscribeReadOwnGroup}}, {{$permission_mqtt_representDevices}}, + {{$permission_mqtt_writeToUNSNamespace}}, + {{$permission_mqtt_subscribeReadWholeUNSNamespace}}, {{$permission_auth_readKerberosMapping}}, {{$permission_mqtt_readAllBirthMessages}}, {{$permission_ccl_rebirth}}, @@ -357,6 +361,12 @@ data: {{$permission_mqtt_representDevices}}: { "name": "MQTT: Represent Devices" }, + {{$permission_mqtt_writeToUNSNamespace}}: { + "name": "MQTT: Write to UNS Namespace" + }, + {{$permission_mqtt_subscribeReadWholeUNSNamespace}}: { + "name": "MQTT: Subscribe and read to whole UNS namespace" + }, {{$classDef_serviceAccount}}: { "name": "Service Account" }, @@ -483,6 +493,12 @@ data: {{$permission_mqtt_readAllBirthMessages}}: { "spBv1.0/+/NBIRTH/+": "rs", "spBv1.0/+/DBIRTH/+/+": "rs" + }, + {{$permission_mqtt_subscribeReadWholeUNSNamespace}} :{ + "UNS/v1/#: rs" + }, + {{$permission_mqtt_writeToUNSNamespace}}: { + "UNS/v1/#: w" } }, {{$application_sparkplugAddressInformation}}: { @@ -853,14 +869,14 @@ data: } } -{{end}}{{/* configdb.enabled */}} + {{end}}{{/* configdb.enabled */}} --- -{{ if .Values.auth.enabled }} + { { if .Values.auth.enabled } } apiVersion: v1 kind: ConfigMap metadata: name: auth-json-dumps - namespace: {{ .Release.Namespace }} + namespace: { { .Release.Namespace } } labels: component: auth data: @@ -1088,7 +1104,9 @@ data: ], {{$role_warehouse}}: [ {{$permission_mqtt_subscribeReadWholeNamespace}}, - {{$permission_ccl_rebirth}} + {{$permission_ccl_rebirth}}, + {{$permission_mqtt_subscribeReadWholeUNSNamespace}}, + {{$permission_mqtt_writeToUNSNamespace}} ], {{$role_commandEscalation}}: [ {{$permission_mqtt_issueGlobalCommands}}, @@ -1135,7 +1153,9 @@ data: {{$permission_mqtt_issueGroupCommands}}, {{$permission_mqtt_subscribeReadOwnGroup}}, {{$permission_mqtt_representDevices}}, - {{$permission_mqtt_readAllBirthMessages}} + {{$permission_mqtt_readAllBirthMessages}}, + {{$permission_mqtt_writeToUNSNamespace}}, + {{$permission_mqtt_subscribeReadWholeUNSNamespace}} ], {{$permissionGroup_configStore}}: [ {{$permission_configStore_readConfigForApp}}, @@ -1401,4 +1421,4 @@ data: } } -{{end}}{{/* auth.enabled */}} + {{end}}{{/* auth.enabled */}} From b3f5d3ec941d98cc60e4f1a345ca3c69d0748d7d Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Fri, 6 Sep 2024 10:12:06 +0100 Subject: [PATCH 33/58] Deploy: WIP add helm chart for UNS mode --- .../ingester/sparkplug-ingester.yaml | 0 deploy/templates/warehouse/uns-injector.yaml | 70 +++++++++++++++++++ deploy/values.yaml | 39 +++++++++-- 3 files changed, 102 insertions(+), 7 deletions(-) create mode 100644 deploy/templates/ingester/sparkplug-ingester.yaml create mode 100644 deploy/templates/warehouse/uns-injector.yaml diff --git a/deploy/templates/ingester/sparkplug-ingester.yaml b/deploy/templates/ingester/sparkplug-ingester.yaml new file mode 100644 index 00000000..e69de29b diff --git a/deploy/templates/warehouse/uns-injector.yaml b/deploy/templates/warehouse/uns-injector.yaml new file mode 100644 index 00000000..29ea6c93 --- /dev/null +++ b/deploy/templates/warehouse/uns-injector.yaml @@ -0,0 +1,70 @@ +{ { if and (eq .Values.acs.unsMode.enabled) (eq .Values.warehouse.injector true) } } +apiVersion: apps/v1 +kind: Deployment +metadata: + name: influxdb-injector + namespace: { { .Release.Namespace } } + labels: + component: influxdb-injector +spec: + replicas: 1 + selector: + matchLabels: + component: influxdb-injector + template: + metadata: + labels: + component: influxdb-injector + factory-plus.service: influxdb-injector + spec: + { { - with .Values.acs.imagePullSecrets } } + imagePullSecrets: + { { - toYaml . | nindent 8 } } + { { - end } } + volumes: + - name: krb5-conf + configMap: + name: krb5-conf + - name: krb5-keytabs + secret: + secretName: krb5-keytabs + items: + - key: sv1warehouse + path: client + + containers: + - name: influxdb-ingester + image: "{{ include "amrc-connectivity-stack.image-name" (list . .Values.warehouse.injector) }}" + command: [ "/usr/bin/k5start", "-Uf", "/keytabs/client" ] + args: [ "node", "--es-module-specifier-resolution=node", "bin/injector.js" ] + imagePullPolicy: Always + env: + - name: KRB5_CONFIG + value: /config/krb5-conf/krb5.conf + - name: CLIENT_KEYTAB + value: /keytabs/client + - name: LOG_LEVEL + value: { { .Values.warehouse.injector.logLevel | required "values.warehouse.injector.logLevel" } } + - name: BATCH_SIZE + value: { { .Values.warehouse.injector.batchSize | quote | required "values.warehouse.injector.batchSize" } } + - name: FLUSH_INTERVAL + value: { { .Values.warehouse.injector.flushInterval | quote | required "values.warehouse.injector.flushInterval" } } + - name: DIRECTORY_URL + value: http://directory.{{ .Release.Namespace }}.svc.cluster.local + - name: INFLUX_URL + value: http://acs-influxdb2.{{ .Release.Namespace }}.svc.cluster.local + - name: INFLUX_ORG + value: default + - name: INFLUX_BUCKET + value: 'default' + - name: INFLUX_TOKEN + valueFrom: + secretKeyRef: + name: influxdb-auth + key: admin-token + volumeMounts: + - mountPath: /config/krb5-conf + name: krb5-conf + - mountPath: /keytabs + name: krb5-keytabs + { { - end - } } diff --git a/deploy/values.yaml b/deploy/values.yaml index 311abdc7..17b549eb 100644 --- a/deploy/values.yaml +++ b/deploy/values.yaml @@ -5,13 +5,15 @@ acs: baseUrl: factoryplus.myorganisation.com # -- Whether or not services should be served over HTTPS secure: true + # -- Whether the metrics from the sparkplug namespace will be republished to the UNS namespace + unsMode: true # -- The name of the secret holding the wildcard certificate for the # above domain. It will be used for every service unless that service # specifies its own tlsSecretName. tlsSecretName: factoryplus-tls cacheMaxAge: 300 # -- Image pull secrets for container images - imagePullSecrets: [] + imagePullSecrets: [ ] # -- An optional tag that will force images to use this version # regardless of the version in the Helm chart. Each component can # further override this value by setting the `tag` property in its @@ -27,7 +29,7 @@ identity: # objects with 'principal', 'permission' and (optionally) # 'restrictions' properties; see the kadmin documentation for their # meaning. - kadminUsers: [] + kadminUsers: [ ] # -- Enable support for cross-realm authentication crossRealm: [ ] # crossRealm: @@ -129,8 +131,8 @@ serviceSetup: # Helm charts to deploy to the edge; these default to the charts # created automatically but can be overridden to customise helmChart: - # Chart to deploy an edge cluster - #cluster: null + # Chart to deploy an edge cluster + #cluster: null mqtt: # -- Whether or not to enable the MQTT component @@ -144,6 +146,15 @@ mqtt: # -- Possible values are either 1 to enable all possible debugging, or a comma-separated list of debug tags (the tags printed before the log lines). No logging is specified as an empty string. verbosity: 0 + ingester: + enabled: true + image: + # -- The registry of the MQTT component + registry: ghcr.io/amrc-factoryplus + # -- The repository of the MQTT component + repository: sparkplug-ingester + pullPolicy: IfNotPresent + visualiser: enabled: true image: @@ -213,6 +224,20 @@ warehouse: repository: influxdb-sparkplug-ingester pullPolicy: IfNotPresent + injector: + enabled: true + # -- The minimum log level that the injector will log messages at (One of 'fatal', 'error', 'warn', 'info', 'debug', 'trace' or 'silent'.) + logLevel: info + # -- The number of messages to batch together before sending to InfluxDB + batchSize: 5000 + # -- Send all buffered messages after this amount of time has elapsed if the buffer is not full (in milliseconds) + flushInterval: 10000 + image: + # -- The registry of the Warehouse component + registry: ghcr.io/amrc-factoryplus + # -- The repository of the Warehouse component + repository: influxdb-injector + pullPolicy: IfNotPresent git: # -- Whether or not to enable the Git component enabled: true @@ -254,7 +279,7 @@ shell: pullPolicy: IfNotPresent # XXX This should probably be included in acs-krb-utils -curl: +curl: image: registry: docker.io repository: appropriate/curl @@ -330,8 +355,8 @@ traefik: ingressRoute: dashboard: enabled: false -# -- [AZURE] Enable the below section to expose your instance of Factory+/ACS over the internet, replacing the -# -- tags with the details of your pre-configured load balancer. + # -- [AZURE] Enable the below section to expose your instance of Factory+/ACS over the internet, replacing the + # -- tags with the details of your pre-configured load balancer. service: spec: loadBalancerIP: From ad7070239baca010d0165a07215bede0f6a34c2b Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Fri, 6 Sep 2024 13:09:34 +0100 Subject: [PATCH 34/58] Add UNS-specific items to service-setup --- acs-manager/get-keytab.sh | 2 +- acs-service-setup/dumps/uns.yaml | 38 +++ acs-service-setup/lib/uuids.js | 7 + acs-service-setup/package.json | 2 +- .../auth/principals/service-clients.yaml | 12 + deploy/templates/dumps.yaml | 298 ++++++++---------- 6 files changed, 198 insertions(+), 161 deletions(-) create mode 100644 acs-service-setup/dumps/uns.yaml diff --git a/acs-manager/get-keytab.sh b/acs-manager/get-keytab.sh index cc72b489..58a31a4a 100755 --- a/acs-manager/get-keytab.sh +++ b/acs-manager/get-keytab.sh @@ -4,4 +4,4 @@ # # bin/bash -kubectl --kubeconfig ./k3s.yaml get -n fpd-v3 secret manager-keytab -o jsonpath="{.data.client-keytab}" | base64 -d >"./keytab" +kubectl --kubeconfig /Users/me1ago/.kube/ago.yaml get -n factory-plus secret manager-keytab -o jsonpath="{.data.client-keytab}" | base64 -d >"./keytab" diff --git a/acs-service-setup/dumps/uns.yaml b/acs-service-setup/dumps/uns.yaml new file mode 100644 index 00000000..7d0d18b7 --- /dev/null +++ b/acs-service-setup/dumps/uns.yaml @@ -0,0 +1,38 @@ +# This dump creates a service account for the Sparkplug Ingester service +# and grants it the necessary permissions to read and write to the UNS. +# It also adds the ReadEntireUNS permission to the Warehouse role so +# that the UNS historian can use it and has permission to read the UNS. +--- +service: !u UUIDs.Service.ConfigDB +version: 1 +overwrite: true +objects: + !u ACS.Class.Permission: + - !u ACS.Perm.MQTT.WriteToEntireUNS + - !u ACS.Perm.MQTT.ReadEntireUNS + !u ACS.Class.ServiceAccount: + - !u ACS.ServiceAccount.SparkplugIngester +configs: + !u UUIDs.App.Info: + !u ACS.Perm.MQTT.WriteToEntireUNS: { name: "MQTT: Write to entire UNS" } + !u ACS.Perm.MQTT.ReadEntireUNS: { name: "MQTT: Read entire UNS" } + !u ACS.ServiceAccount.SparkplugIngester: { name: "Sparkplug Ingester" } + !u UUIDs.App.MQTTPermissionTemplate: + !u ACS.Perm.MQTT.WriteToEntireUNS: "UNS/v1/#: w" + !u ACS.Perm.MQTT.ReadEntireUNS: "UNS/v1/#: rs" +--- +service: !u UUIDs.Service.Authentication +version: 1 +groups: + !u ACS.Role.Warehouse: + - !u ACS.Perm.MQTT.ReadEntireUNS +principals: + - uuid: !u ACS.ServiceAccount.SparkplugIngester + kerberos: sv1sparkplugingester@{{realm}} +aces: + - principal: !u ACS.ServiceAccount.SparkplugIngester + permission: !u ACS.Perm.MQTT.WriteToEntireUNS + target: !u UUIDs.Special.Null + - principal: !u ACS.ServiceAccount.SparkplugIngester + permission: !u ACS.Perm.MQTT.ReadWholeNamespace + target: !u UUIDs.Special.Null diff --git a/acs-service-setup/lib/uuids.js b/acs-service-setup/lib/uuids.js index d1886457..eb82fe08 100644 --- a/acs-service-setup/lib/uuids.js +++ b/acs-service-setup/lib/uuids.js @@ -8,6 +8,7 @@ export const ACS = { ClientRole: "1c567e3c-5519-4418-8682-6086f22fbc13", EdgeAccount: "97756c9a-38e6-4238-b78c-3df6f227a6c9", ServiceAccount: "e463b4ae-a322-46cc-8976-4ba76838e908", + Permission: "8ae784bb-c4b5-4995-9bf6-799b3c7f21ad", UserAccount: "8b3e8f35-78e5-4f93-bf21-7238bcb2ba9d", UserGroup: "f1fabdd1-de90-4399-b3da-ccf6c2b2c08b", }, @@ -27,6 +28,8 @@ export const ACS = { ReadAllStates: "8790cf3d-b793-423c-b373-8cfcf9f63529", ReadNode: "046d6603-fa62-4208-9400-65d61f8b1ec4", ReadWholeNamespace: "81833dbb-1150-4078-b1db-978c646ba73e", + WriteToEntireUNS: "9fa6ff20-9d2a-4444-960c-40ebcf56f5b4", + ReadEntireUNS: "ffa40b36-3a61-4545-832a-2d1e8b860d63", }, }, PermGroup: { @@ -41,9 +44,13 @@ export const ACS = { Service: { Manager: "619eecab-742d-4824-8b97-bcae472e5c04", }, + ServiceAccount: { + SparkplugIngester: "e5939141-a3d5-4ab8-b609-b450ca785d7c", + }, Role: { EdgeNodeConsumer: "17a64293-b82d-4db4-af4d-63359bb62934", GlobalDebugger: "4473fe9c-05b0-42cc-ad8c-8e05f6d0ca86", + Warehouse: "6958c812-fbe2-4e6c-b997-6f850b89f679", }, /* XXX This should not be fixed. Currently this matches the fixed * UUID deployed by the dumps in the ACS Helm chart. This needs diff --git a/acs-service-setup/package.json b/acs-service-setup/package.json index 7455c0a7..8d84d61b 100644 --- a/acs-service-setup/package.json +++ b/acs-service-setup/package.json @@ -12,7 +12,7 @@ "author": "", "license": "ISC", "dependencies": { - "@amrc-factoryplus/utilities": "^1.3.1", + "@amrc-factoryplus/utilities": "^1.3.4", "eslint": "^8.55.0", "yaml": "^2.3.4" } diff --git a/deploy/templates/auth/principals/service-clients.yaml b/deploy/templates/auth/principals/service-clients.yaml index 69326cc9..ad4f2ff1 100644 --- a/deploy/templates/auth/principals/service-clients.yaml +++ b/deploy/templates/auth/principals/service-clients.yaml @@ -122,3 +122,15 @@ spec: group: {{ .Values.acs.organisation }}-Service-Core node: Monitor {{- end }} +--- +{{- if .Values.acs.unsMode }} +apiVersion: factoryplus.app.amrc.co.uk/v1 +kind: KerberosKey +metadata: + name: sv1sparkplugingester + namespace: {{ .Release.Namespace }} +spec: + type: Random + principal: sv1sparkplugingester@{{ .Values.identity.realm | required "values.identity.realm is required!" }} + secret: sparkplugingester-keytabs/client +{{- end }} diff --git a/deploy/templates/dumps.yaml b/deploy/templates/dumps.yaml index de6b54e0..95f3fbf7 100644 --- a/deploy/templates/dumps.yaml +++ b/deploy/templates/dumps.yaml @@ -1,146 +1,144 @@ # ==================================================== # Ensure that well-known UUIDs are used where required - # ---------------------------------------------------- - # ⚠ Do not change these! - # ==================================================== +# ---------------------------------------------------- +# ⚠ Do not change these! +# ==================================================== + +{{$classDef_classDefinition := "04a1c90d-2295-4cbe-b33a-74eded62cbf1" | quote}} +{{$classDef_application := "d319bd87-f42b-4b66-be4f-f82ff48b93f0" | quote}} +{{$classDef_serviceFunction := "265d481f-87a7-4f93-8fc6-53fa64dc11bb" | quote}} +{{$classDef_serviceAccount := "e463b4ae-a322-46cc-8976-4ba76838e908" | quote}} +{{$classDef_permission := "8ae784bb-c4b5-4995-9bf6-799b3c7f21ad" | quote}} +{{$classDef_permissionGroup := "ac0d5288-6136-4ced-a372-325fbbcdd70d" | quote}} +{{$classDef_clientRole := "1c567e3c-5519-4418-8682-6086f22fbc13" | quote}} +{{$classDef_userAccount := "8b3e8f35-78e5-4f93-bf21-7238bcb2ba9d" | quote}} +{{$classDef_userGroup := "f1fabdd1-de90-4399-b3da-ccf6c2b2c08b" | quote}} +{{$classDef_cellGateway := "00da3c0b-f62b-4761-a689-39ad0c33f864" | quote}} +{{$classDef_softGateway := "5bee4d24-32e1-44f8-b953-1f86ff4b3e87" | quote}} +{{$classDef_serviceRequirement := "b419cbc2-ab0f-4311-bd9e-f0591f7e88cb" | quote}} +{{$classDef_gitRepo := "d25f2afc-1ab8-4d27-b51b-d02314624e3e" | quote}} +{{$classDef_edgeClusterAccount := "97756c9a-38e6-4238-b78c-3df6f227a6c9" | quote}} +{{$classDef_edgeCluster := "f24d354d-abc1-4e32-98e1-0667b3e40b61" | quote}} +{{$classDef_metricSchema := "83ee28d4-023e-4c2c-ab86-12c24e86372c" | quote}} + +{{$special_wildcard := "00000000-0000-0000-0000-000000000000" | quote}} +{{$special_self := "5855a1cc-46d8-4b16-84f8-ab3916ecb230" | quote}} + +{{$application_objectRegistration := "cb40bed5-49ad-4443-a7f5-08c75009da8f" | quote}} +{{$application_generalObjectInformation := "64a8bfa9-7772-45c4-9d1a-9e6290690957" | quote}} +{{$application_applicationConfigSchema := "dbd8a535-52ba-4f6e-b4f8-9b71aefe09d3" | quote}} +{{$application_mqttPermissionTemplate := "1266ddf1-156c-4266-9808-d6949418b185" | quote}} +{{$application_sparkplugAddressInformation := "8e32801b-f35a-4cbf-a5c3-2af64d3debd7" | quote}} +{{$application_commandEscalation := "60e99f28-67fe-4344-a6ab-b1edb8b8e810" | quote}} +{{$application_gitRepoConfiguration := "38d62a93-b6b4-4f63-bad4-d433e3eaff29" | quote}} +{{$application_edgeClusterConfiguration := "bdb13634-0b3d-4e38-a065-9d88c12ee78d" | quote}} +{{$application_edgeClusterStatus := "747a62c9-1b66-4a2e-8dd9-0b70a91b6b75" | quote}} +{{$application_edgeDeployment := "f2b9417a-ef7f-421f-b387-bb8183a48cdb" | quote}} +{{$application_helmChartTemplate := "729fe070-5e67-4bc7-94b5-afd75cb42b03" | quote}} +{{$application_serviceSetup := "5b47881c-b012-4040-945c-eacafca539b2" | quote}} +{{$application_edgeAgentConfig := "aac6f843-cfee-4683-b121-6943bfdf9173" | quote }} +{{$application_serviceConfig := "5b47881c-b012-4040-945c-eacafca539b2" | quote}} +{{$application_schemaIcon := "65c0ccba-151d-48d3-97b4-d0026a811900" | quote}} + +{{$service_configStore := "af15f175-78a0-4e05-97c0-2a0bb82b9f3b" | quote}} +{{$service_commandEscalation := "78ea7071-24ac-4916-8351-aa3e549d8ccd" | quote}} +{{$service_directory := "af4a1d66-e6f7-43c4-8a67-0fa3be2b1cf9" | quote}} +{{$service_authorisation := "cab2642a-f7d9-42e5-8845-8f35affe1fd4" | quote}} +{{$service_mqtt := "feb27ba3-bd2c-4916-9269-79a61ebc4a47" | quote}} +{{$service_warehouse := "a8e5a73f-2dd1-4cda-8e46-bc6cedb14269" | quote}} +{{$service_git := "7adf4db0-2e7b-4a68-ab9d-376f4c5ce14b" | quote}} +{{$service_manager := "619eecab-742d-4824-8b97-bcae472e5c04" | quote}} + +{{$serviceRequirement_gitServiceAccount := "a461ef62-0560-4be2-8d97-1a56916ce4f8" | quote}} +{{$serviceRequirement_edgeDeploymentServiceAccount := "26d192cf-73c1-4c14-93cf-1e63743bab08" | quote}} +{{$serviceRequirement_edgeClusterRepositories := "3a58340c-d4ec-453d-99c3-0cf6ab7d8fa9" | quote}} + +{{$permission_auth_manageKerberosMappings := "327c4cc8-9c46-4e1e-bb6b-257ace37b0f6" | quote}} +{{$permission_auth_readEffectivePermissions := "35252562-51e5-4dd8-84cd-ba0fafa62669" | quote}} +{{$permission_auth_manageACLsPerPermission := "3a41f5ce-fc08-4669-9762-ec9e71061168" | quote}} +{{$permission_auth_readACLEntry := "ba566181-0e8a-405b-b16e-3fb89130fbee" | quote}} +{{$permission_auth_manageGroups := "be9b6d47-c845-49b2-b9d5-d87b83f11c3b" | quote}} +{{$permission_auth_readKerberosMapping := "e8c9c0f7-0d54-4db2-b8d6-cd80c45f6a5c" | quote}} + +{{$permission_configStore_readConfigForApp := "4a339562-cd57-408d-9d1a-6529a383ea4b" | quote}} +{{$permission_configStore_writeConfigForApp := "6c799ccb-d2ad-4715-a2a7-3c8728d6c0bf" | quote}} +{{$permission_configStore_manageAppSchema := "95c7cbcb-ce60-49ed-aa81-2fe3eec4559d" | quote}} +{{$permission_configStore_manageObjects := "f0b7917b-d475-4888-9d5a-2af96b3c26b6" | quote}} +{{$permission_configStore_deleteObjects := "6957174b-7b08-45ca-ac5c-c03ab6928a6e" | quote}} + +{{$permission_mqtt_subscribeReadNode := "046d6603-fa62-4208-9400-65d61f8b1ec4" | quote}} +{{$permission_mqtt_subscribeToWholeNamespace := "21000098-3a53-48da-8d3e-cc0650603d8e" | quote}} +{{$permission_mqtt_subscribeReadWholeNamespace := "81833dbb-1150-4078-b1db-978c646ba73e" | quote}} +{{$permission_mqtt_issueGlobalCommands := "50f1e694-7e18-4930-aa59-97cc90a6a1ec" | quote}} +{{$permission_mqtt_publishAllFromGroup := "64c019f8-6754-4270-8917-6659a5628b86" | quote}} +{{$permission_mqtt_subscribeReadAllStates := "8790cf3d-b793-423c-b373-8cfcf9f63529" | quote}} +{{$permission_mqtt_updateGroupState := "9a32f195-a8cc-4562-a87a-d4653279474f" | quote}} +{{$permission_mqtt_participateAsNode := "a1314953-8226-44f4-8a3e-e87b09310579" | quote}} +{{$permission_mqtt_updateOwnState := "bdc96a3e-d6fb-48ed-b790-0aa95cf826f0" | quote}} +{{$permission_mqtt_issueGroupCommands := "cff45682-f2f0-4c72-91f3-7dda20d43509" | quote}} +{{$permission_mqtt_subscribeReadOwnGroup := "d617e37c-3908-41b1-8820-d3f8d41a4280" | quote}} +{{$permission_mqtt_representDevices := "e82456b3-a7d9-4971-9d8c-fd0be4545ab4" | quote}} +{{$permission_mqtt_readAllBirthMessages := "67dc4dd0-0939-42b1-b1f9-9049f4d91d40" | quote}} + +{{$permission_directory_overrideServiceAdvertisementPermissions := "3bda2ab2-4128-463d-83c9-16b976a8d83e" | quote}} +{{$permission_directory_advertiseService := "4db4c39a-f18d-4e83-aeb0-5af2c14ddc2b" | quote}} +{{$permission_directory_manageServiceAdvertisementForOwner := "97dcf2a1-7f4b-476c-b561-e40fc42440ee" | quote}} + +{{$permission_ccl_rebirth := "fbb9c25d-386d-4966-a325-f16471d9f7be" | quote}} +{{$permission_ccl_reloadEdgeAgentConfig := "6335f100-e68e-4e4d-b46d-85b42f85a036" | quote}} + +{{$permission_git_createRepo := "3668660f-f949-4657-be76-21967144c1a2" | quote}} +{{$permission_git_pullFromRepo := "12ecb694-b4b9-4d2a-927e-d100019f7ebe" | quote}} +{{$permission_git_pushToRepo := "b2d8d437-5060-4202-bcc2-bd2beda09651" | quote}} - {{$classDef_classDefinition := "04a1c90d-2295-4cbe-b33a-74eded62cbf1" | quote}} - {{$classDef_application := "d319bd87-f42b-4b66-be4f-f82ff48b93f0" | quote}} - {{$classDef_serviceFunction := "265d481f-87a7-4f93-8fc6-53fa64dc11bb" | quote}} - {{$classDef_serviceAccount := "e463b4ae-a322-46cc-8976-4ba76838e908" | quote}} - {{$classDef_permission := "8ae784bb-c4b5-4995-9bf6-799b3c7f21ad" | quote}} - {{$classDef_permissionGroup := "ac0d5288-6136-4ced-a372-325fbbcdd70d" | quote}} - {{$classDef_clientRole := "1c567e3c-5519-4418-8682-6086f22fbc13" | quote}} - {{$classDef_userAccount := "8b3e8f35-78e5-4f93-bf21-7238bcb2ba9d" | quote}} - {{$classDef_userGroup := "f1fabdd1-de90-4399-b3da-ccf6c2b2c08b" | quote}} - {{$classDef_cellGateway := "00da3c0b-f62b-4761-a689-39ad0c33f864" | quote}} - {{$classDef_softGateway := "5bee4d24-32e1-44f8-b953-1f86ff4b3e87" | quote}} - {{$classDef_serviceRequirement := "b419cbc2-ab0f-4311-bd9e-f0591f7e88cb" | quote}} - {{$classDef_gitRepo := "d25f2afc-1ab8-4d27-b51b-d02314624e3e" | quote}} - {{$classDef_edgeClusterAccount := "97756c9a-38e6-4238-b78c-3df6f227a6c9" | quote}} - {{$classDef_edgeCluster := "f24d354d-abc1-4e32-98e1-0667b3e40b61" | quote}} - {{$classDef_metricSchema := "83ee28d4-023e-4c2c-ab86-12c24e86372c" | quote}} - - {{$special_wildcard := "00000000-0000-0000-0000-000000000000" | quote}} - {{$special_self := "5855a1cc-46d8-4b16-84f8-ab3916ecb230" | quote}} - - {{$application_objectRegistration := "cb40bed5-49ad-4443-a7f5-08c75009da8f" | quote}} - {{$application_generalObjectInformation := "64a8bfa9-7772-45c4-9d1a-9e6290690957" | quote}} - {{$application_applicationConfigSchema := "dbd8a535-52ba-4f6e-b4f8-9b71aefe09d3" | quote}} - {{$application_mqttPermissionTemplate := "1266ddf1-156c-4266-9808-d6949418b185" | quote}} - {{$application_sparkplugAddressInformation := "8e32801b-f35a-4cbf-a5c3-2af64d3debd7" | quote}} - {{$application_commandEscalation := "60e99f28-67fe-4344-a6ab-b1edb8b8e810" | quote}} - {{$application_gitRepoConfiguration := "38d62a93-b6b4-4f63-bad4-d433e3eaff29" | quote}} - {{$application_edgeClusterConfiguration := "bdb13634-0b3d-4e38-a065-9d88c12ee78d" | quote}} - {{$application_edgeClusterStatus := "747a62c9-1b66-4a2e-8dd9-0b70a91b6b75" | quote}} - {{$application_edgeDeployment := "f2b9417a-ef7f-421f-b387-bb8183a48cdb" | quote}} - {{$application_helmChartTemplate := "729fe070-5e67-4bc7-94b5-afd75cb42b03" | quote}} - {{$application_serviceSetup := "5b47881c-b012-4040-945c-eacafca539b2" | quote}} - {{$application_edgeAgentConfig := "aac6f843-cfee-4683-b121-6943bfdf9173" | quote }} - {{$application_serviceConfig := "5b47881c-b012-4040-945c-eacafca539b2" | quote}} - {{$application_schemaIcon := "65c0ccba-151d-48d3-97b4-d0026a811900" | quote}} - - {{$service_configStore := "af15f175-78a0-4e05-97c0-2a0bb82b9f3b" | quote}} - {{$service_commandEscalation := "78ea7071-24ac-4916-8351-aa3e549d8ccd" | quote}} - {{$service_directory := "af4a1d66-e6f7-43c4-8a67-0fa3be2b1cf9" | quote}} - {{$service_authorisation := "cab2642a-f7d9-42e5-8845-8f35affe1fd4" | quote}} - {{$service_mqtt := "feb27ba3-bd2c-4916-9269-79a61ebc4a47" | quote}} - {{$service_warehouse := "a8e5a73f-2dd1-4cda-8e46-bc6cedb14269" | quote}} - {{$service_git := "7adf4db0-2e7b-4a68-ab9d-376f4c5ce14b" | quote}} - {{$service_manager := "619eecab-742d-4824-8b97-bcae472e5c04" | quote}} - - {{$serviceRequirement_gitServiceAccount := "a461ef62-0560-4be2-8d97-1a56916ce4f8" | quote}} - {{$serviceRequirement_edgeDeploymentServiceAccount := "26d192cf-73c1-4c14-93cf-1e63743bab08" | quote}} - {{$serviceRequirement_edgeClusterRepositories := "3a58340c-d4ec-453d-99c3-0cf6ab7d8fa9" | quote}} - - {{$permission_auth_manageKerberosMappings := "327c4cc8-9c46-4e1e-bb6b-257ace37b0f6" | quote}} - {{$permission_auth_readEffectivePermissions := "35252562-51e5-4dd8-84cd-ba0fafa62669" | quote}} - {{$permission_auth_manageACLsPerPermission := "3a41f5ce-fc08-4669-9762-ec9e71061168" | quote}} - {{$permission_auth_readACLEntry := "ba566181-0e8a-405b-b16e-3fb89130fbee" | quote}} - {{$permission_auth_manageGroups := "be9b6d47-c845-49b2-b9d5-d87b83f11c3b" | quote}} - {{$permission_auth_readKerberosMapping := "e8c9c0f7-0d54-4db2-b8d6-cd80c45f6a5c" | quote}} - - {{$permission_configStore_readConfigForApp := "4a339562-cd57-408d-9d1a-6529a383ea4b" | quote}} - {{$permission_configStore_writeConfigForApp := "6c799ccb-d2ad-4715-a2a7-3c8728d6c0bf" | quote}} - {{$permission_configStore_manageAppSchema := "95c7cbcb-ce60-49ed-aa81-2fe3eec4559d" | quote}} - {{$permission_configStore_manageObjects := "f0b7917b-d475-4888-9d5a-2af96b3c26b6" | quote}} - {{$permission_configStore_deleteObjects := "6957174b-7b08-45ca-ac5c-c03ab6928a6e" | quote}} - - {{$permission_mqtt_subscribeReadNode := "046d6603-fa62-4208-9400-65d61f8b1ec4" | quote}} - {{$permission_mqtt_subscribeToWholeNamespace := "21000098-3a53-48da-8d3e-cc0650603d8e" | quote}} - {{$permission_mqtt_subscribeReadWholeNamespace := "81833dbb-1150-4078-b1db-978c646ba73e" | quote}} - {{$permission_mqtt_issueGlobalCommands := "50f1e694-7e18-4930-aa59-97cc90a6a1ec" | quote}} - {{$permission_mqtt_publishAllFromGroup := "64c019f8-6754-4270-8917-6659a5628b86" | quote}} - {{$permission_mqtt_subscribeReadAllStates := "8790cf3d-b793-423c-b373-8cfcf9f63529" | quote}} - {{$permission_mqtt_updateGroupState := "9a32f195-a8cc-4562-a87a-d4653279474f" | quote}} - {{$permission_mqtt_participateAsNode := "a1314953-8226-44f4-8a3e-e87b09310579" | quote}} - {{$permission_mqtt_updateOwnState := "bdc96a3e-d6fb-48ed-b790-0aa95cf826f0" | quote}} - {{$permission_mqtt_issueGroupCommands := "cff45682-f2f0-4c72-91f3-7dda20d43509" | quote}} - {{$permission_mqtt_subscribeReadOwnGroup := "d617e37c-3908-41b1-8820-d3f8d41a4280" | quote}} - {{$permission_mqtt_representDevices := "e82456b3-a7d9-4971-9d8c-fd0be4545ab4" | quote}} - {{$permission_mqtt_readAllBirthMessages := "67dc4dd0-0939-42b1-b1f9-9049f4d91d40" | quote}} - {{$permission_mqtt_subscribeReadWholeUNSNamespace := "034b38e1-00f4-41bf-be2d-1d41e829526a" | quote}} - {{$permission_mqtt_writeToUNSNamespace := "1e737a42-03df-486c-89bb-78242c4b9099" | quote}} - - {{$permission_directory_overrideServiceAdvertisementPermissions := "3bda2ab2-4128-463d-83c9-16b976a8d83e" | quote}} - {{$permission_directory_advertiseService := "4db4c39a-f18d-4e83-aeb0-5af2c14ddc2b" | quote}} - {{$permission_directory_manageServiceAdvertisementForOwner := "97dcf2a1-7f4b-476c-b561-e40fc42440ee" | quote}} - - {{$permission_ccl_rebirth := "fbb9c25d-386d-4966-a325-f16471d9f7be" | quote}} - {{$permission_ccl_reloadEdgeAgentConfig := "6335f100-e68e-4e4d-b46d-85b42f85a036" | quote}} - - {{$permission_git_createRepo := "3668660f-f949-4657-be76-21967144c1a2" | quote}} - {{$permission_git_pullFromRepo := "12ecb694-b4b9-4d2a-927e-d100019f7ebe" | quote}} - {{$permission_git_pushToRepo := "b2d8d437-5060-4202-bcc2-bd2beda09651" | quote}} - - {{$permission_clusterManager_manageClusters := "a40acff8-0c61-4251-bef3-d8d53e50cdd0" | quote}} - {{$permission_clusterManager_manageSecrets := "07fba27a-0d01-4c07-875b-d25345261d3a" | quote}} - - {{$permissionGroup_authorisation := "50b727d4-3faa-40dc-b347-01c99a226c58" | quote}} - {{$permissionGroup_configStore := "c43c7157-a50b-4d2a-ac1a-86ff8e8e88c1" | quote}} - {{$permissionGroup_mqtt := "a637134a-d06b-41e7-ad86-4bf62fde914a" | quote}} - {{$permissionGroup_directory := "58b5da47-d098-44f7-8c1d-6e4bd800e718" | quote}} - {{$permissionGroup_commands := "9584ee09-a35a-4278-bc13-21a8be1f007c" | quote}} - {{$permissionGroup_git := "c0c55c78-116e-4526-8ff4-e4595251f76c" | quote}} - {{$permissionGroup_clusterManager := "9e07fd33-6400-4662-92c4-4dff1f61f990" | quote}} - - {{$role_commandEscalation := "dbd0c099-6c59-4bc6-aa92-4ba8a9b543f4" | quote}} - {{$role_edgeNode := "87e4a5b7-9a89-4796-a216-39666a47b9d2" | quote}} - {{$role_edgeNodeConsumer := "17a64293-b82d-4db4-af4d-63359bb62934" | quote}} - {{$role_globalPrimaryApplication := "c0d17bcf-2a90-40e5-b244-07bf631f7417" | quote}} - {{$role_warehouse := "6958c812-fbe2-4e6c-b997-6f850b89f679" | quote}} - - {{$schema_serviceV1 := "05688a03-730e-4cda-9932-172e2c62e45c" | quote}} - {{$schema_threePhaseCircuitV1 := "0d3dbae6-3195-4249-9ca1-897221db016f" | quote}} - {{$schema_directCurrentCircuitV1 := "462a55a1-d942-4fe8-83ff-63f66bf069d4" | quote}} - {{$schema_powerMonitoringV1 := "481dbce2-cabc-4fb1-b402-ee51f49f62b0" | quote}} - {{$schema_powerMonitoringV2 := "b6253da7-8d95-455c-bc42-23693ca95d46" | quote}} - {{$schema_singlePhaseCircuitV1 := "d6de8765-bfbe-4f6b-b5d8-822dbd7f3a49" | quote}} - - # XXX These are currently all fixed UUIDs which will end up identical - # between installations. This is incorrect: these represent the accounts - # created in the local realm, and different accounts in different realms - # should have different UUIDs. There was originally logic here in the - # Helm chart to generate these unique UUIDs, but this turned out to be - # difficult to manage across ACS upgrades. - {{$serviceAccount_authorisation := "1e1989ab-14e4-42bd-8171-495230acc406" | quote}} - {{$serviceAccount_commandEscalation := "23d4e8f9-76c0-49d5-addc-00b6ac05ee58" | quote}} - {{$serviceAccount_configStore := "36861e8d-9152-40c4-8f08-f51c2d7e3c25" | quote}} - {{$serviceAccount_dataWarehouse := "388ddbdc-4eb4-4ae8-bbd0-9be32f3c31e8" | quote}} - {{$serviceAccount_directory := "5cc3b068-938f-4bb2-8ceb-64338a02fbeb" | quote}} - {{$serviceAccount_manager := "2340e706-1280-420c-84a6-016547b55e95" | quote}} - {{$serviceAccount_mqtt := "2f42daeb-4521-4522-8e19-85dfb73db88e" | quote}} - {{$serviceAccount_krbkeys := "a04b4195-7db4-4480-b3f3-4d22c08b96ea" | quote}} - {{$serviceAccount_git := "626df296-8156-4c67-8aed-aac70161aa8b" | quote}} - {{$serviceAccount_clusterManager := "127cde3c-773a-4f61-b0ba-7412a2695253" | quote}} - {{$userGroup_sparkplugNode := "1d3121a0-aade-4376-8fa3-57ba1460ba76" | quote}} +{{$permission_clusterManager_manageClusters := "a40acff8-0c61-4251-bef3-d8d53e50cdd0" | quote}} +{{$permission_clusterManager_manageSecrets := "07fba27a-0d01-4c07-875b-d25345261d3a" | quote}} - { { if .Values.configdb.enabled } } +{{$permissionGroup_authorisation := "50b727d4-3faa-40dc-b347-01c99a226c58" | quote}} +{{$permissionGroup_configStore := "c43c7157-a50b-4d2a-ac1a-86ff8e8e88c1" | quote}} +{{$permissionGroup_mqtt := "a637134a-d06b-41e7-ad86-4bf62fde914a" | quote}} +{{$permissionGroup_directory := "58b5da47-d098-44f7-8c1d-6e4bd800e718" | quote}} +{{$permissionGroup_commands := "9584ee09-a35a-4278-bc13-21a8be1f007c" | quote}} +{{$permissionGroup_git := "c0c55c78-116e-4526-8ff4-e4595251f76c" | quote}} +{{$permissionGroup_clusterManager := "9e07fd33-6400-4662-92c4-4dff1f61f990" | quote}} + +{{$role_commandEscalation := "dbd0c099-6c59-4bc6-aa92-4ba8a9b543f4" | quote}} +{{$role_edgeNode := "87e4a5b7-9a89-4796-a216-39666a47b9d2" | quote}} +{{$role_edgeNodeConsumer := "17a64293-b82d-4db4-af4d-63359bb62934" | quote}} +{{$role_globalPrimaryApplication := "c0d17bcf-2a90-40e5-b244-07bf631f7417" | quote}} +{{$role_warehouse := "6958c812-fbe2-4e6c-b997-6f850b89f679" | quote}} + +{{$schema_serviceV1 := "05688a03-730e-4cda-9932-172e2c62e45c" | quote}} +{{$schema_threePhaseCircuitV1 := "0d3dbae6-3195-4249-9ca1-897221db016f" | quote}} +{{$schema_directCurrentCircuitV1 := "462a55a1-d942-4fe8-83ff-63f66bf069d4" | quote}} +{{$schema_powerMonitoringV1 := "481dbce2-cabc-4fb1-b402-ee51f49f62b0" | quote}} +{{$schema_powerMonitoringV2 := "b6253da7-8d95-455c-bc42-23693ca95d46" | quote}} +{{$schema_singlePhaseCircuitV1 := "d6de8765-bfbe-4f6b-b5d8-822dbd7f3a49" | quote}} + +# XXX These are currently all fixed UUIDs which will end up identical +# between installations. This is incorrect: these represent the accounts +# created in the local realm, and different accounts in different realms +# should have different UUIDs. There was originally logic here in the +# Helm chart to generate these unique UUIDs, but this turned out to be +# difficult to manage across ACS upgrades. +{{$serviceAccount_authorisation := "1e1989ab-14e4-42bd-8171-495230acc406" | quote}} +{{$serviceAccount_commandEscalation := "23d4e8f9-76c0-49d5-addc-00b6ac05ee58" | quote}} +{{$serviceAccount_configStore := "36861e8d-9152-40c4-8f08-f51c2d7e3c25" | quote}} +{{$serviceAccount_dataWarehouse := "388ddbdc-4eb4-4ae8-bbd0-9be32f3c31e8" | quote}} +{{$serviceAccount_directory := "5cc3b068-938f-4bb2-8ceb-64338a02fbeb" | quote}} +{{$serviceAccount_manager := "2340e706-1280-420c-84a6-016547b55e95" | quote}} +{{$serviceAccount_mqtt := "2f42daeb-4521-4522-8e19-85dfb73db88e" | quote}} +{{$serviceAccount_krbkeys := "a04b4195-7db4-4480-b3f3-4d22c08b96ea" | quote}} +{{$serviceAccount_git := "626df296-8156-4c67-8aed-aac70161aa8b" | quote}} +{{$serviceAccount_clusterManager := "127cde3c-773a-4f61-b0ba-7412a2695253" | quote}} +{{$userGroup_sparkplugNode := "1d3121a0-aade-4376-8fa3-57ba1460ba76" | quote}} + +{{ if .Values.configdb.enabled }} apiVersion: v1 kind: ConfigMap metadata: name: configdb-json-dumps - namespace: { { .Release.Namespace } } + namespace: {{ .Release.Namespace }} labels: component: configdb data: @@ -210,8 +208,6 @@ data: {{$permission_mqtt_issueGroupCommands}}, {{$permission_mqtt_subscribeReadOwnGroup}}, {{$permission_mqtt_representDevices}}, - {{$permission_mqtt_writeToUNSNamespace}}, - {{$permission_mqtt_subscribeReadWholeUNSNamespace}}, {{$permission_auth_readKerberosMapping}}, {{$permission_mqtt_readAllBirthMessages}}, {{$permission_ccl_rebirth}}, @@ -361,12 +357,6 @@ data: {{$permission_mqtt_representDevices}}: { "name": "MQTT: Represent Devices" }, - {{$permission_mqtt_writeToUNSNamespace}}: { - "name": "MQTT: Write to UNS Namespace" - }, - {{$permission_mqtt_subscribeReadWholeUNSNamespace}}: { - "name": "MQTT: Subscribe and read to whole UNS namespace" - }, {{$classDef_serviceAccount}}: { "name": "Service Account" }, @@ -493,12 +483,6 @@ data: {{$permission_mqtt_readAllBirthMessages}}: { "spBv1.0/+/NBIRTH/+": "rs", "spBv1.0/+/DBIRTH/+/+": "rs" - }, - {{$permission_mqtt_subscribeReadWholeUNSNamespace}} :{ - "UNS/v1/#: rs" - }, - {{$permission_mqtt_writeToUNSNamespace}}: { - "UNS/v1/#: w" } }, {{$application_sparkplugAddressInformation}}: { @@ -869,14 +853,14 @@ data: } } - {{end}}{{/* configdb.enabled */}} +{{end}}{{/* configdb.enabled */}} --- - { { if .Values.auth.enabled } } +{{ if .Values.auth.enabled }} apiVersion: v1 kind: ConfigMap metadata: name: auth-json-dumps - namespace: { { .Release.Namespace } } + namespace: {{ .Release.Namespace }} labels: component: auth data: @@ -1104,9 +1088,7 @@ data: ], {{$role_warehouse}}: [ {{$permission_mqtt_subscribeReadWholeNamespace}}, - {{$permission_ccl_rebirth}}, - {{$permission_mqtt_subscribeReadWholeUNSNamespace}}, - {{$permission_mqtt_writeToUNSNamespace}} + {{$permission_ccl_rebirth}} ], {{$role_commandEscalation}}: [ {{$permission_mqtt_issueGlobalCommands}}, @@ -1153,9 +1135,7 @@ data: {{$permission_mqtt_issueGroupCommands}}, {{$permission_mqtt_subscribeReadOwnGroup}}, {{$permission_mqtt_representDevices}}, - {{$permission_mqtt_readAllBirthMessages}}, - {{$permission_mqtt_writeToUNSNamespace}}, - {{$permission_mqtt_subscribeReadWholeUNSNamespace}} + {{$permission_mqtt_readAllBirthMessages}} ], {{$permissionGroup_configStore}}: [ {{$permission_configStore_readConfigForApp}}, @@ -1421,4 +1401,4 @@ data: } } - {{end}}{{/* auth.enabled */}} +{{end}}{{/* auth.enabled */}} From 38c8d39bd7c4855ff43d8465b1cbfbd88e3d52fa Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Fri, 6 Sep 2024 13:16:01 +0100 Subject: [PATCH 35/58] Fix values.yaml indentation after merge --- deploy/values.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/deploy/values.yaml b/deploy/values.yaml index 5f3b537a..89bff6cf 100644 --- a/deploy/values.yaml +++ b/deploy/values.yaml @@ -152,7 +152,8 @@ mqtt: # -- Possible values are either 1 to enable all possible debugging, or a comma-separated list of debug tags (the tags printed before the log lines). No logging is specified as an empty string. verbosity: 0 - ingester: +ingesters: + sparkplug: enabled: true image: # -- The registry of the MQTT component @@ -229,8 +230,8 @@ warehouse: # -- The repository of the Warehouse component repository: influxdb-sparkplug-ingester pullPolicy: IfNotPresent - - injector: +historians: + uns: enabled: true # -- The minimum log level that the injector will log messages at (One of 'fatal', 'error', 'warn', 'info', 'debug', 'trace' or 'silent'.) logLevel: info From 183a7bdc92ab1cab0cd92fb3dfc362445e6096c7 Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Fri, 6 Sep 2024 14:07:19 +0100 Subject: [PATCH 36/58] Refactor codebase to introduce historian-uns --- .github/workflows/publish.yml | 1 + acs-service-setup/dumps/uns.yaml | 12 +++-- acs-service-setup/lib/uuids.js | 1 + .../auth/principals/service-clients.yaml | 44 +++++++++++------- .../uns-injector.yaml => historians/uns.yaml} | 45 +++++++++---------- .../ingester/sparkplug-ingester.yaml | 0 deploy/values.yaml | 8 ++-- .../.env.example | 0 .../.gitignore | 0 .../Dockerfile | 0 {influxdb-injector => historian-uns}/LICENSE | 0 historian-uns/README.md | 8 ++++ .../SECURITY.md | 0 .../package-lock.json | 4 +- .../package.json | 6 +-- historian-uns/run-dev.sh | 9 ++++ .../src/Types/index.d.ts | 0 .../src/Utils/UnsTopic.ts | 0 .../src/Utils/logger.ts | 0 .../src/app.ts | 2 +- .../src/mqttclient.ts | 2 +- .../tsconfig.json | 0 influxdb-injector/Makefile | 7 --- influxdb-injector/README.md | 5 --- influxdb-injector/run-dev.sh | 9 ---- 25 files changed, 88 insertions(+), 75 deletions(-) rename deploy/templates/{warehouse/uns-injector.yaml => historians/uns.yaml} (57%) delete mode 100644 deploy/templates/ingester/sparkplug-ingester.yaml rename {influxdb-injector => historian-uns}/.env.example (100%) rename {influxdb-injector => historian-uns}/.gitignore (100%) rename {influxdb-injector => historian-uns}/Dockerfile (100%) rename {influxdb-injector => historian-uns}/LICENSE (100%) create mode 100644 historian-uns/README.md rename {influxdb-injector => historian-uns}/SECURITY.md (100%) rename {influxdb-injector => historian-uns}/package-lock.json (99%) rename {influxdb-injector => historian-uns}/package.json (91%) create mode 100644 historian-uns/run-dev.sh rename {influxdb-injector => historian-uns}/src/Types/index.d.ts (100%) rename {influxdb-injector => historian-uns}/src/Utils/UnsTopic.ts (100%) rename {influxdb-injector => historian-uns}/src/Utils/logger.ts (100%) rename {influxdb-injector => historian-uns}/src/app.ts (97%) rename {influxdb-injector => historian-uns}/src/mqttclient.ts (99%) rename {influxdb-injector => historian-uns}/tsconfig.json (100%) delete mode 100644 influxdb-injector/Makefile delete mode 100644 influxdb-injector/README.md delete mode 100644 influxdb-injector/run-dev.sh diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 09cd791f..7813775c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -166,6 +166,7 @@ jobs: - acs-visualiser - edge-helm-charts - influxdb-sparkplug-ingester + - historian-uns permissions: contents: read packages: write diff --git a/acs-service-setup/dumps/uns.yaml b/acs-service-setup/dumps/uns.yaml index 7d0d18b7..5ef0dad1 100644 --- a/acs-service-setup/dumps/uns.yaml +++ b/acs-service-setup/dumps/uns.yaml @@ -12,23 +12,24 @@ objects: - !u ACS.Perm.MQTT.ReadEntireUNS !u ACS.Class.ServiceAccount: - !u ACS.ServiceAccount.SparkplugIngester + - !u ACS.ServiceAccount.HistorianUNS configs: !u UUIDs.App.Info: !u ACS.Perm.MQTT.WriteToEntireUNS: { name: "MQTT: Write to entire UNS" } !u ACS.Perm.MQTT.ReadEntireUNS: { name: "MQTT: Read entire UNS" } - !u ACS.ServiceAccount.SparkplugIngester: { name: "Sparkplug Ingester" } + !u ACS.ServiceAccount.SparkplugIngester: { name: "Ingester (Sparkplug)" } + !u ACS.ServiceAccount.HistorianUNS: { name: "Historian (UNS)" } !u UUIDs.App.MQTTPermissionTemplate: !u ACS.Perm.MQTT.WriteToEntireUNS: "UNS/v1/#: w" !u ACS.Perm.MQTT.ReadEntireUNS: "UNS/v1/#: rs" --- service: !u UUIDs.Service.Authentication version: 1 -groups: - !u ACS.Role.Warehouse: - - !u ACS.Perm.MQTT.ReadEntireUNS principals: - uuid: !u ACS.ServiceAccount.SparkplugIngester kerberos: sv1sparkplugingester@{{realm}} + - uuid: !u ACS.ServiceAccount.HistorianUNS + kerberos: sv1historianuns@{{realm}} aces: - principal: !u ACS.ServiceAccount.SparkplugIngester permission: !u ACS.Perm.MQTT.WriteToEntireUNS @@ -36,3 +37,6 @@ aces: - principal: !u ACS.ServiceAccount.SparkplugIngester permission: !u ACS.Perm.MQTT.ReadWholeNamespace target: !u UUIDs.Special.Null + - principal: !u ACS.ServiceAccount.HistorianUNS + permission: !u ACS.Perm.MQTT.ReadEntireUNS + target: !u UUIDs.Special.Null diff --git a/acs-service-setup/lib/uuids.js b/acs-service-setup/lib/uuids.js index 9cec66c6..a2e51168 100644 --- a/acs-service-setup/lib/uuids.js +++ b/acs-service-setup/lib/uuids.js @@ -57,6 +57,7 @@ export const ACS = { }, ServiceAccount: { SparkplugIngester: "e5939141-a3d5-4ab8-b609-b450ca785d7c", + HistorianUNS: "b6d0cb6a-708b-424f-a062-8c30e4b2fc4c", }, Role: { EdgeNodeConsumer: "17a64293-b82d-4db4-af4d-63359bb62934", diff --git a/deploy/templates/auth/principals/service-clients.yaml b/deploy/templates/auth/principals/service-clients.yaml index ad4f2ff1..7c0a4df5 100644 --- a/deploy/templates/auth/principals/service-clients.yaml +++ b/deploy/templates/auth/principals/service-clients.yaml @@ -1,18 +1,18 @@ ## Service client principals. - ## - ## These are the principals that services use when they are acting as a client of another - ## service. These are the principals that should be granted rights. - ## - ## Random type principals get a random key and a Kerberos keytab. They are the most - ## secure option but can only be used for services that can act as a Kerberos client. - ## - ## Password type principals get a random password generated by the system. This is next - ## most secure. - ## - ## PresetPassword type principals use a password set by the administrator in the - ## krb5-presets secret. This option should only be used for services that can't pull - ## their password from a k8s secret, like Canary. - # +## +## These are the principals that services use when they are acting as a client of another +## service. These are the principals that should be granted rights. +## +## Random type principals get a random key and a Kerberos keytab. They are the most +## secure option but can only be used for services that can act as a Kerberos client. +## +## Password type principals get a random password generated by the system. This is next +## most secure. +## +## PresetPassword type principals use a password set by the administrator in the +## krb5-presets secret. This option should only be used for services that can't pull +## their password from a k8s secret, like Canary. +# {{- if .Values.auth.enabled }} apiVersion: factoryplus.app.amrc.co.uk/v1 kind: KerberosKey @@ -123,7 +123,7 @@ spec: node: Monitor {{- end }} --- -{{- if .Values.acs.unsMode }} +{{- if .Values.unsIngesters.sparkplug.enabled }} apiVersion: factoryplus.app.amrc.co.uk/v1 kind: KerberosKey metadata: @@ -134,3 +134,17 @@ spec: principal: sv1sparkplugingester@{{ .Values.identity.realm | required "values.identity.realm is required!" }} secret: sparkplugingester-keytabs/client {{- end }} +--- +# In the future if we have any more ingesters then this should be +# enabled if any of the ingesters are enabled. +{{- if .Values.unsIngesters.sparkplug.enabled }} +apiVersion: factoryplus.app.amrc.co.uk/v1 +kind: KerberosKey +metadata: + name: sv1historianuns + namespace: {{ .Release.Namespace }} +spec: + type: Random + principal: sv1historianuns@{{ .Values.identity.realm | required "values.identity.realm is required!" }} + secret: historian-uns-keytabs/client +{{- end }} diff --git a/deploy/templates/warehouse/uns-injector.yaml b/deploy/templates/historians/uns.yaml similarity index 57% rename from deploy/templates/warehouse/uns-injector.yaml rename to deploy/templates/historians/uns.yaml index 29ea6c93..5c9c2bcc 100644 --- a/deploy/templates/warehouse/uns-injector.yaml +++ b/deploy/templates/historians/uns.yaml @@ -1,40 +1,39 @@ -{ { if and (eq .Values.acs.unsMode.enabled) (eq .Values.warehouse.injector true) } } +# In the future if we have any more ingesters then this should be +# enabled if any of the ingesters are enabled. +{{- if .Values.unsIngesters.sparkplug.enabled }} apiVersion: apps/v1 kind: Deployment metadata: - name: influxdb-injector - namespace: { { .Release.Namespace } } + name: historian-uns + namespace: {{ .Release.Namespace }} labels: - component: influxdb-injector + component: historian-uns spec: replicas: 1 selector: matchLabels: - component: influxdb-injector + component: historian-uns template: metadata: labels: - component: influxdb-injector - factory-plus.service: influxdb-injector + component: historian-uns + factory-plus.service: historian-uns spec: - { { - with .Values.acs.imagePullSecrets } } + {{- with .Values.acs.imagePullSecrets }} imagePullSecrets: - { { - toYaml . | nindent 8 } } - { { - end } } + {{- toYaml . | nindent 8 }} + {{- end }} volumes: - name: krb5-conf configMap: name: krb5-conf - - name: krb5-keytabs + - name: keytabs secret: - secretName: krb5-keytabs - items: - - key: sv1warehouse - path: client + secretName: historian-uns-keytabs containers: - - name: influxdb-ingester - image: "{{ include "amrc-connectivity-stack.image-name" (list . .Values.warehouse.injector) }}" + - name: historian-uns + image: "{{ include "amrc-connectivity-stack.image-name" (list . .Values.historians.uns) }}" command: [ "/usr/bin/k5start", "-Uf", "/keytabs/client" ] args: [ "node", "--es-module-specifier-resolution=node", "bin/injector.js" ] imagePullPolicy: Always @@ -44,11 +43,11 @@ spec: - name: CLIENT_KEYTAB value: /keytabs/client - name: LOG_LEVEL - value: { { .Values.warehouse.injector.logLevel | required "values.warehouse.injector.logLevel" } } + value: {{ .Values.historians.uns.logLevel | required "values.historians.uns.logLevel" }} - name: BATCH_SIZE - value: { { .Values.warehouse.injector.batchSize | quote | required "values.warehouse.injector.batchSize" } } + value: {{ .Values.historians.uns.batchSize | quote | required "values.historians.uns.batchSize" }} - name: FLUSH_INTERVAL - value: { { .Values.warehouse.injector.flushInterval | quote | required "values.warehouse.injector.flushInterval" } } + value: {{ .Values.historians.uns.flushInterval | quote | required "values.historians.uns.flushInterval" }} - name: DIRECTORY_URL value: http://directory.{{ .Release.Namespace }}.svc.cluster.local - name: INFLUX_URL @@ -56,7 +55,7 @@ spec: - name: INFLUX_ORG value: default - name: INFLUX_BUCKET - value: 'default' + value: 'uns' - name: INFLUX_TOKEN valueFrom: secretKeyRef: @@ -66,5 +65,5 @@ spec: - mountPath: /config/krb5-conf name: krb5-conf - mountPath: /keytabs - name: krb5-keytabs - { { - end - } } + name: keytabs +{{- end -}} diff --git a/deploy/templates/ingester/sparkplug-ingester.yaml b/deploy/templates/ingester/sparkplug-ingester.yaml deleted file mode 100644 index e69de29b..00000000 diff --git a/deploy/values.yaml b/deploy/values.yaml index 89bff6cf..2ef8f7aa 100644 --- a/deploy/values.yaml +++ b/deploy/values.yaml @@ -13,8 +13,6 @@ acs: email: '' # -- Whether or not to use the staging environment for Let's Encrypt staging: false - # -- Whether the metrics from the sparkplug namespace will be republished to the UNS namespace - unsMode: true # -- The name of the secret holding the wildcard certificate for the # above domain. It will be used for every service unless that service # specifies its own tlsSecretName. @@ -152,7 +150,7 @@ mqtt: # -- Possible values are either 1 to enable all possible debugging, or a comma-separated list of debug tags (the tags printed before the log lines). No logging is specified as an empty string. verbosity: 0 -ingesters: +unsIngesters: sparkplug: enabled: true image: @@ -242,8 +240,8 @@ historians: image: # -- The registry of the Warehouse component registry: ghcr.io/amrc-factoryplus - # -- The repository of the Warehouse component - repository: influxdb-injector + # -- The repository of the UNS Historian component + repository: historian-uns pullPolicy: IfNotPresent git: # -- Whether or not to enable the Git component diff --git a/influxdb-injector/.env.example b/historian-uns/.env.example similarity index 100% rename from influxdb-injector/.env.example rename to historian-uns/.env.example diff --git a/influxdb-injector/.gitignore b/historian-uns/.gitignore similarity index 100% rename from influxdb-injector/.gitignore rename to historian-uns/.gitignore diff --git a/influxdb-injector/Dockerfile b/historian-uns/Dockerfile similarity index 100% rename from influxdb-injector/Dockerfile rename to historian-uns/Dockerfile diff --git a/influxdb-injector/LICENSE b/historian-uns/LICENSE similarity index 100% rename from influxdb-injector/LICENSE rename to historian-uns/LICENSE diff --git a/historian-uns/README.md b/historian-uns/README.md new file mode 100644 index 00000000..a75cdf9d --- /dev/null +++ b/historian-uns/README.md @@ -0,0 +1,8 @@ +# UNS Historian + +This component persists a copy of all data sent to the UNS (UNS/v1/#) +topics. + +See the [ACS Helm +chart](https://github.com/AMRC-FactoryPlus/amrc-connectivity-stack) for +information on how to deploy this component. diff --git a/influxdb-injector/SECURITY.md b/historian-uns/SECURITY.md similarity index 100% rename from influxdb-injector/SECURITY.md rename to historian-uns/SECURITY.md diff --git a/influxdb-injector/package-lock.json b/historian-uns/package-lock.json similarity index 99% rename from influxdb-injector/package-lock.json rename to historian-uns/package-lock.json index 9bfc0058..8dff9d63 100644 --- a/influxdb-injector/package-lock.json +++ b/historian-uns/package-lock.json @@ -1,11 +1,11 @@ { - "name": "influxdb-sparkplug-ingester", + "name": "historian-uns", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "influxdb-sparkplug-ingester", + "name": "historian-uns", "version": "1.0.0", "license": "MIT", "dependencies": { diff --git a/influxdb-injector/package.json b/historian-uns/package.json similarity index 91% rename from influxdb-injector/package.json rename to historian-uns/package.json index 73373a78..7b9123cc 100644 --- a/influxdb-injector/package.json +++ b/historian-uns/package.json @@ -1,7 +1,7 @@ { - "name": "influxdb-sparkplug-ingester", + "name": "historian-uns", "version": "1.0.0", - "description": "An ingestion engine to enable InfluxDB to be a fully-featured Sparkplug historian", + "description": "An ingestion engine to enable InfluxDB to be a fully-featured UNS historian", "author": "AMRC", "license": "MIT", "main": "./src/app.js", @@ -13,7 +13,7 @@ "acs", "amrc-connectivity-stack", "mqtt", - "sparkplug" + "uns" ], "scripts": { "start": "node dist/app.js", diff --git a/historian-uns/run-dev.sh b/historian-uns/run-dev.sh new file mode 100644 index 00000000..cdede838 --- /dev/null +++ b/historian-uns/run-dev.sh @@ -0,0 +1,9 @@ +# +# AMRC InfluxDB UNS Historian +# Copyright "2023" AMRC +# + +# bin/bash +tmpfile=$(mktemp) +export CLIENT_KEYTAB="$(kubectl --kubeconfig get -n factory-plus secret krb5-keytabs -o jsonpath="{.data.sv1historianuns}" | base64 -d >"$tmpfile" && echo "$tmpfile")" +npm run start:shell diff --git a/influxdb-injector/src/Types/index.d.ts b/historian-uns/src/Types/index.d.ts similarity index 100% rename from influxdb-injector/src/Types/index.d.ts rename to historian-uns/src/Types/index.d.ts diff --git a/influxdb-injector/src/Utils/UnsTopic.ts b/historian-uns/src/Utils/UnsTopic.ts similarity index 100% rename from influxdb-injector/src/Utils/UnsTopic.ts rename to historian-uns/src/Utils/UnsTopic.ts diff --git a/influxdb-injector/src/Utils/logger.ts b/historian-uns/src/Utils/logger.ts similarity index 100% rename from influxdb-injector/src/Utils/logger.ts rename to historian-uns/src/Utils/logger.ts diff --git a/influxdb-injector/src/app.ts b/historian-uns/src/app.ts similarity index 97% rename from influxdb-injector/src/app.ts rename to historian-uns/src/app.ts index 6afa059e..edcb6cc4 100644 --- a/influxdb-injector/src/app.ts +++ b/historian-uns/src/app.ts @@ -1,5 +1,5 @@ /* - * AMRC InfluxDB Sparkplug Ingester + * AMRC InfluxDB UNS Historian * Copyright "2023" AMRC */ import {ServiceClient, UUIDs} from "@amrc-factoryplus/service-client"; diff --git a/influxdb-injector/src/mqttclient.ts b/historian-uns/src/mqttclient.ts similarity index 99% rename from influxdb-injector/src/mqttclient.ts rename to historian-uns/src/mqttclient.ts index 910adb2f..6222b4bc 100644 --- a/influxdb-injector/src/mqttclient.ts +++ b/historian-uns/src/mqttclient.ts @@ -1,5 +1,5 @@ /* - * AMRC InfluxDB Sparkplug Ingester + * AMRC InfluxDB UNS Historian * Copyright "2024" AMRC */ import {ServiceClient} from "@amrc-factoryplus/service-client"; diff --git a/influxdb-injector/tsconfig.json b/historian-uns/tsconfig.json similarity index 100% rename from influxdb-injector/tsconfig.json rename to historian-uns/tsconfig.json diff --git a/influxdb-injector/Makefile b/influxdb-injector/Makefile deleted file mode 100644 index bf4d70ab..00000000 --- a/influxdb-injector/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -top=.. -include ${top}/mk/acs.init.mk - -repo?=influxdb-sparkplug-ingester -k8s.deployment?=influxdb-ingester - -include ${mk}/acs.js.mk diff --git a/influxdb-injector/README.md b/influxdb-injector/README.md deleted file mode 100644 index 5d24db65..00000000 --- a/influxdb-injector/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# InfluxDB Sparkplug Ingester - -A component that allows InfluxDB to function as a comprehensive Sparkplug-based data historian. It was developed for the [AMRC Connectiviy Stack](https://github.com/AMRC-FactoryPlus/amrc-connectivity-stack), the AMRC's open-source implementation of the Factory+ framework. - -See the [ACS Helm chart](https://github.com/AMRC-FactoryPlus/amrc-connectivity-stack) for information on how to deploy this component. diff --git a/influxdb-injector/run-dev.sh b/influxdb-injector/run-dev.sh deleted file mode 100644 index 900f6b30..00000000 --- a/influxdb-injector/run-dev.sh +++ /dev/null @@ -1,9 +0,0 @@ -# -# AMRC InfluxDB Sparkplug Ingester -# Copyright "2023" AMRC -# - -# bin/bash -tmpfile=$(mktemp) -export CLIENT_KEYTAB="$(kubectl --kubeconfig get -n factory-plus secret krb5-keytabs -o jsonpath="{.data.sv1warehouse}" | base64 -d >"$tmpfile" && echo "$tmpfile")" -npm run start:shell \ No newline at end of file From fda7b66f44ce4fa13fb42bde3e01c86644d4d03d Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Fri, 6 Sep 2024 14:10:54 +0100 Subject: [PATCH 37/58] Refactor codebase to introduce historian-sparkplug --- .github/workflows/publish.yml | 2 +- .../auth/principals/service-clients.yaml | 2 +- .../templates/auth/principals/services.yaml | 13 - .../sparkplug.yaml} | 22 +- .../{warehouse => influxdb}/influx-auth.yaml | 0 .../influx-ingress.yaml | 2 +- deploy/values.yaml | 20 +- historian-sparkplug/.gitignore | 17 + historian-sparkplug/Dockerfile | 67 + historian-sparkplug/LICENSE | 21 + historian-sparkplug/Makefile | 7 + historian-sparkplug/README.md | 5 + historian-sparkplug/SECURITY.md | 15 + historian-sparkplug/bin/ingester.js | 28 + historian-sparkplug/bin/ingester.ts | 52 + historian-sparkplug/lib/mqttclient.js | 182 + historian-sparkplug/lib/mqttclient.ts | 533 +++ historian-sparkplug/package-lock.json | 3791 +++++++++++++++++ historian-sparkplug/package.json | 41 + historian-sparkplug/run-dev.sh | 10 + historian-sparkplug/tsconfig.json | 32 + 21 files changed, 4824 insertions(+), 38 deletions(-) rename deploy/templates/{warehouse/influxdb-ingester.yaml => historians/sparkplug.yaml} (72%) rename deploy/templates/{warehouse => influxdb}/influx-auth.yaml (100%) rename deploy/templates/{warehouse => influxdb}/influx-ingress.yaml (86%) create mode 100644 historian-sparkplug/.gitignore create mode 100644 historian-sparkplug/Dockerfile create mode 100644 historian-sparkplug/LICENSE create mode 100644 historian-sparkplug/Makefile create mode 100644 historian-sparkplug/README.md create mode 100644 historian-sparkplug/SECURITY.md create mode 100644 historian-sparkplug/bin/ingester.js create mode 100644 historian-sparkplug/bin/ingester.ts create mode 100644 historian-sparkplug/lib/mqttclient.js create mode 100644 historian-sparkplug/lib/mqttclient.ts create mode 100644 historian-sparkplug/package-lock.json create mode 100644 historian-sparkplug/package.json create mode 100755 historian-sparkplug/run-dev.sh create mode 100644 historian-sparkplug/tsconfig.json diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7813775c..3c2af4d3 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -165,7 +165,7 @@ jobs: - acs-service-setup - acs-visualiser - edge-helm-charts - - influxdb-sparkplug-ingester + - historian-sparkplug - historian-uns permissions: contents: read diff --git a/deploy/templates/auth/principals/service-clients.yaml b/deploy/templates/auth/principals/service-clients.yaml index 7c0a4df5..6df38568 100644 --- a/deploy/templates/auth/principals/service-clients.yaml +++ b/deploy/templates/auth/principals/service-clients.yaml @@ -80,7 +80,7 @@ spec: secret: manager-keytab/client-keytab {{- end }} --- -{{- if .Values.warehouse.ingester.enabled }} +{{- if .Values.historians.sparkplug.enabled }} apiVersion: factoryplus.app.amrc.co.uk/v1 kind: KerberosKey metadata: diff --git a/deploy/templates/auth/principals/services.yaml b/deploy/templates/auth/principals/services.yaml index 09b1dc09..20d65579 100644 --- a/deploy/templates/auth/principals/services.yaml +++ b/deploy/templates/auth/principals/services.yaml @@ -100,19 +100,6 @@ spec: principal: postgres/postgres.{{ .Release.Namespace }}.svc.cluster.local@{{ .Values.identity.realm | required "values.identity.realm is required!" }} {{- end }} --- -{{- if .Values.warehouse.enabled }} -apiVersion: factoryplus.app.amrc.co.uk/v1 -kind: KerberosKey -metadata: - name: http.warehouse - namespace: {{ .Release.Namespace }} -spec: - type: Random - principal: HTTP/warehouse.{{ .Release.Namespace }}.svc.cluster.local@{{ .Values.identity.realm | required "values.identity.realm is required!" }} - additionalPrincipals: - - HTTP/warehouse.{{.Values.acs.baseUrl | required "values.acs.baseUrl is required"}}@{{ .Values.identity.realm | required "values.identity.realm is required!" }} -{{- end }} ---- {{- if .Values.git.enabled }} apiVersion: factoryplus.app.amrc.co.uk/v1 kind: KerberosKey diff --git a/deploy/templates/warehouse/influxdb-ingester.yaml b/deploy/templates/historians/sparkplug.yaml similarity index 72% rename from deploy/templates/warehouse/influxdb-ingester.yaml rename to deploy/templates/historians/sparkplug.yaml index 60e7365f..01176b31 100644 --- a/deploy/templates/warehouse/influxdb-ingester.yaml +++ b/deploy/templates/historians/sparkplug.yaml @@ -1,21 +1,21 @@ -{{ if .Values.warehouse.ingester.enabled }} +{{ if .Values.historians.sparkplug.enabled }} apiVersion: apps/v1 kind: Deployment metadata: - name: influxdb-ingester + name: historian-sparkplug namespace: {{ .Release.Namespace }} labels: - component: influxdb-ingester + component: historian-sparkplug spec: replicas: 1 selector: matchLabels: - component: influxdb-ingester + component: historian-sparkplug template: metadata: labels: - component: influxdb-ingester - factory-plus.service: influxdb-ingester + component: historian-sparkplug + factory-plus.service: historian-sparkplug spec: {{- with .Values.acs.imagePullSecrets }} imagePullSecrets: @@ -33,8 +33,8 @@ spec: path: client containers: - - name: influxdb-ingester - image: "{{ include "amrc-connectivity-stack.image-name" (list . .Values.warehouse.ingester) }}" + - name: historian-sparkplug + image: "{{ include "amrc-connectivity-stack.image-name" (list . .Values.historians.sparkplug) }}" command: [ "/usr/bin/k5start", "-Uf", "/keytabs/client" ] args: [ "node", "--es-module-specifier-resolution=node", "bin/ingester.js" ] imagePullPolicy: Always @@ -44,11 +44,11 @@ spec: - name: CLIENT_KEYTAB value: /keytabs/client - name: LOG_LEVEL - value: {{ .Values.warehouse.ingester.logLevel | required "values.warehouse.ingester.logLevel" }} + value: {{ .Values.historians.sparkplug.logLevel | required "values.historians.sparkplug.logLevel" }} - name: BATCH_SIZE - value: {{ .Values.warehouse.ingester.batchSize | quote | required "values.warehouse.ingester.batchSize" }} + value: {{ .Values.historians.sparkplug.batchSize | quote | required "values.historians.sparkplug.batchSize" }} - name: FLUSH_INTERVAL - value: {{ .Values.warehouse.ingester.flushInterval | quote | required "values.warehouse.ingester.flushInterval" }} + value: {{ .Values.historians.sparkplug.flushInterval | quote | required "values.historians.sparkplug.flushInterval" }} - name: DIRECTORY_URL value: http://directory.{{ .Release.Namespace }}.svc.cluster.local - name: INFLUX_URL diff --git a/deploy/templates/warehouse/influx-auth.yaml b/deploy/templates/influxdb/influx-auth.yaml similarity index 100% rename from deploy/templates/warehouse/influx-auth.yaml rename to deploy/templates/influxdb/influx-auth.yaml diff --git a/deploy/templates/warehouse/influx-ingress.yaml b/deploy/templates/influxdb/influx-ingress.yaml similarity index 86% rename from deploy/templates/warehouse/influx-ingress.yaml rename to deploy/templates/influxdb/influx-ingress.yaml index 84f51d49..0d47dffc 100644 --- a/deploy/templates/warehouse/influx-ingress.yaml +++ b/deploy/templates/influxdb/influx-ingress.yaml @@ -18,6 +18,6 @@ spec: tls: secretName: {{ coalesce .Values.influxdb2.tlsSecretName .Values.acs.tlsSecretName }} domains: - - main: influxdb-ingester.{{.Values.acs.baseUrl | required "values.acs.baseUrl is required"}} + - main: influxdb.{{.Values.acs.baseUrl | required "values.acs.baseUrl is required"}} {{- end -}} {{- end -}} diff --git a/deploy/values.yaml b/deploy/values.yaml index 2ef8f7aa..3a2d97f7 100644 --- a/deploy/values.yaml +++ b/deploy/values.yaml @@ -212,11 +212,10 @@ cmdesc: # -- Possible values are either 1 to enable all possible debugging, or a comma-separated list of debug tags (the tags printed before the log lines). No logging is specified as an empty string. verbosity: 1 -warehouse: - # -- Whether or not to enable the Warehouse component - ingester: +historians: + uns: enabled: true - # -- The minimum log level that the ingester will log messages at (One of 'fatal', 'error', 'warn', 'info', 'debug', 'trace' or 'silent'.) + # -- The minimum log level that the historian will log messages at (One of 'fatal', 'error', 'warn', 'info', 'debug', 'trace' or 'silent'.) logLevel: info # -- The number of messages to batch together before sending to InfluxDB batchSize: 5000 @@ -225,13 +224,12 @@ warehouse: image: # -- The registry of the Warehouse component registry: ghcr.io/amrc-factoryplus - # -- The repository of the Warehouse component - repository: influxdb-sparkplug-ingester + # -- The repository of the UNS Historian component + repository: historian-uns pullPolicy: IfNotPresent -historians: - uns: + sparkplug: enabled: true - # -- The minimum log level that the injector will log messages at (One of 'fatal', 'error', 'warn', 'info', 'debug', 'trace' or 'silent'.) + # -- The minimum log level that the historian will log messages at (One of 'fatal', 'error', 'warn', 'info', 'debug', 'trace' or 'silent'.) logLevel: info # -- The number of messages to batch together before sending to InfluxDB batchSize: 5000 @@ -240,8 +238,8 @@ historians: image: # -- The registry of the Warehouse component registry: ghcr.io/amrc-factoryplus - # -- The repository of the UNS Historian component - repository: historian-uns + # -- The repository of the Warehouse component + repository: historian-sparkplug pullPolicy: IfNotPresent git: # -- Whether or not to enable the Git component diff --git a/historian-sparkplug/.gitignore b/historian-sparkplug/.gitignore new file mode 100644 index 00000000..eed26523 --- /dev/null +++ b/historian-sparkplug/.gitignore @@ -0,0 +1,17 @@ +/node_modules/ + +# Vim swap +*.swp + +# Environment +.env +dist/ + +dist/ + +# Secrets +/keytabs/ +/volumes/ + +# IDE +.idea/ diff --git a/historian-sparkplug/Dockerfile b/historian-sparkplug/Dockerfile new file mode 100644 index 00000000..2ff683bf --- /dev/null +++ b/historian-sparkplug/Dockerfile @@ -0,0 +1,67 @@ +# syntax=docker/dockerfile:1 +# The line above must be the first line in the file! + +ARG base_version +ARG base_prefix=ghcr.io/amrc-factoryplus/acs-base + +ARG acs_build=${base_prefix}-js-build:${base_version} +ARG acs_run=${base_prefix}-js-run:${base_version} + +FROM ${acs_build} as ts-compiler +# This ARG must go here, in the image that uses it, or it isn't +# available to the shell scripts. Don't ask me why... +ARG acs_npm=NO +ARG revision=unknown + +USER root +RUN <<'SHELL' + install -d -o node /home/node /usr/app +SHELL +USER node +WORKDIR /usr/app +COPY --chown=node . ./ +RUN <<'SHELL' + touch /home/node/.npmrc + if [ "${acs_npm}" != NO ] + then + echo "SETTING NPM REGISTRY TO ${acs_npm}" >&2 + npm config set @amrc-factoryplus:registry "${acs_npm}" + fi + npm install --save=false + + echo "export const GIT_VERSION=\"$revision\";" > ./lib/git-version.js + + npm run clean + echo tsc -v + npm run build +SHELL + +FROM ${acs_build} as util-build +USER root +RUN <<'SHELL' + # Are these necessary? + apk upgrade --update-cache --available + apk add openssl + rm -rf /var/cache/apk/* + install -d -o node /home/node /usr/app +SHELL +USER node +WORKDIR /usr/app +COPY --chown=node --from=ts-compiler /usr/app/package*.json ./ +COPY --chown=node --from=ts-compiler /usr/app/dist ./ +COPY --chown=node --from=ts-compiler /home/node/.npmrc /home/node +RUN npm install --save=false --only=production + +FROM ${acs_run} +USER root +RUN <<'SHELL' + apk upgrade --update-cache --available + apk add openssl + rm -rf /var/cache/apk/* +SHELL +WORKDIR /usr/app +# This copy leaves the app files owned as root, i.e. read-only to the +# running application. This is a Good Thing. +COPY --from=util-build /usr/app ./ +USER node +CMD [ "node", "--es-module-specifier-resolution=node", "bin/ingester.js" ] diff --git a/historian-sparkplug/LICENSE b/historian-sparkplug/LICENSE new file mode 100644 index 00000000..cdb7bae2 --- /dev/null +++ b/historian-sparkplug/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 AMRC-FactoryPlus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/historian-sparkplug/Makefile b/historian-sparkplug/Makefile new file mode 100644 index 00000000..28ab401e --- /dev/null +++ b/historian-sparkplug/Makefile @@ -0,0 +1,7 @@ +top=.. +include ${top}/mk/acs.init.mk + +repo?=historian-sparkplug +k8s.deployment?=historian-sparkplug + +include ${mk}/acs.js.mk diff --git a/historian-sparkplug/README.md b/historian-sparkplug/README.md new file mode 100644 index 00000000..48e92298 --- /dev/null +++ b/historian-sparkplug/README.md @@ -0,0 +1,5 @@ +# InfluxDB Sparkplug Historian + +A component that allows InfluxDB to function as a comprehensive Sparkplug-based data historian. It was developed for the [AMRC Connectiviy Stack](https://github.com/AMRC-FactoryPlus/amrc-connectivity-stack), the AMRC's open-source implementation of the Factory+ framework. + +See the [ACS Helm chart](https://github.com/AMRC-FactoryPlus/amrc-connectivity-stack) for information on how to deploy this component. diff --git a/historian-sparkplug/SECURITY.md b/historian-sparkplug/SECURITY.md new file mode 100644 index 00000000..91a8ba7e --- /dev/null +++ b/historian-sparkplug/SECURITY.md @@ -0,0 +1,15 @@ +## Reporting a Vulnerability + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please register a new advisory from the Security tab in Github. + +Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: + +- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) +- Full paths of source file(s) related to the manifestation of the issue +- The location of the affected source code (tag/branch/commit or direct URL) +- Any special configuration required to reproduce the issue +- Step-by-step instructions to reproduce the issue +- Proof-of-concept or exploit code (if possible) +- Impact of the issue, including how an attacker might exploit the issue diff --git a/historian-sparkplug/bin/ingester.js b/historian-sparkplug/bin/ingester.js new file mode 100644 index 00000000..7ae99c60 --- /dev/null +++ b/historian-sparkplug/bin/ingester.js @@ -0,0 +1,28 @@ +import { Debug, ServiceClient } from "@amrc-factoryplus/utilities"; +import MQTTClient from "../lib/mqttclient"; +const deviceUUID = process.env.DEVICE_UUID; +const MQTTURL = process.env.MQTT_URL; +const sparkplugAddress = process.env.SPARKPLUG_ADDRESS; +if (!deviceUUID) { + throw new Error("Device UUID not set"); +} +if (!MQTTURL) { + throw new Error("MQTT URL not set"); +} +if (!sparkplugAddress) { + throw new Error("Sparkplug Address not set"); +} +const debug = new Debug(); +const client = await new ServiceClient({ + directory_url: process.env.DIRECTORY_URL, + root_principal: process.env.ROOT_PRINCIPAL, +}).init(); +const mqtt = await new MQTTClient({ + e: { + serviceClient: client, + deviceUUID: deviceUUID, + url: MQTTURL, + sparkplugAddress: sparkplugAddress + } +}).init(); +mqtt.run(); diff --git a/historian-sparkplug/bin/ingester.ts b/historian-sparkplug/bin/ingester.ts new file mode 100644 index 00000000..1dbff36c --- /dev/null +++ b/historian-sparkplug/bin/ingester.ts @@ -0,0 +1,52 @@ +/* + * AMRC InfluxDB Sparkplug Historian + * Copyright "2023" AMRC + */ + +import {ServiceClient, UUIDs} from "@amrc-factoryplus/utilities"; +import pino from "pino"; +import pretty from 'pino-pretty'; +import MQTTClient from "@lib/mqttclient.js"; +let dotenv: any = null; +try {dotenv = await import ('dotenv')} catch (e) {} + +const stream = pretty({ + colorize: true +}) + +dotenv?.config(); + +const directoryUrl = process.env.DIRECTORY_URL; +if (!directoryUrl) { + throw new Error("DIRECTORY_URL environment variable is not set"); +} + +export const logger = pino({ + name: 'InfluxDB Sparkplug Historian', + level: process.env.LOG_LEVEL || 'info', +}, stream); + + +const client = await new ServiceClient({ + directory_url: directoryUrl, +}).init(); + +// Overwrite MQTT server if specified in environment +if (process.env.MQTT_URL) { + client.Discovery.set_service_url(UUIDs.Service.MQTT, process.env.MQTT_URL); +} + +// Overwrite Command Escalation server if specified in environment +if (process.env.CMD_ESC_URL) { + client.Discovery.set_service_url(UUIDs.Service.Command_Escalation, process.env.CMD_ESC_URL); +} + +logger.info(client.service_urls('feb27ba3-bd2c-4916-9269-79a61ebc4a47')); + +const mqtt = await new MQTTClient({ + e: { + serviceClient: client, + } +}).init(); + +mqtt.run(); diff --git a/historian-sparkplug/lib/mqttclient.js b/historian-sparkplug/lib/mqttclient.js new file mode 100644 index 00000000..30be1af7 --- /dev/null +++ b/historian-sparkplug/lib/mqttclient.js @@ -0,0 +1,182 @@ +import { Address, Debug, MetricBuilder, SpB, Topic } from "@amrc-factoryplus/utilities"; +const debug = new Debug(); +export default class MQTTClient { + serviceClient; + deviceUUID; + url; + address; + seq; + mqtt; + constructor({ e }) { + this.serviceClient = e.serviceClient; + this.deviceUUID = e.deviceUUID; + this.url = e.url; + this.address = Address.parse(e.sparkplugAddress); + this.seq = 0; + } + async init() { + return this; + } + will() { + const nDeath = { + timestamp: Date.now(), + metrics: MetricBuilder.death.node([]), + }; + // @ts-ignore + const will = SpB.encodePayload(nDeath); + return { + topic: this.address.topic("DEATH"), + payload: will, + qos: 0, + retain: false, + }; + } + async run() { + const mqtt = await this.serviceClient.mqtt_client({ + verbose: true, + // @ts-ignore + will: this.will(), + }); + this.mqtt = mqtt; + mqtt.on("gssconnect", this.on_connect.bind(this)); + mqtt.on("error", this.on_error.bind(this)); + mqtt.on("message", this.on_message.bind(this)); + // We subscribe to the whole Sparkplug namespace + mqtt.subscribe('spBv1.0/#'); + } + // encode_metrics(metrics, with_uuid) { + // const payload = { + // timestamp: Date.now(), + // metrics: metrics, + // seq: this.seq, + // }; + // this.seq = (this.seq < 255) ? (this.seq + 1) : 0; + // if (with_uuid) + // payload.uuid = UUIDs.FactoryPlus; + // + // return SpB.encodePayload(payload); + // } + // publish(kind, metrics, with_uuid) { + // if (!this.mqtt) { + // debug.log("mqtt", "Can't publish without an MQTT connection."); + // return; + // } + // + // const topic = this.address.topic(kind); + // const payload = this.encode_metrics(metrics, with_uuid); + // + // this.mqtt.publish(topic, payload); + // } + on_connect() { + debug.log("mqtt", "Connected to MQTT broker."); + // this.rebirth(); + } + // rebirth() { + // + // this.seq = 0; + // const Birth = MetricBuilder.birth; + // const metrics = Birth.node([]); + // //Birth.command_escalation(metrics); + // metrics.push.apply(metrics, [ + // {name: "Device_Information/Manufacturer", type: "String", value: Device_Info.Manufacturer}, + // {name: "Device_Information/Model", type: "String", value: Device_Info.Model}, + // {name: "Device_Information/Serial", type: "String", value: Device_Info.Serial}, + // + // {name: "Schema_UUID", type: "UUID", value: Schema.Service}, + // {name: "Instance_UUID", type: "UUID", value: this.device_uuid}, + // {name: "Service_UUID", type: "UUID", value: Service.Registry}, + // {name: "Service_URL", type: "String", value: this.url}, + // ]); + // metrics.push.apply(metrics, + // Object.values(Changed).map(v => + // ({name: `Last_Changed/${v}`, type: "UUID", value: ""}))); + // + // debug.log("mqtt", `Publishing birth certificate`); + // this.publish("BIRTH", metrics, true); + // } + // publish_changed(changes) { + // const metrics = []; + // for (let [to, uuid] of Object.entries(changes)) { + // if (!(to in Changed)) + // continue; + // metrics.push({ + // name: `Last_Changed/${Changed[to]}`, + // type: "UUID", + // value: uuid, + // }); + // } + // this.publish("DATA", metrics); + // } + on_error(error) { + debug.log("mqtt", "MQTT error: %o", error); + } + async on_message(topicString, message) { + let topic = Topic.parse(topicString); + if (!topic) { + debug.log("mqtt", `Bad topic: ${topicString}`); + return; + } + let address = topic.address; + let payload; + try { + // @ts-ignore + payload = SpB.decodePayload(message); + } + catch { + debug.log("mqtt", `Bad payload on topic ${topicString}`); + return; + } + switch (topic.type) { + case "BIRTH": + //await this.on_birth(address, payload); + break; + case "DEATH": + //await this.on_death(address, payload); + break; + case "DATA": + await this.on_data(address, payload); + break; + case "CMD": + await this.on_command(address, payload); + break; + default: + debug.log("mqtt", `Unknown Sparkplug message type ${topic.type}!`); + } + } + async on_data(addr, payload) { + if (!payload.metrics) { + debug.log("mqtt", `Received DATA with no metrics!`); + return; + } + // for (let m of payload.metrics) { + // switch (m.name) { + // // case "Node Control/Rebirth": + // // await this.rebirth(); + // // break; + // default: + // debug.log("mqtt", `Received unknown CMD: ${m.name}`); + // /* Ignore for now */ + // } + // } + } + async on_command(addr, payload) { + if (!addr.equals(this.address)) { + //console.log(`Received CMD for ${addr}`); + return; + } + if (!payload.metrics) { + debug.log("mqtt", `Received CMD with no metrics!`); + return; + } + for (let m of payload.metrics) { + switch (m.name) { + // case "Node Control/Rebirth": + // await this.rebirth(); + // break; + default: + debug.log("mqtt", `Received unknown CMD: ${m.name}`); + /* Ignore for now */ + } + } + } +} diff --git a/historian-sparkplug/lib/mqttclient.ts b/historian-sparkplug/lib/mqttclient.ts new file mode 100644 index 00000000..391f8f9c --- /dev/null +++ b/historian-sparkplug/lib/mqttclient.ts @@ -0,0 +1,533 @@ +/* + * AMRC InfluxDB Sparkplug Historian + * Copyright "2024" AMRC + */ + +import {ServiceClient, SpB, Topic, UUIDs} from "@amrc-factoryplus/utilities"; +import {Reader} from "protobufjs"; +import {logger} from "../bin/ingester.js"; +import Long from "long"; +import {InfluxDB, Point} from '@influxdata/influxdb-client' +import {Agent} from 'http' + +let dotenv: any = null; +try { + dotenv = await import ('dotenv') +} catch (e) { +} + +dotenv?.config() + +const influxURL: string = process.env.INFLUX_URL; +if (!influxURL) { + throw new Error("INFLUX_URL environment variable is not set"); +} + +const influxToken: string = process.env.INFLUX_TOKEN +if (!influxToken) { + throw new Error("INFLUX_TOKEN environment variable is not set"); +} + +const influxOrganisation: string = process.env.INFLUX_ORG +if (!influxOrganisation) { + throw new Error("INFLUX_ORG environment variable is not set"); +} + +const batchSize: number = Number.parseInt(process.env.BATCH_SIZE); +if (!batchSize) { + throw new Error("BATCH_SIZE environment variable is not set"); +} + +const flushInterval: number = Number.parseInt(process.env.FLUSH_INTERVAL); +if (!flushInterval) { + throw new Error("FLUSH_INTERVAL environment variable is not set"); +} + +let i = 0; + +// Node.js HTTP client OOTB does not reuse established TCP connections, a custom node HTTP agent +// can be used to reuse them and thus reduce the count of newly established networking sockets +const keepAliveAgent = new Agent({ + keepAlive: true, // reuse existing connections + keepAliveMsecs: 20 * 1000, // 20 seconds keep alive +}) + +const influxDB = new InfluxDB({ + url: influxURL, token: influxToken, transportOptions: { + agent: keepAliveAgent, + } +}) + +let interval: any; + +/* points/lines are batched in order to minimize networking and increase performance */ + +const writeApi = influxDB.getWriteApi(influxOrganisation, process.env.INFLUX_BUCKET || 'default', 'ns', { + /* the maximum points/lines to send in a single batch to InfluxDB server */ + batchSize: batchSize + 1, // don't let automatically flush data + /* maximum time in millis to keep points in an unflushed batch, 0 means don't periodically flush */ + flushInterval: 0, // Never allow the package to flush: we'll flush manually + /* maximum size of the retry buffer - it contains items that could not be sent for the first time */ + maxBufferLines: 30_000, /* the count of internally-scheduled retries upon write failure, the delays between write attempts follow an exponential backoff strategy if there is no Retry-After HTTP header */ + maxRetries: 0, // do not retry writes + // ... there are more write options that can be customized, see + // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeoptions.html and + // https://influxdata.github.io/influxdb-client-js/influxdb-client.writeretryoptions.html +}); + +interface MQTTClientConstructorParams { + e: { + serviceClient: ServiceClient; + } +} + +export default class MQTTClient { + private serviceClient: ServiceClient; + private mqtt: any; + private aliasResolver = {}; + private birthDebounce = {}; + + constructor({e}: MQTTClientConstructorParams) { + this.serviceClient = e.serviceClient; + } + + async init() { + + process.on('exit', () => { + this.flushBuffer('EXIT'); + keepAliveAgent.destroy(); + }) + + return this; + } + + private flushBuffer(source: string) { + let bufferSize = i; + i = 0; + writeApi.flush().then(() => { + logger.info(`🚀 Flushed ${bufferSize} points to InfluxDB [${source}]`); + // Reset the interval + this.resetInterval(); + }) + } + + async run() { + + const mqtt = await this.serviceClient.mqtt_client(); + this.mqtt = mqtt; + + mqtt.on("authenticated", this.on_connect.bind(this)); + mqtt.on("error", this.on_error.bind(this)); + mqtt.on("message", this.on_message.bind(this)); + mqtt.on("close", this.on_close.bind(this)); + mqtt.on("reconnect", this.on_reconnect.bind(this)); + + logger.info("Connecting to Factory+ broker..."); + } + + on_connect() { + logger.info("🔌 Connected to Factory+ broker"); + logger.info("👂 Subscribing to entire Factory+ namespace"); + this.mqtt.subscribe('spBv1.0/#'); + this.resetInterval(); + } + + private resetInterval() { + clearInterval(interval); + interval = setInterval(() => { + this.flushBuffer(`${flushInterval}ms INTERVAL`); + }, flushInterval); + } + + on_close() { + logger.warn(`❌ Disconnected from Factory+ broker`); + + // Flush any remaining data + this.flushBuffer('CONN_CLOSE'); + } + + on_reconnect() { + logger.warn(`⚠️ Reconnecting to Factory+ broker...`); + } + + on_error(error: any) { + logger.error("🚨 MQTT error: %o", error); + // Flush any remaining data + this.flushBuffer('MQTT_ERROR'); + } + + async on_message(topicString: string, message: Uint8Array | Reader) { + let topic = Topic.parse(topicString); + let payload; + + try { + payload = SpB.decodePayload(message); + } catch { + logger.error(`🚨 Bad payload on topic ${topicString}`); + return; + } + + if (!topic) { + logger.error(`🚨 Bad topic: ${topicString}`); + return; + } + + switch (topic.type) { + case "BIRTH": + + // Don't handle Node births + if (!topic.address.isDevice()) return; + + let topLevelSchema = null; + let schemaUUIDMapping = {}; + + let topLevelInstance = null; + let instanceUUIDMapping = {}; + + // If we have a Factory+ payload then process the Schema UUIDs and Instance UUIDs + if (payload.uuid === UUIDs.FactoryPlus) { + + // Schema_UUIDs + payload.metrics.forEach((metric) => { + // If the name ends in Schema_UUID (e.g. Phases/1/Schema_UUID) + if (metric.name.endsWith("Schema_UUID")) { + // Then get the entire string before the /Schema_UUID + let schemaPath = metric.name.split("/").slice(0, -1).join("/"); + + // If the schemaPath is empty then this is the top level Schema_UUID + if (schemaPath === "") { + // So set the topLevelSchema to this value + topLevelSchema = metric.value; + } else { + // Add this mapping to the schemaUUIDMapping array. This means + // that all metrics that contain this schema path in their name + // will have + schemaUUIDMapping[schemaPath] = metric.value; + } + } + }) + + // Instance_UUIDs + payload.metrics.forEach((metric) => { + // If the name ends in Instance_UUID (e.g. Phases/1/Instance_UUID) + if (metric.name.endsWith("Instance_UUID")) { + // Then get the entire string before the /Instance_UUID + let instancePath = metric.name.split("/").slice(0, -1).join("/"); + + // If the instancePath is empty then this is the top level Instance_UUID + if (instancePath === "") { + // So set the topLevelInstance to this value + topLevelInstance = metric.value; + } else { + // Add this mapping to the instanceUUIDMapping array. This means + // that all metrics that contain this instance path in their name + // will have + instanceUUIDMapping[instancePath] = metric.value; + } + } + }) + } + + if (this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { + logger.info(`🔄 Received updated birth certificate for ${topic.address.group}/${topic.address.node}/${topic.address.device} with Instance_UUID ${topLevelInstance} using Schema_UUID ${topLevelSchema}`); + } else { + logger.info(`👶 Received birth certificate for ${topic.address.group}/${topic.address.node}/${topic.address.device} with Instance_UUID ${topLevelInstance} using Schema_UUID ${topLevelSchema}`); + } + + // Store the birth certificate mapping in the alias resolver. This uses the alias as the key and a simplified object containing the name and type as the value. + this.setNestedValue(this.aliasResolver, [topic.address.group, topic.address.node, topic.address.device], payload.metrics.reduce(function (acc, obj) { + let alias = Long.isLong(obj.alias) ? obj.alias.toNumber() : obj.alias; + + // Work out all schemas that are involved in this metric. + // + // e.g. Assume the current metric is CNC/Axes/1/BaseAxis/Position/Actual + // + // The schemaUUIDMapping object will contain the following (non-relevant emitted): + // - Axes/1: e39007e9-1427-4867-9d72-1c00c663db15 + // - Axes/1/BaseAxis: 777dd941-f426-4355-8130-e144530b1376 + // - Axes/1/BaseAxis/Position: 1a2c3594-d311-4f6b-865b-b97db3fa6d42 + + // Schema_UUIDs + + let schemas = []; + // Get all entries in the schemaUUIDMapping object that have keys that fit in the current obj.name + Object.entries(schemaUUIDMapping).forEach(([schemaPath, schemaUUID]) => { + // If the current obj.name contains the schemaPath then add the schemaUUID to the schemas array + if (obj.name.includes(schemaPath)) { + schemas.push(schemaUUID); + } + }); + + // Get the bottom level schema by finding the the entry in the schemaUUIDMapping object that has + // the key with the most slashes that fits in the current obj.name + let bottomLevelSchema = Object.entries(schemaUUIDMapping).reduce((acc, [schemaPath, schemaUUID]) => { + if (obj.name.includes(schemaPath) && schemaPath.split("/").length > acc.split("/").length) { + return schemaUUID; + } else { + return acc; + } + }, ""); + + // Instance_UUIDs + + let instances = []; + // Get all entries in the instanceUUIDMapping object that have keys that fit in the current obj.name + Object.entries(instanceUUIDMapping).forEach(([instancePath, instanceUUID]) => { + // If the current obj.name contains the instancePath then add the instanceUUID to the instances array + if (obj.name.includes(instancePath)) { + instances.push(instanceUUID); + } + }); + + // Get the bottom level instance by finding the the entry in the instanceUUIDMapping object that has + // the key with the most slashes that fits in the current obj.name + let bottomLevelInstance = Object.entries(instanceUUIDMapping).reduce((acc, [instancePath, instanceUUID]) => { + if (obj.name.includes(instancePath) && instancePath.split("/").length > acc.split("/").length) { + return instanceUUID; + } else { + return acc; + } + }, ""); + + acc[alias] = { + instance: { + // The top level instance for this device + top: topLevelInstance, + + // The last instance before this metric + bottom: bottomLevelInstance, + + // All instances between the top and bottom, inclusive + full: instances, + }, + schema: { + // The top level schema for this device + top: topLevelSchema, + + // The last schema before this metric + bottom: bottomLevelSchema, + + // All schemas between the top and bottom, inclusive + full: schemas, + }, + name: obj.name, + type: obj.type, + alias: alias, + unit: obj.properties?.engUnit?.value, + transient: obj.isTransient + }; + return acc; + }, {})); + + // Clear the debounce + delete this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]; + + // Store the default values in InfluxDB + this.writeMetrics(payload, topic); + + break; + case "DEATH": + + // If the death certificate is for a device then remove it from the known devices, otherwise remove the entire node + if (topic.address.isDevice()) { + logger.info(`💀 Received death certificate for ${topic.address.group}/${topic.address.node}/${topic.address.device}. Removing from known devices.`); + delete this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device] + delete this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device] + break; + } else { + logger.info(`💀💀💀 Received death certificate for entire node ${topic.address.group}/${topic.address.node}. Removing from known nodes.`); + delete this.birthDebounce?.[topic.address.group]?.[topic.address.node] + delete this.aliasResolver?.[topic.address.group]?.[topic.address.node] + break; + } + case "DATA": + + // Don't handle Node data + if (!topic.address.isDevice()) return; + + // Check if we have a birth certificate for the device + if (this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { + + // Device is known, resolve aliases and write to InfluxDB + this.writeMetrics(payload, topic); + + } else { + + // Check that we don't already have an active debounce for this device + if (this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]) { + logger.info(`⏳ Device ${topic.address.group}/${topic.address.node}/${topic.address.device} is unknown but has pending birth certificate request. Ignoring.`); + return; + } + + logger.info(`✨ Device ${topic.address.group}/${topic.address.node}/${topic.address.device} is unknown, requesting birth certificate`); + + // Create debounce timout for this device + this.setNestedValue(this.birthDebounce, [topic.address.group, topic.address.node, topic.address.device], true); + setTimeout(() => { + delete this.birthDebounce?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]; + }, Math.floor(Math.random() * (10000 - 5000 + 1) + 5000)); + + // Request birth certificate + let response = await this.serviceClient.fetch({ + service: UUIDs.Service.Command_Escalation, + url: `/v1/address/${topic.address.group}/${topic.address.node}/${topic.address.device}`, + method: "POST", + headers: { + "content-type": "application/json" + }, + body: JSON.stringify({ + "name": "Device Control/Rebirth", "value": "true" + }) + }) + + logger.info('📣 Birth certificate request sent for %s. Status: %s', topic.address, response.status); + + } + break; + } + + return; + } + + private writeMetrics(payload, topic: Topic) { + payload.metrics.forEach((metric) => { + let birth = this.aliasResolver?.[topic.address.group]?.[topic.address.node]?.[topic.address.device]?.[metric.alias]; + + if (!birth) { + logger.error(`Metric ${metric.alias} is unknown for ${topic.address.group}/${topic.address.node}/${topic.address.device}`); + } + + let metricTimestamp: Date + if (metric.timestamp) { + metricTimestamp = new Date(metric.timestamp); + } else if (payload.timestamp) { + // Metrics might not have a timestamp so use the packet timestamp if we have it. + metricTimestamp = new Date(payload.timestamp); + } else { + // No timestamp can be found on the metric or the payload, just use the current time instead. + metricTimestamp = new Date(); + } + // Send each metric to InfluxDB + this.writeToInfluxDB(birth, topic, metric.value, metricTimestamp) + }); + } + + /** + * Writes metric values to InfluxDB using the metric timestamp. + * @param birth Birth certificate for device. + * @param topic Topic the metric was published on. + * @param value Metric value to write to InfluxDB. + * @param timestamp Timestamp from the metric to write to influx. + */ + writeToInfluxDB(birth, topic: Topic, value, timestamp: Date) { + if (value === null) return; + if (birth.transient) { + logger.debug(`Metric ${birth.name} is transient, not writing to InfluxDB`); + return; + } + + // Get the value after the last / + let metricName = birth.name.split('/').pop(); + + // Get the path as everything behind the last / + let path = birth.name.substring(0, birth.name.lastIndexOf("/")); + + writeApi.useDefaultTags({ + topLevelInstance: birth.instance.top, + bottomLevelInstance: birth.instance.bottom, + usesInstances: birth.instance.top + ':' + birth.instance.full.join(':'), + topLevelSchema: birth.schema.top, + bottomLevelSchema: birth.schema.bottom, + usesSchemas: birth.schema.top + ':' + birth.schema.full.join(':'), + group: topic.address.group, + node: topic.address.node, + device: topic.address.device, + path: path, + unit: birth.unit + }); + + let numVal = null; + + switch (birth.type) { + case "Int8": + case "Int16": + case "Int32": + case "Int64": + // Validate + numVal = Number(value); + if (!Number.isInteger(numVal)) { + logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${numVal}. Not recording.`); + return; + } + writeApi.writePoint( + new Point(`${metricName}:i`) + .intField('value', numVal) + .timestamp(timestamp) + ); + break; + case "UInt8": + case "UInt16": + case "UInt32": + case "UInt64": + // Validate + numVal = Number(value); + if (!Number.isInteger(numVal)) { + logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${numVal}. Not recording.`); + return; + } + writeApi.writePoint( + new Point(`${metricName}:u`) + .uintField('value', numVal) + .timestamp(timestamp) + ); + break; + case "Float": + case "Double": + // Validate + numVal = Number(value); + if (isNaN(parseFloat(numVal))) { + logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${numVal}. Not recording.`); + return; + } + writeApi.writePoint( + new Point(`${metricName}:d`) + .floatField('value', numVal) + .timestamp(timestamp) + ); + break; + case "Boolean": + if (typeof value != "boolean") { + logger.warn(`${topic.address}/${path}/${metricName} should be a ${birth.type} but received ${value}. Not recording.`); + return; + } + writeApi.writePoint( + new Point(`${metricName}:b`) + .booleanField('value', value) + .timestamp(timestamp)); + break; + default: + writeApi.writePoint( + new Point(`${metricName}:s`) + .stringField('value', value) + .timestamp(timestamp)); + break; + + } + + i++; + + logger.debug(`Added to write buffer (${i}/${batchSize}): [${birth.type}] ${topic.address}/${path}/${metricName} = ${value}`); + + if (i >= batchSize) { + this.flushBuffer(`${batchSize} point BATCH`); + } + } + + setNestedValue(obj, path, value) { + for (let k = 0; k < path.length - 1; k++) { + obj = obj[path[k]] = obj[path[k]] || {}; + } + obj[path[path.length - 1]] = value; + return obj; + } +} diff --git a/historian-sparkplug/package-lock.json b/historian-sparkplug/package-lock.json new file mode 100644 index 00000000..f9d2d793 --- /dev/null +++ b/historian-sparkplug/package-lock.json @@ -0,0 +1,3791 @@ +{ + "name": "historian-sparkplug", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "historian-sparkplug", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@amrc-factoryplus/utilities": "^1.0.8", + "@influxdata/influxdb-client": "^1.33.2", + "@influxdata/influxdb-client-apis": "^1.33.2", + "async": "^3.2.4", + "long": "^5.2.3", + "pino": "^8.11.0", + "pino-pretty": "^10.0.0" + }, + "devDependencies": { + "cross-env": "^7.0.3", + "dotenv": "^16.0.3", + "ts-node": "^10.9.1", + "tsc-alias": "^1.7.0" + } + }, + "node_modules/@amrc-factoryplus/utilities": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@amrc-factoryplus/utilities/-/utilities-1.0.8.tgz", + "integrity": "sha512-pSnakabCRTs7AlRtjYPNM47BQLsN2XR7xrNXuKmBDf+iytsCU1m0pCmQXuUM8/yvk80PxabMLm7dIlG405r5Bg==", + "dependencies": { + "@types/express": "4", + "@types/long": "^4.0.0", + "@types/node": ">=13.7.0", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "express": "^4.18.1", + "find-package-json": "^1.2.0", + "got-fetch": "^5.1.1", + "http-errors": "^2.0.0", + "mqtt": "^4.3.5", + "optional-js": "^2.3.0", + "path-to-regexp": "^6.2.1", + "pg": "^8.7.3", + "protobufjs": "^6.11.3", + "semver": "^7.5.1", + "sparkplug-payload": "^1.0.1", + "typescript": "^4.8.4" + }, + "optionalDependencies": { + "gssapi.js": "^2.0.1", + "pg-native": "^3.0.0" + } + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + }, + "node_modules/@amrc-factoryplus/utilities/node_modules/semver": { + "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" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@influxdata/influxdb-client": { + "version": "1.33.2", + "resolved": "https://registry.npmjs.org/@influxdata/influxdb-client/-/influxdb-client-1.33.2.tgz", + "integrity": "sha512-RT5SxH+grHAazo/YK3UTuWK/frPWRM0N7vkrCUyqVprDgQzlLP+bSK4ak2Jv3QVF/pazTnsxWjvtKZdwskV5Xw==" + }, + "node_modules/@influxdata/influxdb-client-apis": { + "version": "1.33.2", + "resolved": "https://registry.npmjs.org/@influxdata/influxdb-client-apis/-/influxdb-client-apis-1.33.2.tgz", + "integrity": "sha512-W6x9TOAQ3AUx0RBCrCibDhSvMqN50lxJmElc3rHn7+R/9Zi35oczu8r9YMkyNlzWnksu+dcyKr8/xLv28Ot4hw==", + "peerDependencies": { + "@influxdata/influxdb-client": "*" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "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": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "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_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/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "node_modules/@sindresorhus/is": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", + "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "peer": true, + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.33", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", + "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "peer": true + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, + "node_modules/@types/mime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" + }, + "node_modules/@types/node": { + "version": "18.15.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", + "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==" + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, + "node_modules/@types/serve-static": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", + "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", + "dependencies": { + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", + "integrity": "sha512-iFY7JCgHbepc0b82yLaw4IMortylNb6wG4kL+4R0C3iv6i+RHGHux/yUX5BTiRvSX/shMnngjR1YyNMnXEFh5A==", + "optional": true + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/are-we-there-yet": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.0.6.tgz", + "integrity": "sha512-Zfw6bteqM9gQXZ1BIWOgM8xEwMrUGoyL8nW13+O+OOgNX3YhuDN1GDgg1NzdTlmm3j+9sHy7uBZ12r+z9lXnZQ==", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.0 || ^1.1.13" + } + }, + "node_modules/are-we-there-yet/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "optional": true + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/are-we-there-yet/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "optional": true, + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "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/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", + "optional": true, + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bl/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "optional": true + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "optional": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g==", + "optional": true + }, + "node_modules/buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", + "optional": true, + "engines": { + "node": ">=0.2.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "peer": true, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.9", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.9.tgz", + "integrity": "sha512-CaAMr53AS1Tb9evO1BIWFnZjSr8A4pbXofpsNVWPMDZZj3ZQKHwsQG9BrTqQ4x5ZYJXz1T2b8LLtTZODxSpzbg==", + "peer": true, + "dependencies": { + "@types/http-cache-semantics": "^4.0.1", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.2", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", + "optional": true, + "dependencies": { + "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "optional": true + }, + "node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", + "optional": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/cmake-js": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/cmake-js/-/cmake-js-6.3.2.tgz", + "integrity": "sha512-7MfiQ/ijzeE2kO+WFB9bv4QP5Dn2yVaAP2acFJr4NIFy2hT4w6O4EpOTLNcohR5IPX7M4wNf/5taIqMj7UA9ug==", + "optional": true, + "dependencies": { + "axios": "^0.21.1", + "bluebird": "^3", + "debug": "^4", + "fs-extra": "^5.0.0", + "is-iojs": "^1.0.1", + "lodash": "^4", + "memory-stream": "0", + "npmlog": "^1.2.0", + "rc": "^1.2.7", + "semver": "^5.0.3", + "splitargs": "0", + "tar": "^4", + "unzipper": "^0.8.13", + "url-join": "0", + "which": "^1.0.9", + "yargs": "^3.6.0" + }, + "bin": { + "cmake-js": "bin/cmake-js" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/cmake-js/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "optional": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/cmake-js/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==", + "optional": true + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" + }, + "node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/commist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", + "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", + "dependencies": { + "leven": "^2.1.0", + "minimist": "^1.1.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "optional": true + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "peer": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "optional": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "optional": true + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/duplexify/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/duplexify/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fast-copy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.1.tgz", + "integrity": "sha512-Knr7NOtK3HWRYGtHoJrjkaWepqT8thIVGAwt0p0aUs1zqkAzXZV4vo9fFNwyb5fcqK1GKYFYxldQdIDVKhUAfA==" + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-redact": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.1.2.tgz", + "integrity": "sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-package-json": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/find-package-json/-/find-package-json-1.2.0.tgz", + "integrity": "sha512-+SOGcLGYDJHtyqHd87ysBhmaeQ95oWspDKnMXBrnQ9Eq4OkLNqejgoaD8xVWu6GPa0B6roa6KinCMEMcVeqONw==" + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "optional": true, + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "peer": true, + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", + "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "optional": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "optional": true, + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "optional": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/gauge": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", + "integrity": "sha512-fVbU2wRE91yDvKUnrIaQlHKAWKY5e08PmztCrwuH5YVQ+Z/p3d0ny2T48o6uvAAXHIUnfaQdHkmxYbQft1eHVA==", + "optional": true, + "dependencies": { + "ansi": "^0.3.0", + "has-unicode": "^2.0.0", + "lodash.pad": "^4.1.0", + "lodash.padend": "^4.1.0", + "lodash.padstart": "^4.1.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.0.tgz", + "integrity": "sha512-WTcaQ963xV97MN3x0/CbAriXFZcXCfgxVp91I+Ze6pawQOa7SgzwSx2zIJJsX+kTajMnVs0xcFD1TxZKFqhdnQ==", + "peer": true, + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got-fetch": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/got-fetch/-/got-fetch-5.1.4.tgz", + "integrity": "sha512-Pdv+SSgtTCDZbNuGkOf0c0FZy5Syqf225JEgG/vKt13HAe8r2vNJ11DxKKODsmr7L7/6ff3lf+AxpBtD5k/dRQ==", + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "got": "^12.0.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "optional": true + }, + "node_modules/gssapi.js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gssapi.js/-/gssapi.js-2.0.1.tgz", + "integrity": "sha512-5D+qylV8uIKMaxTTKhpzvfGRz5+okr/rpwC6YlaCoDVBpvkuNgL8pM7+r7aTzZ2oT5dA4w2WoZTV82opGj+RZQ==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "bindings": "^1.5.0", + "cmake-js": "^6.1.0", + "node-addon-api": "^1.7.2" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "optional": true + }, + "node_modules/help-me": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", + "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", + "dependencies": { + "glob": "^7.1.6", + "readable-stream": "^3.6.0" + } + }, + "node_modules/help-me/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/help-me/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "peer": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http2-wrapper": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz", + "integrity": "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==", + "peer": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "optional": true + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-iojs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-iojs/-/is-iojs-1.1.0.tgz", + "integrity": "sha512-tLn1j3wYSL6DkvEI+V/j0pKohpa5jk+ER74v6S4SgCXnjS0WA+DoZbwZBrrhgwksMvtuwndyGeG5F8YMsoBzSA==", + "optional": true + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "optional": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "devOptional": true + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "peer": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optional": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", + "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", + "peer": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", + "optional": true, + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/libpq": { + "version": "1.8.12", + "resolved": "https://registry.npmjs.org/libpq/-/libpq-1.8.12.tgz", + "integrity": "sha512-4lUY9BD9suz76mVS0kH4rRgRy620g/c9YZH5GYC3smfIpjtj6KiPuQ4IwQSHSZMMMhMM3tBFrYUrw8mHOOZVeg==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "bindings": "1.5.0", + "nan": "^2.14.0" + } + }, + "node_modules/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==", + "optional": true + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "optional": true + }, + "node_modules/lodash.pad": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", + "integrity": "sha512-mvUHifnLqM+03YNzeTBS1/Gr6JRFjd3rRx88FHWUvamVaT9k2O/kXha3yBSOwB9/DTQrSTLJNHvLBBt2FdX7Mg==", + "optional": true + }, + "node_modules/lodash.padend": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "integrity": "sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw==", + "optional": true + }, + "node_modules/lodash.padstart": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", + "integrity": "sha512-sW73O6S8+Tg66eY56DBk85aQzzUJDtpoXFBgELMd5P/SotAguo+1kYO6RuYgXxA4HJH3LFTFPASX6ET6bjfriw==", + "optional": true + }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memory-stream": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/memory-stream/-/memory-stream-0.0.3.tgz", + "integrity": "sha512-q0D3m846qY6ZkIt+19ZemU5vH56lpOZZwoJc3AICARKh/menBuayQUjAGPrqtHQQMUYERSdOrej92J9kz7LgYA==", + "optional": true, + "dependencies": { + "readable-stream": "~1.0.26-2" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "optional": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/minipass/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "optional": true + }, + "node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "optional": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "optional": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mqtt": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.7.tgz", + "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==", + "dependencies": { + "commist": "^1.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.1.1", + "duplexify": "^4.1.1", + "help-me": "^3.0.0", + "inherits": "^2.0.3", + "lru-cache": "^6.0.0", + "minimist": "^1.2.5", + "mqtt-packet": "^6.8.0", + "number-allocator": "^1.0.9", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^3.1.0", + "ws": "^7.5.5", + "xtend": "^4.0.2" + }, + "bin": { + "mqtt": "bin/mqtt.js", + "mqtt_pub": "bin/pub.js", + "mqtt_sub": "bin/sub.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mqtt-packet": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", + "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "dependencies": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + }, + "node_modules/mqtt-packet/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mqtt-packet/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==" + }, + "node_modules/mqtt/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mqtt/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==" + }, + "node_modules/mqtt/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/mqtt/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/mylas": { + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/mylas/-/mylas-2.1.13.tgz", + "integrity": "sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/raouldeheer" + } + }, + "node_modules/nan": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", + "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", + "optional": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "optional": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", + "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npmlog": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-1.2.1.tgz", + "integrity": "sha512-1J5KqSRvESP6XbjPaXt2H6qDzgizLTM7x0y1cXIjP2PpvdCqyNC7TO3cPRKsuYlElbi/DwkzRRdG2zpmE0IktQ==", + "optional": true, + "dependencies": { + "ansi": "~0.3.0", + "are-we-there-yet": "~1.0.0", + "gauge": "~1.2.0" + } + }, + "node_modules/number-allocator": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz", + "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==", + "dependencies": { + "debug": "^4.3.1", + "js-sdsl": "4.3.0" + } + }, + "node_modules/number-allocator/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/number-allocator/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==" + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", + "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optional-js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/optional-js/-/optional-js-2.3.0.tgz", + "integrity": "sha512-B0LLi+Vg+eko++0z/b8zIv57kp7HKEzaPJo7LowJXMUKYdf+3XJGu/cw03h/JhIOsLnP+cG5QnTHAuicjA5fMw==" + }, + "node_modules/os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", + "optional": true, + "dependencies": { + "lcid": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "peer": true, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pg": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.10.0.tgz", + "integrity": "sha512-ke7o7qSTMb47iwzOSaZMfeR7xToFdkE71ifIipOAAaLIM0DYzfOAXlgFFmYUIE2BcJtvnVlGCID84ZzCegE8CQ==", + "dependencies": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.5.0", + "pg-pool": "^3.6.0", + "pg-protocol": "^1.6.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-native": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pg-native/-/pg-native-3.0.1.tgz", + "integrity": "sha512-LBVNWkNh0fVx/cienARRP2y22J5OpUsKBe0TpxzAx3arEUUdIs77aLSAHS3scS7SMaqc+OkG40CEu5fN0/cjIw==", + "optional": true, + "dependencies": { + "libpq": "^1.8.10", + "pg-types": "^1.12.1", + "readable-stream": "1.0.31" + } + }, + "node_modules/pg-native/node_modules/pg-types": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-1.13.0.tgz", + "integrity": "sha512-lfKli0Gkl/+za/+b6lzENajczwZHc7D5kiUCZfgm914jipD2kIOIvEkAhZ8GrW3/TUoP9w8FHjwpPObBye5KQQ==", + "optional": true, + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~1.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.0", + "postgres-interval": "^1.1.0" + } + }, + "node_modules/pg-native/node_modules/postgres-array": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.3.tgz", + "integrity": "sha512-5wClXrAP0+78mcsNX3/ithQ5exKvCyK5lr5NEEEeGwwM6NJdQgzIJBVxLvRW+huFpX92F2QnZ5CcokH0VhK2qQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pg-native/node_modules/readable-stream": { + "version": "1.0.31", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.31.tgz", + "integrity": "sha512-tco/Dwv1f/sgIgN6CWdj/restacPKNskK6yps1981ivH2ZmLYcs5o5rVzL3qaO/cSkhN8hYOMWs7+glzOLSgRg==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/pg-pool": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.0.tgz", + "integrity": "sha512-clFRf2ksqd+F497kWFyM21tMjeikn60oGDmqMT8UBrynEwVEX/5R5xd2sdvdo1cZCFlguORNpVuqxIj+aK4cfQ==", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", + "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/pgpass/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pino": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.11.0.tgz", + "integrity": "sha512-Z2eKSvlrl2rH8p5eveNUnTdd4AjJk8tAsLkHYZQKGHP4WTh2Gi1cOSOs3eWPqaj+niS3gj4UkoreoaWgF3ZWYg==", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "v1.0.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.1.0", + "thread-stream": "^2.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz", + "integrity": "sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==", + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/pino-abstract-transport/node_modules/readable-stream": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz", + "integrity": "sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/pino-pretty": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.0.0.tgz", + "integrity": "sha512-zKFjYXBzLaLTEAN1ayKpHXtL5UeRQC7R3lvhKe7fWs7hIVEjKGG/qIXwQt9HmeUp71ogUd/YcW+LmMwRp4KT6Q==", + "dependencies": { + "colorette": "^2.0.7", + "dateformat": "^4.6.3", + "fast-copy": "^3.0.0", + "fast-safe-stringify": "^2.1.1", + "help-me": "^4.0.1", + "joycon": "^3.1.1", + "minimist": "^1.2.6", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.0.0", + "pump": "^3.0.0", + "readable-stream": "^4.0.0", + "secure-json-parse": "^2.4.0", + "sonic-boom": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "pino-pretty": "bin.js" + } + }, + "node_modules/pino-pretty/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/pino-pretty/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/pino-pretty/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/pino-pretty/node_modules/help-me": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-4.2.0.tgz", + "integrity": "sha512-TAOnTB8Tz5Dw8penUuzHVrKNKlCIbwwbHnXraNJxPwf8LRtE2HlM84RYuezMFcwOJmoYOCWVDyJ8TQGxn9PgxA==", + "dependencies": { + "glob": "^8.0.0", + "readable-stream": "^3.6.0" + } + }, + "node_modules/pino-pretty/node_modules/help-me/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pino-pretty/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pino-pretty/node_modules/readable-stream": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz", + "integrity": "sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-pretty/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/pino-pretty/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pino-std-serializers": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.0.tgz", + "integrity": "sha512-IWgSzUL8X1w4BIWTwErRgtV8PyOGOOi60uqv0oKuS/fOA8Nco/OeI6lBuc4dyP8MMfdFwyHqTMcBIA7nDiqEqA==" + }, + "node_modules/plimit-lit": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/plimit-lit/-/plimit-lit-1.5.0.tgz", + "integrity": "sha512-Eb/MqCb1Iv/ok4m1FqIXqvUKPISufcjZ605hl3KM/n8GaX8zfhtgdLwZU3vKjuHGh2O9Rjog/bHTq8ofIShdng==", + "dev": true, + "dependencies": { + "queue-lit": "^1.5.0" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/process-warning": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", + "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==" + }, + "node_modules/protobufjs": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/protobufjs/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-lit": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-1.5.0.tgz", + "integrity": "sha512-IslToJ4eiCEE9xwMzq3viOO5nH8sUWUCwoElrhNMozzr9IIt2qqvB4I+uHu/zJTQVqc9R5DFwok4ijNK1pU3fA==", + "dev": true + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "optional": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "peer": true + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "peer": true, + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "optional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "optional": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sonic-boom": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz", + "integrity": "sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/sparkplug-payload": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkplug-payload/-/sparkplug-payload-1.0.1.tgz", + "integrity": "sha512-N4i++SFY7ECH7NB2bi1zmL9uPRKXF5cXQRxudUqZi9sribVZB7TZWvMIcTTakqqs1WkryYgpuV34CwEYm7I0Cg==", + "dependencies": { + "protobufjs": "^6.8.0" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/split2/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/split2/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/splitargs": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/splitargs/-/splitargs-0.0.7.tgz", + "integrity": "sha512-UUFYD2oWbNwULH6WoVtLUOw8ch586B+HUqcsAjjjeoBQAM1bD4wZRXu01koaxyd8UeYpybWqW4h+lO1Okv40Tg==", + "optional": true + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "optional": true + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "optional": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "optional": true, + "dependencies": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "optional": true + }, + "node_modules/thread-stream": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.3.0.tgz", + "integrity": "sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==", + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tsc-alias": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/tsc-alias/-/tsc-alias-1.8.5.tgz", + "integrity": "sha512-Y3ka0olwSRdbHPyX5kXhYY2aoBKuT53DFdeY+PpQUR4hg5M/b8eIRmC8dL4FBdd0wT366iWc6iDUUGe6QwI7mg==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.3", + "commander": "^9.0.0", + "globby": "^11.0.4", + "mylas": "^2.1.9", + "normalize-path": "^3.0.0", + "plimit-lit": "^1.2.6" + }, + "bin": { + "tsc-alias": "dist/bin/index.js" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "optional": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unzipper": { + "version": "0.8.14", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.8.14.tgz", + "integrity": "sha512-8rFtE7EP5ssOwGpN2dt1Q4njl0N1hUXJ7sSPz0leU2hRdq6+pra57z4YPBlVqm40vcgv6ooKZEAx48fMTv9x4w==", + "optional": true, + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "~1.0.10", + "listenercount": "~1.0.1", + "readable-stream": "~2.1.5", + "setimmediate": "~1.0.4" + } + }, + "node_modules/unzipper/node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==", + "optional": true + }, + "node_modules/unzipper/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "optional": true + }, + "node_modules/unzipper/node_modules/process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==", + "optional": true + }, + "node_modules/unzipper/node_modules/readable-stream": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", + "integrity": "sha512-NkXT2AER7VKXeXtJNSaWLpWIhmtSE3K2PguaLEeWr4JILghcIKqoLt1A3wHrnpDC5+ekf8gfk1GKWkFXe4odMw==", + "optional": true, + "dependencies": { + "buffer-shims": "^1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/url-join": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz", + "integrity": "sha512-H6dnQ/yPAAVzMQRvEvyz01hhfQL5qRWSEt7BX8t9DqnPw9BjMb64fjIRq76Uvf1hkHp+mTZvEVJ5guXOT0Xqaw==", + "optional": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "optional": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/window-size": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "integrity": "sha512-2thx4pB0cV3h+Bw7QmMXcEbdmOzv9t0HFplJH/Lz6yu60hXYy5RT8rUu+wlIreVxWsGN20mo+MHeCSfUpQBwPw==", + "optional": true, + "bin": { + "window-size": "cli.js" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", + "optional": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", + "optional": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yargs": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "integrity": "sha512-ONJZiimStfZzhKamYvR/xvmgW3uEkAUFSP91y2caTEPhzF6uP2JfPiVZcq66b/YR0C3uitxSV7+T1x8p5bkmMg==", + "optional": true, + "dependencies": { + "camelcase": "^2.0.1", + "cliui": "^3.0.3", + "decamelize": "^1.1.1", + "os-locale": "^1.4.0", + "string-width": "^1.0.1", + "window-size": "^0.1.4", + "y18n": "^3.2.0" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + } +} diff --git a/historian-sparkplug/package.json b/historian-sparkplug/package.json new file mode 100644 index 00000000..debb790c --- /dev/null +++ b/historian-sparkplug/package.json @@ -0,0 +1,41 @@ +{ + "name": "historian-sparkplug", + "version": "1.0.0", + "description": "An ingestion engine to enable InfluxDB to be a fully-featured Sparkplug historian", + "author": "AMRC", + "license": "MIT", + "keywords": [ + "amrc", + "factory-plus", + "factoryplus", + "acs", + "amrc-connectivity-stack", + "mqtt", + "sparkplug" + ], + "type": "module", + "scripts": { + "start": "node --trace-warnings dist/bin/ingester.js", + "start:shell": "k5start -Uf $CLIENT_KEYTAB npm run start", + "dev": " npm run build && npm run start:dev", + "build": "tsc && tsc-alias", + "clean": "tsc --build --clean", + "lint": "eslint --ignore-path .gitignore --ext .ts src/", + "lint:fix": "npm run lint -- --fix" + }, + "dependencies": { + "@amrc-factoryplus/utilities": "^1.0.8", + "@influxdata/influxdb-client": "^1.33.2", + "@influxdata/influxdb-client-apis": "^1.33.2", + "async": "^3.2.4", + "long": "^5.2.3", + "pino": "^8.11.0", + "pino-pretty": "^10.0.0" + }, + "devDependencies": { + "cross-env": "^7.0.3", + "dotenv": "^16.0.3", + "ts-node": "^10.9.1", + "tsc-alias": "^1.7.0" + } +} diff --git a/historian-sparkplug/run-dev.sh b/historian-sparkplug/run-dev.sh new file mode 100755 index 00000000..319876e8 --- /dev/null +++ b/historian-sparkplug/run-dev.sh @@ -0,0 +1,10 @@ +# +# AMRC InfluxDB Sparkplug Historian +# Copyright "2023" AMRC +# + +# bin/bash +tmpfile=$(mktemp) +export CLIENT_KEYTAB="$(kubectl --kubeconfig ~/.kube/fplus get -n factory-plus secret krb5-keytabs -o jsonpath="{.data.sv1warehouse}" | base64 -d >"$tmpfile" && echo "$tmpfile")" +echo $CLIENT_KEYTAB +npm run start:shell diff --git a/historian-sparkplug/tsconfig.json b/historian-sparkplug/tsconfig.json new file mode 100644 index 00000000..a3a2f0a7 --- /dev/null +++ b/historian-sparkplug/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "target": "es2017", + "lib": ["es2017", "esnext.asynciterable", "dom"], + "typeRoots": ["node_modules/@types"], + "allowSyntheticDefaultImports": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node", + "module": "es2022", + "pretty": true, + "sourceMap": true, + "declaration": true, + "outDir": "dist", + "allowJs": true, + "noEmit": false, + "esModuleInterop": true, + "resolveJsonModule": true, + "importHelpers": true, + "skipLibCheck": true, + "baseUrl": "src", + "paths": { + "@/*": ["*"], + "@bin/*": ["../bin/*"], + "@lib/*": ["../lib/*"] + } + }, + "include": ["bin/**/*.ts", "lib/**/*.json", ".env"], + "exclude": ["node_modules"] +} From fa4f4586a7704f235213fb2848df5f1039029752 Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Fri, 6 Sep 2024 14:34:25 +0100 Subject: [PATCH 38/58] Add uns-ingester-sparkplug --- .github/workflows/publish.yml | 1 + .../auth/principals/service-clients.yaml | 2 +- deploy/templates/uns-ingesters/sparkplug.yaml | 54 +++++++++++++++++++ deploy/values.yaml | 5 +- ingesters/sparkplug/README.md | 5 -- ingesters/sparkplug/run-dev.sh | 9 ---- .../.env.example | 1 - .../.gitignore | 0 .../Dockerfile | 0 .../LICENSE | 0 uns-ingester-sparkplug/README.md | 8 +++ .../SECURITY.md | 0 .../bin/ingester.js | 0 .../bin/ingester.ts | 2 +- .../lib/mqttclient.js | 0 .../lib/mqttclient.ts | 2 +- .../package-lock.json | 4 +- .../package.json | 2 +- uns-ingester-sparkplug/run-dev.sh | 9 ++++ .../tsconfig.json | 0 20 files changed, 82 insertions(+), 22 deletions(-) create mode 100644 deploy/templates/uns-ingesters/sparkplug.yaml delete mode 100644 ingesters/sparkplug/README.md delete mode 100755 ingesters/sparkplug/run-dev.sh rename {ingesters/sparkplug => uns-ingester-sparkplug}/.env.example (74%) rename {ingesters/sparkplug => uns-ingester-sparkplug}/.gitignore (100%) rename {ingesters/sparkplug => uns-ingester-sparkplug}/Dockerfile (100%) rename {ingesters/sparkplug => uns-ingester-sparkplug}/LICENSE (100%) create mode 100644 uns-ingester-sparkplug/README.md rename {ingesters/sparkplug => uns-ingester-sparkplug}/SECURITY.md (100%) rename {ingesters/sparkplug => uns-ingester-sparkplug}/bin/ingester.js (100%) rename {ingesters/sparkplug => uns-ingester-sparkplug}/bin/ingester.ts (97%) rename {ingesters/sparkplug => uns-ingester-sparkplug}/lib/mqttclient.js (100%) rename {ingesters/sparkplug => uns-ingester-sparkplug}/lib/mqttclient.ts (99%) rename {ingesters/sparkplug => uns-ingester-sparkplug}/package-lock.json (99%) rename {ingesters/sparkplug => uns-ingester-sparkplug}/package.json (96%) create mode 100755 uns-ingester-sparkplug/run-dev.sh rename {ingesters/sparkplug => uns-ingester-sparkplug}/tsconfig.json (100%) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3c2af4d3..bbe1e871 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -167,6 +167,7 @@ jobs: - edge-helm-charts - historian-sparkplug - historian-uns + - uns-ingester-sparkplug permissions: contents: read packages: write diff --git a/deploy/templates/auth/principals/service-clients.yaml b/deploy/templates/auth/principals/service-clients.yaml index 6df38568..33bd1f13 100644 --- a/deploy/templates/auth/principals/service-clients.yaml +++ b/deploy/templates/auth/principals/service-clients.yaml @@ -132,7 +132,7 @@ metadata: spec: type: Random principal: sv1sparkplugingester@{{ .Values.identity.realm | required "values.identity.realm is required!" }} - secret: sparkplugingester-keytabs/client + secret: uns-ingester-sparkplug-keytabs/client {{- end }} --- # In the future if we have any more ingesters then this should be diff --git a/deploy/templates/uns-ingesters/sparkplug.yaml b/deploy/templates/uns-ingesters/sparkplug.yaml new file mode 100644 index 00000000..290b6d0e --- /dev/null +++ b/deploy/templates/uns-ingesters/sparkplug.yaml @@ -0,0 +1,54 @@ +{{- if .Values.unsIngesters.sparkplug.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: uns-ingester-sparkplug + namespace: {{ .Release.Namespace }} + labels: + component: uns-ingester-sparkplug +spec: + replicas: 1 + selector: + matchLabels: + component: uns-ingester-sparkplug + template: + metadata: + labels: + component: uns-ingester-sparkplug + factory-plus.service: uns-ingester-sparkplug + spec: + {{- with .Values.acs.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: krb5-conf + configMap: + name: krb5-conf + - name: keytabs + secret: + secretName: uns-ingester-sparkplug-keytabs + + containers: + - name: uns-ingester-sparkplug + image: "{{ include "amrc-connectivity-stack.image-name" (list . .Values.unsIngesters.sparkplug) }}" + command: [ "/usr/bin/k5start", "-Uf", "/keytabs/client" ] + args: [ "node", "--es-module-specifier-resolution=node", "bin/injector.js" ] + imagePullPolicy: Always + env: + - name: KRB5_CONFIG + value: /config/krb5-conf/krb5.conf + - name: CLIENT_KEYTAB + value: /keytabs/client + - name: LOG_LEVEL + value: {{ .Values.unsIngesters.sparkplug.logLevel | required "values.unsIngesters.sparkplug.logLevel" }} + - name: DIRECTORY_URL + value: http://directory.{{ .Release.Namespace }}.svc.cluster.local + - name: VERBOSE + value: {{.Values.unsIngesters.sparkplug.verbosity | quote | required "values.unsIngesters.sparkplug.verbosity"}} + volumeMounts: + - mountPath: /config/krb5-conf + name: krb5-conf + - mountPath: /keytabs + name: keytabs +{{- end -}} diff --git a/deploy/values.yaml b/deploy/values.yaml index 3a2d97f7..e5d0a41b 100644 --- a/deploy/values.yaml +++ b/deploy/values.yaml @@ -157,8 +157,11 @@ unsIngesters: # -- The registry of the MQTT component registry: ghcr.io/amrc-factoryplus # -- The repository of the MQTT component - repository: sparkplug-ingester + repository: uns-ingester-sparkplug pullPolicy: IfNotPresent + # -- The minimum log level that the historian will log messages at (One of 'fatal', 'error', 'warn', 'info', 'debug', 'trace' or 'silent'.) + logLevel: info + verbosity: 0 visualiser: enabled: true diff --git a/ingesters/sparkplug/README.md b/ingesters/sparkplug/README.md deleted file mode 100644 index 5d24db65..00000000 --- a/ingesters/sparkplug/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# InfluxDB Sparkplug Ingester - -A component that allows InfluxDB to function as a comprehensive Sparkplug-based data historian. It was developed for the [AMRC Connectiviy Stack](https://github.com/AMRC-FactoryPlus/amrc-connectivity-stack), the AMRC's open-source implementation of the Factory+ framework. - -See the [ACS Helm chart](https://github.com/AMRC-FactoryPlus/amrc-connectivity-stack) for information on how to deploy this component. diff --git a/ingesters/sparkplug/run-dev.sh b/ingesters/sparkplug/run-dev.sh deleted file mode 100755 index ab43a959..00000000 --- a/ingesters/sparkplug/run-dev.sh +++ /dev/null @@ -1,9 +0,0 @@ -# -# AMRC ACS UNS Ingester -# Copyright "2023" AMRC -# - -# bin/bash -tmpfile=$(mktemp) -export CLIENT_KEYTAB="$(kubectl --kubeconfig ~/.kube/p2.yaml get -n factory-plus secret krb5-keytabs -o jsonpath="{.data.sv1warehouse}" | base64 -d >"$tmpfile" && echo "$tmpfile")" -npm run start:shell diff --git a/ingesters/sparkplug/.env.example b/uns-ingester-sparkplug/.env.example similarity index 74% rename from ingesters/sparkplug/.env.example rename to uns-ingester-sparkplug/.env.example index 1a3e236e..1cc68f75 100644 --- a/ingesters/sparkplug/.env.example +++ b/uns-ingester-sparkplug/.env.example @@ -1,4 +1,3 @@ DIRECTORY_URL=https://directory.domain.co.uk -UNS_MQTT_URL=mqtt://localhost:1883 LOG_LEVEL=debug CMD_ESC_URL=https://cmdesc.domain.co.uk diff --git a/ingesters/sparkplug/.gitignore b/uns-ingester-sparkplug/.gitignore similarity index 100% rename from ingesters/sparkplug/.gitignore rename to uns-ingester-sparkplug/.gitignore diff --git a/ingesters/sparkplug/Dockerfile b/uns-ingester-sparkplug/Dockerfile similarity index 100% rename from ingesters/sparkplug/Dockerfile rename to uns-ingester-sparkplug/Dockerfile diff --git a/ingesters/sparkplug/LICENSE b/uns-ingester-sparkplug/LICENSE similarity index 100% rename from ingesters/sparkplug/LICENSE rename to uns-ingester-sparkplug/LICENSE diff --git a/uns-ingester-sparkplug/README.md b/uns-ingester-sparkplug/README.md new file mode 100644 index 00000000..c22cedb8 --- /dev/null +++ b/uns-ingester-sparkplug/README.md @@ -0,0 +1,8 @@ +# Sparkplug UNS Ingester + +A component that takes Sparkplug messages from `spBv1.0/#` and +re-publishes them to the UNS. + +See the [ACS Helm +chart](https://github.com/AMRC-FactoryPlus/amrc-connectivity-stack) for +information on how to deploy this component. diff --git a/ingesters/sparkplug/SECURITY.md b/uns-ingester-sparkplug/SECURITY.md similarity index 100% rename from ingesters/sparkplug/SECURITY.md rename to uns-ingester-sparkplug/SECURITY.md diff --git a/ingesters/sparkplug/bin/ingester.js b/uns-ingester-sparkplug/bin/ingester.js similarity index 100% rename from ingesters/sparkplug/bin/ingester.js rename to uns-ingester-sparkplug/bin/ingester.js diff --git a/ingesters/sparkplug/bin/ingester.ts b/uns-ingester-sparkplug/bin/ingester.ts similarity index 97% rename from ingesters/sparkplug/bin/ingester.ts rename to uns-ingester-sparkplug/bin/ingester.ts index 177334ba..5d84024b 100644 --- a/ingesters/sparkplug/bin/ingester.ts +++ b/uns-ingester-sparkplug/bin/ingester.ts @@ -1,5 +1,5 @@ /* - * AMRC ACS UNS Ingester + * AMRC ACS UNS Ingester (Sparkplug) * Copyright "2023" AMRC */ diff --git a/ingesters/sparkplug/lib/mqttclient.js b/uns-ingester-sparkplug/lib/mqttclient.js similarity index 100% rename from ingesters/sparkplug/lib/mqttclient.js rename to uns-ingester-sparkplug/lib/mqttclient.js diff --git a/ingesters/sparkplug/lib/mqttclient.ts b/uns-ingester-sparkplug/lib/mqttclient.ts similarity index 99% rename from ingesters/sparkplug/lib/mqttclient.ts rename to uns-ingester-sparkplug/lib/mqttclient.ts index 54cc557a..8a5c3e62 100644 --- a/ingesters/sparkplug/lib/mqttclient.ts +++ b/uns-ingester-sparkplug/lib/mqttclient.ts @@ -1,5 +1,5 @@ /* - * AMRC ACS UNS Ingester + * AMRC ACS UNS Ingester (Sparkplug) * Copyright "2024" AMRC */ diff --git a/ingesters/sparkplug/package-lock.json b/uns-ingester-sparkplug/package-lock.json similarity index 99% rename from ingesters/sparkplug/package-lock.json rename to uns-ingester-sparkplug/package-lock.json index a7ecf9d2..9d5bc736 100644 --- a/ingesters/sparkplug/package-lock.json +++ b/uns-ingester-sparkplug/package-lock.json @@ -1,11 +1,11 @@ { - "name": "sparkplug-ingester", + "name": "uns-ingester-sparkplug", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "sparkplug-ingester", + "name": "uns-ingester-sparkplug", "version": "1.0.0", "license": "MIT", "dependencies": { diff --git a/ingesters/sparkplug/package.json b/uns-ingester-sparkplug/package.json similarity index 96% rename from ingesters/sparkplug/package.json rename to uns-ingester-sparkplug/package.json index 4fdff77c..9bb37fde 100644 --- a/ingesters/sparkplug/package.json +++ b/uns-ingester-sparkplug/package.json @@ -1,5 +1,5 @@ { - "name": "sparkplug-ingester", + "name": "uns-ingester-sparkplug", "version": "1.0.0", "description": "An ingestion engine to enable InfluxDB to be a fully-featured Sparkplug historian", "author": "AMRC", diff --git a/uns-ingester-sparkplug/run-dev.sh b/uns-ingester-sparkplug/run-dev.sh new file mode 100755 index 00000000..39924ef0 --- /dev/null +++ b/uns-ingester-sparkplug/run-dev.sh @@ -0,0 +1,9 @@ +# +# AMRC ACS UNS Ingester (Sparkplug) +# Copyright "2023" AMRC +# + +# bin/bash +tmpfile=$(mktemp) +export CLIENT_KEYTAB="$(kubectl --kubeconfig ~/.kube/p2.yaml get -n factory-plus secret krb5-keytabs -o jsonpath="{.data.sv1sparkplugingester}" | base64 -d >"$tmpfile" && echo "$tmpfile")" +npm run start:shell diff --git a/ingesters/sparkplug/tsconfig.json b/uns-ingester-sparkplug/tsconfig.json similarity index 100% rename from ingesters/sparkplug/tsconfig.json rename to uns-ingester-sparkplug/tsconfig.json From 16b47130bf39aca44edb7ba5d5131ae635fa8578 Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Fri, 6 Sep 2024 15:13:05 +0100 Subject: [PATCH 39/58] Update executable paths in YAML and Dockerfile Revised the arguments for node commands to ensure correct script execution in the uns.yaml, sparkplug.yaml, and Dockerfile files. Replaced "bin/injector.js" with "app.js" or appropriate script names. --- deploy/templates/historians/uns.yaml | 2 +- deploy/templates/uns-ingesters/sparkplug.yaml | 2 +- historian-uns/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/templates/historians/uns.yaml b/deploy/templates/historians/uns.yaml index 5c9c2bcc..27932bb2 100644 --- a/deploy/templates/historians/uns.yaml +++ b/deploy/templates/historians/uns.yaml @@ -35,7 +35,7 @@ spec: - name: historian-uns image: "{{ include "amrc-connectivity-stack.image-name" (list . .Values.historians.uns) }}" command: [ "/usr/bin/k5start", "-Uf", "/keytabs/client" ] - args: [ "node", "--es-module-specifier-resolution=node", "bin/injector.js" ] + args: [ "node", "--es-module-specifier-resolution=node", "app.js" ] imagePullPolicy: Always env: - name: KRB5_CONFIG diff --git a/deploy/templates/uns-ingesters/sparkplug.yaml b/deploy/templates/uns-ingesters/sparkplug.yaml index 290b6d0e..fffe1042 100644 --- a/deploy/templates/uns-ingesters/sparkplug.yaml +++ b/deploy/templates/uns-ingesters/sparkplug.yaml @@ -33,7 +33,7 @@ spec: - name: uns-ingester-sparkplug image: "{{ include "amrc-connectivity-stack.image-name" (list . .Values.unsIngesters.sparkplug) }}" command: [ "/usr/bin/k5start", "-Uf", "/keytabs/client" ] - args: [ "node", "--es-module-specifier-resolution=node", "bin/injector.js" ] + args: [ "node", "--es-module-specifier-resolution=node", "bin/ingester.js" ] imagePullPolicy: Always env: - name: KRB5_CONFIG diff --git a/historian-uns/Dockerfile b/historian-uns/Dockerfile index f87def5a..45ed2c1d 100644 --- a/historian-uns/Dockerfile +++ b/historian-uns/Dockerfile @@ -64,4 +64,4 @@ WORKDIR /usr/app # running application. This is a Good Thing. COPY --from=util-build /usr/app ./ USER node -CMD [ "node", "--es-module-specifier-resolution=node", "bin/app.js" ] +CMD [ "node", "--es-module-specifier-resolution=node", "app.js" ] From 632462652a01047ca197ebd2f91fb933e1bea2ce Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Fri, 6 Sep 2024 15:16:24 +0100 Subject: [PATCH 40/58] Allow global debuggers to read UNS --- acs-service-setup/dumps/uns.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/acs-service-setup/dumps/uns.yaml b/acs-service-setup/dumps/uns.yaml index 5ef0dad1..9feb1e01 100644 --- a/acs-service-setup/dumps/uns.yaml +++ b/acs-service-setup/dumps/uns.yaml @@ -40,3 +40,6 @@ aces: - principal: !u ACS.ServiceAccount.HistorianUNS permission: !u ACS.Perm.MQTT.ReadEntireUNS target: !u UUIDs.Special.Null +groups: + !u ACS.Group.GlobalDebuggers: + - !u ACS.Perm.MQTT.ReadEntireUNS From c00045206546f73c318a17f367b842f95d37d027 Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Fri, 6 Sep 2024 15:28:41 +0100 Subject: [PATCH 41/58] Update ReleaseNotes.md --- ReleaseNotes.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 7f51d444..470cde1c 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -8,6 +8,13 @@ chronological order. These changes have not been released yet, but are likely to appear in the next release. +### Historian value changes +With the introduction of the UNS ingesters, the historian (formerly +the `sparkplug-influxdb-ingester`) has been renamed to support the +concept of multiple historians. Therefore, the `warehouse.ingester` +values have relocated to the `historians.sparkplug` key. Make sure +to update your values file accordingly. + ## v3.1.0 ### Administration interface From 2b6bd17759ded82c40f99e1cfa2d35a2cfede242 Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Fri, 6 Sep 2024 15:40:33 +0100 Subject: [PATCH 42/58] Add CmdEsc.Rebirth permission for SparkplugIngester Extend SparkplugIngester permissions to include CmdEsc.Rebirth. This change allows the service account to issue rebirth requests in addition to its existing read permission. --- acs-service-setup/dumps/uns.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/acs-service-setup/dumps/uns.yaml b/acs-service-setup/dumps/uns.yaml index 9feb1e01..f5102454 100644 --- a/acs-service-setup/dumps/uns.yaml +++ b/acs-service-setup/dumps/uns.yaml @@ -37,6 +37,9 @@ aces: - principal: !u ACS.ServiceAccount.SparkplugIngester permission: !u ACS.Perm.MQTT.ReadWholeNamespace target: !u UUIDs.Special.Null + - principal: !u ACS.ServiceAccount.SparkplugIngester + permission: !u UUIDs.Permission.CmdEsc.Rebirth + target: !u UUIDs.Special.Null - principal: !u ACS.ServiceAccount.HistorianUNS permission: !u ACS.Perm.MQTT.ReadEntireUNS target: !u UUIDs.Special.Null From 234536859025e719dcd020072ac8c2276090072f Mon Sep 17 00:00:00 2001 From: D J Newbould <132448197+djnewbould@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:06:59 +0100 Subject: [PATCH 43/58] Changed the service account setup --- acs-service-setup/dumps/uns.yaml | 24 ++++--------------- acs-service-setup/lib/uuids.js | 2 ++ .../auth/principals/service-clients.yaml | 18 ++++++++++++++ 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/acs-service-setup/dumps/uns.yaml b/acs-service-setup/dumps/uns.yaml index f5102454..fbcd887b 100644 --- a/acs-service-setup/dumps/uns.yaml +++ b/acs-service-setup/dumps/uns.yaml @@ -10,9 +10,6 @@ objects: !u ACS.Class.Permission: - !u ACS.Perm.MQTT.WriteToEntireUNS - !u ACS.Perm.MQTT.ReadEntireUNS - !u ACS.Class.ServiceAccount: - - !u ACS.ServiceAccount.SparkplugIngester - - !u ACS.ServiceAccount.HistorianUNS configs: !u UUIDs.App.Info: !u ACS.Perm.MQTT.WriteToEntireUNS: { name: "MQTT: Write to entire UNS" } @@ -25,24 +22,13 @@ configs: --- service: !u UUIDs.Service.Authentication version: 1 -principals: - - uuid: !u ACS.ServiceAccount.SparkplugIngester - kerberos: sv1sparkplugingester@{{realm}} - - uuid: !u ACS.ServiceAccount.HistorianUNS - kerberos: sv1historianuns@{{realm}} aces: - - principal: !u ACS.ServiceAccount.SparkplugIngester - permission: !u ACS.Perm.MQTT.WriteToEntireUNS - target: !u UUIDs.Special.Null - - principal: !u ACS.ServiceAccount.SparkplugIngester - permission: !u ACS.Perm.MQTT.ReadWholeNamespace - target: !u UUIDs.Special.Null - - principal: !u ACS.ServiceAccount.SparkplugIngester - permission: !u UUIDs.Permission.CmdEsc.Rebirth - target: !u UUIDs.Special.Null - - principal: !u ACS.ServiceAccount.HistorianUNS + - principal: !u ACS.Group.HistorianUNS permission: !u ACS.Perm.MQTT.ReadEntireUNS target: !u UUIDs.Special.Null + - principal: !u ACS.Group.SparkplugIngesters + permission: !u ACS.Perm.MQTT.WriteToEntireUNS + target: !u UUIDs.Special.Self groups: !u ACS.Group.GlobalDebuggers: - - !u ACS.Perm.MQTT.ReadEntireUNS + - !u ACS.Group.SparkplugIngesters diff --git a/acs-service-setup/lib/uuids.js b/acs-service-setup/lib/uuids.js index a2e51168..56ee4fd9 100644 --- a/acs-service-setup/lib/uuids.js +++ b/acs-service-setup/lib/uuids.js @@ -23,6 +23,8 @@ export const ACS = { EdgeGroups: "9ba0de4b-056f-4b5e-b966-2d5d85d07767", EdgePermissions: "7594cd71-e5b9-4467-88c0-b11a66d47fec", CentralMonitor: "1bc3dbca-68fe-48d2-9590-3a528c111827", + SparkplugIngesters: "e414d355-b991-429b-8f5d-97e823ff71f5", + HistorianUNS: "03f5f08a-f61e-4134-8f66-b2951e3bbb69", }, Perm: { MQTT: { diff --git a/deploy/templates/auth/principals/service-clients.yaml b/deploy/templates/auth/principals/service-clients.yaml index 33bd1f13..888ee720 100644 --- a/deploy/templates/auth/principals/service-clients.yaml +++ b/deploy/templates/auth/principals/service-clients.yaml @@ -133,6 +133,15 @@ spec: type: Random principal: sv1sparkplugingester@{{ .Values.identity.realm | required "values.identity.realm is required!" }} secret: uns-ingester-sparkplug-keytabs/client + account: + class: e463b4ae-a322-46cc-8976-4ba76838e908 + name: Sparkplug Ingester + groups: + - e414d355-b991-429b-8f5d-97e823ff71f5 + sparkplug: + group: {{ .Values.acs.organisation }}-Service-Core + node: SparkplugIngester + {{- end }} --- # In the future if we have any more ingesters then this should be @@ -147,4 +156,13 @@ spec: type: Random principal: sv1historianuns@{{ .Values.identity.realm | required "values.identity.realm is required!" }} secret: historian-uns-keytabs/client + account: + class: e463b4ae-a322-46cc-8976-4ba76838e908 + name: Historian UNS + groups: + - 03f5f08a-f61e-4134-8f66-b2951e3bbb69 + sparkplug: + group: {{ .Values.acs.organisation }}-Service-Core + node: HistorianUNS + {{- end }} From a46af94ef74dfb4f0f10c6d1a56df8139b572509 Mon Sep 17 00:00:00 2001 From: D J Newbould <132448197+djnewbould@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:18:51 +0100 Subject: [PATCH 44/58] Changed kubeconfig path to use env variable --- historian-uns/run-dev.sh | 2 +- uns-ingester-sparkplug/run-dev.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/historian-uns/run-dev.sh b/historian-uns/run-dev.sh index cdede838..7e6f055d 100644 --- a/historian-uns/run-dev.sh +++ b/historian-uns/run-dev.sh @@ -5,5 +5,5 @@ # bin/bash tmpfile=$(mktemp) -export CLIENT_KEYTAB="$(kubectl --kubeconfig get -n factory-plus secret krb5-keytabs -o jsonpath="{.data.sv1historianuns}" | base64 -d >"$tmpfile" && echo "$tmpfile")" +export CLIENT_KEYTAB="$(kubectl --kubeconfig "$KUBECONFIG" get -n factory-plus secret krb5-keytabs -o jsonpath="{.data.sv1historianuns}" | base64 -d >"$tmpfile" && echo "$tmpfile")" npm run start:shell diff --git a/uns-ingester-sparkplug/run-dev.sh b/uns-ingester-sparkplug/run-dev.sh index 39924ef0..07583b5f 100755 --- a/uns-ingester-sparkplug/run-dev.sh +++ b/uns-ingester-sparkplug/run-dev.sh @@ -5,5 +5,5 @@ # bin/bash tmpfile=$(mktemp) -export CLIENT_KEYTAB="$(kubectl --kubeconfig ~/.kube/p2.yaml get -n factory-plus secret krb5-keytabs -o jsonpath="{.data.sv1sparkplugingester}" | base64 -d >"$tmpfile" && echo "$tmpfile")" +export CLIENT_KEYTAB="$(kubectl --kubeconfig "$KUBECONFIG" get -n factory-plus secret krb5-keytabs -o jsonpath="{.data.sv1sparkplugingester}" | base64 -d >"$tmpfile" && echo "$tmpfile")" npm run start:shell From 7ea17b1ad56072e311bc2d21dd6036bc3b641f09 Mon Sep 17 00:00:00 2001 From: D J Newbould <132448197+djnewbould@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:22:40 +0100 Subject: [PATCH 45/58] Add ReadEntireUNS permission to global debuggers --- acs-service-setup/dumps/admin.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/acs-service-setup/dumps/admin.yaml b/acs-service-setup/dumps/admin.yaml index fa701a3a..f093b8c5 100644 --- a/acs-service-setup/dumps/admin.yaml +++ b/acs-service-setup/dumps/admin.yaml @@ -49,3 +49,6 @@ aces: - principal: !u ACS.Group.GlobalDebuggers permission: !u UUIDs.Permission.CmdEsc.Rebirth target: !u UUIDs.Special.Null + - principal: !u ACS.Group.GlobalDebuggers + permission: !u ACS.Perm.MQTT.ReadEntireUNS + target: !u UUIDs.Special.Null From f2ed730c21296bcc5bd3bcf57eb489e9412ef422 Mon Sep 17 00:00:00 2001 From: D J Newbould <132448197+djnewbould@users.noreply.github.com> Date: Tue, 10 Sep 2024 10:12:22 +0100 Subject: [PATCH 46/58] Removed redundant JS files --- uns-ingester-sparkplug/bin/ingester.js | 28 ---- uns-ingester-sparkplug/lib/mqttclient.js | 182 ----------------------- 2 files changed, 210 deletions(-) delete mode 100644 uns-ingester-sparkplug/bin/ingester.js delete mode 100644 uns-ingester-sparkplug/lib/mqttclient.js diff --git a/uns-ingester-sparkplug/bin/ingester.js b/uns-ingester-sparkplug/bin/ingester.js deleted file mode 100644 index 7ae99c60..00000000 --- a/uns-ingester-sparkplug/bin/ingester.js +++ /dev/null @@ -1,28 +0,0 @@ -import { Debug, ServiceClient } from "@amrc-factoryplus/utilities"; -import MQTTClient from "../lib/mqttclient"; -const deviceUUID = process.env.DEVICE_UUID; -const MQTTURL = process.env.MQTT_URL; -const sparkplugAddress = process.env.SPARKPLUG_ADDRESS; -if (!deviceUUID) { - throw new Error("Device UUID not set"); -} -if (!MQTTURL) { - throw new Error("MQTT URL not set"); -} -if (!sparkplugAddress) { - throw new Error("Sparkplug Address not set"); -} -const debug = new Debug(); -const client = await new ServiceClient({ - directory_url: process.env.DIRECTORY_URL, - root_principal: process.env.ROOT_PRINCIPAL, -}).init(); -const mqtt = await new MQTTClient({ - e: { - serviceClient: client, - deviceUUID: deviceUUID, - url: MQTTURL, - sparkplugAddress: sparkplugAddress - } -}).init(); -mqtt.run(); diff --git a/uns-ingester-sparkplug/lib/mqttclient.js b/uns-ingester-sparkplug/lib/mqttclient.js deleted file mode 100644 index 30be1af7..00000000 --- a/uns-ingester-sparkplug/lib/mqttclient.js +++ /dev/null @@ -1,182 +0,0 @@ -import { Address, Debug, MetricBuilder, SpB, Topic } from "@amrc-factoryplus/utilities"; -const debug = new Debug(); -export default class MQTTClient { - serviceClient; - deviceUUID; - url; - address; - seq; - mqtt; - constructor({ e }) { - this.serviceClient = e.serviceClient; - this.deviceUUID = e.deviceUUID; - this.url = e.url; - this.address = Address.parse(e.sparkplugAddress); - this.seq = 0; - } - async init() { - return this; - } - will() { - const nDeath = { - timestamp: Date.now(), - metrics: MetricBuilder.death.node([]), - }; - // @ts-ignore - const will = SpB.encodePayload(nDeath); - return { - topic: this.address.topic("DEATH"), - payload: will, - qos: 0, - retain: false, - }; - } - async run() { - const mqtt = await this.serviceClient.mqtt_client({ - verbose: true, - // @ts-ignore - will: this.will(), - }); - this.mqtt = mqtt; - mqtt.on("gssconnect", this.on_connect.bind(this)); - mqtt.on("error", this.on_error.bind(this)); - mqtt.on("message", this.on_message.bind(this)); - // We subscribe to the whole Sparkplug namespace - mqtt.subscribe('spBv1.0/#'); - } - // encode_metrics(metrics, with_uuid) { - // const payload = { - // timestamp: Date.now(), - // metrics: metrics, - // seq: this.seq, - // }; - // this.seq = (this.seq < 255) ? (this.seq + 1) : 0; - // if (with_uuid) - // payload.uuid = UUIDs.FactoryPlus; - // - // return SpB.encodePayload(payload); - // } - // publish(kind, metrics, with_uuid) { - // if (!this.mqtt) { - // debug.log("mqtt", "Can't publish without an MQTT connection."); - // return; - // } - // - // const topic = this.address.topic(kind); - // const payload = this.encode_metrics(metrics, with_uuid); - // - // this.mqtt.publish(topic, payload); - // } - on_connect() { - debug.log("mqtt", "Connected to MQTT broker."); - // this.rebirth(); - } - // rebirth() { - // - // this.seq = 0; - // const Birth = MetricBuilder.birth; - // const metrics = Birth.node([]); - // //Birth.command_escalation(metrics); - // metrics.push.apply(metrics, [ - // {name: "Device_Information/Manufacturer", type: "String", value: Device_Info.Manufacturer}, - // {name: "Device_Information/Model", type: "String", value: Device_Info.Model}, - // {name: "Device_Information/Serial", type: "String", value: Device_Info.Serial}, - // - // {name: "Schema_UUID", type: "UUID", value: Schema.Service}, - // {name: "Instance_UUID", type: "UUID", value: this.device_uuid}, - // {name: "Service_UUID", type: "UUID", value: Service.Registry}, - // {name: "Service_URL", type: "String", value: this.url}, - // ]); - // metrics.push.apply(metrics, - // Object.values(Changed).map(v => - // ({name: `Last_Changed/${v}`, type: "UUID", value: ""}))); - // - // debug.log("mqtt", `Publishing birth certificate`); - // this.publish("BIRTH", metrics, true); - // } - // publish_changed(changes) { - // const metrics = []; - // for (let [to, uuid] of Object.entries(changes)) { - // if (!(to in Changed)) - // continue; - // metrics.push({ - // name: `Last_Changed/${Changed[to]}`, - // type: "UUID", - // value: uuid, - // }); - // } - // this.publish("DATA", metrics); - // } - on_error(error) { - debug.log("mqtt", "MQTT error: %o", error); - } - async on_message(topicString, message) { - let topic = Topic.parse(topicString); - if (!topic) { - debug.log("mqtt", `Bad topic: ${topicString}`); - return; - } - let address = topic.address; - let payload; - try { - // @ts-ignore - payload = SpB.decodePayload(message); - } - catch { - debug.log("mqtt", `Bad payload on topic ${topicString}`); - return; - } - switch (topic.type) { - case "BIRTH": - //await this.on_birth(address, payload); - break; - case "DEATH": - //await this.on_death(address, payload); - break; - case "DATA": - await this.on_data(address, payload); - break; - case "CMD": - await this.on_command(address, payload); - break; - default: - debug.log("mqtt", `Unknown Sparkplug message type ${topic.type}!`); - } - } - async on_data(addr, payload) { - if (!payload.metrics) { - debug.log("mqtt", `Received DATA with no metrics!`); - return; - } - // for (let m of payload.metrics) { - // switch (m.name) { - // // case "Node Control/Rebirth": - // // await this.rebirth(); - // // break; - // default: - // debug.log("mqtt", `Received unknown CMD: ${m.name}`); - // /* Ignore for now */ - // } - // } - } - async on_command(addr, payload) { - if (!addr.equals(this.address)) { - //console.log(`Received CMD for ${addr}`); - return; - } - if (!payload.metrics) { - debug.log("mqtt", `Received CMD with no metrics!`); - return; - } - for (let m of payload.metrics) { - switch (m.name) { - // case "Node Control/Rebirth": - // await this.rebirth(); - // break; - default: - debug.log("mqtt", `Received unknown CMD: ${m.name}`); - /* Ignore for now */ - } - } - } -} From 01ce6baf3dd6b626b31117c07054dd8455de6072 Mon Sep 17 00:00:00 2001 From: D J Newbould <132448197+djnewbould@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:01:05 +0100 Subject: [PATCH 47/58] Removed overwriting env variables --- historian-uns/src/app.ts | 12 +----------- uns-ingester-sparkplug/bin/ingester.ts | 12 +----------- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/historian-uns/src/app.ts b/historian-uns/src/app.ts index edcb6cc4..2cf99cd4 100644 --- a/historian-uns/src/app.ts +++ b/historian-uns/src/app.ts @@ -25,7 +25,7 @@ if (!directoryUrl) { } export const logger = pino({ - name: 'ACS UNS Ingester', + name: 'ACS Historian UNS', level: process.env.LOG_LEVEL || 'info', }, stream); @@ -34,16 +34,6 @@ const client = await new ServiceClient({ env: process.env }).init(); -// Overwrite MQTT server if specified in environment -if (process.env.MQTT_URL) { - client.Discovery.set_service_url(UUIDs.Service.MQTT, process.env.MQTT_URL); -} - -// Overwrite Command Escalation server if specified in environment -if (process.env.CMD_ESC_URL) { - client.Discovery.set_service_url(UUIDs.Service.Command_Escalation, process.env.CMD_ESC_URL); -} - // Well known UUID for MQTT Component service function (see: https://factoryplus.app.amrc.co.uk/docs/framework-components/core-components/mqtt) logger.info(client.service_urls('feb27ba3-bd2c-4916-9269-79a61ebc4a47')); diff --git a/uns-ingester-sparkplug/bin/ingester.ts b/uns-ingester-sparkplug/bin/ingester.ts index 5d84024b..8c7bbcf8 100644 --- a/uns-ingester-sparkplug/bin/ingester.ts +++ b/uns-ingester-sparkplug/bin/ingester.ts @@ -26,7 +26,7 @@ if (!directoryUrl) { } export const logger = pino({ - name: 'ACS UNS Ingester', + name: 'ACS UNS Ingester Sparkplug', level: process.env.LOG_LEVEL || 'info', }, stream); @@ -35,16 +35,6 @@ const client = await new ServiceClient({ env: process.env }).init(); -// Overwrite MQTT server if specified in environment -if (process.env.MQTT_URL) { - client.Discovery.set_service_url(UUIDs.Service.MQTT, process.env.MQTT_URL); -} - -// Overwrite Command Escalation server if specified in environment -if (process.env.CMD_ESC_URL) { - client.Discovery.set_service_url(UUIDs.Service.Command_Escalation, process.env.CMD_ESC_URL); -} - // Well known UUID for MQTT Component service function (see: https://factoryplus.app.amrc.co.uk/docs/framework-components/core-components/mqtt) logger.info(client.service_urls('feb27ba3-bd2c-4916-9269-79a61ebc4a47')); From d5f92b67e8784d1b1925b149facbcb2c591f4df8 Mon Sep 17 00:00:00 2001 From: D J Newbould <132448197+djnewbould@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:01:32 +0100 Subject: [PATCH 48/58] implemented correct rebirth method --- uns-ingester-sparkplug/lib/mqttclient.ts | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/uns-ingester-sparkplug/lib/mqttclient.ts b/uns-ingester-sparkplug/lib/mqttclient.ts index 8a5c3e62..914f5922 100644 --- a/uns-ingester-sparkplug/lib/mqttclient.ts +++ b/uns-ingester-sparkplug/lib/mqttclient.ts @@ -334,24 +334,15 @@ export default class MQTTClient { }, Math.floor(Math.random() * (10000 - 5000 + 1) + 5000)); // Request birth certificate - let response = await this.serviceClient.fetch({ - service: UUIDs.Service.Command_Escalation, - url: `/v1/address/${topic.address.group}/${topic.address.node}/${topic.address.device}`, - method: "POST", - headers: { - "content-type": "application/json" - }, - body: JSON.stringify({ - "name": "Device Control/Rebirth", "value": "true" - }) - }) - - logger.info('📣 Birth certificate request sent for %s. Status: %s', topic.address, response.status); - + try { + await this.serviceClient.CmdEsc.rebirth(topic.address); + logger.info(`📣 Birth certificate request sent for ${topic.address}`); + } catch (e) { + logger.error(`🔥 Birth certificate request failed for ${topic.address}. Error: ${e.message}`); + } } break; } - return; } From c5cba598f0ee7d2391baed72f579fbc4dba4f17a Mon Sep 17 00:00:00 2001 From: D J Newbould <132448197+djnewbould@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:52:54 +0100 Subject: [PATCH 49/58] Fixed incorrect logger import --- historian-uns/src/Utils/logger.ts | 2 +- historian-uns/src/app.ts | 15 ++------------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/historian-uns/src/Utils/logger.ts b/historian-uns/src/Utils/logger.ts index 7ae2176e..bbb891c5 100644 --- a/historian-uns/src/Utils/logger.ts +++ b/historian-uns/src/Utils/logger.ts @@ -14,6 +14,6 @@ const stream = pretty({ dotenv?.config(); export const logger = pino({ - name: 'InfluxDB Sparkplug Ingester', + name: 'ACS Historian UNS', level: process.env.LOG_LEVEL || 'info', }, stream); \ No newline at end of file diff --git a/historian-uns/src/app.ts b/historian-uns/src/app.ts index 2cf99cd4..0194c2f8 100644 --- a/historian-uns/src/app.ts +++ b/historian-uns/src/app.ts @@ -2,10 +2,9 @@ * AMRC InfluxDB UNS Historian * Copyright "2023" AMRC */ -import {ServiceClient, UUIDs} from "@amrc-factoryplus/service-client"; +import {ServiceClient} from "@amrc-factoryplus/service-client"; import MQTTClient from "./mqttclient.js"; -import pretty from "pino-pretty"; -import pino from "pino"; +import {logger} from "./Utils/logger.js"; let dotenv: any = null; try { @@ -13,10 +12,6 @@ try { } catch (e) { } -const stream = pretty({ - colorize: true -}) - dotenv?.config(); const directoryUrl = process.env.DIRECTORY_URL; @@ -24,12 +19,6 @@ if (!directoryUrl) { throw new Error("DIRECTORY_URL environment variable is not set"); } -export const logger = pino({ - name: 'ACS Historian UNS', - level: process.env.LOG_LEVEL || 'info', -}, stream); - - const client = await new ServiceClient({ env: process.env }).init(); From 8a568a62bf063fbbee2720e8c25df17acbd85f1c Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Tue, 17 Sep 2024 11:51:56 +0100 Subject: [PATCH 50/58] Updated upload and download artefacts to v4 --- .github/workflows/publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index bbe1e871..a8abd77e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -350,7 +350,7 @@ jobs: build_version=${{ env.BUILD_PHP_VERSION }} - name: Upload Backend - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: ${{ steps.prepare.outputs.version }}-backend path: /tmp/image.tar @@ -385,7 +385,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: Download artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ steps.prepare.outputs.version }}-backend path: /tmp From 4912e812402b4274e35896eb3d13feb707277d66 Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Mon, 23 Sep 2024 13:07:15 +0100 Subject: [PATCH 51/58] Added missing uns and ingester group creation --- acs-service-setup/dumps/uns.yaml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/acs-service-setup/dumps/uns.yaml b/acs-service-setup/dumps/uns.yaml index fbcd887b..c6b87953 100644 --- a/acs-service-setup/dumps/uns.yaml +++ b/acs-service-setup/dumps/uns.yaml @@ -10,18 +10,22 @@ objects: !u ACS.Class.Permission: - !u ACS.Perm.MQTT.WriteToEntireUNS - !u ACS.Perm.MQTT.ReadEntireUNS + !u ACS.Class.UserGroup: + - !u ACS.Group.SparkplugIngesters + - !u ACS.Group.HistorianUNS configs: !u UUIDs.App.Info: !u ACS.Perm.MQTT.WriteToEntireUNS: { name: "MQTT: Write to entire UNS" } !u ACS.Perm.MQTT.ReadEntireUNS: { name: "MQTT: Read entire UNS" } - !u ACS.ServiceAccount.SparkplugIngester: { name: "Ingester (Sparkplug)" } - !u ACS.ServiceAccount.HistorianUNS: { name: "Historian (UNS)" } !u UUIDs.App.MQTTPermissionTemplate: !u ACS.Perm.MQTT.WriteToEntireUNS: "UNS/v1/#: w" !u ACS.Perm.MQTT.ReadEntireUNS: "UNS/v1/#: rs" --- service: !u UUIDs.Service.Authentication version: 1 +groups: + !u ACS.Group.GlobalDebuggers: + - !u ACS.Group.SparkplugIngesters aces: - principal: !u ACS.Group.HistorianUNS permission: !u ACS.Perm.MQTT.ReadEntireUNS @@ -29,6 +33,3 @@ aces: - principal: !u ACS.Group.SparkplugIngesters permission: !u ACS.Perm.MQTT.WriteToEntireUNS target: !u UUIDs.Special.Self -groups: - !u ACS.Group.GlobalDebuggers: - - !u ACS.Group.SparkplugIngesters From 8527d0700887d423c14429aaaa107fb64ee1eea2 Mon Sep 17 00:00:00 2001 From: D J Newbould Date: Mon, 23 Sep 2024 13:19:25 +0100 Subject: [PATCH 52/58] Added group name config --- acs-service-setup/dumps/uns.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/acs-service-setup/dumps/uns.yaml b/acs-service-setup/dumps/uns.yaml index c6b87953..e1969454 100644 --- a/acs-service-setup/dumps/uns.yaml +++ b/acs-service-setup/dumps/uns.yaml @@ -17,6 +17,8 @@ configs: !u UUIDs.App.Info: !u ACS.Perm.MQTT.WriteToEntireUNS: { name: "MQTT: Write to entire UNS" } !u ACS.Perm.MQTT.ReadEntireUNS: { name: "MQTT: Read entire UNS" } + !u ACS.Group.SparkplugIngesters: { name: "Sparkplug Ingesters" } + !u ACS.Group.HistorianUNS: { name: "Historian UNS" } !u UUIDs.App.MQTTPermissionTemplate: !u ACS.Perm.MQTT.WriteToEntireUNS: "UNS/v1/#: w" !u ACS.Perm.MQTT.ReadEntireUNS: "UNS/v1/#: rs" From 4affbd949174829a2a90b0b5e97c93b44e7f8b23 Mon Sep 17 00:00:00 2001 From: D J Newbould <132448197+djnewbould@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:44:56 +0100 Subject: [PATCH 53/58] Changed uns historian to be disabled by default --- deploy/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/values.yaml b/deploy/values.yaml index e5d0a41b..9cbe6691 100644 --- a/deploy/values.yaml +++ b/deploy/values.yaml @@ -217,7 +217,7 @@ cmdesc: historians: uns: - enabled: true + enabled: false # -- The minimum log level that the historian will log messages at (One of 'fatal', 'error', 'warn', 'info', 'debug', 'trace' or 'silent'.) logLevel: info # -- The number of messages to batch together before sending to InfluxDB From b847b1ccd6b847b6a4e9866b06d5a4ed3596218b Mon Sep 17 00:00:00 2001 From: D J Newbould <132448197+djnewbould@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:45:39 +0100 Subject: [PATCH 54/58] Removed redundant sparkplug properties --- deploy/templates/auth/principals/service-clients.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/deploy/templates/auth/principals/service-clients.yaml b/deploy/templates/auth/principals/service-clients.yaml index 888ee720..beb9a7d9 100644 --- a/deploy/templates/auth/principals/service-clients.yaml +++ b/deploy/templates/auth/principals/service-clients.yaml @@ -138,9 +138,6 @@ spec: name: Sparkplug Ingester groups: - e414d355-b991-429b-8f5d-97e823ff71f5 - sparkplug: - group: {{ .Values.acs.organisation }}-Service-Core - node: SparkplugIngester {{- end }} --- @@ -161,8 +158,5 @@ spec: name: Historian UNS groups: - 03f5f08a-f61e-4134-8f66-b2951e3bbb69 - sparkplug: - group: {{ .Values.acs.organisation }}-Service-Core - node: HistorianUNS {{- end }} From a81141bc741c2b98135b1e1622858a98659d9241 Mon Sep 17 00:00:00 2001 From: D J Newbould <132448197+djnewbould@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:46:08 +0100 Subject: [PATCH 55/58] Removed redundant service account UUIDs --- acs-service-setup/lib/uuids.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/acs-service-setup/lib/uuids.js b/acs-service-setup/lib/uuids.js index 56ee4fd9..34553dfe 100644 --- a/acs-service-setup/lib/uuids.js +++ b/acs-service-setup/lib/uuids.js @@ -57,10 +57,7 @@ export const ACS = { Service: { Manager: "619eecab-742d-4824-8b97-bcae472e5c04", }, - ServiceAccount: { - SparkplugIngester: "e5939141-a3d5-4ab8-b609-b450ca785d7c", - HistorianUNS: "b6d0cb6a-708b-424f-a062-8c30e4b2fc4c", - }, + ServiceAccount: {}, Role: { EdgeNodeConsumer: "17a64293-b82d-4db4-af4d-63359bb62934", GlobalDebugger: "4473fe9c-05b0-42cc-ad8c-8e05f6d0ca86", From a271083623ee477b3e612fdcaabe70c4ccd59122 Mon Sep 17 00:00:00 2001 From: D J Newbould <132448197+djnewbould@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:46:51 +0100 Subject: [PATCH 56/58] Fixed incorrect uns mqtt permission values --- acs-service-setup/dumps/uns.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/acs-service-setup/dumps/uns.yaml b/acs-service-setup/dumps/uns.yaml index e1969454..513563e3 100644 --- a/acs-service-setup/dumps/uns.yaml +++ b/acs-service-setup/dumps/uns.yaml @@ -20,8 +20,10 @@ configs: !u ACS.Group.SparkplugIngesters: { name: "Sparkplug Ingesters" } !u ACS.Group.HistorianUNS: { name: "Historian UNS" } !u UUIDs.App.MQTTPermissionTemplate: - !u ACS.Perm.MQTT.WriteToEntireUNS: "UNS/v1/#: w" - !u ACS.Perm.MQTT.ReadEntireUNS: "UNS/v1/#: rs" + !u ACS.Perm.MQTT.WriteToEntireUNS: + UNS/v1/#: w + !u ACS.Perm.MQTT.ReadEntireUNS: + UNS/v1/#: rs --- service: !u UUIDs.Service.Authentication version: 1 From a71191eb0c0bace2d96894667c1d6656c4cf6b0d Mon Sep 17 00:00:00 2001 From: D J Newbould <132448197+djnewbould@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:52:02 +0100 Subject: [PATCH 57/58] decoupled historian uns from sparkplug ingester --- deploy/templates/auth/principals/service-clients.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/templates/auth/principals/service-clients.yaml b/deploy/templates/auth/principals/service-clients.yaml index beb9a7d9..5d012503 100644 --- a/deploy/templates/auth/principals/service-clients.yaml +++ b/deploy/templates/auth/principals/service-clients.yaml @@ -143,7 +143,7 @@ spec: --- # In the future if we have any more ingesters then this should be # enabled if any of the ingesters are enabled. -{{- if .Values.unsIngesters.sparkplug.enabled }} +{{- if .Values.historians.uns.enabled }} apiVersion: factoryplus.app.amrc.co.uk/v1 kind: KerberosKey metadata: From 04694712014bf1a57c12bf54197d7f8ced80ef0f Mon Sep 17 00:00:00 2001 From: Alex Godbehere Date: Mon, 14 Oct 2024 09:24:25 +0100 Subject: [PATCH 58/58] Update release notes for v3.4.0 Add details on Unified Namespace (UNS) and historian changes. Explain the introduction of UNS, changes to Sparkplug ingester, and provide instructions to enable or disable historians. --- ReleaseNotes.md | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 470cde1c..83bf5894 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -8,12 +8,23 @@ chronological order. These changes have not been released yet, but are likely to appear in the next release. -### Historian value changes -With the introduction of the UNS ingesters, the historian (formerly -the `sparkplug-influxdb-ingester`) has been renamed to support the -concept of multiple historians. Therefore, the `warehouse.ingester` -values have relocated to the `historians.sparkplug` key. Make sure -to update your values file accordingly. +## v3.4.0 + +### Unified Namespace & Historian +This release of ACS enables a true Unified Namespace (UNS). The UNS is a +single point of truth for all data collected by ACS in human-readable +format. The UNS is "fed" by ingesters, which take channels of data (in +this case, Sparkplug), and publishes the human-readable content to +`UNS/v1`. In the future additional ingesters may be added to ACS. + +In addition to the Sparkplug ingester, this release features a UNS +historian, which persists the UNS data to the same InfluxDB +database used by the legacy Sparkplug historian. **By default, the +UNS historian is disabled** in an effort to minimise the impact of +this change on existing installations. To enable the UNS historian, +set the `historians.uns.enabled` environment variable to `true`. If +you only want to exclusively persist UNS data (and not legacy +Sparkplug data) then set `historians.sparkplug.enabled` to `false`. ## v3.1.0