From 74a60e2aaa9b0ce3bfa50a68360a5be869f6c613 Mon Sep 17 00:00:00 2001 From: abcb1122 <130499564+abcb1122@users.noreply.github.com> Date: Thu, 5 Sep 2024 12:30:09 -0500 Subject: [PATCH 1/9] Update pt.yaml (#587) --- locales/pt.yaml | 98 ++++++++++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/locales/pt.yaml b/locales/pt.yaml index c1042c87..8a28d310 100644 --- a/locales/pt.yaml +++ b/locales/pt.yaml @@ -3,144 +3,144 @@ start: | ${disclaimer} ---———— DISCLAIMER ————--- - Este bot ajudará você a preencher as transações de Bitcoin P2P por meio da Rede Lightning. + Este bot vai te ajudar a completar transações P2P usando Bitcoin via Lightning Network. Depois de iniciar o bot, você pode usar os seguintes comandos: - 1. Publique seu pedido usando o comando /buy ou /sell e siga as instruções. + 1. Publique sua oferta usando o comando /buy ou /sell e siga as instruções. - 2. Espere que outro usuário escolha sua solicitação usando o "Buy" ou "Sell" botões. Você também pode escolher outros usuários pedidos com esses botões! + 2. Espere que outro usuário ative sua oferta usando os botões "Buy" ou "Sell". Você também pode aceitar as ofertas de outros usuários usando esses botões! - 3. Suas ordens e reputação são visíveis no ${channel} canal. + 3. Suas ordens e reputação são visíveis no canal ${channel} . - 4. Se você estiver vendendo o bot, publicará a ordem no ${channel} canal na expectativa de que outro usuário aceite o pedido. Você pode cancelar esse pedido de venda a qualquer momento ANTES que outro usuário o leve com o comando /cancel. + 4. Se você estiver vendendo o bot, publicará a oferta no canal ${channel} na expectativa de que outro usuário aceite o pedido. Você pode cancelar essa oferta de venda a qualquer momento ANTES que outro usuário a aceite com o comando /cancel. - 5. Uma vez que alguém aceite seu pedido, o bot solicitará que você pague a fatura da rede Lightning, Esse pagamento será realizado, o pedido expirará em um lapso máximo de ${orderExpiration} horas começando quando o pedido foi realizado. O bot revelará quem é o comprador que você pode enviar para o pagamento da Fiat. Depois de receber o pagamento fiduciário, você deve enviar fundos ao comprador usando o comando /release. + 5. Uma vez que alguém aceite sua oferta, o bot solicitará que você pague a fatura da rede Lightning, Esse pagamento será retido, o pedido expirará em um tempo máximo de ${orderExpiration} horas a partir do momento em que foi aceito. O bot informará quem é o comprador para que você forneça a informação para receber o pagamento. Depois de receber o pagamento, você deve liberar os fundos para que os sats cheguem ao invoice do comprador usando o comando /release. - 6. Se você quiser comprar, precisa publicar seu pedido usando o comando /buy E espere até que um vendedor o leve. Você pode cancelar o pedido a qualquer momento usando o comando /cancel. + 6. Se você quiser comprar, precisa publicar sua oferta usando o comando /buy e esperar até que um vendedor a aceite. Você pode cancelar o pedido a qualquer momento usando o comando /cancel. - 7. Depois que alguém leva seu pedido de compra, você precisa criar uma fatura de rede Lightning e enviá-la para o bot, depois disso você precisa entrar em contato com o vendedor para obter as instruções de pagamento da Fiat. Depois de pagar, o vendedor deve usar o comando /release, O bot enviará os sats para sua fatura de rede de Lightning. + 7. Depois que alguém aceite seu pedido de compra, você precisa criar uma fatura (invoice) na rede Lightning e enviá-la para o bot, envie a fatura como texto o bot não aceita QR code. Depois disso você deve entrar em contato com o vendedor para receber as instruções e informação para realizar o de pagamento. Depois de pagar, o vendedor deve usar o comando /release. O bot enviará os sats para sua fatura de rede de Lightning. - 8. Se você está fazendo um pedido de venda, ou seja, você compra, Você deve criar uma fatura do LN para obter seus sats e pedir ao vendedor que forneça as instruções de pagamento da Fiat. Depois que o vendedor receber o pagamento fiduciário, ele usará o comando /release para enviar os sats à sua carteira. + 8. Se você está aceitando uma oferta de venda, ou seja, você está comprando, deve criar uma fatura na rede Lightning para receber seus sats e pedir ao vendedor que forneça as instruções de pagamento. Depois que o vendedor receber o pagamento fiduciário, ele usará o comando /release para enviar os sats à sua wallet LN. - 9. Se você estiver fazendo um pedido de compra, ou seja, vende sats. Você deve pagar a fatura do LN. Este sats será mantido até que o comprador efetue o pagamento da Fiat. Você deve entrar em contato com o comprador e fornecer a ele as informações necessárias para prosseguir com o pagamento da Fiat. Depois de receber o pagamento fiduciário, você deve liberar o fundo mantido pelo bot, você deve usar o comando /release e os SATs serão enviados automaticamente para a carteira do comprador. + 9. Se você estiver aceitando uma oferta de compra, ou seja, você está vendendo sats, deve pagar a fatura do na rede Lightning enviado pelo bot. Estes sats serão retidos até que o comprador efetue o pagamento e envie o comando /fiatsent. Você deve entrar em contato com o comprador e fornecer a informação necessária para receber o pagamento. Depois de receber o pagamento fiduciário, você deve liberar os sats retidos pelo bot usando o comando /release. Os sats serão enviados automaticamente para a wallet LN do comprador. - Você pode encontrar mais informações sobre como usar este bot aqui 👇 + Mais informação sobre como usar o bot aqui 👇 - https://lnp2pbot.com/learn + https://lnp2pbot.com/aprenda - Faça uma transação rápida e segura! -init_bot_error: Para usar este bot, você precisa primeiro inicializar a inicialização com o comando /start -non_handle_error: 👤 Para usar este bot, você precisa ativar seu nome de usuário do Telegram, para ativá-lo, abra o menu de hambúrguer no canto superior esquerdo e selecione Configurações -> editar Perfil -> nome de usuário + Faça transações rápidas e seguras! +init_bot_error: Para usar este bot, você deve iniciar com o comando /start +non_handle_error: 👤 Para usar este bot, você precisa ativar seu nome de usuário do Telegram, para ativá-lo, abra as configurações e selecione Meu Perfil -> Editar -> Nome de Usuário invoice_payment_request: | - Alguém quer te comprar ${order.amount} sats por ${currency} ${order.fiat_amount}. + Alguém quer comprar ${order.amount} sats por ${currency} ${order.fiat_amount}. Reputação do comprador: ${rate}, dias usando o bot: ${days} - Por favor, pague esta fatura para iniciar seu processo de venda, esta fatura expirará ${expirationTime} minutos + Por favor, pague esta fatura para iniciar seu processo de venda, a fatura expirará em ${expirationTime} minutos pending_sell: | - 📝 Sua oferta foi publicada no ${channel} canal + 📝 Oferta publicada no canal ${channel} - Você tem que esperar até que outro usuário escolha seu pedido, ele estará disponível para ${orderExpirationWindow} horas no canal + Você tem que esperar até que outro usuário aceite sua oferta, ela estará disponível por ${orderExpirationWindow} horas no canal - Você pode cancelar este pedido antes que outro usuário o retire executando o comando 👇 + Você pode cancelar a oferta antes que outro usuário a aceite executando o comando 👇 cancel_order_cmd: | /cancel ${orderId} pending_buy: | - 📝 Você oferece para comprar sats é ativo no ${channel} canal. + 📝 Oferta publicada no canal ${channel} - Você precisa esperar até que outro usuário retire o pedido, esse pedido expirará ${orderExpirationWindow} horas. + Você tem que esperar até que outro usuário aceite sua oferta, ela estará disponível por ${orderExpirationWindow} horas no canal - Você pode cancelar este pedido antes que outro usuário o retire executando o comando 👇 -must_be_int: ${fieldName} deve ser um número + Você pode cancelar a oferta antes que outro usuário a aceite executando o comando 👇 +must_be_int: ${fieldName} deve ser um número enteiro must_be_numeric: ${fieldName} deve ser numérico sats_amount: quantidade de sats fiat_amount: quantidade fiduciária sell_correct_format: | /sell \<_sats amount_\> \<_fiat amount_\> \<_fiat code_\> \<_payment method_\> \[_premium/discount_\] - Para criar uma ordem de venda de 1000 Satoshis por 2 dólares americanos \(USD\) e indicar que o pagamento fiduciário é por transferência ou depósito de caixa eletrônico, você deve evitar \<\> e \[\]\. + Para criar uma oferta de venda de 1000 satoshis por 2 dólares americanos \(USD\) e indicar que o pagamento fiduciário é por transferência ou depósito no caixa eletrônico, você deve evitar \<\> e \[\]\. - `/sell 1000 2 USD "transferência ou depósito de caixa eletrônico"` + `/sell 1000 2 USD "transferência ou depósito no caixa eletrônico"` - Para criar uma venda com um excedente no preço de 3% \(premium\) Você precisa adicionar o parâmetro 0 indicando a quantidade fiduciária\. O bot calculará o preço de venda usando o preço de mercado do Bitcoin e aplicando o superávit indicado, você precisa adicionar 3 como o último parâmetro + Para criar uma oferta de venda com um acréscimo no preço de 3% \(premium\) Você precisa adicionar o parâmetro 0 indicando a quantidade fiduciária\. O bot calculará o preço de venda usando o preço de mercado do Bitcoin e aplicando o acréscimo indicado, você precisa adicionar 3 como o último parâmetro `/sell 0 2 USD "forma de pagamento" 3` - Para criar uma venda por intervalo, em vez de indicar uma quantidade fiduciária fixa, você pode indicar um miminum e uma quantidade máxima para transações separadas por um hífen *\-* + Para criar uma oferta de venda por faixa, em vez de indicar uma quantidade fiduciária fixa, você pode indicar um valor mínimo e máximo para suas transações separados por um hífen *\-* `/sell 0 100\-500 USD "forma de pagamento" 3` buy_correct_format: | /buy \<_sats amount_\> \<_fiat amount_\> \<_fiat code_\> \<_payment method_\> \[_premium/discount_\] - Para criar e pedir 1000 Satoshis para 2 \(USD\) e indicar que o pagamento fiduciário é através da transferência, você deve omitir os dois \<\> e \[\]\. + Para criar uma oferta e pedir 1000 Satoshis por 2 \(USD\) e indicar que o pagamento fiduciário é através de transferência, você deve omitir os dois \<\> e \[\]\. `/buy 1000 2 USD "transferência online"` - Se você não deseja estabelecer uma quantidade fixa de satoshis e deseja comprar com um preço sob valor de mercado, você pode fazer um pedido de compra estabelecendo um determinado desconto, Essa taxa é a porcentagem que será incluída no preço de mercado quando seu pedido for publicado\. Você precisa especificar 0 no \<_sats amount_\> campo, o bot calculará o preço\. Se você quiser comprar com um desconto de 2% no mercado de preços, você deve escrever \-2 como o último parâmetro + Se você não deseja estabelecer uma quantidade fixa de satoshis e deseja comprar com um preço debaixo do valor de mercado, você pode fazer um pedido de compra estabelecendo um determinado desconto. Essa taxa é a porcentagem que será subtraída do preço de mercado quando sua ordem for aceita. Basta colocar 0 no campo \<_sats amount_\> , o bot calculará o preço. Se você quiser comprar com um desconto de 2% deve escrever \-2 como último parâmetro `/buy 0 2 USD "forma de pagamento" \-2` - Se você deseja criar o pedido de compra por intervalo, em vez de indicar uma quantidade fiduciária fixa, pode definir o mínimo e o máximo para transações separadas por um hífen *\-* + Se você deseja criar uma oferta de compra numa faixa de valores, em vez de indicar uma quantidade fiduciária fixa, pode definir o valor mínimo e máximo para suas transações separados por um hífen *\-* `/buy 0 100\-500 USD "forma de pagamento" \-2` -min_invoice_amount: fatura precisa ser igual ou superior a que ${minPaymentAmount} satoshis -min_expiration_time: A expiração do tempo para a fatura deve ser de pelo menos ${expirationTime} minutos +min_invoice_amount: fatura precisa ser igual ou maior a ${minPaymentAmount} satoshis +min_expiration_time: A expiração do tempo da fatura deve ser de pelo menos ${expirationTime} minutos invoice_expired: Fatura expirou invoice_expired_long: | - Fatura expirou. Você pode usar o seguinte comando para me enviar uma nova fatura para receber os satoshis 👇 + Fatura expirou. Você pode usar o seguinte comando para enviar uma nova fatura e receber os satoshis 👇 setinvoice_cmd_order: /setinvoice -invoice_require_destination: Fatura precisa de um endereço de receptor +invoice_require_destination: Fatura precisa de um endereço de destino invoice_require_hash: Fatura precisa de um hash order_id_invalid: ID do pedido inválido order_invalid_type: Este ${type} pedido é inválido -order_already_taken: Este pedido já foi feito por outro usuário. +order_already_taken: Este pedido já foi aceito por outro usuário. order_already_settled: Esta ordem já foi liquidada. invalid_data: Você enviou dados inválidos, tente novamente. begin_take_buy: | - 🤖 Pressione Continue aceitando a oferta, se você pressionar cancelar, será liberado do pedido e ela será republicada. Você tem ${expirationTime} minutos antes que esse pedido expire. 👇 + 🤖 Pressione Continue para aceitar a oferta, se você pressionar Cancel, desvincularei você do pedido e ele será publicado novamente. Você tem ${expirationTime} minutos ou o pedido expirará. 👇 continue: Continuar cancel: Cancelar -pay_invoice: Por favor, pague esta fatura de ${amount} sats para ${currency} ${fiatAmount} para iniciar a operação. +pay_invoice: Por favor, pague esta fatura de ${amount} sats por ${currency} ${fiatAmount} para iniciar a operação. payment_received: | 🤑 Pagamento recebido! - Agora eu preciso que o comprador envie uma fatura para que eu possa enviar Satoshis para sua carteira. Assim que o comprador enviar a fatura, colocarei vocês dois em contato. + Agora eu preciso que o comprador envie uma fatura para que eu possa enviar satoshis para sua wallet LN. Assim que o comprador enviar a fatura, colocarei vocês dois em contato. - Espere um pouco.Se o comprador não cooperar, a garantia será devolvida a você. + Paciência. Se o comprador não aparecer, a garantia retornará à sua wallet LN. someone_took_your_order: | - 🤖 Alguém recebeu seu pedido e já me enviou os SATs, use um processador de pagamento da Fiat que permita enviar o dinheiro imediatamente e no qual não há risco de congelar fundos. + 🤖 Alguém aceitou sua oferta e já enviou os sats, use um processador de pagamentos que permita enviar o dinheiro imediatamente e no qual não há risco de congelar os fundos. - Se por algum motivo o seu processador de pagamento coloca o pagamento em pausa e os fundos não chegam em menos de ${expirationTime}, Os SATs retornarão ao vendedor, colocando o comprador em risco e não poderei forçar o vendedor a enviar os sats novamente. + Se por algum motivo a plataforma coloca o pagamento em pausa e os fundos não chegarem em menos de ${expirationTime}, Os sats retornarão ao vendedor, colocando o comprador em risco e não poderei forçar o vendedor a enviar os sats novamente. Reputação do vendedor: ${rate}, dias usando o bot: ${days} Se você concorda com o exposto acima, pressione o botão para continuar 👇 you_took_someone_order: | - 🤖 Você tomou esse pedido de venda, use um processador de pagamento fiduciário que permita enviar o dinheiro imediatamente e no qual não há risco de congelar fundos\\. + 🤖 Você aceitou uma oferta de venda, use um processador de pagamentos que permita enviar o dinheiro imediatamente e no qual não há risco de congelar os fundos\\. - *Se por algum motivo o seu processador de pagamento coloca o pagamento em pausa e os fundos não chegam em menos de ${expirationTime}, os sats voltarão ao vendedor, Colocando o comprador em risco e não poderei forçar o vendedor a enviar os sats novamente\\.* + *Se por algum motivo a plataforma coloca o pagamento em pausa e os fundos não chegarem em menos de ${expirationTime}, Os sats retornarão ao vendedor, colocando o comprador em risco e não poderei forçar o vendedor a enviar os sats novamente\\.* Se você concorda com o exposto acima, pressione o botão para continuar 👇 get_in_touch_with_seller: | 🤖 Order Id: #${orderId} - Entre em contato com o vendedor, usuário @${sellerUsername} Para obter os detalhes sobre como enviar o dinheiro que você deve enviar ${currency} ${fiatAmount} usando ${paymentMethod}. + Entre em contato com o vendedor, usuário @${sellerUsername} para receber informação sobre como enviar o pagamento de ${currency} ${fiatAmount} usando ${paymentMethod}. Depois de enviar o dinheiro, por favor me avise com o comando 👇 fiatsent_order_cmd: /fiatsent get_in_touch_with_buyer: | 🤖 Order Id: #${orderId} - Entre em contato com @${buyerUsername} para fornecer informações sobre como enviar você ${currency} ${fiatAmount} através dos ${paymentMethod}. Não libere esses SATs até verificar se o comprador pagou o Fiat. + Entre em contato com o comprador, usuário @${buyerUsername} para enviar informação sobre como você receberá ${currency} ${fiatAmount} usando ${paymentMethod}. Não libere os sats até verificar que recebeu o pagamento. - Depois de confirmar a recepção do dinheiro, você deve desbloquear os sats. + Depois de confirmar a recepção do pagamento, você deve liberar os sats. buyer_took_your_order: | 🤖 Order Id: #${orderId} - @${buyerUsername} fez seu pedido e deseja comprar seus sats. Entre em contato e diga a ele como mandar você ${currency} ${fiatAmount} através dos ${paymentMethod}. + @${buyerUsername} aceitou sua oferta e deseja comprar seus sats. Entre em contato e envie a informação sobre como você receberá ${currency} ${fiatAmount} usando ${paymentMethod}. - Avisarei quando o comprador me informar que enviou o fiat, depois você deverá verificar se o valor chegou. + Avisarei quando o comprador informar que enviou o pagamento, depois você deverá verificar se os fundos chegaram. Se o comprador não responder, você pode iniciar um cancelamento ou uma disputa. Lembre-se de que um administrador NUNCA o contactará para resolver seu pedido, a menos que você abra uma disputa primeiro. waiting_seller_to_pay: 'Enviei uma solicitação de pagamento ao vendedor para que ele envie seus sats para o #${orderId}, Assim que o pagamento for feito, vou colocar vocês em contato' From 5c13f3e8a857681c029607de3c0542f4f1595539 Mon Sep 17 00:00:00 2001 From: CarpeDiemCuba <113469736+CarpeDiemCuba@users.noreply.github.com> Date: Tue, 10 Sep 2024 09:41:05 -0400 Subject: [PATCH 2/9] Add community stats (#589) * fix #481 add community stats * Fix the indentation --- bot/modules/community/actions.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/bot/modules/community/actions.js b/bot/modules/community/actions.js index fe2ddc48..dfd30f70 100644 --- a/bot/modules/community/actions.js +++ b/bot/modules/community/actions.js @@ -49,6 +49,18 @@ exports.onCommunityInfo = async ctx => { const orderCount = await getOrdersNDays(1, commId); const volume = await getVolumeNDays(1, commId); + const creator = await User.findById(community.creator_id); + + let orderChannelsText = ''; + if (community.order_channels.length === 1) { + orderChannelsText = `${community.order_channels[0].name} (${community.order_channels[0].type})`; + } else if (community.order_channels.length === 2) { + orderChannelsText = `${community.order_channels[0].name} (${community.order_channels[0].type}) ${community.order_channels[1].name} (${community.order_channels[1].type})`; + } + + const options = { year: 'numeric', month: 'short', day: 'numeric' }; + const formatDate = community.created_at.toLocaleDateString('en-US', options); + const rows = []; rows.push([ { text: ctx.i18n.t('orders') + ' 24hs', callback_data: 'none' }, @@ -62,13 +74,14 @@ exports.onCommunityInfo = async ctx => { { text: ctx.i18n.t('users'), callback_data: 'none' }, { text: userCount, callback_data: 'none' }, ]); + rows.push([ { text: ctx.i18n.t('use_default'), callback_data: `setCommunity_${commId}`, }, ]); - const text = `${community.name}\n${community.group}`; + const text = `${community.name}: ${community.group} \nCreator: @${creator.username} \nOrder Channels: ${orderChannelsText} \nFee: ${community.fee} \nCreated At: ${formatDate}`; await ctx.reply(text, { reply_markup: { inline_keyboard: rows }, }); @@ -90,4 +103,4 @@ exports.withdrawEarnings = async ctx => { ctx.scene.enter('ADD_EARNINGS_INVOICE_WIZARD_SCENE_ID', { community, }); -}; +}; \ No newline at end of file From 49f6805802e9a892edc092a90eaa0a164f35fe59 Mon Sep 17 00:00:00 2001 From: Daniel Candia Flores Date: Wed, 11 Sep 2024 17:14:06 -0400 Subject: [PATCH 3/9] Issue 543 error displaying username with underscore (#586) * Escape underscore on dispute message for admin solver and add unit tests * Update TG id for translation * Resolve linter errors * Updated package-json with proxiquiry module * Fix error UnknownArrayOrTuple * Test QL security fix * 2nd attempt CodeQL issue * 3rd attempt CodeQL issue * 4th attempt CodeQL issue * Update the MD sanitize with implemented method and fix the issue in the translation file * Update other languages translations --------- Co-authored-by: Daniel Candia Flores --- bot/modules/dispute/messages.js | 17 +- locales/de.yaml | 4 +- locales/en.yaml | 4 +- locales/es.yaml | 8 +- locales/fa.yaml | 4 +- locales/fr.yaml | 4 +- locales/it.yaml | 4 +- locales/ko.yaml | 4 +- locales/pt.yaml | 4 +- locales/ru.yaml | 4 +- locales/uk.yaml | 4 +- package-lock.json | 4157 ++++++++++++++----------- package.json | 8 +- tests/bot/modules/dispute/messages.js | 137 + 14 files changed, 2570 insertions(+), 1793 deletions(-) create mode 100644 tests/bot/modules/dispute/messages.js diff --git a/bot/modules/dispute/messages.js b/bot/modules/dispute/messages.js index 4d0281a6..5b1aa0bb 100644 --- a/bot/modules/dispute/messages.js +++ b/bot/modules/dispute/messages.js @@ -1,4 +1,4 @@ -const { getDisputeChannel, getDetailedOrder } = require('../../../util'); +const { getDisputeChannel, getDetailedOrder, sanitizeMD } = require('../../../util'); const { logger } = require('../../../logger'); exports.beginDispute = async (ctx, initiator, order, buyer, seller) => { @@ -87,11 +87,18 @@ exports.disputeData = async ( } const detailedOrder = getDetailedOrder(ctx.i18n, order, buyer, seller); + + // Fix Issue 543: Escape underscores in usernames + const escapedInitiatorUsername = sanitizeMD(initiatorUser.username); + const escapedCounterPartyUsername = sanitizeMD(counterPartyUser.username); + await ctx.telegram.sendMessage( solver.tg_id, ctx.i18n.t('dispute_started_channel', { - initiatorUser, - counterPartyUser, + initiatorUser: { ...initiatorUser, username: escapedInitiatorUsername }, + initiatorTgId: initiatorUser.tg_id, + counterPartyUser: { ...counterPartyUser, username: escapedCounterPartyUsername }, + counterPartyUserTgId: counterPartyUser.tg_id, buyer, seller, buyerDisputes, @@ -108,14 +115,14 @@ exports.disputeData = async ( await ctx.telegram.sendMessage( buyer.tg_id, ctx.i18n.t('dispute_solver', { - solver: solver.username, + solver: sanitizeMD(solver.username), token: order.buyer_dispute_token, }) ); await ctx.telegram.sendMessage( seller.tg_id, ctx.i18n.t('dispute_solver', { - solver: solver.username, + solver: sanitizeMD(solver.username), token: order.seller_dispute_token, }) ); diff --git a/locales/de.yaml b/locales/de.yaml index 81bbbab7..4b1e32dd 100644 --- a/locales/de.yaml +++ b/locales/de.yaml @@ -202,8 +202,8 @@ order_detail: | seller: Käufer buyer: Verkäufer dispute_started_channel: | - Benutzer ${type} @${initiatorUser.username} - hat einen Streitfall mit @${counterPartyUser.username} für den folgenden Auftrag eröffnet + Benutzer ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} + hat einen Streitfall mit @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} für den folgenden Auftrag eröffnet ${detailedOrder} diff --git a/locales/en.yaml b/locales/en.yaml index 43e39078..08baacf0 100644 --- a/locales/en.yaml +++ b/locales/en.yaml @@ -204,8 +204,8 @@ order_detail: | seller: seller buyer: buyer dispute_started_channel: | - User ${type} @${initiatorUser.username} - has started a dispute with @${counterPartyUser.username} for the order + User ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} + has started a dispute with @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} for the order ${detailedOrder} diff --git a/locales/es.yaml b/locales/es.yaml index 59bcc479..9baf03fd 100644 --- a/locales/es.yaml +++ b/locales/es.yaml @@ -202,16 +202,16 @@ order_detail: | seller: vendedor buyer: comprador dispute_started_channel: | - El ${type} @${initiatorUser.username} - ha iniciado una disputa con @${counterPartyUser.username} en la orden: + El ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} + ha iniciado una disputa con @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} en la orden: ${detailedOrder} Seller Token: ${sellerToken} Buyer Token: ${buyerToken} - @${buyer.username} ya tiene ${buyerDisputes} disputas - @${seller.username} ya tiene ${sellerDisputes} disputas + @${initiatorUser.username} ya tiene ${buyerDisputes} disputas + @${counterPartyUser.username} ya tiene ${sellerDisputes} disputas you_started: '🥴 Has iniciado una disputa en tu orden con Id: ${orderId}.' counterpart_started: '🥴 Tu contraparte ha iniciado una disputa en tu orden con Id: ${orderId}.' dispute_started: '${who} Un solver te atenderá pronto, cuando él/la solver sea asignado a tu disputa el bot te dirá su username, solo él/ella podrá atenderte. Puedes escribirle directamente, pero si él/ella te contacta primero, debes pedirle que te diga cuál es el token de tu disputa, tu token es: ${token}.' diff --git a/locales/fa.yaml b/locales/fa.yaml index 7dadbbbe..b95a5ebb 100644 --- a/locales/fa.yaml +++ b/locales/fa.yaml @@ -204,8 +204,8 @@ order_detail: | seller: seller buyer: buyer dispute_started_channel: | - کاربر ${type} @${initiatorUser.username} - بابت سفارش زیر یک مشاجره را با کاربر @${counterPartyUser.username}آغاز کرده + کاربر ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} + بابت سفارش زیر یک مشاجره را با کاربر @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} آغاز کرده ${detailedOrder} diff --git a/locales/fr.yaml b/locales/fr.yaml index 2a53a378..72421581 100644 --- a/locales/fr.yaml +++ b/locales/fr.yaml @@ -204,8 +204,8 @@ order_detail: | seller: vendeur buyer: acheteur dispute_started_channel: | - L'utilisateur ${type} @${initiatorUser.username} - à déclenché un litige avec @${counterPartyUser.username} concernant l'offre + L'utilisateur ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} + à déclenché un litige avec @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} concernant l'offre ${detailedOrder} diff --git a/locales/it.yaml b/locales/it.yaml index 3c3f994d..4d3862cd 100644 --- a/locales/it.yaml +++ b/locales/it.yaml @@ -202,8 +202,8 @@ order_detail: | seller: venditore buyer: acquirente dispute_started_channel: | - User ${type} @${initiatorUser.username} - ha iniziato una disputa con @${counterPartyUser.username} per l'ordine + User ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} + ha iniziato una disputa con @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} per l'ordine ${detailedOrder} diff --git a/locales/ko.yaml b/locales/ko.yaml index 675f1f27..db10e9e8 100644 --- a/locales/ko.yaml +++ b/locales/ko.yaml @@ -203,8 +203,8 @@ order_detail: | seller: 판매자 buyer: 구매자 dispute_started_channel: | - 사용자 ${type} @${initiatorUser.username} - 님께서 @${counterPartyUser.username}와의 분쟁 조정을 시작하였습니다. 주문 상세 내역은 다음과 같습니다. + 사용자 ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} + 님께서 @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} 와의 분쟁 조정을 시작하였습니다. 주문 상세 내역은 다음과 같습니다. ${detailedOrder} diff --git a/locales/pt.yaml b/locales/pt.yaml index 8a28d310..cbf6b53a 100644 --- a/locales/pt.yaml +++ b/locales/pt.yaml @@ -201,8 +201,8 @@ order_detail: | seller: vendedora buyer: compradora dispute_started_channel: | - Usuário ${type} @${initiatorUser.username} - iniciou uma disputa com @${counterPartyUser.username} para o pedido + Usuário ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} + iniciou uma disputa com @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} para o pedido ${detailedOrder} diff --git a/locales/ru.yaml b/locales/ru.yaml index 8f51c20e..34122308 100644 --- a/locales/ru.yaml +++ b/locales/ru.yaml @@ -201,8 +201,8 @@ order_detail: | seller: продавец buyer: покупатель dispute_started_channel: | - ${type} @${initiatorUser.username} - инициировал разбирательство с @${counterPartyUser.username} относительно заявки: + ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} + инициировал разбирательство с @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} относительно заявки: ${detailedOrder} diff --git a/locales/uk.yaml b/locales/uk.yaml index 9b5734d9..5793167b 100644 --- a/locales/uk.yaml +++ b/locales/uk.yaml @@ -201,8 +201,8 @@ order_detail: | seller: продавець buyer: покупець dispute_started_channel: | - ${type} @${initiatorUser.username} - ініціював диспут з @${counterPartyUser.username} щодо заявки: + ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} + ініціював диспут з @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} щодо заявки: ${detailedOrder} diff --git a/package-lock.json b/package-lock.json index 139aee65..fd8c05d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "crypto": "^1.0.1", "dotenv": "^10.0.0", "invoices": "2.0.6", - "lightning": "^9.8.1", + "lightning": "9.8.1", "mongoose": "6.12.0", "node-schedule": "^2.0.0", "nostr-tools": "^2.5.2", @@ -39,9 +39,11 @@ "mocha": "^9.2.2", "nodemon": "2.0.19", "prettier": "^2.6.2", + "proxyquire": "^2.1.3", "sinon": "^11.1.2", "telegram-test-api": "^2.5.0", - "typescript": "^5.1.6" + "typegram": "^5.2.0", + "typescript": "5.1.6" } }, "node_modules/@aws-crypto/sha256-browser": { @@ -170,47 +172,47 @@ } }, "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.621.0.tgz", - "integrity": "sha512-FpXia5qFf6ijcNDWenVq+mP9r1LbiW/+52i9wrv2+Afi6Nn1ROf8W7St8WvE9TEZ3t78y+vis4CwqfGts+uiKA==", + "version": "3.637.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.637.0.tgz", + "integrity": "sha512-391mca6yEfXVcSOTLGcxzlT0QCFfvoymLlVHfb//bzl806UUTq12cR2k+AnaCKLj+QSejmA7n6lwZWADm00Fvg==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.621.0", - "@aws-sdk/client-sts": "3.621.0", - "@aws-sdk/core": "3.621.0", - "@aws-sdk/credential-provider-node": "3.621.0", + "@aws-sdk/client-sso-oidc": "3.637.0", + "@aws-sdk/client-sts": "3.637.0", + "@aws-sdk/core": "3.635.0", + "@aws-sdk/credential-provider-node": "3.637.0", "@aws-sdk/middleware-host-header": "3.620.0", "@aws-sdk/middleware-logger": "3.609.0", "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.620.0", + "@aws-sdk/middleware-user-agent": "3.637.0", "@aws-sdk/region-config-resolver": "3.614.0", "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-endpoints": "3.637.0", "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.1", + "@smithy/core": "^2.4.0", "@smithy/fetch-http-handler": "^3.2.4", "@smithy/hash-node": "^3.0.3", "@smithy/invalid-dependency": "^3.0.3", "@smithy/middleware-content-length": "^3.0.5", "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.13", + "@smithy/middleware-retry": "^3.0.15", "@smithy/middleware-serde": "^3.0.3", "@smithy/middleware-stack": "^3.0.3", "@smithy/node-config-provider": "^3.1.4", "@smithy/node-http-handler": "^3.1.4", "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", + "@smithy/smithy-client": "^3.2.0", "@smithy/types": "^3.3.0", "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.13", - "@smithy/util-defaults-mode-node": "^3.0.13", + "@smithy/util-defaults-mode-browser": "^3.0.15", + "@smithy/util-defaults-mode-node": "^3.0.15", "@smithy/util-endpoints": "^2.0.5", "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", @@ -222,44 +224,44 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.621.0.tgz", - "integrity": "sha512-xpKfikN4u0BaUYZA9FGUMkkDmfoIP0Q03+A86WjqDWhcOoqNA1DkHsE4kZ+r064ifkPUfcNuUvlkVTEoBZoFjA==", + "version": "3.637.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.637.0.tgz", + "integrity": "sha512-+KjLvgX5yJYROWo3TQuwBJlHCY0zz9PsLuEolmXQn0BVK1L/m9GteZHtd+rEdAoDGBpE0Xqjy1oz5+SmtsaRUw==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.621.0", + "@aws-sdk/core": "3.635.0", "@aws-sdk/middleware-host-header": "3.620.0", "@aws-sdk/middleware-logger": "3.609.0", "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.620.0", + "@aws-sdk/middleware-user-agent": "3.637.0", "@aws-sdk/region-config-resolver": "3.614.0", "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-endpoints": "3.637.0", "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.1", + "@smithy/core": "^2.4.0", "@smithy/fetch-http-handler": "^3.2.4", "@smithy/hash-node": "^3.0.3", "@smithy/invalid-dependency": "^3.0.3", "@smithy/middleware-content-length": "^3.0.5", "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.13", + "@smithy/middleware-retry": "^3.0.15", "@smithy/middleware-serde": "^3.0.3", "@smithy/middleware-stack": "^3.0.3", "@smithy/node-config-provider": "^3.1.4", "@smithy/node-http-handler": "^3.1.4", "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", + "@smithy/smithy-client": "^3.2.0", "@smithy/types": "^3.3.0", "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.13", - "@smithy/util-defaults-mode-node": "^3.0.13", + "@smithy/util-defaults-mode-browser": "^3.0.15", + "@smithy/util-defaults-mode-node": "^3.0.15", "@smithy/util-endpoints": "^2.0.5", "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", @@ -271,45 +273,45 @@ } }, "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.621.0.tgz", - "integrity": "sha512-mMjk3mFUwV2Y68POf1BQMTF+F6qxt5tPu6daEUCNGC9Cenk3h2YXQQoS4/eSyYzuBiYk3vx49VgleRvdvkg8rg==", + "version": "3.637.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.637.0.tgz", + "integrity": "sha512-27bHALN6Qb6m6KZmPvRieJ/QRlj1lyac/GT2Rn5kJpre8Mpp+yxrtvp3h9PjNBty4lCeFEENfY4dGNSozBuBcw==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.621.0", - "@aws-sdk/credential-provider-node": "3.621.0", + "@aws-sdk/core": "3.635.0", + "@aws-sdk/credential-provider-node": "3.637.0", "@aws-sdk/middleware-host-header": "3.620.0", "@aws-sdk/middleware-logger": "3.609.0", "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.620.0", + "@aws-sdk/middleware-user-agent": "3.637.0", "@aws-sdk/region-config-resolver": "3.614.0", "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-endpoints": "3.637.0", "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.1", + "@smithy/core": "^2.4.0", "@smithy/fetch-http-handler": "^3.2.4", "@smithy/hash-node": "^3.0.3", "@smithy/invalid-dependency": "^3.0.3", "@smithy/middleware-content-length": "^3.0.5", "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.13", + "@smithy/middleware-retry": "^3.0.15", "@smithy/middleware-serde": "^3.0.3", "@smithy/middleware-stack": "^3.0.3", "@smithy/node-config-provider": "^3.1.4", "@smithy/node-http-handler": "^3.1.4", "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", + "@smithy/smithy-client": "^3.2.0", "@smithy/types": "^3.3.0", "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.13", - "@smithy/util-defaults-mode-node": "^3.0.13", + "@smithy/util-defaults-mode-browser": "^3.0.15", + "@smithy/util-defaults-mode-node": "^3.0.15", "@smithy/util-endpoints": "^2.0.5", "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", @@ -320,50 +322,50 @@ "node": ">=16.0.0" }, "peerDependencies": { - "@aws-sdk/client-sts": "^3.621.0" + "@aws-sdk/client-sts": "^3.637.0" } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.621.0.tgz", - "integrity": "sha512-707uiuReSt+nAx6d0c21xLjLm2lxeKc7padxjv92CIrIocnQSlJPxSCM7r5zBhwiahJA6MNQwmTl2xznU67KgA==", + "version": "3.637.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.637.0.tgz", + "integrity": "sha512-xUi7x4qDubtA8QREtlblPuAcn91GS/09YVEY/RwU7xCY0aqGuFwgszAANlha4OUIqva8oVj2WO4gJuG+iaSnhw==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.621.0", - "@aws-sdk/core": "3.621.0", - "@aws-sdk/credential-provider-node": "3.621.0", + "@aws-sdk/client-sso-oidc": "3.637.0", + "@aws-sdk/core": "3.635.0", + "@aws-sdk/credential-provider-node": "3.637.0", "@aws-sdk/middleware-host-header": "3.620.0", "@aws-sdk/middleware-logger": "3.609.0", "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.620.0", + "@aws-sdk/middleware-user-agent": "3.637.0", "@aws-sdk/region-config-resolver": "3.614.0", "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-endpoints": "3.637.0", "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.1", + "@smithy/core": "^2.4.0", "@smithy/fetch-http-handler": "^3.2.4", "@smithy/hash-node": "^3.0.3", "@smithy/invalid-dependency": "^3.0.3", "@smithy/middleware-content-length": "^3.0.5", "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.13", + "@smithy/middleware-retry": "^3.0.15", "@smithy/middleware-serde": "^3.0.3", "@smithy/middleware-stack": "^3.0.3", "@smithy/node-config-provider": "^3.1.4", "@smithy/node-http-handler": "^3.1.4", "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", + "@smithy/smithy-client": "^3.2.0", "@smithy/types": "^3.3.0", "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.13", - "@smithy/util-defaults-mode-node": "^3.0.13", + "@smithy/util-defaults-mode-browser": "^3.0.15", + "@smithy/util-defaults-mode-node": "^3.0.15", "@smithy/util-endpoints": "^2.0.5", "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", @@ -375,16 +377,17 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.621.0.tgz", - "integrity": "sha512-CtOwWmDdEiINkGXD93iGfXjN0WmCp9l45cDWHHGa8lRgEDyhuL7bwd/pH5aSzj0j8SiQBG2k0S7DHbd5RaqvbQ==", + "version": "3.635.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.635.0.tgz", + "integrity": "sha512-i1x/E/sgA+liUE1XJ7rj1dhyXpAKO1UKFUcTTHXok2ARjWTvszHnSXMOsB77aPbmn0fUp1JTx2kHUAZ1LVt5Bg==", "optional": true, "dependencies": { - "@smithy/core": "^2.3.1", + "@smithy/core": "^2.4.0", "@smithy/node-config-provider": "^3.1.4", + "@smithy/property-provider": "^3.1.3", "@smithy/protocol-http": "^4.1.0", "@smithy/signature-v4": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", + "@smithy/smithy-client": "^3.2.0", "@smithy/types": "^3.3.0", "@smithy/util-middleware": "^3.0.3", "fast-xml-parser": "4.4.1", @@ -395,12 +398,12 @@ } }, "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.621.0.tgz", - "integrity": "sha512-Q+3awvTVJSqIGRjCUQflRwKPKlZ0TfmL3EQHgFLhZZrToeBapEA62+FY+T70aTKAZZZZprlvYeFPtBloNd5ziA==", + "version": "3.637.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.637.0.tgz", + "integrity": "sha512-9qK1mF+EThtv3tsL1C/wb9MpWctJSkzjrLTFj+0Rtk8VYm6DlGepo/I6a2x3SeDmdBfHAFSrKFU39GqWDp1mwQ==", "optional": true, "dependencies": { - "@aws-sdk/client-cognito-identity": "3.621.0", + "@aws-sdk/client-cognito-identity": "3.637.0", "@aws-sdk/types": "3.609.0", "@smithy/property-provider": "^3.1.3", "@smithy/types": "^3.3.0", @@ -426,9 +429,9 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.621.0.tgz", - "integrity": "sha512-/jc2tEsdkT1QQAI5Dvoci50DbSxtJrevemwFsm0B73pwCcOQZ5ZwwSdVqGsPutzYzUVx3bcXg3LRL7jLACqRIg==", + "version": "3.635.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.635.0.tgz", + "integrity": "sha512-iJyRgEjOCQlBMXqtwPLIKYc7Bsc6nqjrZybdMDenPDa+kmLg7xh8LxHsu9088e+2/wtLicE34FsJJIfzu3L82g==", "optional": true, "dependencies": { "@aws-sdk/types": "3.609.0", @@ -436,7 +439,7 @@ "@smithy/node-http-handler": "^3.1.4", "@smithy/property-provider": "^3.1.3", "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", + "@smithy/smithy-client": "^3.2.0", "@smithy/types": "^3.3.0", "@smithy/util-stream": "^3.1.3", "tslib": "^2.6.2" @@ -446,15 +449,15 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.621.0.tgz", - "integrity": "sha512-0EWVnSc+JQn5HLnF5Xv405M8n4zfdx9gyGdpnCmAmFqEDHA8LmBdxJdpUk1Ovp/I5oPANhjojxabIW5f1uU0RA==", + "version": "3.637.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.637.0.tgz", + "integrity": "sha512-h+PFCWfZ0Q3Dx84SppET/TFpcQHmxFW8/oV9ArEvMilw4EBN+IlxgbL0CnHwjHW64szcmrM0mbebjEfHf4FXmw==", "optional": true, "dependencies": { "@aws-sdk/credential-provider-env": "3.620.1", - "@aws-sdk/credential-provider-http": "3.621.0", + "@aws-sdk/credential-provider-http": "3.635.0", "@aws-sdk/credential-provider-process": "3.620.1", - "@aws-sdk/credential-provider-sso": "3.621.0", + "@aws-sdk/credential-provider-sso": "3.637.0", "@aws-sdk/credential-provider-web-identity": "3.621.0", "@aws-sdk/types": "3.609.0", "@smithy/credential-provider-imds": "^3.2.0", @@ -467,20 +470,20 @@ "node": ">=16.0.0" }, "peerDependencies": { - "@aws-sdk/client-sts": "^3.621.0" + "@aws-sdk/client-sts": "^3.637.0" } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.621.0.tgz", - "integrity": "sha512-4JqpccUgz5Snanpt2+53hbOBbJQrSFq7E1sAAbgY6BKVQUsW5qyXqnjvSF32kDeKa5JpBl3bBWLZl04IadcPHw==", + "version": "3.637.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.637.0.tgz", + "integrity": "sha512-yoEhoxJJfs7sPVQ6Is939BDQJZpZCoUgKr/ySse4YKOZ24t4VqgHA6+wV7rYh+7IW24Rd91UTvEzSuHYTlxlNA==", "optional": true, "dependencies": { "@aws-sdk/credential-provider-env": "3.620.1", - "@aws-sdk/credential-provider-http": "3.621.0", - "@aws-sdk/credential-provider-ini": "3.621.0", + "@aws-sdk/credential-provider-http": "3.635.0", + "@aws-sdk/credential-provider-ini": "3.637.0", "@aws-sdk/credential-provider-process": "3.620.1", - "@aws-sdk/credential-provider-sso": "3.621.0", + "@aws-sdk/credential-provider-sso": "3.637.0", "@aws-sdk/credential-provider-web-identity": "3.621.0", "@aws-sdk/types": "3.609.0", "@smithy/credential-provider-imds": "^3.2.0", @@ -510,12 +513,12 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.621.0.tgz", - "integrity": "sha512-Kza0jcFeA/GEL6xJlzR2KFf1PfZKMFnxfGzJzl5yN7EjoGdMijl34KaRyVnfRjnCWcsUpBWKNIDk9WZVMY9yiw==", + "version": "3.637.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.637.0.tgz", + "integrity": "sha512-Mvz+h+e62/tl+dVikLafhv+qkZJ9RUb8l2YN/LeKMWkxQylPT83CPk9aimVhCV89zth1zpREArl97+3xsfgQvA==", "optional": true, "dependencies": { - "@aws-sdk/client-sso": "3.621.0", + "@aws-sdk/client-sso": "3.637.0", "@aws-sdk/token-providers": "3.614.0", "@aws-sdk/types": "3.609.0", "@smithy/property-provider": "^3.1.3", @@ -546,21 +549,21 @@ } }, "node_modules/@aws-sdk/credential-providers": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.621.0.tgz", - "integrity": "sha512-FQbC7I8ae/72ZekLBa45jWJ+Q3d+YPhc3bW/rCks6RrldM6RgLTGr8pTOPCxHl828ky10RjkBiBmVU818rliyw==", + "version": "3.637.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.637.0.tgz", + "integrity": "sha512-yW1scL3Z7JsrTrmhjyZsB6tsMJ49UCO42BGlNWZAW+kN1vNJ+qbv6XYQJWR4gjpuD2rdmtGcEawcgllE2Bmigw==", "optional": true, "dependencies": { - "@aws-sdk/client-cognito-identity": "3.621.0", - "@aws-sdk/client-sso": "3.621.0", - "@aws-sdk/client-sts": "3.621.0", - "@aws-sdk/credential-provider-cognito-identity": "3.621.0", + "@aws-sdk/client-cognito-identity": "3.637.0", + "@aws-sdk/client-sso": "3.637.0", + "@aws-sdk/client-sts": "3.637.0", + "@aws-sdk/credential-provider-cognito-identity": "3.637.0", "@aws-sdk/credential-provider-env": "3.620.1", - "@aws-sdk/credential-provider-http": "3.621.0", - "@aws-sdk/credential-provider-ini": "3.621.0", - "@aws-sdk/credential-provider-node": "3.621.0", + "@aws-sdk/credential-provider-http": "3.635.0", + "@aws-sdk/credential-provider-ini": "3.637.0", + "@aws-sdk/credential-provider-node": "3.637.0", "@aws-sdk/credential-provider-process": "3.620.1", - "@aws-sdk/credential-provider-sso": "3.621.0", + "@aws-sdk/credential-provider-sso": "3.637.0", "@aws-sdk/credential-provider-web-identity": "3.621.0", "@aws-sdk/types": "3.609.0", "@smithy/credential-provider-imds": "^3.2.0", @@ -617,13 +620,13 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.620.0.tgz", - "integrity": "sha512-bvS6etn+KsuL32ubY5D3xNof1qkenpbJXf/ugGXbg0n98DvDFQ/F+SMLxHgbnER5dsKYchNnhmtI6/FC3HFu/A==", + "version": "3.637.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.637.0.tgz", + "integrity": "sha512-EYo0NE9/da/OY8STDsK2LvM4kNa79DBsf4YVtaG4P5pZ615IeFsD8xOHZeuJmUrSMlVQ8ywPRX7WMucUybsKug==", "optional": true, "dependencies": { "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-endpoints": "3.637.0", "@smithy/protocol-http": "^4.1.0", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" @@ -682,9 +685,9 @@ } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.614.0.tgz", - "integrity": "sha512-wK2cdrXHH4oz4IomV/yrGkftU9A+ITB6nFL+rxxyO78is2ifHJpFdV4aqk4LSkXYPi6CXWNru/Dqc7yiKXgJPw==", + "version": "3.637.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.637.0.tgz", + "integrity": "sha512-pAqOKUHeVWHEXXDIp/qoMk/6jyxIb6GGjnK1/f8dKHtKIEs4tKsnnL563gceEvdad53OPXIt86uoevCcCzmBnw==", "optional": true, "dependencies": { "@aws-sdk/types": "3.609.0", @@ -744,9 +747,9 @@ } }, "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", "engines": { "node": ">=0.1.90" } @@ -761,16 +764,40 @@ "kuler": "^2.0.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.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.3.tgz", - "integrity": "sha512-uGo44hIwoLGNyduRpjdEpovcbMdd+Nv7amtmJxnKmI8xj6yd5LncmSwDa5NgX/41lIFJtkjD6YdVfgEzPfJ5UA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.9.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -779,41 +806,18 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://opencollective.com/eslint" } }, - "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/eslintrc/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==", + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@grammyjs/i18n": { @@ -829,31 +833,10 @@ "node": ">=12" } }, - "node_modules/@grammyjs/i18n/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@grammyjs/i18n/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/@grammyjs/ratelimiter": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@grammyjs/ratelimiter/-/ratelimiter-1.1.5.tgz", - "integrity": "sha512-VQrDv05eOis5QdBwaR/AnnE2AxAsR2CiN8VdYaaCtGSS66yzBcUpz9xmjbn5WtZiJhJBf+9YHCh6IhYT3NYQKw==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@grammyjs/ratelimiter/-/ratelimiter-1.2.0.tgz", + "integrity": "sha512-xBkH/ATJsuv5JgVYX9yQM9DNg75Qqjw+gh82lVsBn4j+d0DkxxC+kuy6WFoB96Cb6oifQfaBJL8CTikdYG4v0A==" }, "node_modules/@grpc/grpc-js": { "version": "1.8.17", @@ -885,91 +868,45 @@ "node": ">=6" } }, - "node_modules/@grpc/proto-loader/node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@grpc/proto-loader/node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@grpc/proto-loader/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "engines": { - "node": ">=12" - } - }, "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.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==", + "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, - "dependencies": { - "ms": "2.1.2" - }, "engines": { - "node": ">=6.0" + "node": ">=12.22" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "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/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", "dev": true }, "node_modules/@mongodb-js/saslprep": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.0.tgz", - "integrity": "sha512-Xfijy7HvfzzqiOAhAepF4SGN5e9leLkMvg/OPOF97XemjfVCYN/oWa75wnkc6mltMSTwY+XlbhWgUOJmkFspSw==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz", + "integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==", "optional": true, "dependencies": { "sparse-bitfield": "^3.0.3" @@ -1016,6 +953,41 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -1070,6 +1042,12 @@ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true + }, "node_modules/@scure/base": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", @@ -1118,14 +1096,23 @@ } }, "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", "dev": true, "dependencies": { "type-detect": "4.0.8" } }, + "node_modules/@sinonjs/commons/node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/@sinonjs/fake-timers": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", @@ -1136,9 +1123,9 @@ } }, "node_modules/@sinonjs/samsam": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.0.2.tgz", - "integrity": "sha512-jxPRPp9n93ci7b8hMfJOFDPRLFYadN6FSpeROFTR4UNF4i5b+EK6m4QXPO46BDhFgRy1JuS87zAnFOzCUwMJcQ==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.3.tgz", + "integrity": "sha512-nhOb2dWPeb1sd3IQXL/dVPnKHDOAFfvichtBf4xV00/rU1QbPCQqKMbvIheIjqwVjh7qIgf2AHTHi391yMOMpQ==", "dev": true, "dependencies": { "@sinonjs/commons": "^1.6.0", @@ -1147,9 +1134,9 @@ } }, "node_modules/@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", + "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", "dev": true }, "node_modules/@smithy/abort-controller": { @@ -1182,18 +1169,20 @@ } }, "node_modules/@smithy/core": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.3.1.tgz", - "integrity": "sha512-BC7VMXx/1BCmRPCVzzn4HGWAtsrb7/0758EtwOGFJQrlSwJBEjCcDLNZLFoL/68JexYa2s+KmgL/UfmXdG6v1w==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.4.0.tgz", + "integrity": "sha512-cHXq+FneIF/KJbt4q4pjN186+Jf4ZB0ZOqEaZMBhT79srEyGDDBV31NqBRBjazz8ppQ1bJbDJMY9ba5wKFV36w==", "optional": true, "dependencies": { "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.13", + "@smithy/middleware-retry": "^3.0.15", "@smithy/middleware-serde": "^3.0.3", "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.11", + "@smithy/smithy-client": "^3.2.0", "@smithy/types": "^3.3.0", + "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-middleware": "^3.0.3", + "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, "engines": { @@ -1299,15 +1288,15 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.13.tgz", - "integrity": "sha512-zvCLfaRYCaUmjbF2yxShGZdolSHft7NNCTA28HVN9hKcEbOH+g5irr1X9s+in8EpambclGnevZY4A3lYpvDCFw==", + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.15.tgz", + "integrity": "sha512-iTMedvNt1ApdvkaoE8aSDuwaoc+BhvHqttbA/FO4Ty+y/S5hW6Ci/CTScG7vam4RYJWZxdTElc3MEfHRVH6cgQ==", "optional": true, "dependencies": { "@smithy/node-config-provider": "^3.1.4", "@smithy/protocol-http": "^4.1.0", "@smithy/service-error-classification": "^3.0.3", - "@smithy/smithy-client": "^3.1.11", + "@smithy/smithy-client": "^3.2.0", "@smithy/types": "^3.3.0", "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", @@ -1473,9 +1462,9 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.11.tgz", - "integrity": "sha512-l0BpyYkciNyMaS+PnFFz4aO5sBcXvGLoJd7mX9xrMBIm2nIQBVvYgp2ZpPDMzwjKCavsXu06iuCm0F6ZJZc6yQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.2.0.tgz", + "integrity": "sha512-pDbtxs8WOhJLJSeaF/eAbPgXg4VVYFlRcL/zoNYA5WbG3wBL06CHtBSg53ppkttDpAJ/hdiede+xApip1CwSLw==", "optional": true, "dependencies": { "@smithy/middleware-endpoint": "^3.1.0", @@ -1573,13 +1562,13 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.13.tgz", - "integrity": "sha512-ZIRSUsnnMRStOP6OKtW+gCSiVFkwnfQF2xtf32QKAbHR6ACjhbAybDvry+3L5qQYdh3H6+7yD/AiUE45n8mTTw==", + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.15.tgz", + "integrity": "sha512-FZ4Psa3vjp8kOXcd3HJOiDPBCWtiilLl57r0cnNtq/Ga9RSDrM5ERL6xt+tO43+2af6Pn5Yp92x2n5vPuduNfg==", "optional": true, "dependencies": { "@smithy/property-provider": "^3.1.3", - "@smithy/smithy-client": "^3.1.11", + "@smithy/smithy-client": "^3.2.0", "@smithy/types": "^3.3.0", "bowser": "^2.11.0", "tslib": "^2.6.2" @@ -1589,16 +1578,16 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.13.tgz", - "integrity": "sha512-voUa8TFJGfD+U12tlNNLCDlXibt9vRdNzRX45Onk/WxZe7TS+hTOZouEZRa7oARGicdgeXvt1A0W45qLGYdy+g==", + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.15.tgz", + "integrity": "sha512-KSyAAx2q6d0t6f/S4XB2+3+6aQacm3aLMhs9aLMqn18uYGUepbdssfogW5JQZpc6lXNBnp0tEnR5e9CEKmEd7A==", "optional": true, "dependencies": { "@smithy/config-resolver": "^3.0.5", "@smithy/credential-provider-imds": "^3.2.0", "@smithy/node-config-provider": "^3.1.4", "@smithy/property-provider": "^3.1.3", - "@smithy/smithy-client": "^3.1.11", + "@smithy/smithy-client": "^3.2.0", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, @@ -1703,24 +1692,29 @@ "node": ">=16.0.0" } }, + "node_modules/@telegraf/types": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@telegraf/types/-/types-7.1.0.tgz", + "integrity": "sha512-kGevOIbpMcIlCDeorKGpwZmdH7kHbqlk/Yj6dEpJMKEQw5lk0KVQY0OLXaCswy8GqlIVLd5625OB+rAntP9xVw==" + }, "node_modules/@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "node_modules/@types/caseless": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", - "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", + "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==" }, "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dependencies": { "@types/node": "*" } @@ -1737,9 +1731,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.35", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", - "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -1748,9 +1742,9 @@ } }, "node_modules/@types/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" }, "node_modules/@types/json5": { "version": "0.0.29", @@ -1764,14 +1758,17 @@ "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" }, "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "node_modules/@types/node": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.0.tgz", - "integrity": "sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q==" + "version": "20.16.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.4.tgz", + "integrity": "sha512-ioyQ1zK9aGEomJ45zz8S8IdzElyxhvP1RVWnPrXDf6wFaUb+kk1tEcVVJkF7RPGM0VWI7cp5U57oCPIn5iN1qg==", + "dependencies": { + "undici-types": "~6.19.2" + } }, "node_modules/@types/qrcode": { "version": "1.5.5", @@ -1783,14 +1780,14 @@ } }, "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" }, "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, "node_modules/@types/request": { "version": "2.48.8", @@ -1803,34 +1800,52 @@ "form-data": "^2.5.0" } }, + "node_modules/@types/request/node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, "node_modules/@types/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", - "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "node_modules/@types/serve-static": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", - "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", "dependencies": { "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" + "@types/node": "*", + "@types/send": "*" } }, "node_modules/@types/tough-cookie": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", - "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==" + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==" + }, + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" }, "node_modules/@types/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" }, "node_modules/@types/whatwg-url": { "version": "8.2.2", @@ -1855,10 +1870,10 @@ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "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/abort-controller": { @@ -1885,9 +1900,9 @@ } }, "node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1916,27 +1931,6 @@ "node": ">= 6.0.0" } }, - "node_modules/agent-base/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/agent-base/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1985,9 +1979,9 @@ } }, "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", @@ -2002,21 +1996,38 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "node_modules/array-includes": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", - "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" }, "engines": { @@ -2026,16 +2037,18 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.flat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", - "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -2044,16 +2057,74 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, "engines": { - "node": "*" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/async": { + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/async": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" @@ -2069,31 +2140,33 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, - "node_modules/axios/node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2101,9 +2174,9 @@ "dev": true }, "node_modules/base-x": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", - "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", + "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", "dependencies": { "safe-buffer": "^5.0.1" } @@ -2133,18 +2206,21 @@ "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/bip174": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/bip174/-/bip174-2.1.0.tgz", - "integrity": "sha512-lkc0XyiX9E9KiVAS1ZiOqK1xfiwvf4FXDDdkDq5crcDzOq+xGytY+14qCsqz7kCiy8rpN1CRNfacRhf9G3JNSA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bip174/-/bip174-2.1.1.tgz", + "integrity": "sha512-mdFV5+/v0XyNYXjBS6CQPLo9ekCx4gtKZFnJm5PMto7Fs9hTTDpkkzOB7/FtluRI6JbUUAu+snTYfJRgHLZbZQ==", "engines": { "node": ">=8.0.0" } @@ -2185,26 +2261,41 @@ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" }, "node_modules/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", - "dev": true, + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" } }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/bolt07": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/bolt07/-/bolt07-1.8.1.tgz", @@ -2258,7 +2349,7 @@ "node_modules/bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", "dependencies": { "base-x": "^3.0.2" } @@ -2324,12 +2415,12 @@ "node_modules/buffer-fill": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==" }, "node_modules/bufferutil": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.7.tgz", - "integrity": "sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", "hasInstallScript": true, "dependencies": { "node-gyp-build": "^4.3.0" @@ -2339,22 +2430,19 @@ } }, "node_modules/builtins": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-4.1.0.tgz", - "integrity": "sha512-1bPRZQtmKaO6h7qV1YHXNtr6nCK28k0Zo95KM4dXfILcZZwoHJBN1m3lfLv9LPkcOZlrSr+J1bzMaZFO98Yq0w==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", + "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==", "dev": true, "dependencies": { "semver": "^7.0.0" } }, "node_modules/builtins/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -2370,21 +2458,19 @@ "node": ">= 0.8" } }, - "node_modules/cacheable-lookup": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.0.4.tgz", - "integrity": "sha512-mbcDEZCkv2CZF4G01kr8eBd/5agkt9oCqz75tJMSIsquvRZ2sL6Hi5zGVKi/0OSC9oO1GHfJ2AV0ZIOY9vye0A==", - "engines": { - "node": ">=10.6.0" - } - }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2400,11 +2486,15 @@ } }, "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cbor": { @@ -2419,42 +2509,56 @@ } }, "node_modules/chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "type-detect": "^4.1.0" }, "engines": { "node": ">=4" } }, + "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/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, "engines": { "node": "*" } }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -2467,6 +2571,9 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } @@ -2481,14 +2588,16 @@ } }, "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/color": { @@ -2536,7 +2645,7 @@ "node_modules/color/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/colorspace": { "version": "1.1.4", @@ -2569,7 +2678,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "node_modules/content-disposition": { @@ -2592,10 +2701,9 @@ } }, "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true, + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "engines": { "node": ">= 0.6" } @@ -2603,7 +2711,7 @@ "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/create-hash": { "version": "1.2.0", @@ -2618,15 +2726,14 @@ } }, "node_modules/cron-parser": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-3.5.0.tgz", - "integrity": "sha512-wyVZtbRs6qDfFd8ap457w3XVntdvqcwBGxBoTvJQH9KGVKL/fB+h2k3C8AqiVxvUQKN1Ps/Ns46CNViOpVDhfQ==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", + "integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==", "dependencies": { - "is-nan": "^1.3.2", - "luxon": "^1.26.0" + "luxon": "^3.2.1" }, "engines": { - "node": ">=0.8" + "node": ">=12.0.0" } }, "node_modules/cross-spawn": { @@ -2650,20 +2757,82 @@ "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in." }, "node_modules/d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "dependencies": { - "ms": "2.0.0" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/decamelize": { @@ -2679,15 +2848,15 @@ } }, "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", "dev": true, "dependencies": { "type-detect": "^4.0.0" }, "engines": { - "node": ">=0.12" + "node": ">=6" } }, "node_modules/deep-extend": { @@ -2705,11 +2874,29 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/define-properties": { + "node_modules/define-data-property": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -2723,26 +2910,28 @@ "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { "node": ">=0.4.0" } }, "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true, + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==", - "dev": true - }, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, "node_modules/diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -2753,9 +2942,9 @@ } }, "node_modules/dijkstrajs": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.2.tgz", - "integrity": "sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz", + "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==" }, "node_modules/doctrine": { "version": "3.0.0", @@ -2793,7 +2982,7 @@ "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -2805,48 +2994,66 @@ "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" }, - "node_modules/encode-utf8": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", - "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==" - }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "engines": { "node": ">= 0.8" } }, "node_modules/es-abstract": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", - "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", + "is-shared-array-buffer": "^1.0.3", "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -2855,13 +3062,58 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-shim-unscopables": { + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" } }, "node_modules/es-to-primitive": { @@ -2907,18 +3159,21 @@ } }, "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "engines": { "node": ">=6" } @@ -2926,7 +3181,7 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "node_modules/escape-string-regexp": { "version": "4.0.0", @@ -2941,46 +3196,49 @@ } }, "node_modules/eslint": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz", - "integrity": "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA==", - "dev": true, - "dependencies": { - "@eslint/eslintrc": "^1.2.3", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@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.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "esquery": "^1.4.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", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.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.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -2993,9 +3251,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", + "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -3005,9 +3263,9 @@ } }, "node_modules/eslint-config-standard": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz", - "integrity": "sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", + "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", "dev": true, "funding": [ { @@ -3023,21 +3281,25 @@ "url": "https://feross.org/support" } ], + "engines": { + "node": ">=12.0.0" + }, "peerDependencies": { "eslint": "^8.0.1", "eslint-plugin-import": "^2.25.2", - "eslint-plugin-n": "^15.0.0", + "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", "eslint-plugin-promise": "^6.0.0" } }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "dependencies": { "debug": "^3.2.7", - "resolve": "^1.20.0" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { @@ -3049,23 +3311,21 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-import-resolver-node/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.9.0.tgz", + "integrity": "sha512-McVbYmwA3NEKwRQY5g4aWMdcZE5xZxV8i8l7CqJSrameuGSQJtSWaL/LxTEzSKKaCcOhlpDR8XEfYXWPrdo/ZQ==", "dev": true, "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.0" + "debug": "^3.2.7" }, "engines": { "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, "node_modules/eslint-module-utils/node_modules/debug": { @@ -3077,70 +3337,6 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-module-utils/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/eslint-module-utils/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/eslint-plugin-es": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", @@ -3185,24 +3381,29 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz", + "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==", "dev": true, "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.9.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" @@ -3211,6 +3412,15 @@ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/eslint-plugin-import/node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -3224,19 +3434,19 @@ } }, "node_modules/eslint-plugin-n": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.2.0.tgz", - "integrity": "sha512-lWLg++jGwC88GDGGBX3CMkk0GIWq0y41aH51lavWApOKcMQcYoL3Ayd0lEdtD3SnQtR+3qBvWQS3qGbR2BxRWg==", + "version": "15.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.7.0.tgz", + "integrity": "sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q==", "dev": true, "dependencies": { - "builtins": "^4.0.0", + "builtins": "^5.0.1", "eslint-plugin-es": "^4.1.0", "eslint-utils": "^3.0.0", "ignore": "^5.1.1", - "is-core-module": "^2.3.0", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.3.0" + "is-core-module": "^2.11.0", + "minimatch": "^3.1.2", + "resolve": "^1.22.1", + "semver": "^7.3.8" }, "engines": { "node": ">=12.22.0" @@ -3249,30 +3459,36 @@ } }, "node_modules/eslint-plugin-n/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/eslint-plugin-promise": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.0.0.tgz", - "integrity": "sha512-7GPezalm5Bfi/E22PnQxDWH2iW9GTvAlUNTztemeHb6c1BniSyoeTrM87JkC0wYdi6aQrZX9p2qEiAno8aTcbw==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.6.0.tgz", + "integrity": "sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" } }, "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "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", @@ -3280,6 +3496,9 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-utils": { @@ -3310,45 +3529,15 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "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" - } - }, - "node_modules/eslint/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/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 - } + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/glob-parent": { @@ -3363,45 +3552,6 @@ "node": ">=10.13.0" } }, - "node_modules/eslint/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/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/eslint/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/eslint/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/esniff": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", @@ -3416,29 +3566,27 @@ "node": ">=0.10" } }, - "node_modules/esniff/node_modules/type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" - }, "node_modules/espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "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.7.1", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "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.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -3480,7 +3628,7 @@ "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "engines": { "node": ">= 0.6" } @@ -3503,38 +3651,38 @@ } }, "node_modules/express": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", - "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", - "dev": true, + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.2", + "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.2", + "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.1.2", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.9.7", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", + "send": "0.18.0", + "serve-static": "1.15.0", "setprototypeof": "1.2.0", - "statuses": "~1.5.0", + "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -3543,26 +3691,71 @@ "node": ">= 0.10.0" } }, - "node_modules/ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dependencies": { - "type": "^2.7.2" - } - }, - "node_modules/ext/node_modules/type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" - }, - "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": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dependencies": { + "type": "^2.7.2" + } + }, + "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==", @@ -3571,7 +3764,7 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "node_modules/fast-xml-parser": { @@ -3596,6 +3789,15 @@ "fxparser": "src/cli/cli.js" } }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/fecha": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", @@ -3613,6 +3815,19 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/fill-keys": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", + "integrity": "sha512-tcgI872xXjwFF4xgQmLxi76GnwJG3g/3isB1l4/G5Z4zrbddGpBjqZCO9oEAcB5wX0Hj/5iQB3toxfO7in1hHA==", + "dev": true, + "dependencies": { + "is-object": "~1.0.1", + "merge-descriptors": "~1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -3626,23 +3841,35 @@ } }, "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~1.5.0", + "statuses": "2.0.1", "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -3669,12 +3896,13 @@ } }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { @@ -3682,9 +3910,9 @@ } }, "node_modules/flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/fn.name": { @@ -3693,9 +3921,9 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.8.tgz", + "integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==", "funding": [ { "type": "individual", @@ -3711,17 +3939,26 @@ } } }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dependencies": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" }, "engines": { - "node": ">= 0.12" + "node": ">= 6" } }, "node_modules/forwarded": { @@ -3735,7 +3972,7 @@ "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "engines": { "node": ">= 0.6" } @@ -3743,7 +3980,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "node_modules/fsevents": { @@ -3761,20 +3998,23 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" }, "engines": { "node": ">= 0.4" @@ -3783,12 +4023,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "node_modules/functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -3807,35 +4041,41 @@ } }, "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "engines": { "node": "*" } }, "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" @@ -3848,6 +4088,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -3877,9 +4118,9 @@ } }, "node_modules/globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -3891,18 +4132,39 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globals/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==", + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -3912,17 +4174,6 @@ "node": ">=4.x" } }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -3933,20 +4184,31 @@ } }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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": ">=4" + "node": ">=8" } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dependencies": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3964,12 +4226,12 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -3991,6 +4253,17 @@ "node": ">=4" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -4001,19 +4274,18 @@ } }, "node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "dev": true, + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dependencies": { - "depd": "~1.1.2", + "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", + "statuses": "2.0.1", "toidentifier": "1.0.1" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/http-shutdown": { @@ -4057,9 +4329,9 @@ ] }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "engines": { "node": ">= 4" @@ -4068,7 +4340,7 @@ "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": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", "dev": true }, "node_modules/import-fresh": { @@ -4090,7 +4362,7 @@ "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "engines": { "node": ">=0.8.19" @@ -4099,7 +4371,8 @@ "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, "dependencies": { "once": "^1.3.0", @@ -4112,13 +4385,13 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "hasown": "^2.0.0", "side-channel": "^1.0.4" }, "engines": { @@ -4141,10 +4414,17 @@ "node": ">=12.20.0" } }, - "node_modules/ip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", - "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==" + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } }, "node_modules/ipaddr.js": { "version": "1.9.1", @@ -4154,6 +4434,22 @@ "node": ">= 0.10" } }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", @@ -4200,9 +4496,9 @@ } }, "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "engines": { "node": ">= 0.4" @@ -4212,12 +4508,30 @@ } }, "node_modules/is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", "dev": true, "dependencies": { - "has": "^1.0.3" + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4241,7 +4555,7 @@ "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "engines": { "node": ">=0.10.0" @@ -4267,25 +4581,10 @@ "node": ">=0.10.0" } }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { "node": ">= 0.4" @@ -4318,6 +4617,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -4344,12 +4661,15 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4396,6 +4716,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -4425,10 +4760,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "node_modules/js-yaml": { @@ -4442,6 +4783,17 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" + }, + "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", @@ -4451,7 +4803,7 @@ "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": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "node_modules/json5": { @@ -4467,9 +4819,9 @@ } }, "node_modules/just-extend": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", "dev": true }, "node_modules/kareem": { @@ -4480,6 +4832,15 @@ "node": ">=12.0.0" } }, + "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/kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", @@ -4559,29 +4920,6 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" }, - "node_modules/lightning/node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "node_modules/lightning/node_modules/bolt07": { "version": "1.8.4", "resolved": "https://registry.npmjs.org/bolt07/-/bolt07-1.8.4.tgz", @@ -4615,141 +4953,6 @@ "bs58": "^5.0.0" } }, - "node_modules/lightning/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/lightning/node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/lightning/node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/lightning/node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/lightning/node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/lightning/node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/lightning/node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/lightning/node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/lightning/node_modules/invoices": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/invoices/-/invoices-3.0.0.tgz", @@ -4777,208 +4980,92 @@ "node": ">=14.0.0" } }, - "node_modules/lightning/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/lightning/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "node_modules/lightning/node_modules/tiny-secp256k1": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-2.2.3.tgz", + "integrity": "sha512-SGcL07SxcPN2nGKHTCvRMkQLYPSoeFcvArUSCYtjVARiFAWU44cCIqYS0mYAU6nY7XfvwURuTIGo2Omt3ZQr0Q==", "dependencies": { - "ee-first": "1.1.1" + "uint8array-tools": "0.0.7" }, "engines": { - "node": ">= 0.8" + "node": ">=14.0.0" } }, - "node_modules/lightning/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "node_modules/lightning/node_modules/type-fest": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.12.0.tgz", + "integrity": "sha512-qj9wWsnFvVEMUDbESiilKeXeHL7FwwiFcogfhfyjmvT968RXSvnl23f1JOClTHYItsi7o501C/7qVllscUP3oA==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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": { - "side-channel": "^1.0.4" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=0.6" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lightning/node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, + "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/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "engines": { - "node": ">= 0.8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lightning/node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "node_modules/logform": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.1.tgz", + "integrity": "sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA==", "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lightning/node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lightning/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/lightning/node_modules/tiny-secp256k1": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-2.2.3.tgz", - "integrity": "sha512-SGcL07SxcPN2nGKHTCvRMkQLYPSoeFcvArUSCYtjVARiFAWU44cCIqYS0mYAU6nY7XfvwURuTIGo2Omt3ZQr0Q==", - "dependencies": { - "uint8array-tools": "0.0.7" - }, - "engines": { - "node": ">=14.0.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": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true - }, - "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/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/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/log-symbols/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/log-symbols/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/logform": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.4.0.tgz", - "integrity": "sha512-CPSJw4ftjf517EhXZGGvTHHkYobo7ZCc0kvwUoOYcjfR2UVrI66RHj8MCrfAdEitdmFqbu2BYdYs8FHHZSb6iw==", - "dependencies": { - "@colors/colors": "1.5.0", + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" } }, - "node_modules/logform/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, "node_modules/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -4987,26 +5074,23 @@ "node_modules/long-timeout": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz", - "integrity": "sha1-lyHXiLR+C8taJMLivuGg2lXatRQ=" + "integrity": "sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w==" }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "get-func-name": "^2.0.1" } }, "node_modules/luxon": { - "version": "1.28.1", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.1.tgz", - "integrity": "sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.5.0.tgz", + "integrity": "sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==", "engines": { - "node": "*" + "node": ">=12" } }, "node_modules/md5.js": { @@ -5022,7 +5106,7 @@ "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "engines": { "node": ">= 0.6" } @@ -5036,12 +5120,12 @@ "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "engines": { "node": ">= 0.6" } @@ -5089,9 +5173,13 @@ } }, "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/mocha": { "version": "9.2.2", @@ -5136,6 +5224,44 @@ "url": "https://opencollective.com/mochajs" } }, + "node_modules/mocha/node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, "node_modules/mocha/node_modules/debug": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", @@ -5159,15 +5285,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/mocha/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/mocha/node_modules/minimatch": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", @@ -5186,18 +5303,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "node_modules/mocha/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/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -5213,19 +5318,29 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/mocha/node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, "engines": { "node": ">=10" } }, - "node_modules/module-alias": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz", - "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==" + "node_modules/module-not-found-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz", + "integrity": "sha512-pEk4ECWQXV6z2zjhRZUongnLJNUeGQJ3w6OQ5ctGwD+i5o93qjRQUk2Rt6VdNeu3sEP0AB4LcfvdebpxBRVr4g==", + "dev": true }, "node_modules/mongodb": { "version": "4.17.1", @@ -5298,32 +5413,19 @@ "node": ">=12.0.0" } }, - "node_modules/mquery/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=4" } }, - "node_modules/mquery/node_modules/ms": { + "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, "node_modules/nanoid": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", @@ -5339,7 +5441,7 @@ "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "node_modules/negotiator": { @@ -5356,46 +5458,64 @@ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, "node_modules/nise": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.0.tgz", - "integrity": "sha512-W5WlHu+wvo3PaKLsJJkgPup2LrsXCcm7AWwyNZkUnn5rwPkuPBi3Iwk5SQtN0mv+K65k7nKKjwNQ30wg3wLAQQ==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", + "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.7.0", - "@sinonjs/fake-timers": "^7.0.4", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "path-to-regexp": "^1.7.0" + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", + "just-extend": "^6.2.0", + "path-to-regexp": "^6.2.1" } }, - "node_modules/nise/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "node_modules/nise/node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "node_modules/nise/node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, "dependencies": { - "isarray": "0.0.1" + "type-detect": "4.0.8" } }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "node_modules/nise/node_modules/@sinonjs/fake-timers": { + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.3.1.tgz", + "integrity": "sha512-EVJO7nW5M/F5Tur0Rf2z/QoMo+1Ia963RiMtapiQrEWvY0iBUvADo8Beegwjpnle5BHkyHuoxSTW3jF43H1XRA==", + "dev": true, "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/nise/node_modules/path-to-regexp": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", + "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", + "dev": true + }, + "node_modules/nise/node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, "peerDependenciesMeta": { "encoding": { "optional": true @@ -5405,26 +5525,26 @@ "node_modules/node-fetch/node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/node-fetch/node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/node-fetch/node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "node_modules/node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", + "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -5432,11 +5552,11 @@ } }, "node_modules/node-schedule": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-2.0.0.tgz", - "integrity": "sha512-cHc9KEcfiuXxYDU+HjsBVo2FkWL1jRAUoczFoMIzRBpOA4p/NRHuuLs85AWOLgKsHtSPjN8csvwIxc2SqMv+CQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-2.1.1.tgz", + "integrity": "sha512-OXdegQq03OmXEjt2hZP33W2YPs/E5BcFQks46+G2gAxs4gHOIVD1u7EqlYLYSKsaIpyKCK9Gbk0ta1/gjRSMRQ==", "dependencies": { - "cron-parser": "^3.1.0", + "cron-parser": "^4.2.0", "long-timeout": "0.1.1", "sorted-array-functions": "^1.3.0" }, @@ -5482,33 +5602,42 @@ "ms": "^2.1.1" } }, - "node_modules/nodemon/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", + "node_modules/nodemon/node_modules/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, "engines": { - "node": ">=12.19" + "node": ">=4" } }, - "node_modules/nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "node_modules/nodemon/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "dependencies": { - "abbrev": "1" - }, "bin": { - "nopt": "bin/nopt.js" + "semver": "bin/semver" + } + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" }, "engines": { - "node": "*" + "node": ">=4" + } + }, + "node_modules/nofilter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", + "engines": { + "node": ">=12.19" } }, "node_modules/normalize-path": { @@ -5521,9 +5650,9 @@ } }, "node_modules/nostr-tools": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-2.5.2.tgz", - "integrity": "sha512-Ls2FKh694eudBye6q89yJ5JhXjQle1MWp1yD2sBZ5j9M3IOBEW8ia9IED5W6daSAjlT/Z/pV77yTkdF45c1Rbg==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-2.7.2.tgz", + "integrity": "sha512-Bq3Ug0SZFtgtL1+0wCnAe8AJtI7yx/00/a2nUug9SkhfOwlKS92Tef12iCK9FdwXw+oFZWMtRnSwcLayQso+xA==", "dependencies": { "@noble/ciphers": "^0.5.1", "@noble/curves": "1.2.0", @@ -5551,9 +5680,12 @@ "optional": true }, "node_modules/object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5562,19 +5694,20 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, "engines": { @@ -5584,15 +5717,47 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -5602,10 +5767,9 @@ } }, "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dependencies": { "ee-first": "1.1.1" }, @@ -5616,7 +5780,7 @@ "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "dependencies": { "wrappy": "1" @@ -5631,9 +5795,9 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "dependencies": { "deep-is": "^0.1.3", @@ -5641,7 +5805,7 @@ "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -5686,12 +5850,11 @@ } }, "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true, + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/parent-module": { @@ -5725,7 +5888,7 @@ "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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -5749,7 +5912,7 @@ "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "node_modules/pathval": { "version": "1.1.1", @@ -5761,9 +5924,9 @@ } }, "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { "node": ">=8.6" @@ -5780,6 +5943,15 @@ "node": ">=10.13.0" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5790,9 +5962,9 @@ } }, "node_modules/prettier": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", - "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -5805,9 +5977,9 @@ } }, "node_modules/protobufjs": { - "version": "7.2.6", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", - "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", "hasInstallScript": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", @@ -5849,6 +6021,17 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/proxyquire": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-2.1.3.tgz", + "integrity": "sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg==", + "dev": true, + "dependencies": { + "fill-keys": "^1.0.2", + "module-not-found-error": "^1.0.1", + "resolve": "^1.11.1" + } + }, "node_modules/psbt": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/psbt/-/psbt-3.0.0.tgz", @@ -5915,9 +6098,9 @@ "dev": true }, "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "engines": { "node": ">=6" } @@ -5931,12 +6114,11 @@ } }, "node_modules/qrcode": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.0.tgz", - "integrity": "sha512-9MgRpgVc+/+47dFvQeD6U2s0Z92EsKzcHogtum4QB+UNd025WOJSHvn/hjk9xmzj7Stj95CyUAs31mrjxliEsQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz", + "integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==", "dependencies": { "dijkstrajs": "^1.0.1", - "encode-utf8": "^1.0.3", "pngjs": "^5.0.0", "yargs": "^15.3.1" }, @@ -5947,6 +6129,14 @@ "node": ">=10.13.0" } }, + "node_modules/qrcode/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, "node_modules/qrcode/node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -6013,14 +6203,6 @@ "node": ">=8" } }, - "node_modules/qrcode/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, "node_modules/qrcode/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -6073,10 +6255,12 @@ } }, "node_modules/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", - "dev": true, + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, "engines": { "node": ">=0.6" }, @@ -6084,6 +6268,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -6101,13 +6305,12 @@ } }, "node_modules/raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", - "dev": true, + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { "bytes": "3.1.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, @@ -6116,9 +6319,9 @@ } }, "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -6141,14 +6344,15 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -6172,7 +6376,7 @@ "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "engines": { "node": ">=0.10.0" } @@ -6183,12 +6387,12 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, "node_modules/resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -6208,10 +6412,21 @@ "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==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { "glob": "^7.1.3" @@ -6232,6 +6447,47 @@ "inherits": "^2.0.1" } }, + "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-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -6259,10 +6515,27 @@ "buffer-alloc": "^1.2.0" } }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-stable-stringify": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz", - "integrity": "sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", "engines": { "node": ">=10" } @@ -6281,43 +6554,54 @@ } }, "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { - "semver": "bin/semver" + "semver": "bin/semver.js" } }, "node_modules/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", - "dev": true, + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dependencies": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/serialize-javascript": { "version": "6.0.0", @@ -6329,15 +6613,14 @@ } }, "node_modules/serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", - "dev": true, + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.2" + "send": "0.18.0" }, "engines": { "node": ">= 0.8.0" @@ -6348,6 +6631,37 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -6387,13 +6701,17 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6407,15 +6725,15 @@ "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "dependencies": { "is-arrayish": "^0.3.1" } }, "node_modules/simple-update-notifier": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz", - "integrity": "sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", "dev": true, "dependencies": { "semver": "~7.0.0" @@ -6437,6 +6755,7 @@ "version": "11.1.2", "resolved": "https://registry.npmjs.org/sinon/-/sinon-11.1.2.tgz", "integrity": "sha512-59237HChms4kg7/sXhiRcUzdSkKuydDeTiamT/jesUVHshBgL8XAmhgFo0GfK6RruMDM/iRSij1EybmMog9cJw==", + "deprecated": "16.1.1", "dev": true, "dependencies": { "@sinonjs/commons": "^1.8.3", @@ -6451,27 +6770,6 @@ "url": "https://opencollective.com/sinon" } }, - "node_modules/sinon/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/sinon/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/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -6482,25 +6780,24 @@ } }, "node_modules/socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "dependencies": { - "ip": "^2.0.0", + "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" }, "engines": { - "node": ">= 10.13.0", + "node": ">= 10.0.0", "npm": ">= 3.0.0" } }, "node_modules/socks-proxy-agent": { - "version": "6.2.0-beta.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.0-beta.0.tgz", - "integrity": "sha512-vJVDGsyaBh7cP8BfynQV1sSqiZ045FkNTyaWLz1g4Ut3sCIuO52sxK0ix8yvqf5n0teDyY1Pw4NRclRiuGTV+w==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", + "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", "dependencies": { "agent-base": "^6.0.2", - "cacheable-lookup": "~6.0.4", "debug": "^4.3.3", "socks": "^2.6.2" }, @@ -6508,27 +6805,6 @@ "node": ">= 10" } }, - "node_modules/socks-proxy-agent/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/socks-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/sorted-array-functions": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.3.0.tgz", @@ -6543,21 +6819,25 @@ "memory-pager": "^1.0.2" } }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==" + }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", "engines": { "node": "*" } }, "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/string_decoder": { @@ -6581,29 +6861,50 @@ "node": ">=8" } }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6623,140 +6924,374 @@ "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "optional": true + }, + "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/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/telegraf": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/telegraf/-/telegraf-4.16.3.tgz", + "integrity": "sha512-yjEu2NwkHlXu0OARWoNhJlIjX09dRktiMQFsM678BAH/PEPVwctzL67+tvXqLCRQQvm3SDtki2saGO9hLlz68w==", + "dependencies": { + "@telegraf/types": "^7.1.0", + "abort-controller": "^3.0.0", + "debug": "^4.3.4", + "mri": "^1.2.0", + "node-fetch": "^2.7.0", + "p-timeout": "^4.1.0", + "safe-compare": "^1.1.4", + "sandwich-stream": "^2.0.2" + }, + "bin": { + "telegraf": "lib/cli.mjs" + }, + "engines": { + "node": "^12.20.0 || >=14.13.1" + } + }, + "node_modules/telegram-test-api": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/telegram-test-api/-/telegram-test-api-2.6.0.tgz", + "integrity": "sha512-Q/NFZwMS8vWytCAcUF/s47rQUvhXXgh0PQYJcAqI0hcxJPv5chX1f407MHzBnHoV+bMl4hStLmA0KaEuFcgFrA==", "dev": true, + "dependencies": { + "axios": "0.24.0", + "body-parser": "~1.19.0", + "debug": "~4.3.2", + "deep-extend": "~0.6.0", + "express": "~4.17.1", + "http-shutdown": "~1.2.2", + "p-timeout": "^4.1.0" + }, + "engines": { + "node": ">=12.0" + } + }, + "node_modules/telegram-test-api/node_modules/axios": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", + "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.14.4" + } + }, + "node_modules/telegram-test-api/node_modules/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/telegram-test-api/node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/telegram-test-api/node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/telegram-test-api/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/telegram-test-api/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/telegram-test-api/node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==", + "dev": true + }, + "node_modules/telegram-test-api/node_modules/express": { + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", + "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.19.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.4.2", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.9.7", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.17.2", + "serve-static": "1.14.2", + "setprototypeof": "1.2.0", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/telegram-test-api/node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/telegram-test-api/node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/telegram-test-api/node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/telegram-test-api/node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/telegram-test-api/node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/telegram-test-api/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, "engines": { - "node": ">=4" + "node": ">= 0.6" } }, - "node_modules/strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", - "optional": true + "node_modules/telegram-test-api/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/telegram-test-api/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "ee-first": "1.1.1" }, "engines": { - "node": ">=4" + "node": ">= 0.8" } }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "node_modules/telegram-test-api/node_modules/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=0.6" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/telegraf": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/telegraf/-/telegraf-4.7.0.tgz", - "integrity": "sha512-rspH4kiVHE1zpnyQvlGFj+Tzu7zN02gSOcdLUayvnkaTwww2E6xBkwne+DKkDPdaRhvQ61J+dcVhLQv9fL+FsQ==", - "dependencies": { - "abort-controller": "^3.0.0", - "debug": "^4.3.3", - "minimist": "^1.2.5", - "module-alias": "^2.2.2", - "node-fetch": "^2.6.7", - "p-timeout": "^4.1.0", - "safe-compare": "^1.1.4", - "sandwich-stream": "^2.0.2", - "typegram": "^3.8.0" - }, - "bin": { - "telegraf": "bin/telegraf" - }, - "engines": { - "node": "^12.20.0 || >=14.13.1" - } - }, - "node_modules/telegraf/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "node_modules/telegram-test-api/node_modules/raw-body": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "dev": true, "dependencies": { - "ms": "2.1.2" + "bytes": "3.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 0.8" } }, - "node_modules/telegraf/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/telegram-test-api": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/telegram-test-api/-/telegram-test-api-2.5.0.tgz", - "integrity": "sha512-jouSQtVLxjjxqBH//Ga6CHiBZ2KlAwGtJ/C/oeuJBohYmDAeljyj1qUK70u2vOb99bWqyhdsosAIGnAffv++Lw==", + "node_modules/telegram-test-api/node_modules/send": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", "dev": true, "dependencies": { - "axios": "~0.21.1", - "bluebird": "~3.7.2", - "body-parser": "~1.19.0", - "debug": "~4.3.1", - "deep-extend": "~0.6.0", - "express": "~4.17.1", - "http-shutdown": "~1.2.2" + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "1.8.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" }, "engines": { - "node": ">=8.0" + "node": ">= 0.8.0" } }, - "node_modules/telegram-test-api/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "node_modules/telegram-test-api/node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "follow-redirects": "^1.14.0" + "ms": "2.0.0" } }, - "node_modules/telegram-test-api/node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "node_modules/telegram-test-api/node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/telegram-test-api/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "node_modules/telegram-test-api/node_modules/serve-static": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", "dev": true, "dependencies": { - "ms": "2.1.2" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.2" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 0.8.0" } }, - "node_modules/telegram-test-api/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/telegram-test-api/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } }, "node_modules/text-hex": { "version": "1.0.0", @@ -6766,7 +7301,7 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "node_modules/tiny-secp256k1": { @@ -6801,13 +7336,10 @@ } }, "node_modules/touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", "dev": true, - "dependencies": { - "nopt": "~1.0.10" - }, "bin": { "nodetouch": "bin/nodetouch.js" } @@ -6824,37 +7356,40 @@ } }, "node_modules/triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "engines": { + "node": ">= 14.0.0" + } }, "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "optional": true }, "node_modules/tstl": { - "version": "2.5.13", - "resolved": "https://registry.npmjs.org/tstl/-/tstl-2.5.13.tgz", - "integrity": "sha512-h9wayHHFI5+yqt8iau0vqH96cTNhezhZ/Fk/hrIdpfkiMu3lg9nzyvMfs5bIdX51IVzZO6DudLqhkL/rVXpT6g==" + "version": "2.5.16", + "resolved": "https://registry.npmjs.org/tstl/-/tstl-2.5.16.tgz", + "integrity": "sha512-+O2ybLVLKcBwKm4HymCEwZIT0PpwS3gCYnxfSDEjJEKADvIFruaQjd3m7CAKNU1c7N3X3WjVz87re7TA2A5FUw==" }, "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==" }, "node_modules/type-check": { "version": "0.4.0", @@ -6869,20 +7404,21 @@ } }, "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/type-fest": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.12.0.tgz", - "integrity": "sha512-qj9wWsnFvVEMUDbESiilKeXeHL7FwwiFcogfhfyjmvT968RXSvnl23f1JOClTHYItsi7o501C/7qVllscUP3oA==", + "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": ">=14.16" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6900,6 +7436,79 @@ "node": ">= 0.6" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -6914,9 +7523,10 @@ "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" }, "node_modules/typegram": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/typegram/-/typegram-3.8.0.tgz", - "integrity": "sha512-MdlbWu0HfmgFJf4+xj6eqGYuanV2LJxBYTzLrD0kTV+woQ5dxDD2k8UVVjYnbBGkAagAyxzQevPiFZRWLFHSBw==" + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typegram/-/typegram-5.2.0.tgz", + "integrity": "sha512-QubWrgT+tVPpM3/KkT/Rdd2zTYUwx96hePKBSio8pAWUD847M6W6akZppFs5BKfLtzuHBeTgjps528LJ+H1k+w==", + "dev": true }, "node_modules/typescript": { "version": "5.1.6", @@ -6960,10 +7570,15 @@ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "engines": { "node": ">= 0.8" } @@ -6992,12 +7607,12 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "engines": { "node": ">= 0.4.0" } @@ -7015,12 +7630,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "node_modules/varuint-bitcoin": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz", @@ -7032,7 +7641,7 @@ "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "engines": { "node": ">= 0.8" } @@ -7046,13 +7655,13 @@ } }, "node_modules/websocket": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", - "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", + "version": "1.0.35", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.35.tgz", + "integrity": "sha512-/REy6amwPZl44DDzvRCkaI1q1bIiQB0mEFQLUrhz3z2EK91cp3n72rAjUlrTP0zV22HJIUOVHQGPxhFRjxjt+Q==", "dependencies": { "bufferutil": "^4.0.1", "debug": "^2.2.0", - "es5-ext": "^0.10.50", + "es5-ext": "^0.10.63", "typedarray-to-buffer": "^3.1.5", "utf-8-validate": "^5.0.2", "yaeti": "^0.0.6" @@ -7070,6 +7679,19 @@ "websocket": "^1.0.28" } }, + "node_modules/websocket/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/websocket/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/whatwg-url": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", @@ -7114,55 +7736,75 @@ } }, "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/wif": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", - "integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=", + "integrity": "sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ==", "dependencies": { "bs58check": "<3.0.0" } }, "node_modules/winston": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.7.2.tgz", - "integrity": "sha512-QziIqtojHBoyzUOdQvQiar1DH0Xp9nF1A1y7NVy2DGEsz82SBDtOalS0ulTRGVT14xPX3WRWkCsdcJKqNflKng==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.14.2.tgz", + "integrity": "sha512-CO8cdpBB2yqzEf8v895L+GNKYJiEq8eKlHU38af3snQBQ+sdAIUepjMSguOIJC7ICbzm0ZI+Af2If4vIJrtmOg==", "dependencies": { + "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", - "logform": "^2.4.0", + "logform": "^2.6.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", - "winston-transport": "^4.5.0" + "winston-transport": "^4.7.0" }, "engines": { "node": ">= 12.0.0" } }, "node_modules/winston-transport": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", - "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.1.tgz", + "integrity": "sha512-wQCXXVgfv/wUPOfb2x0ruxzwkcZfxcktz6JIMUaPLmcNhO4bZTwA/WtDWK74xV3F2dKu8YadrFv0qhwYjVEwhA==", "dependencies": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", + "logform": "^2.6.1", + "readable-stream": "^3.6.2", "triple-beam": "^1.3.0" }, "engines": { - "node": ">= 6.4.0" + "node": ">= 12.0.0" } }, "node_modules/word-wrap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", - "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -7193,7 +7835,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "node_modules/y18n": { @@ -7212,34 +7854,27 @@ "node": ">=0.10.32" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true, "engines": { "node": ">=10" @@ -7260,16 +7895,12 @@ "node": ">=10" } }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, "node_modules/yocto-queue": { diff --git a/package.json b/package.json index b622708c..47a582ed 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "lint": "eslint .", "format": "prettier --write '**/*.js'", "pretest": "npx tsc", - "test": "export NODE_ENV=test && mocha --exit tests/" + "test": "export NODE_ENV=test && mocha --exit 'tests/**/*.js'" }, "license": "MIT", "dependencies": { @@ -22,7 +22,7 @@ "crypto": "^1.0.1", "dotenv": "^10.0.0", "invoices": "2.0.6", - "lightning": "^9.8.1", + "lightning": "9.8.1", "mongoose": "6.12.0", "node-schedule": "^2.0.0", "nostr-tools": "^2.5.2", @@ -53,8 +53,10 @@ "mocha": "^9.2.2", "nodemon": "2.0.19", "prettier": "^2.6.2", + "proxyquire": "^2.1.3", "sinon": "^11.1.2", "telegram-test-api": "^2.5.0", - "typescript": "^5.1.6" + "typegram": "^5.2.0", + "typescript": "5.1.6" } } diff --git a/tests/bot/modules/dispute/messages.js b/tests/bot/modules/dispute/messages.js new file mode 100644 index 00000000..dd876916 --- /dev/null +++ b/tests/bot/modules/dispute/messages.js @@ -0,0 +1,137 @@ +const { assert } = require('chai'); +const sinon = require('sinon'); +const proxyquire = require('proxyquire'); + +const getDetailedOrderStub = sinon.stub().returns('Mocked order detail'); +const { disputeData } = proxyquire('../../../../bot/modules/dispute/messages', { + '../../../util': { getDetailedOrder: getDetailedOrderStub } +}); + +// Mock dependencies +const mockTelegram = { + sendMessage: sinon.stub(), +}; + +const mockI18n = { + t: sinon.stub((key, params) => { + switch (key) { + case 'dispute_started_channel': + return `User ${params.type} @${params.initiatorUser.username} TG ID: ${params.initiatorTgId} + has started a dispute with @${params.counterPartyUser.username} TG ID: ${params.counterPartyUserTgId} for the order + + ${params.detailedOrder} + + Seller Token: ${params.sellerToken} + Buyer Token: ${params.buyerToken} + + @${params.initiatorUser.username} has been involved in ${params.buyerDisputes} disputes + @${params.counterPartyUser.username} has been involved in ${params.sellerDisputes} disputes`; + case 'seller': + return 'seller'; + case 'buyer': + return 'buyer'; + case 'dispute_solver': + return `Dispute taken by ${params.solver} with token ${params.token}`; + default: + return ''; + } + }), +}; + +const mockCtx = { + telegram: mockTelegram, + i18n: mockI18n, +}; + +const mockOrder = { + seller_dispute_token: 'seller_token', + buyer_dispute_token: 'buyer_token', +}; + +const mockBuyerUnderscore = { username: 'buyer_user', tg_id: '246802' }; +const mockBuyerNormal = { username: 'buyeruser', tg_id: '246802' }; +const mockBuyerSpecial = { username: 'buyer-user', tg_id: '246802' }; +const mockSeller = { username: 'seller_user', tg_id: '567890' }; +const mockSolver = { username: 'solver', tg_id: '123456' }; + +describe('disputeData', () => { + afterEach(() => { + sinon.restore(); + }); + + it('should send a message with escaped underscores in username', async () => { + await disputeData( + mockCtx, + mockBuyerUnderscore, + mockSeller, + mockOrder, + 'buyer', + mockSolver, + 5, + 3 + ); + + assert.isTrue(mockTelegram.sendMessage.calledWith( + mockSolver.tg_id, + sinon.match(/buyer\\_user/), + sinon.match({ parse_mode: 'MarkdownV2' }) + )); + }); + + it('should send a message with another escaped character in username', async () => { + await disputeData( + mockCtx, + mockBuyerSpecial, + mockSeller, + mockOrder, + 'buyer', + mockSolver, + 5, + 3 + ); + + assert.isTrue(mockTelegram.sendMessage.calledWith( + mockSolver.tg_id, + sinon.match(/buyer\\-user/), + sinon.match({ parse_mode: 'MarkdownV2' }) + )); + }); + + it('should send a message without underscores in usernames', async () => { + await disputeData( + mockCtx, + mockBuyerNormal, + mockSeller, + mockOrder, + 'buyer', + mockSolver, + 5, + 3 + ); + + assert.isTrue(mockTelegram.sendMessage.calledWith( + mockSolver.tg_id, + sinon.match('buyeruser'), + sinon.match({ parse_mode: 'MarkdownV2' }) + )); + }); + + it('should swap initiator and counterparty if initiator is seller', async () => { + await disputeData( + mockCtx, + mockBuyerNormal, + mockSeller, + mockOrder, + 'seller', + mockSolver, + 5, + 3 + ); + + assert.isTrue(mockTelegram.sendMessage.calledWith( + mockSolver.tg_id, + sinon.match(/seller\\_user/), + sinon.match({ parse_mode: 'MarkdownV2' }) + )); + }); +}); From 2ee0fce32aa9300a5822ad3fd296dbd10ff036fe Mon Sep 17 00:00:00 2001 From: Catrya <140891948+Catrya@users.noreply.github.com> Date: Fri, 13 Sep 2024 16:29:37 -0400 Subject: [PATCH 4/9] fix error when an admin use chechorder with a pending order (#591) --- util/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/index.js b/util/index.js index 0960768e..6128d311 100644 --- a/util/index.js +++ b/util/index.js @@ -366,8 +366,8 @@ exports.getDetailedOrder = (i18n, order, buyer, seller) => { const fee = order.fee ? parseInt(order.fee) : ''; const creator = order.creator_id === buyerId ? buyerUsername : sellerUsername; - const buyerAge = getUserAge(buyer); - const sellerAge = getUserAge(seller); + const buyerAge = buyer? getUserAge(buyer) : ''; + const sellerAge = seller? getUserAge(seller) : ''; const buyerTrades = buyer ? buyer.trades_completed : 0; const sellerTrades = seller ? seller.trades_completed : 0; const message = i18n.t('order_detail', { From a46260d193702e88e184d3fef7775a6a98c419f5 Mon Sep 17 00:00:00 2001 From: webwarrior-ws Date: Thu, 26 Sep 2024 17:00:07 +0200 Subject: [PATCH 5/9] Convert JS to TS (commits 7-13 of PR435) - attempt#2 (#585) * util/index: convert js to ts The languageModel & fiatModel interface created to type-check the data and ensure that it conforms to the expected structure and format. This can help you avoid errors and bugs when working with the data in your code. This commit enables resolveJsonModule to import module with '.json' extension. Co-authored-by: webwarrior * jobs: convert js to ts The --downlevelIteration flag is a TypeScript compiler option that enables support for iterating over new concepts like Map, Set, or Generator in older JavaScript runtimes. By default, TypeScript targets ES3, which does not support these features. If you use a for...of loop or a spread operator on an iterable object, you may get an error. Use Date instead of Date.toISOString cause paid_at has type Date and during the conversion from js to ts, we got compilation errors. Co-authored-by: webwarrior * bot/start: fixing types & import/exports Co-authored-by: webwarrior * bot/validation: convert js to ts Using null instead of a boolean/undefined type is better. * lnurl/lnurl-pay: convert js to ts I had to change the '|', otherwise typescript would complain this error msg: ``` The '|' operator is not allowed for boolean types. Consider using '||' instead. ``` Co-authored-by: webwarrior * refactor: correcting a bad practice * refactor: there's no need for isInt() * bot: fix bugs in validations.ts Fix bugs in validations.ts introduced in d36a6b7 when porting to TypeScript. * bot,util: fix bug in validateAdmin Fixed bug in validateAdmin that would throw an error when community is null even though null value is valid in this case. * bot: fix date comparison in isValidInvoice Don't convert dates to strings in isValidInvoice. * WIP: added some debug logging Added debug logging for case when `Invoice expiry is too short` error is encountered. * WIP: more debug logging Added debug logging of message that caused error when taking dispute in community. * bot,util,locales,tests: don't use objects in locales Don't use object properties inside locales, as it doesn't work and leads to parse errors. --------- Co-authored-by: Mehrshad --- bot/modules/dispute/messages.js | 44 ++-- bot/start.ts | 75 ++++--- bot/{validations.js => validations.ts} | 147 ++++++++----- ...ngs.js => calculate_community_earnings.ts} | 13 +- jobs/{cancel_orders.js => cancel_orders.ts} | 19 +- jobs/{communities.js => communities.ts} | 15 +- ...d_orders.js => delete_published_orders.ts} | 15 +- jobs/index.js | 19 -- jobs/index.ts | 19 ++ jobs/{node_info.js => node_info.ts} | 13 +- jobs/pending_payments.ts | 27 ++- lnurl/{lnurl-pay.js => lnurl-pay.ts} | 15 +- locales/de.yaml | 8 +- locales/en.yaml | 8 +- locales/es.yaml | 8 +- locales/fa.yaml | 8 +- locales/fr.yaml | 8 +- locales/it.yaml | 8 +- locales/ko.yaml | 8 +- locales/pt.yaml | 8 +- locales/ru.yaml | 8 +- locales/uk.yaml | 8 +- package-lock.json | 10 + package.json | 1 + tests/bot/modules/dispute/messages.js | 8 +- tsconfig.json | 2 + util/fiatModel.ts | 4 + util/{index.js => index.ts} | 203 ++++++++++-------- util/languagesModel.ts | 9 + 29 files changed, 427 insertions(+), 311 deletions(-) rename bot/{validations.js => validations.ts} (75%) rename jobs/{calculate_community_earnings.js => calculate_community_earnings.ts} (77%) rename jobs/{cancel_orders.js => cancel_orders.ts} (86%) rename jobs/{communities.js => communities.ts} (70%) rename jobs/{delete_published_orders.js => delete_published_orders.ts} (73%) delete mode 100644 jobs/index.js create mode 100644 jobs/index.ts rename jobs/{node_info.js => node_info.ts} (62%) rename lnurl/{lnurl-pay.js => lnurl-pay.ts} (76%) rename util/{index.js => index.ts} (70%) create mode 100644 util/languagesModel.ts diff --git a/bot/modules/dispute/messages.js b/bot/modules/dispute/messages.js index 5b1aa0bb..d8bc775f 100644 --- a/bot/modules/dispute/messages.js +++ b/bot/modules/dispute/messages.js @@ -1,4 +1,8 @@ -const { getDisputeChannel, getDetailedOrder, sanitizeMD } = require('../../../util'); +const { + getDisputeChannel, + getDetailedOrder, + sanitizeMD, +} = require('../../../util'); const { logger } = require('../../../logger'); exports.beginDispute = async (ctx, initiator, order, buyer, seller) => { @@ -91,25 +95,25 @@ exports.disputeData = async ( // Fix Issue 543: Escape underscores in usernames const escapedInitiatorUsername = sanitizeMD(initiatorUser.username); const escapedCounterPartyUsername = sanitizeMD(counterPartyUser.username); - - await ctx.telegram.sendMessage( - solver.tg_id, - ctx.i18n.t('dispute_started_channel', { - initiatorUser: { ...initiatorUser, username: escapedInitiatorUsername }, - initiatorTgId: initiatorUser.tg_id, - counterPartyUser: { ...counterPartyUser, username: escapedCounterPartyUsername }, - counterPartyUserTgId: counterPartyUser.tg_id, - buyer, - seller, - buyerDisputes, - sellerDisputes, - detailedOrder, - type, - sellerToken: order.seller_dispute_token, - buyerToken: order.buyer_dispute_token, - }), - { parse_mode: 'MarkdownV2' } - ); + + const message = ctx.i18n.t('dispute_started_channel', { + initiatorUser: escapedInitiatorUsername, + initiatorTgId: initiatorUser.tg_id, + counterPartyUser: escapedCounterPartyUsername, + counterPartyUserTgId: counterPartyUser.tg_id, + buyer, + seller, + buyerDisputes, + sellerDisputes, + detailedOrder, + type, + sellerToken: order.seller_dispute_token, + buyerToken: order.buyer_dispute_token, + }); + console.log(`Contens of message:\n${message}`); + await ctx.telegram.sendMessage(solver.tg_id, message, { + parse_mode: 'MarkdownV2', + }); // message to both parties letting them know the dispute // has been taken by a solver await ctx.telegram.sendMessage( diff --git a/bot/start.ts b/bot/start.ts index fe7a1013..25984393 100644 --- a/bot/start.ts +++ b/bot/start.ts @@ -4,18 +4,17 @@ import { Message } from 'typegram' import { UserDocument } from '../models/user' import { FilterQuery } from 'mongoose'; const OrderEvents = require('./modules/events/orders'); - -const { limit } = require('@grammyjs/ratelimiter'); +import { limit } from "@grammyjs/ratelimiter" const schedule = require('node-schedule'); -const { +import { Order, User, PendingPayment, Community, Dispute, Config, -} = require('../models'); -const { getCurrenciesWithPrice, deleteOrderFromChannel, removeAtSymbol } = require('../util'); +} from '../models'; +import { getCurrenciesWithPrice, deleteOrderFromChannel, removeAtSymbol } from '../util'; const { commandArgsMiddleware, stageMiddleware, @@ -55,7 +54,7 @@ const { validateLightningAddress, } = require('./validations'); import * as messages from './messages'; -const { +import { attemptPendingPayments, cancelOrders, deleteOrders, @@ -63,8 +62,10 @@ const { attemptCommunitiesPendingPayments, deleteCommunity, nodeInfo, -} = require('../jobs'); -const { logger } = require('../logger'); +} from '../jobs'; +import { logger } from "../logger"; +import { ICommunity, IUsernameId } from '../models/community'; + export interface MainContext extends Context { match: Array | null; i18n: I18nContext; @@ -72,7 +73,7 @@ export interface MainContext extends Context { admin: UserDocument; } -interface OrderQuery { +export interface OrderQuery { status?: string; buyer_id?: string; seller_id?: string; @@ -80,7 +81,7 @@ interface OrderQuery { const askForConfirmation = async (user: UserDocument, command: string) => { try { - let orders = []; + let orders: any[] = []; if (command === '/cancel') { const where: FilterQuery = { $and: [ @@ -133,6 +134,7 @@ const askForConfirmation = async (user: UserDocument, command: string) => { return orders; } catch (error) { logger.error(error); + return null; } }; @@ -145,7 +147,7 @@ has the same condition. The problem mentioned above is similar to this issue: https://github.com/telegraf/telegraf/issues/1319#issuecomment-766360594 */ -const ctxUpdateAssertMsg = "ctx.update.message.text is not available."; +export const ctxUpdateAssertMsg = "ctx.update.message.text is not available."; const initialize = (botToken: string, options: Partial>): Telegraf => { const i18n = new I18n({ @@ -215,7 +217,7 @@ const initialize = (botToken: string, options: Partial'); if (!val) return; let config = await Config.findOne(); - if (!config) { + if (config === null) { config = new Config(); } config.maintenance = false; @@ -262,11 +264,11 @@ const initialize = (botToken: string, options: Partial el); + const [command, orderId] = params.filter((el: string) => el); if (!orderId) { const orders = await askForConfirmation(ctx.user, command); - if (!orders.length) return await ctx.reply(`${command} `); + if (orders === null || orders.length === 0) return await ctx.reply(`${command} `); return await messages.showConfirmationButtons(ctx, orders, command); } else if (!(await validateObjectId(ctx, orderId))) { @@ -325,7 +327,7 @@ const initialize = (botToken: string, options: Partial el); + const [command, orderId] = params.filter((el: string) => el); if (!orderId) { const orders = await askForConfirmation(ctx.user, command); - if (!orders.length) return await ctx.reply(`${command} `); + if (orders === null || orders.length === 0) return await ctx.reply(`${command} `); return await messages.showConfirmationButtons(ctx, orders, command); } else if (!(await validateObjectId(ctx, orderId))) { @@ -445,7 +448,7 @@ const initialize = (botToken: string, options: Partial el); + const [command, orderId] = params.filter((el: string) => el); if (!orderId) { const orders = await askForConfirmation(ctx.user, command); - if (!orders.length) return await ctx.reply(`${command} `); + if (orders === null || orders.length === 0) return await ctx.reply(`${command} `); return await messages.showConfirmationButtons(ctx, orders, command); } else if (!(await validateObjectId(ctx, orderId))) { @@ -637,7 +641,7 @@ const initialize = (botToken: string, options: Partial el.id !== user.id + if (community === null) throw Error("Community was not found in DB"); + community.banned_users = community.banned_users.toObject().filter( + (el: IUsernameId) => el.id !== user.id ); await community.save(); } else { @@ -739,7 +745,7 @@ const initialize = (botToken: string, options: Partial { try { const config = await Config.findOne({}); + if (config === null) throw Error("Config was not found in DB"); await messages.showInfoMessage(ctx, ctx.user, config); } catch (error) { logger.error(error); diff --git a/bot/validations.js b/bot/validations.ts similarity index 75% rename from bot/validations.js rename to bot/validations.ts index 356d5447..2af82307 100644 --- a/bot/validations.js +++ b/bot/validations.ts @@ -1,22 +1,34 @@ +import { MainContext, OrderQuery, ctxUpdateAssertMsg } from "./start"; +import { ICommunity } from "../models/community"; +import { FilterQuery } from "mongoose"; +import { UserDocument } from "../models/user"; +import { IOrder } from "../models/order"; +import { Telegraf } from "telegraf"; + const { parsePaymentRequest } = require('invoices'); const { ObjectId } = require('mongoose').Types; -const messages = require('./messages'); -const { Order, User, Community } = require('../models'); -const { - isIso4217, - isDisputeSolver, - removeLightningPrefix, -} = require('../util'); +import * as messages from './messages'; +import { Order, User, Community } from '../models'; +import { isIso4217, isDisputeSolver, removeLightningPrefix } from '../util'; const { existLightningAddress } = require('../lnurl/lnurl-pay'); -const { logger } = require('../logger'); +import { logger } from '../logger'; + +const ctxUpdateMessageFromAssertMsg = "ctx.update.message.from is not available"; // We look in database if the telegram user exists, // if not, it creates a new user -const validateUser = async (ctx, start) => { +const validateUser = async (ctx: MainContext, start: boolean) => { try { - const tgUser = ctx.update.callback_query - ? ctx.update.callback_query.from - : ctx.update.message.from; + let tgUser = null; + if (("callback_query" in ctx.update) && ctx.update.callback_query) { + tgUser = ctx.update.callback_query.from; + } + else if (("message" in ctx.update) && ctx.update.message) { + tgUser = ctx.update.message.from; + } + else { + throw new Error(ctxUpdateAssertMsg); + } // We need to make sure the user has a username if (!tgUser.username) { await ctx.telegram.sendMessage(tgUser.id, ctx.i18n.t('non_handle_error')); @@ -51,13 +63,19 @@ const validateUser = async (ctx, start) => { } }; -const validateSuperAdmin = async (ctx, id) => { +const validateSuperAdmin = async (ctx: MainContext, id?: string) => { try { - const tgUserId = id || ctx.update.message.from.id; + let tgUserId = id; + if (!tgUserId) { + if (!('message' in ctx.update) || !('from' in ctx.update.message)) { + throw new Error(ctxUpdateMessageFromAssertMsg); + } + tgUserId = ctx.update.message.from.id.toString(); + } const user = await User.findOne({ tg_id: tgUserId }); // If the user never started the bot we can't send messages // to that user, so we do nothing - if (!user) return; + if (user === null) return; if (!user.admin) return await messages.notAuthorized(ctx, tgUserId); @@ -68,18 +86,24 @@ const validateSuperAdmin = async (ctx, id) => { } }; -const validateAdmin = async (ctx, id) => { +const validateAdmin = async (ctx: MainContext, id?: string) => { try { - const tgUserId = id || ctx.update.message.from.id; + let tgUserId = id; + if (!tgUserId) { + if (!('message' in ctx.update) || !('from' in ctx.update.message)) { + throw new Error(ctxUpdateMessageFromAssertMsg); + } + tgUserId = ctx.update.message.from.id.toString(); + } const user = await User.findOne({ tg_id: tgUserId }); // If the user never started the bot we can't send messages // to that user, so we do nothing - if (!user) return; + if (user === null) return; let community = null; if (user.default_community_id) community = await Community.findOne({ _id: user.default_community_id }); - + const isSolver = isDisputeSolver(community, user); if (!user.admin && !isSolver) @@ -92,7 +116,7 @@ const validateAdmin = async (ctx, id) => { } }; -const processParameters = args => { +const processParameters = (args: string[]) => { const correctedArgs = []; let isGrouping = false; let groupedString = ''; @@ -124,7 +148,7 @@ const processParameters = args => { return correctedArgs; }; -const validateSellOrder = async ctx => { +const validateSellOrder = async (ctx: MainContext) => { try { let args = ctx.state.command.args; if (args.length < 4) { @@ -169,11 +193,11 @@ const validateSellOrder = async ctx => { return false; } - if (amount !== 0 && amount < process.env.MIN_PAYMENT_AMT) { + if (amount !== 0 && amount < Number(process.env.MIN_PAYMENT_AMT)) { await messages.mustBeGreatherEqThan( ctx, 'monto_en_sats', - process.env.MIN_PAYMENT_AMT + Number(process.env.MIN_PAYMENT_AMT) ); return false; } @@ -188,7 +212,7 @@ const validateSellOrder = async ctx => { return false; } - if (fiatAmount.some(x => x < 1)) { + if (fiatAmount.some((x: number) => x < 1)) { await messages.mustBeGreatherEqThan(ctx, 'monto_en_fiat', 1); return false; } @@ -213,7 +237,7 @@ const validateSellOrder = async ctx => { } }; -const validateBuyOrder = async ctx => { +const validateBuyOrder = async (ctx: MainContext) => { try { let args = ctx.state.command.args; if (args.length < 4) { @@ -257,11 +281,11 @@ const validateBuyOrder = async ctx => { return false; } - if (amount !== 0 && amount < process.env.MIN_PAYMENT_AMT) { + if (amount !== 0 && amount < Number(process.env.MIN_PAYMENT_AMT)) { await messages.mustBeGreatherEqThan( ctx, 'monto_en_sats', - process.env.MIN_PAYMENT_AMT + Number(process.env.MIN_PAYMENT_AMT) ); return false; } @@ -276,7 +300,7 @@ const validateBuyOrder = async ctx => { return false; } - if (fiatAmount.some(x => x < 1)) { + if (fiatAmount.some((x: number) => x < 1)) { await messages.mustBeGreatherEqThan(ctx, 'monto_en_fiat', 1); return false; } @@ -300,21 +324,22 @@ const validateBuyOrder = async ctx => { return false; } }; -const validateLightningAddress = async lightningAddress => { +const validateLightningAddress = async (lightningAddress: string) => { const pattern = /^[\w-.]+@(?:[\w-]+(? { +const validateInvoice = async (ctx: MainContext, lnInvoice: string) => { try { const checkedPrefixlnInvoice = removeLightningPrefix(lnInvoice); const invoice = parsePaymentRequest({ request: checkedPrefixlnInvoice }); const latestDate = new Date( - Date.now() + parseInt(process.env.INVOICE_EXPIRATION_WINDOW) - ).toISOString(); - if (!!invoice.tokens && invoice.tokens < process.env.MIN_PAYMENT_AMT) { + Date.now() + Number(process.env.INVOICE_EXPIRATION_WINDOW) + ); + if (!("MAIN_PAYMENT_AMT" in process.env)) throw Error("MIN_PAYMENT_AMT not found, please check .env file"); + if (!!invoice.tokens && invoice.tokens < Number(process.env.MIN_PAYMENT_AMT)) { await messages.minimunAmountInvoiceMessage(ctx); return false; } @@ -347,14 +372,14 @@ const validateInvoice = async (ctx, lnInvoice) => { } }; -const isValidInvoice = async (ctx, lnInvoice) => { +const isValidInvoice = async (ctx: MainContext, lnInvoice: string) => { try { const checkedPrefixlnInvoice = removeLightningPrefix(lnInvoice); const invoice = parsePaymentRequest({ request: checkedPrefixlnInvoice }); const latestDate = new Date( - Date.now() + parseInt(process.env.INVOICE_EXPIRATION_WINDOW) - ).toISOString(); - if (!!invoice.tokens && invoice.tokens < process.env.MIN_PAYMENT_AMT) { + Date.now() + Number(process.env.INVOICE_EXPIRATION_WINDOW) + ); + if (!!invoice.tokens && invoice.tokens < Number(process.env.MIN_PAYMENT_AMT)) { await messages.invoiceMustBeLargerMessage(ctx); return { success: false, @@ -362,6 +387,9 @@ const isValidInvoice = async (ctx, lnInvoice) => { } if (new Date(invoice.expires_at) < latestDate) { + console.debug(`Date(invoice.expires_at) = ${new Date(invoice.expires_at)}`); + console.debug(`latestDate = ${latestDate}`); + console.debug(`INVOICE_EXPIRATION_WINDOW = ${Number(process.env.INVOICE_EXPIRATION_WINDOW)}`); await messages.invoiceExpiryTooShortMessage(ctx); return { success: false, @@ -401,7 +429,7 @@ const isValidInvoice = async (ctx, lnInvoice) => { } }; -const isOrderCreator = (user, order) => { +const isOrderCreator = (user: UserDocument, order: IOrder) => { try { return user._id == order.creator_id; } catch (error) { @@ -410,7 +438,7 @@ const isOrderCreator = (user, order) => { } }; -const validateTakeSellOrder = async (ctx, bot, user, order) => { +const validateTakeSellOrder = async (ctx: MainContext, bot: Telegraf, user: UserDocument, order: IOrder) => { try { if (!order) { await messages.invalidOrderMessage(ctx, bot, user); @@ -439,10 +467,10 @@ const validateTakeSellOrder = async (ctx, bot, user, order) => { } }; -const validateTakeBuyOrder = async (ctx, bot, user, order) => { +const validateTakeBuyOrder = async (ctx: MainContext, bot: Telegraf, user: UserDocument, order: IOrder) => { try { if (!order) { - await messages.invalidOrderMessage(bot, user); + await messages.invalidOrderMessage(ctx, bot, user); return false; } if (isOrderCreator(user, order) && process.env.NODE_ENV === 'production') { @@ -464,9 +492,9 @@ const validateTakeBuyOrder = async (ctx, bot, user, order) => { } }; -const validateReleaseOrder = async (ctx, user, orderId) => { +const validateReleaseOrder = async (ctx: MainContext, user: UserDocument, orderId: string) => { try { - let where = { + let where: FilterQuery = { seller_id: user._id, status: 'WAITING_BUYER_INVOICE', _id: orderId, @@ -495,7 +523,7 @@ const validateReleaseOrder = async (ctx, user, orderId) => { } order = await Order.findOne(where); - if (!order) { + if (order === null) { await messages.notActiveOrderMessage(ctx); return false; } @@ -507,7 +535,7 @@ const validateReleaseOrder = async (ctx, user, orderId) => { } }; -const validateDisputeOrder = async (ctx, user, orderId) => { +const validateDisputeOrder = async (ctx: MainContext, user: UserDocument, orderId: string) => { try { const where = { $and: [ @@ -519,7 +547,7 @@ const validateDisputeOrder = async (ctx, user, orderId) => { const order = await Order.findOne(where); - if (!order) { + if (order === null) { await messages.notActiveOrderMessage(ctx); return false; } @@ -531,9 +559,9 @@ const validateDisputeOrder = async (ctx, user, orderId) => { } }; -const validateFiatSentOrder = async (ctx, user, orderId) => { +const validateFiatSentOrder = async (ctx: MainContext, user: UserDocument, orderId: string) => { try { - const where = { + const where: FilterQuery = { $and: [ { buyer_id: user._id }, { $or: [{ status: 'ACTIVE' }, { status: 'PAID_HOLD_INVOICE' }] }, @@ -544,7 +572,7 @@ const validateFiatSentOrder = async (ctx, user, orderId) => { where._id = orderId; } const order = await Order.findOne(where); - if (!order) { + if (order === null) { await messages.notActiveOrderMessage(ctx); return false; } @@ -567,7 +595,7 @@ const validateFiatSentOrder = async (ctx, user, orderId) => { }; // If a seller have an order with status FIAT_SENT, return false -const validateSeller = async (ctx, user) => { +const validateSeller = async (ctx: MainContext, user: UserDocument) => { try { const where = { seller_id: user._id, @@ -588,10 +616,13 @@ const validateSeller = async (ctx, user) => { } }; -const validateParams = async (ctx, paramNumber, errOutputString) => { +const validateParams = async (ctx: MainContext, paramNumber: number, errOutputString: string): Promise> => { try { + if (!('message' in ctx.update) || !('text' in ctx.update.message)) { + throw new Error(ctxUpdateAssertMsg); + } const paramsArray = ctx.update.message.text.split(' '); - const params = paramsArray.filter(el => el !== ''); + const params = paramsArray.filter((el: string) => el !== ''); if (params.length !== paramNumber) { await messages.customMessage( ctx, @@ -604,11 +635,11 @@ const validateParams = async (ctx, paramNumber, errOutputString) => { return params.slice(1); } catch (error) { logger.error(error); - return false; + return null; } }; -const validateObjectId = async (ctx, id) => { +const validateObjectId = async (ctx: MainContext, id: string) => { try { if (!ObjectId.isValid(id)) { await messages.notValidIdMessage(ctx); @@ -622,10 +653,10 @@ const validateObjectId = async (ctx, id) => { } }; -const validateUserWaitingOrder = async (ctx, bot, user) => { +const validateUserWaitingOrder = async (ctx: MainContext, bot: Telegraf, user: UserDocument) => { try { // If is a seller - let where = { + let where: FilterQuery = { seller_id: user._id, status: 'WAITING_PAYMENT', }; @@ -652,12 +683,12 @@ const validateUserWaitingOrder = async (ctx, bot, user) => { }; // We check if the user is banned from the community in the order -const isBannedFromCommunity = async (user, communityId) => { +const isBannedFromCommunity = async (user: UserDocument, communityId: string) => { try { if (!communityId) return false; const community = await Community.findOne({ _id: communityId }); if (!community) return false; - return community.banned_users.some(buser => buser.id == user._id); + return community.banned_users.toObject().some((buser: ICommunity) => buser.id == user._id); } catch (error) { logger.error(error); return false; diff --git a/jobs/calculate_community_earnings.js b/jobs/calculate_community_earnings.ts similarity index 77% rename from jobs/calculate_community_earnings.js rename to jobs/calculate_community_earnings.ts index 87eb3e28..3ccc7b39 100644 --- a/jobs/calculate_community_earnings.js +++ b/jobs/calculate_community_earnings.ts @@ -1,5 +1,5 @@ -const { Order, Community } = require('../models'); -const { logger } = require('../logger'); +import { Order, Community } from '../models'; +import { logger } from "../logger"; const calculateEarnings = async () => { try { @@ -12,9 +12,9 @@ const calculateEarnings = async () => { for (const order of orders) { const amount = order.amount; const fee = order.fee; - const botFee = order.bot_fee || parseFloat(process.env.MAX_FEE); + const botFee = order.bot_fee || Number(process.env.MAX_FEE); const communityFeePercent = - order.community_fee || parseFloat(process.env.FEE_PERCENT); + order.community_fee || Number(process.env.FEE_PERCENT); const maxFee = amount * botFee; const communityFee = fee - maxFee * communityFeePercent; const earnings = earningsMap.get(order.community_id) || [0, 0]; @@ -27,6 +27,7 @@ const calculateEarnings = async () => { } for (const [communityId, earnings] of earningsMap) { const community = await Community.findById(communityId); + if (community === null) throw Error("Community was not found in DB"); const amount = Math.round(earnings[0]); community.earnings = community.earnings + amount; community.orders_to_redeem = community.orders_to_redeem + earnings[1]; @@ -36,9 +37,9 @@ const calculateEarnings = async () => { ); } } catch (error) { - const message = error.toString(); + const message = String(error); logger.error(`calculateEarnings catch error: ${message}`); } }; -module.exports = calculateEarnings; +export default calculateEarnings; diff --git a/jobs/cancel_orders.js b/jobs/cancel_orders.ts similarity index 86% rename from jobs/cancel_orders.js rename to jobs/cancel_orders.ts index 4cce5064..686b3dec 100644 --- a/jobs/cancel_orders.js +++ b/jobs/cancel_orders.ts @@ -1,16 +1,18 @@ -const { User, Order } = require('../models'); +import { Telegraf } from "telegraf"; +import { MainContext } from "../bot/start"; +import { User, Order } from "../models"; const { cancelShowHoldInvoice, cancelAddInvoice } = require('../bot/commands'); -const messages = require('../bot/messages'); -const { getUserI18nContext, holdInvoiceExpirationInSecs } = require('../util'); -const { logger } = require('../logger'); +import * as messages from "../bot/messages"; +import { getUserI18nContext, holdInvoiceExpirationInSecs } from '../util'; +import { logger } from "../logger"; const OrderEvents = require('../bot/modules/events/orders'); -const cancelOrders = async bot => { +const cancelOrders = async (bot: Telegraf) => { try { const holdInvoiceTime = new Date(); holdInvoiceTime.setSeconds( holdInvoiceTime.getSeconds() - - parseInt(process.env.HOLD_INVOICE_EXPIRATION_WINDOW) + Number(process.env.HOLD_INVOICE_EXPIRATION_WINDOW) ); // We get the orders where the seller didn't pay the hold invoice before expired // or where the buyer didn't add the invoice @@ -54,6 +56,7 @@ const cancelOrders = async bot => { for (const order of activeOrders) { const buyerUser = await User.findOne({ _id: order.buyer_id }); const sellerUser = await User.findOne({ _id: order.seller_id }); + if (buyerUser === null || sellerUser === null) return; const i18nCtxBuyer = await getUserI18nContext(buyerUser); const i18nCtxSeller = await getUserI18nContext(sellerUser); // Instead of cancel this order we should send this to the admins @@ -79,7 +82,7 @@ const cancelOrders = async bot => { // Now we cancel orders expired // ============================== orderTime = new Date(); - let orderExpirationTime = parseInt( + let orderExpirationTime = Number( process.env.ORDER_PUBLISHED_EXPIRATION_WINDOW ); orderExpirationTime = orderExpirationTime + orderExpirationTime * 0.2; @@ -106,4 +109,4 @@ const cancelOrders = async bot => { } }; -module.exports = cancelOrders; +export default cancelOrders; diff --git a/jobs/communities.js b/jobs/communities.ts similarity index 70% rename from jobs/communities.js rename to jobs/communities.ts index 4d28409e..a3599506 100644 --- a/jobs/communities.js +++ b/jobs/communities.ts @@ -1,12 +1,15 @@ -const { Order, Community } = require('../models'); -const { logger } = require('../logger'); +import { Telegraf } from "telegraf"; +import { MainContext } from "../bot/start"; -const deleteCommunity = async bot => { +import { Order, Community } from '../models'; +import { logger } from "../logger"; + +const deleteCommunity = async (bot: Telegraf) => { try { const communities = await Community.find(); for (const community of communities) { // Delete communities with COMMUNITY_TTL days without a successful order - const days = 86400 * parseInt(process.env.COMMUNITY_TTL); + const days = 86400 * Number(process.env.COMMUNITY_TTL); const time = new Date(); time.setSeconds(time.getSeconds() - days); // If is a new community we don't do anything @@ -26,9 +29,9 @@ const deleteCommunity = async bot => { } } } catch (error) { - const message = error.toString(); + const message = String(error); logger.error(`deleteCommunity catch error: ${message}`); } }; -module.exports = deleteCommunity; +export default deleteCommunity; diff --git a/jobs/delete_published_orders.js b/jobs/delete_published_orders.ts similarity index 73% rename from jobs/delete_published_orders.js rename to jobs/delete_published_orders.ts index bec2af2f..4182840d 100644 --- a/jobs/delete_published_orders.js +++ b/jobs/delete_published_orders.ts @@ -1,13 +1,16 @@ -const { Order } = require('../models'); +import { Telegraf } from "telegraf"; +import { MainContext } from "../bot/start"; + +import { Order } from '../models'; const { deleteOrderFromChannel } = require('../util'); -const { logger } = require('../logger'); +import { logger } from '../logger'; -const deleteOrders = async bot => { +const deleteOrders = async (bot: Telegraf) => { try { const windowTime = new Date(); windowTime.setSeconds( windowTime.getSeconds() - - parseInt(process.env.ORDER_PUBLISHED_EXPIRATION_WINDOW) + Number(process.env.ORDER_PUBLISHED_EXPIRATION_WINDOW) ); // We get the pending orders where time is expired const pendingOrders = await Order.find({ @@ -25,9 +28,9 @@ const deleteOrders = async bot => { await deleteOrderFromChannel(orderCloned, bot.telegram); } } catch (error) { - const message = error.toString(); + const message = String(error); logger.error(`deleteOrders catch error: ${message}`); } }; -module.exports = deleteOrders; +export default deleteOrders; diff --git a/jobs/index.js b/jobs/index.js deleted file mode 100644 index b784f178..00000000 --- a/jobs/index.js +++ /dev/null @@ -1,19 +0,0 @@ -const { - attemptPendingPayments, - attemptCommunitiesPendingPayments, -} = require('./pending_payments'); -const cancelOrders = require('./cancel_orders'); -const deleteOrders = require('./delete_published_orders'); -const calculateEarnings = require('./calculate_community_earnings'); -const deleteCommunity = require('./communities'); -const nodeInfo = require('./node_info'); - -module.exports = { - attemptPendingPayments, - cancelOrders, - deleteOrders, - calculateEarnings, - attemptCommunitiesPendingPayments, - deleteCommunity, - nodeInfo, -}; diff --git a/jobs/index.ts b/jobs/index.ts new file mode 100644 index 00000000..281f16f6 --- /dev/null +++ b/jobs/index.ts @@ -0,0 +1,19 @@ +import { + attemptPendingPayments, + attemptCommunitiesPendingPayments, +} from "./pending_payments"; +import cancelOrders from "./cancel_orders"; +import deleteOrders from "./delete_published_orders"; +import calculateEarnings from './calculate_community_earnings' +import deleteCommunity from './communities' +import nodeInfo from './node_info' + +export { + attemptPendingPayments, + cancelOrders, + deleteOrders, + calculateEarnings, + attemptCommunitiesPendingPayments, + deleteCommunity, + nodeInfo, +}; diff --git a/jobs/node_info.js b/jobs/node_info.ts similarity index 62% rename from jobs/node_info.js rename to jobs/node_info.ts index 94c994d0..22e82eb3 100644 --- a/jobs/node_info.js +++ b/jobs/node_info.ts @@ -1,11 +1,14 @@ -const { Config } = require('../models'); +import { Telegraf } from "telegraf"; +import { MainContext } from "../bot/start"; + +import { Config } from '../models'; const { getInfo } = require('../ln'); const { logger } = require('../logger'); -const info = async bot => { +const info = async (bot: Telegraf) => { try { let config = await Config.findOne({}); - if (!config) { + if (config === null) { config = new Config(); } const info = await getInfo(); @@ -15,9 +18,9 @@ const info = async bot => { config.node_uri = info.uris[0]; await config.save(); } catch (error) { - const message = error.toString(); + const message = String(error); logger.error(`node info catch error: ${message}`); } }; -module.exports = info; +export default info; diff --git a/jobs/pending_payments.ts b/jobs/pending_payments.ts index 90bdfff7..b3b9a091 100644 --- a/jobs/pending_payments.ts +++ b/jobs/pending_payments.ts @@ -1,14 +1,14 @@ -const { payRequest, isPendingPayment } = require('../ln'); -const { PendingPayment, Order, User, Community } = require('../models'); +import { PendingPayment, Order, User, Community } from '../models'; import * as messages from '../bot/messages'; -const { getUserI18nContext } = require('../util'); -const { logger } = require('../logger'); +import { logger } from "../logger"; import { Telegraf } from 'telegraf'; import { I18nContext } from '@grammyjs/i18n'; import { MainContext } from '../bot/start'; +const { payRequest, isPendingPayment } = require('../ln'); +import { getUserI18nContext } from '../util'; const { orderUpdated } = require('../bot/modules/events/orders'); -exports.attemptPendingPayments = async (bot: Telegraf): Promise => { +export const attemptPendingPayments = async (bot: Telegraf): Promise => { const pendingPayments = await PendingPayment.find({ paid: false, attempts: { $lt: process.env.PAYMENT_ATTEMPTS }, @@ -18,6 +18,7 @@ exports.attemptPendingPayments = async (bot: Telegraf): Promise): Promise): Promise): Promise): Promise => { +export const attemptCommunitiesPendingPayments = async (bot: Telegraf): Promise => { const pendingPayments = await PendingPayment.find({ paid: false, attempts: { $lt: process.env.PAYMENT_ATTEMPTS }, @@ -136,6 +141,7 @@ exports.attemptCommunitiesPendingPayments = async (bot: Telegraf): request: pending.payment_request, }); const user = await User.findById(pending.user_id); + if (user === null) throw Error("User was not found in DB"); const i18nCtx: I18nContext = await getUserI18nContext(user); // If the buyer's invoice is expired we let it know and don't try to pay again if (!!payment && payment.is_expired) { @@ -147,9 +153,10 @@ exports.attemptCommunitiesPendingPayments = async (bot: Telegraf): } const community = await Community.findById(pending.community_id); + if (community === null) throw Error("Community was not found in DB"); if (!!payment && !!payment.confirmed_at) { pending.paid = true; - pending.paid_at = new Date().toISOString(); + pending.paid_at = new Date(); // Reset the community's values community.earnings = 0; diff --git a/lnurl/lnurl-pay.js b/lnurl/lnurl-pay.ts similarity index 76% rename from lnurl/lnurl-pay.js rename to lnurl/lnurl-pay.ts index bd0ada6a..96aa85d0 100644 --- a/lnurl/lnurl-pay.js +++ b/lnurl/lnurl-pay.ts @@ -1,11 +1,11 @@ -const axios = require('axios').default; -const { logger } = require('../logger'); +import axios from 'axios'; +import { logger } from "../logger"; // { // pr: String, // bech32-serialized lightning invoice // routes: [], // an empty array // } -const resolvLightningAddress = async (address, amountMsat) => { +const resolvLightningAddress = async (address: string, amountMsat: number) => { const [user, domain] = address.split('@'); const lnAddressQuery = `https://${domain}/.well-known/lnurlp/${user}`; @@ -17,7 +17,7 @@ const resolvLightningAddress = async (address, amountMsat) => { } if ( - (lnAddressRes.minSendable > amountMsat) | + (lnAddressRes.minSendable > amountMsat) || (lnAddressRes.maxSendable < amountMsat) ) { logger.info('lnAddress invalid amount'); @@ -31,7 +31,7 @@ const resolvLightningAddress = async (address, amountMsat) => { return res; }; -const existLightningAddress = async address => { +const existLightningAddress = async (address: string) => { const [user, domain] = address.split('@'); const lnAddressQuery = `https://${domain}/.well-known/lnurlp/${user}`; @@ -48,7 +48,4 @@ const existLightningAddress = async address => { } }; -module.exports = { - resolvLightningAddress, - existLightningAddress, -}; +export { resolvLightningAddress, existLightningAddress } diff --git a/locales/de.yaml b/locales/de.yaml index 4b1e32dd..d3182561 100644 --- a/locales/de.yaml +++ b/locales/de.yaml @@ -202,16 +202,16 @@ order_detail: | seller: Käufer buyer: Verkäufer dispute_started_channel: | - Benutzer ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} - hat einen Streitfall mit @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} für den folgenden Auftrag eröffnet + Benutzer ${type} @${initiatorUser} TG ID: ${initiatorTgId} + hat einen Streitfall mit @${counterPartyUser} TG ID: ${counterPartyUserTgId} für den folgenden Auftrag eröffnet ${detailedOrder} Seller Token: ${sellerToken} Buyer Token: ${buyerToken} - @${initiatorUser.username} war an ${initiatorUser.disputes} Streitfällen beteiligt - @${counterPartyUser.username} war an ${counterPartyUser.disputes} Streitfällen beteiligt + @${initiatorUser} war an ${buyerDisputes} Streitfällen beteiligt + @${counterPartyUser} war an ${sellerDisputes} Streitfällen beteiligt you_started: '🥴 Sie haben einen Streitfall zu Ihrer Bestellnummer begonnen: ${orderId}.' counterpart_started: '🥴 Ihre Gegenpartei hat einen Streit über Ihre Bestellungsnummer begonnen: ${orderId}.' dispute_started: '${who} Wenn er/sie Ihrem Streitfall zugewiesen wird, teilt der Bot Ihnen seinen/ihren Benutzernamen mit, und nur er/sie kann Sie betreuen. Sie können ihm/ihr direkt schreiben, aber wenn er/sie Sie zuerst kontaktiert, müssen Sie ihn/sie bitten, Ihnen den Token Ihres Streitfalls mitzuteilen, Ihr Token ist: ${token}.' diff --git a/locales/en.yaml b/locales/en.yaml index 08baacf0..a9d73982 100644 --- a/locales/en.yaml +++ b/locales/en.yaml @@ -204,16 +204,16 @@ order_detail: | seller: seller buyer: buyer dispute_started_channel: | - User ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} - has started a dispute with @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} for the order + User ${type} @${initiatorUser} TG ID: ${initiatorTgId} + has started a dispute with @${counterPartyUser} TG ID: ${counterPartyUserTgId} for the order ${detailedOrder} Seller Token: ${sellerToken} Buyer Token: ${buyerToken} - @${initiatorUser.username} has been involved in ${initiatorUser.disputes} disputes - @${counterPartyUser.username} has been involved in ${counterPartyUser.disputes} disputes + @${initiatorUser} has been involved in ${buyerDisputes} disputes + @${counterPartyUser} has been involved in ${sellerDisputes} disputes you_started: '🥴 You have started a dispute on your order Id: ${orderId}.' counterpart_started: '🥴 Your counterparty started a dispute on your order Id: ${orderId}.' dispute_started: '${who} A solver will attend you soon, when he/she is assigned to your dispute the bot will tell you his/her username, only he/she will be able to attend you. You can write to him/her directly, but if he/she contacts you first, you must ask him/her to tell you what is the token of your dispute, your token is: ${token}.' diff --git a/locales/es.yaml b/locales/es.yaml index 9baf03fd..26cbc22a 100644 --- a/locales/es.yaml +++ b/locales/es.yaml @@ -202,16 +202,16 @@ order_detail: | seller: vendedor buyer: comprador dispute_started_channel: | - El ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} - ha iniciado una disputa con @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} en la orden: + El ${type} @${initiatorUser} TG ID: ${initiatorTgId} + ha iniciado una disputa con @${counterPartyUser} TG ID: ${counterPartyUserTgId} en la orden: ${detailedOrder} Seller Token: ${sellerToken} Buyer Token: ${buyerToken} - @${initiatorUser.username} ya tiene ${buyerDisputes} disputas - @${counterPartyUser.username} ya tiene ${sellerDisputes} disputas + @${initiatorUser} ya tiene ${buyerDisputes} disputas + @${counterPartyUser} ya tiene ${sellerDisputes} disputas you_started: '🥴 Has iniciado una disputa en tu orden con Id: ${orderId}.' counterpart_started: '🥴 Tu contraparte ha iniciado una disputa en tu orden con Id: ${orderId}.' dispute_started: '${who} Un solver te atenderá pronto, cuando él/la solver sea asignado a tu disputa el bot te dirá su username, solo él/ella podrá atenderte. Puedes escribirle directamente, pero si él/ella te contacta primero, debes pedirle que te diga cuál es el token de tu disputa, tu token es: ${token}.' diff --git a/locales/fa.yaml b/locales/fa.yaml index b95a5ebb..64fa703a 100644 --- a/locales/fa.yaml +++ b/locales/fa.yaml @@ -204,16 +204,16 @@ order_detail: | seller: seller buyer: buyer dispute_started_channel: | - کاربر ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} - بابت سفارش زیر یک مشاجره را با کاربر @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} آغاز کرده + کاربر ${type} @${initiatorUser} TG ID: ${initiatorTgId} + بابت سفارش زیر یک مشاجره را با کاربر @${counterPartyUser} TG ID: ${counterPartyUserTgId} آغاز کرده ${detailedOrder} Seller Token: ${sellerToken} Buyer Token: ${buyerToken} - کابر@${initiatorUser.username} بابت ${initiatorUser.disputes} به اختلاف خورده - کاربر@${counterPartyUser.username} بابت ${counterPartyUser.disputes} به اختلاف خورده + کابر@${initiatorUser} بابت ${buyerDisputes} به اختلاف خورده + کاربر@${counterPartyUser} بابت ${sellerDisputes} به اختلاف خورده you_started: '🥴 شما در مورد شناسه سفارش خود اختلاف نظر شروع کرده اید: ${orderId}.' counterpart_started: '🥴 طرف مقابل شما یک اختلاف بر سر شناسه سفارش شما شروع کرد: ${orderId}.' dispute_started: '${who} یک حل کننده به زودی در شما حضور خواهد یافت، هنگامی که او به منازعه شما منصوب شد، ربات نام کاربری خود را به شما می گوید، فقط او می تواند در شما حضور داشته باشد. شما می توانید مستقیماً برای او نامه بنویسید، اما اگر ابتدا با شما تماس گرفت، باید از او بخواهید که به شما بگوید نشانه اختلاف شما چیست، رمز شما این است: ${token}.' diff --git a/locales/fr.yaml b/locales/fr.yaml index 72421581..7fe68d21 100644 --- a/locales/fr.yaml +++ b/locales/fr.yaml @@ -204,16 +204,16 @@ order_detail: | seller: vendeur buyer: acheteur dispute_started_channel: | - L'utilisateur ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} - à déclenché un litige avec @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} concernant l'offre + L'utilisateur ${type} @${initiatorUser} TG ID: ${initiatorTgId} + à déclenché un litige avec @${counterPartyUser} TG ID: ${counterPartyUserTgId} concernant l'offre ${detailedOrder} Seller Token: ${sellerToken} Buyer Token: ${buyerToken} - @${initiatorUser.username} a été impliqué.e dans ${initiatorUser.disputes} litiges - @${counterPartyUser.username} a été impliqué.e dans ${counterPartyUser.disputes} litiges + @${initiatorUser} a été impliqué.e dans ${buyerDisputes} litiges + @${counterPartyUser} a été impliqué.e dans ${sellerDisputes} litiges you_started : '🥴 Vous avez commencé un litige sur votre commande Id : ${orderId}.' counterpart_started : '🥴 Votre contrepartie a démarré un litige sur votre commande Id : ${orderId}.' dispute_started : "${who} Un solver va bientôt venir vous voir, lorsqu'il/elle sera assigné(e) à votre litige, le bot vous indiquera son nom d'utilisateur, il/elle seul(e) sera en mesure de venir vous voir. Vous pouvez lui écrire directement, mais s'il vous contacte en premier, vous devez lui demander de vous dire quel est le jeton de votre litige, votre jeton est : ${token}." diff --git a/locales/it.yaml b/locales/it.yaml index 4d3862cd..b46301fe 100644 --- a/locales/it.yaml +++ b/locales/it.yaml @@ -202,16 +202,16 @@ order_detail: | seller: venditore buyer: acquirente dispute_started_channel: | - User ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} - ha iniziato una disputa con @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} per l'ordine + User ${type} @${initiatorUser} TG ID: ${initiatorTgId} + ha iniziato una disputa con @${counterPartyUser} TG ID: ${counterPartyUserTgId} per l'ordine ${detailedOrder} Seller Token: ${sellerToken} Buyer Token: ${buyerToken} - @${initiatorUser.username} è stato coinvolto in ${initiatorUser.disputes} dispute - @${counterPartyUser.username} è stato coinvolto in in ${counterPartyUser.disputes} disputee + @${initiatorUser} è stato coinvolto in ${buyerDisputes} dispute + @${counterPartyUser} è stato coinvolto in in ${sellerDisputes} disputee you_started: '🥴 Hai aperto una controversia per il tuo ordine Id: ${orderId}.' counterpart_started: '🥴 La tua controparte ha aperto una controversia sul tuo ordine Id: ${orderId}.' dispute_started: '${who} Un risolutore ti assisterà presto, quando sarà assegnato alla tua controversia il bot ti dirà il suo nome utente, solo lui potrà assisterti. Potete scrivergli direttamente, ma se vi contatta prima, dovete chiedergli di dirvi qual è il token della vostra controversia, il vostro token è: ${token}.' diff --git a/locales/ko.yaml b/locales/ko.yaml index db10e9e8..cd019dab 100644 --- a/locales/ko.yaml +++ b/locales/ko.yaml @@ -203,16 +203,16 @@ order_detail: | seller: 판매자 buyer: 구매자 dispute_started_channel: | - 사용자 ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} - 님께서 @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} 와의 분쟁 조정을 시작하였습니다. 주문 상세 내역은 다음과 같습니다. + 사용자 ${type} @${initiatorUser} TG ID: ${initiatorTgId} + 님께서 @${counterPartyUser} TG ID: ${counterPartyUserTgId} 와의 분쟁 조정을 시작하였습니다. 주문 상세 내역은 다음과 같습니다. ${detailedOrder} Seller Token: ${sellerToken} Buyer Token: ${buyerToken} - ${initiatorUser.disputes} 분쟁 조정에 @${initiatorUser.username}님께서 참여하셨습니다. - ${counterPartyUser.disputes} 분쟁 조정에 @${counterPartyUser.username}님께서 참여하셨습니다. + ${buyerDisputes} 분쟁 조정에 @${initiatorUser}님께서 참여하셨습니다. + ${sellerDisputes} 분쟁 조정에 @${counterPartyUser}님께서 참여하셨습니다. you_started: '🥴 주문 ID에 대한 분쟁이 시작되었습니다: ${orderId}' counterpart_started: '🥴 거래 상대방이 주문 ID에 대해 분쟁을 시작했습니다: ${orderId}' dispute_started: '${who} 해결사가 분쟁에 배정되면 봇이 자신의 사용자 아이디를 알려주며, 해당 해결사만 분쟁에 참석할 수 있습니다. 해결사에게 직접 편지를 보낼 수도 있지만, 해결사가 먼저 연락하는 경우 분쟁의 토큰이 무엇인지 알려달라고 요청해야 합니다(토큰은 ${토큰}입니다).' diff --git a/locales/pt.yaml b/locales/pt.yaml index cbf6b53a..21c518e0 100644 --- a/locales/pt.yaml +++ b/locales/pt.yaml @@ -201,16 +201,16 @@ order_detail: | seller: vendedora buyer: compradora dispute_started_channel: | - Usuário ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} - iniciou uma disputa com @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} para o pedido + Usuário ${type} @${initiatorUser} TG ID: ${initiatorTgId} + iniciou uma disputa com @${counterPartyUser} TG ID: ${counterPartyUserTgId} para o pedido ${detailedOrder} Seller Token: ${sellerToken} Buyer Token: ${buyerToken} - @${initiatorUser.username} esteve envolvido em ${initiatorUser.disputes} disputas - @${counterPartyUser.username} esteve envolvido em ${counterPartyUser.disputes} disputas + @${initiatorUser} esteve envolvido em ${buyerDisputes} disputas + @${counterPartyUser} esteve envolvido em ${sellerDisputes} disputas you_started: '🥴 Você iniciou uma disputa em seu pedido Id: ${orderId}.' counterpart_started: '🥴 Sua contraparte iniciou uma disputa em seu pedido Id: ${orderId}.' dispute_started: '${who} Um solucionador o atenderá em breve. Quando ele for designado para sua disputa, o bot informará seu nome de usuário e somente ele poderá atendê-lo. Você pode escrever diretamente para ele/ela, mas se ele/ela entrar em contato com você primeiro, você deve pedir a ele/ela que lhe diga qual é o token de sua disputa, seu token é: ${token}.' diff --git a/locales/ru.yaml b/locales/ru.yaml index 34122308..32c5c2d2 100644 --- a/locales/ru.yaml +++ b/locales/ru.yaml @@ -201,16 +201,16 @@ order_detail: | seller: продавец buyer: покупатель dispute_started_channel: | - ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} - инициировал разбирательство с @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} относительно заявки: + ${type} @${initiatorUser} TG ID: ${initiatorTgId} + инициировал разбирательство с @${counterPartyUser} TG ID: ${counterPartyUserTgId} относительно заявки: ${detailedOrder} Seller Token: ${sellerToken} Buyer Token: ${buyerToken} - @${initiatorUser.username} уже имел разбирательств: ${initiatorUser.disputes} - @${counterPartyUser.username} уже имел разбирательств: ${counterPartyUser.disputes} + @${initiatorUser} уже имел разбирательств: ${buyerDisputes} + @${counterPartyUser} уже имел разбирательств: ${sellerDisputes} you_started: '🥴 Вы начали спор по вашему заказу Id: ${orderId}.' counterpart_started: '🥴 Ваш контрагент начал спор по вашему заказу Id: ${orderId}.' dispute_started: '${who} Скоро к вам придет решатель, когда он будет назначен на ваш спор, бот сообщит вам его/ее имя пользователя, только он/она сможет прийти к вам. Вы можете написать ему напрямую, но если он свяжется с вами первым, вы должны попросить его сказать вам, какой токен у вашего спора, ваш токен: ${token}.' diff --git a/locales/uk.yaml b/locales/uk.yaml index 5793167b..60ef8e2c 100644 --- a/locales/uk.yaml +++ b/locales/uk.yaml @@ -201,16 +201,16 @@ order_detail: | seller: продавець buyer: покупець dispute_started_channel: | - ${type} @${initiatorUser.username} TG ID: ${initiatorTgId} - ініціював диспут з @${counterPartyUser.username} TG ID: ${counterPartyUserTgId} щодо заявки: + ${type} @${initiatorUser} TG ID: ${initiatorTgId} + ініціював диспут з @${counterPartyUser} TG ID: ${counterPartyUserTgId} щодо заявки: ${detailedOrder} Seller Token: ${sellerToken} Buyer Token: ${buyerToken} - @${initiatorUser.username} вже мав спір: ${initiatorUser.disputes} - @${counterPartyUser.username} вже мав спір: ${counterPartyUser.disputes} + @${initiatorUser} вже мав спір: ${buyerDdisputes} + @${counterPartyUser} вже мав спір: ${sellerDisputes} you_started: '🥴 Ви почали оскарження свого замовлення з ідентифікатором: ${orderId}.' counterpart_started: '🥴 Ваш контрагент розпочав суперечку щодо вашого замовлення з ідентифікатором: ${orderId}.' dispute_started: "${who} Розв'язувач незабаром прийде до вас, коли його/її буде призначено до вашої суперечки, бот повідомить вам своє ім'я користувача, лише він/вона зможе прийти до вас. Ви можете написати йому/їй безпосередньо, але якщо він/вона зв’яжеться з вами першим, ви повинні попросити його/її сказати вам, що є символом вашої суперечки, ваш маркер: ${token}." diff --git a/package-lock.json b/package-lock.json index fd8c05d8..6458396d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ }, "devDependencies": { "@types/node": "^20.5.0", + "@types/node-schedule": "^2.1.0", "@types/qrcode": "^1.5.2", "chai": "^4.3.4", "chokidar": "^3.5.3", @@ -1770,6 +1771,15 @@ "undici-types": "~6.19.2" } }, + "node_modules/@types/node-schedule": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/node-schedule/-/node-schedule-2.1.0.tgz", + "integrity": "sha512-NiTwl8YN3v/1YCKrDFSmCTkVxFDylueEqsOFdgF+vPsm+AlyJKGAo5yzX1FiOxPsZiN6/r8gJitYx2EaSuBmmg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/qrcode": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.5.tgz", diff --git a/package.json b/package.json index 47a582ed..87471cd2 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "devDependencies": { "@types/node": "^20.5.0", "@types/qrcode": "^1.5.2", + "@types/node-schedule": "^2.1.0", "chai": "^4.3.4", "chokidar": "^3.5.3", "eslint": "^8.15.0", diff --git a/tests/bot/modules/dispute/messages.js b/tests/bot/modules/dispute/messages.js index dd876916..1c0d4ba2 100644 --- a/tests/bot/modules/dispute/messages.js +++ b/tests/bot/modules/dispute/messages.js @@ -16,16 +16,16 @@ const mockI18n = { t: sinon.stub((key, params) => { switch (key) { case 'dispute_started_channel': - return `User ${params.type} @${params.initiatorUser.username} TG ID: ${params.initiatorTgId} - has started a dispute with @${params.counterPartyUser.username} TG ID: ${params.counterPartyUserTgId} for the order + return `User ${params.type} @${params.initiatorUser} TG ID: ${params.initiatorTgId} + has started a dispute with @${params.counterPartyUser} TG ID: ${params.counterPartyUserTgId} for the order ${params.detailedOrder} Seller Token: ${params.sellerToken} Buyer Token: ${params.buyerToken} - @${params.initiatorUser.username} has been involved in ${params.buyerDisputes} disputes - @${params.counterPartyUser.username} has been involved in ${params.sellerDisputes} disputes`; + @${params.initiatorUser} has been involved in ${params.buyerDisputes} disputes + @${params.counterPartyUser} has been involved in ${params.sellerDisputes} disputes`; case 'seller': return 'seller'; case 'buyer': diff --git a/tsconfig.json b/tsconfig.json index f2c464b6..7b8d0663 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,5 +2,7 @@ "compilerOptions": { "strict": true, "esModuleInterop": true, + "resolveJsonModule": true, + "downlevelIteration": true } } diff --git a/util/fiatModel.ts b/util/fiatModel.ts index a722adc0..cc8d22e8 100644 --- a/util/fiatModel.ts +++ b/util/fiatModel.ts @@ -10,3 +10,7 @@ export interface IFiat { price?: boolean; locale?: string; } + +export interface IFiatCurrencies { + [key: string]: IFiat; +} diff --git a/util/index.js b/util/index.ts similarity index 70% rename from util/index.js rename to util/index.ts index 6128d311..902d9e4c 100644 --- a/util/index.js +++ b/util/index.ts @@ -1,20 +1,29 @@ -const axios = require('axios'); +import { I18nContext } from "@grammyjs/i18n"; +import { ICommunity, IOrderChannel } from "../models/community"; +import { IOrder } from "../models/order"; +import { UserDocument } from "../models/user"; +import { IFiatCurrencies, IFiat } from "./fiatModel"; +import { ILanguage, ILanguages } from "./languagesModel"; +import { Telegram } from "telegraf"; +import axios from "axios"; +import fiatJson from './fiat.json'; +import languagesJson from './languages.json'; +import { Order, Community } from "../models"; +import { logger } from "../logger"; const { I18n } = require('@grammyjs/i18n'); -const currencies = require('./fiat.json'); // ISO 639-1 language codes -const languages = require('./languages.json'); -const { Order, Community } = require('../models'); -const { logger } = require('../logger'); -// ISO 4217, all ISO currency codes are 3 letters but users can trade shitcoins +const languages: ILanguages = languagesJson; +const currencies: IFiatCurrencies = fiatJson; -const isIso4217 = code => { +// ISO 4217, all ISO currency codes are 3 letters but users can trade shitcoins +const isIso4217 = (code: string): boolean => { if (code.length < 3 || code.length > 5) { return false; } const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split(''); - code = code.toLowerCase().split(''); - return code.every(letter => { + code = code.toLowerCase() + return code.split('').every(letter => { if (alphabet.indexOf(letter) == -1) { return false; } @@ -22,19 +31,16 @@ const isIso4217 = code => { }); }; -exports.isIso4217 = isIso4217; - -const getCurrency = code => { - if (!isIso4217(code)) return false; +const getCurrency = (code: string): (IFiat | null) => { + if (!isIso4217(code)) return null; const currency = currencies[code]; - if (!currency) return false; + if (!currency) return null; return currency; }; -exports.getCurrency = getCurrency; +const plural = (n: number): string => { -const plural = n => { if (n === 1) { return ''; } @@ -45,8 +51,7 @@ exports.plural = plural; // This function formats a number to locale strings. // If Iso code or locale code doesn´t exist, the function will return a number without format. - -exports.numberFormat = (code, number) => { +const numberFormat = (code: string, number: number) => { if (!isIso4217(code)) return false; if (!currencies[code]) return number; @@ -62,8 +67,7 @@ exports.numberFormat = (code, number) => { // This function checks if the current buyer and seller were doing circular operations // In order to increase their trades_completed and volume_traded. // If we found those trades in the last 24 hours we decrease both variables to both users - -exports.handleReputationItems = async (buyer, seller, amount) => { +const handleReputationItems = async (buyer: UserDocument, seller: UserDocument, amount: number) => { try { const yesterday = new Date(Date.now() - 86400000).toISOString(); const orders = await Order.find({ @@ -74,7 +78,7 @@ exports.handleReputationItems = async (buyer, seller, amount) => { }); if (orders.length > 0) { let totalAmount = 0; - orders.forEach(order => { + orders.forEach((order: IOrder) => { totalAmount += order.amount; }); const lastAmount = orders[orders.length - 1].amount; @@ -128,9 +132,10 @@ exports.handleReputationItems = async (buyer, seller, amount) => { } }; -exports.getBtcFiatPrice = async (fiatCode, fiatAmount) => { +const getBtcFiatPrice = async (fiatCode: string, fiatAmount: number) => { try { const currency = getCurrency(fiatCode); + if (currency === null) throw Error("Currency not found"); if (!currency.price) return; // Before hit the endpoint we make sure the code have only 3 chars const code = currency.code.substring(0, 3); @@ -140,13 +145,13 @@ exports.getBtcFiatPrice = async (fiatCode, fiatAmount) => { } const sats = (fiatAmount / response.data.btc) * 100000000; - return parseInt(sats); + return Number(sats); } catch (error) { logger.error(error); } }; -exports.getBtcExchangePrice = (fiatAmount, satsAmount) => { +const getBtcExchangePrice = (fiatAmount: number, satsAmount: number) => { try { const satsPerBtc = 1e8; const feeRate = (satsPerBtc * fiatAmount) / satsAmount; @@ -157,8 +162,8 @@ exports.getBtcExchangePrice = (fiatAmount, satsAmount) => { } }; -const objectToArray = object => { - const array = []; +const objectToArray = (object: any): any[] => { + const array: any[] = []; for (const i in object) array.push(object[i]); @@ -167,20 +172,20 @@ const objectToArray = object => { exports.objectToArray = objectToArray; -exports.getCurrenciesWithPrice = () => { +const getCurrenciesWithPrice = () => { const currenciesArr = objectToArray(currencies); const withPrice = currenciesArr.filter(currency => currency.price); return withPrice; }; -exports.toKebabCase = string => +const toKebabCase = (string: string) => string .replace(/([a-z])([A-Z])/g, '$1-$2') .replace(/[\s_]+/g, '-') .toLowerCase(); -const getEmojiRate = rate => { +const getEmojiRate = (rate: number) => { const star = '⭐'; const roundedRate = Math.round(rate); const output = []; @@ -189,12 +194,9 @@ const getEmojiRate = rate => { return output.join(''); }; -exports.getEmojiRate = getEmojiRate; - // Round number to exp decimal digits // Source: https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Math/round#redondeo_decimal - -const decimalRound = (value, exp) => { +const decimalRound = (value: number, exp: number): number => { if (typeof exp === 'undefined' || +exp === 0) { return Math.round(value); } @@ -205,32 +207,29 @@ const decimalRound = (value, exp) => { return NaN; } // Shift - value = value.toString().split('e'); - value = Math.round(+(value[0] + 'e' + (value[1] ? +value[1] - exp : -exp))); + let valueArr = value.toString().split('e'); + value = Math.round(+(valueArr[0] + 'e' + (valueArr[1] ? +valueArr[1] - exp : -exp))); // Shift back - value = value.toString().split('e'); - return +(value[0] + 'e' + (value[1] ? +value[1] + exp : exp)); + valueArr = value.toString().split('e'); + return +(valueArr[0] + 'e' + (valueArr[1] ? +valueArr[1] + exp : exp)); }; -exports.decimalRound = decimalRound; - -exports.extractId = text => { +const extractId = (text: string): (string | null) => { const matches = text.match(/:([a-f0-9]{24}):$/); - - return matches[1]; + if (matches !== null){ + return matches?.[1]; + } + return null; }; // Clean strings that are going to be rendered with markdown - -const sanitizeMD = text => { +const sanitizeMD = (text: any) => { if (!text) return ''; - return text.toString().replace(/(?=[|<>(){}[\]\-_!#.`=+])/g, '\\'); + return String(text).replace(/(?=[|<>(){}[\]\-_!#.`=+])/g, '\\'); }; -exports.sanitizeMD = sanitizeMD; - -exports.secondsToTime = secs => { +const secondsToTime = (secs: number) => { const hours = Math.floor(secs / (60 * 60)); const divisor = secs % (60 * 60); @@ -242,9 +241,9 @@ exports.secondsToTime = secs => { }; }; -exports.isGroupAdmin = async (groupId, user, telegram) => { +const isGroupAdmin = async (groupId: string, user: UserDocument, telegram: Telegram) => { try { - const member = await telegram.getChatMember(groupId, user.tg_id); + const member = await telegram.getChatMember(groupId, Number(user.tg_id)); if ( member && (member.status === 'creator' || member.status === 'administrator') @@ -268,12 +267,12 @@ exports.isGroupAdmin = async (groupId, user, telegram) => { logger.error(error); return { success: false, - message: error.toString(), + message: String(error), }; } }; -exports.deleteOrderFromChannel = async (order, telegram) => { +const deleteOrderFromChannel = async (order: IOrder, telegram: Telegram) => { try { let channel = process.env.CHANNEL; if (order.community_id) { @@ -291,13 +290,13 @@ exports.deleteOrderFromChannel = async (order, telegram) => { } } } - await telegram.deleteMessage(channel, order.tg_channel_message1); + await telegram.deleteMessage(channel!, Number(order.tg_channel_message1!)); } catch (error) { logger.error(error); } }; -exports.getOrderChannel = async order => { +const getOrderChannel = async (order: IOrder) => { let channel = process.env.CHANNEL; if (order.community_id) { const community = await Community.findOne({ _id: order.community_id }); @@ -307,7 +306,7 @@ exports.getOrderChannel = async order => { if (community.order_channels.length === 1) { channel = community.order_channels[0].name; } else { - community.order_channels.forEach(async c => { + community.order_channels.forEach(async (c: IOrderChannel) => { if (c.type === order.type) { channel = c.name; } @@ -318,10 +317,11 @@ exports.getOrderChannel = async order => { return channel; }; -exports.getDisputeChannel = async order => { +const getDisputeChannel = async (order: IOrder) => { let channel = process.env.DISPUTE_CHANNEL; if (order.community_id) { const community = await Community.findOne({ _id: order.community_id }); + if (community === null) throw Error("Community was not found in DB"); channel = community.dispute_channel; } @@ -333,8 +333,13 @@ exports.getDisputeChannel = async order => { * @param {*} user * @returns i18n context */ -exports.getUserI18nContext = async user => { - const language = user.language || 'en'; +const getUserI18nContext = async (user: UserDocument) => { + let language = null; + if (!('language' in user)) { + language = 'en'; + } else { + language = user.language; + } const i18n = new I18n({ locale: language, defaultLanguageOnMissing: true, @@ -344,7 +349,7 @@ exports.getUserI18nContext = async user => { return i18n.createContext(user.lang); }; -exports.getDetailedOrder = (i18n, order, buyer, seller) => { +const getDetailedOrder = (i18n: I18nContext, order: IOrder, buyer: UserDocument, seller: UserDocument) => { try { const buyerUsername = buyer ? sanitizeMD(buyer.username) : ''; const buyerReputation = buyer @@ -363,7 +368,7 @@ exports.getDetailedOrder = (i18n, order, buyer, seller) => { takenAt = sanitizeMD(takenAt); const previousDisputeStatus = sanitizeMD(order.previous_dispute_status); const status = sanitizeMD(order.status); - const fee = order.fee ? parseInt(order.fee) : ''; + const fee = order.fee ? sanitizeMD(Number(order.fee)) : ''; const creator = order.creator_id === buyerId ? buyerUsername : sellerUsername; const buyerAge = buyer? getUserAge(buyer) : ''; @@ -397,7 +402,7 @@ exports.getDetailedOrder = (i18n, order, buyer, seller) => { }; // We need to know if this user is a dispute solver for this community -exports.isDisputeSolver = (community, user) => { +const isDisputeSolver = (community: ICommunity | null, user: UserDocument) => { if (!community || !user) { return false; } @@ -407,49 +412,45 @@ exports.isDisputeSolver = (community, user) => { // Return the fee the bot will charge to the seller // this fee is a combination from the global bot fee and the community fee -exports.getFee = async (amount, communityId) => { - const maxFee = Math.round(amount * parseFloat(process.env.MAX_FEE)); +const getFee = async (amount: number, communityId: string) => { + const maxFee = Math.round(amount * Number(process.env.MAX_FEE)); if (!communityId) return maxFee; - const botFee = maxFee * parseFloat(process.env.FEE_PERCENT); + const botFee = maxFee * Number(process.env.FEE_PERCENT); let communityFee = Math.round(maxFee - botFee); const community = await Community.findOne({ _id: communityId }); + if (community === null) throw Error("Community was not found in DB"); communityFee = communityFee * (community.fee / 100); return botFee + communityFee; }; -exports.itemsFromMessage = str => { +const itemsFromMessage = (str: string) => { return str .split(' ') .map(e => e.trim()) .filter(e => !!e); }; -// Check if a number is int -const isInt = n => parseInt(n) === n; - -exports.isInt = isInt; - // Check if a number is float -exports.isFloat = n => typeof n === 'number' && !isInt(n); +const isFloat = (n: number) => typeof n === 'number' && !Number.isInteger(n); // Returns an emoji flag for a language -exports.getLanguageFlag = code => { +const getLanguageFlag = (code: string): ILanguage => { return languages[code]; }; -exports.delay = time => { +const delay = (time: number) => { return new Promise(resolve => setTimeout(resolve, time)); }; // Returns the hold invoice expiration time in seconds, // and the hold invoice safety window in seconds -exports.holdInvoiceExpirationInSecs = () => { +const holdInvoiceExpirationInSecs = () => { const expirationTimeInSecs = - parseInt(process.env.HOLD_INVOICE_CLTV_DELTA) * 10 * 60; + Number(process.env.HOLD_INVOICE_CLTV_DELTA) * 10 * 60; const safetyWindowInSecs = - parseInt(process.env.HOLD_INVOICE_CLTV_DELTA_SAFETY_WINDOW) * 10 * 60; + Number(process.env.HOLD_INVOICE_CLTV_DELTA_SAFETY_WINDOW) * 10 * 60; return { expirationTimeInSecs, safetyWindowInSecs, @@ -457,7 +458,7 @@ exports.holdInvoiceExpirationInSecs = () => { }; // Returns the user age in days -const getUserAge = user => { +const getUserAge = (user: UserDocument) => { const userCreationDate = new Date(user.created_at); const today = new Date(); const ageInDays = Math.floor( @@ -466,21 +467,19 @@ const getUserAge = user => { return ageInDays; }; -exports.getUserAge = getUserAge; - /** * Returns order expiration time text * @param {*} order order object * @param {*} i18n context * @returns String with the remaining time to expiration in format '1 hours 30 minutes' */ -exports.getTimeToExpirationOrder = (order, i18n) => { +const getTimeToExpirationOrder = (order: IOrder, i18n: I18nContext) => { const initialDateObj = new Date(order.created_at); - const timeToExpire = parseInt(process.env.ORDER_PUBLISHED_EXPIRATION_WINDOW); + const timeToExpire = Number(process.env.ORDER_PUBLISHED_EXPIRATION_WINDOW); initialDateObj.setSeconds(initialDateObj.getSeconds() + timeToExpire); const currentDateObj = new Date(); - const timeDifferenceMs = initialDateObj - currentDateObj; + const timeDifferenceMs = initialDateObj.valueOf() - currentDateObj.valueOf(); const totalSecondsRemaining = Math.floor(timeDifferenceMs / 1000); const textHour = i18n.t('hours'); const textMin = i18n.t('minutes'); @@ -494,18 +493,18 @@ exports.getTimeToExpirationOrder = (order, i18n) => { return `${hours} ${textHour} ${minutes} ${textMin}`; }; -exports.getStars = (rate, totalReviews) => { +export const getStars = (rate: number, totalReviews: number) => { const stars = getEmojiRate(rate); const roundedRating = decimalRound(rate, -1); return `${roundedRating} ${stars} (${totalReviews})`; }; -exports.removeAtSymbol = text => { +export const removeAtSymbol = (text: string) => { return text[0] === '@' ? text.slice(1) : text; -}; +} -exports.removeLightningPrefix = invoice => { +export const removeLightningPrefix = (invoice: string) => { const prefix = 'lightning:'; // Check if the invoice starts with the prefix @@ -516,3 +515,35 @@ exports.removeLightningPrefix = invoice => { // Return the invoice as is if no prefix is found return invoice; }; + +export { + isIso4217, + plural, + getCurrency, + handleReputationItems, + getBtcFiatPrice, + getBtcExchangePrice, + getCurrenciesWithPrice, + getEmojiRate, + decimalRound, + extractId, + sanitizeMD, + secondsToTime, + isGroupAdmin, + deleteOrderFromChannel, + getOrderChannel, + getUserI18nContext, + numberFormat, + getDisputeChannel, + getDetailedOrder, + isDisputeSolver, + getFee, + itemsFromMessage, + isFloat, + getLanguageFlag, + delay, + holdInvoiceExpirationInSecs, + getUserAge, + getTimeToExpirationOrder, + toKebabCase +}; diff --git a/util/languagesModel.ts b/util/languagesModel.ts new file mode 100644 index 00000000..fa159815 --- /dev/null +++ b/util/languagesModel.ts @@ -0,0 +1,9 @@ +export interface ILanguage { + name: string; + emoji: string; + code: string; +} + +export interface ILanguages { + [key: string]: ILanguage; +} From 3332ac3b52e1d55a18ddc6bc0fd02820e931fc9e Mon Sep 17 00:00:00 2001 From: Catrya <140891948+Catrya@users.noreply.github.com> Date: Fri, 11 Oct 2024 14:49:04 -0400 Subject: [PATCH 6/9] fix solver username (#597) --- bot/modules/dispute/messages.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot/modules/dispute/messages.js b/bot/modules/dispute/messages.js index d8bc775f..dbc7754c 100644 --- a/bot/modules/dispute/messages.js +++ b/bot/modules/dispute/messages.js @@ -119,14 +119,14 @@ exports.disputeData = async ( await ctx.telegram.sendMessage( buyer.tg_id, ctx.i18n.t('dispute_solver', { - solver: sanitizeMD(solver.username), + solver: solver.username, token: order.buyer_dispute_token, }) ); await ctx.telegram.sendMessage( seller.tg_id, ctx.i18n.t('dispute_solver', { - solver: sanitizeMD(solver.username), + solver: solver.username, token: order.seller_dispute_token, }) ); From c02f05113d5ce1b252dc4c1f19d04a601fec9620 Mon Sep 17 00:00:00 2001 From: Daniel Candia Flores Date: Fri, 18 Oct 2024 14:37:02 -0400 Subject: [PATCH 7/9] Issue 579 fix unit testing (#593) * Add tests for bot/validations.js * Remove only * Update bot tests and lightning tests * Update describe name * Update files to pass the linter check * Adde stubs for dependencies and added some new tests * Fix lint issues --------- Co-authored-by: Daniel Candia Flores --- bot/validations.ts | 20 +- package-lock.json | 1050 ++++++++-------- package.json | 2 +- tests/bot/bot.spec.js | 593 +++++++++ tests/bot/mocks/currenciesResponse.js | 117 ++ tests/bot/mocks/languagesResponse.js | 33 + tests/bot/validation.spec.js | 1114 +++++++++++++++++ tests/bot_test.js | 145 --- .../lightning.spec.js} | 12 +- tests/{ => ln/mocks}/lightningResponse.js | 4 +- tests/order.js | 28 - tests/user.js | 16 - util/index.ts | 12 +- 13 files changed, 2398 insertions(+), 748 deletions(-) create mode 100644 tests/bot/bot.spec.js create mode 100644 tests/bot/mocks/currenciesResponse.js create mode 100644 tests/bot/mocks/languagesResponse.js create mode 100644 tests/bot/validation.spec.js delete mode 100644 tests/bot_test.js rename tests/{lightning_test.js => ln/lightning.spec.js} (58%) rename tests/{ => ln/mocks}/lightningResponse.js (87%) delete mode 100644 tests/order.js delete mode 100644 tests/user.js diff --git a/bot/validations.ts b/bot/validations.ts index 2af82307..1fedbbea 100644 --- a/bot/validations.ts +++ b/bot/validations.ts @@ -1,5 +1,5 @@ import { MainContext, OrderQuery, ctxUpdateAssertMsg } from "./start"; -import { ICommunity } from "../models/community"; +import { ICommunity, IUsernameId } from "../models/community"; import { FilterQuery } from "mongoose"; import { UserDocument } from "../models/user"; import { IOrder } from "../models/order"; @@ -9,7 +9,7 @@ const { parsePaymentRequest } = require('invoices'); const { ObjectId } = require('mongoose').Types; import * as messages from './messages'; import { Order, User, Community } from '../models'; -import { isIso4217, isDisputeSolver, removeLightningPrefix } from '../util'; +import { isIso4217, isDisputeSolver, removeLightningPrefix, isOrderCreator } from '../util'; const { existLightningAddress } = require('../lnurl/lnurl-pay'); import { logger } from '../logger'; @@ -106,6 +106,7 @@ const validateAdmin = async (ctx: MainContext, id?: string) => { const isSolver = isDisputeSolver(community, user); + // TODO this validation does not return anything if (!user.admin && !isSolver) return await messages.notAuthorized(ctx, tgUserId); @@ -192,7 +193,8 @@ const validateSellOrder = async (ctx: MainContext) => { await messages.mustBeANumberOrRange(ctx); return false; } - + + // TODO, this validation could be amount > 0? if (amount !== 0 && amount < Number(process.env.MIN_PAYMENT_AMT)) { await messages.mustBeGreatherEqThan( ctx, @@ -338,7 +340,7 @@ const validateInvoice = async (ctx: MainContext, lnInvoice: string) => { const latestDate = new Date( Date.now() + Number(process.env.INVOICE_EXPIRATION_WINDOW) ); - if (!("MAIN_PAYMENT_AMT" in process.env)) throw Error("MIN_PAYMENT_AMT not found, please check .env file"); + if (!("MIN_PAYMENT_AMT" in process.env)) throw Error("MIN_PAYMENT_AMT not found, please check .env file"); if (!!invoice.tokens && invoice.tokens < Number(process.env.MIN_PAYMENT_AMT)) { await messages.minimunAmountInvoiceMessage(ctx); return false; @@ -429,14 +431,6 @@ const isValidInvoice = async (ctx: MainContext, lnInvoice: string) => { } }; -const isOrderCreator = (user: UserDocument, order: IOrder) => { - try { - return user._id == order.creator_id; - } catch (error) { - logger.error(error); - return false; - } -}; const validateTakeSellOrder = async (ctx: MainContext, bot: Telegraf, user: UserDocument, order: IOrder) => { try { @@ -688,7 +682,7 @@ const isBannedFromCommunity = async (user: UserDocument, communityId: string) => if (!communityId) return false; const community = await Community.findOne({ _id: communityId }); if (!community) return false; - return community.banned_users.toObject().some((buser: ICommunity) => buser.id == user._id); + return community.banned_users.some((buser: IUsernameId) => buser.id == user._id); } catch (error) { logger.error(error); return false; diff --git a/package-lock.json b/package-lock.json index 6458396d..9dac649e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -173,50 +173,50 @@ } }, "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.637.0.tgz", - "integrity": "sha512-391mca6yEfXVcSOTLGcxzlT0QCFfvoymLlVHfb//bzl806UUTq12cR2k+AnaCKLj+QSejmA7n6lwZWADm00Fvg==", + "version": "3.658.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.658.1.tgz", + "integrity": "sha512-MCYLKmNy0FlNT9TvXfOxj0jh+ZQq+G9qEy/VZqu3JsQSgiFvFRdzgzcbQ9gQx7fZrDC/TPdABOTh483zI4cu9g==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.637.0", - "@aws-sdk/client-sts": "3.637.0", - "@aws-sdk/core": "3.635.0", - "@aws-sdk/credential-provider-node": "3.637.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.637.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.637.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.4.0", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.15", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", + "@aws-sdk/client-sso-oidc": "3.658.1", + "@aws-sdk/client-sts": "3.658.1", + "@aws-sdk/core": "3.658.1", + "@aws-sdk/credential-provider-node": "3.658.1", + "@aws-sdk/middleware-host-header": "3.654.0", + "@aws-sdk/middleware-logger": "3.654.0", + "@aws-sdk/middleware-recursion-detection": "3.654.0", + "@aws-sdk/middleware-user-agent": "3.654.0", + "@aws-sdk/region-config-resolver": "3.654.0", + "@aws-sdk/types": "3.654.0", + "@aws-sdk/util-endpoints": "3.654.0", + "@aws-sdk/util-user-agent-browser": "3.654.0", + "@aws-sdk/util-user-agent-node": "3.654.0", + "@smithy/config-resolver": "^3.0.8", + "@smithy/core": "^2.4.6", + "@smithy/fetch-http-handler": "^3.2.8", + "@smithy/hash-node": "^3.0.6", + "@smithy/invalid-dependency": "^3.0.6", + "@smithy/middleware-content-length": "^3.0.8", + "@smithy/middleware-endpoint": "^3.1.3", + "@smithy/middleware-retry": "^3.0.21", + "@smithy/middleware-serde": "^3.0.6", + "@smithy/middleware-stack": "^3.0.6", + "@smithy/node-config-provider": "^3.1.7", + "@smithy/node-http-handler": "^3.2.3", + "@smithy/protocol-http": "^4.1.3", + "@smithy/smithy-client": "^3.3.5", + "@smithy/types": "^3.4.2", + "@smithy/url-parser": "^3.0.6", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.15", - "@smithy/util-defaults-mode-node": "^3.0.15", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", + "@smithy/util-defaults-mode-browser": "^3.0.21", + "@smithy/util-defaults-mode-node": "^3.0.21", + "@smithy/util-endpoints": "^2.1.2", + "@smithy/util-middleware": "^3.0.6", + "@smithy/util-retry": "^3.0.6", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -225,47 +225,47 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.637.0.tgz", - "integrity": "sha512-+KjLvgX5yJYROWo3TQuwBJlHCY0zz9PsLuEolmXQn0BVK1L/m9GteZHtd+rEdAoDGBpE0Xqjy1oz5+SmtsaRUw==", + "version": "3.658.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.658.1.tgz", + "integrity": "sha512-lOuaBtqPTYGn6xpXlQF4LsNDsQ8Ij2kOdnk+i69Kp6yS76TYvtUuukyLL5kx8zE1c8WbYtxj9y8VNw9/6uKl7Q==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.635.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.637.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.637.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.4.0", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.15", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", + "@aws-sdk/core": "3.658.1", + "@aws-sdk/middleware-host-header": "3.654.0", + "@aws-sdk/middleware-logger": "3.654.0", + "@aws-sdk/middleware-recursion-detection": "3.654.0", + "@aws-sdk/middleware-user-agent": "3.654.0", + "@aws-sdk/region-config-resolver": "3.654.0", + "@aws-sdk/types": "3.654.0", + "@aws-sdk/util-endpoints": "3.654.0", + "@aws-sdk/util-user-agent-browser": "3.654.0", + "@aws-sdk/util-user-agent-node": "3.654.0", + "@smithy/config-resolver": "^3.0.8", + "@smithy/core": "^2.4.6", + "@smithy/fetch-http-handler": "^3.2.8", + "@smithy/hash-node": "^3.0.6", + "@smithy/invalid-dependency": "^3.0.6", + "@smithy/middleware-content-length": "^3.0.8", + "@smithy/middleware-endpoint": "^3.1.3", + "@smithy/middleware-retry": "^3.0.21", + "@smithy/middleware-serde": "^3.0.6", + "@smithy/middleware-stack": "^3.0.6", + "@smithy/node-config-provider": "^3.1.7", + "@smithy/node-http-handler": "^3.2.3", + "@smithy/protocol-http": "^4.1.3", + "@smithy/smithy-client": "^3.3.5", + "@smithy/types": "^3.4.2", + "@smithy/url-parser": "^3.0.6", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.15", - "@smithy/util-defaults-mode-node": "^3.0.15", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", + "@smithy/util-defaults-mode-browser": "^3.0.21", + "@smithy/util-defaults-mode-node": "^3.0.21", + "@smithy/util-endpoints": "^2.1.2", + "@smithy/util-middleware": "^3.0.6", + "@smithy/util-retry": "^3.0.6", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -274,48 +274,48 @@ } }, "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.637.0.tgz", - "integrity": "sha512-27bHALN6Qb6m6KZmPvRieJ/QRlj1lyac/GT2Rn5kJpre8Mpp+yxrtvp3h9PjNBty4lCeFEENfY4dGNSozBuBcw==", + "version": "3.658.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.658.1.tgz", + "integrity": "sha512-RGcZAI3qEA05JszPKwa0cAyp8rnS1nUvs0Sqw4hqLNQ1kD7b7V6CPjRXe7EFQqCOMvM4kGqx0+cEEVTOmBsFLw==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.635.0", - "@aws-sdk/credential-provider-node": "3.637.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.637.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.637.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.4.0", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.15", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", + "@aws-sdk/core": "3.658.1", + "@aws-sdk/credential-provider-node": "3.658.1", + "@aws-sdk/middleware-host-header": "3.654.0", + "@aws-sdk/middleware-logger": "3.654.0", + "@aws-sdk/middleware-recursion-detection": "3.654.0", + "@aws-sdk/middleware-user-agent": "3.654.0", + "@aws-sdk/region-config-resolver": "3.654.0", + "@aws-sdk/types": "3.654.0", + "@aws-sdk/util-endpoints": "3.654.0", + "@aws-sdk/util-user-agent-browser": "3.654.0", + "@aws-sdk/util-user-agent-node": "3.654.0", + "@smithy/config-resolver": "^3.0.8", + "@smithy/core": "^2.4.6", + "@smithy/fetch-http-handler": "^3.2.8", + "@smithy/hash-node": "^3.0.6", + "@smithy/invalid-dependency": "^3.0.6", + "@smithy/middleware-content-length": "^3.0.8", + "@smithy/middleware-endpoint": "^3.1.3", + "@smithy/middleware-retry": "^3.0.21", + "@smithy/middleware-serde": "^3.0.6", + "@smithy/middleware-stack": "^3.0.6", + "@smithy/node-config-provider": "^3.1.7", + "@smithy/node-http-handler": "^3.2.3", + "@smithy/protocol-http": "^4.1.3", + "@smithy/smithy-client": "^3.3.5", + "@smithy/types": "^3.4.2", + "@smithy/url-parser": "^3.0.6", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.15", - "@smithy/util-defaults-mode-node": "^3.0.15", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", + "@smithy/util-defaults-mode-browser": "^3.0.21", + "@smithy/util-defaults-mode-node": "^3.0.21", + "@smithy/util-endpoints": "^2.1.2", + "@smithy/util-middleware": "^3.0.6", + "@smithy/util-retry": "^3.0.6", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -323,53 +323,53 @@ "node": ">=16.0.0" }, "peerDependencies": { - "@aws-sdk/client-sts": "^3.637.0" + "@aws-sdk/client-sts": "^3.658.1" } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.637.0.tgz", - "integrity": "sha512-xUi7x4qDubtA8QREtlblPuAcn91GS/09YVEY/RwU7xCY0aqGuFwgszAANlha4OUIqva8oVj2WO4gJuG+iaSnhw==", + "version": "3.658.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.658.1.tgz", + "integrity": "sha512-yw9hc5blTnbT1V6mR7Cx9HGc9KQpcLQ1QXj8rntiJi6tIYu3aFNVEyy81JHL7NsuBSeQulJTvHO3y6r3O0sfRg==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.637.0", - "@aws-sdk/core": "3.635.0", - "@aws-sdk/credential-provider-node": "3.637.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.637.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.637.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.4.0", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.15", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", + "@aws-sdk/client-sso-oidc": "3.658.1", + "@aws-sdk/core": "3.658.1", + "@aws-sdk/credential-provider-node": "3.658.1", + "@aws-sdk/middleware-host-header": "3.654.0", + "@aws-sdk/middleware-logger": "3.654.0", + "@aws-sdk/middleware-recursion-detection": "3.654.0", + "@aws-sdk/middleware-user-agent": "3.654.0", + "@aws-sdk/region-config-resolver": "3.654.0", + "@aws-sdk/types": "3.654.0", + "@aws-sdk/util-endpoints": "3.654.0", + "@aws-sdk/util-user-agent-browser": "3.654.0", + "@aws-sdk/util-user-agent-node": "3.654.0", + "@smithy/config-resolver": "^3.0.8", + "@smithy/core": "^2.4.6", + "@smithy/fetch-http-handler": "^3.2.8", + "@smithy/hash-node": "^3.0.6", + "@smithy/invalid-dependency": "^3.0.6", + "@smithy/middleware-content-length": "^3.0.8", + "@smithy/middleware-endpoint": "^3.1.3", + "@smithy/middleware-retry": "^3.0.21", + "@smithy/middleware-serde": "^3.0.6", + "@smithy/middleware-stack": "^3.0.6", + "@smithy/node-config-provider": "^3.1.7", + "@smithy/node-http-handler": "^3.2.3", + "@smithy/protocol-http": "^4.1.3", + "@smithy/smithy-client": "^3.3.5", + "@smithy/types": "^3.4.2", + "@smithy/url-parser": "^3.0.6", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.15", - "@smithy/util-defaults-mode-node": "^3.0.15", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", + "@smithy/util-defaults-mode-browser": "^3.0.21", + "@smithy/util-defaults-mode-node": "^3.0.21", + "@smithy/util-endpoints": "^2.1.2", + "@smithy/util-middleware": "^3.0.6", + "@smithy/util-retry": "^3.0.6", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -378,19 +378,19 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.635.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.635.0.tgz", - "integrity": "sha512-i1x/E/sgA+liUE1XJ7rj1dhyXpAKO1UKFUcTTHXok2ARjWTvszHnSXMOsB77aPbmn0fUp1JTx2kHUAZ1LVt5Bg==", + "version": "3.658.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.658.1.tgz", + "integrity": "sha512-vJVMoMcSKXK2gBRSu9Ywwv6wQ7tXH8VL1fqB1uVxgCqBZ3IHfqNn4zvpMPWrwgO2/3wv7XFyikGQ5ypPTCw4jA==", "optional": true, "dependencies": { - "@smithy/core": "^2.4.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/property-provider": "^3.1.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/signature-v4": "^4.1.0", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "@smithy/util-middleware": "^3.0.3", + "@smithy/core": "^2.4.6", + "@smithy/node-config-provider": "^3.1.7", + "@smithy/property-provider": "^3.1.6", + "@smithy/protocol-http": "^4.1.3", + "@smithy/signature-v4": "^4.1.4", + "@smithy/smithy-client": "^3.3.5", + "@smithy/types": "^3.4.2", + "@smithy/util-middleware": "^3.0.6", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" }, @@ -399,15 +399,15 @@ } }, "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.637.0.tgz", - "integrity": "sha512-9qK1mF+EThtv3tsL1C/wb9MpWctJSkzjrLTFj+0Rtk8VYm6DlGepo/I6a2x3SeDmdBfHAFSrKFU39GqWDp1mwQ==", + "version": "3.658.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.658.1.tgz", + "integrity": "sha512-JY4rZ4e2emL7PNHCU7F/BQV8PpQGEBZLkEoPD55RO4CitaIhlVZRpUCGLih+0Hw4MOnTUqJdfQBM+qZk6G+Now==", "optional": true, "dependencies": { - "@aws-sdk/client-cognito-identity": "3.637.0", - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", + "@aws-sdk/client-cognito-identity": "3.658.1", + "@aws-sdk/types": "3.654.0", + "@smithy/property-provider": "^3.1.6", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -415,14 +415,14 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.620.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.620.1.tgz", - "integrity": "sha512-ExuILJ2qLW5ZO+rgkNRj0xiAipKT16Rk77buvPP8csR7kkCflT/gXTyzRe/uzIiETTxM7tr8xuO9MP/DQXqkfg==", + "version": "3.654.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.654.0.tgz", + "integrity": "sha512-kogsx3Ql81JouHS7DkheCDU9MYAvK0AokxjcshDveGmf7BbgbWCA8Fnb9wjQyNDaOXNvkZu8Z8rgkX91z324/w==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", + "@aws-sdk/types": "3.654.0", + "@smithy/property-provider": "^3.1.6", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -430,19 +430,19 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.635.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.635.0.tgz", - "integrity": "sha512-iJyRgEjOCQlBMXqtwPLIKYc7Bsc6nqjrZybdMDenPDa+kmLg7xh8LxHsu9088e+2/wtLicE34FsJJIfzu3L82g==", + "version": "3.658.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.658.1.tgz", + "integrity": "sha512-4ubkJjEVCZflxkZnV1JDQv8P2pburxk1LrEp55telfJRzXrnowzBKwuV2ED0QMNC448g2B3VCaffS+Ct7c4IWQ==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/property-provider": "^3.1.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", + "@aws-sdk/types": "3.654.0", + "@smithy/fetch-http-handler": "^3.2.8", + "@smithy/node-http-handler": "^3.2.3", + "@smithy/property-provider": "^3.1.6", + "@smithy/protocol-http": "^4.1.3", + "@smithy/smithy-client": "^3.3.5", + "@smithy/types": "^3.4.2", + "@smithy/util-stream": "^3.1.8", "tslib": "^2.6.2" }, "engines": { @@ -450,47 +450,47 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.637.0.tgz", - "integrity": "sha512-h+PFCWfZ0Q3Dx84SppET/TFpcQHmxFW8/oV9ArEvMilw4EBN+IlxgbL0CnHwjHW64szcmrM0mbebjEfHf4FXmw==", + "version": "3.658.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.658.1.tgz", + "integrity": "sha512-2uwOamQg5ppwfegwen1ddPu5HM3/IBSnaGlaKLFhltkdtZ0jiqTZWUtX2V+4Q+buLnT0hQvLS/frQ+7QUam+0Q==", "optional": true, "dependencies": { - "@aws-sdk/credential-provider-env": "3.620.1", - "@aws-sdk/credential-provider-http": "3.635.0", - "@aws-sdk/credential-provider-process": "3.620.1", - "@aws-sdk/credential-provider-sso": "3.637.0", - "@aws-sdk/credential-provider-web-identity": "3.621.0", - "@aws-sdk/types": "3.609.0", - "@smithy/credential-provider-imds": "^3.2.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", + "@aws-sdk/credential-provider-env": "3.654.0", + "@aws-sdk/credential-provider-http": "3.658.1", + "@aws-sdk/credential-provider-process": "3.654.0", + "@aws-sdk/credential-provider-sso": "3.658.1", + "@aws-sdk/credential-provider-web-identity": "3.654.0", + "@aws-sdk/types": "3.654.0", + "@smithy/credential-provider-imds": "^3.2.3", + "@smithy/property-provider": "^3.1.6", + "@smithy/shared-ini-file-loader": "^3.1.7", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { - "@aws-sdk/client-sts": "^3.637.0" + "@aws-sdk/client-sts": "^3.658.1" } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.637.0.tgz", - "integrity": "sha512-yoEhoxJJfs7sPVQ6Is939BDQJZpZCoUgKr/ySse4YKOZ24t4VqgHA6+wV7rYh+7IW24Rd91UTvEzSuHYTlxlNA==", + "version": "3.658.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.658.1.tgz", + "integrity": "sha512-XwxW6N+uPXPYAuyq+GfOEdfL/MZGAlCSfB5gEWtLBFmFbikhmEuqfWtI6CD60OwudCUOh6argd21BsJf8o1SJA==", "optional": true, "dependencies": { - "@aws-sdk/credential-provider-env": "3.620.1", - "@aws-sdk/credential-provider-http": "3.635.0", - "@aws-sdk/credential-provider-ini": "3.637.0", - "@aws-sdk/credential-provider-process": "3.620.1", - "@aws-sdk/credential-provider-sso": "3.637.0", - "@aws-sdk/credential-provider-web-identity": "3.621.0", - "@aws-sdk/types": "3.609.0", - "@smithy/credential-provider-imds": "^3.2.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", + "@aws-sdk/credential-provider-env": "3.654.0", + "@aws-sdk/credential-provider-http": "3.658.1", + "@aws-sdk/credential-provider-ini": "3.658.1", + "@aws-sdk/credential-provider-process": "3.654.0", + "@aws-sdk/credential-provider-sso": "3.658.1", + "@aws-sdk/credential-provider-web-identity": "3.654.0", + "@aws-sdk/types": "3.654.0", + "@smithy/credential-provider-imds": "^3.2.3", + "@smithy/property-provider": "^3.1.6", + "@smithy/shared-ini-file-loader": "^3.1.7", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -498,15 +498,15 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.620.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.620.1.tgz", - "integrity": "sha512-hWqFMidqLAkaV9G460+1at6qa9vySbjQKKc04p59OT7lZ5cO5VH5S4aI05e+m4j364MBROjjk2ugNvfNf/8ILg==", + "version": "3.654.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.654.0.tgz", + "integrity": "sha512-PmQoo8sZ9Q2Ow8OMzK++Z9lI7MsRUG7sNq3E72DVA215dhtTICTDQwGlXH2AAmIp7n+G9LLRds+4wo2ehG4mkg==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", + "@aws-sdk/types": "3.654.0", + "@smithy/property-provider": "^3.1.6", + "@smithy/shared-ini-file-loader": "^3.1.7", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -514,17 +514,17 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.637.0.tgz", - "integrity": "sha512-Mvz+h+e62/tl+dVikLafhv+qkZJ9RUb8l2YN/LeKMWkxQylPT83CPk9aimVhCV89zth1zpREArl97+3xsfgQvA==", + "version": "3.658.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.658.1.tgz", + "integrity": "sha512-YOagVEsZEk9DmgJEBg+4MBXrPcw/tYas0VQ5OVBqC5XHNbi2OBGJqgmjVPesuu393E7W0VQxtJFDS00O1ewQgA==", "optional": true, "dependencies": { - "@aws-sdk/client-sso": "3.637.0", - "@aws-sdk/token-providers": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", + "@aws-sdk/client-sso": "3.658.1", + "@aws-sdk/token-providers": "3.654.0", + "@aws-sdk/types": "3.654.0", + "@smithy/property-provider": "^3.1.6", + "@smithy/shared-ini-file-loader": "^3.1.7", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -532,44 +532,44 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.621.0.tgz", - "integrity": "sha512-w7ASSyfNvcx7+bYGep3VBgC3K6vEdLmlpjT7nSIHxxQf+WSdvy+HynwJosrpZax0sK5q0D1Jpn/5q+r5lwwW6w==", + "version": "3.654.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.654.0.tgz", + "integrity": "sha512-6a2g9gMtZToqSu+CusjNK5zvbLJahQ9di7buO3iXgbizXpLXU1rnawCpWxwslMpT5fLgMSKDnKDrr6wdEk7jSw==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", + "@aws-sdk/types": "3.654.0", + "@smithy/property-provider": "^3.1.6", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { - "@aws-sdk/client-sts": "^3.621.0" + "@aws-sdk/client-sts": "^3.654.0" } }, "node_modules/@aws-sdk/credential-providers": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.637.0.tgz", - "integrity": "sha512-yW1scL3Z7JsrTrmhjyZsB6tsMJ49UCO42BGlNWZAW+kN1vNJ+qbv6XYQJWR4gjpuD2rdmtGcEawcgllE2Bmigw==", + "version": "3.658.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.658.1.tgz", + "integrity": "sha512-lfXA6kZS6GHyi/67EbfrKdLoqHR6j7G35eFwaqxyNkfMhNBpAF0eZK3SYiwnzdR9+Wb/enTFawYiFbG5R+dQzA==", "optional": true, "dependencies": { - "@aws-sdk/client-cognito-identity": "3.637.0", - "@aws-sdk/client-sso": "3.637.0", - "@aws-sdk/client-sts": "3.637.0", - "@aws-sdk/credential-provider-cognito-identity": "3.637.0", - "@aws-sdk/credential-provider-env": "3.620.1", - "@aws-sdk/credential-provider-http": "3.635.0", - "@aws-sdk/credential-provider-ini": "3.637.0", - "@aws-sdk/credential-provider-node": "3.637.0", - "@aws-sdk/credential-provider-process": "3.620.1", - "@aws-sdk/credential-provider-sso": "3.637.0", - "@aws-sdk/credential-provider-web-identity": "3.621.0", - "@aws-sdk/types": "3.609.0", - "@smithy/credential-provider-imds": "^3.2.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", + "@aws-sdk/client-cognito-identity": "3.658.1", + "@aws-sdk/client-sso": "3.658.1", + "@aws-sdk/client-sts": "3.658.1", + "@aws-sdk/credential-provider-cognito-identity": "3.658.1", + "@aws-sdk/credential-provider-env": "3.654.0", + "@aws-sdk/credential-provider-http": "3.658.1", + "@aws-sdk/credential-provider-ini": "3.658.1", + "@aws-sdk/credential-provider-node": "3.658.1", + "@aws-sdk/credential-provider-process": "3.654.0", + "@aws-sdk/credential-provider-sso": "3.658.1", + "@aws-sdk/credential-provider-web-identity": "3.654.0", + "@aws-sdk/types": "3.654.0", + "@smithy/credential-provider-imds": "^3.2.3", + "@smithy/property-provider": "^3.1.6", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -577,14 +577,14 @@ } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.620.0.tgz", - "integrity": "sha512-VMtPEZwqYrII/oUkffYsNWY9PZ9xpNJpMgmyU0rlDQ25O1c0Hk3fJmZRe6pEkAJ0omD7kLrqGl1DUjQVxpd/Rg==", + "version": "3.654.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.654.0.tgz", + "integrity": "sha512-rxGgVHWKp8U2ubMv+t+vlIk7QYUaRCHaVpmUlJv0Wv6Q0KeO9a42T9FxHphjOTlCGQOLcjCreL9CF8Qhtb4mdQ==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", + "@aws-sdk/types": "3.654.0", + "@smithy/protocol-http": "^4.1.3", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -592,13 +592,13 @@ } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.609.0.tgz", - "integrity": "sha512-S62U2dy4jMDhDFDK5gZ4VxFdWzCtLzwbYyFZx2uvPYTECkepLUfzLic2BHg2Qvtu4QjX+oGE3P/7fwaGIsGNuQ==", + "version": "3.654.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.654.0.tgz", + "integrity": "sha512-OQYb+nWlmASyXfRb989pwkJ9EVUMP1CrKn2eyTk3usl20JZmKo2Vjis6I0tLUkMSxMhnBJJlQKyWkRpD/u1FVg==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/types": "^3.3.0", + "@aws-sdk/types": "3.654.0", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -606,14 +606,14 @@ } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.620.0.tgz", - "integrity": "sha512-nh91S7aGK3e/o1ck64sA/CyoFw+gAYj2BDOnoNa6ouyCrVJED96ZXWbhye/fz9SgmNUZR2g7GdVpiLpMKZoI5w==", + "version": "3.654.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.654.0.tgz", + "integrity": "sha512-gKSomgltKVmsT8sC6W7CrADZ4GHwX9epk3GcH6QhebVO3LA9LRbkL3TwOPUXakxxOLLUTYdOZLIOtFf7iH00lg==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", + "@aws-sdk/types": "3.654.0", + "@smithy/protocol-http": "^4.1.3", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -621,15 +621,15 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.637.0.tgz", - "integrity": "sha512-EYo0NE9/da/OY8STDsK2LvM4kNa79DBsf4YVtaG4P5pZ615IeFsD8xOHZeuJmUrSMlVQ8ywPRX7WMucUybsKug==", + "version": "3.654.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.654.0.tgz", + "integrity": "sha512-liCcqPAyRsr53cy2tYu4qeH4MMN0eh9g6k56XzI5xd4SghXH5YWh4qOYAlQ8T66ZV4nPMtD8GLtLXGzsH8moFg==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.637.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", + "@aws-sdk/types": "3.654.0", + "@aws-sdk/util-endpoints": "3.654.0", + "@smithy/protocol-http": "^4.1.3", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -637,16 +637,16 @@ } }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.614.0.tgz", - "integrity": "sha512-vDCeMXvic/LU0KFIUjpC3RiSTIkkvESsEfbVHiHH0YINfl8HnEqR5rj+L8+phsCeVg2+LmYwYxd5NRz4PHxt5g==", + "version": "3.654.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.654.0.tgz", + "integrity": "sha512-ydGOrXJxj3x0sJhsXyTmvJVLAE0xxuTWFJihTl67RtaO7VRNtd82I3P3bwoMMaDn5WpmV5mPo8fEUDRlBm3fPg==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", + "@aws-sdk/types": "3.654.0", + "@smithy/node-config-provider": "^3.1.7", + "@smithy/types": "^3.4.2", "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", + "@smithy/util-middleware": "^3.0.6", "tslib": "^2.6.2" }, "engines": { @@ -654,31 +654,31 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.614.0.tgz", - "integrity": "sha512-okItqyY6L9IHdxqs+Z116y5/nda7rHxLvROxtAJdLavWTYDydxrZstImNgGWTeVdmc0xX2gJCI77UYUTQWnhRw==", + "version": "3.654.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.654.0.tgz", + "integrity": "sha512-D8GeJYmvbfWkQDtTB4owmIobSMexZel0fOoetwvgCQ/7L8VPph3Q2bn1TRRIXvH7wdt6DcDxA3tKMHPBkT3GlA==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", + "@aws-sdk/types": "3.654.0", + "@smithy/property-provider": "^3.1.6", + "@smithy/shared-ini-file-loader": "^3.1.7", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { - "@aws-sdk/client-sso-oidc": "^3.614.0" + "@aws-sdk/client-sso-oidc": "^3.654.0" } }, "node_modules/@aws-sdk/types": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.609.0.tgz", - "integrity": "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==", + "version": "3.654.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.654.0.tgz", + "integrity": "sha512-VWvbED3SV+10QJIcmU/PKjsKilsTV16d1I7/on4bvD/jo1qGeMXqLDBSen3ks/tuvXZF/mFc7ZW/W2DiLVtO7A==", "optional": true, "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -686,14 +686,14 @@ } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.637.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.637.0.tgz", - "integrity": "sha512-pAqOKUHeVWHEXXDIp/qoMk/6jyxIb6GGjnK1/f8dKHtKIEs4tKsnnL563gceEvdad53OPXIt86uoevCcCzmBnw==", + "version": "3.654.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.654.0.tgz", + "integrity": "sha512-i902fcBknHs0Irgdpi62+QMvzxE+bczvILXigYrlHL4+PiEnlMVpni5L5W1qCkNZXf8AaMrSBuR1NZAGp6UOUw==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/types": "^3.3.0", - "@smithy/util-endpoints": "^2.0.5", + "@aws-sdk/types": "3.654.0", + "@smithy/types": "^3.4.2", + "@smithy/util-endpoints": "^2.1.2", "tslib": "^2.6.2" }, "engines": { @@ -713,26 +713,26 @@ } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.609.0.tgz", - "integrity": "sha512-fojPU+mNahzQ0YHYBsx0ZIhmMA96H+ZIZ665ObU9tl+SGdbLneVZVikGve+NmHTQwHzwkFsZYYnVKAkreJLAtA==", + "version": "3.654.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.654.0.tgz", + "integrity": "sha512-ykYAJqvnxLt7wfrqya28wuH3/7NdrwzfiFd7NqEVQf7dXVxL5RPEpD7DxjcyQo3DsHvvdUvGZVaQhozycn1pzA==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/types": "^3.3.0", + "@aws-sdk/types": "3.654.0", + "@smithy/types": "^3.4.2", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.614.0.tgz", - "integrity": "sha512-15ElZT88peoHnq5TEoEtZwoXTXRxNrk60TZNdpl/TUBJ5oNJ9Dqb5Z4ryb8ofN6nm9aFf59GVAerFDz8iUoHBA==", + "version": "3.654.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.654.0.tgz", + "integrity": "sha512-a0ojjdBN6pqv6gB4H/QPPSfhs7mFtlVwnmKCM/QrTaFzN0U810PJ1BST3lBx5sa23I5jWHGaoFY+5q65C3clLQ==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.609.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", + "@aws-sdk/types": "3.654.0", + "@smithy/node-config-provider": "^3.1.7", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -781,9 +781,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", + "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -813,9 +813,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -870,13 +870,13 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "deprecated": "Use @eslint/config-array instead", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", + "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" }, @@ -1141,12 +1141,12 @@ "dev": true }, "node_modules/@smithy/abort-controller": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.1.tgz", - "integrity": "sha512-MBJBiidoe+0cTFhyxT8g+9g7CeVccLM0IOKKUMCNQ1CNMJ/eIfoo0RTfVrXOONEI1UCN1W+zkiHSbzUNE9dZtQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.4.tgz", + "integrity": "sha512-VupaALAQlXViW3/enTf/f5l5JZYSAxoJL7f0nanhNNKnww6DGCg1oYIuNP78KDugnkwthBO6iEcym16HhWV8RQ==", "optional": true, "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -1154,15 +1154,15 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.5.tgz", - "integrity": "sha512-SkW5LxfkSI1bUC74OtfBbdz+grQXYiPYolyu8VfpLIjEoN/sHVBlLeGXMQ1vX4ejkgfv6sxVbQJ32yF2cl1veA==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.8.tgz", + "integrity": "sha512-Tv1obAC18XOd2OnDAjSWmmthzx6Pdeh63FbLin8MlPiuJ2ATpKkq0NcNOJFr0dO+JmZXnwu8FQxKJ3TKJ3Hulw==", "optional": true, "dependencies": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", + "@smithy/node-config-provider": "^3.1.7", + "@smithy/types": "^3.4.2", "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", + "@smithy/util-middleware": "^3.0.6", "tslib": "^2.6.2" }, "engines": { @@ -1170,19 +1170,19 @@ } }, "node_modules/@smithy/core": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.4.0.tgz", - "integrity": "sha512-cHXq+FneIF/KJbt4q4pjN186+Jf4ZB0ZOqEaZMBhT79srEyGDDBV31NqBRBjazz8ppQ1bJbDJMY9ba5wKFV36w==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.4.6.tgz", + "integrity": "sha512-6lQQp99hnyuNNIzeTYSzCUXJHwvvFLY7hfdFGSJM95tjRDJGfzWYFRBXPaM9766LiiTsQ561KErtbufzUFSYUg==", "optional": true, "dependencies": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.15", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", + "@smithy/middleware-endpoint": "^3.1.3", + "@smithy/middleware-retry": "^3.0.21", + "@smithy/middleware-serde": "^3.0.6", + "@smithy/protocol-http": "^4.1.3", + "@smithy/smithy-client": "^3.3.5", + "@smithy/types": "^3.4.2", "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", + "@smithy/util-middleware": "^3.0.6", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -1191,15 +1191,15 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.0.tgz", - "integrity": "sha512-0SCIzgd8LYZ9EJxUjLXBmEKSZR/P/w6l7Rz/pab9culE/RWuqelAKGJvn5qUOl8BgX8Yj5HWM50A5hiB/RzsgA==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.3.tgz", + "integrity": "sha512-VoxMzSzdvkkjMJNE38yQgx4CfnmT+Z+5EUXkg4x7yag93eQkVQgZvN3XBSHC/ylfBbLbAtdu7flTCChX9I+mVg==", "optional": true, "dependencies": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", + "@smithy/node-config-provider": "^3.1.7", + "@smithy/property-provider": "^3.1.6", + "@smithy/types": "^3.4.2", + "@smithy/url-parser": "^3.0.6", "tslib": "^2.6.2" }, "engines": { @@ -1207,25 +1207,25 @@ } }, "node_modules/@smithy/fetch-http-handler": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", - "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.8.tgz", + "integrity": "sha512-Lqe0B8F5RM7zkw//6avq1SJ8AfaRd3ubFUS1eVp5WszV7p6Ne5hQ4dSuMHDpNRPhgTvj4va9Kd/pcVigHEHRow==", "optional": true, "dependencies": { - "@smithy/protocol-http": "^4.1.0", - "@smithy/querystring-builder": "^3.0.3", - "@smithy/types": "^3.3.0", + "@smithy/protocol-http": "^4.1.3", + "@smithy/querystring-builder": "^3.0.6", + "@smithy/types": "^3.4.2", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "node_modules/@smithy/hash-node": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.3.tgz", - "integrity": "sha512-2ctBXpPMG+B3BtWSGNnKELJ7SH9e4TNefJS0cd2eSkOOROeBnnVBnAy9LtJ8tY4vUEoe55N4CNPxzbWvR39iBw==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.6.tgz", + "integrity": "sha512-c/FHEdKK/7DU2z6ZE91L36ahyXWayR3B+FzELjnYq7wH5YqIseM24V+pWCS9kFn1Ln8OFGTf+pyYPiHZuX0s/Q==", "optional": true, "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.4.2", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" @@ -1235,12 +1235,12 @@ } }, "node_modules/@smithy/invalid-dependency": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.3.tgz", - "integrity": "sha512-ID1eL/zpDULmHJbflb864k72/SNOZCADRc9i7Exq3RUNJw6raWUSlFEQ+3PX3EYs++bTxZB2dE9mEHTQLv61tw==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.6.tgz", + "integrity": "sha512-czM7Ioq3s8pIXht7oD+vmgy4Wfb4XavU/k/irO8NdXFFOx7YAlsCCcKOh/lJD1mJSYQqiR7NmpZ9JviryD/7AQ==", "optional": true, "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" } }, @@ -1257,13 +1257,13 @@ } }, "node_modules/@smithy/middleware-content-length": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.5.tgz", - "integrity": "sha512-ILEzC2eyxx6ncej3zZSwMpB5RJ0zuqH7eMptxC4KN3f+v9bqT8ohssKbhNR78k/2tWW+KS5Spw+tbPF4Ejyqvw==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.8.tgz", + "integrity": "sha512-VuyszlSO49WKh3H9/kIO2kf07VUwGV80QRiaDxUfP8P8UKlokz381ETJvwLhwuypBYhLymCYyNhB3fLAGBX2og==", "optional": true, "dependencies": { - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", + "@smithy/protocol-http": "^4.1.3", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -1271,17 +1271,17 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.1.0.tgz", - "integrity": "sha512-5y5aiKCEwg9TDPB4yFE7H6tYvGFf1OJHNczeY10/EFF8Ir8jZbNntQJxMWNfeQjC1mxPsaQ6mR9cvQbf+0YeMw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.1.3.tgz", + "integrity": "sha512-KeM/OrK8MVFUsoJsmCN0MZMVPjKKLudn13xpgwIMpGTYpA8QZB2Xq5tJ+RE6iu3A6NhOI4VajDTwBsm8pwwrhg==", "optional": true, "dependencies": { - "@smithy/middleware-serde": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-middleware": "^3.0.3", + "@smithy/middleware-serde": "^3.0.6", + "@smithy/node-config-provider": "^3.1.7", + "@smithy/shared-ini-file-loader": "^3.1.7", + "@smithy/types": "^3.4.2", + "@smithy/url-parser": "^3.0.6", + "@smithy/util-middleware": "^3.0.6", "tslib": "^2.6.2" }, "engines": { @@ -1289,18 +1289,18 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.15.tgz", - "integrity": "sha512-iTMedvNt1ApdvkaoE8aSDuwaoc+BhvHqttbA/FO4Ty+y/S5hW6Ci/CTScG7vam4RYJWZxdTElc3MEfHRVH6cgQ==", + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.21.tgz", + "integrity": "sha512-/h0fElV95LekVVEJuSw+aI11S1Y3zIUwBc6h9ZbUv43Gl2weXsbQwjLoet6j/Qtb0phfrSxS6pNg6FqgJOWZkA==", "optional": true, "dependencies": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/service-error-classification": "^3.0.3", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", + "@smithy/node-config-provider": "^3.1.7", + "@smithy/protocol-http": "^4.1.3", + "@smithy/service-error-classification": "^3.0.6", + "@smithy/smithy-client": "^3.3.5", + "@smithy/types": "^3.4.2", + "@smithy/util-middleware": "^3.0.6", + "@smithy/util-retry": "^3.0.6", "tslib": "^2.6.2", "uuid": "^9.0.1" }, @@ -1309,12 +1309,12 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.3.tgz", - "integrity": "sha512-puUbyJQBcg9eSErFXjKNiGILJGtiqmuuNKEYNYfUD57fUl4i9+mfmThtQhvFXU0hCVG0iEJhvQUipUf+/SsFdA==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.6.tgz", + "integrity": "sha512-KKTUSl1MzOM0MAjGbudeaVNtIDo+PpekTBkCNwvfZlKndodrnvRo+00USatiyLOc0ujjO9UydMRu3O9dYML7ag==", "optional": true, "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -1322,12 +1322,12 @@ } }, "node_modules/@smithy/middleware-stack": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.3.tgz", - "integrity": "sha512-r4klY9nFudB0r9UdSMaGSyjyQK5adUyPnQN/ZM6M75phTxOdnc/AhpvGD1fQUvgmqjQEBGCwpnPbDm8pH5PapA==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.6.tgz", + "integrity": "sha512-2c0eSYhTQ8xQqHMcRxLMpadFbTXg6Zla5l0mwNftFCZMQmuhI7EbAJMx6R5eqfuV3YbJ3QGyS3d5uSmrHV8Khg==", "optional": true, "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -1335,14 +1335,14 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.4.tgz", - "integrity": "sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.7.tgz", + "integrity": "sha512-g3mfnC3Oo8pOI0dYuPXLtdW1WGVb3bR2tkV21GNkm0ZvQjLTtamXAwCWt/FCb0HGvKt3gHHmF1XerG0ICfalOg==", "optional": true, "dependencies": { - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", + "@smithy/property-provider": "^3.1.6", + "@smithy/shared-ini-file-loader": "^3.1.7", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -1350,15 +1350,15 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.1.4.tgz", - "integrity": "sha512-+UmxgixgOr/yLsUxcEKGH0fMNVteJFGkmRltYFHnBMlogyFdpzn2CwqWmxOrfJELhV34v0WSlaqG1UtE1uXlJg==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.2.3.tgz", + "integrity": "sha512-/gcm5DJ3k1b1zEInzBGAZC8ntJ+jwrz1NcSIu+9dSXd1FfG0G6QgkDI40tt8/WYUbHtLyo8fEqtm2v29koWo/w==", "optional": true, "dependencies": { - "@smithy/abort-controller": "^3.1.1", - "@smithy/protocol-http": "^4.1.0", - "@smithy/querystring-builder": "^3.0.3", - "@smithy/types": "^3.3.0", + "@smithy/abort-controller": "^3.1.4", + "@smithy/protocol-http": "^4.1.3", + "@smithy/querystring-builder": "^3.0.6", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -1366,12 +1366,12 @@ } }, "node_modules/@smithy/property-provider": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.3.tgz", - "integrity": "sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.6.tgz", + "integrity": "sha512-NK3y/T7Q/Bw+Z8vsVs9MYIQ5v7gOX7clyrXcwhhIBQhbPgRl6JDrZbusO9qWDhcEus75Tg+VCxtIRfo3H76fpw==", "optional": true, "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -1379,12 +1379,12 @@ } }, "node_modules/@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.3.tgz", + "integrity": "sha512-GcbMmOYpH9iRqtC05RbRnc/0FssxSTHlmaNhYBTgSgNCYpdR3Kt88u5GAZTBmouzv+Zlj/VRv92J9ruuDeJuEw==", "optional": true, "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -1392,12 +1392,12 @@ } }, "node_modules/@smithy/querystring-builder": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", - "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.6.tgz", + "integrity": "sha512-sQe08RunoObe+Usujn9+R2zrLuQERi3CWvRO3BvnoWSYUaIrLKuAIeY7cMeDax6xGyfIP3x/yFWbEKSXvOnvVg==", "optional": true, "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.4.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" }, @@ -1406,12 +1406,12 @@ } }, "node_modules/@smithy/querystring-parser": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.3.tgz", - "integrity": "sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.6.tgz", + "integrity": "sha512-UJKw4LlEkytzz2Wq+uIdHf6qOtFfee/o7ruH0jF5I6UAuU+19r9QV7nU3P/uI0l6+oElRHmG/5cBBcGJrD7Ozg==", "optional": true, "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -1419,24 +1419,24 @@ } }, "node_modules/@smithy/service-error-classification": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.3.tgz", - "integrity": "sha512-Jn39sSl8cim/VlkLsUhRFq/dKDnRUFlfRkvhOJaUbLBXUsLRLNf9WaxDv/z9BjuQ3A6k/qE8af1lsqcwm7+DaQ==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.6.tgz", + "integrity": "sha512-53SpchU3+DUZrN7J6sBx9tBiCVGzsib2e4sc512Q7K9fpC5zkJKs6Z9s+qbMxSYrkEkle6hnMtrts7XNkMJJMg==", "optional": true, "dependencies": { - "@smithy/types": "^3.3.0" + "@smithy/types": "^3.4.2" }, "engines": { "node": ">=16.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.4.tgz", - "integrity": "sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.7.tgz", + "integrity": "sha512-IA4K2qTJYXkF5OfVN4vsY1hfnUZjaslEE8Fsr/gGFza4TAC2A9NfnZuSY2srQIbt9bwtjHiAayrRVgKse4Q7fA==", "optional": true, "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -1444,16 +1444,16 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.1.0.tgz", - "integrity": "sha512-aRryp2XNZeRcOtuJoxjydO6QTaVhxx/vjaR+gx7ZjaFgrgPRyZ3HCTbfwqYj6ZWEBHkCSUfcaymKPURaByukag==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.1.4.tgz", + "integrity": "sha512-72MiK7xYukNsnLJI9NqvUHqTu0ziEsfMsYNlWpiJfuGQnCTFKpckThlEatirvcA/LmT1h7rRO+pJD06PYsPu9Q==", "optional": true, "dependencies": { "@smithy/is-array-buffer": "^3.0.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", + "@smithy/protocol-http": "^4.1.3", + "@smithy/types": "^3.4.2", "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", + "@smithy/util-middleware": "^3.0.6", "@smithy/util-uri-escape": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" @@ -1463,16 +1463,16 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.2.0.tgz", - "integrity": "sha512-pDbtxs8WOhJLJSeaF/eAbPgXg4VVYFlRcL/zoNYA5WbG3wBL06CHtBSg53ppkttDpAJ/hdiede+xApip1CwSLw==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.3.5.tgz", + "integrity": "sha512-7IZi8J3Dr9n3tX+lcpmJ/5tCYIqoXdblFBaPuv0SEKZFRpCxE+TqIWL6I3t7jLlk9TWu3JSvEZAhtjB9yvB+zA==", "optional": true, "dependencies": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", + "@smithy/middleware-endpoint": "^3.1.3", + "@smithy/middleware-stack": "^3.0.6", + "@smithy/protocol-http": "^4.1.3", + "@smithy/types": "^3.4.2", + "@smithy/util-stream": "^3.1.8", "tslib": "^2.6.2" }, "engines": { @@ -1480,9 +1480,9 @@ } }, "node_modules/@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.4.2.tgz", + "integrity": "sha512-tHiFcfcVedVBHpmHUEUHOCCih8iZbIAYn9NvPsNzaPm/237I3imdDdZoOC8c87H5HBAVEa06tTgb+OcSWV9g5w==", "optional": true, "dependencies": { "tslib": "^2.6.2" @@ -1492,13 +1492,13 @@ } }, "node_modules/@smithy/url-parser": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.3.tgz", - "integrity": "sha512-pw3VtZtX2rg+s6HMs6/+u9+hu6oY6U7IohGhVNnjbgKy86wcIsSZwgHrFR+t67Uyxvp4Xz3p3kGXXIpTNisq8A==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.6.tgz", + "integrity": "sha512-47Op/NU8Opt49KyGpHtVdnmmJMsp2hEwBdyjuFB9M2V5QVOwA7pBhhxKN5z6ztKGrMw76gd8MlbPuzzvaAncuQ==", "optional": true, "dependencies": { - "@smithy/querystring-parser": "^3.0.3", - "@smithy/types": "^3.3.0", + "@smithy/querystring-parser": "^3.0.6", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" } }, @@ -1563,14 +1563,14 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.15.tgz", - "integrity": "sha512-FZ4Psa3vjp8kOXcd3HJOiDPBCWtiilLl57r0cnNtq/Ga9RSDrM5ERL6xt+tO43+2af6Pn5Yp92x2n5vPuduNfg==", + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.21.tgz", + "integrity": "sha512-M/FhTBk4c/SsB91dD/M4gMGfJO7z/qJaM9+XQQIqBOf4qzZYMExnP7R4VdGwxxH8IKMGW+8F0I4rNtVRrcfPoA==", "optional": true, "dependencies": { - "@smithy/property-provider": "^3.1.3", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", + "@smithy/property-provider": "^3.1.6", + "@smithy/smithy-client": "^3.3.5", + "@smithy/types": "^3.4.2", "bowser": "^2.11.0", "tslib": "^2.6.2" }, @@ -1579,17 +1579,17 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.15.tgz", - "integrity": "sha512-KSyAAx2q6d0t6f/S4XB2+3+6aQacm3aLMhs9aLMqn18uYGUepbdssfogW5JQZpc6lXNBnp0tEnR5e9CEKmEd7A==", + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.21.tgz", + "integrity": "sha512-NiLinPvF86U3S2Pdx/ycqd4bnY5dmFSPNL5KYRwbNjqQFS09M5Wzqk8BNk61/47xCYz1X/6KeiSk9qgYPTtuDw==", "optional": true, "dependencies": { - "@smithy/config-resolver": "^3.0.5", - "@smithy/credential-provider-imds": "^3.2.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/property-provider": "^3.1.3", - "@smithy/smithy-client": "^3.2.0", - "@smithy/types": "^3.3.0", + "@smithy/config-resolver": "^3.0.8", + "@smithy/credential-provider-imds": "^3.2.3", + "@smithy/node-config-provider": "^3.1.7", + "@smithy/property-provider": "^3.1.6", + "@smithy/smithy-client": "^3.3.5", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -1597,13 +1597,13 @@ } }, "node_modules/@smithy/util-endpoints": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.5.tgz", - "integrity": "sha512-ReQP0BWihIE68OAblC/WQmDD40Gx+QY1Ez8mTdFMXpmjfxSyz2fVQu3A4zXRfQU9sZXtewk3GmhfOHswvX+eNg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.2.tgz", + "integrity": "sha512-FEISzffb4H8DLzGq1g4MuDpcv6CIG15fXoQzDH9SjpRJv6h7J++1STFWWinilG0tQh9H1v2UKWG19Jjr2B16zQ==", "optional": true, "dependencies": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", + "@smithy/node-config-provider": "^3.1.7", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -1623,12 +1623,12 @@ } }, "node_modules/@smithy/util-middleware": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.3.tgz", - "integrity": "sha512-l+StyYYK/eO3DlVPbU+4Bi06Jjal+PFLSMmlWM1BEwyLxZ3aKkf1ROnoIakfaA7mC6uw3ny7JBkau4Yc+5zfWw==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.6.tgz", + "integrity": "sha512-BxbX4aBhI1O9p87/xM+zWy0GzT3CEVcXFPBRDoHAM+pV0eSW156pR+PSYEz0DQHDMYDsYAflC2bQNz2uaDBUZQ==", "optional": true, "dependencies": { - "@smithy/types": "^3.3.0", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -1636,13 +1636,13 @@ } }, "node_modules/@smithy/util-retry": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.3.tgz", - "integrity": "sha512-AFw+hjpbtVApzpNDhbjNG5NA3kyoMs7vx0gsgmlJF4s+yz1Zlepde7J58zpIRIsdjc+emhpAITxA88qLkPF26w==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.6.tgz", + "integrity": "sha512-BRZiuF7IwDntAbevqMco67an0Sr9oLQJqqRCsSPZZHYRnehS0LHDAkJk/pSmI7Z8c/1Vet294H7fY2fWUgB+Rg==", "optional": true, "dependencies": { - "@smithy/service-error-classification": "^3.0.3", - "@smithy/types": "^3.3.0", + "@smithy/service-error-classification": "^3.0.6", + "@smithy/types": "^3.4.2", "tslib": "^2.6.2" }, "engines": { @@ -1650,14 +1650,14 @@ } }, "node_modules/@smithy/util-stream": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.1.3.tgz", - "integrity": "sha512-FIv/bRhIlAxC0U7xM1BCnF2aDRPq0UaelqBHkM2lsCp26mcBbgI0tCVTv+jGdsQLUmAMybua/bjDsSu8RQHbmw==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.1.8.tgz", + "integrity": "sha512-hoKOqSmb8FD3WLObuB5hwbM7bNIWgcnvkThokTvVq7J5PKjlLUK5qQQcB9zWLHIoSaIlf3VIv2OxZY2wtQjcRQ==", "optional": true, "dependencies": { - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/types": "^3.3.0", + "@smithy/fetch-http-handler": "^3.2.8", + "@smithy/node-http-handler": "^3.2.3", + "@smithy/types": "^3.4.2", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", @@ -1732,9 +1732,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.5", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", - "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -1764,9 +1764,9 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "node_modules/@types/node": { - "version": "20.16.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.4.tgz", - "integrity": "sha512-ioyQ1zK9aGEomJ45zz8S8IdzElyxhvP1RVWnPrXDf6wFaUb+kk1tEcVVJkF7RPGM0VWI7cp5U57oCPIn5iN1qg==", + "version": "20.16.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.8.tgz", + "integrity": "sha512-sbo5JmfbZNkyDv+2HCccr9Y9ZkKJBMTru7UdAsCojMGjKNjdaOV73bqEW242QrHEZL8R4LbHMrW+FHB5lZ5/bw==", "dependencies": { "undici-types": "~6.19.2" } @@ -1790,9 +1790,9 @@ } }, "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" + "version": "6.9.16", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", + "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==" }, "node_modules/@types/range-parser": { "version": "1.2.7", @@ -2830,11 +2830,11 @@ } }, "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -3206,16 +3206,16 @@ } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -3322,9 +3322,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.9.0.tgz", - "integrity": "sha512-McVbYmwA3NEKwRQY5g4aWMdcZE5xZxV8i8l7CqJSrameuGSQJtSWaL/LxTEzSKKaCcOhlpDR8XEfYXWPrdo/ZQ==", + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.11.1.tgz", + "integrity": "sha512-EwcbfLOhwVMAfatfqLecR2yv3dE5+kQ8kx+Rrt0DvDXEVwW86KQ/xbMDQhtp5l42VXukD5SOF8mQQHbaNtO0CQ==", "dev": true, "dependencies": { "debug": "^3.2.7" @@ -3931,9 +3931,9 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, "node_modules/follow-redirects": { - "version": "1.15.8", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.8.tgz", - "integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", @@ -5307,12 +5307,6 @@ "node": ">=10" } }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -5399,11 +5393,6 @@ "url": "https://opencollective.com/mongoose" } }, - "node_modules/mongoose/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, "node_modules/mpath": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", @@ -5432,9 +5421,9 @@ } }, "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==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/nanoid": { "version": "3.3.1", @@ -5499,9 +5488,9 @@ } }, "node_modules/nise/node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", "dev": true }, "node_modules/nise/node_modules/type-detect": { @@ -6608,11 +6597,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, "node_modules/serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -7195,12 +7179,6 @@ "node": ">= 0.6" } }, - "node_modules/telegram-test-api/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/telegram-test-api/node_modules/on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", diff --git a/package.json b/package.json index 87471cd2..547e1d2b 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "lint": "eslint .", "format": "prettier --write '**/*.js'", "pretest": "npx tsc", - "test": "export NODE_ENV=test && mocha --exit 'tests/**/*.js'" + "test": "export NODE_ENV=test && mocha --exit tests/**/*.spec.js" }, "license": "MIT", "dependencies": { diff --git a/tests/bot/bot.spec.js b/tests/bot/bot.spec.js new file mode 100644 index 00000000..579ef6b8 --- /dev/null +++ b/tests/bot/bot.spec.js @@ -0,0 +1,593 @@ +const path = require('path'); +const fs = require('fs'); +const sinon = require('sinon'); +const { expect } = require('chai'); +const proxyquire = require('proxyquire'); + +const { initialize } = require('../../bot'); +const { User, Order } = require('../../models'); +const { getCurrenciesWithPrice } = require('../../util'); +const { mockUpdatesResponseForCurrencies } = require('./mocks/currenciesResponse'); +const { mockUpdatesResponseForLanguages } = require('./mocks/languagesResponse'); + +describe('Telegram bot', () => { + const token = '123456'; + let server; + let sandbox; + let order, user; + + beforeEach(() => { + user = { + lang: 'ESP', + trades_completed: 7, + admin: false, + banned: false, + disputes: 0, + _id: '61006f0e85ad4f96cde94141', + balance: 0, + tg_id: '1', + username: 'negrunch', + created_at: '2021-07-27T20:39:42.403Z', + }; + order = { + buyer_dispute: false, + seller_dispute: false, + buyer_cooperativecancel: false, + seller_cooperativecancel: false, + _id: '612d451148df8353e387eeff', + description: + 'Vendiendo 111 sats\n' + + 'Por ves 111\n' + + 'Pago por Pagomovil\n' + + 'Tiene 7 operaciones exitosas', + amount: 111, + fee: 0.111, + creator_id: '61006f0e85ad4f96cde94141', + seller_id: '61006f0e85ad4f96cde94141', + type: 'sell', + status: 'PENDING', + fiat_amount: 111, + fiat_code: 'ves', + payment_method: 'Pagomovil', + tg_chat_id: '1', + tg_order_message: '1', + created_at: '2021-08-30T20:52:33.870Z', + }; + sandbox = sinon.createSandbox(); + // Mock process.env + sandbox.stub(process, 'env').value({ + CHANNEL: '@testChannel', + MIN_PAYMENT_AMT: 100, + NODE_ENV: 'test', + INVOICE_EXPIRATION_WINDOW: 3600000, + LND_GRPC_HOST: '127.0.0.1:10005', + }); + + // Mock TelegramServer + server = { + getClient: sandbox.stub().returns({ + makeCommand: sandbox.stub().returns({}), + sendCommand: sandbox.stub().resolves({ ok: true }), + getUpdates: sandbox.stub().resolves({ + ok: true, + result: [{ + update_id: 1, + message: { + message_id: 1, + from: { + id: 1, + is_bot: false, + first_name: 'Test', + username: 'testuser', + language_code: 'en', + }, + chat: { + id: 1, + first_name: 'Test', + username: 'testuser', + type: 'private', + }, + date: 1678888888, + text: '/start', + entities: [{ + offset: 0, + length: 6, + type: 'bot_command', + }], + }, + }], + }), + sendMessage: sandbox.stub().resolves({ ok: true }), + }), + ApiURL: 'http://localhost:9001', + }; + + // Mock mongo connection and models + sandbox.stub(User, 'findOne').resolves(user); + sandbox.stub(Order, 'findOne').resolves(null); + sandbox.stub(Order.prototype, 'save').resolves(order); + + // Initialize the bot + initialize(token, { telegram: { apiRoot: server.ApiURL } }); + }); + + afterEach(() => { + sandbox.restore(); + }); + + it('should start', async () => { + const client = server.getClient(token, { timeout: 5000 }); + const command = client.makeCommand('/start'); + const res = await client.sendCommand(command); + expect(res.ok).to.be.equal(true); + const updates = await client.getUpdates(); + expect(updates.ok).to.be.equal(true); + expect(updates.result.length).to.be.equal(1); + }); + + it('should return /sell help', async () => { + const client = server.getClient(token, { timeout: 5000 }); + const command = client.makeCommand('/sell help'); + const res = await client.sendCommand(command); + expect(res.ok).to.be.equal(true); + }); + + it('should create a /sell', async () => { + const client = server.getClient(token, { timeout: 5000 }); + const command = client.makeCommand('/sell 100 1 ves Pagomovil'); + const res = await client.sendCommand(command); + expect(res.ok).to.be.equal(true); + }); + + it('should return unknown_command for unregistered command', async () => { + const client = server.getClient(token, { timeout: 5000 }); + const command = client.makeCommand('/sello 100 1 ves Pagomovil'); + const res = await client.sendCommand(command); + expect(res.ok).to.be.equal(true); + + const mockUpdatesResponse = { + ok: true, + result: [ + { + update_id: 1, + message: { + text: "😕 I do not understand. Please use /help to see the list of available commands" + }, + }, + ], + }; + client.getUpdates.onCall(0).resolves(mockUpdatesResponse); + + const updates = await client.getUpdates(); + expect(updates.ok).to.be.equal(true); + expect(updates.result[0].message.text).to.equal('😕 I do not understand. Please use /help to see the list of available commands'); + }); + + it('should return /buy help', async () => { + const client = server.getClient(token, { timeout: 5000 }); + const command = client.makeCommand('/buy help'); + const res = await client.sendCommand(command); + expect(res.ok).to.be.equal(true); + }); + + it('should return the list of supported currencies', async () => { + const client = server.getClient(token, { timeout: 5000 }); + const command = client.makeCommand('/listcurrencies'); + client.getUpdates.onCall(0).resolves(mockUpdatesResponseForCurrencies); + + const res = await client.sendCommand(command); + expect(res.ok).to.be.equal(true); + const updates = await client.getUpdates(); + expect(updates.ok).to.be.equal(true); + expect( + (updates.result[0].message.text.match(/\n/g) || []).length - 1 + ).to.be.equal(getCurrenciesWithPrice().length); + }); + + it('should return flags of langs supported', async () => { + const client = server.getClient(token, { timeout: 5000 }); + const command = client.makeCommand('/setlang'); + client.getUpdates.onCall(0).resolves(mockUpdatesResponseForLanguages); + + const res = await client.sendCommand(command); + expect(res.ok).to.be.equal(true); + const updates = await client.getUpdates(); + expect(updates.ok).to.be.equal(true); + let flags = 0; + updates.result[0].message.reply_markup.inline_keyboard.forEach(flag => { + flags += flag.length; + }); + let langs = 0; + fs.readdirSync(path.join(__dirname, '../../locales')).forEach(file => { + langs++; + }); + expect(flags).to.be.equal(langs); + }); +}); + +describe('Bot Initialization', () => { + let initialize; + let botStub; + let scheduleStub; + let validateUserStub; + let startMessageStub; + let attemptPendingPaymentsStub; + + beforeEach(() => { + botStub = { + catch: sinon.stub(), + use: sinon.stub(), + start: sinon.stub(), + command: sinon.stub(), + on: sinon.stub(), + action: sinon.stub(), + handleUpdate: sinon.stub().resolves(), + telegram: { + sendMessage: sinon.stub().resolves({ ok: true }), + getMe: sinon.stub().resolves({ ok: true, result: { id: 12345 } }), + getChatMember: sinon.stub().resolves({ ok: true, result: { status: 'administrator' } }), + }, + }; + + scheduleStub = { + scheduleJob: sinon.stub(), + }; + + validateUserStub = sinon.stub().resolves(); + startMessageStub = sinon.stub().resolves(); + attemptPendingPaymentsStub = sinon.stub(); + + // Replace the real modules with the stubs + initialize = proxyquire('../../bot/start', { + 'telegraf': { Telegraf: sinon.stub().returns(botStub) }, + 'node-schedule': scheduleStub, + '@grammyjs/i18n': { I18n: sinon.stub().returns({ middleware: sinon.stub().returns(() => { }) }) }, + '@grammyjs/ratelimiter': { limit: sinon.stub().returns(() => { }) }, + '../models': { + Order: { + findOne: sinon.stub().resolves(null), + prototype: { + save: sinon.stub().resolves(), + }, + }, + User: { + findOne: sinon.stub().resolves(null), + prototype: { + save: sinon.stub().resolves(), + }, + }, + Community: { + findById: sinon.stub().resolves(null), + prototype: { + save: sinon.stub().resolves(), + }, + }, + Config: { + findOne: sinon.stub().resolves(null), + prototype: { + save: sinon.stub().resolves(), + }, + }, + Dispute: { + findOne: sinon.stub().resolves(null), + prototype: { + save: sinon.stub().resolves(), + }, + }, + PendingPayment: { + findOne: sinon.stub().resolves(null), + }, + }, + '../ln': { + settleHoldInvoice: sinon.stub().resolves(), + cancelHoldInvoice: sinon.stub().resolves(), + payToBuyer: sinon.stub().resolves(), + subscribeInvoice: sinon.stub().resolves(), + getInvoice: sinon.stub().resolves({ + is_confirmed: false, + is_canceled: false, + is_held: false, + }), + }, + '../jobs': { + attemptPendingPayments: attemptPendingPaymentsStub, + cancelOrders: sinon.stub().resolves(), + deleteOrders: sinon.stub().resolves(), + calculateEarnings: sinon.stub().resolves(), + attemptCommunitiesPendingPayments: sinon.stub().resolves(), + deleteCommunity: sinon.stub().resolves(), + nodeInfo: sinon.stub().resolves(), + }, + './modules/community': { configure: sinon.stub() }, + './modules/language': { configure: sinon.stub() }, + './modules/nostr': { configure: sinon.stub() }, + './modules/orders': { configure: sinon.stub() }, + './modules/user': { configure: sinon.stub() }, + './modules/dispute': { configure: sinon.stub() }, + './ordersActions': { + getOrders: sinon.stub().resolves([]), + }, + './commands': { + rateUser: sinon.stub().resolves(), + cancelAddInvoice: sinon.stub().resolves(), + addInvoice: sinon.stub().resolves(), + cancelShowHoldInvoice: sinon.stub().resolves(), + showHoldInvoice: sinon.stub().resolves(), + addInvoicePHI: sinon.stub().resolves(), + cancelOrder: sinon.stub().resolves(), + fiatSent: sinon.stub().resolves(), + release: sinon.stub().resolves(), + }, + './validations': { + validateParams: sinon.stub().resolves([]), + validateObjectId: sinon.stub().resolves(true), + validateLightningAddress: sinon.stub().resolves(true), + validateUserWaitingOrder: sinon.stub().resolves(true), + isBannedFromCommunity: sinon.stub().resolves(false), + validateSuperAdmin: sinon.stub().resolves(true), + validateAdmin: sinon.stub().resolves(true), + validateSellOrder: sinon.stub().resolves(true), + validateBuyOrder: sinon.stub().resolves(true), + validateInvoice: sinon.stub().resolves(true), + validateTakeSellOrder: sinon.stub().resolves(true), + validateTakeBuyOrder: sinon.stub().resolves(true), + validateReleaseOrder: sinon.stub().resolves(true), + validateDisputeOrder: sinon.stub().resolves(true), + validateFiatSentOrder: sinon.stub().resolves(true), + validateSeller: sinon.stub().resolves(true), + isValidInvoice: sinon.stub().resolves({ success: true }), + validateUser: validateUserStub + }, + '../util': { + getCurrenciesWithPrice: sinon.stub().returns([]), + deleteOrderFromChannel: sinon.stub().resolves(), + removeAtSymbol: sinon.stub().returns(''), + getEmojiRate: sinon.stub().returns(''), + decimalRound: sinon.stub().returns(0), + getUserAge: sinon.stub().returns(0), + getStars: sinon.stub().returns(''), + getOrderChannel: sinon.stub().returns(''), + holdInvoiceExpirationInSecs: sinon.stub().returns({ + expirationTimeInSecs: 0, + safetyWindowInSecs: 0, + }), + sanitizeMD: sinon.stub().returns(''), + getCurrency: sinon.stub().returns(''), + numberFormat: sinon.stub().returns(''), + getDetailedOrder: sinon.stub().returns({}), + secondsToTime: sinon.stub().returns(''), + }, + './messages': { + startMessage: startMessageStub, + bannedUserErrorMessage: sinon.stub().resolves(), + notOrdersMessage: sinon.stub().resolves(), + notAuthorized: sinon.stub().resolves(), + sellOrderCorrectFormatMessage: sinon.stub().resolves(), + invalidRangeWithAmount: sinon.stub().resolves(), + mustBeANumberOrRange: sinon.stub().resolves(), + mustBeGreatherEqThan: sinon.stub().resolves(), + mustBeValidCurrency: sinon.stub().resolves(), + buyOrderCorrectFormatMessage: sinon.stub().resolves(), + invalidTypeOrderMessage: sinon.stub().resolves(), + alreadyTakenOrderMessage: sinon.stub().resolves(), + invalidOrderMessage: sinon.stub().resolves(), + cantTakeOwnOrderMessage: sinon.stub().resolves(), + minimunAmountInvoiceMessage: sinon.stub().resolves(), + minimunExpirationTimeInvoiceMessage: sinon.stub().resolves(), + expiredInvoiceMessage: sinon.stub().resolves(), + requiredAddressInvoiceMessage: sinon.stub().resolves(), + requiredHashInvoiceMessage: sinon.stub().resolves(), + invoiceMustBeLargerMessage: sinon.stub().resolves(), + invoiceExpiryTooShortMessage: sinon.stub().resolves(), + invoiceHasExpiredMessage: sinon.stub().resolves(), + invoiceHasWrongDestinationMessage: sinon.stub().resolves(), + invoiceInvalidMessage: sinon.stub().resolves(), + notLightningInvoiceMessage: sinon.stub().resolves(), + customMessage: sinon.stub().resolves(), + notValidIdMessage: sinon.stub().resolves(), + userCantTakeMoreThanOneWaitingOrderMessage: sinon.stub().resolves(), + waitingForBuyerOrderMessage: sinon.stub().resolves(), + notActiveOrderMessage: sinon.stub().resolves(), + orderOnfiatSentStatusMessages: sinon.stub().resolves(), + sellerPaidHoldMessage: sinon.stub().resolves(), + successCancelOrderMessage: sinon.stub().resolves(), + successCancelOrderByAdminMessage: sinon.stub().resolves(), + successCancelAllOrdersMessage: sinon.stub().resolves(), + successCompleteOrderMessage: sinon.stub().resolves(), + successCompleteOrderByAdminMessage: sinon.stub().resolves(), + checkOrderMessage: sinon.stub().resolves(), + checkInvoiceMessage: sinon.stub().resolves(), + notFoundUserMessage: sinon.stub().resolves(), + userBannedErrorMessage: sinon.stub().resolves(), + disableLightningAddress: sinon.stub().resolves(), + invalidLightningAddress: sinon.stub().resolves(), + successSetAddress: sinon.stub().resolves(), + setinvoice_no_response: sinon.stub().resolves(), + showConfirmationButtons: sinon.stub().resolves(), + need_default_community: sinon.stub().resolves(), + updateUserSettingsMessage: sinon.stub().resolves(), + not_wizard: sinon.stub().resolves(), + no_capital_letters: sinon.stub().resolves(), + unknown_command: sinon.stub().resolves(), + maintenance: sinon.stub().resolves(), + operation_successful: sinon.stub().resolves(), + }, + './middleware': { + userMiddleware: sinon.stub().resolves(), + adminMiddleware: sinon.stub().resolves(), + superAdminMiddleware: sinon.stub().resolves(), + commandArgsMiddleware: sinon.stub().returns(() => { }), + stageMiddleware: sinon.stub().returns(() => { }), + }, + '../logger': { + error: sinon.stub(), + notice: sinon.stub(), + debug: sinon.stub(), + info: sinon.stub(), + }, + }).initialize; + }); + + afterEach(() => { + sinon.restore(); + }); + + it('should initialize the bot and register middleware', () => { + initialize('dummy-token', {}); + + expect(botStub.catch.calledOnce).to.be.equal(true); + expect(botStub.use.callCount).to.be.equal(5); + }); + + it('should schedule recurring jobs', () => { + process.env.PENDING_PAYMENT_WINDOW = '10'; + + initialize('dummy-token', {}); + + expect(scheduleStub.scheduleJob.calledWith( + `*/${process.env.PENDING_PAYMENT_WINDOW} * * * *`, + sinon.match.func + )).to.be.equal(true); + + const scheduledFunction = scheduleStub.scheduleJob.getCall(0).args[1]; + + scheduledFunction(); + + expect(scheduleStub.scheduleJob.callCount).to.be.equal(7); + expect(scheduleStub.scheduleJob.getCall(0).args[0]).to.equal('*/10 * * * *'); + expect(attemptPendingPaymentsStub.calledOnce).to.be.equal(true); + }); + + it('should register the /start command handler', async () => { + const ctx = { + update: { + message: { + text: '/start', + }, + }, + }; + + initialize('dummy-token', {}); + + await botStub.start.firstCall.args[0](ctx); + + expect(validateUserStub.calledOnceWithExactly(ctx, true)).to.be.equal(true); + expect(startMessageStub.calledOnceWithExactly(ctx)).to.be.equal(true); + }); + + it('should handle text messages that are not commands using the first text handler', async () => { + const ctx = { + update: { + message: { + text: 'Hello, bot!', + from: { + id: 1, + is_bot: false, + first_name: 'Test', + username: 'testuser', + language_code: 'en', + }, + }, + }, + chat: { + id: 1, + first_name: 'Test', + username: 'testuser', + type: 'private', + }, + reply: sinon.stub().resolves({ ok: true }), + i18n: { + t: sinon.stub().returns('maintenance'), + }, + }; + + botStub.on = sinon.stub().callsFake((event, middleware, handler) => { + if (event === 'text') { + const capturedHandler = handler; + capturedHandler(ctx); + } + }); + + const ConfigStub = { + findOne: sinon.stub().resolves({ maintenance: true }), + prototype: { + save: sinon.stub().resolves(), + }, + }; + + const TelegrafMock = sinon.stub().returns(botStub); + + const startModule = proxyquire('../../bot/start', { + 'telegraf': { Telegraf: TelegrafMock }, + '../models': { Config: ConfigStub }, + }); + + botStub.telegram.sendMessage = sinon.stub().resolves({ ok: true }); + + const bot = startModule.initialize('dummy-token', {}); + + await bot.handleUpdate({ + update_id: 1, + message: ctx.update.message, + }); + + expect(ConfigStub.findOne.calledOnceWithExactly({ maintenance: true })).to.be.equal(true); + expect(ctx.reply.calledOnceWithExactly('maintenance')).to.be.equal(true); + }); + + it('should handle text messages that are not commands using the second text handler', async () => { + const i18nStub = sinon.stub(); + i18nStub.withArgs('unknown_command').returns('This is an unknown command.'); + const ctx = { + message: { + text: '/command', + from: { + id: 1, + is_bot: false, + first_name: 'Test', + username: 'testuser', + language_code: 'en', + }, + chat: { + id: 1, + first_name: 'Test', + username: 'testuser', + type: 'private', + }, + }, + + + reply: sinon.stub().resolves({ ok: true }), + i18n: { + t: i18nStub, + }, + }; + + botStub.on = sinon.stub().callsFake((event, middleware, handler) => { + if (event === 'text') { + const capturedHandler = handler; + capturedHandler(ctx); + } + }); + + const TelegrafMock = sinon.stub().returns(botStub); + + const startModule = proxyquire('../../bot/start', { + 'telegraf': { Telegraf: TelegrafMock }, + }); + + // Mock the Telegram API sendMessage method + botStub.telegram.sendMessage = sinon.stub().resolves({ ok: true }); + + // Call initialize from the proxied module + const bot = startModule.initialize('dummy-token', {}); + + await bot.handleUpdate({ + update_id: 1, + message: ctx.message, + }); + + expect(ctx.reply.calledOnce).to.be.equal(true); + expect(ctx.reply.calledWithExactly('This is an unknown command.')).to.be.equal(true); + }); +}); diff --git a/tests/bot/mocks/currenciesResponse.js b/tests/bot/mocks/currenciesResponse.js new file mode 100644 index 00000000..9e5f3fb8 --- /dev/null +++ b/tests/bot/mocks/currenciesResponse.js @@ -0,0 +1,117 @@ +const mockUpdatesResponseForCurrencies = { + ok: true, + result: [ + { + time: 1726511559928, + botToken: '123456', + message: { + chat_id: 1, + text: 'Code | Name |\n' + + 'AED | United Arab Emirates Dirham | 🇦🇪\n' + + 'ANG | Netherlands Antillean Guilder | 🇧🇶\n' + + 'AOA | Angolan Kwanza | 🇦🇴\n' + + 'ARS | Peso argentino | 🇦🇷\n' + + 'AUD | Australian Dollar | 🇦🇺\n' + + 'AZN | Azerbaijani Manat | 🇦🇿\n' + + 'BDT | Bangladeshi Taka | 🇧🇩\n' + + 'BHD | Bahraini Dinar | 🇧🇭\n' + + 'BIF | Burundian Franc | 🇧🇮\n' + + 'BMD | Bermudan Dollar | 🇧🇲\n' + + 'BOB | Boliviano | 🇧🇴\n' + + 'BRL | Brazilian Real | 🇧🇷\n' + + 'BWP | Botswanan Pula | 🇧🇼\n' + + 'BYN | Belarusian Ruble | 🇧🇾\n' + + 'CAD | Canadian Dollar | 🇨🇦\n' + + 'CDF | Congolese Franc | 🇨🇩\n' + + 'CHF | Swiss Franc | 🇨🇭\n' + + 'CLP | Peso chileno | 🇨🇱\n' + + 'CNY | Chinese Yuan | 🇨🇳\n' + + 'COP | Peso colombiano | 🇨🇴\n' + + 'CRC | Colón | 🇨🇷\n' + + 'CUP | Peso cubano | 🇨🇺\n' + + 'CZK | Czech Republic Koruna | 🇨🇿\n' + + 'DJF | Djiboutian Franc | 🇩🇯\n' + + 'DKK | Danish Krone | 🇩🇰\n' + + 'DOP | Peso dominicano | 🇩🇴\n' + + 'DZD | Algerian Dinar | 🇩🇿\n' + + 'EGP | Egyptian Pound | 🇪🇬\n' + + 'ETB | Ethiopian Birr | 🇪🇹\n' + + 'EUR | Euro | 🇪🇺\n' + + 'GBP | British Pound Sterling | 🇬🇧\n' + + 'GEL | Georgian Lari | 🇬🇪\n' + + 'GHS | Ghanaian Cedi | 🇬🇭\n' + + 'GNF | Guinean Franc | 🇬🇳\n' + + 'GTQ | Quetzal | 🇬🇹\n' + + 'HKD | Hong Kong Dollar | 🇭🇰\n' + + 'HNL | Lempira | 🇭🇳\n' + + 'HUF | Hungarian Forint | 🇭🇺\n' + + 'IDR | Indonesian Rupiah | 🇮🇩\n' + + 'ILS | Israeli New Sheqel | 🇮🇱\n' + + 'INR | Indian Rupee | 🇮🇳\n' + + 'IRR | Iranian Rial | 🇮🇷\n' + + 'IRT | Iranian Tomen | 🇮🇷\n' + + 'JMD | Jamaican Dollar | 🇯🇲\n' + + 'JOD | Jordanian Dinar | 🇯🇴\n' + + 'JPY | Japanese Yen | 🇯🇵\n' + + 'KES | Kenyan Shilling | 🇰🇪\n' + + 'KGS | Kyrgystani Som | 🇰🇬\n' + + 'KRW | South Korean Won | 🇰🇷\n' + + 'KZT | Kazakhstani Tenge | 🇰🇿\n' + + 'LBP | Lebanese Pound | 🇱🇧\n' + + 'LKR | Sri Lankan Rupee | 🇱🇰\n' + + 'MAD | Moroccan Dirham | 🇲🇦\n' + + 'MGA | Malagasy Ariary | 🇲🇬\n' + + 'MLC | Moneda Libremente Convertible | 🇨🇺\n' + + 'MXN | Peso mexicano | 🇲🇽\n' + + 'MWK | Malawian Kwacha | 🇲🇼\n' + + 'MYR | Malaysian Ringgit | 🇲🇾\n' + + 'NAD | Namibian Dollar | 🇳🇦\n' + + 'NGN | Nigerian Naira | 🇳🇬\n' + + 'NIO | Nicaraguan Córdoba | 🇳🇮\n' + + 'NOK | Norwegian Krone | 🇳🇴\n' + + 'NPR | Nepalese Rupee | 🇳🇵\n' + + 'NZD | New Zealand Dollar | 🇳🇿\n' + + 'PAB | Panamanian Balboa | 🇵🇦\n' + + 'PEN | Peruvian Nuevo Sol | 🇵🇪\n' + + 'PHP | Philippine Peso | 🇵🇭\n' + + 'PKR | Pakistani Rupee | 🇵🇰\n' + + 'PLN | Polish Zloty | 🇵🇱\n' + + 'PYG | Paraguayan Guarani | 🇵🇾\n' + + 'QAR | Qatari Rial | 🇶🇦\n' + + 'RON | Romanian Leu | 🇷🇴\n' + + 'RSD | Serbian Dinar | 🇷🇸\n' + + 'RUB | руб | 🇷🇺\n' + + 'RWF | Rwandan Franc | 🇷🇼\n' + + 'SAR | Saudi Riyal | 🇸🇦\n' + + 'SEK | Swedish Krona | 🇸🇪\n' + + 'SGD | Singapore Dollar | 🇸🇬\n' + + 'THB | Thai Baht | 🇹🇭\n' + + 'TND | Tunisian Dinar | 🇹🇳\n' + + 'TRY | Turkish Lira | 🇹🇷\n' + + 'TTD | Trinidad and Tobago Dollar | 🇹🇹\n' + + 'TWD | New Taiwan Dollar | 🇹🇼\n' + + 'TZS | Tanzanian Shilling | 🇹🇿\n' + + 'UAH | Ukrainian Hryvnia | 🇺🇦\n' + + 'UGX | Ugandan Shilling | 🇺🇬\n' + + 'USD | US Dollar | 🇺🇸\n' + + 'USDSV | USD en El Salvador | 🇺🇸🇸🇻\n' + + 'USDVE | USD en Bs | 🇺🇸🇻🇪\n' + + 'USDUY | USD en Uruguay | 🇺🇸🇺🇾\n' + + 'UYU | Peso uruguayo | 🇺🇾\n' + + 'UZS | Uzbekistan Som | 🇺🇿\n' + + 'VES | Bolívar | 🇻🇪\n' + + 'VND | Vietnamese Dong | 🇻🇳\n' + + 'XAF | CFA Franc BEAC | 🇨🇲 🇨🇫 🇹🇩 🇬🇶 🇬🇦 🇨🇬\n' + + 'XOF | CFA Franc BCEAO | 🇧🇯 🇧🇫 🇨🇮 🇬🇼 🇲🇱 🇳🇪 🇸🇳 🇹🇬\n' + + 'ZAR | South African Rand | 🇿🇦\n' + }, + updateId: 2, + messageId: 2, + isRead: true + } + ] +}; + +module.exports = { + mockUpdatesResponseForCurrencies, +}; diff --git a/tests/bot/mocks/languagesResponse.js b/tests/bot/mocks/languagesResponse.js new file mode 100644 index 00000000..0e14b10f --- /dev/null +++ b/tests/bot/mocks/languagesResponse.js @@ -0,0 +1,33 @@ +const mockUpdatesResponseForLanguages = { + "ok": true, + "result": + [{ + "time": 1727274810291, + "botToken": "123456", + "message": { + "chat_id": 1, + "text": "Select language", + "reply_markup": + { + "inline_keyboard": + [ + [ + { + "text": "Русский 🇷🇺", + "callback_data": "setLanguage_ru" + }, + { + "text": "Українська 🇺🇦", + "callback_data": "setLanguage_uk" + } + ], + [ + { "text": "한글 🇰🇷", "callback_data": "setLanguage_ko" }, { "text": "Português 🇵🇹", "callback_data": "setLanguage_pt" }], [{ "text": "Français 🇫🇷", "callback_data": "setLanguage_fr" }, { "text": "Italiano 🇮🇹", "callback_data": "setLanguage_it" }], [{ "text": "Español 🇪🇸", "callback_data": "setLanguage_es" }, { "text": "فارسی 🇮🇷", "callback_data": "setLanguage_fa" }], [{ "text": "Deutsch 🇩🇪", "callback_data": "setLanguage_de" }, { "text": "English 🇬🇧", "callback_data": "setLanguage_en" }]] + } + }, "updateId": 2, "messageId": 2, "isRead": true + }] +}; + +module.exports = { + mockUpdatesResponseForLanguages, +}; \ No newline at end of file diff --git a/tests/bot/validation.spec.js b/tests/bot/validation.spec.js new file mode 100644 index 00000000..2c4f449a --- /dev/null +++ b/tests/bot/validation.spec.js @@ -0,0 +1,1114 @@ +const { expect } = require('chai'); +const sinon = require('sinon'); +const { ObjectId } = require('mongoose').Types; +const proxyquire = require('proxyquire'); + +const { + validateSellOrder, + validateBuyOrder, + validateInvoice, + isValidInvoice, + validateUser, + validateParams, + validateObjectId, + validateSuperAdmin, + validateAdmin, + validateTakeSellOrder, + validateUserWaitingOrder, + isBannedFromCommunity, +} = require('../../bot/validations'); +const messages = require('../../bot/messages'); +const { Order, User, Community } = require('../../models'); + +describe('Validations', () => { + let ctx; + let replyStub; + let sandbox; + let validations; + let existLightningAddressStub; + let isDisputeSolverStub; + let isOrderCreatorStub; + let bot, user, community; + + beforeEach(() => { + ctx = { + i18n: { + t: key => key, + locale: () => 'en', + }, + state: { + command: { + args: [], + }, + }, + update: { + callback_query: { + from: { + id: 1, + }, + }, + message: { + text: '', + from: { + id: 1, + }, + }, + }, + telegram: { + sendMessage: sinon.stub(), + }, + reply: () => { }, + botInfo: { + username: 'testbot', + }, + }; + + sandbox = sinon.createSandbox(); + // Mock process.env within the sandbox + sandbox.stub(process, 'env').value({ + MIN_PAYMENT_AMT: 100, + NODE_ENV: 'production', + INVOICE_EXPIRATION_WINDOW: 3600000, + }); + + replyStub = sinon.stub(ctx, 'reply'); + existLightningAddressStub = sinon.stub(); + isDisputeSolverStub = sinon.stub(); + isOrderCreatorStub = sinon.stub(); + validations = proxyquire('../../bot/validations', { + '../lnurl/lnurl-pay': { + existLightningAddress: existLightningAddressStub, + }, + '../util': { + isDisputeSolver: isDisputeSolverStub, + isOrderCreator: isOrderCreatorStub, + } + }); + bot = { + telegram: { + sendMessage: sinon.stub(), + }, + }; + user = { + _id: new ObjectId(), + tg_id: 12345, + }; + }); + + afterEach(() => { + sinon.restore(); + sandbox.restore(); + }); + + describe('validateSellOrder', () => { + it('should return false if args length is less than 4', async () => { + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.equal(true); + }); + + it('should return false if amount is not a number', async () => { + ctx.state.command.args = ['test', '100', 'USD', 'zelle']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.equal(true); + }); + + it('should return false if fiat amount is not a number', async () => { + ctx.state.command.args = ['10000', 'test', 'USD', 'zelle']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.equal(true); + }); + + it('should return false if fiat code is not valid, fiat code less than 3 characters', async () => { + ctx.state.command.args = ['10000', '100', 'US', 'zelle']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.equal(true); + }); + + it('should return false if fiat code is not valid, fiat code more than 5 characters', async () => { + ctx.state.command.args = ['10000', '100', 'USSDDD', 'zelle']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.equal(true); + }); + + it('should return false if amount is less than minimum', async () => { + ctx.state.command.args = ['1', '100', 'USD', 'zelle']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.equal(true); + }); + + it('should return object if validation success', async () => { + ctx.state.command.args = ['10000', '100', 'USD', 'zelle']; + const result = await validateSellOrder(ctx); + expect(result).to.be.an('object'); + }); + + it('should return object if validation success with price margin', async () => { + ctx.state.command.args = ['10000', '100', 'USD', 'zelle', '5']; + const result = await validateSellOrder(ctx); + expect(result).to.be.an('object'); + expect(result.priceMargin).to.equal('5'); + }); + + it('should return false if price margin is not a number', async () => { + ctx.state.command.args = ['10000', '100', 'USD', 'zelle', 'test']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.be.equal(true); + }); + + it('should work with ranges', async () => { + ctx.state.command.args = ['0', '100-200', 'USD', 'zelle', '5']; + const result = await validateSellOrder(ctx); + expect(result).to.be.an('object'); + expect(result.fiatAmount).to.deep.equal([100, 200]); + }); + + it('should fail with ranges with double dash', async () => { + ctx.state.command.args = ['0', '100--200', 'USD', 'zelle', '5']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + }); + + it('should fail with invalid ranges', async () => { + ctx.state.command.args = ['0', '200-100', 'USD', 'zelle', '5']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + }); + + it('should fail with ranges and amount', async () => { + ctx.state.command.args = ['1000', '100-200', 'USD', 'zelle', '5']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + }); + }); + + describe('validateBuyOrder', () => { + it('should return false if args length is less than 4', async () => { + const result = await validateBuyOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.be.equal(true); + }); + + it('should return false if amount is not a number', async () => { + ctx.state.command.args = ['test', '100', 'USD', 'zelle']; + const result = await validateBuyOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.be.equal(true); + }); + + it('should return false if fiat amount is not a number', async () => { + ctx.state.command.args = ['10000', 'test', 'USD', 'zelle']; + const result = await validateBuyOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.be.equal(true); + }); + + it('should return false if amount is less than minimum', async () => { + ctx.state.command.args = ['1', '100', 'USD', 'zelle']; + const result = await validateBuyOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.be.equal(true); + }); + + it('should return object if validation success', async () => { + ctx.state.command.args = ['10000', '100', 'USD', 'zelle']; + const result = await validateBuyOrder(ctx); + expect(result).to.be.an('object'); + }); + + it('should return object if validation success with price margin', async () => { + ctx.state.command.args = ['10000', '100', 'USD', 'zelle', '5']; + const result = await validateBuyOrder(ctx); + expect(result).to.be.an('object'); + expect(result.priceMargin).to.equal('5'); + }); + + it('should return false if price margin is not a number', async () => { + ctx.state.command.args = ['10000', '100', 'USD', 'zelle', 'test']; + const result = await validateBuyOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.be.equal(true); + }); + + it('should work with ranges', async () => { + ctx.state.command.args = ['0', '100-200', 'USD', 'zelle', '5']; + const result = await validateBuyOrder(ctx); + expect(result).to.be.an('object'); + expect(result.fiatAmount).to.deep.equal([100, 200]); + }); + + it('should fail with ranges with double dash', async () => { + ctx.state.command.args = ['0', '100--200', 'USD', 'zelle', '5']; + const result = await validateBuyOrder(ctx); + expect(result).to.equal(false); + }); + + it('should fail with invalid ranges', async () => { + ctx.state.command.args = ['0', '200-100', 'USD', 'zelle', '5']; + const result = await validateBuyOrder(ctx); + expect(result).to.equal(false); + }); + + it('should fail with ranges and amount', async () => { + ctx.state.command.args = ['1000', '100-200', 'USD', 'zelle', '5']; + const result = await validateBuyOrder(ctx); + expect(result).to.equal(false); + }); + }); + + describe('validateLightningAddress', () => { + it('should return true for a valid lightning address', async () => { + existLightningAddressStub.withArgs('test@ln.com').returns(true); + const result = await validations.validateLightningAddress('test@ln.com'); + expect(result).to.equal(true); + }); + + it('should return false for an invalid lightning address (existence)', async () => { + existLightningAddressStub.withArgs('test@invalid.com').returns(false); + const result = await validations.validateLightningAddress('test@invalid.com'); + expect(result).to.equal(false); + }); + }); + + describe('validateUser', () => { + it('should create a new user if it does not exist', async () => { + ctx.update.callback_query.from = { + username: 'testuser', + id: '1' + }; + + sinon.stub(User, 'findOne').resolves(null); + sinon.stub(User.prototype, 'save').resolves(); + const user = await validateUser(ctx, true); + expect(user.save.calledOnce).to.equal(true); + expect(user).to.be.an('object'); + expect(user.tg_id).to.be.equal(ctx.update.callback_query.from.id); + expect(user.username).to.be.equal(ctx.update.callback_query.from.username); + }); + + it('should return false if user does not exist and start is false', async () => { + const user = await validateUser(ctx, false); + expect(user).to.equal(false); + }); + + it('should return the user if it exists', async () => { + ctx.update.callback_query.from = { + username: 'testuser', + id: '1' + }; + const newUser = new User({ + tg_id: ctx.update.callback_query.from.id, + username: ctx.update.callback_query.from.username, + }); + + sinon.stub(User, 'findOne').resolves(newUser); + + const user = await validateUser(ctx, false); + expect(user).to.be.an('object'); + expect(user.tg_id).to.be.equal(newUser.tg_id); + expect(user.username).to.be.equal(newUser.username); + }); + + it('should update the username if it has changed', async () => { + ctx.update.callback_query.from = { + username: 'testuser-updated', + id: '1' + }; + const newUser = new User({ + tg_id: ctx.update.callback_query.from.id, + username: ctx.update.callback_query.from.username, + }); + + sinon.stub(User, 'findOne').resolves(newUser); + + const user = await validateUser(ctx, false); + expect(user).to.be.an('object'); + expect(user.tg_id).to.be.equal(newUser.tg_id); + expect(user.username).to.be.equal('testuser-updated'); + }); + + it('should return false if the user is banned', async () => { + ctx.update.callback_query.from = { + username: 'testuser', + id: '1' + }; + const newUser = new User({ + tg_id: ctx.update.callback_query.from.id, + username: ctx.update.callback_query.from.username, + banned: true, + }); + + sinon.stub(User, 'findOne').resolves(newUser); + + const user = await validateUser(ctx, false); + expect(user).to.equal(false); + }); + }); + + describe('validateSuperAdmin', () => { + it('should return the user if it is a superadmin', async () => { + ctx.update.callback_query.from = { + username: 'testuser', + id: '1' + }; + const newUser = new User({ + tg_id: ctx.update.callback_query.from.id, + username: ctx.update.callback_query.from.username, + admin: true, + }); + + sinon.stub(User, 'findOne').resolves(newUser); + + const user = await validateSuperAdmin(ctx); + expect(user).to.be.an('object'); + expect(user.tg_id).to.be.equal(newUser.tg_id); + expect(user.admin).to.equal(true); + }); + + it('should return false if the user is not a superadmin', async () => { + ctx.update.callback_query.from = { + username: 'testuser', + id: '1' + }; + const newUser = new User({ + tg_id: ctx.update.callback_query.from.id, + username: ctx.update.callback_query.from.username, + admin: false, + }); + + sinon.stub(User, 'findOne').resolves(newUser); + + const user = await validateSuperAdmin(ctx); + expect(user).to.equal(undefined); + }); + }); + + describe('validateAdmin', () => { + it('should return the user if it is an admin', async () => { + const newCommunity = new Community({ + name: 'testcommunity' + }); + const newUser = new User({ + tg_id: ctx.update.message.from.id, + username: ctx.update.message.from.username, + admin: true, + default_community_id: new ObjectId(newCommunity._id) + }); + + sinon.stub(User, 'findOne').resolves(newUser); + sinon.stub(Community, 'findOne').resolves(newCommunity); + isDisputeSolverStub.withArgs(newCommunity, newUser).returns(true); + const user = await validateAdmin(ctx); + expect(user).to.be.an('object'); + expect(user.tg_id).to.be.equal(newUser.tg_id); + expect(user.admin).to.equal(true); + }); + + it('should return undefined if the user is not exist', async () => { + sinon.stub(User, 'findOne').resolves(null); + + const user = await validateAdmin(ctx); + expect(user).to.equal(undefined); + }); + + it('should return undefined if the user is not dispute solver and it is not an admin', async () => { + const newCommunity = new Community({ + name: 'testcommunity' + }); + const newUser = new User({ + tg_id: ctx.update.message.from.id, + username: ctx.update.message.from.username, + admin: false, + default_community_id: new ObjectId(newCommunity._id) + }); + + sinon.stub(User, 'findOne').resolves(newUser); + sinon.stub(Community, 'findOne').resolves(newCommunity); + isDisputeSolverStub.withArgs(newCommunity, newUser).returns(false); + + const user = await validateAdmin(ctx); + expect(user).to.equal(undefined); + }); + }); + + describe('validateSellOrder', () => { + it('should return false if the amount is not a number', async () => { + ctx.state.command.args = ['test', '100', 'USD', 'zelle']; + const order = await validateSellOrder(ctx); + expect(order).to.equal(false); + }); + + it('should return false if the fiat amount is not a number', async () => { + ctx.state.command.args = ['10000', 'test', 'USD', 'zelle']; + const order = await validateSellOrder(ctx); + expect(order).to.equal(false); + }); + + it('should return false if the fiat code is not valid', async () => { + ctx.state.command.args = ['10000', '100', 'invalid', 'zelle']; + const order = await validateSellOrder(ctx); + expect(order).to.equal(false); + }); + + it('should return the order data if the order is valid', async () => { + ctx.state.command.args = ['10000', '100', 'USD', 'zelle']; + const order = await validateSellOrder(ctx); + expect(order).to.be.an('object'); + expect(order.amount).to.be.equal(10000); + expect(order.fiatAmount).to.be.an('array').to.deep.equal([100]); + expect(order.fiatCode).to.be.equal('USD'); + expect(order.paymentMethod).to.be.equal('zelle'); + }); + }); + + describe('validateBuyOrder', () => { + it('should return false if the amount is not a number', async () => { + ctx.state.command.args = ['test', '100', 'USD', 'zelle']; + const order = await validateBuyOrder(ctx); + expect(order).to.equal(false); + }); + + it('should return false if the fiat amount is not a number', async () => { + ctx.state.command.args = ['10000', 'test', 'USD', 'zelle']; + const order = await validateBuyOrder(ctx); + expect(order).to.equal(false); + }); + + it('should return false if the fiat code is not valid', async () => { + ctx.state.command.args = ['10000', '100', 'invalid', 'zelle']; + const order = await validateBuyOrder(ctx); + expect(order).to.equal(false); + }); + + it('should return the order data if the order is valid', async () => { + ctx.state.command.args = ['10000', '100', 'USD', 'zelle']; + const order = await validateBuyOrder(ctx); + expect(order).to.be.an('object'); + expect(order.amount).to.be.equal(10000); + expect(order.fiatAmount).to.be.an('array').to.deep.equal([100]); + expect(order.fiatCode).to.be.equal('USD'); + expect(order.paymentMethod).to.be.equal('zelle'); + }); + }); + + // TODO possible duplicated of isValidInvoice + describe('validateInvoice', () => { + // This test goes to the catch + it('should return false if the invoice is not valid', async () => { + const invoice = await validateInvoice(ctx, 'invalid-invoice'); + expect(invoice).to.equal(false); + }); + + it('should return false if the invoice amount is too low', async () => { + const minPaymentAmount = 10; + const resInvoice = { + network: 'bc', + destination: '03...', + id: '123', + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: '2023-03-15T12:14:48.000Z' + }; + const { validateInvoice } = proxyquire('../../bot/validations', { + 'invoices': { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'minimunAmountInvoiceMessage'); + + const invoice = await validateInvoice( + ctx, + lnInvoice + ); + + expect(messages.minimunAmountInvoiceMessage.calledOnce).to.equal(true); + expect(invoice).to.equal(false); + }); + + it('should return false if the invoice is expired with an expired date', async () => { + const minPaymentAmount = 2000; + const resInvoice = { + network: 'bc', + destination: '03...', + id: '123', + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: '2023-09-23T11:00:00.000Z' + }; + const { validateInvoice } = proxyquire('../../bot/validations', { + 'invoices': { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'minimunExpirationTimeInvoiceMessage'); + + const invoice = await validateInvoice( + ctx, + lnInvoice + ); + + expect(messages.minimunExpirationTimeInvoiceMessage.calledOnce).to.equal(true); + expect(invoice).to.equal(false); + }); + + it('should return false if the invoice is expired with is_expired true', async () => { + const minPaymentAmount = 2000; + const resInvoice = { + network: 'bc', + destination: '03...', + id: '123', + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: true, + expires_at: new Date(Date.now() + 86400000).toISOString() // One day after + }; + const { validateInvoice } = proxyquire('../../bot/validations', { + 'invoices': { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'expiredInvoiceMessage'); + + const invoice = await validateInvoice( + ctx, + lnInvoice + ); + + expect(messages.expiredInvoiceMessage.calledOnce).to.equal(true); + expect(invoice).to.equal(false); + }); + it('should return false if the invoice does not have a destination address', async () => { + const minPaymentAmount = 2000; + const resInvoice = { + network: 'bc', + // destination: '03...', Missed destination address + id: '123', + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: new Date(Date.now() + 86400000).toISOString() // One day after + }; + const { validateInvoice } = proxyquire('../../bot/validations', { + 'invoices': { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'requiredAddressInvoiceMessage'); + + const invoice = await validateInvoice( + ctx, + lnInvoice + ); + + expect(messages.requiredAddressInvoiceMessage.calledOnce).to.equal(true); + expect(invoice).to.equal(false); + }); + it('should return false if the invoice does not have an id', async () => { + const minPaymentAmount = 2000; + const resInvoice = { + network: 'bc', + destination: '03...', + // id: '123', Missed Id + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: new Date(Date.now() + 86400000).toISOString() // One day after + }; + const { validateInvoice } = proxyquire('../../bot/validations', { + 'invoices': { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'requiredHashInvoiceMessage'); + + const invoice = await validateInvoice( + ctx, + lnInvoice + ); + + expect(messages.requiredHashInvoiceMessage.calledOnce).to.equal(true); + expect(invoice).to.equal(false); + }); + it('should return the invoice if it is valid', async () => { + const resInvoice = { + network: 'bc', + destination: '03...', + id: '123', + tokens: 20000, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: new Date(Date.now() + 86400000).toISOString() // One day after + }; + const { validateInvoice } = proxyquire('../../bot/validations', { + 'invoices': { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = 'lnbc20m1p0t9k3gpp5kqum3c9qsp58yj2cp8gp5c9yqcnzen9s08jx2p4d7r97777g4qsq9qy9qsqgqqqqqqgqqqqqqgqjqdhnx9'; + + const invoice = await validateInvoice( + ctx, + lnInvoice + ); + expect(invoice).to.be.an('object'); + expect(invoice.network).to.be.equal('bc'); + expect(invoice.tokens).to.be.equal(20000); + }); + }); + + describe('isValidInvoice', () => { + // This goes to the catch + it('should return false if the invoice is not valid', async () => { + sinon.stub(messages, 'invoiceInvalidMessage'); + + const { success } = await isValidInvoice(ctx, 'invalid-invoice'); + expect(success).to.equal(false); + expect(messages.invoiceInvalidMessage.calledOnce).to.equal(true); + }); + + it('should return false if the invoice amount is too low', async () => { + const minPaymentAmount = 10; + const resInvoice = { + network: 'bc', + destination: '03...', + id: '123', + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: '2023-03-15T12:14:48.000Z' + }; + const { isValidInvoice } = proxyquire('../../bot/validations', { + 'invoices': { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'invoiceMustBeLargerMessage'); + + const { success } = await isValidInvoice( + ctx, + lnInvoice + ); + + expect(messages.invoiceMustBeLargerMessage.calledOnce).to.equal(true); + expect(success).to.equal(false); + }); + + it('should return false if the invoice is expired with an expired date', async () => { + const minPaymentAmount = 2000; + const resInvoice = { + network: 'bc', + destination: '03...', + id: '123', + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: '2023-09-23T11:00:00.000Z' + }; + const { isValidInvoice } = proxyquire('../../bot/validations', { + 'invoices': { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'invoiceExpiryTooShortMessage'); + + const { success } = await isValidInvoice( + ctx, + lnInvoice + ); + + expect(messages.invoiceExpiryTooShortMessage.calledOnce).to.equal(true); + expect(success).to.equal(false); + }); + + it('should return false if the invoice is expired with is_expired true', async () => { + const minPaymentAmount = 2000; + const resInvoice = { + network: 'bc', + destination: '03...', + id: '123', + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: true, + expires_at: new Date(Date.now() + 86400000).toISOString() // One day after + }; + const { isValidInvoice } = proxyquire('../../bot/validations', { + 'invoices': { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'invoiceHasExpiredMessage'); + + const { success } = await isValidInvoice( + ctx, + lnInvoice + ); + + expect(messages.invoiceHasExpiredMessage.calledOnce).to.equal(true); + expect(success).to.equal(false); + }); + it('should return false if the invoice does not have a destination address', async () => { + const minPaymentAmount = 2000; + const resInvoice = { + network: 'bc', + // destination: '03...', Missed destination address + id: '123', + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: new Date(Date.now() + 86400000).toISOString() // One day after + }; + const { isValidInvoice } = proxyquire('../../bot/validations', { + 'invoices': { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'invoiceHasWrongDestinationMessage'); + + const { success } = await isValidInvoice( + ctx, + lnInvoice + ); + + expect(messages.invoiceHasWrongDestinationMessage.calledOnce).to.equal(true); + expect(success).to.equal(false); + }); + it('should return false if the invoice does not have an id', async () => { + const minPaymentAmount = 2000; + const resInvoice = { + network: 'bc', + destination: '03...', + // id: '123', Missed Id + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: new Date(Date.now() + 86400000).toISOString() // One day after + }; + const { isValidInvoice } = proxyquire('../../bot/validations', { + 'invoices': { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'requiredHashInvoiceMessage'); + + const { success } = await isValidInvoice( + ctx, + lnInvoice + ); + + expect(messages.requiredHashInvoiceMessage.calledOnce).to.equal(true); + expect(success).to.equal(false); + }); + it('should return the invoice if it is valid', async () => { + const resInvoice = { + network: 'bc', + destination: '03...', + id: '123', + tokens: 20000, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: new Date(Date.now() + 86400000).toISOString() // One day after + }; + const { isValidInvoice } = proxyquire('../../bot/validations', { + 'invoices': { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = 'lnbc20m1p0t9k3gpp5kqum3c9qsp58yj2cp8gp5c9yqcnzen9s08jx2p4d7r97777g4qsq9qy9qsqgqqqqqqgqqqqqqgqjqdhnx9'; + + const { invoice } = await isValidInvoice( + ctx, + lnInvoice + ); + expect(invoice).to.be.an('object'); + expect(invoice.network).to.be.equal('bc'); + expect(invoice.tokens).to.be.equal(20000); + }); + }); + + describe('validateTakeSellOrder', () => { + it('should return false if the order does not exist', async () => { + const user = { _id: '1' }; + const order = null; + + sinon.stub(messages, 'invalidOrderMessage').resolves(); + + const isValid = await validateTakeSellOrder(ctx, {}, user, order); + + expect(messages.invalidOrderMessage.calledOnce).to.equal(true); + expect(isValid).to.equal(false); + }); + + it('should return false if the user is the order creator', async () => { + const user = { _id: '1' }; + const order = { + creator_id: '1', + type: 'sell', + status: 'PENDING', + }; + + sinon.stub(messages, 'cantTakeOwnOrderMessage').resolves(); + + const isValid = await validateTakeSellOrder(ctx, {}, user, order); + + expect(messages.cantTakeOwnOrderMessage.calledOnce).to.equal(true); + expect(isValid).to.equal(false); + }); + + it('should return false if the order type is not sell', async () => { + const user = { _id: '2' }; + const order = { + creator_id: '1', + type: 'buy', + status: 'PENDING', + }; + + sinon.stub(messages, 'invalidTypeOrderMessage').resolves(); + + const isValid = await validateTakeSellOrder(ctx, {}, user, order); + + expect(messages.invalidTypeOrderMessage.calledOnce).to.equal(true); + expect(isValid).to.equal(false); + }); + + it('should return false if the order status is not PENDING', async () => { + const user = { _id: '2' }; + const order = { + creator_id: '1', + type: 'sell', + status: 'ACTIVE', + }; + + sinon.stub(messages, 'alreadyTakenOrderMessage').resolves(); + + const isValid = await validateTakeSellOrder(ctx, {}, user, order); + + expect(messages.alreadyTakenOrderMessage.calledOnce).to.equal(true); + expect(isValid).to.equal(false); + }); + }); + + describe('validateParams', () => { + it('should return empty array if params length is not equal to paramNumber', async () => { + ctx.update.message.text = '/command param1 param2 param3'; + + sinon.stub(messages, 'customMessage').resolves(); + + const result = await validateParams(ctx, 3, 'errOutputString'); + expect(result).to.be.an('array').to.have.lengthOf(0); + expect(messages.customMessage.calledOnce).to.equal(true); + }); + + it('should return sliced array if params length is equal to paramNumber', async () => { + ctx.update.message.text = '/command param1 param2'; + const result = await validateParams(ctx, 3, 'errOutputString'); + expect(result).to.deep.equal(['param1', 'param2']); + expect(ctx.reply.notCalled).to.equal(true); + }); + }); + + describe('validateObjectId', () => { + it('should return true if id is valid', async () => { + const validId = new ObjectId(); + const result = await validateObjectId(ctx, validId.toString()); + expect(result).to.equal(true); + expect(ctx.reply.notCalled).to.equal(true); + }); + + it('should return false if id is invalid', async () => { + const invalidId = 'invalidId'; + const result = await validateObjectId(ctx, invalidId); + expect(result).to.equal(false); + expect(ctx.reply.calledOnce).to.equal(true); + }); + }); + + describe('validateUserWaitingOrder', () => { + beforeEach(() => { + sinon.stub(Order, 'find'); + }); + + afterEach(() => { + Order.find.restore(); + }); + + it('should return true if user has no waiting orders', async () => { + Order.find.returns([]); + const result = await validateUserWaitingOrder(ctx, bot, user); + expect(result).to.equal(true); + }); + + it('should return false and send message if user has a waiting sell order', async () => { + const order = { + _id: new ObjectId(), + seller_id: user._id, + status: 'WAITING_PAYMENT', + }; + Order.find.onCall(0).returns([order]); + Order.find.onCall(1).returns([]); + sinon.stub(messages, 'userCantTakeMoreThanOneWaitingOrderMessage').resolves(); + const result = await validateUserWaitingOrder(ctx, bot, user); + expect(result).to.equal(false); + expect( + messages.userCantTakeMoreThanOneWaitingOrderMessage.calledOnce + ).to.equal(true); + }); + + it('should return false and send message if user has a waiting buy order', async () => { + const order = { + _id: new ObjectId(), + buyer_id: user._id, + status: 'WAITING_BUYER_INVOICE', + }; + Order.find.onCall(0).returns([]); + Order.find.onCall(1).returns([order]); + sinon.stub(messages, 'userCantTakeMoreThanOneWaitingOrderMessage').resolves(); + const result = await validateUserWaitingOrder(ctx, bot, user); + expect(result).to.equal(false); + expect( + messages.userCantTakeMoreThanOneWaitingOrderMessage.calledOnce + ).to.equal(true); + }); + }); + + describe('isBannedFromCommunity', () => { + beforeEach(() => { + community = { + _id: new ObjectId(), + banned_users: [], + }; + sinon.stub(Community, 'findOne'); + }); + + afterEach(() => { + Community.findOne.restore(); + }); + + it('should return false if communityId is null', async () => { + const result = await isBannedFromCommunity(user, null); + expect(result).to.equal(false); + }); + + it('should return false if community is not found', async () => { + Community.findOne.returns(null); + const result = await isBannedFromCommunity(user, community._id); + expect(result).to.equal(false); + }); + + it('should return false if user is not banned', async () => { + Community.findOne.returns(community); + const result = await isBannedFromCommunity(user, community._id); + expect(result).to.equal(false); + }); + + it('should return true if user is banned', async () => { + const user = { _id: 'userId' }; + const communityId = 'communityId'; + community.banned_users = [{ id: 'userId', username: 'username' }]; + + Community.findOne.returns(community); + + const result = await isBannedFromCommunity(user, communityId); + expect(result).to.equal(true); + }); + }); +}); diff --git a/tests/bot_test.js b/tests/bot_test.js deleted file mode 100644 index 5a13934e..00000000 --- a/tests/bot_test.js +++ /dev/null @@ -1,145 +0,0 @@ -require('dotenv').config(); -const path = require('path'); -const fs = require('fs'); -const TelegramServer = require('telegram-test-api'); -const sinon = require('sinon'); -const { expect } = require('chai'); -const { initialize } = require('../bot'); -const { User, Order } = require('../models'); -const ordersActions = require('../bot/ordersActions'); -const testUser = require('./user'); -const testOrder = require('./order'); -const { getCurrenciesWithPrice } = require('../util'); -const { connect: mongoConnect } = require('../db_connect'); - -mongoConnect(); - -describe('Telegram bot test', () => { - const serverConfig = { port: 9001 }; - const token = '123456'; - let server; - beforeEach(() => { - server = new TelegramServer(serverConfig); - return server.start().then(() => { - // the options passed to Telegraf in this format will make it try to - // get messages from the server's local URL - const bot = initialize(token, { telegram: { apiRoot: server.ApiURL } }); - bot.startPolling(); - }); - }); - - afterEach(() => server.stop()); - - it('should start', async () => { - const client = server.getClient(token, { timeout: 5000 }); - const command = client.makeCommand('/start'); - const res = await client.sendCommand(command); - expect(res.ok).to.be.equal(true); - const updates = await client.getUpdates(); - expect(updates.ok).to.be.equal(true); - expect(updates.result.length).to.be.equal(1); - }); - - it('should return /sell help', async () => { - const client = server.getClient(token, { timeout: 5000 }); - // We spy on the User findOne called on ValidateUser() - const userStub = sinon.stub(User, 'findOne'); - // We spy on the Order findOne called on validateSeller() - const orderStub = sinon.stub(Order, 'findOne'); - // We make it to return our data - userStub.returns(testUser); - orderStub.returns(false); - const command = client.makeCommand('/sell help'); - const res = await client.sendCommand(command); - expect(res.ok).to.be.equal(true); - // const updates = await client.getUpdates(); - // We restore the stubs - userStub.restore(); - orderStub.restore(); - // expect(updates.ok).to.be.equal(true); - // TODO: we will check the message with the text from i18n - // expect(updates.result[0].message.text).to.be.equal("/sell \\<_monto en sats_\\> \\<_monto en fiat_\\> \\<_código fiat_\\> \\<_método de pago_\\> \\[_prima/descuento_\\]"); - }); - - it('should create a /sell', async () => { - const client = server.getClient(token, { timeout: 5000 }); - // We spy on the User findOne called on ValidateUser() - const userStub = sinon.stub(User, 'findOne'); - // We spy on the Order findOne called on validateSeller() - const orderStub = sinon.stub(Order, 'findOne'); - // We spy the createOrder call - const createOrderStub = sinon.stub(ordersActions, 'createOrder'); - // We make it to return our data - userStub.returns(testUser); - orderStub.returns(false); - createOrderStub.returns(testOrder); - const command = client.makeCommand('/sell 100 1 ves Pagomovil'); - const res = await client.sendCommand(command); - expect(res.ok).to.be.equal(true); - // const updates = await client.getUpdates(); - // We restore the stubs - userStub.restore(); - orderStub.restore(); - createOrderStub.restore(); - // expect(updates.ok).to.be.equal(true); - // expect(updates.result.length).to.be.equal(3); - // expect(updates.result[0].message.chat_id).to.be.equal(process.env.CHANNEL); - }); - - it('should return /buy help', async () => { - const client = server.getClient(token, { timeout: 5000 }); - // We spy on the User findOne called on ValidateUser() - const userStub = sinon.stub(User, 'findOne'); - // We spy on the Order findOne called on validateSeller() - const orderStub = sinon.stub(Order, 'findOne'); - // We make it to return our data - userStub.returns(testUser); - orderStub.returns(false); - const command = client.makeCommand('/buy help'); - const res = await client.sendCommand(command); - expect(res.ok).to.be.equal(true); - // const updates = await client.getUpdates(); - // We restore the stubs - userStub.restore(); - orderStub.restore(); - // expect(updates.ok).to.be.equal(true); - // TODO: we will check the message with the text from i18n - // expect(updates.result[0].message.text).to.be.equal("/buy \\<_monto en sats_\\> \\<_monto en fiat_\\> \\<_código fiat_\\> \\<_método de pago_\\> \\[_prima/descuento_\\]"); - }); - - it('should return the list of supported currencies', async () => { - const client = server.getClient(token, { timeout: 5000 }); - const userStub = sinon.stub(User, 'findOne'); - userStub.returns(testUser); - const command = client.makeCommand('/listcurrencies'); - const res = await client.sendCommand(command); - expect(res.ok).to.be.equal(true); - const updates = await client.getUpdates(); - userStub.restore(); - expect(updates.ok).to.be.equal(true); - expect( - (updates.result[0].message.text.match(/\n/g) || []).length - 1 - ).to.be.equal(getCurrenciesWithPrice().length); - }); - - it('should return flags of langs supported', async () => { - const client = server.getClient(token, { timeout: 5000 }); - const userStub = sinon.stub(User, 'findOne'); - userStub.returns(testUser); - const command = client.makeCommand('/setlang'); - const res = await client.sendCommand(command); - expect(res.ok).to.be.equal(true); - const updates = await client.getUpdates(); - userStub.restore(); - expect(updates.ok).to.be.equal(true); - let flags = 0; - updates.result[0].message.reply_markup.inline_keyboard.forEach(flag => { - flags += flag.length; - }); - let langs = 0; - fs.readdirSync(path.join(__dirname, '../locales')).forEach(file => { - langs++; - }); - expect(flags).to.be.equal(langs); - }); -}); diff --git a/tests/lightning_test.js b/tests/ln/lightning.spec.js similarity index 58% rename from tests/lightning_test.js rename to tests/ln/lightning.spec.js index 2ce2ffb5..1299805c 100644 --- a/tests/lightning_test.js +++ b/tests/ln/lightning.spec.js @@ -2,22 +2,22 @@ const sinon = require('sinon'); const { expect } = require('chai'); const lightning = require('lightning'); const { parsePaymentRequest } = require('invoices'); -const { createHodlInvoiceResponse } = require('./lightningResponse'); -const { createHoldInvoice } = require('../ln'); +const { mockCreateHodlResponseForLightning } = require('./mocks/lightningResponse'); +const { createHoldInvoice } = require('../../ln'); -describe('Testing lighting network', () => { +describe('Lighting network', () => { it('Should create hold invoice', async () => { // We spy on the lighting service call const stub = sinon.stub(lightning, 'createHodlInvoice'); // Then we test our internal lightning call - stub.returns(createHodlInvoiceResponse); + stub.returns(mockCreateHodlResponseForLightning); const { hash, request } = await createHoldInvoice({ description: 'Holis', amount: 200, }); const invoice = parsePaymentRequest({ request }); - expect(hash).to.be.equal(createHodlInvoiceResponse.id); - expect(invoice.tokens).to.be.equal(createHodlInvoiceResponse.tokens); + expect(hash).to.be.equal(mockCreateHodlResponseForLightning.id); + expect(invoice.tokens).to.be.equal(mockCreateHodlResponseForLightning.tokens); }); }); diff --git a/tests/lightningResponse.js b/tests/ln/mocks/lightningResponse.js similarity index 87% rename from tests/lightningResponse.js rename to tests/ln/mocks/lightningResponse.js index e9f0db5e..98d2c20f 100644 --- a/tests/lightningResponse.js +++ b/tests/ln/mocks/lightningResponse.js @@ -1,4 +1,4 @@ -const createHodlInvoiceResponse = { +const mockCreateHodlResponseForLightning = { chain_address: undefined, created_at: '2021-08-09T17:32:02.000Z', description: 'Venta por @P2PLNBot', @@ -11,5 +11,5 @@ const createHodlInvoiceResponse = { }; module.exports = { - createHodlInvoiceResponse, + mockCreateHodlResponseForLightning, }; diff --git a/tests/order.js b/tests/order.js deleted file mode 100644 index 1970bef0..00000000 --- a/tests/order.js +++ /dev/null @@ -1,28 +0,0 @@ -const order = { - buyer_dispute: false, - seller_dispute: false, - buyer_cooperativecancel: false, - seller_cooperativecancel: false, - _id: '612d451148df8353e387eeff', - description: - 'Vendiendo 111 sats\n' + - 'Por ves 111\n' + - 'Pago por Pagomovil\n' + - 'Tiene 7 operaciones exitosas', - amount: 111, - fee: 0.111, - creator_id: '61006f0e85ad4f96cde94141', - seller_id: '61006f0e85ad4f96cde94141', - type: 'sell', - status: 'PENDING', - fiat_amount: 111, - fiat_code: 'ves', - payment_method: 'Pagomovil', - tg_chat_id: '1', - tg_order_message: '1', - created_at: '2021-08-30T20:52:33.870Z', -}; - -order.save = () => 'saved'; - -module.exports = order; diff --git a/tests/user.js b/tests/user.js deleted file mode 100644 index 0c6fef0d..00000000 --- a/tests/user.js +++ /dev/null @@ -1,16 +0,0 @@ -const user = { - lang: 'ESP', - trades_completed: 7, - admin: false, - banned: false, - disputes: 0, - _id: '61006f0e85ad4f96cde94141', - balance: 0, - tg_id: '1', - username: 'negrunch', - created_at: '2021-07-27T20:39:42.403Z', -}; - -user.save = () => {}; - -module.exports = user; diff --git a/util/index.ts b/util/index.ts index 902d9e4c..7ca1bef5 100644 --- a/util/index.ts +++ b/util/index.ts @@ -31,6 +31,15 @@ const isIso4217 = (code: string): boolean => { }); }; +const isOrderCreator = (user: UserDocument, order: IOrder) => { + try { + return user._id == order.creator_id; + } catch (error) { + logger.error(error); + return false; + } +}; + const getCurrency = (code: string): (IFiat | null) => { if (!isIso4217(code)) return null; const currency = currencies[code]; @@ -545,5 +554,6 @@ export { holdInvoiceExpirationInSecs, getUserAge, getTimeToExpirationOrder, - toKebabCase + toKebabCase, + isOrderCreator }; From 73827fb50102247cea022382911ad6d0b9ac2dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Calder=C3=B3n?= Date: Fri, 18 Oct 2024 16:03:06 -0300 Subject: [PATCH 8/9] Avoid showing catch output (#598) Remove debug logs on validations --- bot/validations.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bot/validations.ts b/bot/validations.ts index 1fedbbea..7d434bbb 100644 --- a/bot/validations.ts +++ b/bot/validations.ts @@ -336,7 +336,12 @@ const validateLightningAddress = async (lightningAddress: string) => { const validateInvoice = async (ctx: MainContext, lnInvoice: string) => { try { const checkedPrefixlnInvoice = removeLightningPrefix(lnInvoice); - const invoice = parsePaymentRequest({ request: checkedPrefixlnInvoice }); + let invoice; + try { + invoice = parsePaymentRequest({ request: checkedPrefixlnInvoice }); + } catch (error) { + return false; + } const latestDate = new Date( Date.now() + Number(process.env.INVOICE_EXPIRATION_WINDOW) ); @@ -389,9 +394,6 @@ const isValidInvoice = async (ctx: MainContext, lnInvoice: string) => { } if (new Date(invoice.expires_at) < latestDate) { - console.debug(`Date(invoice.expires_at) = ${new Date(invoice.expires_at)}`); - console.debug(`latestDate = ${latestDate}`); - console.debug(`INVOICE_EXPIRATION_WINDOW = ${Number(process.env.INVOICE_EXPIRATION_WINDOW)}`); await messages.invoiceExpiryTooShortMessage(ctx); return { success: false, From 5672c6fdc76fe129ef307d1d8b34c8129ecafab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Calder=C3=B3n?= Date: Fri, 18 Oct 2024 16:19:34 -0300 Subject: [PATCH 9/9] Fix lint formatting (#599) --- tests/bot/validation.spec.js | 2180 +++++++++++++++++----------------- 1 file changed, 1084 insertions(+), 1096 deletions(-) diff --git a/tests/bot/validation.spec.js b/tests/bot/validation.spec.js index 2c4f449a..d073b255 100644 --- a/tests/bot/validation.spec.js +++ b/tests/bot/validation.spec.js @@ -4,1111 +4,1099 @@ const { ObjectId } = require('mongoose').Types; const proxyquire = require('proxyquire'); const { - validateSellOrder, - validateBuyOrder, - validateInvoice, - isValidInvoice, - validateUser, - validateParams, - validateObjectId, - validateSuperAdmin, - validateAdmin, - validateTakeSellOrder, - validateUserWaitingOrder, - isBannedFromCommunity, + validateSellOrder, + validateBuyOrder, + validateInvoice, + isValidInvoice, + validateUser, + validateParams, + validateObjectId, + validateSuperAdmin, + validateAdmin, + validateTakeSellOrder, + validateUserWaitingOrder, + isBannedFromCommunity, } = require('../../bot/validations'); const messages = require('../../bot/messages'); const { Order, User, Community } = require('../../models'); describe('Validations', () => { - let ctx; - let replyStub; - let sandbox; - let validations; - let existLightningAddressStub; - let isDisputeSolverStub; - let isOrderCreatorStub; - let bot, user, community; + let ctx; + let replyStub; + let sandbox; + let validations; + let existLightningAddressStub; + let isDisputeSolverStub; + let isOrderCreatorStub; + let bot, user, community; + + beforeEach(() => { + ctx = { + i18n: { + t: key => key, + locale: () => 'en', + }, + state: { + command: { + args: [], + }, + }, + update: { + callback_query: { + from: { + id: 1, + }, + }, + message: { + text: '', + from: { + id: 1, + }, + }, + }, + telegram: { + sendMessage: sinon.stub(), + }, + reply: () => {}, + botInfo: { + username: 'testbot', + }, + }; + + sandbox = sinon.createSandbox(); + // Mock process.env within the sandbox + sandbox.stub(process, 'env').value({ + MIN_PAYMENT_AMT: 100, + NODE_ENV: 'production', + INVOICE_EXPIRATION_WINDOW: 3600000, + }); + + replyStub = sinon.stub(ctx, 'reply'); + existLightningAddressStub = sinon.stub(); + isDisputeSolverStub = sinon.stub(); + isOrderCreatorStub = sinon.stub(); + validations = proxyquire('../../bot/validations', { + '../lnurl/lnurl-pay': { + existLightningAddress: existLightningAddressStub, + }, + '../util': { + isDisputeSolver: isDisputeSolverStub, + isOrderCreator: isOrderCreatorStub, + }, + }); + bot = { + telegram: { + sendMessage: sinon.stub(), + }, + }; + user = { + _id: new ObjectId(), + tg_id: 12345, + }; + }); + + afterEach(() => { + sinon.restore(); + sandbox.restore(); + }); + + describe('validateSellOrder', () => { + it('should return false if args length is less than 4', async () => { + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.equal(true); + }); + + it('should return false if amount is not a number', async () => { + ctx.state.command.args = ['test', '100', 'USD', 'zelle']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.equal(true); + }); + it('should return false if fiat amount is not a number', async () => { + ctx.state.command.args = ['10000', 'test', 'USD', 'zelle']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.equal(true); + }); + + it('should return false if fiat code is not valid, fiat code less than 3 characters', async () => { + ctx.state.command.args = ['10000', '100', 'US', 'zelle']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.equal(true); + }); + + it('should return false if fiat code is not valid, fiat code more than 5 characters', async () => { + ctx.state.command.args = ['10000', '100', 'USSDDD', 'zelle']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.equal(true); + }); + + it('should return false if amount is less than minimum', async () => { + ctx.state.command.args = ['1', '100', 'USD', 'zelle']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.equal(true); + }); + + it('should return object if validation success', async () => { + ctx.state.command.args = ['10000', '100', 'USD', 'zelle']; + const result = await validateSellOrder(ctx); + expect(result).to.be.an('object'); + }); + + it('should return object if validation success with price margin', async () => { + ctx.state.command.args = ['10000', '100', 'USD', 'zelle', '5']; + const result = await validateSellOrder(ctx); + expect(result).to.be.an('object'); + expect(result.priceMargin).to.equal('5'); + }); + + it('should return false if price margin is not a number', async () => { + ctx.state.command.args = ['10000', '100', 'USD', 'zelle', 'test']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.be.equal(true); + }); + + it('should work with ranges', async () => { + ctx.state.command.args = ['0', '100-200', 'USD', 'zelle', '5']; + const result = await validateSellOrder(ctx); + expect(result).to.be.an('object'); + expect(result.fiatAmount).to.deep.equal([100, 200]); + }); + + it('should fail with ranges with double dash', async () => { + ctx.state.command.args = ['0', '100--200', 'USD', 'zelle', '5']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + }); + + it('should fail with invalid ranges', async () => { + ctx.state.command.args = ['0', '200-100', 'USD', 'zelle', '5']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + }); + + it('should fail with ranges and amount', async () => { + ctx.state.command.args = ['1000', '100-200', 'USD', 'zelle', '5']; + const result = await validateSellOrder(ctx); + expect(result).to.equal(false); + }); + }); + + describe('validateBuyOrder', () => { + it('should return false if args length is less than 4', async () => { + const result = await validateBuyOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.be.equal(true); + }); + + it('should return false if amount is not a number', async () => { + ctx.state.command.args = ['test', '100', 'USD', 'zelle']; + const result = await validateBuyOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.be.equal(true); + }); + + it('should return false if fiat amount is not a number', async () => { + ctx.state.command.args = ['10000', 'test', 'USD', 'zelle']; + const result = await validateBuyOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.be.equal(true); + }); + + it('should return false if amount is less than minimum', async () => { + ctx.state.command.args = ['1', '100', 'USD', 'zelle']; + const result = await validateBuyOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.be.equal(true); + }); + + it('should return object if validation success', async () => { + ctx.state.command.args = ['10000', '100', 'USD', 'zelle']; + const result = await validateBuyOrder(ctx); + expect(result).to.be.an('object'); + }); + + it('should return object if validation success with price margin', async () => { + ctx.state.command.args = ['10000', '100', 'USD', 'zelle', '5']; + const result = await validateBuyOrder(ctx); + expect(result).to.be.an('object'); + expect(result.priceMargin).to.equal('5'); + }); + + it('should return false if price margin is not a number', async () => { + ctx.state.command.args = ['10000', '100', 'USD', 'zelle', 'test']; + const result = await validateBuyOrder(ctx); + expect(result).to.equal(false); + expect(replyStub.calledOnce).to.be.equal(true); + }); + + it('should work with ranges', async () => { + ctx.state.command.args = ['0', '100-200', 'USD', 'zelle', '5']; + const result = await validateBuyOrder(ctx); + expect(result).to.be.an('object'); + expect(result.fiatAmount).to.deep.equal([100, 200]); + }); + + it('should fail with ranges with double dash', async () => { + ctx.state.command.args = ['0', '100--200', 'USD', 'zelle', '5']; + const result = await validateBuyOrder(ctx); + expect(result).to.equal(false); + }); + + it('should fail with invalid ranges', async () => { + ctx.state.command.args = ['0', '200-100', 'USD', 'zelle', '5']; + const result = await validateBuyOrder(ctx); + expect(result).to.equal(false); + }); + + it('should fail with ranges and amount', async () => { + ctx.state.command.args = ['1000', '100-200', 'USD', 'zelle', '5']; + const result = await validateBuyOrder(ctx); + expect(result).to.equal(false); + }); + }); + + describe('validateLightningAddress', () => { + it('should return true for a valid lightning address', async () => { + existLightningAddressStub.withArgs('test@ln.com').returns(true); + const result = await validations.validateLightningAddress('test@ln.com'); + expect(result).to.equal(true); + }); + + it('should return false for an invalid lightning address (existence)', async () => { + existLightningAddressStub.withArgs('test@invalid.com').returns(false); + const result = await validations.validateLightningAddress( + 'test@invalid.com' + ); + expect(result).to.equal(false); + }); + }); + + describe('validateUser', () => { + it('should create a new user if it does not exist', async () => { + ctx.update.callback_query.from = { + username: 'testuser', + id: '1', + }; + + sinon.stub(User, 'findOne').resolves(null); + sinon.stub(User.prototype, 'save').resolves(); + const user = await validateUser(ctx, true); + expect(user.save.calledOnce).to.equal(true); + expect(user).to.be.an('object'); + expect(user.tg_id).to.be.equal(ctx.update.callback_query.from.id); + expect(user.username).to.be.equal( + ctx.update.callback_query.from.username + ); + }); + + it('should return false if user does not exist and start is false', async () => { + const user = await validateUser(ctx, false); + expect(user).to.equal(false); + }); + + it('should return the user if it exists', async () => { + ctx.update.callback_query.from = { + username: 'testuser', + id: '1', + }; + const newUser = new User({ + tg_id: ctx.update.callback_query.from.id, + username: ctx.update.callback_query.from.username, + }); + + sinon.stub(User, 'findOne').resolves(newUser); + + const user = await validateUser(ctx, false); + expect(user).to.be.an('object'); + expect(user.tg_id).to.be.equal(newUser.tg_id); + expect(user.username).to.be.equal(newUser.username); + }); + + it('should update the username if it has changed', async () => { + ctx.update.callback_query.from = { + username: 'testuser-updated', + id: '1', + }; + const newUser = new User({ + tg_id: ctx.update.callback_query.from.id, + username: ctx.update.callback_query.from.username, + }); + + sinon.stub(User, 'findOne').resolves(newUser); + + const user = await validateUser(ctx, false); + expect(user).to.be.an('object'); + expect(user.tg_id).to.be.equal(newUser.tg_id); + expect(user.username).to.be.equal('testuser-updated'); + }); + + it('should return false if the user is banned', async () => { + ctx.update.callback_query.from = { + username: 'testuser', + id: '1', + }; + const newUser = new User({ + tg_id: ctx.update.callback_query.from.id, + username: ctx.update.callback_query.from.username, + banned: true, + }); + + sinon.stub(User, 'findOne').resolves(newUser); + + const user = await validateUser(ctx, false); + expect(user).to.equal(false); + }); + }); + + describe('validateSuperAdmin', () => { + it('should return the user if it is a superadmin', async () => { + ctx.update.callback_query.from = { + username: 'testuser', + id: '1', + }; + const newUser = new User({ + tg_id: ctx.update.callback_query.from.id, + username: ctx.update.callback_query.from.username, + admin: true, + }); + + sinon.stub(User, 'findOne').resolves(newUser); + + const user = await validateSuperAdmin(ctx); + expect(user).to.be.an('object'); + expect(user.tg_id).to.be.equal(newUser.tg_id); + expect(user.admin).to.equal(true); + }); + + it('should return false if the user is not a superadmin', async () => { + ctx.update.callback_query.from = { + username: 'testuser', + id: '1', + }; + const newUser = new User({ + tg_id: ctx.update.callback_query.from.id, + username: ctx.update.callback_query.from.username, + admin: false, + }); + + sinon.stub(User, 'findOne').resolves(newUser); + + const user = await validateSuperAdmin(ctx); + expect(user).to.equal(undefined); + }); + }); + + describe('validateAdmin', () => { + it('should return the user if it is an admin', async () => { + const newCommunity = new Community({ + name: 'testcommunity', + }); + const newUser = new User({ + tg_id: ctx.update.message.from.id, + username: ctx.update.message.from.username, + admin: true, + default_community_id: new ObjectId(newCommunity._id), + }); + + sinon.stub(User, 'findOne').resolves(newUser); + sinon.stub(Community, 'findOne').resolves(newCommunity); + isDisputeSolverStub.withArgs(newCommunity, newUser).returns(true); + const user = await validateAdmin(ctx); + expect(user).to.be.an('object'); + expect(user.tg_id).to.be.equal(newUser.tg_id); + expect(user.admin).to.equal(true); + }); + + it('should return undefined if the user is not exist', async () => { + sinon.stub(User, 'findOne').resolves(null); + + const user = await validateAdmin(ctx); + expect(user).to.equal(undefined); + }); + + it('should return undefined if the user is not dispute solver and it is not an admin', async () => { + const newCommunity = new Community({ + name: 'testcommunity', + }); + const newUser = new User({ + tg_id: ctx.update.message.from.id, + username: ctx.update.message.from.username, + admin: false, + default_community_id: new ObjectId(newCommunity._id), + }); + + sinon.stub(User, 'findOne').resolves(newUser); + sinon.stub(Community, 'findOne').resolves(newCommunity); + isDisputeSolverStub.withArgs(newCommunity, newUser).returns(false); + + const user = await validateAdmin(ctx); + expect(user).to.equal(undefined); + }); + }); + + describe('validateSellOrder', () => { + it('should return false if the amount is not a number', async () => { + ctx.state.command.args = ['test', '100', 'USD', 'zelle']; + const order = await validateSellOrder(ctx); + expect(order).to.equal(false); + }); + + it('should return false if the fiat amount is not a number', async () => { + ctx.state.command.args = ['10000', 'test', 'USD', 'zelle']; + const order = await validateSellOrder(ctx); + expect(order).to.equal(false); + }); + + it('should return false if the fiat code is not valid', async () => { + ctx.state.command.args = ['10000', '100', 'invalid', 'zelle']; + const order = await validateSellOrder(ctx); + expect(order).to.equal(false); + }); + + it('should return the order data if the order is valid', async () => { + ctx.state.command.args = ['10000', '100', 'USD', 'zelle']; + const order = await validateSellOrder(ctx); + expect(order).to.be.an('object'); + expect(order.amount).to.be.equal(10000); + expect(order.fiatAmount).to.be.an('array').to.deep.equal([100]); + expect(order.fiatCode).to.be.equal('USD'); + expect(order.paymentMethod).to.be.equal('zelle'); + }); + }); + + describe('validateBuyOrder', () => { + it('should return false if the amount is not a number', async () => { + ctx.state.command.args = ['test', '100', 'USD', 'zelle']; + const order = await validateBuyOrder(ctx); + expect(order).to.equal(false); + }); + + it('should return false if the fiat amount is not a number', async () => { + ctx.state.command.args = ['10000', 'test', 'USD', 'zelle']; + const order = await validateBuyOrder(ctx); + expect(order).to.equal(false); + }); + + it('should return false if the fiat code is not valid', async () => { + ctx.state.command.args = ['10000', '100', 'invalid', 'zelle']; + const order = await validateBuyOrder(ctx); + expect(order).to.equal(false); + }); + + it('should return the order data if the order is valid', async () => { + ctx.state.command.args = ['10000', '100', 'USD', 'zelle']; + const order = await validateBuyOrder(ctx); + expect(order).to.be.an('object'); + expect(order.amount).to.be.equal(10000); + expect(order.fiatAmount).to.be.an('array').to.deep.equal([100]); + expect(order.fiatCode).to.be.equal('USD'); + expect(order.paymentMethod).to.be.equal('zelle'); + }); + }); + + // TODO possible duplicated of isValidInvoice + describe('validateInvoice', () => { + // This test goes to the catch + it('should return false if the invoice is not valid', async () => { + const invoice = await validateInvoice(ctx, 'invalid-invoice'); + expect(invoice).to.equal(false); + }); + + it('should return false if the invoice amount is too low', async () => { + const minPaymentAmount = 10; + const resInvoice = { + network: 'bc', + destination: '03...', + id: '123', + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: '2023-03-15T12:14:48.000Z', + }; + const { validateInvoice } = proxyquire('../../bot/validations', { + invoices: { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = + 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'minimunAmountInvoiceMessage'); + + const invoice = await validateInvoice(ctx, lnInvoice); + + expect(messages.minimunAmountInvoiceMessage.calledOnce).to.equal(true); + expect(invoice).to.equal(false); + }); + + it('should return false if the invoice is expired with an expired date', async () => { + const minPaymentAmount = 2000; + const resInvoice = { + network: 'bc', + destination: '03...', + id: '123', + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: '2023-09-23T11:00:00.000Z', + }; + const { validateInvoice } = proxyquire('../../bot/validations', { + invoices: { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = + 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'minimunExpirationTimeInvoiceMessage'); + + const invoice = await validateInvoice(ctx, lnInvoice); + + expect(messages.minimunExpirationTimeInvoiceMessage.calledOnce).to.equal( + true + ); + expect(invoice).to.equal(false); + }); + + it('should return false if the invoice is expired with is_expired true', async () => { + const minPaymentAmount = 2000; + const resInvoice = { + network: 'bc', + destination: '03...', + id: '123', + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: true, + expires_at: new Date(Date.now() + 86400000).toISOString(), // One day after + }; + const { validateInvoice } = proxyquire('../../bot/validations', { + invoices: { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = + 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'expiredInvoiceMessage'); + + const invoice = await validateInvoice(ctx, lnInvoice); + + expect(messages.expiredInvoiceMessage.calledOnce).to.equal(true); + expect(invoice).to.equal(false); + }); + it('should return false if the invoice does not have a destination address', async () => { + const minPaymentAmount = 2000; + const resInvoice = { + network: 'bc', + // destination: '03...', Missed destination address + id: '123', + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: new Date(Date.now() + 86400000).toISOString(), // One day after + }; + const { validateInvoice } = proxyquire('../../bot/validations', { + invoices: { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = + 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'requiredAddressInvoiceMessage'); + + const invoice = await validateInvoice(ctx, lnInvoice); + + expect(messages.requiredAddressInvoiceMessage.calledOnce).to.equal(true); + expect(invoice).to.equal(false); + }); + it('should return false if the invoice does not have an id', async () => { + const minPaymentAmount = 2000; + const resInvoice = { + network: 'bc', + destination: '03...', + // id: '123', Missed Id + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: new Date(Date.now() + 86400000).toISOString(), // One day after + }; + const { validateInvoice } = proxyquire('../../bot/validations', { + invoices: { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = + 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'requiredHashInvoiceMessage'); + + const invoice = await validateInvoice(ctx, lnInvoice); + + expect(messages.requiredHashInvoiceMessage.calledOnce).to.equal(true); + expect(invoice).to.equal(false); + }); + it('should return the invoice if it is valid', async () => { + const resInvoice = { + network: 'bc', + destination: '03...', + id: '123', + tokens: 20000, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: new Date(Date.now() + 86400000).toISOString(), // One day after + }; + const { validateInvoice } = proxyquire('../../bot/validations', { + invoices: { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = + 'lnbc20m1p0t9k3gpp5kqum3c9qsp58yj2cp8gp5c9yqcnzen9s08jx2p4d7r97777g4qsq9qy9qsqgqqqqqqgqqqqqqgqjqdhnx9'; + + const invoice = await validateInvoice(ctx, lnInvoice); + expect(invoice).to.be.an('object'); + expect(invoice.network).to.be.equal('bc'); + expect(invoice.tokens).to.be.equal(20000); + }); + }); + + describe('isValidInvoice', () => { + // This goes to the catch + it('should return false if the invoice is not valid', async () => { + sinon.stub(messages, 'invoiceInvalidMessage'); + + const { success } = await isValidInvoice(ctx, 'invalid-invoice'); + expect(success).to.equal(false); + expect(messages.invoiceInvalidMessage.calledOnce).to.equal(true); + }); + + it('should return false if the invoice amount is too low', async () => { + const minPaymentAmount = 10; + const resInvoice = { + network: 'bc', + destination: '03...', + id: '123', + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: '2023-03-15T12:14:48.000Z', + }; + const { isValidInvoice } = proxyquire('../../bot/validations', { + invoices: { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = + 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'invoiceMustBeLargerMessage'); + + const { success } = await isValidInvoice(ctx, lnInvoice); + + expect(messages.invoiceMustBeLargerMessage.calledOnce).to.equal(true); + expect(success).to.equal(false); + }); + + it('should return false if the invoice is expired with an expired date', async () => { + const minPaymentAmount = 2000; + const resInvoice = { + network: 'bc', + destination: '03...', + id: '123', + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: '2023-09-23T11:00:00.000Z', + }; + const { isValidInvoice } = proxyquire('../../bot/validations', { + invoices: { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = + 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'invoiceExpiryTooShortMessage'); + + const { success } = await isValidInvoice(ctx, lnInvoice); + + expect(messages.invoiceExpiryTooShortMessage.calledOnce).to.equal(true); + expect(success).to.equal(false); + }); + + it('should return false if the invoice is expired with is_expired true', async () => { + const minPaymentAmount = 2000; + const resInvoice = { + network: 'bc', + destination: '03...', + id: '123', + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: true, + expires_at: new Date(Date.now() + 86400000).toISOString(), // One day after + }; + const { isValidInvoice } = proxyquire('../../bot/validations', { + invoices: { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = + 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'invoiceHasExpiredMessage'); + + const { success } = await isValidInvoice(ctx, lnInvoice); + + expect(messages.invoiceHasExpiredMessage.calledOnce).to.equal(true); + expect(success).to.equal(false); + }); + it('should return false if the invoice does not have a destination address', async () => { + const minPaymentAmount = 2000; + const resInvoice = { + network: 'bc', + // destination: '03...', Missed destination address + id: '123', + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: new Date(Date.now() + 86400000).toISOString(), // One day after + }; + const { isValidInvoice } = proxyquire('../../bot/validations', { + invoices: { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = + 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'invoiceHasWrongDestinationMessage'); + + const { success } = await isValidInvoice(ctx, lnInvoice); + + expect(messages.invoiceHasWrongDestinationMessage.calledOnce).to.equal( + true + ); + expect(success).to.equal(false); + }); + it('should return false if the invoice does not have an id', async () => { + const minPaymentAmount = 2000; + const resInvoice = { + network: 'bc', + destination: '03...', + // id: '123', Missed Id + tokens: minPaymentAmount, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: new Date(Date.now() + 86400000).toISOString(), // One day after + }; + const { isValidInvoice } = proxyquire('../../bot/validations', { + invoices: { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = + 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; + + sinon.stub(messages, 'requiredHashInvoiceMessage'); + + const { success } = await isValidInvoice(ctx, lnInvoice); + + expect(messages.requiredHashInvoiceMessage.calledOnce).to.equal(true); + expect(success).to.equal(false); + }); + it('should return the invoice if it is valid', async () => { + const resInvoice = { + network: 'bc', + destination: '03...', + id: '123', + tokens: 20000, + description: '', + expiry: 3600, + timestamp: 1678888888, + features: {}, + routes: [], + cltv_expiry: 9, + is_expired: false, + expires_at: new Date(Date.now() + 86400000).toISOString(), // One day after + }; + const { isValidInvoice } = proxyquire('../../bot/validations', { + invoices: { + parsePaymentRequest: sinon.stub().returns(resInvoice), + }, + }); + + const lnInvoice = + 'lnbc20m1p0t9k3gpp5kqum3c9qsp58yj2cp8gp5c9yqcnzen9s08jx2p4d7r97777g4qsq9qy9qsqgqqqqqqgqqqqqqgqjqdhnx9'; + + const { invoice } = await isValidInvoice(ctx, lnInvoice); + expect(invoice).to.be.an('object'); + expect(invoice.network).to.be.equal('bc'); + expect(invoice.tokens).to.be.equal(20000); + }); + }); + + describe('validateTakeSellOrder', () => { + it('should return false if the order does not exist', async () => { + const user = { _id: '1' }; + const order = null; + + sinon.stub(messages, 'invalidOrderMessage').resolves(); + + const isValid = await validateTakeSellOrder(ctx, {}, user, order); + + expect(messages.invalidOrderMessage.calledOnce).to.equal(true); + expect(isValid).to.equal(false); + }); + + it('should return false if the user is the order creator', async () => { + const user = { _id: '1' }; + const order = { + creator_id: '1', + type: 'sell', + status: 'PENDING', + }; + + sinon.stub(messages, 'cantTakeOwnOrderMessage').resolves(); + + const isValid = await validateTakeSellOrder(ctx, {}, user, order); + + expect(messages.cantTakeOwnOrderMessage.calledOnce).to.equal(true); + expect(isValid).to.equal(false); + }); + + it('should return false if the order type is not sell', async () => { + const user = { _id: '2' }; + const order = { + creator_id: '1', + type: 'buy', + status: 'PENDING', + }; + + sinon.stub(messages, 'invalidTypeOrderMessage').resolves(); + + const isValid = await validateTakeSellOrder(ctx, {}, user, order); + + expect(messages.invalidTypeOrderMessage.calledOnce).to.equal(true); + expect(isValid).to.equal(false); + }); + + it('should return false if the order status is not PENDING', async () => { + const user = { _id: '2' }; + const order = { + creator_id: '1', + type: 'sell', + status: 'ACTIVE', + }; + + sinon.stub(messages, 'alreadyTakenOrderMessage').resolves(); + + const isValid = await validateTakeSellOrder(ctx, {}, user, order); + + expect(messages.alreadyTakenOrderMessage.calledOnce).to.equal(true); + expect(isValid).to.equal(false); + }); + }); + + describe('validateParams', () => { + it('should return empty array if params length is not equal to paramNumber', async () => { + ctx.update.message.text = '/command param1 param2 param3'; + + sinon.stub(messages, 'customMessage').resolves(); + + const result = await validateParams(ctx, 3, 'errOutputString'); + expect(result).to.be.an('array').to.have.lengthOf(0); + expect(messages.customMessage.calledOnce).to.equal(true); + }); + + it('should return sliced array if params length is equal to paramNumber', async () => { + ctx.update.message.text = '/command param1 param2'; + const result = await validateParams(ctx, 3, 'errOutputString'); + expect(result).to.deep.equal(['param1', 'param2']); + expect(ctx.reply.notCalled).to.equal(true); + }); + }); + + describe('validateObjectId', () => { + it('should return true if id is valid', async () => { + const validId = new ObjectId(); + const result = await validateObjectId(ctx, validId.toString()); + expect(result).to.equal(true); + expect(ctx.reply.notCalled).to.equal(true); + }); + + it('should return false if id is invalid', async () => { + const invalidId = 'invalidId'; + const result = await validateObjectId(ctx, invalidId); + expect(result).to.equal(false); + expect(ctx.reply.calledOnce).to.equal(true); + }); + }); + + describe('validateUserWaitingOrder', () => { + beforeEach(() => { + sinon.stub(Order, 'find'); + }); + + afterEach(() => { + Order.find.restore(); + }); + + it('should return true if user has no waiting orders', async () => { + Order.find.returns([]); + const result = await validateUserWaitingOrder(ctx, bot, user); + expect(result).to.equal(true); + }); + + it('should return false and send message if user has a waiting sell order', async () => { + const order = { + _id: new ObjectId(), + seller_id: user._id, + status: 'WAITING_PAYMENT', + }; + Order.find.onCall(0).returns([order]); + Order.find.onCall(1).returns([]); + sinon + .stub(messages, 'userCantTakeMoreThanOneWaitingOrderMessage') + .resolves(); + const result = await validateUserWaitingOrder(ctx, bot, user); + expect(result).to.equal(false); + expect( + messages.userCantTakeMoreThanOneWaitingOrderMessage.calledOnce + ).to.equal(true); + }); + + it('should return false and send message if user has a waiting buy order', async () => { + const order = { + _id: new ObjectId(), + buyer_id: user._id, + status: 'WAITING_BUYER_INVOICE', + }; + Order.find.onCall(0).returns([]); + Order.find.onCall(1).returns([order]); + sinon + .stub(messages, 'userCantTakeMoreThanOneWaitingOrderMessage') + .resolves(); + const result = await validateUserWaitingOrder(ctx, bot, user); + expect(result).to.equal(false); + expect( + messages.userCantTakeMoreThanOneWaitingOrderMessage.calledOnce + ).to.equal(true); + }); + }); + + describe('isBannedFromCommunity', () => { beforeEach(() => { - ctx = { - i18n: { - t: key => key, - locale: () => 'en', - }, - state: { - command: { - args: [], - }, - }, - update: { - callback_query: { - from: { - id: 1, - }, - }, - message: { - text: '', - from: { - id: 1, - }, - }, - }, - telegram: { - sendMessage: sinon.stub(), - }, - reply: () => { }, - botInfo: { - username: 'testbot', - }, - }; - - sandbox = sinon.createSandbox(); - // Mock process.env within the sandbox - sandbox.stub(process, 'env').value({ - MIN_PAYMENT_AMT: 100, - NODE_ENV: 'production', - INVOICE_EXPIRATION_WINDOW: 3600000, - }); - - replyStub = sinon.stub(ctx, 'reply'); - existLightningAddressStub = sinon.stub(); - isDisputeSolverStub = sinon.stub(); - isOrderCreatorStub = sinon.stub(); - validations = proxyquire('../../bot/validations', { - '../lnurl/lnurl-pay': { - existLightningAddress: existLightningAddressStub, - }, - '../util': { - isDisputeSolver: isDisputeSolverStub, - isOrderCreator: isOrderCreatorStub, - } - }); - bot = { - telegram: { - sendMessage: sinon.stub(), - }, - }; - user = { - _id: new ObjectId(), - tg_id: 12345, - }; + community = { + _id: new ObjectId(), + banned_users: [], + }; + sinon.stub(Community, 'findOne'); }); afterEach(() => { - sinon.restore(); - sandbox.restore(); - }); - - describe('validateSellOrder', () => { - it('should return false if args length is less than 4', async () => { - const result = await validateSellOrder(ctx); - expect(result).to.equal(false); - expect(replyStub.calledOnce).to.equal(true); - }); - - it('should return false if amount is not a number', async () => { - ctx.state.command.args = ['test', '100', 'USD', 'zelle']; - const result = await validateSellOrder(ctx); - expect(result).to.equal(false); - expect(replyStub.calledOnce).to.equal(true); - }); - - it('should return false if fiat amount is not a number', async () => { - ctx.state.command.args = ['10000', 'test', 'USD', 'zelle']; - const result = await validateSellOrder(ctx); - expect(result).to.equal(false); - expect(replyStub.calledOnce).to.equal(true); - }); - - it('should return false if fiat code is not valid, fiat code less than 3 characters', async () => { - ctx.state.command.args = ['10000', '100', 'US', 'zelle']; - const result = await validateSellOrder(ctx); - expect(result).to.equal(false); - expect(replyStub.calledOnce).to.equal(true); - }); - - it('should return false if fiat code is not valid, fiat code more than 5 characters', async () => { - ctx.state.command.args = ['10000', '100', 'USSDDD', 'zelle']; - const result = await validateSellOrder(ctx); - expect(result).to.equal(false); - expect(replyStub.calledOnce).to.equal(true); - }); - - it('should return false if amount is less than minimum', async () => { - ctx.state.command.args = ['1', '100', 'USD', 'zelle']; - const result = await validateSellOrder(ctx); - expect(result).to.equal(false); - expect(replyStub.calledOnce).to.equal(true); - }); - - it('should return object if validation success', async () => { - ctx.state.command.args = ['10000', '100', 'USD', 'zelle']; - const result = await validateSellOrder(ctx); - expect(result).to.be.an('object'); - }); - - it('should return object if validation success with price margin', async () => { - ctx.state.command.args = ['10000', '100', 'USD', 'zelle', '5']; - const result = await validateSellOrder(ctx); - expect(result).to.be.an('object'); - expect(result.priceMargin).to.equal('5'); - }); - - it('should return false if price margin is not a number', async () => { - ctx.state.command.args = ['10000', '100', 'USD', 'zelle', 'test']; - const result = await validateSellOrder(ctx); - expect(result).to.equal(false); - expect(replyStub.calledOnce).to.be.equal(true); - }); - - it('should work with ranges', async () => { - ctx.state.command.args = ['0', '100-200', 'USD', 'zelle', '5']; - const result = await validateSellOrder(ctx); - expect(result).to.be.an('object'); - expect(result.fiatAmount).to.deep.equal([100, 200]); - }); - - it('should fail with ranges with double dash', async () => { - ctx.state.command.args = ['0', '100--200', 'USD', 'zelle', '5']; - const result = await validateSellOrder(ctx); - expect(result).to.equal(false); - }); - - it('should fail with invalid ranges', async () => { - ctx.state.command.args = ['0', '200-100', 'USD', 'zelle', '5']; - const result = await validateSellOrder(ctx); - expect(result).to.equal(false); - }); - - it('should fail with ranges and amount', async () => { - ctx.state.command.args = ['1000', '100-200', 'USD', 'zelle', '5']; - const result = await validateSellOrder(ctx); - expect(result).to.equal(false); - }); - }); - - describe('validateBuyOrder', () => { - it('should return false if args length is less than 4', async () => { - const result = await validateBuyOrder(ctx); - expect(result).to.equal(false); - expect(replyStub.calledOnce).to.be.equal(true); - }); - - it('should return false if amount is not a number', async () => { - ctx.state.command.args = ['test', '100', 'USD', 'zelle']; - const result = await validateBuyOrder(ctx); - expect(result).to.equal(false); - expect(replyStub.calledOnce).to.be.equal(true); - }); - - it('should return false if fiat amount is not a number', async () => { - ctx.state.command.args = ['10000', 'test', 'USD', 'zelle']; - const result = await validateBuyOrder(ctx); - expect(result).to.equal(false); - expect(replyStub.calledOnce).to.be.equal(true); - }); - - it('should return false if amount is less than minimum', async () => { - ctx.state.command.args = ['1', '100', 'USD', 'zelle']; - const result = await validateBuyOrder(ctx); - expect(result).to.equal(false); - expect(replyStub.calledOnce).to.be.equal(true); - }); - - it('should return object if validation success', async () => { - ctx.state.command.args = ['10000', '100', 'USD', 'zelle']; - const result = await validateBuyOrder(ctx); - expect(result).to.be.an('object'); - }); - - it('should return object if validation success with price margin', async () => { - ctx.state.command.args = ['10000', '100', 'USD', 'zelle', '5']; - const result = await validateBuyOrder(ctx); - expect(result).to.be.an('object'); - expect(result.priceMargin).to.equal('5'); - }); - - it('should return false if price margin is not a number', async () => { - ctx.state.command.args = ['10000', '100', 'USD', 'zelle', 'test']; - const result = await validateBuyOrder(ctx); - expect(result).to.equal(false); - expect(replyStub.calledOnce).to.be.equal(true); - }); - - it('should work with ranges', async () => { - ctx.state.command.args = ['0', '100-200', 'USD', 'zelle', '5']; - const result = await validateBuyOrder(ctx); - expect(result).to.be.an('object'); - expect(result.fiatAmount).to.deep.equal([100, 200]); - }); - - it('should fail with ranges with double dash', async () => { - ctx.state.command.args = ['0', '100--200', 'USD', 'zelle', '5']; - const result = await validateBuyOrder(ctx); - expect(result).to.equal(false); - }); - - it('should fail with invalid ranges', async () => { - ctx.state.command.args = ['0', '200-100', 'USD', 'zelle', '5']; - const result = await validateBuyOrder(ctx); - expect(result).to.equal(false); - }); - - it('should fail with ranges and amount', async () => { - ctx.state.command.args = ['1000', '100-200', 'USD', 'zelle', '5']; - const result = await validateBuyOrder(ctx); - expect(result).to.equal(false); - }); - }); - - describe('validateLightningAddress', () => { - it('should return true for a valid lightning address', async () => { - existLightningAddressStub.withArgs('test@ln.com').returns(true); - const result = await validations.validateLightningAddress('test@ln.com'); - expect(result).to.equal(true); - }); - - it('should return false for an invalid lightning address (existence)', async () => { - existLightningAddressStub.withArgs('test@invalid.com').returns(false); - const result = await validations.validateLightningAddress('test@invalid.com'); - expect(result).to.equal(false); - }); - }); - - describe('validateUser', () => { - it('should create a new user if it does not exist', async () => { - ctx.update.callback_query.from = { - username: 'testuser', - id: '1' - }; - - sinon.stub(User, 'findOne').resolves(null); - sinon.stub(User.prototype, 'save').resolves(); - const user = await validateUser(ctx, true); - expect(user.save.calledOnce).to.equal(true); - expect(user).to.be.an('object'); - expect(user.tg_id).to.be.equal(ctx.update.callback_query.from.id); - expect(user.username).to.be.equal(ctx.update.callback_query.from.username); - }); - - it('should return false if user does not exist and start is false', async () => { - const user = await validateUser(ctx, false); - expect(user).to.equal(false); - }); - - it('should return the user if it exists', async () => { - ctx.update.callback_query.from = { - username: 'testuser', - id: '1' - }; - const newUser = new User({ - tg_id: ctx.update.callback_query.from.id, - username: ctx.update.callback_query.from.username, - }); - - sinon.stub(User, 'findOne').resolves(newUser); - - const user = await validateUser(ctx, false); - expect(user).to.be.an('object'); - expect(user.tg_id).to.be.equal(newUser.tg_id); - expect(user.username).to.be.equal(newUser.username); - }); - - it('should update the username if it has changed', async () => { - ctx.update.callback_query.from = { - username: 'testuser-updated', - id: '1' - }; - const newUser = new User({ - tg_id: ctx.update.callback_query.from.id, - username: ctx.update.callback_query.from.username, - }); - - sinon.stub(User, 'findOne').resolves(newUser); - - const user = await validateUser(ctx, false); - expect(user).to.be.an('object'); - expect(user.tg_id).to.be.equal(newUser.tg_id); - expect(user.username).to.be.equal('testuser-updated'); - }); - - it('should return false if the user is banned', async () => { - ctx.update.callback_query.from = { - username: 'testuser', - id: '1' - }; - const newUser = new User({ - tg_id: ctx.update.callback_query.from.id, - username: ctx.update.callback_query.from.username, - banned: true, - }); - - sinon.stub(User, 'findOne').resolves(newUser); - - const user = await validateUser(ctx, false); - expect(user).to.equal(false); - }); - }); - - describe('validateSuperAdmin', () => { - it('should return the user if it is a superadmin', async () => { - ctx.update.callback_query.from = { - username: 'testuser', - id: '1' - }; - const newUser = new User({ - tg_id: ctx.update.callback_query.from.id, - username: ctx.update.callback_query.from.username, - admin: true, - }); - - sinon.stub(User, 'findOne').resolves(newUser); - - const user = await validateSuperAdmin(ctx); - expect(user).to.be.an('object'); - expect(user.tg_id).to.be.equal(newUser.tg_id); - expect(user.admin).to.equal(true); - }); - - it('should return false if the user is not a superadmin', async () => { - ctx.update.callback_query.from = { - username: 'testuser', - id: '1' - }; - const newUser = new User({ - tg_id: ctx.update.callback_query.from.id, - username: ctx.update.callback_query.from.username, - admin: false, - }); - - sinon.stub(User, 'findOne').resolves(newUser); - - const user = await validateSuperAdmin(ctx); - expect(user).to.equal(undefined); - }); - }); - - describe('validateAdmin', () => { - it('should return the user if it is an admin', async () => { - const newCommunity = new Community({ - name: 'testcommunity' - }); - const newUser = new User({ - tg_id: ctx.update.message.from.id, - username: ctx.update.message.from.username, - admin: true, - default_community_id: new ObjectId(newCommunity._id) - }); - - sinon.stub(User, 'findOne').resolves(newUser); - sinon.stub(Community, 'findOne').resolves(newCommunity); - isDisputeSolverStub.withArgs(newCommunity, newUser).returns(true); - const user = await validateAdmin(ctx); - expect(user).to.be.an('object'); - expect(user.tg_id).to.be.equal(newUser.tg_id); - expect(user.admin).to.equal(true); - }); - - it('should return undefined if the user is not exist', async () => { - sinon.stub(User, 'findOne').resolves(null); - - const user = await validateAdmin(ctx); - expect(user).to.equal(undefined); - }); - - it('should return undefined if the user is not dispute solver and it is not an admin', async () => { - const newCommunity = new Community({ - name: 'testcommunity' - }); - const newUser = new User({ - tg_id: ctx.update.message.from.id, - username: ctx.update.message.from.username, - admin: false, - default_community_id: new ObjectId(newCommunity._id) - }); - - sinon.stub(User, 'findOne').resolves(newUser); - sinon.stub(Community, 'findOne').resolves(newCommunity); - isDisputeSolverStub.withArgs(newCommunity, newUser).returns(false); - - const user = await validateAdmin(ctx); - expect(user).to.equal(undefined); - }); - }); - - describe('validateSellOrder', () => { - it('should return false if the amount is not a number', async () => { - ctx.state.command.args = ['test', '100', 'USD', 'zelle']; - const order = await validateSellOrder(ctx); - expect(order).to.equal(false); - }); - - it('should return false if the fiat amount is not a number', async () => { - ctx.state.command.args = ['10000', 'test', 'USD', 'zelle']; - const order = await validateSellOrder(ctx); - expect(order).to.equal(false); - }); - - it('should return false if the fiat code is not valid', async () => { - ctx.state.command.args = ['10000', '100', 'invalid', 'zelle']; - const order = await validateSellOrder(ctx); - expect(order).to.equal(false); - }); - - it('should return the order data if the order is valid', async () => { - ctx.state.command.args = ['10000', '100', 'USD', 'zelle']; - const order = await validateSellOrder(ctx); - expect(order).to.be.an('object'); - expect(order.amount).to.be.equal(10000); - expect(order.fiatAmount).to.be.an('array').to.deep.equal([100]); - expect(order.fiatCode).to.be.equal('USD'); - expect(order.paymentMethod).to.be.equal('zelle'); - }); - }); - - describe('validateBuyOrder', () => { - it('should return false if the amount is not a number', async () => { - ctx.state.command.args = ['test', '100', 'USD', 'zelle']; - const order = await validateBuyOrder(ctx); - expect(order).to.equal(false); - }); - - it('should return false if the fiat amount is not a number', async () => { - ctx.state.command.args = ['10000', 'test', 'USD', 'zelle']; - const order = await validateBuyOrder(ctx); - expect(order).to.equal(false); - }); - - it('should return false if the fiat code is not valid', async () => { - ctx.state.command.args = ['10000', '100', 'invalid', 'zelle']; - const order = await validateBuyOrder(ctx); - expect(order).to.equal(false); - }); - - it('should return the order data if the order is valid', async () => { - ctx.state.command.args = ['10000', '100', 'USD', 'zelle']; - const order = await validateBuyOrder(ctx); - expect(order).to.be.an('object'); - expect(order.amount).to.be.equal(10000); - expect(order.fiatAmount).to.be.an('array').to.deep.equal([100]); - expect(order.fiatCode).to.be.equal('USD'); - expect(order.paymentMethod).to.be.equal('zelle'); - }); - }); - - // TODO possible duplicated of isValidInvoice - describe('validateInvoice', () => { - // This test goes to the catch - it('should return false if the invoice is not valid', async () => { - const invoice = await validateInvoice(ctx, 'invalid-invoice'); - expect(invoice).to.equal(false); - }); - - it('should return false if the invoice amount is too low', async () => { - const minPaymentAmount = 10; - const resInvoice = { - network: 'bc', - destination: '03...', - id: '123', - tokens: minPaymentAmount, - description: '', - expiry: 3600, - timestamp: 1678888888, - features: {}, - routes: [], - cltv_expiry: 9, - is_expired: false, - expires_at: '2023-03-15T12:14:48.000Z' - }; - const { validateInvoice } = proxyquire('../../bot/validations', { - 'invoices': { - parsePaymentRequest: sinon.stub().returns(resInvoice), - }, - }); - - const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; - - sinon.stub(messages, 'minimunAmountInvoiceMessage'); - - const invoice = await validateInvoice( - ctx, - lnInvoice - ); - - expect(messages.minimunAmountInvoiceMessage.calledOnce).to.equal(true); - expect(invoice).to.equal(false); - }); - - it('should return false if the invoice is expired with an expired date', async () => { - const minPaymentAmount = 2000; - const resInvoice = { - network: 'bc', - destination: '03...', - id: '123', - tokens: minPaymentAmount, - description: '', - expiry: 3600, - timestamp: 1678888888, - features: {}, - routes: [], - cltv_expiry: 9, - is_expired: false, - expires_at: '2023-09-23T11:00:00.000Z' - }; - const { validateInvoice } = proxyquire('../../bot/validations', { - 'invoices': { - parsePaymentRequest: sinon.stub().returns(resInvoice), - }, - }); - - const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; - - sinon.stub(messages, 'minimunExpirationTimeInvoiceMessage'); - - const invoice = await validateInvoice( - ctx, - lnInvoice - ); - - expect(messages.minimunExpirationTimeInvoiceMessage.calledOnce).to.equal(true); - expect(invoice).to.equal(false); - }); - - it('should return false if the invoice is expired with is_expired true', async () => { - const minPaymentAmount = 2000; - const resInvoice = { - network: 'bc', - destination: '03...', - id: '123', - tokens: minPaymentAmount, - description: '', - expiry: 3600, - timestamp: 1678888888, - features: {}, - routes: [], - cltv_expiry: 9, - is_expired: true, - expires_at: new Date(Date.now() + 86400000).toISOString() // One day after - }; - const { validateInvoice } = proxyquire('../../bot/validations', { - 'invoices': { - parsePaymentRequest: sinon.stub().returns(resInvoice), - }, - }); - - const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; - - sinon.stub(messages, 'expiredInvoiceMessage'); - - const invoice = await validateInvoice( - ctx, - lnInvoice - ); - - expect(messages.expiredInvoiceMessage.calledOnce).to.equal(true); - expect(invoice).to.equal(false); - }); - it('should return false if the invoice does not have a destination address', async () => { - const minPaymentAmount = 2000; - const resInvoice = { - network: 'bc', - // destination: '03...', Missed destination address - id: '123', - tokens: minPaymentAmount, - description: '', - expiry: 3600, - timestamp: 1678888888, - features: {}, - routes: [], - cltv_expiry: 9, - is_expired: false, - expires_at: new Date(Date.now() + 86400000).toISOString() // One day after - }; - const { validateInvoice } = proxyquire('../../bot/validations', { - 'invoices': { - parsePaymentRequest: sinon.stub().returns(resInvoice), - }, - }); - - const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; - - sinon.stub(messages, 'requiredAddressInvoiceMessage'); - - const invoice = await validateInvoice( - ctx, - lnInvoice - ); - - expect(messages.requiredAddressInvoiceMessage.calledOnce).to.equal(true); - expect(invoice).to.equal(false); - }); - it('should return false if the invoice does not have an id', async () => { - const minPaymentAmount = 2000; - const resInvoice = { - network: 'bc', - destination: '03...', - // id: '123', Missed Id - tokens: minPaymentAmount, - description: '', - expiry: 3600, - timestamp: 1678888888, - features: {}, - routes: [], - cltv_expiry: 9, - is_expired: false, - expires_at: new Date(Date.now() + 86400000).toISOString() // One day after - }; - const { validateInvoice } = proxyquire('../../bot/validations', { - 'invoices': { - parsePaymentRequest: sinon.stub().returns(resInvoice), - }, - }); - - const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; - - sinon.stub(messages, 'requiredHashInvoiceMessage'); - - const invoice = await validateInvoice( - ctx, - lnInvoice - ); - - expect(messages.requiredHashInvoiceMessage.calledOnce).to.equal(true); - expect(invoice).to.equal(false); - }); - it('should return the invoice if it is valid', async () => { - const resInvoice = { - network: 'bc', - destination: '03...', - id: '123', - tokens: 20000, - description: '', - expiry: 3600, - timestamp: 1678888888, - features: {}, - routes: [], - cltv_expiry: 9, - is_expired: false, - expires_at: new Date(Date.now() + 86400000).toISOString() // One day after - }; - const { validateInvoice } = proxyquire('../../bot/validations', { - 'invoices': { - parsePaymentRequest: sinon.stub().returns(resInvoice), - }, - }); - - const lnInvoice = 'lnbc20m1p0t9k3gpp5kqum3c9qsp58yj2cp8gp5c9yqcnzen9s08jx2p4d7r97777g4qsq9qy9qsqgqqqqqqgqqqqqqgqjqdhnx9'; - - const invoice = await validateInvoice( - ctx, - lnInvoice - ); - expect(invoice).to.be.an('object'); - expect(invoice.network).to.be.equal('bc'); - expect(invoice.tokens).to.be.equal(20000); - }); - }); - - describe('isValidInvoice', () => { - // This goes to the catch - it('should return false if the invoice is not valid', async () => { - sinon.stub(messages, 'invoiceInvalidMessage'); - - const { success } = await isValidInvoice(ctx, 'invalid-invoice'); - expect(success).to.equal(false); - expect(messages.invoiceInvalidMessage.calledOnce).to.equal(true); - }); - - it('should return false if the invoice amount is too low', async () => { - const minPaymentAmount = 10; - const resInvoice = { - network: 'bc', - destination: '03...', - id: '123', - tokens: minPaymentAmount, - description: '', - expiry: 3600, - timestamp: 1678888888, - features: {}, - routes: [], - cltv_expiry: 9, - is_expired: false, - expires_at: '2023-03-15T12:14:48.000Z' - }; - const { isValidInvoice } = proxyquire('../../bot/validations', { - 'invoices': { - parsePaymentRequest: sinon.stub().returns(resInvoice), - }, - }); - - const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; - - sinon.stub(messages, 'invoiceMustBeLargerMessage'); - - const { success } = await isValidInvoice( - ctx, - lnInvoice - ); - - expect(messages.invoiceMustBeLargerMessage.calledOnce).to.equal(true); - expect(success).to.equal(false); - }); - - it('should return false if the invoice is expired with an expired date', async () => { - const minPaymentAmount = 2000; - const resInvoice = { - network: 'bc', - destination: '03...', - id: '123', - tokens: minPaymentAmount, - description: '', - expiry: 3600, - timestamp: 1678888888, - features: {}, - routes: [], - cltv_expiry: 9, - is_expired: false, - expires_at: '2023-09-23T11:00:00.000Z' - }; - const { isValidInvoice } = proxyquire('../../bot/validations', { - 'invoices': { - parsePaymentRequest: sinon.stub().returns(resInvoice), - }, - }); - - const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; - - sinon.stub(messages, 'invoiceExpiryTooShortMessage'); - - const { success } = await isValidInvoice( - ctx, - lnInvoice - ); - - expect(messages.invoiceExpiryTooShortMessage.calledOnce).to.equal(true); - expect(success).to.equal(false); - }); - - it('should return false if the invoice is expired with is_expired true', async () => { - const minPaymentAmount = 2000; - const resInvoice = { - network: 'bc', - destination: '03...', - id: '123', - tokens: minPaymentAmount, - description: '', - expiry: 3600, - timestamp: 1678888888, - features: {}, - routes: [], - cltv_expiry: 9, - is_expired: true, - expires_at: new Date(Date.now() + 86400000).toISOString() // One day after - }; - const { isValidInvoice } = proxyquire('../../bot/validations', { - 'invoices': { - parsePaymentRequest: sinon.stub().returns(resInvoice), - }, - }); - - const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; - - sinon.stub(messages, 'invoiceHasExpiredMessage'); - - const { success } = await isValidInvoice( - ctx, - lnInvoice - ); - - expect(messages.invoiceHasExpiredMessage.calledOnce).to.equal(true); - expect(success).to.equal(false); - }); - it('should return false if the invoice does not have a destination address', async () => { - const minPaymentAmount = 2000; - const resInvoice = { - network: 'bc', - // destination: '03...', Missed destination address - id: '123', - tokens: minPaymentAmount, - description: '', - expiry: 3600, - timestamp: 1678888888, - features: {}, - routes: [], - cltv_expiry: 9, - is_expired: false, - expires_at: new Date(Date.now() + 86400000).toISOString() // One day after - }; - const { isValidInvoice } = proxyquire('../../bot/validations', { - 'invoices': { - parsePaymentRequest: sinon.stub().returns(resInvoice), - }, - }); - - const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; - - sinon.stub(messages, 'invoiceHasWrongDestinationMessage'); - - const { success } = await isValidInvoice( - ctx, - lnInvoice - ); - - expect(messages.invoiceHasWrongDestinationMessage.calledOnce).to.equal(true); - expect(success).to.equal(false); - }); - it('should return false if the invoice does not have an id', async () => { - const minPaymentAmount = 2000; - const resInvoice = { - network: 'bc', - destination: '03...', - // id: '123', Missed Id - tokens: minPaymentAmount, - description: '', - expiry: 3600, - timestamp: 1678888888, - features: {}, - routes: [], - cltv_expiry: 9, - is_expired: false, - expires_at: new Date(Date.now() + 86400000).toISOString() // One day after - }; - const { isValidInvoice } = proxyquire('../../bot/validations', { - 'invoices': { - parsePaymentRequest: sinon.stub().returns(resInvoice), - }, - }); - - const lnInvoice = 'lntb1u1p0g9j8ypqsp5xwyewd3a2v9hk6cakck29p29dj79wsdq6sty85c3qtgzq0w9qmmvpjlncqp58yj98ygg77skup0l293p7memz0hxq698j2zcqzpgxqyz5vqsp5uscy8wn5z9cqlcw78pd6skddj3sr8gzk9c9jxqyjw5d9q8wkdgg7z0xpvyjry9a9q6d8h829vdje7r29s5pjq7939v9kck2gsqgjg9'; - - sinon.stub(messages, 'requiredHashInvoiceMessage'); - - const { success } = await isValidInvoice( - ctx, - lnInvoice - ); - - expect(messages.requiredHashInvoiceMessage.calledOnce).to.equal(true); - expect(success).to.equal(false); - }); - it('should return the invoice if it is valid', async () => { - const resInvoice = { - network: 'bc', - destination: '03...', - id: '123', - tokens: 20000, - description: '', - expiry: 3600, - timestamp: 1678888888, - features: {}, - routes: [], - cltv_expiry: 9, - is_expired: false, - expires_at: new Date(Date.now() + 86400000).toISOString() // One day after - }; - const { isValidInvoice } = proxyquire('../../bot/validations', { - 'invoices': { - parsePaymentRequest: sinon.stub().returns(resInvoice), - }, - }); - - const lnInvoice = 'lnbc20m1p0t9k3gpp5kqum3c9qsp58yj2cp8gp5c9yqcnzen9s08jx2p4d7r97777g4qsq9qy9qsqgqqqqqqgqqqqqqgqjqdhnx9'; - - const { invoice } = await isValidInvoice( - ctx, - lnInvoice - ); - expect(invoice).to.be.an('object'); - expect(invoice.network).to.be.equal('bc'); - expect(invoice.tokens).to.be.equal(20000); - }); - }); - - describe('validateTakeSellOrder', () => { - it('should return false if the order does not exist', async () => { - const user = { _id: '1' }; - const order = null; - - sinon.stub(messages, 'invalidOrderMessage').resolves(); - - const isValid = await validateTakeSellOrder(ctx, {}, user, order); - - expect(messages.invalidOrderMessage.calledOnce).to.equal(true); - expect(isValid).to.equal(false); - }); - - it('should return false if the user is the order creator', async () => { - const user = { _id: '1' }; - const order = { - creator_id: '1', - type: 'sell', - status: 'PENDING', - }; - - sinon.stub(messages, 'cantTakeOwnOrderMessage').resolves(); - - const isValid = await validateTakeSellOrder(ctx, {}, user, order); - - expect(messages.cantTakeOwnOrderMessage.calledOnce).to.equal(true); - expect(isValid).to.equal(false); - }); - - it('should return false if the order type is not sell', async () => { - const user = { _id: '2' }; - const order = { - creator_id: '1', - type: 'buy', - status: 'PENDING', - }; - - sinon.stub(messages, 'invalidTypeOrderMessage').resolves(); - - const isValid = await validateTakeSellOrder(ctx, {}, user, order); - - expect(messages.invalidTypeOrderMessage.calledOnce).to.equal(true); - expect(isValid).to.equal(false); - }); - - it('should return false if the order status is not PENDING', async () => { - const user = { _id: '2' }; - const order = { - creator_id: '1', - type: 'sell', - status: 'ACTIVE', - }; - - sinon.stub(messages, 'alreadyTakenOrderMessage').resolves(); - - const isValid = await validateTakeSellOrder(ctx, {}, user, order); - - expect(messages.alreadyTakenOrderMessage.calledOnce).to.equal(true); - expect(isValid).to.equal(false); - }); - }); - - describe('validateParams', () => { - it('should return empty array if params length is not equal to paramNumber', async () => { - ctx.update.message.text = '/command param1 param2 param3'; - - sinon.stub(messages, 'customMessage').resolves(); - - const result = await validateParams(ctx, 3, 'errOutputString'); - expect(result).to.be.an('array').to.have.lengthOf(0); - expect(messages.customMessage.calledOnce).to.equal(true); - }); - - it('should return sliced array if params length is equal to paramNumber', async () => { - ctx.update.message.text = '/command param1 param2'; - const result = await validateParams(ctx, 3, 'errOutputString'); - expect(result).to.deep.equal(['param1', 'param2']); - expect(ctx.reply.notCalled).to.equal(true); - }); - }); - - describe('validateObjectId', () => { - it('should return true if id is valid', async () => { - const validId = new ObjectId(); - const result = await validateObjectId(ctx, validId.toString()); - expect(result).to.equal(true); - expect(ctx.reply.notCalled).to.equal(true); - }); - - it('should return false if id is invalid', async () => { - const invalidId = 'invalidId'; - const result = await validateObjectId(ctx, invalidId); - expect(result).to.equal(false); - expect(ctx.reply.calledOnce).to.equal(true); - }); - }); - - describe('validateUserWaitingOrder', () => { - beforeEach(() => { - sinon.stub(Order, 'find'); - }); - - afterEach(() => { - Order.find.restore(); - }); - - it('should return true if user has no waiting orders', async () => { - Order.find.returns([]); - const result = await validateUserWaitingOrder(ctx, bot, user); - expect(result).to.equal(true); - }); - - it('should return false and send message if user has a waiting sell order', async () => { - const order = { - _id: new ObjectId(), - seller_id: user._id, - status: 'WAITING_PAYMENT', - }; - Order.find.onCall(0).returns([order]); - Order.find.onCall(1).returns([]); - sinon.stub(messages, 'userCantTakeMoreThanOneWaitingOrderMessage').resolves(); - const result = await validateUserWaitingOrder(ctx, bot, user); - expect(result).to.equal(false); - expect( - messages.userCantTakeMoreThanOneWaitingOrderMessage.calledOnce - ).to.equal(true); - }); - - it('should return false and send message if user has a waiting buy order', async () => { - const order = { - _id: new ObjectId(), - buyer_id: user._id, - status: 'WAITING_BUYER_INVOICE', - }; - Order.find.onCall(0).returns([]); - Order.find.onCall(1).returns([order]); - sinon.stub(messages, 'userCantTakeMoreThanOneWaitingOrderMessage').resolves(); - const result = await validateUserWaitingOrder(ctx, bot, user); - expect(result).to.equal(false); - expect( - messages.userCantTakeMoreThanOneWaitingOrderMessage.calledOnce - ).to.equal(true); - }); - }); - - describe('isBannedFromCommunity', () => { - beforeEach(() => { - community = { - _id: new ObjectId(), - banned_users: [], - }; - sinon.stub(Community, 'findOne'); - }); - - afterEach(() => { - Community.findOne.restore(); - }); - - it('should return false if communityId is null', async () => { - const result = await isBannedFromCommunity(user, null); - expect(result).to.equal(false); - }); - - it('should return false if community is not found', async () => { - Community.findOne.returns(null); - const result = await isBannedFromCommunity(user, community._id); - expect(result).to.equal(false); - }); - - it('should return false if user is not banned', async () => { - Community.findOne.returns(community); - const result = await isBannedFromCommunity(user, community._id); - expect(result).to.equal(false); - }); - - it('should return true if user is banned', async () => { - const user = { _id: 'userId' }; - const communityId = 'communityId'; - community.banned_users = [{ id: 'userId', username: 'username' }]; - - Community.findOne.returns(community); - - const result = await isBannedFromCommunity(user, communityId); - expect(result).to.equal(true); - }); + Community.findOne.restore(); + }); + + it('should return false if communityId is null', async () => { + const result = await isBannedFromCommunity(user, null); + expect(result).to.equal(false); + }); + + it('should return false if community is not found', async () => { + Community.findOne.returns(null); + const result = await isBannedFromCommunity(user, community._id); + expect(result).to.equal(false); + }); + + it('should return false if user is not banned', async () => { + Community.findOne.returns(community); + const result = await isBannedFromCommunity(user, community._id); + expect(result).to.equal(false); + }); + + it('should return true if user is banned', async () => { + const user = { _id: 'userId' }; + const communityId = 'communityId'; + community.banned_users = [{ id: 'userId', username: 'username' }]; + + Community.findOne.returns(community); + + const result = await isBannedFromCommunity(user, communityId); + expect(result).to.equal(true); }); + }); });