From 72ea6ee76a248ecc7c2a390e240c2cafc00c317f Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Fri, 3 Nov 2023 16:05:46 +0300 Subject: [PATCH 01/12] Checking the config during dev and deploy --- package-lock.json | 36 ----------------------------------- package.json | 1 - src/handlers/adminHandlers.js | 8 ++++++-- src/index.js | 10 ++++++++-- 4 files changed, 14 insertions(+), 41 deletions(-) diff --git a/package-lock.json b/package-lock.json index d6d4f9a..bb1925f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,6 @@ "dependencies": { "@ffmpeg-installer/ffmpeg": "^1.1.0", "axios": "^1.6.0", - "config": "^3.3.9", "fluent-ffmpeg": "^2.1.2", "openai": "^3.2.1", "telegraf": "^4.12.2" @@ -293,17 +292,6 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/config": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/config/-/config-3.3.9.tgz", - "integrity": "sha512-G17nfe+cY7kR0wVpc49NCYvNtelm/pPy8czHoFkAgtV1lkmcp7DHtWCdDu+C9Z7gb2WVqa9Tm3uF9aKaPbCfhg==", - "dependencies": { - "json5": "^2.2.3" - }, - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -502,17 +490,6 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -1077,14 +1054,6 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "config": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/config/-/config-3.3.9.tgz", - "integrity": "sha512-G17nfe+cY7kR0wVpc49NCYvNtelm/pPy8czHoFkAgtV1lkmcp7DHtWCdDu+C9Z7gb2WVqa9Tm3uF9aKaPbCfhg==", - "requires": { - "json5": "^2.2.3" - } - }, "cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -1223,11 +1192,6 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" - }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", diff --git a/package.json b/package.json index 6680eeb..277a1f4 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,6 @@ "dependencies": { "@ffmpeg-installer/ffmpeg": "^1.1.0", "axios": "^1.6.0", - "config": "^3.3.9", "fluent-ffmpeg": "^2.1.2", "openai": "^3.2.1", "telegraf": "^4.12.2" diff --git a/src/handlers/adminHandlers.js b/src/handlers/adminHandlers.js index 4527eae..16916a8 100644 --- a/src/handlers/adminHandlers.js +++ b/src/handlers/adminHandlers.js @@ -15,8 +15,12 @@ export const addHandler = (config, callback) => { } config.USERS_ID += `,${requestText}`; - - fs.writeFileSync('config/production.json', JSON.stringify(config), 'utf8'); + if (process.env.NODE_ENV === "production") { + fs.writeFileSync('config/production.json', JSON.stringify(config), 'utf8'); + } else { + fs.writeFileSync('config/default.json', JSON.stringify(config), 'utf8'); + } + callback(config); ctx.reply(LEXICON_EN['add']); diff --git a/src/index.js b/src/index.js index 99eb2e6..b9028a7 100644 --- a/src/index.js +++ b/src/index.js @@ -17,7 +17,13 @@ import { addHandler, showHandler } from "./handlers/adminHandlers.js"; const sessions = {}; -let config = JSON.parse(fs.readFileSync('config/production.json', 'utf8')); +let config; + +if (process.env.NODE_ENV === "production") { + config = JSON.parse(fs.readFileSync('config/production.json', 'utf8')); +} else { + config = JSON.parse(fs.readFileSync('config/default.json', 'utf8')); +} const bot = new Telegraf(config.BOT_TOKEN); @@ -55,4 +61,4 @@ process.once("SIGINT", () => bot.stop("SIGINT")); process.once("SIGTERM", () => bot.stop("SIGTERM")); bot.launch({ dropPendingUpdates: true }) - .then(sendMessages(bot, await getUsersArray(config))); +// .then(sendMessages(bot, await getUsersArray(config))); From 3f7bd6072c1790cf410501d2f7ff11876258e161 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Fri, 3 Nov 2023 19:12:47 +0300 Subject: [PATCH 02/12] Added error catching for TimeoutError handler --- src/index.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/index.js b/src/index.js index b9028a7..d2cd97e 100644 --- a/src/index.js +++ b/src/index.js @@ -3,10 +3,10 @@ import { message } from "telegraf/filters"; import fs from 'fs'; import { getUsersArray } from "./utils/checkAccess.js"; +import { sendMessages } from "./utils/sendMessages.js"; import { LEXICON_EN } from "./lexicon/lexicon_en.js"; import { setMenu } from "./keyboards/set_menu.js"; import { deleteWebHook } from "./utils/deleteWebhook.js"; -import { sendMessages } from "./utils/sendMessages.js"; import { startHandler, helpHandler, chatIDHandler, @@ -25,7 +25,7 @@ if (process.env.NODE_ENV === "production") { config = JSON.parse(fs.readFileSync('config/default.json', 'utf8')); } -const bot = new Telegraf(config.BOT_TOKEN); +const bot = new Telegraf(config.BOT_TOKEN, {handlerTimeout: 15_000_000}); const updateConfigValue = (updatedConfig) => { @@ -53,9 +53,14 @@ bot.hears(LEXICON_EN["reset_btn"], newHandler(config, sessions)); bot.on(message("text"), textHandler(config, sessions)); bot.on(message("voice"), voiceHandler(config, sessions)); +bot.catch((error, ctx) => { + if (error.name === 'TimeoutError') { + return ctx.reply(LEXICON_EN['waiting']); + } +}); -setMenu(bot); -deleteWebHook(bot); +// setMenu(bot); +// deleteWebHook(bot); process.once("SIGINT", () => bot.stop("SIGINT")); process.once("SIGTERM", () => bot.stop("SIGTERM")); From e8f893e7be26b853acfa0eb87ec49ff184c8d5e6 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Fri, 3 Nov 2023 19:14:08 +0300 Subject: [PATCH 03/12] Interim changes --- package-lock.json | 36 +++++++++++++++++++++++++++++++++++ package.json | 1 + src/handlers/adminHandlers.js | 27 ++++++++++++++++++++------ src/handlers/otherHandlers.js | 13 +++++++++---- src/lexicon/lexicon_en.js | 1 + src/openai.js | 2 +- src/utils/textFilter.js | 9 +++++++++ 7 files changed, 78 insertions(+), 11 deletions(-) create mode 100644 src/utils/textFilter.js diff --git a/package-lock.json b/package-lock.json index bb1925f..d6d4f9a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "@ffmpeg-installer/ffmpeg": "^1.1.0", "axios": "^1.6.0", + "config": "^3.3.9", "fluent-ffmpeg": "^2.1.2", "openai": "^3.2.1", "telegraf": "^4.12.2" @@ -292,6 +293,17 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/config": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/config/-/config-3.3.9.tgz", + "integrity": "sha512-G17nfe+cY7kR0wVpc49NCYvNtelm/pPy8czHoFkAgtV1lkmcp7DHtWCdDu+C9Z7gb2WVqa9Tm3uF9aKaPbCfhg==", + "dependencies": { + "json5": "^2.2.3" + }, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -490,6 +502,17 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -1054,6 +1077,14 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "config": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/config/-/config-3.3.9.tgz", + "integrity": "sha512-G17nfe+cY7kR0wVpc49NCYvNtelm/pPy8czHoFkAgtV1lkmcp7DHtWCdDu+C9Z7gb2WVqa9Tm3uF9aKaPbCfhg==", + "requires": { + "json5": "^2.2.3" + } + }, "cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -1192,6 +1223,11 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", diff --git a/package.json b/package.json index 277a1f4..6680eeb 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "dependencies": { "@ffmpeg-installer/ffmpeg": "^1.1.0", "axios": "^1.6.0", + "config": "^3.3.9", "fluent-ffmpeg": "^2.1.2", "openai": "^3.2.1", "telegraf": "^4.12.2" diff --git a/src/handlers/adminHandlers.js b/src/handlers/adminHandlers.js index 16916a8..a02eef6 100644 --- a/src/handlers/adminHandlers.js +++ b/src/handlers/adminHandlers.js @@ -1,11 +1,12 @@ import fs from 'fs'; import { LEXICON_EN } from "../lexicon/lexicon_en.js"; +import { getUsersArray } from '../utils/checkAccess.js'; export const addHandler = (config, callback) => { return async (ctx) => { if (ctx.from.id == config.SUPER_USER) { try { - const requestText = ctx.message.text + const requestText = await ctx.message.text .replace("/add", "") .trim(); @@ -21,15 +22,15 @@ export const addHandler = (config, callback) => { fs.writeFileSync('config/default.json', JSON.stringify(config), 'utf8'); } - callback(config); + await callback(config); - ctx.reply(LEXICON_EN['add']); + await ctx.reply(LEXICON_EN['add']); ctx.telegram.sendMessage(requestText, LEXICON_EN['added']); } catch(e) { console.log(LEXICON_EN['errorSending'], requestText); } } else { - ctx.reply(LEXICON_EN['super']); + await ctx.reply(LEXICON_EN['super']); } } }; @@ -37,9 +38,23 @@ export const addHandler = (config, callback) => { export const showHandler = (config) => { return async (ctx) => { if (ctx.from.id == config.SUPER_USER) { - await ctx.reply(config.USERS_ID); + let usersExists = ""; + const users = await getUsersArray(config); + + users.forEach((userId) => { + ctx.telegram + .getChatMember(ctx.chat.id, userId) + .then((chatMember) => { + usersExists += `${userId},`; + console.log(usersExists); + console.log(`ID ${userId} exists`); + }) + .catch((error) => { + console.log(`ID ${userId} does not exist: ${error}`); + }); + }); } else { - ctx.reply(LEXICON_EN['super']); + await ctx.reply(LEXICON_EN['super']); } } } \ No newline at end of file diff --git a/src/handlers/otherHandlers.js b/src/handlers/otherHandlers.js index 61d756c..e446bd3 100644 --- a/src/handlers/otherHandlers.js +++ b/src/handlers/otherHandlers.js @@ -7,6 +7,8 @@ import { converter } from '../converter.js'; import { createInitialSession } from '../utils/createSession.js'; import { checkAccess } from '../utils/checkAccess.js'; +import { textFormat } from '../utils/textFilter.js'; + export const textHandler = (config, sessions) => { return async (ctx) => { if (await checkAccess(config, ctx)) return; @@ -30,13 +32,15 @@ export const textHandler = (config, sessions) => { role: openai.roles.ASSISTANT, content: response.content, }); - await ctx.reply(response.content); + + await ctx.reply(response.content, { parse_mode: 'MarkdownV2' }); + } else { await ctx.reply(LEXICON_EN['manyRequests']); } } catch (error) { console.log(await printError(error)); - await ctx.reply(LEXICON_EN['noResponce']); + await ctx.reply(`${LEXICON_EN['noResponce']}\n\n${error.message}`); } }; }; @@ -68,13 +72,14 @@ export const voiceHandler = (config, sessions) => { role: openai.roles.ASSISTANT, content: response.content, }); - await ctx.reply(response.content); + + await ctx.reply(response.content, { parse_mode: 'MarkdownV2' }); } else { await ctx.reply(LEXICON_EN['manyRequests']); } } catch (error) { console.log(printError(error)); - await ctx.reply(LEXICON_EN['noResponce']); + await ctx.reply(`${LEXICON_EN['noResponce']}\n${error.name}: ${error.message}`); } }; }; diff --git a/src/lexicon/lexicon_en.js b/src/lexicon/lexicon_en.js index 8b3d070..478cf9a 100644 --- a/src/lexicon/lexicon_en.js +++ b/src/lexicon/lexicon_en.js @@ -36,6 +36,7 @@ export const LEXICON_EN = { remove: 'user ID deleted ⏫', super: 'You are not a super user 🔒', errorSending: 'Error sending message to: ', + waiting: 'The server timed out waiting for a response ⚠️', }; export const getIDs = async (chatId, userId) => { diff --git a/src/openai.js b/src/openai.js index b248934..6d2a723 100644 --- a/src/openai.js +++ b/src/openai.js @@ -52,7 +52,7 @@ class OpenAI { }); const image_url = response.data.data[0].url; - console.log(image_url); + return image_url; } catch (error) { console.log(printError(error)); diff --git a/src/utils/textFilter.js b/src/utils/textFilter.js new file mode 100644 index 0000000..d027c97 --- /dev/null +++ b/src/utils/textFilter.js @@ -0,0 +1,9 @@ +export const textFormat = async (text) => { + let output = text; + + output = output.replace(/!/g, "\\!"); + output = output.replace(/\./g, "\\!"); + output = output.replace(/_([^_]+)_/g, "$1"); + output = output.replace(/\*([^*]+)\*/g, "$1"); + return output; +}; From 48fc8372255c0b1533aa0b0347e2d1a73cc3e513 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Fri, 3 Nov 2023 23:18:04 +0300 Subject: [PATCH 04/12] fix: fixed a bug with TimeoutError --- .../{otherHandlers.js => openaiHandlers.js} | 55 +++++++++++++++---- src/handlers/userHandlers.js | 33 ----------- src/index.js | 30 +++++----- 3 files changed, 61 insertions(+), 57 deletions(-) rename src/handlers/{otherHandlers.js => openaiHandlers.js} (63%) diff --git a/src/handlers/otherHandlers.js b/src/handlers/openaiHandlers.js similarity index 63% rename from src/handlers/otherHandlers.js rename to src/handlers/openaiHandlers.js index e446bd3..35fde74 100644 --- a/src/handlers/otherHandlers.js +++ b/src/handlers/openaiHandlers.js @@ -7,7 +7,7 @@ import { converter } from '../converter.js'; import { createInitialSession } from '../utils/createSession.js'; import { checkAccess } from '../utils/checkAccess.js'; -import { textFormat } from '../utils/textFilter.js'; +// import { textFormat } from '../utils/textFilter.js'; export const textHandler = (config, sessions) => { return async (ctx) => { @@ -15,8 +15,9 @@ export const textHandler = (config, sessions) => { const sessionId = ctx.message.chat.id; sessions[sessionId] ??= createInitialSession(); + + const processing = await ctx.reply(code(LEXICON_EN['processing'])); try { - const processing = await ctx.reply(code(LEXICON_EN['processing'])); const text = ctx.message.text; sessions[sessionId].messages.push({ role: openai.roles.USER, @@ -25,7 +26,7 @@ export const textHandler = (config, sessions) => { const response = await openai.chat(sessions[sessionId].messages); - await ctx.deleteMessage(processing.message_id); + if (response && response.content) { sessions[sessionId].messages.push({ @@ -33,14 +34,16 @@ export const textHandler = (config, sessions) => { content: response.content, }); - await ctx.reply(response.content, { parse_mode: 'MarkdownV2' }); - + await ctx.reply(response.content); + // await ctx.reply(response.content, { parse_mode: 'MarkdownV2' }); } else { await ctx.reply(LEXICON_EN['manyRequests']); } } catch (error) { console.log(await printError(error)); await ctx.reply(`${LEXICON_EN['noResponce']}\n\n${error.message}`); + } finally { + await ctx.deleteMessage(processing.message_id); } }; }; @@ -51,8 +54,9 @@ export const voiceHandler = (config, sessions) => { const sessionId = ctx.message.chat.id; sessions[sessionId] ??= createInitialSession(); + + const processing = await ctx.reply(code(LEXICON_EN['processing'])); try { - const processing = await ctx.reply(code(LEXICON_EN['processing'])); const link = await ctx.telegram.getFileLink(ctx.message.voice.file_id); const userId = String(ctx.message.from.id); const oggPath = await converter.create(link.href, userId); @@ -64,22 +68,53 @@ export const voiceHandler = (config, sessions) => { }); const response = await openai.chat(sessions[sessionId].messages); - - await ctx.deleteMessage(processing.message_id); if (response && response.content) { sessions[sessionId].messages.push({ role: openai.roles.ASSISTANT, content: response.content, }); - - await ctx.reply(response.content, { parse_mode: 'MarkdownV2' }); + await ctx.reply(response.content); + // await ctx.reply(response.content, { parse_mode: 'MarkdownV2' }); } else { await ctx.reply(LEXICON_EN['manyRequests']); } } catch (error) { console.log(printError(error)); await ctx.reply(`${LEXICON_EN['noResponce']}\n${error.name}: ${error.message}`); + } finally { + await ctx.deleteMessage(processing.message_id); } }; }; + +export const imageHandler = (config) => { + return async (ctx) => { + if (await checkAccess(config, ctx)) return; + + const requestText = ctx.message.text + .replace("/image", "") + .trim(); + + if (!requestText){ + await ctx.reply(LEXICON_EN['empty'], { parse_mode: "HTML" }); + return; + } + + const processing = await ctx.reply(code(LEXICON_EN["processing"])); + + const size = "1024x1024"; + const count = 1; + + const imageUrl = await openai.getImage(requestText, size, count); + + await ctx.deleteMessage(processing.message_id); + + if (imageUrl) { + await ctx.replyWithPhoto({ url: imageUrl }, { caption: requestText }); + return; + } + + await ctx.reply(LEXICON_EN["security"]); + }; +}; diff --git a/src/handlers/userHandlers.js b/src/handlers/userHandlers.js index d6dc94b..95c357d 100644 --- a/src/handlers/userHandlers.js +++ b/src/handlers/userHandlers.js @@ -1,7 +1,5 @@ import { LEXICON_EN, getIDs, getHelp, printPassword } from "../lexicon/lexicon_en.js"; import { createMenuKeyboard } from "../keyboards/keyboards.js"; -import { code } from "telegraf/format"; -import { openai } from "../openai.js"; import { createInitialSession } from "../utils/createSession.js"; import { checkAccess } from "../utils/checkAccess.js"; @@ -53,34 +51,3 @@ export const newHandler = (config, sessions) => { await ctx.reply(LEXICON_EN["reset"], menuKeyboard); }; }; - -export const imageHandler = (config) => { - return async (ctx) => { - if (await checkAccess(config, ctx)) return; - - const requestText = ctx.message.text - .replace("/image", "") - .trim(); - - if (!requestText){ - await ctx.reply(LEXICON_EN['empty'], { parse_mode: "HTML" }); - return; - } - - const processing = await ctx.reply(code(LEXICON_EN["processing"])); - - const size = "1024x1024"; - const count = 1; - - const imageUrl = await openai.getImage(requestText, size, count); - - await ctx.deleteMessage(processing.message_id); - - if (imageUrl) { - await ctx.replyWithPhoto({ url: imageUrl }, { caption: requestText }); - return; - } - - await ctx.reply(LEXICON_EN["security"]); - }; -}; diff --git a/src/index.js b/src/index.js index d2cd97e..738118e 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,6 @@ import { Telegraf, session } from "telegraf"; import { message } from "telegraf/filters"; -import fs from 'fs'; +import fs from "fs"; import { getUsersArray } from "./utils/checkAccess.js"; import { sendMessages } from "./utils/sendMessages.js"; @@ -9,10 +9,13 @@ import { setMenu } from "./keyboards/set_menu.js"; import { deleteWebHook } from "./utils/deleteWebhook.js"; import { - startHandler, helpHandler, chatIDHandler, - newHandler, imageHandler, passwordHandler, + startHandler, + helpHandler, + chatIDHandler, + newHandler, + passwordHandler, } from "./handlers/userHandlers.js"; -import { textHandler, voiceHandler } from "./handlers/otherHandlers.js"; +import { textHandler, voiceHandler, imageHandler } from "./handlers/openaiHandlers.js"; import { addHandler, showHandler } from "./handlers/adminHandlers.js"; const sessions = {}; @@ -20,13 +23,12 @@ const sessions = {}; let config; if (process.env.NODE_ENV === "production") { - config = JSON.parse(fs.readFileSync('config/production.json', 'utf8')); + config = JSON.parse(fs.readFileSync("config/production.json", "utf8")); } else { - config = JSON.parse(fs.readFileSync('config/default.json', 'utf8')); + config = JSON.parse(fs.readFileSync("config/default.json", "utf8")); } -const bot = new Telegraf(config.BOT_TOKEN, {handlerTimeout: 15_000_000}); - +const bot = new Telegraf(config.BOT_TOKEN, { handlerTimeout: 12_000_000 }); const updateConfigValue = (updatedConfig) => { config = updatedConfig; @@ -53,17 +55,17 @@ bot.hears(LEXICON_EN["reset_btn"], newHandler(config, sessions)); bot.on(message("text"), textHandler(config, sessions)); bot.on(message("voice"), voiceHandler(config, sessions)); -bot.catch((error, ctx) => { - if (error.name === 'TimeoutError') { - return ctx.reply(LEXICON_EN['waiting']); +bot.catch(async (error, ctx) => { + if (error.name === "TimeoutError") { + return ctx.reply(LEXICON_EN["waiting"]); } }); -// setMenu(bot); -// deleteWebHook(bot); +setMenu(bot); +deleteWebHook(bot); process.once("SIGINT", () => bot.stop("SIGINT")); process.once("SIGTERM", () => bot.stop("SIGTERM")); bot.launch({ dropPendingUpdates: true }) -// .then(sendMessages(bot, await getUsersArray(config))); + .then(sendMessages(bot, await getUsersArray(config))); From 787cf8523fd818a6d2bb83864c3b6fac24dd95a5 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Sat, 4 Nov 2023 00:21:17 +0300 Subject: [PATCH 05/12] fix: added check to adding users & funs for checks --- src/handlers/adminHandlers.js | 37 ++++++++++++++++++----------------- src/index.js | 8 ++++---- src/lexicon/lexicon_en.js | 1 + src/utils/usersCheck.js | 28 ++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 22 deletions(-) create mode 100644 src/utils/usersCheck.js diff --git a/src/handlers/adminHandlers.js b/src/handlers/adminHandlers.js index a02eef6..26a4b09 100644 --- a/src/handlers/adminHandlers.js +++ b/src/handlers/adminHandlers.js @@ -1,12 +1,13 @@ import fs from 'fs'; import { LEXICON_EN } from "../lexicon/lexicon_en.js"; import { getUsersArray } from '../utils/checkAccess.js'; +import { existUser, getExistsUsers } from '../utils/usersCheck.js'; export const addHandler = (config, callback) => { return async (ctx) => { if (ctx.from.id == config.SUPER_USER) { try { - const requestText = await ctx.message.text + const requestText = ctx.message.text .replace("/add", "") .trim(); @@ -15,17 +16,26 @@ export const addHandler = (config, callback) => { return; } + const userExistence = await existUser(requestText, ctx); + + if (!userExistence){ + await ctx.reply(LEXICON_EN['noUser'], { parse_mode: "HTML" }); + return; + } + config.USERS_ID += `,${requestText}`; + if (process.env.NODE_ENV === "production") { - fs.writeFileSync('config/production.json', JSON.stringify(config), 'utf8'); + fs.writeFileSync('config/production.json', JSON.stringify(config, null, 2), 'utf8'); } else { - fs.writeFileSync('config/default.json', JSON.stringify(config), 'utf8'); + fs.writeFileSync('config/default.json', JSON.stringify(config, null, 2), 'utf8'); } - + await callback(config); await ctx.reply(LEXICON_EN['add']); - ctx.telegram.sendMessage(requestText, LEXICON_EN['added']); + await ctx.telegram.sendMessage(requestText, LEXICON_EN['added']); + } catch(e) { console.log(LEXICON_EN['errorSending'], requestText); } @@ -38,21 +48,12 @@ export const addHandler = (config, callback) => { export const showHandler = (config) => { return async (ctx) => { if (ctx.from.id == config.SUPER_USER) { - let usersExists = ""; const users = await getUsersArray(config); + let usersExists = await getExistsUsers(users, ctx); + usersExists = usersExists.slice(0, -1); - users.forEach((userId) => { - ctx.telegram - .getChatMember(ctx.chat.id, userId) - .then((chatMember) => { - usersExists += `${userId},`; - console.log(usersExists); - console.log(`ID ${userId} exists`); - }) - .catch((error) => { - console.log(`ID ${userId} does not exist: ${error}`); - }); - }); + config.USERS_ID = usersExists; + console.log(config); } else { await ctx.reply(LEXICON_EN['super']); } diff --git a/src/index.js b/src/index.js index 738118e..2044c81 100644 --- a/src/index.js +++ b/src/index.js @@ -30,7 +30,7 @@ if (process.env.NODE_ENV === "production") { const bot = new Telegraf(config.BOT_TOKEN, { handlerTimeout: 12_000_000 }); -const updateConfigValue = (updatedConfig) => { +const updateConfigValue = async (updatedConfig) => { config = updatedConfig; }; @@ -61,11 +61,11 @@ bot.catch(async (error, ctx) => { } }); -setMenu(bot); -deleteWebHook(bot); +// setMenu(bot); +// deleteWebHook(bot); process.once("SIGINT", () => bot.stop("SIGINT")); process.once("SIGTERM", () => bot.stop("SIGTERM")); bot.launch({ dropPendingUpdates: true }) - .then(sendMessages(bot, await getUsersArray(config))); +// .then(sendMessages(bot, await getUsersArray(config))); diff --git a/src/lexicon/lexicon_en.js b/src/lexicon/lexicon_en.js index 478cf9a..f7e8c36 100644 --- a/src/lexicon/lexicon_en.js +++ b/src/lexicon/lexicon_en.js @@ -37,6 +37,7 @@ export const LEXICON_EN = { super: 'You are not a super user 🔒', errorSending: 'Error sending message to: ', waiting: 'The server timed out waiting for a response ⚠️', + noUser: 'There is no user with this ID ⚠️', }; export const getIDs = async (chatId, userId) => { diff --git a/src/utils/usersCheck.js b/src/utils/usersCheck.js new file mode 100644 index 0000000..0115403 --- /dev/null +++ b/src/utils/usersCheck.js @@ -0,0 +1,28 @@ +export const getExistsUsers = async (users, ctx) => { + let usersExists = ""; + + for (const userId of users) { + try { + await ctx.telegram.getChatMember(ctx.chat.id, userId); + usersExists += `${userId},`; + console.log(`ID ${userId} exists`); + } catch (error) { + console.log(`ID ${userId} does not exist: ${error}`); + } + } + + return usersExists; +}; + +export const existUser = async (userID, ctx) => { + try { + await ctx.telegram.getChatMember(ctx.chat.id, userID); + return true; + } catch (error) { + console.log(error.message); + return false; + } +}; + + + From 42ae2b3f5d3dcac77ebd9b7a5cd75eac16550eec Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Sat, 4 Nov 2023 14:55:38 +0300 Subject: [PATCH 06/12] feat: added command to view list of users --- src/handlers/adminHandlers.js | 69 +++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/src/handlers/adminHandlers.js b/src/handlers/adminHandlers.js index 26a4b09..8c2a5c7 100644 --- a/src/handlers/adminHandlers.js +++ b/src/handlers/adminHandlers.js @@ -1,61 +1,74 @@ import fs from 'fs'; -import { LEXICON_EN } from "../lexicon/lexicon_en.js"; +import { LEXICON_EN } from '../lexicon/lexicon_en.js'; import { getUsersArray } from '../utils/checkAccess.js'; -import { existUser, getExistsUsers } from '../utils/usersCheck.js'; export const addHandler = (config, callback) => { return async (ctx) => { if (ctx.from.id == config.SUPER_USER) { try { - const requestText = ctx.message.text - .replace("/add", "") - .trim(); - - if (!requestText){ - await ctx.reply(LEXICON_EN['emptyAdd'], { parse_mode: "HTML" }); - return; - } - - const userExistence = await existUser(requestText, ctx); + const requestText = parseInt(ctx.message.text + .replace('/add', '') + .trim()); - if (!userExistence){ - await ctx.reply(LEXICON_EN['noUser'], { parse_mode: "HTML" }); + if (!requestText) { + await ctx.reply(LEXICON_EN['emptyAdd'], { parse_mode: 'HTML' }); return; } config.USERS_ID += `,${requestText}`; - if (process.env.NODE_ENV === "production") { - fs.writeFileSync('config/production.json', JSON.stringify(config, null, 2), 'utf8'); + if (process.env.NODE_ENV === 'production') { + fs.writeFileSync('config/production.json', + JSON.stringify(config, null, 2), 'utf8'); } else { - fs.writeFileSync('config/default.json', JSON.stringify(config, null, 2), 'utf8'); + fs.writeFileSync('config/default.json', + JSON.stringify(config, null, 2), 'utf8'); } await callback(config); - await ctx.reply(LEXICON_EN['add']); - await ctx.telegram.sendMessage(requestText, LEXICON_EN['added']); + const output =`Added ID: ${requestText}\n\n` + + `${LEXICON_EN['add']}`; - } catch(e) { + ctx.reply(output, { parse_mode: 'HTML' }); + } catch (e) { console.log(LEXICON_EN['errorSending'], requestText); } } else { - await ctx.reply(LEXICON_EN['super']); + await ctx.reply(LEXICON_EN['super']); } - } + }; }; export const showHandler = (config) => { return async (ctx) => { if (ctx.from.id == config.SUPER_USER) { const users = await getUsersArray(config); - let usersExists = await getExistsUsers(users, ctx); - usersExists = usersExists.slice(0, -1); - config.USERS_ID = usersExists; - console.log(config); + const uniqueIDs = [...new Set(users)]; + + config.USERS_ID = uniqueIDs.join(','); + + if (process.env.NODE_ENV === 'production') { + fs.writeFileSync('config/production.json', + JSON.stringify(config, null, 2), 'utf8'); + } else { + fs.writeFileSync('config/default.json', + JSON.stringify(config, null, 2), 'utf8'); + } + + let output = '🗃 Bot users:\n\n'; + + uniqueIDs.forEach( + (id) => { + output += `👤 ${id}\n`; + }); + + await ctx.reply(output, { parse_mode: 'HTML' }); + + await callback(config); } else { await ctx.reply(LEXICON_EN['super']); } - } -} \ No newline at end of file + }; +}; From 0bba1c7e83cb0d8ff8542dcb2977a73f81c7826c Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Sat, 4 Nov 2023 14:56:21 +0300 Subject: [PATCH 07/12] fix: added a linter and fixed some bugs --- .eslintrc.cjs | 34 + package-lock.json | 1851 +++++++++++++++++++++++++++++++- package.json | 2 + src/converter.js | 24 +- src/handlers/openaiHandlers.js | 26 +- src/handlers/userHandlers.js | 25 +- src/index.js | 73 +- src/keyboards/keyboards.js | 6 +- src/keyboards/set_menu.js | 14 +- src/lexicon/lexicon_en.js | 38 +- src/openai.js | 28 +- src/utils/checkAccess.js | 6 +- src/utils/deleteWebhook.js | 16 +- src/utils/generatePassword.js | 20 +- src/utils/sendMessages.js | 4 +- src/utils/textFilter.js | 9 - src/utils/usersCheck.js | 28 - 17 files changed, 2015 insertions(+), 189 deletions(-) create mode 100644 .eslintrc.cjs delete mode 100644 src/utils/textFilter.js delete mode 100644 src/utils/usersCheck.js diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..20c8ac8 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,34 @@ +module.exports = { + 'env': { + 'browser': true, + 'es2021': true, + }, + 'extends': 'google', + 'overrides': [ + { + 'env': { + 'node': true, + }, + 'files': [ + '.eslintrc.{js,cjs}', + ], + 'parserOptions': { + 'sourceType': 'script', + }, + }, + ], + 'parserOptions': { + 'ecmaVersion': 'latest', + 'sourceType': 'module', + }, + 'rules': { + 'no-unused-vars': 1, + 'import/extensions': 0, + 'require-jsdoc': 0, + 'linebreak-style': 0, + 'object-curly-spacing': ['error', 'always'], + 'quotes': ['error', 'single'], + 'no-multi-str': 0, + 'guard-for-in': 0, + }, +}; diff --git a/package-lock.json b/package-lock.json index d6d4f9a..4ed831a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,9 +18,99 @@ }, "devDependencies": { "cross-env": "^7.0.3", + "eslint": "^8.53.0", + "eslint-config-google": "^0.14.0", "nodemon": "^2.0.22" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", + "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/eslintrc/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@eslint/js": { + "version": "8.53.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.53.0.tgz", + "integrity": "sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@ffmpeg-installer/darwin-arm64": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-arm64/-/darwin-arm64-4.1.5.tgz", @@ -138,11 +228,108 @@ "win32" ] }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@telegraf/types": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/@telegraf/types/-/types-6.9.1.tgz", "integrity": "sha512-bzqwhicZq401T0e09tu8b1KvGfJObPmzKU/iKCT5V466AsAZZWQrBYQ5edbmD1VZuHLEwopoOVY5wPP4HaLtug==" }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -160,6 +347,67 @@ "node": ">=6.5" } }, + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "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/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -173,6 +421,12 @@ "node": ">= 8" } }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "node_modules/async": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", @@ -249,6 +503,52 @@ "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==" }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -276,6 +576,24 @@ "fsevents": "~2.3.2" } }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -345,6 +663,12 @@ "ms": "^2.1.1" } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -353,6 +677,219 @@ "node": ">=0.4.0" } }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.53.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.53.0.tgz", + "integrity": "sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.3", + "@eslint/js": "8.53.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-google": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", + "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", @@ -361,6 +898,45 @@ "node": ">=6" } }, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -373,6 +949,42 @@ "node": ">=8" } }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", + "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, "node_modules/fluent-ffmpeg": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz", @@ -428,6 +1040,32 @@ "node": ">= 6" } }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -440,6 +1078,27 @@ "node": ">= 6" } }, + "node_modules/globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -449,12 +1108,62 @@ "node": ">=4" } }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", "dev": true }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -497,22 +1206,104 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -558,6 +1349,12 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, "node_modules/node-fetch": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", @@ -629,6 +1426,15 @@ "node": ">=0.10.0" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, "node_modules/openai": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/openai/-/openai-3.2.1.tgz", @@ -646,6 +1452,53 @@ "follow-redirects": "^1.14.8" } }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-timeout": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-4.1.0.tgz", @@ -654,6 +1507,36 @@ "node": ">=10" } }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -675,6 +1558,15 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -686,6 +1578,35 @@ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -698,6 +1619,63 @@ "node": ">=8.10.0" } }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safe-compare": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/safe-compare/-/safe-compare-1.1.4.tgz", @@ -765,6 +1743,30 @@ "semver": "bin/semver.js" } }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -819,6 +1821,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -848,12 +1856,45 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -882,9 +1923,88 @@ "engines": { "node": ">= 8" } + }, + "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==", + "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", + "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@eslint/js": { + "version": "8.53.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.53.0.tgz", + "integrity": "sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==", + "dev": true + }, "@ffmpeg-installer/darwin-arm64": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-arm64/-/darwin-arm64-4.1.5.tgz", @@ -948,23 +2068,135 @@ "integrity": "sha512-Drt5u2vzDnIONf4ZEkKtFlbvwj6rI3kxw1Ck9fpudmtgaZIHD4ucsWB2lCZBXRxJgXR+2IMSti+4rtM4C4rXgg==", "optional": true }, + "@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, "@telegraf/types": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/@telegraf/types/-/types-6.9.1.tgz", "integrity": "sha512-bzqwhicZq401T0e09tu8b1KvGfJObPmzKU/iKCT5V466AsAZZWQrBYQ5edbmD1VZuHLEwopoOVY5wPP4HaLtug==" }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "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" + } + }, + "acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "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" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, - "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==", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { - "event-target-shim": "^5.0.0" + "color-convert": "^2.0.1" } }, "anymatch": { @@ -977,6 +2209,12 @@ "picomatch": "^2.0.4" } }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "async": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", @@ -1047,6 +2285,39 @@ "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==" }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -1063,6 +2334,21 @@ "readdirp": "~3.6.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1114,16 +2400,209 @@ "ms": "^2.1.1" } }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "8.53.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.53.0.tgz", + "integrity": "sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.3", + "@eslint/js": "8.53.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "eslint-config-google": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", + "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", + "dev": true, + "requires": {} + }, + "eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true + }, + "espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "requires": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + } + }, + "esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, "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==" }, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1133,6 +2612,33 @@ "to-regex-range": "^5.0.1" } }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", + "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "dev": true, + "requires": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, "fluent-ffmpeg": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz", @@ -1167,6 +2673,26 @@ "mime-types": "^2.1.12" } }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -1176,18 +2702,71 @@ "is-glob": "^4.0.1" } }, + "globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true + }, "ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", "dev": true }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -1218,16 +2797,83 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "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==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, + "keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -1261,6 +2907,12 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, "node-fetch": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", @@ -1302,6 +2954,15 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, "openai": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/openai/-/openai-3.2.1.tgz", @@ -1321,11 +2982,64 @@ } } }, + "optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, "p-timeout": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-4.1.0.tgz", "integrity": "sha512-+/wmHtzJuWii1sXn3HCuH/FTwGhrp4tmJTxSKJbfS+vkipci6osxXM5mY0jUiRzWKMTgUT8l7HFbeSwZAynqHw==" }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -1338,6 +3052,12 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, "proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -1349,6 +3069,18 @@ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, + "punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -1358,6 +3090,36 @@ "picomatch": "^2.2.1" } }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, "safe-compare": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/safe-compare/-/safe-compare-1.1.4.tgz", @@ -1409,6 +3171,21 @@ } } }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -1448,6 +3225,12 @@ } } }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -1471,12 +3254,36 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, "undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -1499,6 +3306,18 @@ "requires": { "isexe": "^2.0.0" } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index 6680eeb..5595dda 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,8 @@ "homepage": "https://github.com/BLazzeD21/Node.js-ChatGPT-Bot#readme", "devDependencies": { "cross-env": "^7.0.3", + "eslint": "^8.53.0", + "eslint-config-google": "^0.14.0", "nodemon": "^2.0.22" }, "dependencies": { diff --git a/src/converter.js b/src/converter.js index db7052e..48b3b7c 100644 --- a/src/converter.js +++ b/src/converter.js @@ -18,22 +18,22 @@ class OggConverter { toMp3(input, output) { try { const outputPath = resolve( - __dirname, - '..', - dirname(input), - `${output}.mp3` + __dirname, + '..', + dirname(input), + `${output}.mp3`, ); return new Promise((resolve, reject) => { ffmpeg(input) - .inputOption('-t 30') - .output(outputPath) - .on('end', () => { - deleteFile(input); - resolve(outputPath); - }) - .on('error', (err) => reject(err.message)) - .run(); + .inputOption('-t 30') + .output(outputPath) + .on('end', () => { + deleteFile(input); + resolve(outputPath); + }) + .on('error', (err) => reject(err.message)) + .run(); }); } catch (error) { console.log('Error create:' + error.message); diff --git a/src/handlers/openaiHandlers.js b/src/handlers/openaiHandlers.js index 35fde74..61951b4 100644 --- a/src/handlers/openaiHandlers.js +++ b/src/handlers/openaiHandlers.js @@ -25,8 +25,7 @@ export const textHandler = (config, sessions) => { }); const response = await openai.chat(sessions[sessionId].messages); - - + if (response && response.content) { sessions[sessionId].messages.push({ @@ -43,7 +42,7 @@ export const textHandler = (config, sessions) => { console.log(await printError(error)); await ctx.reply(`${LEXICON_EN['noResponce']}\n\n${error.message}`); } finally { - await ctx.deleteMessage(processing.message_id); + await ctx.deleteMessage(processing.message_id); } }; }; @@ -68,7 +67,7 @@ export const voiceHandler = (config, sessions) => { }); const response = await openai.chat(sessions[sessionId].messages); - + if (response && response.content) { sessions[sessionId].messages.push({ role: openai.roles.ASSISTANT, @@ -81,9 +80,10 @@ export const voiceHandler = (config, sessions) => { } } catch (error) { console.log(printError(error)); - await ctx.reply(`${LEXICON_EN['noResponce']}\n${error.name}: ${error.message}`); + await ctx.reply(`${LEXICON_EN['noResponce']}\ + \n${error.name}: ${error.message}`); } finally { - await ctx.deleteMessage(processing.message_id); + await ctx.deleteMessage(processing.message_id); } }; }; @@ -93,17 +93,17 @@ export const imageHandler = (config) => { if (await checkAccess(config, ctx)) return; const requestText = ctx.message.text - .replace("/image", "") - .trim(); + .replace('/image', '') + .trim(); - if (!requestText){ - await ctx.reply(LEXICON_EN['empty'], { parse_mode: "HTML" }); + if (!requestText) { + await ctx.reply(LEXICON_EN['empty'], { parse_mode: 'HTML' }); return; } - const processing = await ctx.reply(code(LEXICON_EN["processing"])); + const processing = await ctx.reply(code(LEXICON_EN['processing'])); - const size = "1024x1024"; + const size = '1024x1024'; const count = 1; const imageUrl = await openai.getImage(requestText, size, count); @@ -115,6 +115,6 @@ export const imageHandler = (config) => { return; } - await ctx.reply(LEXICON_EN["security"]); + await ctx.reply(LEXICON_EN['security']); }; }; diff --git a/src/handlers/userHandlers.js b/src/handlers/userHandlers.js index 95c357d..400e6fd 100644 --- a/src/handlers/userHandlers.js +++ b/src/handlers/userHandlers.js @@ -1,9 +1,12 @@ -import { LEXICON_EN, getIDs, getHelp, printPassword } from "../lexicon/lexicon_en.js"; -import { createMenuKeyboard } from "../keyboards/keyboards.js"; +import { + LEXICON_EN, getIDs, + getHelp, printPassword, +} from '../lexicon/lexicon_en.js'; +import { createMenuKeyboard } from '../keyboards/keyboards.js'; -import { createInitialSession } from "../utils/createSession.js"; -import { checkAccess } from "../utils/checkAccess.js"; -import { generatePassword } from "../utils/generatePassword.js"; +import { createInitialSession } from '../utils/createSession.js'; +import { checkAccess } from '../utils/checkAccess.js'; +import { generatePassword } from '../utils/generatePassword.js'; const menuKeyboard = createMenuKeyboard(); @@ -11,7 +14,7 @@ export const startHandler = (sessions) => { return async (ctx) => { const sessionId = ctx.message.chat.id; sessions[sessionId] = createInitialSession(); - await ctx.reply(LEXICON_EN["start"], menuKeyboard); + await ctx.reply(LEXICON_EN['start'], menuKeyboard); }; }; @@ -28,9 +31,9 @@ export const chatIDHandler = () => { const chatId = ctx.message.chat.id; await ctx.reply( - await getIDs(chatId, userId), - { parse_mode: "HTML" }, - menuKeyboard + await getIDs(chatId, userId), + { parse_mode: 'HTML' }, + menuKeyboard, ); }; }; @@ -38,7 +41,7 @@ export const chatIDHandler = () => { export const passwordHandler = () => { return async (ctx) => { const password = await generatePassword(); - await ctx.reply(await printPassword(password), { parse_mode: "HTML" }); + await ctx.reply(await printPassword(password), { parse_mode: 'HTML' }); }; }; @@ -48,6 +51,6 @@ export const newHandler = (config, sessions) => { const sessionId = ctx.message.chat.id; sessions[sessionId] = createInitialSession(); - await ctx.reply(LEXICON_EN["reset"], menuKeyboard); + await ctx.reply(LEXICON_EN['reset'], menuKeyboard); }; }; diff --git a/src/index.js b/src/index.js index 2044c81..6e2f601 100644 --- a/src/index.js +++ b/src/index.js @@ -1,31 +1,30 @@ -import { Telegraf, session } from "telegraf"; -import { message } from "telegraf/filters"; -import fs from "fs"; +import { Telegraf, session } from 'telegraf'; +import { message } from 'telegraf/filters'; +import fs from 'fs'; -import { getUsersArray } from "./utils/checkAccess.js"; -import { sendMessages } from "./utils/sendMessages.js"; -import { LEXICON_EN } from "./lexicon/lexicon_en.js"; -import { setMenu } from "./keyboards/set_menu.js"; -import { deleteWebHook } from "./utils/deleteWebhook.js"; +import { getUsersArray } from './utils/checkAccess.js'; +import { sendMessages } from './utils/sendMessages.js'; +import { LEXICON_EN } from './lexicon/lexicon_en.js'; +import { setMenu } from './keyboards/set_menu.js'; +import { deleteWebHook } from './utils/deleteWebhook.js'; import { - startHandler, - helpHandler, - chatIDHandler, - newHandler, - passwordHandler, -} from "./handlers/userHandlers.js"; -import { textHandler, voiceHandler, imageHandler } from "./handlers/openaiHandlers.js"; -import { addHandler, showHandler } from "./handlers/adminHandlers.js"; + startHandler, helpHandler, chatIDHandler, + newHandler, passwordHandler, +} from './handlers/userHandlers.js'; +import { textHandler, voiceHandler, imageHandler, +} from './handlers/openaiHandlers.js'; +import { addHandler, showHandler, +} from './handlers/adminHandlers.js'; const sessions = {}; let config; -if (process.env.NODE_ENV === "production") { - config = JSON.parse(fs.readFileSync("config/production.json", "utf8")); +if (process.env.NODE_ENV === 'production') { + config = JSON.parse(fs.readFileSync('config/production.json', 'utf8')); } else { - config = JSON.parse(fs.readFileSync("config/default.json", "utf8")); + config = JSON.parse(fs.readFileSync('config/default.json', 'utf8')); } const bot = new Telegraf(config.BOT_TOKEN, { handlerTimeout: 12_000_000 }); @@ -36,36 +35,36 @@ const updateConfigValue = async (updatedConfig) => { bot.use(session()); -bot.command("start", startHandler(sessions)); +bot.command('start', startHandler(sessions)); -bot.command("add", addHandler(config, updateConfigValue)); +bot.command('add', addHandler(config, updateConfigValue)); -bot.command("show", showHandler(config)); +bot.command('show', showHandler(config)); -bot.command("new", newHandler(config, sessions)); -bot.command("help", helpHandler(config)); -bot.command("image", imageHandler(config)); -bot.command("chatid", chatIDHandler()); -bot.command("password", passwordHandler()); +bot.command('new', newHandler(config, sessions)); +bot.command('help', helpHandler(config)); +bot.command('image', imageHandler(config)); +bot.command('chatid', chatIDHandler()); +bot.command('password', passwordHandler()); -bot.hears(LEXICON_EN["getIDs_btn"], chatIDHandler()); -bot.hears(LEXICON_EN["password_btn"], passwordHandler()); -bot.hears(LEXICON_EN["reset_btn"], newHandler(config, sessions)); +bot.hears(LEXICON_EN['getIDs_btn'], chatIDHandler()); +bot.hears(LEXICON_EN['password_btn'], passwordHandler()); +bot.hears(LEXICON_EN['reset_btn'], newHandler(config, sessions)); -bot.on(message("text"), textHandler(config, sessions)); -bot.on(message("voice"), voiceHandler(config, sessions)); +bot.on(message('text'), textHandler(config, sessions)); +bot.on(message('voice'), voiceHandler(config, sessions)); bot.catch(async (error, ctx) => { - if (error.name === "TimeoutError") { - return ctx.reply(LEXICON_EN["waiting"]); + if (error.name === 'TimeoutError') { + return ctx.reply(LEXICON_EN['waiting']); } }); // setMenu(bot); // deleteWebHook(bot); -process.once("SIGINT", () => bot.stop("SIGINT")); -process.once("SIGTERM", () => bot.stop("SIGTERM")); +process.once('SIGINT', () => bot.stop('SIGINT')); +process.once('SIGTERM', () => bot.stop('SIGTERM')); -bot.launch({ dropPendingUpdates: true }) +bot.launch({ dropPendingUpdates: true }); // .then(sendMessages(bot, await getUsersArray(config))); diff --git a/src/keyboards/keyboards.js b/src/keyboards/keyboards.js index 658cffa..d36796f 100644 --- a/src/keyboards/keyboards.js +++ b/src/keyboards/keyboards.js @@ -3,7 +3,7 @@ import { Markup } from 'telegraf'; export function createMenuKeyboard() { return Markup.keyboard( - [[LEXICON_EN['reset_btn']], - [LEXICON_EN['password_btn'], LEXICON_EN['getIDs_btn']]], + [[LEXICON_EN['reset_btn']], + [LEXICON_EN['password_btn'], LEXICON_EN['getIDs_btn']]], ).resize(); -} \ No newline at end of file +} diff --git a/src/keyboards/set_menu.js b/src/keyboards/set_menu.js index e16940d..97d9d3d 100644 --- a/src/keyboards/set_menu.js +++ b/src/keyboards/set_menu.js @@ -3,11 +3,11 @@ import { LEXICON_EN } from '../lexicon/lexicon_en.js'; export const setMenu = async (bot) => { bot.telegram - .setMyCommands(commands) - .then(() => { - console.log(LEXICON_EN['commands']); - }) - .catch((error) => { - console.error(LEXICON_EN['commandsError'], error); - }); + .setMyCommands(commands) + .then(() => { + console.log(LEXICON_EN['commands']); + }) + .catch((error) => { + console.error(LEXICON_EN['commandsError'], error); + }); }; diff --git a/src/lexicon/lexicon_en.js b/src/lexicon/lexicon_en.js index f7e8c36..7a9c8e4 100644 --- a/src/lexicon/lexicon_en.js +++ b/src/lexicon/lexicon_en.js @@ -1,15 +1,15 @@ export const commands = [ { command: 'start', description: 'Update the bot' }, { command: 'new', description: 'Open a new session' }, - { command: 'help', description: "Find out the bot's capabilities" }, + { command: 'help', description: 'Find out the bot\'s capabilities' }, { command: 'image', description: 'Creating an image based on a text query' }, { command: 'chatid', description: 'Find the chat ID and your ID' }, { command: 'add', description: 'Adding new users' }, { command: 'remove', description: 'Removing users' }, - {command: 'show', description: 'List of all elevated users'}, + { command: 'show', description: 'List of all elevated users' }, ]; -let date = new Date(); +const date = new Date(); export const LEXICON_EN = { botStarted: `Bot has been started! 🤖\n\n${date}`, @@ -18,21 +18,24 @@ export const LEXICON_EN = { webhook: 'Webhook deleted successfully', webhookError: 'Error deleting webhook: ', start: - 'Hello, welcome to an artificial intelligence chatbot that will help you with everything! 🤖\n\nYou can find the source code of the bot here:\nhttps://github.com/BLazzeD21/Node.js-ChatGPT-Bot', + 'Hello, welcome to an artificial intelligence chatbot\ + that will help you with everything! 🤖\n\nYou can find\ + the source code of the bot here:\nhttps://github.com/BLazzeD21/Node.js-ChatGPT-Bot', deniedAccess: 'This functionality is not available to you ⛔️', processing: 'Text accepted for processing', - manyRequests: - 'You are sending too many requests, the server is not able to process your messages in time ⚠️', + manyRequests: 'You are sending too many requests, the server is not\ + able to process your messages in time ⚠️', noResponce: 'Sorry, no response received from the server ⛔️', security: 'Your request was rejected by openai\'s security system 🚔', - empty: 'Make the right request\n\nWrite the command like this: /image request text', - emptyAdd: 'Make the right request\n\nWrite the command like this: /add id', + empty: 'Make the right request\n\nWrite the command like this:\ + /image request text', + emptyAdd: 'Make the right request\n\nWrite the command like this:\ + /add id', reset: 'The context has been reset.', reset_btn: 'Reset context 🗑', getIDs_btn: 'Get IDs 🗃', password_btn: 'Generate password 🎲', add: 'New user ID added successfully ⏬', - added: 'You have been successfully added to the system. Welcome! ❤️', remove: 'user ID deleted ⏫', super: 'You are not a super user 🔒', errorSending: 'Error sending message to: ', @@ -41,14 +44,17 @@ export const LEXICON_EN = { }; export const getIDs = async (chatId, userId) => { - return `Your ID: ${userId}\nThis chat ID: ${chatId}`; + return `Your ID: ${userId}\n`+ + `This chat ID: ${chatId}`; }; export const getHelp = async () => { let helpMessage = 'Commands available in the bot:\n'; - for (let key in commands) { - helpMessage += `/${commands[key]['command']} - ${commands[key]['description']}\n`; + for (const key in commands) { + helpMessage += `/${commands[key]['command']}` + + ' - ' + + `${commands[key]['description']}\n`; } return helpMessage; @@ -58,8 +64,8 @@ export const printError = async (error) => { return `${error.name}: ${error.message}`; }; -export const messageSent = async (recipient_id) => { - return `Message sent to user ID: ${recipient_id}`; +export const messageSent = async (recipientId) => { + return `Message sent to user ID: ${recipientId}`; }; export const errorWhileSending = async (error) => { @@ -67,5 +73,5 @@ export const errorWhileSending = async (error) => { }; export const printPassword = async (password) => { - return `Generated password:\n${password}` -} + return `Generated password:\n${password}`; +}; diff --git a/src/openai.js b/src/openai.js index 6d2a723..0bfcfcd 100644 --- a/src/openai.js +++ b/src/openai.js @@ -1,14 +1,14 @@ -import { printError } from "./lexicon/lexicon_en.js"; +import { printError } from './lexicon/lexicon_en.js'; -import { Configuration, OpenAIApi } from "openai"; -import config from "config"; -import { createReadStream } from "fs"; +import { Configuration, OpenAIApi } from 'openai'; +import config from 'config'; +import { createReadStream } from 'fs'; class OpenAI { roles = { - ASSISTANT: "assistant", - USER: "user", - SYSTEM: "system", + ASSISTANT: 'assistant', + USER: 'user', + SYSTEM: 'system', }; constructor(apiKey) { @@ -21,7 +21,7 @@ class OpenAI { async chat(messages) { try { const response = await this.openai.createChatCompletion({ - model: "gpt-3.5-turbo", + model: 'gpt-3.5-turbo', messages, }); @@ -34,8 +34,8 @@ class OpenAI { async transcription(filepath) { try { const response = await this.openai.createTranscription( - createReadStream(filepath), - "whisper-1" + createReadStream(filepath), + 'whisper-1', ); return response.data.text; } catch (error) { @@ -51,13 +51,13 @@ class OpenAI { size: size, }); - const image_url = response.data.data[0].url; - - return image_url; + const imageUrl = response.data.data[0].url; + + return imageUrl; } catch (error) { console.log(printError(error)); } } } -export const openai = new OpenAI(config.get("OPENAI_KEY")); +export const openai = new OpenAI(config.get('OPENAI_KEY')); diff --git a/src/utils/checkAccess.js b/src/utils/checkAccess.js index a6fe03a..a43d106 100644 --- a/src/utils/checkAccess.js +++ b/src/utils/checkAccess.js @@ -2,9 +2,9 @@ import { LEXICON_EN } from '../lexicon/lexicon_en.js'; export async function getUsersArray(config) { return config - .USERS_ID - .split(",") - .map((id) => parseInt(id)); + .USERS_ID + .split(',') + .map((id) => parseInt(id)); } export async function checkAccess(config, ctx) { diff --git a/src/utils/deleteWebhook.js b/src/utils/deleteWebhook.js index 0130e01..21f4b7e 100644 --- a/src/utils/deleteWebhook.js +++ b/src/utils/deleteWebhook.js @@ -1,12 +1,12 @@ -import { LEXICON_EN } from "../lexicon/lexicon_en.js"; +import { LEXICON_EN } from '../lexicon/lexicon_en.js'; export const deleteWebHook = async (bot) => { bot.telegram - .deleteWebhook() - .then(() => { - console.log(LEXICON_EN['webhook']); - }) - .catch((error) => { - console.error(LEXICON_EN['webhookError'], error); - }); + .deleteWebhook() + .then(() => { + console.log(LEXICON_EN['webhook']); + }) + .catch((error) => { + console.error(LEXICON_EN['webhookError'], error); + }); }; diff --git a/src/utils/generatePassword.js b/src/utils/generatePassword.js index 32930f2..7e1e37e 100644 --- a/src/utils/generatePassword.js +++ b/src/utils/generatePassword.js @@ -1,13 +1,13 @@ export const generatePassword = async () => { - const template = "*******-*******-*******"; - let password = ""; + const template = '*******-*******-*******'; + let password = ''; for (let i = 0; i < template.length; i++) { - if (template[i] === "*") { + if (template[i] === '*') { const randomChar = - Math.random() < 0.5 - ? await generateRandomLetter() - : await generateRandomDigit(); + Math.random() < 0.5 ? + await generateRandomLetter() : + await generateRandomDigit(); password += randomChar; } else { password += template[i]; @@ -18,13 +18,13 @@ export const generatePassword = async () => { }; const generateRandomLetter = async () => { - const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; const randomIndex = Math.floor(Math.random() * letters.length); return letters[randomIndex]; -} +}; const generateRandomDigit = async () => { - const digits = "0123456789"; + const digits = '0123456789'; const randomIndex = Math.floor(Math.random() * digits.length); return digits[randomIndex]; -} +}; diff --git a/src/utils/sendMessages.js b/src/utils/sendMessages.js index a6741f9..ae538a2 100644 --- a/src/utils/sendMessages.js +++ b/src/utils/sendMessages.js @@ -1,9 +1,9 @@ -import { LEXICON_EN, messageSent } from "../lexicon/lexicon_en.js"; +import { LEXICON_EN, messageSent } from '../lexicon/lexicon_en.js'; export const sendMessages = async (bot, allowedUserId) => { for (const recipient of allowedUserId) { try { - await bot.telegram.sendMessage(recipient, LEXICON_EN["botStarted"]); + await bot.telegram.sendMessage(recipient, LEXICON_EN['botStarted']); console.log(await messageSent(recipient)); } catch (error) { console.error(LEXICON_EN['errorSending'], recipient.toString()); diff --git a/src/utils/textFilter.js b/src/utils/textFilter.js deleted file mode 100644 index d027c97..0000000 --- a/src/utils/textFilter.js +++ /dev/null @@ -1,9 +0,0 @@ -export const textFormat = async (text) => { - let output = text; - - output = output.replace(/!/g, "\\!"); - output = output.replace(/\./g, "\\!"); - output = output.replace(/_([^_]+)_/g, "$1"); - output = output.replace(/\*([^*]+)\*/g, "$1"); - return output; -}; diff --git a/src/utils/usersCheck.js b/src/utils/usersCheck.js deleted file mode 100644 index 0115403..0000000 --- a/src/utils/usersCheck.js +++ /dev/null @@ -1,28 +0,0 @@ -export const getExistsUsers = async (users, ctx) => { - let usersExists = ""; - - for (const userId of users) { - try { - await ctx.telegram.getChatMember(ctx.chat.id, userId); - usersExists += `${userId},`; - console.log(`ID ${userId} exists`); - } catch (error) { - console.log(`ID ${userId} does not exist: ${error}`); - } - } - - return usersExists; -}; - -export const existUser = async (userID, ctx) => { - try { - await ctx.telegram.getChatMember(ctx.chat.id, userID); - return true; - } catch (error) { - console.log(error.message); - return false; - } -}; - - - From 6ef1f7acb5e1234a8f620357fb558a9152a65c4e Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Sat, 4 Nov 2023 17:48:54 +0300 Subject: [PATCH 08/12] feat: added command to delete users --- src/handlers/adminHandlers.js | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/handlers/adminHandlers.js b/src/handlers/adminHandlers.js index 8c2a5c7..9b84bcf 100644 --- a/src/handlers/adminHandlers.js +++ b/src/handlers/adminHandlers.js @@ -40,6 +40,53 @@ export const addHandler = (config, callback) => { }; }; +export const removeHandler = (config, callback) => { + return async (ctx) => { + if (ctx.from.id == config.SUPER_USER) { + try { + const requestText = parseInt(ctx.message.text + .replace('/remove', '') + .trim()); + + if (!requestText) { + await ctx.reply(LEXICON_EN['removeAdd'], { parse_mode: 'HTML' }); + return; + } + const usersID = config.USERS_ID.split(','); + + if (!usersID.includes(requestText.toString())) { + ctx.reply('No'); + return; + } + const filteredUsers = usersID + .filter((id) => id !== requestText.toString()) + .join(','); + + config.USERS_ID = filteredUsers; + + if (process.env.NODE_ENV === 'production') { + fs.writeFileSync('config/production.json', + JSON.stringify(config, null, 2), 'utf8'); + } else { + fs.writeFileSync('config/default.json', + JSON.stringify(config, null, 2), 'utf8'); + } + + await callback(config); + + const output =`Removed ID: ${requestText}\n\n` + + `${LEXICON_EN['remove']}`; + + ctx.reply(output, { parse_mode: 'HTML' }); + } catch (e) { + console.log(LEXICON_EN['errorSending'], requestText); + } + } else { + await ctx.reply(LEXICON_EN['super']); + } + }; +}; + export const showHandler = (config) => { return async (ctx) => { if (ctx.from.id == config.SUPER_USER) { From 8972b29e85273ed2c0e869c7b3359a7ef64eb0fb Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Sat, 4 Nov 2023 17:49:44 +0300 Subject: [PATCH 09/12] fix: new checks created and many bugs fixed --- src/handlers/openaiHandlers.js | 75 ++++++++++++++++++++++------------ src/index.js | 6 +-- src/keyboards/set_menu.js | 2 +- src/lexicon/lexicon_en.js | 16 ++++---- src/openai.js | 10 +++-- src/utils/deleteFile.js | 2 +- src/utils/deleteWebhook.js | 2 +- 7 files changed, 67 insertions(+), 46 deletions(-) diff --git a/src/handlers/openaiHandlers.js b/src/handlers/openaiHandlers.js index 61951b4..91fa9fa 100644 --- a/src/handlers/openaiHandlers.js +++ b/src/handlers/openaiHandlers.js @@ -1,5 +1,5 @@ import { code } from 'telegraf/format'; -import { LEXICON_EN, printError } from '../lexicon/lexicon_en.js'; +import { LEXICON_EN } from '../lexicon/lexicon_en.js'; import { openai } from '../openai.js'; import { converter } from '../converter.js'; @@ -26,6 +26,9 @@ export const textHandler = (config, sessions) => { const response = await openai.chat(sessions[sessionId].messages); + if (response=='401') { + throw new Error('Request failed with status code 401'); + } if (response && response.content) { sessions[sessionId].messages.push({ @@ -34,13 +37,14 @@ export const textHandler = (config, sessions) => { }); await ctx.reply(response.content); - // await ctx.reply(response.content, { parse_mode: 'MarkdownV2' }); } else { - await ctx.reply(LEXICON_EN['manyRequests']); + await ctx.reply(LEXICON_EN['responseError'], { parse_mode: 'HTML' }); } } catch (error) { - console.log(await printError(error)); - await ctx.reply(`${LEXICON_EN['noResponce']}\n\n${error.message}`); + console.log(`${error.name}: ${error.message}`); + await ctx.reply( + `${LEXICON_EN['noResponce']}\n\n${error.name}: ${error.message}`, + ); } finally { await ctx.deleteMessage(processing.message_id); } @@ -68,20 +72,24 @@ export const voiceHandler = (config, sessions) => { const response = await openai.chat(sessions[sessionId].messages); + if (response=='401') { + throw new Error('Request failed with status code 401'); + } + if (response && response.content) { sessions[sessionId].messages.push({ role: openai.roles.ASSISTANT, content: response.content, }); await ctx.reply(response.content); - // await ctx.reply(response.content, { parse_mode: 'MarkdownV2' }); } else { - await ctx.reply(LEXICON_EN['manyRequests']); + await ctx.reply(LEXICON_EN['responseError'], { parse_mode: 'HTML' }); } } catch (error) { - console.log(printError(error)); - await ctx.reply(`${LEXICON_EN['noResponce']}\ - \n${error.name}: ${error.message}`); + console.log(`${error.name}: ${error.message}`); + await ctx.reply( + `${LEXICON_EN['noResponce']}\n\n${error.name}: ${error.message}`, + ); } finally { await ctx.deleteMessage(processing.message_id); } @@ -92,29 +100,42 @@ export const imageHandler = (config) => { return async (ctx) => { if (await checkAccess(config, ctx)) return; - const requestText = ctx.message.text - .replace('/image', '') - .trim(); + const processing = await ctx.reply(code(LEXICON_EN['processing'])); + try { + const requestText = ctx.message.text + .replace('/image', '') + .trim(); - if (!requestText) { - await ctx.reply(LEXICON_EN['empty'], { parse_mode: 'HTML' }); - return; - } + if (!requestText) { + await ctx.reply(LEXICON_EN['empty'], { parse_mode: 'HTML' }); + return; + } - const processing = await ctx.reply(code(LEXICON_EN['processing'])); + const size = '1024x1024'; + const count = 1; - const size = '1024x1024'; - const count = 1; + const imageUrl = await openai.getImage(requestText, size, count); - const imageUrl = await openai.getImage(requestText, size, count); + if (imageUrl == '400') { + await ctx.reply(LEXICON_EN['security']); + return; + } - await ctx.deleteMessage(processing.message_id); + if (imageUrl=='401') { + throw new Error('Request failed with status code 401'); + } - if (imageUrl) { - await ctx.replyWithPhoto({ url: imageUrl }, { caption: requestText }); - return; + if (imageUrl) { + await ctx.replyWithPhoto({ url: imageUrl }, { caption: requestText }); + return; + } + } catch (error) { + console.log(`${error.name} imageHandler: ${error.message}`); + await ctx.reply( + `${LEXICON_EN['noResponce']}\n\n${error.name}: ${error.message}`, + ); + } finally { + await ctx.deleteMessage(processing.message_id); } - - await ctx.reply(LEXICON_EN['security']); }; }; diff --git a/src/index.js b/src/index.js index 6e2f601..168f232 100644 --- a/src/index.js +++ b/src/index.js @@ -14,7 +14,7 @@ import { } from './handlers/userHandlers.js'; import { textHandler, voiceHandler, imageHandler, } from './handlers/openaiHandlers.js'; -import { addHandler, showHandler, +import { addHandler, removeHandler, showHandler, } from './handlers/adminHandlers.js'; const sessions = {}; @@ -38,7 +38,7 @@ bot.use(session()); bot.command('start', startHandler(sessions)); bot.command('add', addHandler(config, updateConfigValue)); - +bot.command('remove', removeHandler(config, updateConfigValue)); bot.command('show', showHandler(config)); bot.command('new', newHandler(config, sessions)); @@ -67,4 +67,4 @@ process.once('SIGINT', () => bot.stop('SIGINT')); process.once('SIGTERM', () => bot.stop('SIGTERM')); bot.launch({ dropPendingUpdates: true }); -// .then(sendMessages(bot, await getUsersArray(config))); +// .then(sendMessages(bot, await getUsersArray(config))); diff --git a/src/keyboards/set_menu.js b/src/keyboards/set_menu.js index 97d9d3d..be9c248 100644 --- a/src/keyboards/set_menu.js +++ b/src/keyboards/set_menu.js @@ -8,6 +8,6 @@ export const setMenu = async (bot) => { console.log(LEXICON_EN['commands']); }) .catch((error) => { - console.error(LEXICON_EN['commandsError'], error); + console.log(`${error.name} setmenu: ${error.message}`); }); }; diff --git a/src/lexicon/lexicon_en.js b/src/lexicon/lexicon_en.js index 7a9c8e4..fa1d31f 100644 --- a/src/lexicon/lexicon_en.js +++ b/src/lexicon/lexicon_en.js @@ -14,23 +14,25 @@ const date = new Date(); export const LEXICON_EN = { botStarted: `Bot has been started! 🤖\n\n${date}`, commands: 'Custom commands set successfully', - commandsError: 'Error setting custom commands: ', webhook: 'Webhook deleted successfully', - webhookError: 'Error deleting webhook: ', start: 'Hello, welcome to an artificial intelligence chatbot\ that will help you with everything! 🤖\n\nYou can find\ the source code of the bot here:\nhttps://github.com/BLazzeD21/Node.js-ChatGPT-Bot', deniedAccess: 'This functionality is not available to you ⛔️', processing: 'Text accepted for processing', - manyRequests: 'You are sending too many requests, the server is not\ - able to process your messages in time ⚠️', + responseError: 'Your request could not be processed or ' + + 'the number of requests has been exceeded, please try again. ' + + '\n\nIf the problem is not solved, ' + + 'create a new session via /new or wait a little. ⚠️', noResponce: 'Sorry, no response received from the server ⛔️', security: 'Your request was rejected by openai\'s security system 🚔', empty: 'Make the right request\n\nWrite the command like this:\ /image request text', emptyAdd: 'Make the right request\n\nWrite the command like this:\ /add id', + removeAdd: 'Make the right request\n\nWrite the command like this:\ + /remove id', reset: 'The context has been reset.', reset_btn: 'Reset context 🗑', getIDs_btn: 'Get IDs 🗃', @@ -60,16 +62,12 @@ export const getHelp = async () => { return helpMessage; }; -export const printError = async (error) => { - return `${error.name}: ${error.message}`; -}; - export const messageSent = async (recipientId) => { return `Message sent to user ID: ${recipientId}`; }; export const errorWhileSending = async (error) => { - return `Error sending message:: ${error}`; + return `Error sending message: ${error}`; }; export const printPassword = async (password) => { diff --git a/src/openai.js b/src/openai.js index 0bfcfcd..5b9e2a4 100644 --- a/src/openai.js +++ b/src/openai.js @@ -1,4 +1,3 @@ -import { printError } from './lexicon/lexicon_en.js'; import { Configuration, OpenAIApi } from 'openai'; import config from 'config'; @@ -27,7 +26,8 @@ class OpenAI { return response.data.choices[0].message; } catch (error) { - console.log(printError(error)); + console.log(`${error.name} chat: ${error.message}`); + return error.response.status; } } @@ -39,7 +39,8 @@ class OpenAI { ); return response.data.text; } catch (error) { - console.log(printError(error)); + console.log(`${error.name} transcription: ${error.message}`); + return error.response.status; } } @@ -55,7 +56,8 @@ class OpenAI { return imageUrl; } catch (error) { - console.log(printError(error)); + console.log(`${error.name} getImage: ${error.message}`); + return error.response.status; } } } diff --git a/src/utils/deleteFile.js b/src/utils/deleteFile.js index ccd5241..e63921f 100644 --- a/src/utils/deleteFile.js +++ b/src/utils/deleteFile.js @@ -4,6 +4,6 @@ export async function deleteFile(path) { try { await unlink(path); } catch (error) { - console.log(error.message); + console.log(`${error.name} deletefile: ${error.message}`); } } diff --git a/src/utils/deleteWebhook.js b/src/utils/deleteWebhook.js index 21f4b7e..2968e72 100644 --- a/src/utils/deleteWebhook.js +++ b/src/utils/deleteWebhook.js @@ -7,6 +7,6 @@ export const deleteWebHook = async (bot) => { console.log(LEXICON_EN['webhook']); }) .catch((error) => { - console.error(LEXICON_EN['webhookError'], error); + console.log(`${error.name} webhook: ${error.message}`); }); }; From 605ba8d96aec5a65733a2781947ef8d032a711e0 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Sat, 4 Nov 2023 17:59:51 +0300 Subject: [PATCH 10/12] fix: checking for an empty array with users --- src/utils/checkAccess.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/utils/checkAccess.js b/src/utils/checkAccess.js index a43d106..a3550cc 100644 --- a/src/utils/checkAccess.js +++ b/src/utils/checkAccess.js @@ -1,10 +1,17 @@ import { LEXICON_EN } from '../lexicon/lexicon_en.js'; export async function getUsersArray(config) { - return config + let usersArray = config .USERS_ID .split(',') .map((id) => parseInt(id)); + + if (usersArray.includes(NaN)) { + usersArray = [config.SUPER_USER]; + } + + console.log(usersArray); + return usersArray; } export async function checkAccess(config, ctx) { From acb22989d63fa17e42e01af4c3553d2471acda76 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Sat, 4 Nov 2023 18:46:49 +0300 Subject: [PATCH 11/12] feat: formatting text from a bot using Markdown --- src/handlers/openaiHandlers.js | 5 +++-- src/utils/checkAccess.js | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/handlers/openaiHandlers.js b/src/handlers/openaiHandlers.js index 91fa9fa..ffe4eda 100644 --- a/src/handlers/openaiHandlers.js +++ b/src/handlers/openaiHandlers.js @@ -36,7 +36,7 @@ export const textHandler = (config, sessions) => { content: response.content, }); - await ctx.reply(response.content); + await ctx.reply(response.content, { parse_mode: 'Markdown' }); } else { await ctx.reply(LEXICON_EN['responseError'], { parse_mode: 'HTML' }); } @@ -81,7 +81,8 @@ export const voiceHandler = (config, sessions) => { role: openai.roles.ASSISTANT, content: response.content, }); - await ctx.reply(response.content); + + await ctx.reply(response.content, { parse_mode: 'Markdown' }); } else { await ctx.reply(LEXICON_EN['responseError'], { parse_mode: 'HTML' }); } diff --git a/src/utils/checkAccess.js b/src/utils/checkAccess.js index a3550cc..daf8afa 100644 --- a/src/utils/checkAccess.js +++ b/src/utils/checkAccess.js @@ -10,7 +10,6 @@ export async function getUsersArray(config) { usersArray = [config.SUPER_USER]; } - console.log(usersArray); return usersArray; } From 12da300d9c8a10bab5c245aa34a9d1a9fbf75925 Mon Sep 17 00:00:00 2001 From: Alexandr Sekerin Date: Sat, 4 Nov 2023 18:53:36 +0300 Subject: [PATCH 12/12] fix: unnecessary comments removed --- src/handlers/openaiHandlers.js | 2 -- src/index.js | 8 ++++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/handlers/openaiHandlers.js b/src/handlers/openaiHandlers.js index ffe4eda..333c032 100644 --- a/src/handlers/openaiHandlers.js +++ b/src/handlers/openaiHandlers.js @@ -7,8 +7,6 @@ import { converter } from '../converter.js'; import { createInitialSession } from '../utils/createSession.js'; import { checkAccess } from '../utils/checkAccess.js'; -// import { textFormat } from '../utils/textFilter.js'; - export const textHandler = (config, sessions) => { return async (ctx) => { if (await checkAccess(config, ctx)) return; diff --git a/src/index.js b/src/index.js index 168f232..72ec1dd 100644 --- a/src/index.js +++ b/src/index.js @@ -60,11 +60,11 @@ bot.catch(async (error, ctx) => { } }); -// setMenu(bot); -// deleteWebHook(bot); +setMenu(bot); +deleteWebHook(bot); process.once('SIGINT', () => bot.stop('SIGINT')); process.once('SIGTERM', () => bot.stop('SIGTERM')); -bot.launch({ dropPendingUpdates: true }); -// .then(sendMessages(bot, await getUsersArray(config))); +bot.launch({ dropPendingUpdates: true }) + .then(sendMessages(bot, await getUsersArray(config)));