From 97cb8516c33dcf431b7851cd0dcf99c05eee6e2a Mon Sep 17 00:00:00 2001 From: boa604 Date: Thu, 15 Jan 2026 14:59:20 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D0=BD=D0=B8=D1=86=D0=B8=D0=B0=D0=BB?= =?UTF-8?q?=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B2=D0=B5=D1=82=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20node=20=D1=81=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D0=B8?= =?UTF-8?q?=2014=20=D0=BD=D0=B0=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8E=202?= =?UTF-8?q?2,=20=D0=B0=20=D1=82=D0=B0=D0=BA=D0=B6=D0=B5=20=D0=B8=D1=81?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D1=83=D0=B5=D0=BC=D1=8B=D1=85=20?= =?UTF-8?q?=D1=81=D0=B5=D1=80=D0=B2=D0=B5=D1=80=D0=BE=D0=BC=20=D0=B1=D0=B8?= =?UTF-8?q?=D0=B1=D0=BB=D0=B8=D0=BE=D1=82=D0=B5=D0=BA.=20=D0=94=D0=BE?= =?UTF-8?q?=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BC=D0=BE?= =?UTF-8?q?=D0=B4=D1=83=D0=BB=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B?= =?UTF-8?q?=20=D1=81=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=B0=D0=BC?= =?UTF-8?q?=D0=B8,=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B8=20=D0=BA=D0=BB=D0=BE=D0=BD=D0=B8=D1=80=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B8=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D1=85,=20=D0=BE=D1=82=D0=BA=D0=B0=D0=B7=20=D0=BE?= =?UTF-8?q?=D1=82=20module-alias=20=D0=B8=20lodash?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.js | 18 +- core/constants.js | 16 +- core/db_connector.js | 51 +- core/http_client.js | 236 ++ core/in_queue.js | 130 +- core/kafka_connector.js | 94 +- core/logger.js | 18 +- core/mqtt_connector.js | 43 +- core/notifier.js | 31 +- core/out_queue.js | 19 +- core/out_queue_processor.js | 48 +- core/service_available_controller.js | 21 +- core/utils.js | 152 +- index.js | 7 +- models/obj_config.js | 289 ++- modules/diadoc.js | 98 +- modules/parus_oracle_db.js | 19 + modules/pws.js | 25 +- modules/sbis.js | 13 +- package-lock.json | 3036 ++++++++------------------ package.json | 20 +- 21 files changed, 1923 insertions(+), 2461 deletions(-) create mode 100644 core/http_client.js diff --git a/config.js b/config.js index 7bd3b7a..79bf37f 100644 --- a/config.js +++ b/config.js @@ -7,6 +7,16 @@ // Тело модуля //------------ +//Переменные окружения +/* + Только для СУБД Oracle. + 1. NODE_ORACLE_DB_THIN_MODE - Установите значение "1", чтобы использовать режим "тонкого клиента" (Thin-режим) + при подключении к БД (не требует установки Oracle Client). + 2. ORACLE_CLIENT_LIB_DIR - Путь к директории с библиотеками Oracle Client, + используется только для работы в режиме "толстого клиента" (Thick-режим), если значение не указано, + то будет использоваться значение из переменной операционной системы PATH. +*/ + //Общие параметры let common = { //Наименование сервера приложений @@ -14,7 +24,7 @@ let common = { //Версия сервера приложений sVersion: "8.5.6.1", //Релиз сервера приложений - sRelease: "2025.11.06", + sRelease: "2025.12.24", //Таймаут останова сервера (мс) nTerminateTimeout: 60000, //Контролировать версию Системы @@ -94,6 +104,8 @@ const kafka = [ nMaxRetryTime: 20000, //Время ожидания между попытками переподключения (мс) nInitialRetryTime: 10000, + //Уровень протоколирования подключения (NOTHING - ничего, ERROR - ошибки, WARN - предупреждения, INFO - общая информация) + sLogLevel: "NOTHING", //Использовать аутентификацию по SSL-сертификату bAuthSSL: false, //Параметры аутентификации по SSL-сертификату @@ -122,7 +134,9 @@ const mqtt = [ //Время ожидания успешного подключения (мс) nConnectTimeout: 5000, //Время ожидания между попытками переподключения (мс) - nReconnectPeriod: 10000 + nReconnectPeriod: 10000, + //Уровень протоколирования подключения (NOTHING - ничего, ERROR - ошибки, INFO - общая информация) + sLogLevel: "NOTHING" } ]; diff --git a/core/constants.js b/core/constants.js index 421d22e..02e7e0e 100644 --- a/core/constants.js +++ b/core/constants.js @@ -8,9 +8,9 @@ //----------------- //Путь к модулям -exports.SMODULES_PATH_CORE = "@core"; //Модули ядра -exports.SMODULES_PATH_MODULES = "@modules"; //Дополнительные пользовательские модули -exports.SMODULES_PATH_MODELS = "@models"; //Модели данных и схемы валидации +exports.SMODULES_PATH_CORE = "."; //Модули ядра +exports.SMODULES_PATH_MODULES = "../modules"; //Дополнительные пользовательские модули +exports.SMODULES_PATH_MODELS = "../models"; //Модели данных и схемы валидации //Типовые коды ошибок exports.SERR_COMMON = "ERR_COMMON"; //Общая ошибка @@ -38,6 +38,16 @@ exports.SERR_APP_SERVER_BEFORE = "ERR_APP_SERVER_BEFORE"; //Ошибка пре exports.SERR_APP_SERVER_AFTER = "ERR_APP_SERVER_AFTER"; //Ошибка постобработчика exports.SERR_DB_SERVER = "ERR_DB_SERVER"; //Ошибка обработчика сервера БД +//Типовые коды ошибок брокера сообщений Kafka +exports.SERR_KAFKA_GROUP_UNAVAILABLE = "ERR_KAFKA_GROUP_UNAVAILABLE"; //Группа получателя недоступна +exports.SERR_KAFKA = "ERR_KAFKA"; //Ошибка +exports.SWARN_KAFKA = "WARN_KAFKA"; //Предупреждение +exports.SINFO_KAFKA = "INFO_KAFKA"; //Информация + +//Типовые коды MQTT +exports.SERR_MQTT = "ERR_MQTT"; //Ошибка +exports.SINFO_MQTT = "INFO_MQTT"; //Предупреждение + //Шаблоны подсветки консольных сообщений протокола работы exports.SCONSOLE_LOG_COLOR_PATTERN_ERR = "\x1b[31m%s\x1b[0m%s"; //Цвет для ошибок exports.SCONSOLE_LOG_COLOR_PATTERN_WRN = "\x1b[33m%s\x1b[0m%s"; //Цвет для предупреждений diff --git a/core/db_connector.js b/core/db_connector.js index 789c38c..4e4c806 100644 --- a/core/db_connector.js +++ b/core/db_connector.js @@ -7,10 +7,9 @@ // Подключение библиотек //---------------------- -const _ = require("lodash"); //Работа с массивами и объектами const EventEmitter = require("events"); //Обработчик пользовательских событий const { ServerError } = require("./server_errors"); //Типовая ошибка -const { makeModuleFullPath, validateObject } = require("./utils"); //Вспомогательные функции +const { makeModuleFullPath, validateObject, deepClone } = require("./utils"); //Вспомогательные функции const prmsDBConnectorSchema = require("../models/prms_db_connector"); //Схемы валидации параметров функций модуля const intfDBConnectorModuleSchema = require("../models/intf_db_connector_module"); //Схема валидации интерфейса модуля взаимодействия с БД const objServiceSchema = require("../models/obj_service"); //Схема валидации сервиса @@ -69,7 +68,7 @@ class DBConnector extends EventEmitter { throw new ServerError(SERR_MODULES_BAD_INTERFACE, sCheckResult); } //Всё успешно - сохраним настройки подключения - this.connectSettings = _.cloneDeep(prms.connectSettings); + this.connectSettings = deepClone(prms.connectSettings); //Инициализируем остальные свойства this.connection = null; this.bConnected = false; @@ -176,7 +175,7 @@ class DBConnector extends EventEmitter { //Забираем для каждого из сервисов список его функций let srvsFuncs = srvs.map(async srv => { const response = await this.getServiceFunctions({ nServiceId: srv.nId }); - let tmp = _.cloneDeep(srv); + let tmp = deepClone(srv); response.forEach(f => { tmp.functions.push(f); }); @@ -211,7 +210,7 @@ class DBConnector extends EventEmitter { if (!sCheckResult) { try { //Подготовим параметры для передачи в БД - let getServiceFunctionsData = _.cloneDeep(prms); + let getServiceFunctionsData = deepClone(prms); getServiceFunctionsData.connection = this.connection; //И выполним считывание функций сервиса let res = await this.connector.getServiceFunctions(getServiceFunctionsData); @@ -240,7 +239,7 @@ class DBConnector extends EventEmitter { if (!sCheckResult) { try { //Подготовим параметры для передачи в БД - let getServiceContextData = _.cloneDeep(prms); + let getServiceContextData = deepClone(prms); getServiceContextData.connection = this.connection; //И выполним считывание контекста сервиса let res = await this.connector.getServiceContext(getServiceContextData); @@ -269,7 +268,7 @@ class DBConnector extends EventEmitter { if (!sCheckResult) { try { //Подготовим параметры для передачи в БД - let setServiceContextData = _.cloneDeep(prms); + let setServiceContextData = deepClone(prms); setServiceContextData.connection = this.connection; //И выполним установку контекста сервиса await this.connector.setServiceContext(setServiceContextData); @@ -295,7 +294,7 @@ class DBConnector extends EventEmitter { if (!sCheckResult) { try { //Подготовим параметры для передачи в БД - let clearServiceContextData = _.cloneDeep(prms); + let clearServiceContextData = deepClone(prms); clearServiceContextData.connection = this.connection; //И выполним очистку контекста сервиса await this.connector.clearServiceContext(clearServiceContextData); @@ -321,7 +320,7 @@ class DBConnector extends EventEmitter { if (!sCheckResult) { try { //Подготовим параметры для передачи в БД - let isServiceAuthData = _.cloneDeep(prms); + let isServiceAuthData = deepClone(prms); isServiceAuthData.connection = this.connection; //И выполним проверку атентифицированности сервиса let res = await this.connector.isServiceAuth(isServiceAuthData); @@ -354,7 +353,7 @@ class DBConnector extends EventEmitter { if (!sCheckResult) { try { //Подготовим параметры для передачи в БД - let putServiceAuthInQueueData = _.cloneDeep(prms); + let putServiceAuthInQueueData = deepClone(prms); putServiceAuthInQueueData.connection = this.connection; //И выполним постановку в очередь задания на аутентификацию сервиса await this.connector.putServiceAuthInQueue(putServiceAuthInQueueData); @@ -384,7 +383,7 @@ class DBConnector extends EventEmitter { if (!sCheckResult) { try { //Подготовим параметры для передачи в БД - let getServiceExpiredQueueInfoData = _.cloneDeep(prms); + let getServiceExpiredQueueInfoData = deepClone(prms); getServiceExpiredQueueInfoData.connection = this.connection; //И выполним получение информации о просроченных сообщениях let res = await this.connector.getServiceExpiredQueueInfo(getServiceExpiredQueueInfoData); @@ -413,7 +412,7 @@ class DBConnector extends EventEmitter { if (!sCheckResult) { try { //Подготовим параметры для передачи в БД - let logData = _.cloneDeep(prms); + let logData = deepClone(prms); logData.connection = this.connection; logData.nExsSrv = this.nExsSrv; //И выполним запись в журнал @@ -436,7 +435,7 @@ class DBConnector extends EventEmitter { //Запись информации в журнал работы async putLogInf(sMsg, prms) { //Подготовим параметры для передачи в БД - let logData = _.cloneDeep(prms); + let logData = deepClone(prms); //Выставим сообщение и тип записи журнала logData.nLogState = objLogSchema.NLOG_STATE_INF; logData.sMsg = sMsg; @@ -452,7 +451,7 @@ class DBConnector extends EventEmitter { //Запись предупреждения в журнал работы async putLogWrn(sMsg, prms) { //Подготовим параметры для передачи в БД - let logData = _.cloneDeep(prms); + let logData = deepClone(prms); //Выставим сообщение и тип записи журнала logData.nLogState = objLogSchema.NLOG_STATE_WRN; logData.sMsg = sMsg; @@ -468,7 +467,7 @@ class DBConnector extends EventEmitter { //Запись ошибки в журнал работы async putLogErr(sMsg, prms) { //Подготовим параметры для передачи в БД - let logData = _.cloneDeep(prms); + let logData = deepClone(prms); //Выставим сообщение и тип записи журнала logData.nLogState = objLogSchema.NLOG_STATE_ERR; logData.sMsg = sMsg; @@ -489,7 +488,7 @@ class DBConnector extends EventEmitter { //Если структура объекта в норме if (!sCheckResult) { //Подготовим параметры - let getQueueData = _.cloneDeep(prms); + let getQueueData = deepClone(prms); getQueueData.connection = this.connection; try { //Исполняем действие в БД @@ -518,7 +517,7 @@ class DBConnector extends EventEmitter { //Если структура объекта в норме if (!sCheckResult) { //Подготовим параметры - let putQueueData = _.cloneDeep(prms); + let putQueueData = deepClone(prms); putQueueData.blMsg = prms.blMsg ? prms.blMsg : Buffer.from(""); putQueueData.connection = this.connection; //Исполняем действие в БД @@ -549,7 +548,7 @@ class DBConnector extends EventEmitter { if (!sCheckResult) { try { //Подготовим параметры для передачи в БД - let getQueueOutgoingData = _.cloneDeep(prms); + let getQueueOutgoingData = deepClone(prms); getQueueOutgoingData.connection = this.connection; getQueueOutgoingData.nExsSrv = this.nExsSrv; //Выполняем считывание из БД @@ -577,7 +576,7 @@ class DBConnector extends EventEmitter { //Если структура объекта в норме if (!sCheckResult) { //Подготовим параметры - let setStateData = _.cloneDeep(prms); + let setStateData = deepClone(prms); setStateData.connection = this.connection; try { //Исполняем действие в БД @@ -610,7 +609,7 @@ class DBConnector extends EventEmitter { //Если структура объекта в норме if (!sCheckResult) { //Подготовим параметры - let getQueueMsgData = _.cloneDeep(prms); + let getQueueMsgData = deepClone(prms); getQueueMsgData.connection = this.connection; //Исполняем действие в БД try { @@ -643,7 +642,7 @@ class DBConnector extends EventEmitter { //Если структура объекта в норме if (!sCheckResult) { //Подготовим параметры - let setQueueMsgData = _.cloneDeep(prms); + let setQueueMsgData = deepClone(prms); if (!setQueueMsgData.blMsg) setQueueMsgData.blMsg = Buffer.from(""); setQueueMsgData.connection = this.connection; //Исполняем действие в БД @@ -677,7 +676,7 @@ class DBConnector extends EventEmitter { //Если структура объекта в норме if (!sCheckResult) { //Подготовим параметры - let setQueueOptionsData = _.cloneDeep(prms); + let setQueueOptionsData = deepClone(prms); setQueueOptionsData.connection = this.connection; //Исполняем действие в БД try { @@ -710,7 +709,7 @@ class DBConnector extends EventEmitter { //Если структура объекта в норме if (!sCheckResult) { //Подготовим параметры - let getQueueRespData = _.cloneDeep(prms); + let getQueueRespData = deepClone(prms); getQueueRespData.connection = this.connection; //Исполняем действие в БД try { @@ -743,7 +742,7 @@ class DBConnector extends EventEmitter { //Если структура объекта в норме if (!sCheckResult) { //Подготовим параметры - let setQueueRespData = _.cloneDeep(prms); + let setQueueRespData = deepClone(prms); if (!setQueueRespData.blResp) setQueueRespData.blResp = Buffer.from(""); setQueueRespData.connection = this.connection; //Исполняем действие в БД @@ -777,7 +776,7 @@ class DBConnector extends EventEmitter { //Если структура объекта в норме if (!sCheckResult) { //Подготовим параметры - let setQueueOptionsRespData = _.cloneDeep(prms); + let setQueueOptionsRespData = deepClone(prms); setQueueOptionsRespData.connection = this.connection; //Исполняем действие в БД try { @@ -835,7 +834,7 @@ class DBConnector extends EventEmitter { //Исполняем действие в БД try { //Подготовим параметры для передачи в БД - let execQueuePrcData = _.cloneDeep(prms); + let execQueuePrcData = deepClone(prms); execQueuePrcData.connection = this.connection; //И выполним обработчик со стороны БД let res = await this.connector.execQueuePrc(execQueuePrcData); diff --git a/core/http_client.js b/core/http_client.js new file mode 100644 index 0000000..acc1825 --- /dev/null +++ b/core/http_client.js @@ -0,0 +1,236 @@ +/* + Сервис интеграции ПП Парус 8 с WEB API + Модуль ядра: работа с HTTP/HTTPS запросами +*/ + +//------------------------------ +// Подключение внешних библиотек +//------------------------------ + +const { URL } = require("url"); + +//-------------------------- +// Локальные идентификаторы +//-------------------------- + +const DEFAULT_TIMEOUT = 30000; //Таймаут по умолчанию + +//Выполнение HTTP/HTTPS запроса +const httpRequest = async (rawOptions = {}) => { + try { + //Нормализуем параметры запроса + const options = normalizeOptions(rawOptions); + //Сформируем ссылку + const url = buildURL(options.url, options.query); + //Подготовим заголовки и тело запроса + const headers = prepareHeaders(options.headers); + const { body, contentLength, isStream } = prepareBody({ + body: options.body, + json: options.json, + headers + }); + //Если не указан размер тела + if (contentLength !== undefined && !headers.has("content-length")) { + //Установим размер тела в заголовок + headers.set("content-length", String(contentLength)); + } + //Выполним запрос с использованием fetch + return httpRequestFetch({ options, url, headers, body, isStream }); + } catch (e) { + throw e; + } +}; + +//Ошибка HTTP-запроса +class HttpError extends Error { + constructor(message, response) { + super(message); + this.name = "HttpError"; + this.response = response; + } +} + +//Выполнение запроса с использованием fetch +const httpRequestFetch = async ({ options, url, headers, body, isStream }) => { + try { + const fetchImpl = globalThis.fetch; + if (typeof fetchImpl !== "function") { + throw new Error("globalThis.fetch недоступен. Используйте Node.js >= 18."); + } + + let requestBody = body; + if (isStream && body && typeof body.pipe === "function") { + const chunks = []; + try { + for await (const chunk of body) { + chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)); + } + requestBody = chunks.length > 0 ? Buffer.concat(chunks) : undefined; + } catch (streamError) { + throw new Error(`Ошибка чтения потока: ${streamError.message}`); + } + } + + const timeoutController = new AbortController(); + const signals = []; + + if (options.signal && options.signal instanceof AbortSignal) { + signals.push(options.signal); + } + signals.push(timeoutController.signal); + + const combinedSignal = AbortSignal.any(signals); + + const timeoutId = + options.timeout > 0 + ? setTimeout( + () => timeoutController.abort(new Error(`Время ожидания выполнения запроса истекло после ${options.timeout} мс`)), + options.timeout + ) + : null; + + try { + const fetchOptions = { + method: options.method, + headers: Object.fromEntries(headers), + body: requestBody, + signal: combinedSignal, + redirect: options.followRedirects ? "follow" : "manual" + }; + + if (options.proxy || options.ca || options.cert || options.key || options.passphrase || options.rejectUnauthorized === false) { + const { Agent, ProxyAgent } = require("undici"); + const connectOptions = { + rejectUnauthorized: options.rejectUnauthorized !== undefined ? options.rejectUnauthorized : true + }; + + if (options.ca) { + connectOptions.ca = Array.isArray(options.ca) ? options.ca : [options.ca]; + } + if (options.cert) { + connectOptions.cert = options.cert; + } + if (options.key) { + connectOptions.key = options.key; + } + if (options.passphrase) { + connectOptions.passphrase = options.passphrase; + } + + if (options.proxy) { + const proxyUrl = new URL(options.proxy); + if (proxyUrl.protocol !== "http:" && proxyUrl.protocol !== "https:") { + throw new Error("Поддерживаются только HTTP/HTTPS-прокси (protocol=http|https)."); + } + const proxyAuth = + proxyUrl.username || proxyUrl.password + ? `Basic ${Buffer.from(`${decodeURIComponent(proxyUrl.username)}:${decodeURIComponent(proxyUrl.password)}`).toString( + "base64" + )}` + : null; + fetchOptions.dispatcher = new ProxyAgent({ + uri: options.proxy, + token: proxyAuth, + connect: connectOptions + }); + } else { + fetchOptions.dispatcher = new Agent({ + connect: connectOptions + }); + } + } + + const response = await fetchImpl(url.toString(), fetchOptions); + const responseBody = Buffer.from(await response.arrayBuffer()); + const result = { + statusCode: response.status, + headers: Object.fromEntries(response.headers.entries()), + body: responseBody, + ok: response.ok, + url: response.url + }; + + if (options.throwOnErrorStatus && !result.ok) { + throw new HttpError(`Запрос не выполнен со статусом ${result.statusCode}`, result); + } + + return result; + } finally { + if (timeoutId) clearTimeout(timeoutId); + } + } catch (e) { + throw e; + } +}; + +//Нормализация параметров запроса +const normalizeOptions = options => { + if (!options || typeof options !== "object") { + throw new TypeError("options должен быть объектом"); + } + if (!options.url) throw new Error("options.url обязателен"); + return { + method: (options.method || "GET").toUpperCase(), + url: options.url, + headers: options.headers || {}, + query: options.query || options.qs || {}, + body: options.body, + json: options.json, + timeout: options.timeout ?? DEFAULT_TIMEOUT, + followRedirects: options.followRedirects ?? false, + proxy: options.proxy || null, + ca: options.ca, + cert: options.cert, + key: options.key, + passphrase: options.passphrase, + rejectUnauthorized: options.rejectUnauthorized !== undefined ? options.rejectUnauthorized : true, + throwOnErrorStatus: options.throwOnErrorStatus ?? false, + signal: options.signal || null + }; +}; + +//Формирование ссылки +const buildURL = (base, query = {}) => { + const url = new URL(base); + Object.entries(query).forEach(([key, value]) => { + if (value === undefined || value === null) return; + url.searchParams.append(key, String(value)); + }); + return url; +}; + +//Подготовка заголовков запроса +const prepareHeaders = (inputHeaders = {}) => { + const headers = new Map(); + Object.entries(inputHeaders).forEach(([key, value]) => { + if (value === undefined || value === null) return; + headers.set(String(key).toLowerCase(), String(value)); + }); + return headers; +}; + +//Подготовка тела запроса +const prepareBody = ({ body, json, headers }) => { + if (json !== undefined) { + const payload = Buffer.from(JSON.stringify(json)); + if (!headers.has("content-type")) headers.set("content-type", "application/json; charset=utf-8"); + return { body: payload, contentLength: payload.length, isStream: false }; + } + if (body === undefined || body === null) return { body: undefined, contentLength: undefined, isStream: false }; + if (Buffer.isBuffer(body) || body instanceof Uint8Array) { + return { body, contentLength: body.length, isStream: false }; + } + if (typeof body === "string") { + const payload = Buffer.from(body); + return { body: payload, contentLength: payload.length, isStream: false }; + } + if (typeof body.pipe === "function") { + return { body, contentLength: undefined, isStream: true }; + } + const payload = Buffer.from(JSON.stringify(body)); + if (!headers.has("content-type")) headers.set("content-type", "application/json; charset=utf-8"); + return { body: payload, contentLength: payload.length, isStream: false }; +}; + +exports.httpRequest = httpRequest; +exports.HttpError = HttpError; diff --git a/core/in_queue.js b/core/in_queue.js index 90a93f5..379e46a 100644 --- a/core/in_queue.js +++ b/core/in_queue.js @@ -7,11 +7,9 @@ // Подключение внешних библиотек //------------------------------ -const _ = require("lodash"); //Работа с массивами и коллекциями const EventEmitter = require("events"); //Обработчик пользовательских событий const express = require("express"); //WEB-сервер Express const cors = require("cors"); //Управление заголовками безопасности для WEB-сервера Express -const bodyParser = require("body-parser"); //Модуль для Express (разбор тела входящего запроса) const { ServerError } = require("./server_errors"); //Типовая ошибка const { makeErrorText, @@ -23,6 +21,7 @@ const { deepMerge, deepCopyObject, isUndefined, + deepClone, getKafkaConnectionSettings, getMQTTConnectionSettings, getURLProtocol @@ -67,13 +66,13 @@ class InQueue extends EventEmitter { //Если структура объекта в норме if (!sCheckResult) { //Общие параметры сервера приложений - this.common = _.cloneDeep(prms.common); + this.common = deepClone(prms.common); //Список обслуживаемых сервисов this.services = null; //Признак функционирования обработчика this.bWorking = false; //Параметры очереди - this.inComing = _.cloneDeep(prms.inComing); + this.inComing = deepClone(prms.inComing); //Запомним подключение к БД this.dbConn = prms.dbConn; //Запомним логгер @@ -82,8 +81,8 @@ class InQueue extends EventEmitter { this.notifier = prms.notifier; //WEB-приложение this.webApp = express(); + // Глобально разрешаем CORS для всех маршрутов и методов. this.webApp.use(cors()); - this.webApp.options("*", cors()); //WEB-сервер this.srv = null; //Параметры подключения к Kafka @@ -130,16 +129,16 @@ class InQueue extends EventEmitter { prms.function.nFnPrmsType ) ) { - blMsg = prms.req.body && !_.isEmpty(prms.req.body) ? prms.req.body : null; + blMsg = prms.req.body && !(Object.keys(prms.req.body ?? {}).length === 0) ? Buffer.from(JSON.stringify(prms.req.body)) : null; } else { //Для GET, HEAD, DELETE, CONNECT, OPTIONS и TRACE - параметры запроса - if (!_.isEmpty(prms.req.query)) blMsg = Buffer.from(JSON.stringify(prms.req.query)); + if (!(Object.keys(prms.req.query ?? {}).length === 0)) blMsg = Buffer.from(JSON.stringify(prms.req.query)); } //Определимся с параметрами сообщения полученными от внешней системы options = { method: prms.req.method, - qs: _.cloneDeep(prms.req.query), - headers: _.cloneDeep(prms.req.headers), + qs: deepClone(prms.req.query), + headers: deepClone(prms.req.headers), ip: prms.req.ip, hostName: prms.req.hostname, protocol: prms.req.protocol, @@ -152,8 +151,6 @@ class InQueue extends EventEmitter { sOptions: buildOptionsXML({ options }), blMsg }); - //Запомним идентификатор записи очереди в запросе - prms.req.nQId = q.nId; //Скажем что пришло новое входящее сообщение await this.logger.info( `Новое входящее сообщение от ${prms.req.connection.address().address} для функции ${prms.function.sCode} (${buildURL({ @@ -173,11 +170,11 @@ class InQueue extends EventEmitter { const fnBefore = getAppSrvFunction(prms.function.sAppSrvBefore); let resBefore = null; try { - let resBeforePrms = _.cloneDeep(prms); - resBeforePrms.queue = _.cloneDeep(q); + let resBeforePrms = deepClone(prms); + resBeforePrms.queue = deepClone(q); resBeforePrms.queue.blMsg = blMsg; resBeforePrms.queue.blResp = blResp; - resBeforePrms.options = _.cloneDeep(options); + resBeforePrms.options = deepClone(options); resBeforePrms.dbConn = this.dbConn; resBeforePrms.notifier = this.notifier; resBeforePrms.res = prms.res; @@ -200,7 +197,7 @@ class InQueue extends EventEmitter { nExecState: objQueueSchema.NQUEUE_EXEC_STATE_APP_OK }); //Фиксируем результат исполнения "До" - обработанный запрос внешней системы - if (!_.isUndefined(resBefore.blMsg)) { + if (resBefore.blMsg !== undefined) { blMsg = resBefore.blMsg; q = await this.dbConn.setQueueMsg({ nQueueId: q.nId, @@ -208,7 +205,7 @@ class InQueue extends EventEmitter { }); } //Фиксируем результат исполнения "До" - ответ на запрос - if (!_.isUndefined(resBefore.blResp)) { + if (resBefore.blResp !== undefined) { blResp = resBefore.blResp; q = await this.dbConn.setQueueResp({ nQueueId: q.nId, @@ -217,16 +214,16 @@ class InQueue extends EventEmitter { }); } //Фиксируем результат исполнения "До" - параметры ответа на запрос - if (!_.isUndefined(resBefore.optionsResp)) { + if (resBefore.optionsResp !== undefined) { optionsResp = deepMerge(optionsResp, resBefore.optionsResp); let sOptionsResp = buildOptionsXML({ options: optionsResp }); q = await this.dbConn.setQueueOptionsResp({ nQueueId: q.nId, sOptionsResp }); } //Фиксируем результат исполнения "До" - флаг ошибочной аутентификации - если он поднят, то это ошибка, дальше ничего не делаем - if (!_.isUndefined(resBefore.bUnAuth) && resBefore.bUnAuth === true) + if (resBefore.bUnAuth !== undefined && resBefore.bUnAuth === true) throw new ServerError(SERR_UNAUTH, "Нет аутентификации"); //Фиксируем результат исполнения "До" - флаг прекращения дальнейшей обработки сообщения - если он поднят, то дальше обработку сообщения прекращаем - if (!_.isUndefined(resBefore.bStopPropagation) && resBefore.bStopPropagation === true) bStopPropagation = true; + if (resBefore.bStopPropagation !== undefined && resBefore.bStopPropagation === true) bStopPropagation = true; } else { //Или расскажем об ошибке throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult); @@ -281,12 +278,12 @@ class InQueue extends EventEmitter { const fnAfter = getAppSrvFunction(prms.function.sAppSrvAfter); let resAfter = null; try { - let resAfterPrms = _.cloneDeep(prms); - resAfterPrms.queue = _.cloneDeep(q); + let resAfterPrms = deepClone(prms); + resAfterPrms.queue = deepClone(q); resAfterPrms.queue.blMsg = blMsg; resAfterPrms.queue.blResp = blResp; - resAfterPrms.options = _.cloneDeep(options); - resAfterPrms.optionsResp = _.cloneDeep(optionsResp); + resAfterPrms.options = deepClone(options); + resAfterPrms.optionsResp = deepClone(optionsResp); resAfterPrms.dbConn = this.dbConn; resAfterPrms.notifier = this.notifier; resAfter = await fnAfter(resAfterPrms); @@ -308,7 +305,7 @@ class InQueue extends EventEmitter { nExecState: objQueueSchema.NQUEUE_EXEC_STATE_APP_OK }); //Фиксируем результат исполнения "После" - ответ системы - if (!_.isUndefined(resAfter.blResp)) { + if (resAfter.blResp !== undefined) { blResp = resAfter.blResp; q = await this.dbConn.setQueueResp({ nQueueId: q.nId, @@ -317,13 +314,13 @@ class InQueue extends EventEmitter { }); } //Фиксируем результат исполнения "После" - параметры ответа на запрос - if (!_.isUndefined(resAfter.optionsResp)) { + if (resAfter.optionsResp !== undefined) { optionsResp = deepMerge(optionsResp, resAfter.optionsResp); let sOptionsResp = buildOptionsXML({ options: optionsResp }); q = await this.dbConn.setQueueOptionsResp({ nQueueId: q.nId, sOptionsResp }); } //Если пришел флаг ошибочной аутентификации и он положительный - то это ошибка, дальше ничего не делаем - if (!_.isUndefined(resAfter.bUnAuth)) + if (resAfter.bUnAuth !== undefined) if (resAfter.bUnAuth === true) throw new ServerError(SERR_UNAUTH, "Нет аутентификации"); } else { //Или расскажем об ошибке @@ -331,19 +328,13 @@ class InQueue extends EventEmitter { } } } - //Всё успешно - отдаём результат клиенту, если ещё не отдали - if (bStopPropagation === false && !prms.res.writableFinished) { - if (optionsResp.headers) prms.res.set(optionsResp.headers); - prms.res.status(optionsResp.statusCode || 200).send(blResp); - } - //Если отправка ответа была прервана по таймауту - if (prms.req.bIsTimedOut === true) { - //Вернем ошибку обработчика с информацией об этом - throw new ServerError( - SERR_WEB_SERVER, - "Истекло время ожидания обработки входящего запроса. Канал закрыт. Клиенту был отправлен ответ с ошибкой истечения таймаута (504)." - ); - } else { + //Если мы еще не отдали ответ от сервера + if (!prms.res.writableFinished) { + //Всё успешно - отдаём результат клиенту + if (bStopPropagation === false) { + if (optionsResp.headers) prms.res.set(optionsResp.headers); + prms.res.status(optionsResp.statusCode || 200).send(blResp); + } //Фиксируем успех обработки - в протоколе работы сервиса await this.logger.info(`Входящее сообщение ${q.nId} успешно отработано`, { nQueueId: q.nId }); //Фиксируем успех обработки - в статусе сообщения @@ -352,6 +343,12 @@ class InQueue extends EventEmitter { nIncExecCnt: NINC_EXEC_CNT_YES, nExecState: objQueueSchema.NQUEUE_EXEC_STATE_OK }); + } else { + //Или расскажем об ошибке + throw new ServerError( + SERR_WEB_SERVER, + "Истекло время ожидания обработки входящего запроса. Канал закрыт. Клиенту был отправлен ответ." + ); } } catch (e) { //Тема и текст уведомления об ошибке @@ -557,35 +554,34 @@ class InQueue extends EventEmitter { if (req.headers["content-type"] === "false") req.headers["content-type"] = "application/octet-stream"; next(); }); - //Конфигурируем сервер - устанавливаем таймаут обработки сообщений - this.webApp.use((req, res, next) => { - //Поднимем флаг истечения таймаута обработки - req.bIsTimedOut = false; - //Если требуется установить таймаут на обработку сообщений - if (this.inComing.nTimeout !== 0) + //Если требуется установить таймаут на обработку сообщений + if (this.inComing.nTimeout !== 0) { + //Конфигурируем сервер - устанавливаем таймаут обработки сообщений + this.webApp.use((req, res, next) => { //Устанавливаем таймаут на ответ от сервера res.setTimeout(this.inComing.nTimeout, () => { - //Поднимем флаг исчетечение таймаута обработки - req.bIsTimedOut = true; //Формируем ошибку let err = new Error("Истекло время ожидания формирования ответа для завершения текущего запроса."); err.status = 504; //Отправляем ошибку next(err); }); - next(); - }); + next(); + }); + } //Конфигурируем сервер - обработка тела сообщения - this.webApp.use(bodyParser.raw({ limit: `${this.inComing.nMsgMaxSize}mb`, type: "*/*" })); + this.webApp.use(express.json()); + this.webApp.use(express.urlencoded({ extended: true })); + this.webApp.use(express.raw({ limit: `${this.inComing.nMsgMaxSize}mb`, type: "*/*" })); //Конфигурируем сервер - обходим все сервисы, работающие на приём сообщений - _.forEach( - _.filter(this.services, srv => { + this.services + .filter(srv => { return ( srv.nSrvType === objServiceSchema.NSRV_TYPE_RECIVE && [objServiceSchema.SPROTOCOL_HTTP, objServiceSchema.SPROTOCOL_HTTPS].includes(getURLProtocol(srv.sSrvRoot)) ); - }), - srvs => { + }) + .forEach(srvs => { //Для любых запросов к корневому адресу сервиса - ответ о том, что это за сервис, и что он работает this.webApp.all(srvs.sSrvRoot, (req, res) => { res.status(200).send( @@ -593,19 +589,18 @@ class InQueue extends EventEmitter { ); }); //Для всех статических функций сервиса... - _.forEach( - _.filter(srvs.functions, fn => fn.sFnURL.startsWith("@")), - fn => { + srvs.functions + .filter(fn => fn.sFnURL.startsWith("@")) + .forEach(fn => { this.webApp.use( buildURL({ sSrvRoot: srvs.sSrvRoot, sFnURL: fn.sFnURL.substr(1) }), express.static(`${this.inComing.sStaticDir}/${fn.sFnURL.substr(1)}`) ); - } - ); + }); //Для всех функций сервиса (кроме статических)... - _.forEach( - _.filter(srvs.functions, fn => !fn.sFnURL.startsWith("@")), - fn => { + srvs.functions + .filter(fn => !fn.sFnURL.startsWith("@")) + .forEach(fn => { //...собственный обработчик, в зависимости от указанного способа передачи параметров this.webApp[fn.sFnPrmsType.toLowerCase()](buildURL({ sSrvRoot: srvs.sSrvRoot, sFnURL: fn.sFnURL }), async (req, res) => { try { @@ -629,16 +624,13 @@ class InQueue extends EventEmitter { //Протоколируем в журнал работы сервера await this.logger.error(makeErrorText(new ServerError(SERR_WEB_SERVER, err.message)), { nServiceId: srvs.nId, - nServiceFnId: fn.nId, - nQueueId: req.nQId || null + nServiceFnId: fn.nId }); //Отправим ошибку клиенту res.status(err.status || 500).send(makeErrorText(new ServerError(SERR_WEB_SERVER, err.message))); }); - } - ); - } - ); + }); + }); //Инициализируем настройки подключения let connectionSettings = null; //Считываем прием сообщений по Kafka @@ -713,7 +705,7 @@ class InQueue extends EventEmitter { } } //Запросы на адреса, не входящие в состав объявленных сервисов - 404 NOT FOUND - this.webApp.use("*", (req, res) => { + this.webApp.use((req, res) => { res.status(404).send( `

Сервер приложений ПП Парус 8
(${this.common.sVersion} релиз ${this.common.sRelease})

Запрошенный адрес не найден

` ); diff --git a/core/kafka_connector.js b/core/kafka_connector.js index 1ba72a0..990b8e6 100644 --- a/core/kafka_connector.js +++ b/core/kafka_connector.js @@ -9,19 +9,82 @@ const { makeErrorText, getKafkaBroker, getKafkaAuth } = require("./utils"); //Вспомогательные функции const { Kafka, Partitioners, logLevel } = require("kafkajs"); //Работа с Kafka +const { SERR_KAFKA_GROUP_UNAVAILABLE, SERR_KAFKA, SWARN_KAFKA, SINFO_KAFKA } = require("./constants"); //Глобальные константы +const { ServerError } = require("./server_errors"); //Типовая ошибка + +//---------- +// Константы +//---------- + +//Общие константы работы Kafka +const NCHECK_GROUP_RETRIES = 1; //Количество попыток подключения для проверки доступности группы + +//-------------------------- +// Вспомогательные функции +//-------------------------- + +//Проверка доступности группы +const checkGroupAvailable = async (clientProps, groupId) => { + //Иницализируем подключение к Kafka + let client = new Kafka({ + ...clientProps, + retry: { retries: NCHECK_GROUP_RETRIES } + }); + //Инициализируем доступ к командам + const admin = client.admin(); + //Подключаемся + await admin.connect(); + //Считываем информацию о группе + const groupInfo = await admin.describeGroups([groupId]); + //Отключаемся + await admin.disconnect(); + //Если в данной группе есть участники + if (groupInfo?.groups[0]?.members && groupInfo.groups[0].members.length !== 0) { + //Сообщаем о невозможности запустить сервис + throw new ServerError(SERR_KAFKA_GROUP_UNAVAILABLE, `${SERR_KAFKA}: Группа получателя "${groupId}" активна.`); + } +}; + +//Логгер для вывода внутренних сообщений Kafka в общий поток +const KafkaLogger = selfLogger => { + return level => { + return async ({ log }) => { + //Считываем текст сообщения и доп. информацию + const { message, ...logFullInfo } = log; + //Убираем лишнюю информацию из доп. информации + const { stack, timestamp, logger, ...logInfo } = logFullInfo; + //Исходим от уровня ошибки + switch (level) { + //Ошибка + case logLevel.ERROR: + await selfLogger.error(`${SERR_KAFKA}: ${message} ${JSON.stringify(logInfo)}`); + break; + //Предупреждение + case logLevel.WARN: + await selfLogger.warn(`${SWARN_KAFKA}: ${message} ${JSON.stringify(logInfo)}`); + break; + //Информация + case logLevel.INFO: + await selfLogger.info(`${SINFO_KAFKA}: ${message} ${JSON.stringify(logInfo)}`); + break; + } + }; + }; +}; //------------ // Тело модуля //------------ //Отправка сообщения Kafka -const publishKafka = async ({ settings, url, auth, topic, message }) => { +const publishKafka = async ({ settings, url, auth, topic, message, logger }) => { //Иницализируем подключение к Kafka let kafka = new Kafka({ clientId: settings.sClientIdSender, brokers: [url], connectionTimeout: settings.nConnectionTimeout, - logLevel: logLevel.NOTHING, + logLevel: logLevel[settings.sLogLevel] || logLevel.NOTHING, + logCreator: KafkaLogger(logger), ...auth }); //Инициализируем продюсера @@ -43,13 +106,20 @@ const subscribeKafka = async ({ settings, service, processMessage, logger }) => let bLogLostConnection = true; //Получаем брокера по URL сервиса let sBroker = getKafkaBroker(service.sSrvRoot); - //Иницализируем подключение к Kafka - let client = new Kafka({ + //Формируем свойства подключения к Kafka + let clientProps = { clientId: settings.sClientIdRecipient, brokers: [sBroker], connectionTimeout: settings.nConnectionTimeout, ...getKafkaAuth(service.sSrvUser, service.sSrvPass, settings), - logLevel: logLevel.NOTHING, + logLevel: logLevel[settings.sLogLevel] || logLevel.NOTHING, + logCreator: KafkaLogger(logger) + }; + //Проверка доступности группы + await checkGroupAvailable(clientProps, settings.sGroupId); + //Иницализируем подключение к Kafka + let client = new Kafka({ + ...clientProps, retry: { retries: 0, maxRetryTime: settings.nMaxRetryTime, @@ -59,7 +129,7 @@ const subscribeKafka = async ({ settings, service, processMessage, logger }) => //Если требуется вывести ошибку if (bLogLostConnection) { //Выводим ошибку - logger.error(`Соединение с Kafka потеряно (${sBroker}): ${makeErrorText(error)}`); + logger.error(`${SERR_KAFKA}: Соединение потеряно (${sBroker}): ${makeErrorText(error)}`); //Сбрасываем признак необходимости вывода ошибки bLogLostConnection = false; } @@ -90,7 +160,7 @@ const subscribeKafka = async ({ settings, service, processMessage, logger }) => }) }); } catch (e) { - await logger.error(`Ошибка обработки входящего сообщения Kafka: ${makeErrorText(e)}`); + await logger.error(`${SERR_KAFKA}: Ошибка обработки входящего сообщения: ${makeErrorText(e)}`); } } }); @@ -99,7 +169,7 @@ const subscribeKafka = async ({ settings, service, processMessage, logger }) => //Если сообщение о потере соединения уже выводилось if (!bLogLostConnection) { //Сообщим о восстановлении соединения - logger.info(`Соединение с Kafka восстановлено (${sBroker})`); + logger.info(`${SINFO_KAFKA}: Соединение восстановлено (${sBroker})`); //Устанавливаем признак сообщения о потере соединения bLogLostConnection = true; } @@ -107,7 +177,13 @@ const subscribeKafka = async ({ settings, service, processMessage, logger }) => //Возвращаем соединение return consumer; } catch (e) { - await logger.error(`Ошибка запуска обработчика очереди входящих сообщений Kafka: ${makeErrorText(e)}`); + //Если это фатальная ошибка - выдаем её + if (e.sCode === SERR_KAFKA_GROUP_UNAVAILABLE) { + throw new ServerError(e.sCode, e.sMessage); + } else { + //Если ошибка не фатальная - выводим информацию + await logger.error(`${SERR_KAFKA}: Ошибка запуска обработчика очереди входящих сообщений: ${makeErrorText(e)}`); + } } }; diff --git a/core/logger.js b/core/logger.js index c963cba..e836bc9 100644 --- a/core/logger.js +++ b/core/logger.js @@ -7,14 +7,9 @@ // Подключение библиотек //---------------------- -const _ = require("lodash"); //Работа с массивами и объектами -const { validateObject, getNowString } = require("./utils"); //Вспомогательные функции +const { validateObject, getNowString, deepClone } = require("./utils"); //Вспомогательные функции const db = require("./db_connector"); //Модуль взаимодействия с БД -const { - SCONSOLE_LOG_COLOR_PATTERN_ERR, - SCONSOLE_LOG_COLOR_PATTERN_WRN, - SCONSOLE_LOG_COLOR_PATTERN_INF -} = require("./constants"); //Общие константы +const { SCONSOLE_LOG_COLOR_PATTERN_ERR, SCONSOLE_LOG_COLOR_PATTERN_WRN, SCONSOLE_LOG_COLOR_PATTERN_INF } = require("./constants"); //Общие константы const { NLOG_STATE_INF, NLOG_STATE_WRN, NLOG_STATE_ERR } = require("../models/obj_log"); //Схемы валидации записи журнала работы сервиса обмена const prmsLoggerSchema = require("../models/prms_logger"); //Схемы валидации параметров функций модуля @@ -97,8 +92,7 @@ class Logger { //Протоколирование ошибки async error(sMsg, prms) { //Подготовим параметры для протоколирования - let logData = {}; - if (prms) logData = _.cloneDeep(prms); + let logData = prms ? deepClone(prms) : {}; //Выставим сообщение и тип записи журнала logData.nLogState = NLOG_STATE_ERR; logData.sMsg = sMsg; @@ -108,8 +102,7 @@ class Logger { //Протоколирование предупреждения async warn(sMsg, prms) { //Подготовим параметры для протоколирования - let logData = {}; - if (prms) logData = _.cloneDeep(prms); + let logData = prms ? deepClone(prms) : {}; //Выставим сообщение и тип записи журнала logData.nLogState = NLOG_STATE_WRN; logData.sMsg = sMsg; @@ -119,8 +112,7 @@ class Logger { //Протоколирование информации async info(sMsg, prms) { //Подготовим параметры для протоколирования - let logData = {}; - if (prms) logData = _.cloneDeep(prms); + let logData = prms ? deepClone(prms) : {}; //Выставим сообщение и тип записи журнала logData.nLogState = NLOG_STATE_INF; logData.sMsg = sMsg; diff --git a/core/mqtt_connector.js b/core/mqtt_connector.js index e0af9e1..fba3b64 100644 --- a/core/mqtt_connector.js +++ b/core/mqtt_connector.js @@ -9,13 +9,22 @@ const { makeErrorText } = require("./utils"); //Вспомогательные функции const mqtt = require("mqtt"); //Работа с MQTT +const { SERR_MQTT, SINFO_MQTT } = require("./constants"); //Глобальные константы + +//---------- +// Константы +//---------- + +//Общие константы работы MQTT +const SLOG_ERROR = "ERROR"; //Уровень протоколирования - ошибки +const SLOG_INFO = "INFO"; //Уровень протоколирования - информация //------------ // Тело модуля //------------ //Отправка MQTT сообщения -const publishMQTT = async ({ settings, url, auth, topic, message }) => { +const publishMQTT = async ({ settings, url, auth, topic, message, logger }) => { //Инициализируем подключение const client = await mqtt.connectAsync(url, { clientId: settings.sClientIdSender, @@ -25,6 +34,14 @@ const publishMQTT = async ({ settings, url, auth, topic, message }) => { password: auth.pass, reconnectPeriod: settings.nReconnectPeriod }); + //Прослушиваем ошибки + client.on("error", e => { + //Если требуется выдавать ошибку + if ([SLOG_ERROR, SLOG_INFO].includes(settings.sLogLevel)) { + //Выводим ошибку + logger.error(`${SERR_MQTT}: ${makeErrorText(e)}`); + } + }); //Отправляем сообщение await client.publishAsync(topic, message); //Закрываем подключение @@ -64,18 +81,32 @@ const subscribeMQTT = async ({ settings, service, processMessage, logger }) => { }); //Прослушиваем отключение от сервера client.on("offline", () => { - //Выводим ошибку - logger.error(`Соединение с MQTT потеряно (${sBroker})`); + //Если требуется выдавать ошибку + if (settings.sLogLevel === SLOG_INFO) { + //Выводим ошибку + logger.error(`${SERR_MQTT}: Соединение потеряно (${sBroker})`); + } }); //Прослушиваем восстановление соединения client.on("connect", () => { - //Сообщим о восстановлении соединения - logger.info(`Соединение с MQTT восстановлено (${sBroker})`); + //Если требуется выдавать предупреждение + if (settings.sLogLevel === SLOG_INFO) { + //Сообщим о восстановлении соединения + logger.info(`${SINFO_MQTT}: Соединение восстановлено (${sBroker})`); + } + }); + //Прослушиваем ошибки + client.on("error", e => { + //Если требуется выдавать ошибку + if ([SLOG_ERROR, SLOG_INFO].includes(settings.sLogLevel)) { + //Выводим ошибку + logger.error(`${SERR_MQTT}: ${makeErrorText(e)}`); + } }); //Возвращаем подключение return client; } catch (e) { - logger.error(`Ошибка запуска обработчика очереди исходящих сообщений MQTT: ${makeErrorText(e)}`); + logger.error(`${SERR_MQTT}: Ошибка запуска обработчика очереди входящих сообщений: ${makeErrorText(e)}`); } }; diff --git a/core/notifier.js b/core/notifier.js index 30f4060..5d7ca71 100644 --- a/core/notifier.js +++ b/core/notifier.js @@ -7,11 +7,10 @@ // Подключение внешних библиотек //------------------------------ -const _ = require("lodash"); //Работа с массивами и коллекциями const EventEmitter = require("events"); //Обработчик пользовательских событий const { ServerError } = require("./server_errors"); //Типовая ошибка const { SERR_OBJECT_BAD_INTERFACE, SERR_MAIL_FAILED } = require("./constants"); //Общесистемные константы -const { makeErrorText, validateObject, sendMail } = require("./utils"); //Вспомогательные функции +const { makeErrorText, validateObject, sendMail, deepClone } = require("./utils"); //Вспомогательные функции const prmsNotifierSchema = require("../models/prms_notifier"); //Схемы валидации параметров функций класса //-------------------------- @@ -65,21 +64,15 @@ class Notifier extends EventEmitter { //Добавление уведомления в очередь отправки async addMessage(prms) { //Проверяем структуру переданного объекта для старта - let sCheckResult = validateObject( - prms, - prmsNotifierSchema.addMessage, - "Параметры функции добавления уведомления в очередь отправки" - ); + let sCheckResult = validateObject(prms, prmsNotifierSchema.addMessage, "Параметры функции добавления уведомления в очередь отправки"); //Если структура объекта в норме if (!sCheckResult) { - let tmp = _.cloneDeep(prms); + let tmp = deepClone(prms); tmp.bSent = false; this.messages.push(tmp); } else { await this.logger.error( - `Ошибка добавления уведомления в очередь: ${makeErrorText( - new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult) - )}` + `Ошибка добавления уведомления в очередь: ${makeErrorText(new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult))}` ); } } @@ -113,7 +106,13 @@ class Notifier extends EventEmitter { if (!message.bSent) { try { //Если всё в порядке с настройками - if (this.mail.sHost && this.mail.nPort && this.mail.sFrom && this.mail.hasOwnProperty('bSecure') && this.mail.hasOwnProperty('bRejectUnauthorized')) { + if ( + this.mail.sHost && + this.mail.nPort && + this.mail.sFrom && + this.mail.hasOwnProperty("bSecure") && + this.mail.hasOwnProperty("bRejectUnauthorized") + ) { //Отправляем await sendMail({ mail: this.mail, @@ -135,16 +134,12 @@ class Notifier extends EventEmitter { ); } } catch (e) { - await this.logger.error( - `Ошибка отправки сообщения с темой "${message.sSubject}" для ${message.sTo}: ${makeErrorText( - e - )}` - ); + await this.logger.error(`Ошибка отправки сообщения с темой "${message.sSubject}" для ${message.sTo}: ${makeErrorText(e)}`); } } } //Подчищаем очередь - удалим уже отправленные - _.remove(this.messages, { bSent: true }); + this.messages = this.messages.filter(msg => !msg.bSent); //Выставим флаг - цикл опроса неактивен this.bInSendLoop = false; //Перезапускаем опрос diff --git a/core/out_queue.js b/core/out_queue.js index fcab507..53c41a4 100644 --- a/core/out_queue.js +++ b/core/out_queue.js @@ -7,12 +7,11 @@ // Подключение внешних библиотек //------------------------------ -const _ = require("lodash"); //Работа с массивами и коллекциями const EventEmitter = require("events"); //Обработчик пользовательских событий const ChildProcess = require("child_process"); //Работа с дочерними процессами const { ServerError } = require("./server_errors"); //Типовая ошибка const { SERR_OBJECT_BAD_INTERFACE } = require("./constants"); //Общесистемные константы -const { makeErrorText, validateObject } = require("./utils"); //Вспомогательные функции +const { makeErrorText, validateObject, deepClone } = require("./utils"); //Вспомогательные функции const { NINC_EXEC_CNT_YES, NINC_EXEC_CNT_NO } = require("../models/prms_db_connector"); //Схемы валидации параметров функций модуля взаимодействия с БД const objOutQueueProcessorSchema = require("../models/obj_out_queue_processor"); //Схемы валидации сообщений обмена с обработчиком сообщения очереди const { NFORCE_YES } = require("../models/common"); //Общие константы и схемы валидации @@ -53,7 +52,7 @@ class OutQueue extends EventEmitter { //Признак функционирования обработчика this.bWorking = false; //Параметры очереди - this.outGoing = _.cloneDeep(prms.outGoing); + this.outGoing = deepClone(prms.outGoing); //Количество доступных обработчиков this.nWorkersLeft = this.outGoing.nMaxWorkers; //Идентификатор таймера проверки очереди @@ -150,6 +149,8 @@ class OutQueue extends EventEmitter { if (!sCheckResult) { //Добавляем идентификатор позиции очереди в список обрабатываемых this.addInProgress({ nQueueId: prms.queue.nId }); + //Найдем сервис + const service = this.services.find(s => s.nId === prms.queue.nServiceId); //Отдаём команду дочернему процессу обработчика на старт исполнения prms.proc.send({ nQueueId: prms.queue.nId, @@ -159,10 +160,8 @@ class OutQueue extends EventEmitter { nPoolMax: this.outGoing.nPoolMax, nPoolIncrement: this.outGoing.nPoolIncrement }, - service: _.find(this.services, { nId: prms.queue.nServiceId }), - function: _.find(_.find(this.services, { nId: prms.queue.nServiceId }).functions, { - nId: prms.queue.nServiceFnId - }), + service: service, + function: service?.functions.find(f => f.nId === prms.queue.nServiceFnId), sProxy: this.sProxy, kafka: this.kafka, mqtt: this.mqtt @@ -201,10 +200,8 @@ class OutQueue extends EventEmitter { //Если структура объекта в норме if (!sCheckResult) { //Найдем сервис и функцию, исполнявшие данное сообщение - let service = _.find(this.services, { nId: prms.queue.nServiceId }); - let func = _.find(_.find(this.services, { nId: prms.queue.nServiceId }).functions, { - nId: prms.queue.nServiceFnId - }); + let service = this.services.find(s => s.nId === prms.queue.nServiceId); + let func = service?.functions.find(f => f.nId === prms.queue.nServiceFnId); //Если нашли и для функции-обработчика указан признак необходимости оповещения об ошибках if (service && func && func.nErrNtfSign == objServiceFnSchema.NERR_NTF_SIGN_YES) //Отправим уведомление об ошибке отработки в почту diff --git a/core/out_queue_processor.js b/core/out_queue_processor.js index 3583925..9c80c39 100644 --- a/core/out_queue_processor.js +++ b/core/out_queue_processor.js @@ -7,9 +7,7 @@ // Подключение библиотек //---------------------- -require("module-alias/register"); //Поддержка псевонимов при подключении модулей -const _ = require("lodash"); //Работа с массивами и объектами -const rqp = require("request-promise"); //Работа с HTTP/HTTPS запросами +const { httpRequest } = require("./http_client"); //Работа с HTTP/HTTPS запросами const lg = require("./logger"); //Протоколирование работы const db = require("./db_connector"); //Взаимодействие с БД const { @@ -20,6 +18,7 @@ const { parseOptionsXML, buildOptionsXML, deepMerge, + deepClone, getKafkaConnectionSettings, getMQTTConnectionSettings, getKafkaBroker, @@ -137,9 +136,9 @@ const appProcess = async prms => { //Флаг установленности контекста для функции начала сеанса let bCtxIsSet = false; //Кладём данные тела в объект сообщения и инициализируем поле для ответа - _.extend(prms.queue, { blMsg: qData.blMsg, blResp: null }); + Object.assign(prms.queue, { blMsg: qData.blMsg, blResp: null }); //Кладём данные контекста в сервис - _.extend(prms.service, serviceCtx); + Object.assign(prms.service, serviceCtx); //Собираем параметры для передачи серверу let options = { method: prms.function.sFnPrmsType, encoding: null }; //Инициализируем параметры ответа сервера @@ -238,8 +237,8 @@ const appProcess = async prms => { const fnBefore = getAppSrvFunction(prms.function.sAppSrvBefore); let resBefore = null; try { - let resBeforePrms = _.cloneDeep(prms); - resBeforePrms.options = _.cloneDeep(options); + let resBeforePrms = deepClone(prms); + resBeforePrms.options = deepClone(options); resBeforePrms.dbConn = dbConn; resBefore = await fnBefore(resBeforePrms); } catch (e) { @@ -255,7 +254,7 @@ const appProcess = async prms => { //Если структура ответа в норме if (!sCheckResult) { //Применим ответ "До" - обработанное сообщение очереди - if (!_.isUndefined(resBefore.blMsg)) { + if (resBefore.blMsg !== undefined) { prms.queue.blMsg = resBefore.blMsg; await dbConn.setQueueMsg({ nQueueId: prms.queue.nId, @@ -281,14 +280,14 @@ const appProcess = async prms => { } } //Применим ответ "До" - параметры отправки сообщения удаленному серверу - if (!_.isUndefined(resBefore.options)) options = deepMerge(options, resBefore.options); + if (resBefore.options !== undefined) options = deepMerge(options, resBefore.options); //Применим ответ "До" - флаг отсуствия аутентификации - if (!_.isUndefined(resBefore.bUnAuth)) + if (resBefore.bUnAuth !== undefined) if (resBefore.bUnAuth === true) { throw new ServerError(SERR_UNAUTH, "Нет аутентификации"); } //Применим ответ "До" - контекст работы сервиса - if (!_.isUndefined(resBefore.sCtx)) + if (resBefore.sCtx !== undefined) if (prms.function.nFnType == objServiceFnSchema.NFN_TYPE_LOGIN) { prms.service.sCtx = resBefore.sCtx; prms.service.dCtxExp = resBefore.dCtxExp; @@ -300,7 +299,7 @@ const appProcess = async prms => { bCtxIsSet = true; } //Применим ответ "До" - флаг прекращения дальнейшей обработки сообщения - если он поднят, то дальше обработку сообщения прекращаем - if (!_.isUndefined(resBefore.bStopPropagation) && resBefore.bStopPropagation === true) bStopPropagation = true; + if (resBefore.bStopPropagation !== undefined && resBefore.bStopPropagation === true) bStopPropagation = true; } else { //Или расскажем об ошибке в структуре ответа throw new ServerError(SERR_OBJECT_BAD_INTERFACE, sCheckResult); @@ -317,7 +316,7 @@ const appProcess = async prms => { try { //Сохраняем параметры с которыми уходило сообщение try { - let tmpOptions = _.cloneDeep(options); + let tmpOptions = deepClone(options); //Исключим из параметров заведомо бинарные поля (их сохранение не предусмотрено) delete tmpOptions.body; delete tmpOptions.cert; @@ -364,8 +363,13 @@ const appProcess = async prms => { if (prms.function.nTimeoutConn && !options.timeout) options.timeout = prms.function.nTimeoutConn; //Отправляем запрос serverResp = prms.function.nTimeoutAsynch - ? await wrapPromiseTimeout(prms.function.nTimeoutAsynch, rqp(options)) - : await rqp(options); + ? await wrapPromiseTimeout(prms.function.nTimeoutAsynch, signal => + httpRequest({ + ...options, + signal + }) + ) + : await httpRequest(options); break; } //Сохраняем полученный ответ @@ -376,7 +380,7 @@ const appProcess = async prms => { nIsOriginal: NIS_ORIGINAL_YES }); //Сохраняем заголовки ответа и HTTP-статус - optionsResp.headers = _.cloneDeep(serverResp.headers); + optionsResp.headers = deepClone(serverResp.headers); optionsResp.statusCode = serverResp.statusCode; try { let sOptionsResp = buildOptionsXML({ options: optionsResp }); @@ -401,9 +405,9 @@ const appProcess = async prms => { const fnAfter = getAppSrvFunction(prms.function.sAppSrvAfter); let resAfter = null; try { - let resAfterPrms = _.cloneDeep(prms); - resAfterPrms.options = _.cloneDeep(options); - resAfterPrms.optionsResp = _.cloneDeep(optionsResp); + let resAfterPrms = deepClone(prms); + resAfterPrms.options = deepClone(options); + resAfterPrms.optionsResp = deepClone(optionsResp); resAfter = await fnAfter(resAfterPrms); } catch (e) { throw new ServerError(SERR_APP_SERVER_AFTER, e.message); @@ -418,7 +422,7 @@ const appProcess = async prms => { //Если структура ответа в норме if (!sCheckResult) { //Применим ответ "После" - обработанный ответ удаленного сервиса - if (!_.isUndefined(resAfter.blResp)) { + if (resAfter.blResp !== undefined) { prms.queue.blResp = resAfter.blResp; await dbConn.setQueueResp({ nQueueId: prms.queue.nId, @@ -427,10 +431,10 @@ const appProcess = async prms => { }); } //Применим ответ "После" - флаг утентификации сервиса - if (!_.isUndefined(resAfter.bUnAuth)) + if (resAfter.bUnAuth !== undefined) if (resAfter.bUnAuth === true) throw new ServerError(SERR_UNAUTH, "Нет аутентификации"); //Применим ответ "После" - контекст работы сервиса - if (!_.isUndefined(resAfter.sCtx)) + if (resAfter.sCtx !== undefined) if (prms.function.nFnType == objServiceFnSchema.NFN_TYPE_LOGIN) { prms.service.sCtx = resAfter.sCtx; prms.service.dCtxExp = resAfter.dCtxExp; diff --git a/core/service_available_controller.js b/core/service_available_controller.js index a55d1c0..8232050 100644 --- a/core/service_available_controller.js +++ b/core/service_available_controller.js @@ -7,12 +7,11 @@ // Подключение внешних библиотек //------------------------------ -const _ = require("lodash"); //Работа с массивами и коллекциями -const rqp = require("request-promise"); //Работа с HTTP/HTTPS запросами +const httpRequest = require("./http_client"); //Работа с HTTP/HTTPS запросами const EventEmitter = require("events"); //Обработчик пользовательских событий const { ServerError } = require("./server_errors"); //Типовая ошибка const { SERR_SERVICE_UNAVAILABLE, SERR_OBJECT_BAD_INTERFACE } = require("./constants"); //Общесистемные константы -const { makeErrorText, validateObject } = require("./utils"); //Вспомогательные функции +const { makeErrorText, validateObject, deepClone } = require("./utils"); //Вспомогательные функции const prmsServiceAvailableControllerSchema = require("../models/prms_service_available_controller"); //Схемы валидации параметров функций класса const objServiceSchema = require("../models/obj_service"); //Схемы валидации сервисов @@ -107,10 +106,7 @@ class ServiceAvailableController extends EventEmitter { //Обходим список сервисов для проверки for (let service of this.services) { //Если сервис надо проверять на доступность и это сервис для отправки исходящих сообщений - if ( - service.nUnavlblNtfSign == objServiceSchema.NUNAVLBL_NTF_SIGN_YES && - service.nSrvType == objServiceSchema.NSRV_TYPE_SEND - ) { + if (service.nUnavlblNtfSign == objServiceSchema.NUNAVLBL_NTF_SIGN_YES && service.nSrvType == objServiceSchema.NSRV_TYPE_SEND) { try { // Инициализируем параметры запроса let options = {}; @@ -123,7 +119,7 @@ class ServiceAvailableController extends EventEmitter { options.proxy = service.sProxyURL ?? this.sProxy; } //Отправляем проверочный запрос - await rqp(options); + await httpRequest(options); //Запрос прошел - фиксируем дату доступности и сбрасываем дату недоступности service.dAvailable = new Date(); service.dUnAvailable = null; @@ -193,10 +189,9 @@ class ServiceAvailableController extends EventEmitter { }); } } catch (e) { - await this.logger.error( - `При проверке просроченных сообщений сервиса ${service.sCode}: ${makeErrorText(e)}`, - { nServiceId: service.nId } - ); + await this.logger.error(`При проверке просроченных сообщений сервиса ${service.sCode}: ${makeErrorText(e)}`, { + nServiceId: service.nId + }); } } } @@ -232,7 +227,7 @@ class ServiceAvailableController extends EventEmitter { //Выставляем флаг неактивности (пока) цикла опроса this.bInDetectingLoop = false; //запоминаем список обслуживаемых сервисов и инициализируем даты доступности и недоступности - this.services = _.cloneDeep(prms.services); + this.services = deepClone(prms.services); this.services.forEach(s => { s.dUnAvailable = null; s.dAvailable = new Date(); diff --git a/core/utils.js b/core/utils.js index 2f71cc6..0de4d9e 100644 --- a/core/utils.js +++ b/core/utils.js @@ -8,7 +8,6 @@ //---------------------- const fs = require("fs"); //Работа с файлами -const _ = require("lodash"); //Работа с массивами и объектами const os = require("os"); //Средства операционной системы const xml2js = require("xml2js"); //Конвертация XML в JSON const Schema = require("validate"); //Схемы валидации @@ -29,6 +28,92 @@ const { SPROTOCOL_HTTP, SPROTOCOL_KAFKA } = require("../models/obj_service"); // // Тело модуля //------------ +//Глубокое клонирование +const deepClone = value => { + //Клонируем объект в зависимости от его типа, сохраняя прототипы + const seen = new WeakMap(); + const clone = val => { + //Примитивы и функции возвращаем как есть + if (val === null || typeof val !== "object") return val; + if (typeof val === "function") return val; + //Защита от циклических ссылок + if (seen.has(val)) return seen.get(val); + //Специализированные типы + if (val instanceof Date) return new Date(val); + if (Buffer.isBuffer(val)) return Buffer.from(val); + if (ArrayBuffer.isView(val)) return new val.constructor(val); + if (val instanceof RegExp) return new RegExp(val); + //Ошибки: сохраняем тип, сообщение, стек и пользовательские поля + if (val instanceof Error) { + const clonedError = new val.constructor(val.message); + seen.set(val, clonedError); + clonedError.name = val.name; + clonedError.stack = val.stack; + Reflect.ownKeys(val).forEach(key => { + if (key === "name" || key === "message" || key === "stack") return; + const desc = Object.getOwnPropertyDescriptor(val, key); + if (!desc) return; + if ("value" in desc) desc.value = clone(desc.value); + try { + Object.defineProperty(clonedError, key, desc); + } catch (e) {} + }); + return clonedError; + } + //Коллекции + if (val instanceof Map) { + const m = new Map(); + seen.set(val, m); + val.forEach((v, k) => m.set(clone(k), clone(v))); + return m; + } + if (val instanceof Set) { + const s = new Set(); + seen.set(val, s); + val.forEach(v => s.add(clone(v))); + return s; + } + //Коллекции, которые невозможно корректно клонировать - возвращаем по ссылке + if (val instanceof WeakMap || val instanceof WeakSet || val instanceof Promise) { + return val; + } + //Массивы + if (Array.isArray(val)) { + const arr = new Array(val.length); + seen.set(val, arr); + for (let i = 0; i < val.length; i++) { + if (Object.prototype.hasOwnProperty.call(val, i)) { + arr[i] = clone(val[i]); + } + } + return arr; + } + //Общие объекты и пользовательские классы: сохраняем прототип и дескрипторы свойств + const proto = Object.getPrototypeOf(val); + const obj = Object.create(proto); + seen.set(val, obj); + Reflect.ownKeys(val).forEach(key => { + const desc = Object.getOwnPropertyDescriptor(val, key); + if (!desc) return; + if ("value" in desc) { + desc.value = clone(desc.value); + } + try { + Object.defineProperty(obj, key, desc); + } catch (e) {} + }); + return obj; + }; + try { + return clone(value); + } catch (e) { + //В случае непредвиденной ошибки формируем информативное исключение + const err = new Error("Ошибка глубокого копирования объекта"); + err.originalError = e; + throw err; + } +}; + //Валидация объекта const validateObject = (obj, schema, sObjName) => { //Объявим результат @@ -38,7 +123,7 @@ const validateObject = (obj, schema, sObjName) => { //И есть что проверять if (obj) { //Сделаем это - const objTmp = _.cloneDeep(obj); + const objTmp = deepClone(obj); const errors = schema.validate(objTmp, { strip: false }); //Если есть ошибки if (errors && Array.isArray(errors)) { @@ -47,7 +132,7 @@ const validateObject = (obj, schema, sObjName) => { let a = errors.map(e => { return e.message; }); - sRes = `Объект${sObjName ? ` "${sObjName}" ` : " "}имеет некорректный формат: ${_.uniq(a).join("; ")}`; + sRes = `Объект${sObjName ? ` "${sObjName}" ` : " "}имеет некорректный формат: ${Array.from(new Set(a)).join("; ")}`; } } else { //Валидатор вернул не то, что мы ожидали @@ -322,11 +407,30 @@ const getNowString = () => { }; //Глубокое слияние объектов -const deepMerge = (...args) => { - let res = {}; - for (let i = 0; i < args.length; i++) _.merge(res, args[i]); - return res; -}; +function deepMerge(...sources) { + const isPlainObject = value => Object.prototype.toString.call(value) === "[object Object]"; + + const cloneValue = value => { + return deepClone(value); + }; + + const target = {}; + + for (const source of sources) { + if (!isPlainObject(source)) continue; + + for (const [key, value] of Object.entries(source)) { + if (isPlainObject(value)) { + if (!isPlainObject(target[key])) target[key] = {}; + target[key] = deepMerge(target[key], value); + } else { + target[key] = cloneValue(value); + } + } + } + + return target; +} //Глубокое копирование объекта const deepCopyObject = obj => JSON.parse(JSON.stringify(obj)); @@ -403,18 +507,29 @@ const getURLProtocol = sURL => { return sURL.substring(0, 1) === "/" ? SPROTOCOL_HTTP : new URL(sURL).protocol.slice(0, -1); }; -//Обёртывание промиса в таймаут исполнения -const wrapPromiseTimeout = (timeout, promise, promiseCancellable = true) => { - if (!timeout) return promise; +//Wraps async task with timeout and abort support +const wrapPromiseTimeout = (timeout, executor) => { + if (!timeout || typeof executor !== "function") { + return executor ? executor() : Promise.resolve(); + } + + const controller = new AbortController(); + const sMessage = `Истёк интервал ожидания (${timeout} мс) завершения асинхронного процесса.`; + const timeoutError = new Error(sMessage); + timeoutError.error = sMessage; + let timeoutPid; - const timeoutPromise = new Promise((resolve, reject) => { - const sMessage = `Истёк интервал ожидания (${timeout} мс) завершения асинхронного процесса.`; - let e = new Error(sMessage); - e.error = sMessage; - timeoutPid = setTimeout(() => reject(e), timeout); + + const timeoutPromise = new Promise((_, reject) => { + timeoutPid = setTimeout(() => { + controller.abort(timeoutError); + reject(timeoutError); + }, timeout); }); - return Promise.race([promise, timeoutPromise]).finally(() => { - if (promiseCancellable && promise.promise().isPending()) promise.cancel(); + + const taskPromise = Promise.resolve(executor(controller.signal)); + + return Promise.race([taskPromise, timeoutPromise]).finally(() => { if (timeoutPid) clearTimeout(timeoutPid); }); }; @@ -437,6 +552,7 @@ exports.parseOptionsXML = parseOptionsXML; exports.buildOptionsXML = buildOptionsXML; exports.getNowString = getNowString; exports.deepMerge = deepMerge; +exports.deepClone = deepClone; exports.deepCopyObject = deepCopyObject; exports.isUndefined = isUndefined; exports.getKafkaConnectionSettings = getKafkaConnectionSettings; diff --git a/index.js b/index.js index f721536..84ff42b 100644 --- a/index.js +++ b/index.js @@ -7,7 +7,6 @@ // Подключение библиотек //---------------------- -require("module-alias/register"); //Поддержка псевонимов при подключении модулей const cfg = require("./config"); //Настройки сервера приложений const app = require("./core/app"); //Сервер приложений const { makeErrorText, getNowString } = require("./core/utils"); //Вспомогательные функции @@ -29,11 +28,7 @@ process.env.NODE_TLS_REJECT_UNAUTHORIZED = cfg.outGoing.bValidateSSL === false ? //Обработка события "выход" жизненного цикла процесса process.on("exit", code => { //Сообщим о завершении процесса - console.log( - SCONSOLE_LOG_COLOR_PATTERN_WRN, - `${getNowString()} ПРЕДУПРЕЖДЕНИЕ: `, - `Сервер приложений остановлен (код: ${code})` - ); + console.log(SCONSOLE_LOG_COLOR_PATTERN_WRN, `${getNowString()} ПРЕДУПРЕЖДЕНИЕ: `, `Сервер приложений остановлен (код: ${code})`); }); //Обработка событий мягкого останова процесса diff --git a/models/obj_config.js b/models/obj_config.js index f17d7d4..7cea9df 100644 --- a/models/obj_config.js +++ b/models/obj_config.js @@ -9,6 +9,21 @@ const Schema = require("validate"); //Схемы валидации +//---------- +// Константы +//---------- + +//Уровни протоколирования подключения Kafka +const SKAFKA_LOG_LEVEL_NOTHING = "NOTHING"; //Протоколирование отключено +const SKAFKA_LOG_LEVEL_ERROR = "ERROR"; //Протоколирование ошибок +const SKAFKA_LOG_LEVEL_WARN = "WARN"; //Протоколирование предупреждений +const SKAFKA_LOG_LEVEL_INFO = "INFO"; //Протоколирование общей информации + +//Уровни протоколирования подключения MQTT +const SMQTT_LOG_LEVEL_NOTHING = "NOTHING"; //Протоколирование отключено +const SMQTT_LOG_LEVEL_ERROR = "ERROR"; //Протоколирование ошибок +const SMQTT_LOG_LEVEL_INFO = "INFO"; //Протоколирование информации + //------------- // Тело модуля //------------- @@ -52,6 +67,21 @@ const validatePoolIncrementInComing = val => val >= 0 && val <= 1000; //Функция проверки значения времени ожидания отработки входящего сообщения для обработчика входящих сообщений const validateTimeoutInComing = val => val >= 0; +//Функция проверки значения времени ожидания успешного подключения Kafka +const validateTimeoutKafka = val => val >= 0; + +//Функция проверки значения максимального ожидания между попытками переподключения Kafka +const validateMaxRetryTimeKafka = val => val >= 0; + +//Функция проверки значения максимального ожидания между попытками переподключения Kafka +const validateInitialRetryTimeKafka = val => val >= 0; + +//Функция проверки значения времени ожидания успешного подключения к MQTT +const validateConnectTimeoutMQTT = val => val >= 0; + +//Функция проверки значения времени ожидания между попытками переподключения к MQTT +const validateReconnectPeriodMQTT = val => val >= 0; + //Схема валидации общих параметров сервера приложений const common = new Schema({ //Наименование сервера приложений @@ -169,7 +199,8 @@ const outGoing = new Schema({ type: Boolean, required: true, message: { - type: path => `Признак проверки SSL-сертификатов адресов отправки сообщений (${path}) имеет некорректный тип данных (ожидалось - Number)`, + type: path => + `Признак проверки SSL-сертификатов адресов отправки сообщений (${path}) имеет некорректный тип данных (ожидалось - Boolean)`, required: path => `Не указан признак проверки SSL-сертификатов адресов отправки сообщений (${path})` } }, @@ -340,6 +371,246 @@ const inComing = new Schema({ } }); +//Схема валидации параметров SSL подключения к Kafka +const kafkaSSL = new Schema({ + //Запрещать использование самоподписанных сертификатов (true - запретить, false - разрешить) + bRejectUnauthorized: { + type: Boolean, + required: true, + message: { + type: path => + `Признак запрета использования самоподписанных сертификатов SSL подключения к Kafka (${path}) имеет некорректный тип данных (ожидалось - Boolean)`, + required: path => `Не указан признак запрета использования самоподписанных сертификатов SSL подключения к Kafka (${path})` + } + }, + //Путь к корневому сертификату с информацией об удостоверяющем центре + sPathCa: { + type: String, + required: false, + message: { + type: path => `Путь к корневому сертификату SSL подключения к Kafka (${path}) имеет некорректный тип данных (ожидалось - String)` + } + }, + //Путь к закрытому ключу + sPathKey: { + type: String, + required: false, + message: { + type: path => `Путь к закрытому ключу SSL подключения к Kafka (${path}) имеет некорректный тип данных (ожидалось - String)` + } + }, + //Путь к сертификату + sPathCert: { + type: String, + required: false, + message: { + type: path => `Путь к сертификату SSL подключения к Kafka (${path}) имеет некорректный тип данных (ожидалось - String)` + } + } +}); + +//Схема валидации параметров подключения Kafka +const kafka = new Schema({ + //Мнемокод сервиса обмена + sService: { + type: String, + required: false, + message: { + type: path => `Мнемокод сервиса обмена подключения Kafka (${path}) имеет некорректный тип данных (ожидалось - String)` + } + }, + //ID клиента-отправителя + sClientIdSender: { + type: String, + required: true, + message: { + type: path => `ID клиента-отправителя подключения Kafka (${path}) имеет некорректный тип данных (ожидалось - String)`, + required: path => `Не указан ID клиента-отправителя подключения Kafka (${path})` + } + }, + //ID клиента-получателя + sClientIdRecipient: { + type: String, + required: true, + message: { + type: path => `ID клиента-получателя подключения Kafka (${path}) имеет некорректный тип данных (ожидалось - String)`, + required: path => `Не указан ID клиента-получателя подключения Kafka (${path})` + } + }, + //Группа получателя + sGroupId: { + type: String, + required: true, + message: { + type: path => `Группа получателя подключения Kafka (${path}) имеет некорректный тип данных (ожидалось - String)`, + required: path => `Не указана группа получателя подключения Kafka (${path})` + } + }, + //Время ожидания успешного подключения (мс) + nConnectionTimeout: { + type: Number, + required: true, + use: { validateTimeoutKafka }, + message: { + type: path => `Время ожидания успешного подключения к Kafka (${path}) имеет некорректный тип данных (ожидалось - Number)`, + required: path => `Не указано время ожидания успешного подключения к Kafka (${path})`, + validateTimeoutKafka: path => `Время ожидания успешного подключения Kafka (${path}) должно быть неотрицательным целым числом` + } + }, + //Необходимость попытки переподключения при потере соединения + bRestartOnFailure: { + type: Boolean, + required: true, + message: { + type: path => `Признак необходимости попытки переподключения к Kafka (${path}) имеет некорректный тип данных (ожидалось - Boolean)`, + required: path => `Не указан признак необходимости попытки переподключения к Kafka (${path})` + } + }, + //Время максимального ожидания между попытками переподключения (мс) + nMaxRetryTime: { + type: Number, + required: true, + use: { validateMaxRetryTimeKafka }, + message: { + type: path => + `Время максимального ожидания между попытками переподключения к Kafka (${path}) имеет некорректный тип данных (ожидалось - Number)`, + required: path => `Не указано время максимального ожидания между попытками переподключения к Kafka (${path})`, + validateMaxRetryTimeKafka: path => + `Время максимального ожидания между попытками переподключения к Kafka (${path}) должно быть неотрицательным целым числом` + } + }, + //Время ожидания между попытками переподключения (мс) + nInitialRetryTime: { + type: Number, + required: true, + use: { validateInitialRetryTimeKafka }, + message: { + type: path => `Время ожидания между попытками переподключения к Kafka (${path}) имеет некорректный тип данных (ожидалось - Number)`, + required: path => `Не указано время ожидания между попытками переподключения к Kafka (${path})`, + validateInitialRetryTimeKafka: path => + `Время ожидания между попытками переподключения к Kafka (${path}) должно быть неотрицательным целым числом` + } + }, + //Уровень протоколирования подключения + sLogLevel: { + type: String, + enum: [SKAFKA_LOG_LEVEL_NOTHING, SKAFKA_LOG_LEVEL_ERROR, SKAFKA_LOG_LEVEL_WARN, SKAFKA_LOG_LEVEL_INFO], + required: true, + message: { + type: path => `Уровень протоколирования подключения к Kafka (${path}) имеет некорректный тип данных (ожидалось - String)`, + enum: path => `Значение уровня протоколирования подключения к Kafka (${path}) не поддерживается`, + required: path => `Не указан уровень протоколирования подключения к Kafka (${path})` + } + }, + //Использовать аутентификацию по SSL-сертификату + bAuthSSL: { + type: Boolean, + required: true, + message: { + type: path => `Признак использования аутентификации по SSL к Kafka (${path}) имеет некорректный тип данных (ожидалось - Boolean)`, + required: path => `Не указан признак использования аутентификации по SSL к Kafka (${path})` + } + }, + //Параметры аутентификации по SSL-сертификату + ssl: { + schema: kafkaSSL, + required: true, + message: { + required: path => `Не указаны параметры аутентификации по SSL к Kafka (${path})` + } + } +}); + +//Описатель схемы валидации подключения к Kafka +const defKafka = (bRequired, sName) => { + return { + type: Array, + required: bRequired, + each: kafka, + message: { + type: `Список подключений Kafka (${sName}) имеет некорректный тип данных (ожидалось - Array)`, + required: `Не указан список подключений Kafka (${sName})` + } + }; +}; + +//Схема валидации параметров подключения MQTT +const mqtt = new Schema({ + //Мнемокод сервиса обмена + sService: { + type: String, + required: false, + message: { + type: path => `Мнемокод сервиса обмена подключения MQTT (${path}) имеет некорректный тип данных (ожидалось - String)` + } + }, + //ID клиента-отправителя + sClientIdSender: { + type: String, + required: true, + message: { + type: path => `ID клиента-отправителя подключения MQTT (${path}) имеет некорректный тип данных (ожидалось - String)`, + required: path => `Не указан ID клиента-отправителя подключения MQTT (${path})` + } + }, + //ID клиента-получателя + sClientIdRecipient: { + type: String, + required: true, + message: { + type: path => `ID клиента-получателя подключения MQTT (${path}) имеет некорректный тип данных (ожидалось - String)`, + required: path => `Не указан ID клиента-получателя подключения MQTT (${path})` + } + }, + //Время ожидания успешного подключения (мс) + nConnectTimeout: { + type: Number, + required: true, + use: { validateConnectTimeoutMQTT }, + message: { + type: path => `Время ожидания успешного подключения к MQTT (${path}) имеет некорректный тип данных (ожидалось - Number)`, + required: path => `Не указано время ожидания успешного подключения к MQTT (${path})`, + validateConnectTimeoutMQTT: path => `Время ожидания успешного подключения к MQTT (${path}) должно быть неотрицательным целым числом` + } + }, + //Время ожидания между попытками переподключения (мс) + nReconnectPeriod: { + type: Number, + required: true, + use: { validateReconnectPeriodMQTT }, + message: { + type: path => `Время ожидания между попытками переподключения к MQTT (${path}) имеет некорректный тип данных (ожидалось - Number)`, + required: path => `Не указано время ожидания между попытками переподключения к MQTT (${path})`, + validateReconnectPeriodMQTT: path => + `Время ожидания между попытками переподключения к MQTT (${path}) должно быть неотрицательным целым числом` + } + }, + //Уровень протоколирования подключения + sLogLevel: { + type: String, + enum: [SMQTT_LOG_LEVEL_NOTHING, SMQTT_LOG_LEVEL_ERROR, SMQTT_LOG_LEVEL_INFO], + required: true, + message: { + type: path => `Уровень протоколирования подключения к MQTT (${path}) имеет некорректный тип данных (ожидалось - String)`, + enum: path => `Значение уровня протоколирования подключения к MQTT (${path}) не поддерживается`, + required: path => `Не указан уровень протоколирования подключения к MQTT (${path})` + } + } +}); + +//Описатель схемы валидации подключения к MQTT +const defMQTT = (bRequired, sName) => { + return { + type: Array, + required: bRequired, + each: mqtt, + message: { + type: `Список подключений MQTT (${sName}) имеет некорректный тип данных (ожидалось - Array)`, + required: `Не указан список подключений MQTT (${sName})` + } + }; +}; + //Схема валидации параметров отправки E-Mail уведомлений const mail = new Schema({ //Адреc сервера SMTP @@ -441,6 +712,22 @@ const config = new Schema({ required: path => `Не указаны параметры обработки очереди входящих сообщений (${path})` } }, + //Параметры подключения к Kafka + kafka: { + schema: defKafka(true, "kafka"), + required: true, + message: { + required: path => `Не указаны параметры подключения Kafka (${path})` + } + }, + //Параметры подключения к MQTT + mqtt: { + schema: defMQTT(true, "mqtt"), + required: true, + message: { + required: path => `Не указаны параметры подключения MQTT (${path})` + } + }, //Параметры отправки E-Mail уведомлений mail: { schema: mail, diff --git a/modules/diadoc.js b/modules/diadoc.js index 5bee4ad..fd72d84 100644 --- a/modules/diadoc.js +++ b/modules/diadoc.js @@ -8,8 +8,7 @@ //------------------------------ const xml2js = require("xml2js"); //Конвертация XML в JSON и JSON в XML -const _ = require("lodash"); //Работа с коллекциями и объектами -const rqp = require("request-promise"); //Работа с HTTP/HTTPS запросами +const httpRequest = require("../core/http_client"); //Работа с HTTP/HTTPS запросами const config = require("../config"); //Параметры сервера const { SDDAUTH_API_CLIENT_ID, SDEPARTMENT_NAME, SDEPARTMENT_ID } = require("./diadoc_config"); //Ключ разработчика @@ -62,7 +61,7 @@ const toArray = (obj, tags) => { if (typeof value === "object") { obj[prop] = toArray(value, tag); } - if (tags.indexOf(prop) != -1 && !_.isArray(obj[prop])) { + if (tags.indexOf(prop) != -1 && !Array.isArray(obj[prop])) { obj[prop] = JSON.parse("[" + JSON.stringify(value) + "]"); } } @@ -143,12 +142,12 @@ const getOrganizations = organizations => { //Итоговая выборка let organization = { Organizations: [] }; //Найдем активную организацию не в роуминге - organization.Organizations[0] = organizations.Organizations.find(org => (org.IsRoaming === isRoaming) && (org.IsActive === isActive)); + organization.Organizations[0] = organizations.Organizations.find(org => org.IsRoaming === isRoaming && org.IsActive === isActive); //Если не удалось получить организацию не в роуминге if (!organization.Organizations[0]) { //Найдем активную организацию - organization.Organizations[0] = organizations.Organizations.find(org => (org.IsActive === isActive)); - }; + organization.Organizations[0] = organizations.Organizations.find(org => org.IsActive === isActive); + } //Если не удалось получить активную организацию if (!organization.Organizations[0]) { //Если нет организации не в роуминге и найдено более одной организации @@ -167,10 +166,10 @@ const getOrganizations = organizations => { //Получение организации по ИНН/КПП контрагента const getOrganization = async (sSrvRoot, headers, nInn, nKpp) => { //Параметры запроса - let rqpOptions; + let httpRequestOptions; let serverResp; //Формируем запрос для получения BoxId - rqpOptions = { + httpRequestOptions = { uri: buildOrganizationURL(sSrvRoot), qs: { inn: nInn, @@ -180,18 +179,18 @@ const getOrganization = async (sSrvRoot, headers, nInn, nKpp) => { json: true }; //Выполним запрос - serverResp = { Organizations: [await rqp(rqpOptions)] }; + serverResp = { Organizations: [await httpRequest(httpRequestOptions)] }; return serverResp; }; //Получение ящика организации по ИНН/КПП контрагента const getOrganizationBoxId = async (sSrvRoot, headers, nInn, nKpp) => { //Параметры запроса - let rqpOptions; + let httpRequestOptions; let serverResp; let organization = {}; //Формируем запрос для получения BoxId по ИНН/КПП - rqpOptions = { + httpRequestOptions = { uri: buildOrganizationsByInnKppURL(sSrvRoot), qs: { inn: nInn, @@ -202,7 +201,7 @@ const getOrganizationBoxId = async (sSrvRoot, headers, nInn, nKpp) => { }; try { //Выполним запрос - serverResp = await rqp(rqpOptions); + serverResp = await httpRequest(httpRequestOptions); try { //Получим организацию не в роуминге (или единственную организацию в роуминге) serverResp = getOrganizations(serverResp); @@ -212,9 +211,9 @@ const getOrganizationBoxId = async (sSrvRoot, headers, nInn, nKpp) => { } catch (e) { //Получим головную организацию по ИНН/КПП serverResp = await getOrganization(sSrvRoot, headers, nInn, nKpp); - }; + } //Проверим соответствие КПП организации - if ((serverResp?.Organizations[0]?.Kpp != nKpp) && (serverResp?.Organizations[0])) { + if (serverResp?.Organizations[0]?.Kpp != nKpp && serverResp?.Organizations[0]) { //Если КПП не соответстует заданному - проверим, что в полученной организации есть департамент с заданным КПП for (let i in serverResp.Organizations[0].Departments) { //Если найден подходящий департамент - запомним идентификатор и выходим из цикла @@ -222,23 +221,25 @@ const getOrganizationBoxId = async (sSrvRoot, headers, nInn, nKpp) => { //Сохраняем полученный ответ organization.DepartmentId = serverResp.Organizations[0].Departments[i].DepartmentId; break; - }; - }; - }; + } + } + } //Не удалось получить ящик получателя или полученая организация не соответствует заданному ИНН - if ((!serverResp?.Organizations[0]?.Boxes[0]?.BoxId) || (serverResp?.Organizations[0]?.Inn != nInn)) { + if (!serverResp?.Organizations[0]?.Boxes[0]?.BoxId || serverResp?.Organizations[0]?.Inn != nInn) { throw new Error(`Не удалось получить ящик получателя для контрагента с ИНН: ${nInn} и КПП: ${nKpp}`); } //Не удалось получить департаментом с соответствующим КПП - if ((serverResp?.Organizations[0]?.Kpp != nKpp) && (!organization?.DepartmentId)) { - throw new Error(`Не удалось получить ящик получателя для контрагента с ИНН: ${nInn} и КПП: ${nKpp}, у головной организации отсутствует подразделение с КПП: ${nKpp}`); + if (serverResp?.Organizations[0]?.Kpp != nKpp && !organization?.DepartmentId) { + throw new Error( + `Не удалось получить ящик получателя для контрагента с ИНН: ${nInn} и КПП: ${nKpp}, у головной организации отсутствует подразделение с КПП: ${nKpp}` + ); } //Сохраняем полученный ответ organization.BoxId = serverResp.Organizations[0].Boxes[0].BoxId; return organization; } catch (e) { throw Error(`Ошибка при получении ящика получателя: ${e.message}`); - }; + } }; //Обработчик "До" подключения к сервису @@ -296,12 +297,10 @@ const beforeMessagePost = async prms => { } //Если не достали из контекста токен доступа - значит нет аутентификации на сервере if (!sToken) return { bUnAuth: true }; - //Получим параметры запроса - const optionsData = await toJSON(prms.queue.sOptions); //Конвертируем XML из "Парус 8" в JSON let obj = await toJSON(prms.queue.blMsg.toString()); //Формируем запрос для получения FromBoxId - let rqpOptions = { + let httpRequestOptions = { uri: buildMyOrganizationURL(prms.service.sSrvRoot), headers: buildHeaders(sAPIClientId, sToken), json: true @@ -311,11 +310,11 @@ const beforeMessagePost = async prms => { let organization; try { //Выполним запрос - serverResp = await rqp(rqpOptions); + serverResp = await httpRequest(httpRequestOptions); //Получим идентификатор организации по ИНН/КПП поставщика документа for (let i in serverResp.Organizations) { //Если найдена подходящая организация - запомним идентификатор и выходим из цикла - if (serverResp.Organizations[i].Inn == optionsData.inn_pr && serverResp.Organizations[i].Kpp == optionsData.kpp_pr) { + if (serverResp.Organizations[i].Inn == prms.options.inn_pr && serverResp.Organizations[i].Kpp == prms.options.kpp_pr) { //Сохраняем полученный ответ obj.FromBoxId = serverResp.Organizations[i].Boxes[0].BoxId; break; @@ -323,18 +322,23 @@ const beforeMessagePost = async prms => { } //Не удалось получить ящик отправителя if (!obj.FromBoxId) { - throw new Error(`Не удалось получить ящик текущей организации с ИНН: ${optionsData.inn_pr} и КПП: ${optionsData.kpp_pr}`); + throw new Error(`Не удалось получить ящик текущей организации с ИНН: ${prms.options.inn_pr} и КПП: ${prms.options.kpp_pr}`); } } catch (e) { throw Error(`Ошибка при получении ящика текущей организации: ${e.message}`); } //Получим ящик получателя - organization = await getOrganizationBoxId(prms.service.sSrvRoot, buildHeaders(sAPIClientId, sToken), optionsData.inn_cs, optionsData.kpp_cs); + organization = await getOrganizationBoxId( + prms.service.sSrvRoot, + buildHeaders(sAPIClientId, sToken), + prms.options.inn_cs, + prms.options.kpp_cs + ); obj.ToBoxId = organization.BoxId; //Если не заполнен идентификатор подразделения и при получении ящика удалось его подобрать - if ((!obj.ToDepartmentId) && (organization.DepartmentId)) { + if (!obj.ToDepartmentId && organization.DepartmentId) { obj.ToDepartmentId = organization.DepartmentId; - }; + } //Если пришел ответ if (prms.queue.blResp && serverResp.statusCode == 200) { //Вернем загруженный документ @@ -456,21 +460,19 @@ const beforeEvent = async prms => { } //Если не достали из контекста токен доступа - значит нет аутентификации на сервере if (!sToken) return { bUnAuth: true }; - //Получим параметры запроса - const optionsData = await toJSON(prms.queue.sOptions); //Формируем запрос для получения BoxId - let rqpOptions = { + let httpRequestOptions = { uri: buildMyOrganizationURL(prms.service.sSrvRoot), headers: buildHeaders(sAPIClientId, sToken), json: true }; try { //Выполним запрос - serverResp = await rqp(rqpOptions); + serverResp = await httpRequest(httpRequestOptions); //Получим идентификатор организации по ИНН/КПП контрагента организации for (let i in serverResp.Organizations) { //Если найдена подходящая организация - запомним идентификатор и выходим из цикла - if (serverResp.Organizations[i].Inn == optionsData.inn && serverResp.Organizations[i].Kpp == optionsData.kpp) { + if (serverResp.Organizations[i].Inn == prms.options.inn && serverResp.Organizations[i].Kpp == prms.options.kpp) { //Сохраняем полученный ответ sBoxId = serverResp.Organizations[i].Boxes[0].BoxId; //Если задано подразделение @@ -497,7 +499,7 @@ const beforeEvent = async prms => { } //Не удалось получить ящик текущей организации if (!sBoxId) { - throw new Error(`Не удалось получить ящик текущей организации с ИНН: ${optionsData.inn} и КПП: ${optionsData.kpp}`); + throw new Error(`Не удалось получить ящик текущей организации с ИНН: ${prms.options.inn} и КПП: ${prms.options.kpp}`); } } catch (e) { throw Error(`Ошибка при получении ящика текущей организации: ${e.message}`); @@ -543,7 +545,7 @@ const afterEvent = async prms => { let sAPIClientId = null; //Ключ разработчика let sToken = null; //Токен доступа let resu = null; //Ответ сервера - let rqpOptions = null; //Параметры для запроса информации по ящику + let httpRequestOptions = null; //Параметры для запроса информации по ящику let serverResp; //Результат запроса информации по организации let resp = null; //Ответ сервера let box = null; //Информация ящика @@ -559,10 +561,10 @@ const afterEvent = async prms => { //Получим список уникальных ящиков for (let i in resp.Events) { if (resp.Events[i]?.Message) { - if ((!boxIds.boxIds.find(box => box.boxId === resp.Events[i]?.Message.FromBoxId)) && (resp.Events[i]?.Message.FromBoxId)) { + if (!boxIds.boxIds.find(box => box.boxId === resp.Events[i]?.Message.FromBoxId) && resp.Events[i]?.Message.FromBoxId) { boxIds.boxIds.push({ boxId: resp.Events[i]?.Message.FromBoxId }); } - if ((!boxIds.boxIds.find(box => box.boxId === resp.Events[i]?.Message.ToBoxId)) && (resp.Events[i]?.Message.ToBoxId)) { + if (!boxIds.boxIds.find(box => box.boxId === resp.Events[i]?.Message.ToBoxId) && resp.Events[i]?.Message.ToBoxId) { boxIds.boxIds.push({ boxId: resp.Events[i]?.Message.ToBoxId }); } } @@ -576,9 +578,9 @@ const afterEvent = async prms => { //Если не достали из контекста токен доступа - значит нет аутентификации на сервере if (!sToken) return { bUnAuth: true }; for (let i in boxIds.boxIds) { - rqpOptions = null; + httpRequestOptions = null; //Формируем запрос для получения BoxId - rqpOptions = { + httpRequestOptions = { uri: buildOrganizationBoxIdURL(prms.service.sSrvRoot), headers: buildHeaders(sAPIClientId, sToken), qs: { @@ -588,7 +590,7 @@ const afterEvent = async prms => { }; try { //Выполним запрос - serverResp = await rqp(rqpOptions); + serverResp = await httpRequest(httpRequestOptions); if (serverResp?.Organization) { //Запишем полученную информацию о контрагенте boxIds.boxIds[i].Inn = serverResp?.Organization?.Inn; @@ -702,7 +704,7 @@ const beforeDocLoad = async prms => { surl = `${surl}?${msgId}${prms.options.smsgid}&${entId}${prms.options.sentid}`; let obj; let rblMsg; - if (prms.queue.blMsg && (prms.options.type != 5) && (prms.options.type != 6)) { + if (prms.queue.blMsg && prms.options.type != 5 && prms.options.type != 6) { //Конвертируем XML из "Парус 8" в понятный "ДИАДОК" JSON obj = await toJSON(prms.queue.blMsg.toString()); rblMsg = Buffer.from(JSON.stringify(obj)); @@ -751,7 +753,7 @@ const afterDocLoad = async prms => { await new Promise(resolve => setTimeout(resolve, 2000)); } //Выполним повторный запрос - serverResp = await rqp(prms.options); + serverResp = await httpRequest(prms.options); //Сохраняем полученный ответ prms.queue.blResp = Buffer.from(serverResp.body || ""); prms.optionsResp.statusCode = serverResp.statusCode; @@ -837,8 +839,6 @@ const beforeDepartmentIdGet = async prms => { const afterDepartmentIdGet = async prms => { let resu = null; let organization = {}; - //Получим параметры запроса - const optionsData = await toJSON(prms.queue.sOptions); //Действие выполнено успешно if (prms.optionsResp.statusCode == 200) { try { @@ -846,7 +846,7 @@ const afterDepartmentIdGet = async prms => { //Получим организацию не в роуминге (или единственную организацию в роуминге) organization = getOrganizations(JSON.parse(prms.queue.blResp.toString())); if (!organization) { - throw Error(`Не удалось получить ящик для контрагента с ИНН: ${optionsData.nINN} и КПП: ${optionsData.nKPP}`); + throw Error(`Не удалось получить ящик для контрагента с ИНН: ${prms.options.nINN} и КПП: ${prms.options.nKPP}`); } } catch (e) { //Получим ключ разработчика @@ -854,8 +854,8 @@ const afterDepartmentIdGet = async prms => { //Считаем токен доступа из контекста сервиса let sToken = prms.service.sCtx; //Получим головную организацию по ИНН/КПП - organization = await getOrganization(prms.service.sSrvRoot, buildHeaders(sAPIClientId, sToken), optionsData.nINN, optionsData.nKPP); - }; + organization = await getOrganization(prms.service.sSrvRoot, buildHeaders(sAPIClientId, sToken), prms.options.nINN, prms.options.nKPP); + } //Преобразуем JSON ответ сервиса "ДИАДОК" в XML, понятный "Парус 8" resu = toXML({ root: organization }); } catch (e) { diff --git a/modules/parus_oracle_db.js b/modules/parus_oracle_db.js index c425ebb..8ec0e61 100644 --- a/modules/parus_oracle_db.js +++ b/modules/parus_oracle_db.js @@ -8,6 +8,25 @@ //---------------------- const oracledb = require("oracledb"); //Работа с СУБД Oracle +const { makeErrorText } = require("../core/utils"); //Вспомогательные функции + +//--------------------------- +// Инициализация Thick-режима +//--------------------------- + +//Инициализируем Thick-режим до любых подключений к БД +try { + if (typeof oracledb.initOracleClient === "function" && !(process.env.NODE_ORACLE_DB_THIN_MODE === 1)) { + const libDir = process.env.ORACLE_CLIENT_LIB_DIR; + if (libDir) { + oracledb.initOracleClient({ libDir }); + } else { + oracledb.initOracleClient(); + } + } +} catch (e) { + throw new Error(`Не удалось инициализировать Oracle Client (Thick-режим): ${makeErrorText(e)}`); +} //-------------------------- // Глобальные идентификаторы diff --git a/modules/pws.js b/modules/pws.js index fffdb8e..4230f9f 100644 --- a/modules/pws.js +++ b/modules/pws.js @@ -8,7 +8,7 @@ //------------------------------ const xml2js = require("xml2js"); //Конвертация XML в JSON и JSON в XML -const _ = require("lodash"); //Работа с коллекциями и объектами +const { deepClone } = require("../core/utils"); //Вспомогательные функции //--------------------- // Глобальные константы @@ -48,24 +48,23 @@ const converXMLArraysToJSON = (obj, arrayKey) => { let tmp = []; let itemKey = obj[key][arrayKey]; if (obj[key][itemKey]) { - if (_.isArray(obj[key][itemKey])) { + if (Array.isArray(obj[key][itemKey])) { for (let i = 0; i < obj[key][itemKey].length; i++) { let buf = {}; - buf[itemKey] = _.cloneDeep(obj[key][itemKey][i]); + buf[itemKey] = deepClone(obj[key][itemKey][i]); tmp.push(buf); } } else { let buf = {}; - buf[itemKey] = _.cloneDeep(obj[key][itemKey]); + buf[itemKey] = deepClone(obj[key][itemKey]); tmp.push(buf); } } obj[key] = tmp; converXMLArraysToJSON(obj[key], arrayKey); } else { - if (_.isObject(obj[key])) converXMLArraysToJSON(obj[key], arrayKey); - if (_.isArray(obj[key])) - for (let i = 0; i < obj[key].length; i++) converXMLArraysToJSON(obj[key][i], arrayKey); + if (typeof obj[key] === "object" && obj[key] !== null && !Array.isArray(obj[key])) converXMLArraysToJSON(obj[key], arrayKey); + if (Array.isArray(obj[key])) for (let i = 0; i < obj[key].length; i++) converXMLArraysToJSON(obj[key][i], arrayKey); } } }; @@ -73,10 +72,7 @@ const converXMLArraysToJSON = (obj, arrayKey) => { //Обработчик "До" для полученного сообщения const before = async prms => { //Если пришел запрос в JSON - if ( - prms.options.headers["content-type"] && - prms.options.headers["content-type"].startsWith(SHEADER_REQ_CONTENT_TYPE_JSON) - ) { + if (prms.options.headers["content-type"] && prms.options.headers["content-type"].startsWith(SHEADER_REQ_CONTENT_TYPE_JSON)) { //Конвертируем полученный в JSON-запрос в XML, понятный серверной части let requestXML = ""; try { @@ -102,11 +98,8 @@ const after = async prms => { prms.options.qs[SQUERY_RESP_CT] && prms.options.qs[SQUERY_RESP_CT].startsWith(SHEADER_REQ_CONTENT_TYPE_JSON)) || (prms.function.sCode != SFNC_UPLOAD && - ((prms.options.headers["content-type"] && - prms.options.headers["content-type"].startsWith(SHEADER_REQ_CONTENT_TYPE_JSON)) || - (prms.options.qs && - prms.options.qs[SQUERY_RESP_CT] && - prms.options.qs[SQUERY_RESP_CT].startsWith(SHEADER_REQ_CONTENT_TYPE_JSON)))) + ((prms.options.headers["content-type"] && prms.options.headers["content-type"].startsWith(SHEADER_REQ_CONTENT_TYPE_JSON)) || + (prms.options.qs && prms.options.qs[SQUERY_RESP_CT] && prms.options.qs[SQUERY_RESP_CT].startsWith(SHEADER_REQ_CONTENT_TYPE_JSON)))) ) { //Буфер для конвертации let parseRes = ""; diff --git a/modules/sbis.js b/modules/sbis.js index ac86a75..ca6389b 100644 --- a/modules/sbis.js +++ b/modules/sbis.js @@ -8,8 +8,7 @@ //------------------------------ const xml2js = require("xml2js"); //Конвертация XML в JSON и JSON в XML -const _ = require("lodash"); //Работа с коллекциями и объектами -const rqp = require("request-promise"); //Работа с HTTP/HTTPS запросами +const httpRequest = require("../core/http_client"); //Работа с HTTP/HTTPS запросами const { SMCHD_STORAGE_SYSTEM } = require("./sbis_config"); //Система хранения МЧД //--------------------- @@ -33,7 +32,7 @@ const tag = [ // Список имен тегов для замены ([Старое значение], [Новое значение]) const replaceTags = [ ['"Иные получатели":', '"ИныеПолучатели":'], - ['"Создатель документа":', '"СоздательДокумента":'], + ['"Создатель документа":', '"СоздательДокумента":'] ]; //------------ @@ -41,9 +40,9 @@ const replaceTags = [ //------------ //Замена наименований тегов (для корректной работы toXML) -const replaceTag = (obj) => { +const replaceTag = obj => { for (let value of replaceTags) { - obj = obj.replace(new RegExp(value[0], 'g'), value[1]); + obj = obj.replace(new RegExp(value[0], "g"), value[1]); } return obj; }; @@ -52,7 +51,7 @@ const replaceTag = (obj) => { const toArray = (obj, tags) => { for (const prop in obj) { const value = obj[prop]; - if (tags.indexOf(prop) != -1 && !_.isArray(obj[prop])) { + if (tags.indexOf(prop) != -1 && !Array.isArray(obj[prop])) { obj[prop] = JSON.parse("[" + JSON.stringify(value) + "]"); } if (typeof value === "object") { @@ -255,7 +254,7 @@ const afterAttParse = async prms => { if (prms.optionsResp.statusCode != 200) { //Выполним повторный запрос await new Promise(resolve => setTimeout(resolve, 2000)); - let serverResp = await rqp(prms.options); + let serverResp = await httpRequest(prms.options); //Сохраняем полученный ответ prms.queue.blResp = Buffer.from(serverResp.body || ""); prms.optionsResp.statusCode = serverResp.statusCode; diff --git a/package-lock.json b/package-lock.json index b88a74b..d9815df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "parus_exchange_service", "version": "1.0.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -9,54 +9,59 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "body-parser": "^1.19.0", "cors": "^2.8.5", - "express": "^4.17.1", + "express": "^5.2.1", "kafkajs": "^2.2.4", - "lodash": "^4.17.19", - "module-alias": "^2.2.2", "mqtt": "^5.10.1", - "nodemailer": "^6.4.11", - "oracledb": "^4.2.0", + "nodemailer": "^6.9.16", + "oracledb": "^6.6.0", "pg": "^8.13.1", - "request": "^2.88.2", - "request-promise": "^4.2.6", + "undici": "^6.0.0", "validate": "^5.1.0", - "xml2js": "^0.4.23" + "xml2js": "^0.6.2" + }, + "engines": { + "node": ">=22" } }, "node_modules/@babel/runtime": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", - "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, + "node_modules/@eivifj/dot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@eivifj/dot/-/dot-1.0.3.tgz", + "integrity": "sha512-UE2x9N7XD/1qqtXA+4CZPD1RQAlM0lEdXdy09CJ/wNR+mgGKqwLRH4BGGfOAWwwz06pIT3c2tC4gvXbntGAeMA==", + "license": "MIT" + }, "node_modules/@types/node": { - "version": "22.7.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz", - "integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==", + "version": "25.0.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.8.tgz", + "integrity": "sha512-powIePYMmC3ibL0UJ2i2s0WIbq6cg6UyVFQxSCpaPxxzAaziRfimGivjdF943sSGV6RADVbk0Nvlm5P/FB44Zg==", + "license": "MIT", "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~7.16.0" } }, "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==", + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.23.tgz", + "integrity": "sha512-wwXrtQvbMHxCbBgjHaMGEmImFTQxxpfMOR/ZoQnXxB1woqkUbdLGFDgauo00Py9IudiaqSeiBiulSV9i6XIPig==", + "license": "MIT", "dependencies": { - "@types/node": "*", - "safe-buffer": "~5.1.1" + "@types/node": "*" } }, "node_modules/@types/ws": { - "version": "8.5.12", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", - "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -65,6 +70,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" }, @@ -73,71 +79,18 @@ } }, "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" }, "engines": { "node": ">= 0.6" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -155,20 +108,14 @@ "type": "consulting", "url": "https://feross.org/support" } - ] - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dependencies": { - "tweetnacl": "^0.14.3" - } + ], + "license": "MIT" }, "node_modules/bl": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/bl/-/bl-6.0.16.tgz", - "integrity": "sha512-V/kz+z2Mx5/6qDfRCilmrukUXcXuCoXKg3/3hDvzKKoSUx8CJKudfIoT29XZc3UE9xBvxs5qictiHdprwtteEg==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/bl/-/bl-6.1.6.tgz", + "integrity": "sha512-jLsPgN/YSvPUg9UX0Kd73CXpm2Psg9FxMeCSXnk3WBO3CMT10JMwijubhGfHCnFu6TPn1ei3b975dxv7K2pWVg==", + "license": "MIT", "dependencies": { "@types/readable-stream": "^4.0.0", "buffer": "^6.0.3", @@ -176,34 +123,40 @@ "readable-stream": "^4.2.0" } }, - "node_modules/bl/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/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, "node_modules/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "license": "MIT", "dependencies": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" }, "engines": { - "node": ">= 0.8" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/broker-factory": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/broker-factory/-/broker-factory-3.1.12.tgz", + "integrity": "sha512-5Bmeki5j2IVO+lE07dSOUMZp1ZGKkE47b3ILv4ZD0nmTdc0iTKVS1CgYPDCy5m0Qb9jIKHBaF9SUrtqg5oW+1A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.4", + "fast-unique-numbers": "^9.0.25", + "tslib": "^2.8.1", + "worker-factory": "^7.0.47" } }, "node_modules/buffer": { @@ -224,6 +177,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -232,41 +186,58 @@ "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==" + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" }, "node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", "dependencies": { - "delayed-stream": "~1.0.0" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/commist": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz", - "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==" + "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==", + "license": "MIT" }, "node_modules/component-type": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-type/-/component-type-1.2.1.tgz", - "integrity": "sha1-ikeQFwAjjk/DIml3EjAibyS0Fak=" + "integrity": "sha512-Kgy+2+Uwr75vAi6ChWXgHuLvd+QLD7ssgpaRq2zCvt80ptvAfMc/hijcJxXkBa2wMlEZcJvC2H8Ubo+A9ATHIg==", + "license": "MIT" }, "node_modules/concat-stream": { "version": "2.0.0", @@ -275,6 +246,7 @@ "engines": [ "node >= 6.0" ], + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -286,6 +258,7 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -296,46 +269,50 @@ } }, "node_modules/content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "dependencies": { - "safe-buffer": "5.1.2" - }, + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", "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": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } }, "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==", + "license": "MIT", "dependencies": { "object-assign": "^4", "vary": "^1" @@ -344,83 +321,102 @@ "node": ">= 0.10" } }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", "dependencies": { - "assert-plus": "^1.0.0" + "ms": "^2.1.3" }, "engines": { - "node": ">=0.10" - } - }, - "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/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "engines": { - "node": ">=0.4.0" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "node_modules/eivindfjeldstad-dot": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/eivindfjeldstad-dot/-/eivindfjeldstad-dot-0.0.1.tgz", - "integrity": "sha1-IvyXa/rzBuCDmjHbjoITSA+vuJM=", - "deprecated": "Use @eivifj/dot instead" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" }, "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -429,6 +425,7 @@ "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==", + "license": "MIT", "engines": { "node": ">=6" } @@ -437,211 +434,228 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", "engines": { "node": ">=0.8.x" } }, "node_modules/express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", "dependencies": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" }, "engines": { - "node": ">= 0.10.0" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, "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==", + "version": "9.0.25", + "resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-9.0.25.tgz", + "integrity": "sha512-vHLSJfu0jSazb5X1jgYZIbsUd4mztxHxyFxUAPYvaYLkTsvQDn5+NbJRtfp+/tLIsUlMkD/geL2710QBxylH6w==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.23.8", - "tslib": "^2.6.2" + "@babel/runtime": "^7.28.4", + "tslib": "^2.8.1" }, "engines": { - "node": ">=16.1.0" + "node": ">=18.2.0" } }, "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" }, "engines": { - "node": ">= 0.8" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" + "node": ">= 18.0.0" }, - "engines": { - "node": ">= 0.12" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/har-schema": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", "engines": { - "node": ">=4" + "node": ">= 0.8" } }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, "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==" + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", + "license": "MIT" }, "node_modules/http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" }, "engines": { - "node": ">= 0.6" - } - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "node": ">= 0.8" }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "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==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/ieee754": { @@ -661,177 +675,150 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "license": "MIT", + "engines": { + "node": ">= 12" + } }, "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==", + "license": "MIT", "engines": { "node": ">= 0.10" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" }, "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==", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/js-sdsl" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, "node_modules/kafkajs": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/kafkajs/-/kafkajs-2.2.4.tgz", "integrity": "sha512-j/YeapB1vfPT2iOIUn/vxdyKEuhuY2PxMBvf5JWux6iSaukAccrMtXEY/Lb7OvavDhOWME589bpLrEdnVHjfjA==", + "license": "MIT", "engines": { "node": ">=14.0.0" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "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==" + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } }, "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", "engines": { - "node": ">= 0.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" + "node": ">=18" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", "dependencies": { - "mime-db": "1.47.0" + "mime-db": "^1.54.0" }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/module-alias": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz", - "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==" - }, "node_modules/mqtt": { - "version": "5.10.1", - "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.10.1.tgz", - "integrity": "sha512-hXCOki8sANoQ7w+2OzJzg6qMBxTtrH9RlnVNV8panLZgnl+Gh0J/t4k6r8Az8+C7y3KAcyXtn0mmLixyUom8Sw==", + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.14.1.tgz", + "integrity": "sha512-NxkPxE70Uq3Ph7goefQa7ggSsVzHrayCD0OyxlJgITN/EbzlZN+JEPmaAZdxP1LsIT5FamDyILoQTF72W7Nnbw==", + "license": "MIT", "dependencies": { - "@types/readable-stream": "^4.0.5", - "@types/ws": "^8.5.9", + "@types/readable-stream": "^4.0.21", + "@types/ws": "^8.18.1", "commist": "^3.2.0", "concat-stream": "^2.0.0", - "debug": "^4.3.4", + "debug": "^4.4.1", "help-me": "^5.0.0", - "lru-cache": "^10.0.1", + "lru-cache": "^10.4.3", "minimist": "^1.2.8", - "mqtt-packet": "^9.0.0", + "mqtt-packet": "^9.0.2", "number-allocator": "^1.0.14", - "readable-stream": "^4.4.2", - "reinterval": "^1.1.0", - "rfdc": "^1.3.0", + "readable-stream": "^4.7.0", + "rfdc": "^1.4.1", + "socks": "^2.8.6", "split2": "^4.2.0", - "worker-timers": "^7.1.4", - "ws": "^8.17.1" + "worker-timers": "^8.0.23", + "ws": "^8.18.3" }, "bin": { "mqtt": "build/bin/mqtt.js", @@ -843,74 +830,36 @@ } }, "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==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-9.0.2.tgz", + "integrity": "sha512-MvIY0B8/qjq7bKxdN1eD+nrljoeaai+qjLJgfRn3TiMuz0pamsIWY2bFODPZMSNmabsLANXsLl4EMoWvlaTZWA==", + "license": "MIT", "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.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/mqtt-packet/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/mqtt/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/mqtt/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/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/nodemailer": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.6.0.tgz", - "integrity": "sha512-ikSMDU1nZqpo2WUPE0wTTw/NGGImTkwpJKDIFPZT+YvvR9Sj+ze5wzu95JHkBMglQLoG2ITxU21WukCC/XsFkg==", + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.10.1.tgz", + "integrity": "sha512-Z+iLaBGVaSjbIzQ4pX6XV41HrooLsQ10ZWPUehGmuantvzWoDVBnmsdUcOIDM1t+yPor5pDhVlDESgOMEGxhHA==", + "license": "MIT-0", "engines": { "node": ">=6.0.0" } @@ -919,52 +868,38 @@ "version": "1.0.14", "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz", "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==", + "license": "MIT", "dependencies": { "debug": "^4.3.1", "js-sdsl": "4.3.0" } }, - "node_modules/number-allocator/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/number-allocator/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/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "engines": { - "node": "*" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -972,49 +907,61 @@ "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==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/oracledb": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/oracledb/-/oracledb-4.2.0.tgz", - "integrity": "sha512-07ZylNcUB9wknsiRa7dNqDWgGK3loP8eNWuoCjsiCOZ19PA1g8QLu+0gah7ty82VXl/MOQYFCMl5OpjD9Aqjcw==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/oracledb/-/oracledb-6.10.0.tgz", + "integrity": "sha512-kGUumXmrEWbSpBuKJyb9Ip3rXcNgKK6grunI3/cLPzrRvboZ6ZoLi9JQ+z6M/RIG924tY8BLflihL4CKKQAYMA==", "hasInstallScript": true, + "license": "(Apache-2.0 OR UPL-1.0)", "engines": { - "node": ">=8.16" + "node": ">=14.17" } }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", "engines": { "node": ">= 0.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": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } }, "node_modules/pg": { - "version": "8.13.1", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.13.1.tgz", - "integrity": "sha512-OUir1A0rPNZlX//c7ksiu7crsGZTKSOXJPgtNiHGIlC9H0lO+NC6ZDYksSgBYY/thSWhnSRBv8w1lieNNGATNQ==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.17.1.tgz", + "integrity": "sha512-EIR+jXdYNSMOrpRp7g6WgQr7SaZNZfS7IzZIO0oTNEeibq956JxeD15t3Jk3zZH0KH8DmOIx38qJfQenoE8bXQ==", + "license": "MIT", "dependencies": { - "pg-connection-string": "^2.7.0", - "pg-pool": "^3.7.0", - "pg-protocol": "^1.7.0", - "pg-types": "^2.1.0", - "pgpass": "1.x" + "pg-connection-string": "^2.10.0", + "pg-pool": "^3.11.0", + "pg-protocol": "^1.11.0", + "pg-types": "2.2.0", + "pgpass": "1.0.5" }, "engines": { - "node": ">= 8.0.0" + "node": ">= 16.0.0" }, "optionalDependencies": { - "pg-cloudflare": "^1.1.1" + "pg-cloudflare": "^1.3.0" }, "peerDependencies": { "pg-native": ">=3.0.1" @@ -1026,41 +973,47 @@ } }, "node_modules/pg-cloudflare": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", - "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz", + "integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==", + "license": "MIT", "optional": true }, "node_modules/pg-connection-string": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.7.0.tgz", - "integrity": "sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==" + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.10.0.tgz", + "integrity": "sha512-ur/eoPKzDx2IjPaYyXS6Y8NSblxM7X64deV2ObV57vhjsWiwLvUD6meukAzogiOsu60GO8m/3Cb6FdJsWNjwXg==", + "license": "MIT" }, "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==", + "license": "ISC", "engines": { "node": ">=4.0.0" } }, "node_modules/pg-pool": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.7.0.tgz", - "integrity": "sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.11.0.tgz", + "integrity": "sha512-MJYfvHwtGp870aeusDh+hg9apvOe2zmpZJpyt+BMtzUWlVqbhFmMK6bOBXLBUPd7iRtIF9fZplDc7KrPN3PN7w==", + "license": "MIT", "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.7.0.tgz", - "integrity": "sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ==" + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.11.0.tgz", + "integrity": "sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==", + "license": "MIT" }, "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==", + "license": "MIT", "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", @@ -1076,6 +1029,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", "dependencies": { "split2": "^4.1.0" } @@ -1084,14 +1038,16 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", "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==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1100,6 +1056,7 @@ "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==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1108,6 +1065,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", "dependencies": { "xtend": "^4.0.0" }, @@ -1119,6 +1077,7 @@ "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", "engines": { "node": ">= 0.6.0" } @@ -1126,67 +1085,66 @@ "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==" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" }, "node_modules/proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "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==", + "license": "MIT", "dependencies": { - "forwarded": "~0.1.2", + "forwarded": "0.2.0", "ipaddr.js": "1.9.1" }, "engines": { "node": ">= 0.10" } }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "engines": { - "node": ">=6" - } - }, "node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, "engines": { "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "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==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.10" } }, "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==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", @@ -1198,211 +1156,29 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.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/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz", - "integrity": "sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==", - "deprecated": "request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", - "dependencies": { - "bluebird": "^3.5.0", - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "engines": { - "node": ">=0.6" - } - }, "node_modules/rfdc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } }, "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/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "node_modules/serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "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/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "engines": { - "node": ">=0.10.0" - } - }, - "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/string_decoder/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==", @@ -1419,56 +1195,222 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", + "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } }, "node_modules/toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", "engines": { "node": ">=0.6" } }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "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==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" }, "engines": { "node": ">= 0.6" @@ -1477,62 +1419,53 @@ "node_modules/typecast": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/typecast/-/typecast-0.0.1.tgz", - "integrity": "sha1-//t13La98d744pO2tuiT1sHtGd4=" + "integrity": "sha512-L2f5OCLKsJdCjSyN0d5O6CkNxhiC8EQ2XlXnHpWZVNfF+mj2OTaXhAVnP0/7SY/sxO1DHZpOFMpIuGlFUZEGNA==", + "license": "MIT" }, "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==" + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "license": "MIT" + }, + "node_modules/undici": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz", + "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } }, "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, "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": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "bin": { - "uuid": "bin/uuid" - } + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" }, "node_modules/validate": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/validate/-/validate-5.1.0.tgz", - "integrity": "sha512-Y+vJv+xR3XsaQM8W1rQvwc6is/sgCUBv3lvNKc2DZ1HcVcEWAaHVSFB5uoxkQnw2riUq77Rg5nv1u8YuuSu/Zw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/validate/-/validate-5.2.0.tgz", + "integrity": "sha512-pVADd6GfDT7bALYvvzhfHnfmxCDem2bG7lGY3mwHzY7ktMH/SaczoF+eKkGokQEdGKozkJvyuOiSfQEHXp4zIA==", + "license": "MIT", "dependencies": { + "@eivifj/dot": "^1.0.1", "component-type": "1.2.1", - "eivindfjeldstad-dot": "0.0.1", "typecast": "0.0.1" }, "engines": { @@ -1542,59 +1475,70 @@ "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "engines": [ - "node >=0.6.0" - ], + "node_modules/worker-factory": { + "version": "7.0.47", + "resolved": "https://registry.npmjs.org/worker-factory/-/worker-factory-7.0.47.tgz", + "integrity": "sha512-Ga5U8n7hJqovn98nlFnbyuJj66s8dCU4QOQd0dU0bje7uvrGGhOFeKtsTdB3b6fO5BD93F88rHpkBCGzgGloKw==", + "license": "MIT", "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "@babel/runtime": "^7.28.4", + "fast-unique-numbers": "^9.0.25", + "tslib": "^2.8.1" } }, "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==", + "version": "8.0.28", + "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-8.0.28.tgz", + "integrity": "sha512-+AuNePH2P/PuhQURf5I+SIGBty4dq2CzoQEB+bMXIQiPrYj3WhkUtIW2bSzeETFWyXJFUdQGsyFeZtit15LkOw==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.24.5", - "tslib": "^2.6.2", - "worker-timers-broker": "^6.1.8", - "worker-timers-worker": "^7.0.71" + "@babel/runtime": "^7.28.4", + "tslib": "^2.8.1", + "worker-timers-broker": "^8.0.14", + "worker-timers-worker": "^9.0.12" } }, "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==", + "version": "8.0.14", + "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-8.0.14.tgz", + "integrity": "sha512-ooCGGWGcAYbWEJY2nkA60K9mZ33atvg/QIOBJ3OzdQJU5Z7/NdPFlEiMLiCYW8dpeP/qLcsaUsZzETrKNgGicg==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.24.5", - "fast-unique-numbers": "^8.0.13", - "tslib": "^2.6.2", - "worker-timers-worker": "^7.0.71" + "@babel/runtime": "^7.28.4", + "broker-factory": "^3.1.12", + "fast-unique-numbers": "^9.0.25", + "tslib": "^2.8.1", + "worker-timers-worker": "^9.0.12" } }, "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==", + "version": "9.0.12", + "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-9.0.12.tgz", + "integrity": "sha512-NBXCnKB/9CkhjWZz2dITgK94QM5GIJx+7LAlCA8mKeO6whdwmfH9S3iPEwakhn3+NOB9nHE3jQqdpKpZZJI23g==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.24.5", - "tslib": "^2.6.2" + "@babel/runtime": "^7.28.4", + "tslib": "^2.8.1", + "worker-factory": "^7.0.47" } }, + "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==", + "license": "ISC" + }, "node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -1612,9 +1556,10 @@ } }, "node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "license": "MIT", "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" @@ -1627,6 +1572,7 @@ "version": "11.0.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "license": "MIT", "engines": { "node": ">=4.0" } @@ -1635,1238 +1581,10 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", "engines": { "node": ">=0.4" } } - }, - "dependencies": { - "@babel/runtime": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", - "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", - "requires": { - "regenerator-runtime": "^0.14.0" - } - }, - "@types/node": { - "version": "22.7.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz", - "integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==", - "requires": { - "undici-types": "~6.19.2" - } - }, - "@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==", - "requires": { - "@types/node": "*", - "safe-buffer": "~5.1.1" - } - }, - "@types/ws": { - "version": "8.5.12", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", - "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", - "requires": { - "@types/node": "*" - } - }, - "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==", - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bl": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/bl/-/bl-6.0.16.tgz", - "integrity": "sha512-V/kz+z2Mx5/6qDfRCilmrukUXcXuCoXKg3/3hDvzKKoSUx8CJKudfIoT29XZc3UE9xBvxs5qictiHdprwtteEg==", - "requires": { - "@types/readable-stream": "^4.0.0", - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^4.2.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - } - } - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "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==" - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commist": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz", - "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==" - }, - "component-type": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-type/-/component-type-1.2.1.tgz", - "integrity": "sha1-ikeQFwAjjk/DIml3EjAibyS0Fak=" - }, - "concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "eivindfjeldstad-dot": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/eivindfjeldstad-dot/-/eivindfjeldstad-dot-0.0.1.tgz", - "integrity": "sha1-IvyXa/rzBuCDmjHbjoITSA+vuJM=" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "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==" - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "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==", - "requires": { - "@babel/runtime": "^7.23.8", - "tslib": "^2.6.2" - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "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==" - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "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==" - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "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==" - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "kafkajs": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/kafkajs/-/kafkajs-2.2.4.tgz", - "integrity": "sha512-j/YeapB1vfPT2iOIUn/vxdyKEuhuY2PxMBvf5JWux6iSaukAccrMtXEY/Lb7OvavDhOWME589bpLrEdnVHjfjA==" - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" - }, - "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", - "requires": { - "mime-db": "1.47.0" - } - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" - }, - "module-alias": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz", - "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==" - }, - "mqtt": { - "version": "5.10.1", - "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.10.1.tgz", - "integrity": "sha512-hXCOki8sANoQ7w+2OzJzg6qMBxTtrH9RlnVNV8panLZgnl+Gh0J/t4k6r8Az8+C7y3KAcyXtn0mmLixyUom8Sw==", - "requires": { - "@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-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" - }, - "dependencies": { - "debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "requires": { - "ms": "^2.1.3" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "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==", - "requires": { - "bl": "^6.0.8", - "debug": "^4.3.4", - "process-nextick-args": "^2.0.1" - }, - "dependencies": { - "debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "requires": { - "ms": "^2.1.3" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" - }, - "nodemailer": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.6.0.tgz", - "integrity": "sha512-ikSMDU1nZqpo2WUPE0wTTw/NGGImTkwpJKDIFPZT+YvvR9Sj+ze5wzu95JHkBMglQLoG2ITxU21WukCC/XsFkg==" - }, - "number-allocator": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz", - "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==", - "requires": { - "debug": "^4.3.1", - "js-sdsl": "4.3.0" - }, - "dependencies": { - "debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "requires": { - "ms": "^2.1.3" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "oracledb": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/oracledb/-/oracledb-4.2.0.tgz", - "integrity": "sha512-07ZylNcUB9wknsiRa7dNqDWgGK3loP8eNWuoCjsiCOZ19PA1g8QLu+0gah7ty82VXl/MOQYFCMl5OpjD9Aqjcw==" - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "pg": { - "version": "8.13.1", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.13.1.tgz", - "integrity": "sha512-OUir1A0rPNZlX//c7ksiu7crsGZTKSOXJPgtNiHGIlC9H0lO+NC6ZDYksSgBYY/thSWhnSRBv8w1lieNNGATNQ==", - "requires": { - "pg-cloudflare": "^1.1.1", - "pg-connection-string": "^2.7.0", - "pg-pool": "^3.7.0", - "pg-protocol": "^1.7.0", - "pg-types": "^2.1.0", - "pgpass": "1.x" - } - }, - "pg-cloudflare": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", - "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", - "optional": true - }, - "pg-connection-string": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.7.0.tgz", - "integrity": "sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==" - }, - "pg-int8": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" - }, - "pg-pool": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.7.0.tgz", - "integrity": "sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g==", - "requires": {} - }, - "pg-protocol": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.7.0.tgz", - "integrity": "sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ==" - }, - "pg-types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", - "requires": { - "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" - } - }, - "pgpass": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", - "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", - "requires": { - "split2": "^4.1.0" - } - }, - "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==" - }, - "postgres-bytea": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==" - }, - "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==" - }, - "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==", - "requires": { - "xtend": "^4.0.0" - } - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" - }, - "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==" - }, - "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - } - }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - }, - "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==" - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "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==", - "requires": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - } - }, - "regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - }, - "reinterval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", - "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - } - } - }, - "request-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz", - "integrity": "sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==", - "requires": { - "bluebird": "^3.5.0", - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - } - }, - "request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "requires": { - "lodash": "^4.17.19" - } - }, - "rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" - }, - "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==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" - }, - "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==", - "requires": { - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "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==" - } - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typecast": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/typecast/-/typecast-0.0.1.tgz", - "integrity": "sha1-//t13La98d744pO2tuiT1sHtGd4=" - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" - }, - "undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "validate": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/validate/-/validate-5.1.0.tgz", - "integrity": "sha512-Y+vJv+xR3XsaQM8W1rQvwc6is/sgCUBv3lvNKc2DZ1HcVcEWAaHVSFB5uoxkQnw2riUq77Rg5nv1u8YuuSu/Zw==", - "requires": { - "component-type": "1.2.1", - "eivindfjeldstad-dot": "0.0.1", - "typecast": "0.0.1" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "worker-timers": { - "version": "7.1.8", - "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-7.1.8.tgz", - "integrity": "sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw==", - "requires": { - "@babel/runtime": "^7.24.5", - "tslib": "^2.6.2", - "worker-timers-broker": "^6.1.8", - "worker-timers-worker": "^7.0.71" - } - }, - "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==", - "requires": { - "@babel/runtime": "^7.24.5", - "fast-unique-numbers": "^8.0.13", - "tslib": "^2.6.2", - "worker-timers-worker": "^7.0.71" - } - }, - "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==", - "requires": { - "@babel/runtime": "^7.24.5", - "tslib": "^2.6.2" - } - }, - "ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "requires": {} - }, - "xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - }, - "xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - } } } diff --git a/package.json b/package.json index 01c068f..6c72899 100644 --- a/package.json +++ b/package.json @@ -18,24 +18,18 @@ }, "homepage": "https://git.citpb.ru/CITKParus/P8-ExchangeService/", "dependencies": { - "body-parser": "^1.19.0", "cors": "^2.8.5", - "express": "^4.17.1", + "express": "^5.2.1", "kafkajs": "^2.2.4", - "lodash": "^4.17.19", - "module-alias": "^2.2.2", "mqtt": "^5.10.1", - "nodemailer": "^6.4.11", - "oracledb": "^4.2.0", + "nodemailer": "^6.9.16", + "oracledb": "^6.6.0", "pg": "^8.13.1", - "request": "^2.88.2", - "request-promise": "^4.2.6", + "undici": "^6.0.0", "validate": "^5.1.0", - "xml2js": "^0.4.23" + "xml2js": "^0.6.2" }, - "_moduleAliases": { - "@core": "core", - "@modules": "modules", - "@models": "models" + "engines": { + "node": ">=22" } }