From ac43fc58b88e187e04ad9302a3027d7c89fe1e0e Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sat, 7 Oct 2023 16:26:52 +0800 Subject: [PATCH 01/15] rationalisation first commit --- functions/src/definitions/common/genAI.ts | 41 +++++++- .../common/openai/hyperparameters.json | 8 ++ .../definitions/eventHandlers/userHandlers.ts | 98 ++++++++++--------- 3 files changed, 97 insertions(+), 50 deletions(-) diff --git a/functions/src/definitions/common/genAI.ts b/functions/src/definitions/common/genAI.ts index 52e75ba5..bed3188e 100644 --- a/functions/src/definitions/common/genAI.ts +++ b/functions/src/definitions/common/genAI.ts @@ -62,9 +62,46 @@ async function anonymiseMessage(message: string) { } } } catch (e) { - functions.logger.error("Anonymisation hyperparameters failed: " + e) + functions.logger.error("Anonymisation failed: " + e) return message } } -export { anonymiseMessage } +async function rationaliseMessage(message: string, category: string) { + if (env === "SIT" || env === "DEV") { + return "This is a rationalisation" + } + try { + const rationalisationHyperparameters = hyperparameters?.rationalisation + const model: string = rationalisationHyperparameters.model + const systemMessage: string = rationalisationHyperparameters?.prompt?.system + + const examples: examples[] = + rationalisationHyperparameters?.prompt?.examples + const userMessage: string = + rationalisationHyperparameters?.prompt?.user.replace( + "{{message}}", + message + ) + if (model && systemMessage && examples && userMessage) { + const response = await callChatCompletion( + model, + systemMessage, + examples, + userMessage + ) + if (response) { + return response + } else { + functions.logger.error("No response returned from openAI api") + return null + } + } + } catch (e) { + functions.logger.error("Rationalisation failed: " + e) + return null + } + return null +} + +export { anonymiseMessage, rationaliseMessage } diff --git a/functions/src/definitions/common/openai/hyperparameters.json b/functions/src/definitions/common/openai/hyperparameters.json index 37c3fc16..982c7f5c 100644 --- a/functions/src/definitions/common/openai/hyperparameters.json +++ b/functions/src/definitions/common/openai/hyperparameters.json @@ -19,5 +19,13 @@ ], "user": "{{message}}" } + }, + "rationalisation": { + "model": "gpt-3.5-turbo", + "prompt": { + "system": "bla", + "examples": [], + "user": "" + } } } diff --git a/functions/src/definitions/eventHandlers/userHandlers.ts b/functions/src/definitions/eventHandlers/userHandlers.ts index 2732dc7d..05b1ae9d 100644 --- a/functions/src/definitions/eventHandlers/userHandlers.ts +++ b/functions/src/definitions/eventHandlers/userHandlers.ts @@ -27,7 +27,7 @@ import { getHash, getSignedUrl, } from "../common/mediaUtils" -import { anonymiseMessage } from "../common/genAI" +import { anonymiseMessage, rationaliseMessage } from "../common/genAI" import { calculateSimilarity } from "../common/calculateSimilarity" import { performOCR } from "../common/machineLearningServer/operations" import { defineString } from "firebase-functions/params" @@ -321,16 +321,22 @@ async function newTextInstanceHandler({ } if (!hasMatch) { + const isMachineAssessed = !!( + machineCategory && + machineCategory !== "error" && + machineCategory !== "unsure" && + machineCategory !== "info" + ) + const strippedMessage = await anonymiseMessage(text) + let rationalisation: null | string = null + if (isMachineAssessed && strippedMessage) { + rationalisation = await rationaliseMessage(text, machineCategory) + } messageRef = db.collection("messages").doc() messageUpdateObj = { machineCategory: machineCategory, //Can be "fake news" or "scam" - isMachineCategorised: !!( - machineCategory && - machineCategory !== "error" && - machineCategory !== "unsure" && - machineCategory !== "info" - ), + isMachineCategorised: isMachineAssessed, originalText: text, text: strippedMessage, //text caption: null, @@ -339,36 +345,28 @@ async function newTextInstanceHandler({ lastTimestamp: timestamp, //timestamp of latest instance (firestore timestamp data type) lastRefreshedTimestamp: timestamp, isPollStarted: false, //boolean, whether or not polling has started - isAssessed: !!( - machineCategory && - machineCategory !== "error" && - machineCategory !== "unsure" && - machineCategory !== "info" - ), //boolean, whether or not we have concluded the voting + isAssessed: isMachineAssessed, //boolean, whether or not we have concluded the voting assessedTimestamp: null, assessmentExpiry: null, assessmentExpired: false, truthScore: null, //float, the mean truth score isIrrelevant: - !!machineCategory && machineCategory.includes("irrelevant") + isMachineAssessed && machineCategory.includes("irrelevant") ? true : null, //bool, if majority voted irrelevant then update this - isScam: machineCategory === "scam" ? true : null, - isIllicit: machineCategory === "illicit" ? true : null, - isSpam: machineCategory === "spam" ? true : null, + isScam: isMachineAssessed && machineCategory === "scam" ? true : null, + isIllicit: + isMachineAssessed && machineCategory === "illicit" ? true : null, + isSpam: isMachineAssessed && machineCategory === "spam" ? true : null, isLegitimate: null, isUnsure: null, isInfo: machineCategory === "info" ? true : null, - primaryCategory: - !!machineCategory && - machineCategory != "error" && - machineCategory !== "unsure" && - machineCategory !== "info" - ? machineCategory.split("_")[0] //in case of irrelevant_length, we want to store irrelevant - : null, + primaryCategory: isMachineAssessed + ? machineCategory.split("_")[0] //in case of irrelevant_length, we want to store irrelevant + : null, customReply: null, //string instanceCount: 0, - rationalisation: null, + rationalisation: rationalisation, } } else { messageRef = matchedParentMessageRef @@ -578,17 +576,27 @@ async function newImageInstanceHandler({ } if (!hasMatch || (!matchedInstanceSnap && !matchedParentMessageRef)) { + let rationalisation: null | string = null if (extractedMessage) { strippedMessage = await anonymiseMessage(extractedMessage) } - messageRef = db.collection("messages").doc() + const isMachineAssessed = !!( + machineCategory && + !caption && + machineCategory !== "error" && + machineCategory !== "unsure" && + machineCategory !== "info" + ) + if (extractedMessage && isMachineAssessed && strippedMessage) { + rationalisation = await rationaliseMessage( + strippedMessage, + machineCategory + ) + } + if (extractedMessage) messageRef = db.collection("messages").doc() messageUpdateObj = { machineCategory: machineCategory, //Can be "fake news" or "scam" - isMachineCategorised: !!( - machineCategory && - machineCategory !== "unsure" && - machineCategory !== "info" - ), + isMachineCategorised: isMachineAssessed, originalText: extractedMessage ?? null, text: strippedMessage ?? null, //text caption: caption ?? null, @@ -597,34 +605,28 @@ async function newImageInstanceHandler({ lastTimestamp: timestamp, //timestamp of latest instance (firestore timestamp data type) lastRefreshedTimestamp: timestamp, isPollStarted: false, //boolean, whether or not polling has started - isAssessed: !!( - machineCategory && - machineCategory !== "unsure" && - machineCategory !== "info" - ), //boolean, whether or not we have concluded the voting + isAssessed: isMachineAssessed, //boolean, whether or not we have concluded the voting assessedTimestamp: null, assessmentExpiry: null, assessmentExpired: false, truthScore: null, //float, the mean truth score isIrrelevant: - !!machineCategory && machineCategory.includes("irrelevant") + isMachineAssessed && machineCategory.includes("irrelevant") ? true : null, //bool, if majority voted irrelevant then update this - isScam: machineCategory === "scam" ? true : null, - isIllicit: machineCategory === "illicit" ? true : null, - isSpam: machineCategory === "spam" ? true : null, + isScam: isMachineAssessed && machineCategory === "scam" ? true : null, + isIllicit: + isMachineAssessed && machineCategory === "illicit" ? true : null, + isSpam: isMachineAssessed && machineCategory === "spam" ? true : null, isLegitimate: null, isUnsure: null, - isInfo: machineCategory === "info" ? true : null, - primaryCategory: - !!machineCategory && - machineCategory !== "unsure" && - machineCategory !== "info" - ? machineCategory.split("_")[0] //in case of irrelevant_length, we want to store irrelevant - : null, + isInfo: !caption && machineCategory === "info" ? true : null, + primaryCategory: isMachineAssessed + ? machineCategory.split("_")[0] //in case of irrelevant_length, we want to store irrelevant + : null, customReply: null, //string instanceCount: 0, - rationalisation: null, + rationalisation: rationalisation, } } else { if (matchType === "image" && matchedInstanceSnap) { From e2920033bedb8744faf08146305ebb03006bd200 Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sat, 7 Oct 2023 18:56:57 +0800 Subject: [PATCH 02/15] on messageUpdate, rationalise --- .../eventHandlers/onMessageUpdate.ts | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/functions/src/definitions/eventHandlers/onMessageUpdate.ts b/functions/src/definitions/eventHandlers/onMessageUpdate.ts index e84b6535..55cfea38 100644 --- a/functions/src/definitions/eventHandlers/onMessageUpdate.ts +++ b/functions/src/definitions/eventHandlers/onMessageUpdate.ts @@ -1,7 +1,7 @@ import * as functions from "firebase-functions" import { respondToInstance } from "../common/responseUtils" import { Timestamp } from "firebase-admin/firestore" -import {} from "../common/genAI" +import { rationaliseMessage } from "../common/genAI" const onMessageUpdate = functions .region("asia-southeast1") @@ -12,33 +12,34 @@ const onMessageUpdate = functions const before = change.before const after = change.after const messageData = after.data() + const text = messageData.text + const primaryCategory = messageData.primaryCategory if (!before.data().isAssessed && messageData.isAssessed) { //TODO: rationalisation here + let rationalisation: null | string = null + let primaryCategory = messageData.primaryCategory + if (primaryCategory && !messageData.caption && text) { + rationalisation = await rationaliseMessage(text, primaryCategory) + } await after.ref.update({ assessedTimestamp: Timestamp.fromDate(new Date()), + rationalisation: rationalisation, }) - const machineCategory = messageData.machineCategory - let primaryCategory = messageData.primaryCategory - if (["misleading", "untrue", "accurate"].includes(primaryCategory)) { - primaryCategory = "info" - } - if ( - machineCategory && - machineCategory !== "unsure" && - primaryCategory !== machineCategory - ) { - functions.logger.warn( - "Voted category does not match machine category", - { - issue: "classification_mismatch", - primaryCategory: messageData.primaryCategory, - machineCategory: messageData.machineCategory, - text: messageData.text, - } - ) - } await replyPendingInstances(after) } + // if either the text changed, or the primaryCategory changed, rerun rationalisation + if ( + before.data().text !== text || + before.data().primaryCategory !== primaryCategory + ) { + let rationalisation: null | string = null + if (primaryCategory && !messageData.caption && text) { + rationalisation = await rationaliseMessage(text, primaryCategory) + } + await after.ref.update({ + rationalisation: rationalisation, + }) + } return Promise.resolve() }) From 9456612bf17435bd9ad1aeab69d0d630bbf57f99 Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sat, 7 Oct 2023 18:59:17 +0800 Subject: [PATCH 03/15] on messageUpdate, rationalise --- functions/src/definitions/eventHandlers/onMessageUpdate.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions/src/definitions/eventHandlers/onMessageUpdate.ts b/functions/src/definitions/eventHandlers/onMessageUpdate.ts index 55cfea38..99204c0a 100644 --- a/functions/src/definitions/eventHandlers/onMessageUpdate.ts +++ b/functions/src/definitions/eventHandlers/onMessageUpdate.ts @@ -28,7 +28,7 @@ const onMessageUpdate = functions await replyPendingInstances(after) } // if either the text changed, or the primaryCategory changed, rerun rationalisation - if ( + else if ( before.data().text !== text || before.data().primaryCategory !== primaryCategory ) { From d1ca70c392289039cb2cf4725f84b17501da3ef6 Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sat, 7 Oct 2023 21:20:57 +0800 Subject: [PATCH 04/15] handle irrelevant --- functions/src/definitions/eventHandlers/onMessageUpdate.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/functions/src/definitions/eventHandlers/onMessageUpdate.ts b/functions/src/definitions/eventHandlers/onMessageUpdate.ts index 99204c0a..eda298d2 100644 --- a/functions/src/definitions/eventHandlers/onMessageUpdate.ts +++ b/functions/src/definitions/eventHandlers/onMessageUpdate.ts @@ -34,7 +34,11 @@ const onMessageUpdate = functions ) { let rationalisation: null | string = null if (primaryCategory && !messageData.caption && text) { - rationalisation = await rationaliseMessage(text, primaryCategory) + if (primaryCategory == "irrelevant") { + rationalisation = null + } else { + rationalisation = await rationaliseMessage(text, primaryCategory) + } } await after.ref.update({ rationalisation: rationalisation, From 85459b68e4662db1f913641d7e78ac90805cefdd Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sat, 7 Oct 2023 21:21:08 +0800 Subject: [PATCH 05/15] change responses --- documentation/dataSchema.md | 2 + functions/src/definitions/common/constants.ts | 18 +- .../src/definitions/common/responseUtils.ts | 200 +++++++++++++----- .../definitions/eventHandlers/userHandlers.ts | 32 ++- 4 files changed, 177 insertions(+), 75 deletions(-) diff --git a/documentation/dataSchema.md b/documentation/dataSchema.md index 103b23cb..fb631412 100644 --- a/documentation/dataSchema.md +++ b/documentation/dataSchema.md @@ -54,6 +54,8 @@ erDiagram boolean isInterimPromptSent "Have we sent an interim prompt" boolean isInterimUseful "Whether the interim message is useful" boolean isInterimReplySent "Have we sent an interim reply" + boolean isRationalisationSent "Has the rationalisation been sent" + boolean isRationalisationUseful "Is the rationalisation feature useful" boolean isReplyForced "track if final reply is forced" boolean isMatched "track if message was matched" boolean isReplyImmediate "track if final reply is immediate" diff --git a/functions/src/definitions/common/constants.ts b/functions/src/definitions/common/constants.ts index 25c1e4cf..fbaee549 100644 --- a/functions/src/definitions/common/constants.ts +++ b/functions/src/definitions/common/constants.ts @@ -108,14 +108,7 @@ If you'd like still another update after more votes come in, just tap the button ALREADY_REPLIED: `CheckMate has already provided a final response to this message.`, - //button - SCAMSHIELD_SEEK_CONSENT: - "Would you now like us to share this message with ScamShield on your behalf? Only the contents of this message, and no other information, will be sent.", - - SCAMSHIELD_ON_CONSENT: - "Thank you for sharing this message with us and ScamShield, and for keeping Singapore safe!", - - SCAMSHIELD_ON_DECLINE: `No worries! We will not send your message to ScamShield. If you change your mind, you can still hit "Yes" above. Thank you for sharing this message with us, and for keeping Singapore safe!`, + SCAMSHIELD_ON_DECLINE: `No worries! We will not send your message to ScamShield. Thank you for sharing this message with us, and for keeping Singapore safe!`, //menu text list MENU: `{{prefix}} @@ -171,6 +164,15 @@ Done? You're now ready to use CheckMate! Let's do our part in the fight against On a scale from 1-10, how likely are you to recommend us to a friend, colleague or family member?`, SATISFACTION_SURVEY_THANKS: `Thanks for your feedback!`, + + HOWD_WE_TELL: `*This is an experimental feature powered by generative AI*. + + Here are some signs that this message is a {{category}}: + + {{rationalisation}}`, + RATIONALISATION_USEFUL: `Thanks for your valuable feedback!`, + + RATIONALISATION_NOT_USEFUL: `Sorry to hear that, but thanks anyway for your valuable feedback!`, } const FACTCHECKER_BOT_RESPONSES = { diff --git a/functions/src/definitions/common/responseUtils.ts b/functions/src/definitions/common/responseUtils.ts index 6211bc59..1e931195 100644 --- a/functions/src/definitions/common/responseUtils.ts +++ b/functions/src/definitions/common/responseUtils.ts @@ -4,6 +4,7 @@ import { USER_BOT_RESPONSES, FACTCHECKER_BOT_RESPONSES } from "./constants" import { sendWhatsappButtonMessage, sendWhatsappTextListMessage, + sendWhatsappTextMessage, } from "./sendWhatsappMessage" import { DocumentSnapshot, Timestamp } from "firebase-admin/firestore" import { getThresholds, sleep } from "./utils" @@ -54,6 +55,33 @@ async function respondToInterimFeedback( await sendWhatsappButtonMessage("user", data.from, response, buttons, data.id) } +async function respondToRationalisationFeedback( + instancePath: string, + isUseful: string +) { + const instanceRef = db.doc(instancePath) + const instanceSnap = await instanceRef.get() + const responses = await getResponsesObj("user") + const data = instanceSnap.data() + if (!data) { + functions.logger.log("Missing data in respondToRationalisationFeedback") + return + } + let response + switch (isUseful) { + case "yes": + response = responses?.RATIONALISATION_USEFUL + await instanceRef.update({ isRationalisationUseful: true }) + break + default: + response = responses?.RATIONALISATION_NOT_USEFUL + await instanceRef.update({ isRationalisationUseful: false }) + break + } + + await sendWhatsappTextMessage("user", data.from, response) +} + async function getResponsesObj( botType: "factChecker" ): Promise @@ -223,10 +251,7 @@ async function sendSatisfactionSurvey(instanceSnap: DocumentSnapshot) { } } -async function sendVotingStats( - instancePath: string, - triggerScamShieldConsent: boolean -) { +async function sendVotingStats(instancePath: string) { //get statistics const messageRef = db.doc(instancePath).parent.parent if (!messageRef) { @@ -307,31 +332,94 @@ async function sendVotingStats( await sendTextMessage("user", from, response, instanceSnap.get("id")) - if (triggerScamShieldConsent) { - await sleep(2000) + // if (triggerScamShieldConsent) { + // await sleep(2000) + // const buttons = [ + // { + // type: "reply", + // reply: { + // id: `scamshieldConsent_${instancePath}_consent`, + // title: "Yes", + // }, + // }, + // { + // type: "reply", + // reply: { + // id: `scamshieldConsent_${instancePath}_decline`, + // title: "No", + // }, + // }, + // ] + // await sendWhatsappButtonMessage( + // "user", + // from, + // responses.SCAMSHIELD_SEEK_CONSENT, + // buttons, + // instanceSnap.get("id") + // ) + // } +} + +async function sendRationalisation(instancePath: string) { + const instanceRef = db.doc(instancePath) + const instanceSnap = await instanceRef.get() + const data = instanceSnap.data() + const responses = await getResponsesObj("user") + try { + const messageRef = instanceRef.parent.parent + if (!data) { + throw new Error("instanceSnap data missing") + } + if (!messageRef) { + throw new Error("messageRef is null") + } + const messageSnap = await messageRef.get() + if (!messageSnap) { + throw new Error("messageSnap is null") + } + const rationalisation = messageSnap.get("rationalisation") + const category = messageSnap.get("primaryCategory") + if (!rationalisation) { + throw new Error("rationalisation is null") + } + if (!category) { + throw new Error("category is null") + } const buttons = [ { type: "reply", reply: { - id: `scamshieldConsent_${instancePath}_consent`, - title: "Yes", + id: `feedbackRationalisation_${instancePath}_yes`, + title: "Yes, it's useful", }, }, { type: "reply", reply: { - id: `scamshieldConsent_${instancePath}_decline`, - title: "No", + id: `feedbackRationalisation_${instancePath}_no`, + title: "No, it's not", }, }, ] + const replyText = responses.HOWD_WE_TELL.replace( + "{{category}}", + category + ).replace("{{rationalisation}}", rationalisation) + await instanceRef.update({ + isRationalisationSent: true, + }) await sendWhatsappButtonMessage( "user", - from, - responses.SCAMSHIELD_SEEK_CONSENT, + data.from, + replyText, buttons, - instanceSnap.get("id") + data.id ) + } catch (e) { + functions.logger.error(`Error sending rationalisation: ${e}`) + if (data?.from) { + await sendTextMessage("user", data.from, responses.GENERIC_ERROR) + } } } @@ -576,43 +664,37 @@ async function respondToInstance( isReplyImmediate: boolean replyCategory?: string replyTimestamp?: Timestamp + scamShieldConsent?: boolean } = { isReplied: true, isReplyForced: forceReply, isReplyImmediate: isImmediate, } - let buttons = [ - { - type: "reply", - reply: { - id: `votingResults_${instanceSnap.ref.path}`, - title: "See voting results", - }, - }, - ] - let scamShieldButtons = [ - { - type: "reply", - reply: { - id: `scamshieldConsent_${instanceSnap.ref.path}_consent`, - title: "Yes", - }, + let buttons = [] + + const votingResultsButton = { + type: "reply", + reply: { + id: `votingResults_${instanceSnap.ref.path}`, + title: "See voting results", }, - { - type: "reply", - reply: { - id: `scamshieldConsent_${instanceSnap.ref.path}_decline`, - title: "No", - }, + } + + const declineScamShieldButton = { + type: "reply", + reply: { + id: `scamshieldDecline_${instanceSnap.ref.path}`, + title: "Don't report this", }, - { - type: "reply", - reply: { - id: `votingResults_${instanceSnap.ref.path}_scamshield`, - title: "See voting results", - }, + } + + const viewRationalisationButton = { + type: "reply", + reply: { + id: `rationalisation_${instanceSnap.ref.path}`, + title: "How'd we tell?", }, - ] + } let category if (isScam) { @@ -682,11 +764,23 @@ async function respondToInstance( responseText = getFinalResponseText( responses[category.toUpperCase() as keyof typeof responses] ) + + if (!(isMachineCategorised || responseCount <= 0)) { + buttons.push(votingResultsButton) + } + + const rationalisation = parentMessageSnap.get("rationalisation") + + if ((category === "scam" || category === "illicit") && rationalisation) { + buttons.push(viewRationalisationButton) + } + if (category === "scam" || category === "illicit") { - if (isMachineCategorised || responseCount <= 0) { - scamShieldButtons.pop() - } - buttons = scamShieldButtons + buttons.push(declineScamShieldButton) + updateObj.scamShieldConsent = true + } + + if (buttons.length > 0) { await sendWhatsappButtonMessage( "user", data.from, @@ -695,17 +789,7 @@ async function respondToInstance( data.id ) } else { - if (isMachineCategorised || responseCount <= 0) { - await sendTextMessage("user", data.from, responseText, data.id) - } else { - await sendWhatsappButtonMessage( - "user", - data.from, - responseText, - buttons, - data.id - ) - } + await sendTextMessage("user", data.from, responseText, data.id) } } updateObj.replyCategory = category @@ -745,4 +829,6 @@ export { sendVotingStats, sendReferralMessage, respondToInterimFeedback, + sendRationalisation, + respondToRationalisationFeedback, } diff --git a/functions/src/definitions/eventHandlers/userHandlers.ts b/functions/src/definitions/eventHandlers/userHandlers.ts index 05b1ae9d..cf45e0ce 100644 --- a/functions/src/definitions/eventHandlers/userHandlers.ts +++ b/functions/src/definitions/eventHandlers/userHandlers.ts @@ -21,6 +21,8 @@ import { sendVotingStats, sendReferralMessage, respondToInterimFeedback, + sendRationalisation, + respondToRationalisationFeedback, } from "../common/responseUtils" import { downloadWhatsappMedia, @@ -396,6 +398,8 @@ async function newTextInstanceHandler({ isInterimUseful: null, isInterimReplySent: null, isMeaningfulInterimReplySent: null, + isRationalisationSent: null, + isRationalisationUseful: null, isReplyForced: null, isMatched: hasMatch, isReplyImmediate: null, @@ -668,6 +672,8 @@ async function newImageInstanceHandler({ isInterimUseful: null, isInterimReplySent: null, isMeaningfulInterimReplySent: null, + isRationalisationSent: null, + isRationalisationUseful: null, isReplyForced: null, isMatched: hasMatch, isReplyImmediate: null, @@ -711,16 +717,13 @@ async function onButtonReply(messageObj: Message, platform = "whatsapp") { instanceRef, updateObj: { scamShieldConsent?: boolean } switch (type) { - case "scamshieldConsent": - ;[instancePath, selection] = rest + case "scamshieldDecline": + ;[instancePath] = rest instanceRef = db.doc(instancePath) - updateObj = {} - const replyText = - selection === "consent" - ? responses?.SCAMSHIELD_ON_CONSENT - : responses?.SCAMSHIELD_ON_DECLINE - updateObj.scamShieldConsent = selection === "consent" - await instanceRef.update(updateObj) + const replyText = responses?.SCAMSHIELD_ON_DECLINE + await instanceRef.update({ + scamShieldConsent: false, + }) if (!replyText) { functions.logger.error("No replyText for scamshieldConsent") break @@ -732,7 +735,8 @@ async function onButtonReply(messageObj: Message, platform = "whatsapp") { ;[instancePath, ...scamShield] = rest const triggerScamShieldConsent = scamShield.length > 0 && scamShield[0] === "scamshield" - await sendVotingStats(instancePath, triggerScamShieldConsent) + //await sendVotingStats(instancePath, triggerScamShieldConsent) + await sendVotingStats(instancePath) break case "sendInterim": ;[instancePath] = rest @@ -742,6 +746,14 @@ async function onButtonReply(messageObj: Message, platform = "whatsapp") { ;[instancePath, selection] = rest await respondToInterimFeedback(instancePath, selection) break + case "rationalisation": + ;[instancePath] = rest + await sendRationalisation(instancePath) + break + case "feedbackRationalisation": + ;[instancePath, selection] = rest + await respondToRationalisationFeedback(instancePath, selection) + break } const step = type + (selection ? `_${selection}` : "") return Promise.resolve(step) From b46aa47d3233e14933d984577a3480a15b21126d Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sun, 8 Oct 2023 11:59:27 +0800 Subject: [PATCH 06/15] rationalisation changes --- functions/package-lock.json | 1648 ++++++++++++++++- functions/package.json | 1 + functions/src/definitions/common/constants.ts | 18 +- functions/src/definitions/common/genAI.ts | 5 + .../src/definitions/common/responseUtils.ts | 7 +- functions/src/definitions/common/utils.ts | 16 +- .../eventHandlers/onMessageUpdate.ts | 6 +- .../checkmate.postman_collection.json | 14 +- integration-tests/env.json | 38 +- 9 files changed, 1642 insertions(+), 111 deletions(-) diff --git a/functions/package-lock.json b/functions/package-lock.json index f611e361..d06b0356 100644 --- a/functions/package-lock.json +++ b/functions/package-lock.json @@ -20,6 +20,7 @@ "libphonenumber-js": "^1.10.21", "node-telegram-bot-api": "^0.63.0", "openai": "^4.10.0", + "re2": "^1.20.3", "typesense": "^1.5.3" }, "devDependencies": { @@ -3428,6 +3429,95 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -3915,6 +4005,17 @@ "node": ">= 8" } }, + "node_modules/@npmcli/fs": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz", + "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/@opentelemetry/api": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.6.0.tgz", @@ -3939,6 +4040,15 @@ "node": ">=10.13.0" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -4026,7 +4136,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "optional": true, "engines": { "node": ">= 10" } @@ -4612,6 +4721,11 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "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/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -4678,6 +4792,18 @@ "node": ">= 8.0.0" } }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -4755,6 +4881,23 @@ "node": ">= 8" } }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -5038,8 +5181,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "devOptional": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base-64": { "version": "0.1.0", @@ -5167,7 +5309,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "devOptional": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5241,6 +5382,87 @@ "node": ">= 0.8" } }, + "node_modules/cacache": { + "version": "17.1.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.4.tgz", + "integrity": "sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^7.0.3", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -5341,6 +5563,14 @@ "node": "*" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, "node_modules/ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -5362,6 +5592,14 @@ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "engines": { + "node": ">=6" + } + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -5404,6 +5642,14 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -5436,8 +5682,12 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "devOptional": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" }, "node_modules/content-disposition": { "version": "0.5.4", @@ -5517,7 +5767,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -5620,6 +5869,11 @@ "node": ">=0.4.0" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -5717,6 +5971,11 @@ "stream-shift": "^1.0.0" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -5770,6 +6029,27 @@ "node": ">= 0.8" } }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -5793,6 +6073,19 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==" + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -6256,6 +6549,11 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==" + }, "node_modules/express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", @@ -6740,6 +7038,32 @@ "is-callable": "^1.1.3" } }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -6809,11 +7133,29 @@ "node": ">= 0.6" } }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "devOptional": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.2", @@ -6865,6 +7207,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/gaxios": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.0.2.tgz", @@ -6970,7 +7330,6 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "devOptional": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -7282,8 +7641,7 @@ "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "devOptional": true + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "node_modules/grapheme-splitter": { "version": "1.0.4", @@ -7400,6 +7758,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, "node_modules/hashids": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/hashids/-/hashids-2.3.0.tgz", @@ -7428,6 +7791,11 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -7452,7 +7820,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "optional": true, "dependencies": { "@tootallnate/once": "2", "agent-base": "6", @@ -7600,16 +7967,22 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, "engines": { "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "devOptional": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -7620,6 +7993,15 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/install-artifact-from-github": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/install-artifact-from-github/-/install-artifact-from-github-1.3.3.tgz", + "integrity": "sha512-x79SL0d8WOi1ZjXSTUqqs0GPQZ92YArJAN9O46wgU9wdH2U9ecyyhB9YGDbPe2OLV4ptmt6AZYRQZ2GydQZosQ==", + "bin": { + "install-from-cache": "bin/install-from-cache.js", + "save-to-github-cache": "bin/save-to-github-cache.js" + } + }, "node_modules/internal-slot": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", @@ -7633,6 +8015,11 @@ "node": ">= 0.4" } }, + "node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -7766,6 +8153,11 @@ "node": ">=0.10.0" } }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==" + }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -7917,8 +8309,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isstream": { "version": "0.1.2", @@ -8000,6 +8391,23 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jest": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", @@ -9027,6 +9435,39 @@ "semver": "bin/semver.js" } }, + "node_modules/make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -9183,7 +9624,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "devOptional": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -9200,11 +9640,153 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-collect/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-fetch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", + "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-fetch/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "optional": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -9217,6 +9799,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/nan": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==" + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -9282,6 +9869,30 @@ "node": ">= 6.13.0" } }, + "node_modules/node-gyp": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.0.tgz", + "integrity": "sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg==", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^11.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.13 || ^14.13 || >=16" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -9340,6 +9951,20 @@ "node": ">=4" } }, + "node_modules/nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -9361,6 +9986,20 @@ "node": ">=8" } }, + "node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -9525,6 +10164,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -9585,7 +10238,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -9594,7 +10246,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -9605,6 +10256,29 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -9775,6 +10449,26 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/promise-retry/node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "engines": { + "node": ">= 4" + } + }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -9971,6 +10665,17 @@ "node": ">= 0.8" } }, + "node_modules/re2": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/re2/-/re2-1.20.3.tgz", + "integrity": "sha512-g5j4YjygwGEccP9SCuDI90uPlgALLEYLotfL0K+kqL3XKB4ht7Nm1JuXfOTG96c7JozpvCUxTz1T7oTNwwMI6w==", + "hasInstallScript": true, + "dependencies": { + "install-artifact-from-github": "^1.3.3", + "nan": "^2.17.0", + "node-gyp": "^9.4.0" + } + }, "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -10305,7 +11010,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "devOptional": true, "dependencies": { "glob": "^7.1.3" }, @@ -10473,6 +11177,11 @@ "node": ">= 0.8.0" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, "node_modules/set-function-name": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", @@ -10495,7 +11204,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -10507,7 +11215,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -10528,8 +11235,7 @@ "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/sisteransi": { "version": "1.0.5", @@ -10546,6 +11252,41 @@ "node": ">=8" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -10595,6 +11336,25 @@ "node": ">=0.10.0" } }, + "node_modules/ssri": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", + "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ssri/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -10680,6 +11440,20 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/string.prototype.trim": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", @@ -10733,6 +11507,18 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -10855,6 +11641,44 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tar": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/teeny-request": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-8.0.2.tgz", @@ -11235,6 +12059,28 @@ "node": ">=4" } }, + "node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -11404,7 +12250,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -11448,6 +12293,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -11473,6 +12326,23 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -14229,6 +15099,64 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -14614,6 +15542,14 @@ "fastq": "^1.6.0" } }, + "@npmcli/fs": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz", + "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==", + "requires": { + "semver": "^7.3.5" + } + }, "@opentelemetry/api": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.6.0.tgz", @@ -14629,6 +15565,12 @@ "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==" }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true + }, "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -14715,8 +15657,7 @@ "@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "optional": true + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" }, "@types/babel__core": { "version": "7.20.0", @@ -15207,6 +16148,11 @@ "eslint-visitor-keys": "^3.3.0" } }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -15253,6 +16199,15 @@ "humanize-ms": "^1.2.1" } }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -15304,6 +16259,20 @@ "picomatch": "^2.0.4" } }, + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + } + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -15529,8 +16498,7 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "devOptional": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "base-64": { "version": "0.1.0", @@ -15641,7 +16609,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "devOptional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -15693,6 +16660,65 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" }, + "cacache": { + "version": "17.1.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.4.tgz", + "integrity": "sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==", + "requires": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^7.0.3", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + } + }, + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==" + } + } + }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -15755,6 +16781,11 @@ "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==" }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + }, "ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -15767,6 +16798,11 @@ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -15802,6 +16838,11 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -15828,8 +16869,12 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "devOptional": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" }, "content-disposition": { "version": "0.5.4", @@ -15893,7 +16938,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -15964,6 +17008,11 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -16039,6 +17088,11 @@ "stream-shift": "^1.0.0" } }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -16083,6 +17137,26 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "optional": true, + "requires": { + "iconv-lite": "^0.6.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -16103,6 +17177,16 @@ "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", "optional": true }, + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" + }, + "err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==" + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -16447,6 +17531,11 @@ "jest-util": "^29.5.0" } }, + "exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==" + }, "express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", @@ -16860,6 +17949,22 @@ "is-callable": "^1.1.3" } }, + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "dependencies": { + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + } + } + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -16911,11 +18016,25 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, + "fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "requires": { + "minipass": "^7.0.3" + }, + "dependencies": { + "minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==" + } + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "devOptional": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.3.2", @@ -16951,6 +18070,21 @@ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" }, + "gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + } + }, "gaxios": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.0.2.tgz", @@ -17026,7 +18160,6 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "devOptional": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -17258,8 +18391,7 @@ "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "devOptional": true + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "grapheme-splitter": { "version": "1.0.4", @@ -17336,6 +18468,11 @@ "has-symbols": "^1.0.2" } }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, "hashids": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/hashids/-/hashids-2.3.0.tgz", @@ -17358,6 +18495,11 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + }, "http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -17379,7 +18521,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "optional": true, "requires": { "@tootallnate/once": "2", "agent-base": "6", @@ -17478,14 +18619,17 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "devOptional": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -17496,6 +18640,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "install-artifact-from-github": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/install-artifact-from-github/-/install-artifact-from-github-1.3.3.tgz", + "integrity": "sha512-x79SL0d8WOi1ZjXSTUqqs0GPQZ92YArJAN9O46wgU9wdH2U9ecyyhB9YGDbPe2OLV4ptmt6AZYRQZ2GydQZosQ==" + }, "internal-slot": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", @@ -17506,6 +18655,11 @@ "side-channel": "^1.0.4" } }, + "ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -17597,6 +18751,11 @@ "is-extglob": "^2.1.1" } }, + "is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==" + }, "is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -17694,8 +18853,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "isstream": { "version": "0.1.2", @@ -17761,6 +18919,15 @@ "istanbul-lib-report": "^3.0.0" } }, + "jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, "jest": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", @@ -18582,6 +19749,35 @@ } } }, + "make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "requires": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" + } + } + }, "makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -18699,7 +19895,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "devOptional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -18710,17 +19905,135 @@ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", "optional": true }, + "minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==" + }, + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minipass-fetch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", + "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "requires": { + "encoding": "^0.1.13", + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "dependencies": { + "minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==" + } + } + }, + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "requires": { + "yallist": "^4.0.0" + } + } + } + }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "optional": true + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "nan": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==" + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -18756,6 +20069,24 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" }, + "node-gyp": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.0.tgz", + "integrity": "sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg==", + "requires": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^11.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + } + }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -18804,6 +20135,14 @@ } } }, + "nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "requires": { + "abbrev": "^1.0.0" + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -18819,6 +20158,17 @@ "path-key": "^3.0.0" } }, + "npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "requires": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + } + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -18932,6 +20282,14 @@ "p-limit": "^3.0.2" } }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "requires": { + "aggregate-error": "^3.0.0" + } + }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -18973,14 +20331,12 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "devOptional": true + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" }, "path-parse": { "version": "1.0.7", @@ -18988,6 +20344,22 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "requires": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==" + } + } + }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -19110,6 +20482,22 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "requires": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "dependencies": { + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==" + } + } + }, "prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -19251,6 +20639,16 @@ "unpipe": "1.0.0" } }, + "re2": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/re2/-/re2-1.20.3.tgz", + "integrity": "sha512-g5j4YjygwGEccP9SCuDI90uPlgALLEYLotfL0K+kqL3XKB4ht7Nm1JuXfOTG96c7JozpvCUxTz1T7oTNwwMI6w==", + "requires": { + "install-artifact-from-github": "^1.3.3", + "nan": "^2.17.0", + "node-gyp": "^9.4.0" + } + }, "react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -19499,7 +20897,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "devOptional": true, "requires": { "glob": "^7.1.3" } @@ -19610,6 +21007,11 @@ "send": "0.18.0" } }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, "set-function-name": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", @@ -19629,7 +21031,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "requires": { "shebang-regex": "^3.0.0" } @@ -19637,8 +21038,7 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, "side-channel": { "version": "1.0.4", @@ -19653,8 +21053,7 @@ "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "sisteransi": { "version": "1.0.5", @@ -19668,6 +21067,30 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" + }, + "socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "requires": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + } + }, + "socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "requires": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -19706,6 +21129,21 @@ "tweetnacl": "~0.14.0" } }, + "ssri": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", + "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "requires": { + "minipass": "^7.0.3" + }, + "dependencies": { + "minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==" + } + } + }, "stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -19775,6 +21213,16 @@ "strip-ansi": "^6.0.1" } }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, "string.prototype.trim": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", @@ -19813,6 +21261,14 @@ "ansi-regex": "^5.0.1" } }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, "strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -19897,6 +21353,39 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, + "tar": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "requires": { + "yallist": "^4.0.0" + } + } + } + } + } + }, "teeny-request": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-8.0.2.tgz", @@ -20180,6 +21669,22 @@ "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true }, + "unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "requires": { + "unique-slug": "^4.0.0" + } + }, + "unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "requires": { + "imurmurhash": "^0.1.4" + } + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -20304,7 +21809,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -20333,6 +21837,14 @@ "has-tostringtag": "^1.0.0" } }, + "wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -20349,6 +21861,16 @@ "strip-ansi": "^6.0.0" } }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/functions/package.json b/functions/package.json index 07b1ae02..373dc964 100644 --- a/functions/package.json +++ b/functions/package.json @@ -32,6 +32,7 @@ "libphonenumber-js": "^1.10.21", "node-telegram-bot-api": "^0.63.0", "openai": "^4.10.0", + "re2": "^1.20.3", "typesense": "^1.5.3" }, "devDependencies": { diff --git a/functions/src/definitions/common/constants.ts b/functions/src/definitions/common/constants.ts index fbaee549..6c5ec081 100644 --- a/functions/src/definitions/common/constants.ts +++ b/functions/src/definitions/common/constants.ts @@ -27,18 +27,18 @@ You can try sending the message in again, or report the error via our form at ht We recommend you do not engage further⛔️⛔️ -While this is our assessment, ScamShield (https://scamshield.org.sg) is still the authoritative, official source for scams in Singapore. We are currently exploring a collaboration with ScamShield. +CheckMate will report suspicious messages to ScamShield (https://scamshield.org.sg) on your behalf. -Would you like us to share this message with ScamShield? Only the contents of this message, and no other information, will be sent.{{results}}`, +To avoid reporting this message, select "Don't report this" below.`, //button ILLICIT: `{{thanks}}{{matched}}{{methodology}}*suspicious*!🚨 We recommend you do not engage further⛔️⛔️ -While this is our assessment, ScamShield (https://scamshield.org.sg) is still the authoritative, official source for scams in Singapore. We are currently exploring a collaboration with ScamShield. +CheckMate will report suspicious messages to ScamShield (https://scamshield.org.sg) on your behalf. -Would you like us to share this message with ScamShield? Only the contents of this message, and no other information, will be sent.{{results}}`, +To avoid reporting this message, select "Don't report this" below.`, SPAM: `{{thanks}}{{matched}}{{methodology}}spam!🚧 @@ -66,8 +66,6 @@ Thank you for keeping Singapore safe!`, METHODOLOGY_AUTO: `Based on pattern matching, our auto-classifier is confident that this message is `, - VOTE_RESULTS_SUFFIX: ` You can also see how we voted, before deciding.`, - //not used MATCHED: `In fact, other users have sent this message in {{numberInstances}} times. `, @@ -165,11 +163,9 @@ On a scale from 1-10, how likely are you to recommend us to a friend, colleague SATISFACTION_SURVEY_THANKS: `Thanks for your feedback!`, - HOWD_WE_TELL: `*This is an experimental feature powered by generative AI*. - - Here are some signs that this message is a {{category}}: - - {{rationalisation}}`, + HOWD_WE_TELL: `*This is an experimental feature powered by generative AI*. Do let us know if it was useful below! + +{{rationalisation}}`, RATIONALISATION_USEFUL: `Thanks for your valuable feedback!`, RATIONALISATION_NOT_USEFUL: `Sorry to hear that, but thanks anyway for your valuable feedback!`, diff --git a/functions/src/definitions/common/genAI.ts b/functions/src/definitions/common/genAI.ts index bed3188e..99af920f 100644 --- a/functions/src/definitions/common/genAI.ts +++ b/functions/src/definitions/common/genAI.ts @@ -1,6 +1,8 @@ import { callChatCompletion, ChatMessage, examples } from "./openai/openai" import hyperparameters from "./openai/hyperparameters.json" import * as functions from "firebase-functions" +import { checkUrlPresence } from "./utils" +//import RE2 from "re2" type redaction = { text: string @@ -68,6 +70,9 @@ async function anonymiseMessage(message: string) { } async function rationaliseMessage(message: string, category: string) { + if (checkUrlPresence(message) || category === "irrelevant") { + return null + } if (env === "SIT" || env === "DEV") { return "This is a rationalisation" } diff --git a/functions/src/definitions/common/responseUtils.ts b/functions/src/definitions/common/responseUtils.ts index 1e931195..ea45bb14 100644 --- a/functions/src/definitions/common/responseUtils.ts +++ b/functions/src/definitions/common/responseUtils.ts @@ -402,9 +402,9 @@ async function sendRationalisation(instancePath: string) { }, ] const replyText = responses.HOWD_WE_TELL.replace( - "{{category}}", - category - ).replace("{{rationalisation}}", rationalisation) + "{{rationalisation}}", + rationalisation + ) await instanceRef.update({ isRationalisationSent: true, }) @@ -646,7 +646,6 @@ async function respondToInstance( ? responses.METHODOLOGY_AUTO : responses.METHODOLOGY_HUMAN ) - .replace("{{results}}", isImmediate ? "" : responses.VOTE_RESULTS_SUFFIX) } if (!isAssessed && !forceReply) { diff --git a/functions/src/definitions/common/utils.ts b/functions/src/definitions/common/utils.ts index a042e75b..8d401365 100644 --- a/functions/src/definitions/common/utils.ts +++ b/functions/src/definitions/common/utils.ts @@ -2,6 +2,7 @@ import { thresholds } from "./constants" import * as admin from "firebase-admin" import { findPhoneNumbersInText } from "libphonenumber-js" import { createHash } from "crypto" +//import RE2 from "re2" import { Timestamp } from "firebase-admin/firestore" if (!admin.apps.length) { @@ -59,9 +60,19 @@ function stripPhone(originalStr: string, includePlaceholder = false) { return newStr } +function checkUrlPresence(originalStr: string): boolean { + const urlRegex = new RegExp( + "\\b(?:https?:\\/\\/)?(?:www\\.)?[^ \\n\\r]+?\\.[a-z]{2,}(?:[^\\s]*)?", + "gi" + ) + return urlRegex.test(originalStr) +} + function stripUrl(originalStr: string, includePlaceholder = false) { - const urlRegex = - /\b(?:https?:\/\/)?(?:www\.)?[^ \n\r]+?\.[a-z]{2,}(?:[^\s]*)?/gi + const urlRegex = new RegExp( + "\\b(?:https?:\\/\\/)?(?:www\\.)?[^ \\n\\r]+?\\.[a-z]{2,}(?:[^\\s]*)?", + "gi" + ) const placeholder = includePlaceholder ? "" : "" const replacedString = originalStr.replace(urlRegex, placeholder) return replacedString @@ -99,4 +110,5 @@ export { checkUrl, normalizeSpaces, checkMessageId, + checkUrlPresence, } diff --git a/functions/src/definitions/eventHandlers/onMessageUpdate.ts b/functions/src/definitions/eventHandlers/onMessageUpdate.ts index eda298d2..99204c0a 100644 --- a/functions/src/definitions/eventHandlers/onMessageUpdate.ts +++ b/functions/src/definitions/eventHandlers/onMessageUpdate.ts @@ -34,11 +34,7 @@ const onMessageUpdate = functions ) { let rationalisation: null | string = null if (primaryCategory && !messageData.caption && text) { - if (primaryCategory == "irrelevant") { - rationalisation = null - } else { - rationalisation = await rationaliseMessage(text, primaryCategory) - } + rationalisation = await rationaliseMessage(text, primaryCategory) } await after.ref.update({ rationalisation: rationalisation, diff --git a/integration-tests/checkmate.postman_collection.json b/integration-tests/checkmate.postman_collection.json index 9b9ae0bc..6873384b 100644 --- a/integration-tests/checkmate.postman_collection.json +++ b/integration-tests/checkmate.postman_collection.json @@ -11870,14 +11870,14 @@ " \"type\": \"reply\",\r", " \"reply\": {\r", " \"id\": \"ID\",\r", - " \"title\": \"Yes\"\r", + " \"title\": \"How'd we tell?\"\r", " }\r", " },\r", " {\r", " \"type\": \"reply\",\r", " \"reply\": {\r", " \"id\": \"ID\",\r", - " \"title\": \"No\"\r", + " \"title\": \"Don't report this\"\r", " }\r", " }\r", " ]\r", @@ -11892,13 +11892,13 @@ "\r", " var jsonData = pm.response.json();\r", "\r", - " let reply_id_yes = jsonData.body.interactive.action.buttons[0].reply.id;\r", - " let reply_id_no = jsonData.body.interactive.action.buttons[1].reply.id;\r", - " let [, scamInstancePath , ] = reply_id_yes.split(\"_\")\r", + " let reply_id_rationalisation = jsonData.body.interactive.action.buttons[0].reply.id;\r", + " let reply_id_decline = jsonData.body.interactive.action.buttons[1].reply.id;\r", + " let [, scamInstancePath , ] = reply_id_rationalisation.split(\"_\")\r", " \r", " // check if the id matches the pattern \"menu_dispute_messages/*/instances/*\"\r", - " pm.expect(reply_id_yes).to.match(/scamshieldConsent_messages\\/\\w+\\/instances\\/\\w+_consent/);\r", - " pm.expect(reply_id_no).to.match(/scamshieldConsent_messages\\/\\w+\\/instances\\/\\w+_decline/);\r", + " pm.expect(reply_id_rationalisation).to.match(/rationalisation_messages\\/\\w+\\/instances\\/\\w+/);\r", + " pm.expect(reply_id_decline).to.match(/scamshieldDecline_messages\\/\\w+\\/instances\\/\\w+/);\r", " pm.collectionVariables.set(\"scamInstancePath\", scamInstancePath);\r", "\r", " jsonData.body.interactive.action.buttons[0].reply.id = \"ID\"\r", diff --git a/integration-tests/env.json b/integration-tests/env.json index 40ae6c11..715dbdf6 100644 --- a/integration-tests/env.json +++ b/integration-tests/env.json @@ -135,12 +135,12 @@ }, { "key": "__CONSTANTS__.USER_BOT_RESPONSES.SCAM", - "value": "{{thanks}}{{matched}}{{methodology}}*a scam*!🚫\n\nWe recommend you do not engage further⛔️⛔️\n\nWhile this is our assessment, ScamShield (https://scamshield.org.sg) is still the authoritative, official source for scams in Singapore. We are currently exploring a collaboration with ScamShield.\n\nWould you like us to share this message with ScamShield? Only the contents of this message, and no other information, will be sent.{{results}}", + "value": "{{thanks}}{{matched}}{{methodology}}*a scam*!🚫\n\nWe recommend you do not engage further⛔️⛔️\n\nCheckMate will report suspicious messages to ScamShield (https://scamshield.org.sg) on your behalf.\n\nTo avoid reporting this message, select \"Don't report this\" below.", "enabled": true }, { "key": "__CONSTANTS__.USER_BOT_RESPONSES.ILLICIT", - "value": "{{thanks}}{{matched}}{{methodology}}*suspicious*!🚨\n\nWe recommend you do not engage further⛔️⛔️\n\nWhile this is our assessment, ScamShield (https://scamshield.org.sg) is still the authoritative, official source for scams in Singapore. We are currently exploring a collaboration with ScamShield.\n\nWould you like us to share this message with ScamShield? Only the contents of this message, and no other information, will be sent.{{results}}", + "value": "{{thanks}}{{matched}}{{methodology}}*suspicious*!🚨\n\nWe recommend you do not engage further⛔️⛔️\n\nCheckMate will report suspicious messages to ScamShield (https://scamshield.org.sg) on your behalf.\n\nTo avoid reporting this message, select \"Don't report this\" below.", "enabled": true }, { @@ -198,11 +198,6 @@ "value": "In fact, other users have sent this message in {{numberInstances}} times. ", "enabled": true }, - { - "key": "__CONSTANTS__.USER_BOT_RESPONSES.VOTE_RESULTS_SUFFIX", - "value": " You can also see how we voted, before deciding.", - "enabled": true - }, { "key": "__CONSTANTS__.FACTCHECKER_BOT_RESPONSES.ONBOARDING_1", "value": "Welcome to our community of CheckMates! 👋🏻 We're grateful to have you on board to combat misinformation and scams. 🙇‍♀️🙇🏻 We'd love to get to know you better - could you *reply to this message* and share your name with us? (Reply to this message by swiping right)!", @@ -313,19 +308,9 @@ "value": "CheckMate has already provided a final response to this message.", "enabled": true }, - { - "key": "__CONSTANTS__.USER_BOT_RESPONSES.SCAMSHIELD_SEEK_CONSENT", - "value": "Would you now like us to share this message with ScamShield on your behalf? Only the contents of this message, and no other information, will be sent.", - "enabled": true - }, - { - "key": "__CONSTANTS__.USER_BOT_RESPONSES.SCAMSHIELD_ON_CONSENT", - "value": "Thank you for sharing this message with us and ScamShield, and for keeping Singapore safe!", - "enabled": true - }, { "key": "__CONSTANTS__.USER_BOT_RESPONSES.SCAMSHIELD_ON_DECLINE", - "value": "No worries! We will not send your message to ScamShield. If you change your mind, you can still hit \"Yes\" above. Thank you for sharing this message with us, and for keeping Singapore safe!", + "value": "No worries! We will not send your message to ScamShield. Thank you for sharing this message with us, and for keeping Singapore safe!", "enabled": true }, { @@ -377,9 +362,24 @@ "key": "__CONSTANTS__.USER_BOT_RESPONSES.GENERIC_ERROR", "value": "Sorry, an error occured. 😔 We'll be looking into this! Meanwhile, you can try out other functions of the bot. Apologies!", "enabled": true + }, + { + "key": "__CONSTANTS__.USER_BOT_RESPONSES.HOWD_WE_TELL", + "value": "*This is an experimental feature powered by generative AI*. Do let us know if it was useful below!\n \n{{rationalisation}}", + "enabled": true + }, + { + "key": "__CONSTANTS__.USER_BOT_RESPONSES.RATIONALISATION_USEFUL", + "value": "Thanks for your valuable feedback!", + "enabled": true + }, + { + "key": "__CONSTANTS__.USER_BOT_RESPONSES.RATIONALISATION_NOT_USEFUL", + "value": "Sorry to hear that, but thanks anyway for your valuable feedback!", + "enabled": true } ], "_postman_variable_scope": "environment", "_postman_exported_at": "2023-04-30T14:17:56.196Z", "_postman_exported_using": "Postman/10.13.0" -} +} \ No newline at end of file From 724008b7b0d70f86086d2f525bbb82649208820e Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sat, 14 Oct 2023 08:22:49 +0800 Subject: [PATCH 07/15] exclude irrelevant from rationalisation --- .../definitions/eventHandlers/onMessageUpdate.ts | 14 ++++++++++++-- .../src/definitions/eventHandlers/userHandlers.ts | 13 +++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/functions/src/definitions/eventHandlers/onMessageUpdate.ts b/functions/src/definitions/eventHandlers/onMessageUpdate.ts index 99204c0a..6d039132 100644 --- a/functions/src/definitions/eventHandlers/onMessageUpdate.ts +++ b/functions/src/definitions/eventHandlers/onMessageUpdate.ts @@ -18,7 +18,12 @@ const onMessageUpdate = functions //TODO: rationalisation here let rationalisation: null | string = null let primaryCategory = messageData.primaryCategory - if (primaryCategory && !messageData.caption && text) { + if ( + primaryCategory && + primaryCategory !== "irrelevant" && + !messageData.caption && + text + ) { rationalisation = await rationaliseMessage(text, primaryCategory) } await after.ref.update({ @@ -33,7 +38,12 @@ const onMessageUpdate = functions before.data().primaryCategory !== primaryCategory ) { let rationalisation: null | string = null - if (primaryCategory && !messageData.caption && text) { + if ( + primaryCategory && + primaryCategory !== "irrelevant" && + !messageData.caption && + text + ) { rationalisation = await rationaliseMessage(text, primaryCategory) } await after.ref.update({ diff --git a/functions/src/definitions/eventHandlers/userHandlers.ts b/functions/src/definitions/eventHandlers/userHandlers.ts index cf45e0ce..566ab213 100644 --- a/functions/src/definitions/eventHandlers/userHandlers.ts +++ b/functions/src/definitions/eventHandlers/userHandlers.ts @@ -332,7 +332,11 @@ async function newTextInstanceHandler({ const strippedMessage = await anonymiseMessage(text) let rationalisation: null | string = null - if (isMachineAssessed && strippedMessage) { + if ( + isMachineAssessed && + strippedMessage && + !machineCategory.includes("irrelevant") + ) { rationalisation = await rationaliseMessage(text, machineCategory) } messageRef = db.collection("messages").doc() @@ -591,7 +595,12 @@ async function newImageInstanceHandler({ machineCategory !== "unsure" && machineCategory !== "info" ) - if (extractedMessage && isMachineAssessed && strippedMessage) { + if ( + extractedMessage && + isMachineAssessed && + strippedMessage && + !machineCategory.includes("irrelevant") + ) { rationalisation = await rationaliseMessage( strippedMessage, machineCategory From 65f68e49b83ef1b873a1afd97a345205366cf3a9 Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sat, 14 Oct 2023 09:35:46 +0800 Subject: [PATCH 08/15] changed from url presence to meaningfulness --- functions/src/definitions/common/genAI.ts | 25 +++++++++++++++++-- .../eventHandlers/onMessageUpdate.ts | 2 ++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/functions/src/definitions/common/genAI.ts b/functions/src/definitions/common/genAI.ts index 99af920f..da9e5a6f 100644 --- a/functions/src/definitions/common/genAI.ts +++ b/functions/src/definitions/common/genAI.ts @@ -1,7 +1,7 @@ import { callChatCompletion, ChatMessage, examples } from "./openai/openai" import hyperparameters from "./openai/hyperparameters.json" import * as functions from "firebase-functions" -import { checkUrlPresence } from "./utils" +import { stripUrl, stripPhone, checkUrlPresence } from "./utils" //import RE2 from "re2" type redaction = { @@ -70,7 +70,28 @@ async function anonymiseMessage(message: string) { } async function rationaliseMessage(message: string, category: string) { - if (checkUrlPresence(message) || category === "irrelevant") { + if (category.includes("irrelevant") || category === "unsure") { + return null + } + + let meaningfulLength: number = 300 + switch (category) { + case "illicit": + meaningfulLength = 50 + break + case "scam": + meaningfulLength = 50 + break + case "spam": + meaningfulLength = 75 + break + default: + if (checkUrlPresence(message)) { + return null + } + } + if (stripPhone(stripUrl(message, false), false).length < meaningfulLength) { + //don't bother with rationalisation if remaining message is too short to be meaningful. return null } if (env === "SIT" || env === "DEV") { diff --git a/functions/src/definitions/eventHandlers/onMessageUpdate.ts b/functions/src/definitions/eventHandlers/onMessageUpdate.ts index 6d039132..6fe53e2c 100644 --- a/functions/src/definitions/eventHandlers/onMessageUpdate.ts +++ b/functions/src/definitions/eventHandlers/onMessageUpdate.ts @@ -21,6 +21,7 @@ const onMessageUpdate = functions if ( primaryCategory && primaryCategory !== "irrelevant" && + primaryCategory !== "unsure" && !messageData.caption && text ) { @@ -41,6 +42,7 @@ const onMessageUpdate = functions if ( primaryCategory && primaryCategory !== "irrelevant" && + primaryCategory !== "unsure" && !messageData.caption && text ) { From 98e1ff48b6d5d975177934a968d2fefef8e87c17 Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sat, 14 Oct 2023 10:59:29 +0800 Subject: [PATCH 09/15] added hyperparameters --- functions/src/definitions/common/genAI.ts | 11 ++++------- .../common/openai/hyperparameters.json | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/functions/src/definitions/common/genAI.ts b/functions/src/definitions/common/genAI.ts index da9e5a6f..fc207e66 100644 --- a/functions/src/definitions/common/genAI.ts +++ b/functions/src/definitions/common/genAI.ts @@ -40,7 +40,6 @@ async function anonymiseMessage(message: string) { try { const responseObj = JSON.parse(response) const redactions: redaction[] = responseObj.redacted - console.log(redactions) redactions.forEach((redaction) => { let regex = new RegExp(redaction.text, "g") returnMessage = returnMessage.replace( @@ -94,7 +93,7 @@ async function rationaliseMessage(message: string, category: string) { //don't bother with rationalisation if remaining message is too short to be meaningful. return null } - if (env === "SIT" || env === "DEV") { + if (env === "SIT") { return "This is a rationalisation" } try { @@ -104,11 +103,9 @@ async function rationaliseMessage(message: string, category: string) { const examples: examples[] = rationalisationHyperparameters?.prompt?.examples - const userMessage: string = - rationalisationHyperparameters?.prompt?.user.replace( - "{{message}}", - message - ) + const userMessage: string = rationalisationHyperparameters?.prompt?.user + .replace("{{message}}", message) + .replace("{{category}}", category) if (model && systemMessage && examples && userMessage) { const response = await callChatCompletion( model, diff --git a/functions/src/definitions/common/openai/hyperparameters.json b/functions/src/definitions/common/openai/hyperparameters.json index 982c7f5c..e810e017 100644 --- a/functions/src/definitions/common/openai/hyperparameters.json +++ b/functions/src/definitions/common/openai/hyperparameters.json @@ -23,9 +23,18 @@ "rationalisation": { "model": "gpt-3.5-turbo", "prompt": { - "system": "bla", - "examples": [], - "user": "" + "system": "You are a scam and misinformation analyst whose job is to explain the category assigned to each message by a group of professional fact-checkers. You will receive text messages delimited in triple backticks, and the accompanying category, also delimited in triple backticks. Provide 3 or fewer reasons to explain briefly and directly to the person in a layman fashion why the message could have been given this category. Where relevant, you may use Cialdini's principles of persuasion (reciprocity, commitment and consistency, social proof, authority, liking, scarcity) to explain the category assigned to the message.", + "examples": [ + { + "user": "Text Message:\n```Hello,Vanessa from Sentosa Marketing Department. Wish you have a nice day.We are doing a survey (about Resort Development), can you assist? Get 15 SGD (Paynow) by answering 3 simple questions.```\n\nAssigned Category:\n```scam```\n", + "assistant": "Here are some signs that this message is a scam\n1) It is offering something valuable to the recipient (money), which could be a tactic to persuade the recipient to engage\n2) It is written in poor English, and has bad formatting\n3) The sender is trying to get you to share information with them by appearing friendly and approachable." + }, + { + "user": "Text Message:\n```The FASTEST FINANCIAL APPROVAL COMPANY IN TOWN! Apply up to 2 times INCOME**may apply. $10K=900x12 Month\n$20K=1800x12 Month\n$30K=2750x12 Month\nUp to 100k, 36 Month\nCALL US TODAY HP: 83750447 Sean- 2-3hrs APPROVAL ONLY FOR PINK/BLUE IC```\n\nAssigned Category:\n```illicit```\n", + "assistant": "Here are some signs that this message is illicit\n1) It is promoting a potentially illegal or unauthorized moneylending service\n2) It promises to speed up your loan process as much as possible, which may be valuable to people in urgent need of money\n2) It is offering installment plans without providing any information about the terms, conditions, or legality of the service. This lack of transparency raises concerns about the legitimacy and reliability of the financial services offered." + } + ], + "user": "Text Message:\n```{{message}}```\n\nAssigned Category:\n```{{category}}```\n" } } } From b62fa706f1bebc5acc0ea923a423423ad1997ab4 Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sat, 14 Oct 2023 12:02:36 +0800 Subject: [PATCH 10/15] moved up SIT return for genAI --- functions/src/definitions/common/genAI.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/functions/src/definitions/common/genAI.ts b/functions/src/definitions/common/genAI.ts index fc207e66..84fa0e66 100644 --- a/functions/src/definitions/common/genAI.ts +++ b/functions/src/definitions/common/genAI.ts @@ -72,7 +72,9 @@ async function rationaliseMessage(message: string, category: string) { if (category.includes("irrelevant") || category === "unsure") { return null } - + if (env === "SIT") { + return "This is a rationalisation" + } let meaningfulLength: number = 300 switch (category) { case "illicit": @@ -93,9 +95,6 @@ async function rationaliseMessage(message: string, category: string) { //don't bother with rationalisation if remaining message is too short to be meaningful. return null } - if (env === "SIT") { - return "This is a rationalisation" - } try { const rationalisationHyperparameters = hyperparameters?.rationalisation const model: string = rationalisationHyperparameters.model From 5091ba4840833d4dcdd73733a431002cd1e34ea5 Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sun, 15 Oct 2023 19:46:48 +0800 Subject: [PATCH 11/15] accept statuses and remove separ8 nonprod env var --- .../definitions/common/sendWhatsappMessage.ts | 21 +--- .../definitions/webhookHandlers/whatsapp.ts | 108 +++++++++--------- 2 files changed, 60 insertions(+), 69 deletions(-) diff --git a/functions/src/definitions/common/sendWhatsappMessage.ts b/functions/src/definitions/common/sendWhatsappMessage.ts index 4f9f1a7c..aefffbc0 100644 --- a/functions/src/definitions/common/sendWhatsappMessage.ts +++ b/functions/src/definitions/common/sendWhatsappMessage.ts @@ -4,13 +4,6 @@ import { defineString } from "firebase-functions/params" import { WhatsappButton } from "../../types" const graphApiVersion = defineString("GRAPH_API_VERSION") -const runtimeEnvironment = defineString("ENVIRONMENT") -const testUserPhoneNumberId = defineString( - "WHATSAPP_TEST_USER_BOT_PHONE_NUMBER_ID" -) -const testCheckerPhoneNumberId = defineString( - "WHATSAPP_TEST_CHECKER_BOT_PHONE_NUMBER_ID" -) const graphApiUrl = process.env["TEST_SERVER_URL"] || "https://graph.facebook.com" //only exists in integration test environment @@ -327,18 +320,10 @@ async function markWhatsappMessageAsRead(bot: string, messageId: string) { async function callWhatsappSendMessageApi(data: any, bot: string) { const token = process.env.WHATSAPP_TOKEN let phoneNumberId - if (runtimeEnvironment.value() !== "PROD") { - if (bot == "factChecker") { - phoneNumberId = testCheckerPhoneNumberId.value() - } else { - phoneNumberId = testUserPhoneNumberId.value() - } + if (bot == "factChecker") { + phoneNumberId = process.env.WHATSAPP_CHECKERS_BOT_PHONE_NUMBER_ID } else { - if (bot == "factChecker") { - phoneNumberId = process.env.WHATSAPP_CHECKERS_BOT_PHONE_NUMBER_ID - } else { - phoneNumberId = process.env.WHATSAPP_USER_BOT_PHONE_NUMBER_ID - } + phoneNumberId = process.env.WHATSAPP_USER_BOT_PHONE_NUMBER_ID } const response = await axios({ method: "POST", // Required, HTTP method, a string, e.g. POST, GET diff --git a/functions/src/definitions/webhookHandlers/whatsapp.ts b/functions/src/definitions/webhookHandlers/whatsapp.ts index 261fd53e..dbf58060 100644 --- a/functions/src/definitions/webhookHandlers/whatsapp.ts +++ b/functions/src/definitions/webhookHandlers/whatsapp.ts @@ -6,17 +6,8 @@ import { handleSpecialCommands } from "./specialCommands" import { publishToTopic } from "../common/pubsub" import { onRequest } from "firebase-functions/v2/https" import { checkMessageId } from "../common/utils" -import { user } from "firebase-functions/v1/auth" const runtimeEnvironment = defineString("ENVIRONMENT") -const testUserPhoneNumberId = defineString( - "WHATSAPP_TEST_USER_BOT_PHONE_NUMBER_ID" -) -const testCheckerPhoneNumberId = defineString( - "WHATSAPP_TEST_CHECKER_BOT_PHONE_NUMBER_ID" -) -const testUserWABAId = defineString("WHATSAPP_TEST_USERS_WABA_ID") -const testCheckerWABAId = defineString("WHATSAPP_TEST_CHECKERS_WABA_ID") if (!admin.apps.length) { admin.initializeApp() @@ -31,68 +22,83 @@ app.post("/whatsapp", async (req, res) => { req.body.entry[0].id && req.body.entry[0].changes && req.body.entry[0].changes[0] && - req.body.entry[0].changes[0].value.messages && - req.body.entry[0].changes[0].value.messages[0] + req.body.entry[0].changes[0].value ) { let value = req.body.entry[0].changes[0].value let phoneNumberId = value.metadata.phone_number_id - let message = value.messages[0] - let type = message.type let wabaID = req.body.entry[0].id let checkerPhoneNumberId let userPhoneNumberId let checkerWabaId let userWabaId - if (runtimeEnvironment.value() === "PROD") { - checkerPhoneNumberId = process.env.WHATSAPP_CHECKERS_BOT_PHONE_NUMBER_ID - userPhoneNumberId = process.env.WHATSAPP_USER_BOT_PHONE_NUMBER_ID - checkerWabaId = process.env.WHATSAPP_CHECKERS_WABA_ID - userWabaId = process.env.WHATSAPP_USERS_WABA_ID - } else { - checkerPhoneNumberId = testCheckerPhoneNumberId.value() - userPhoneNumberId = testUserPhoneNumberId.value() - checkerWabaId = testCheckerWABAId.value() - userWabaId = testUserWABAId.value() - } + checkerPhoneNumberId = process.env.WHATSAPP_CHECKERS_BOT_PHONE_NUMBER_ID + userPhoneNumberId = process.env.WHATSAPP_USER_BOT_PHONE_NUMBER_ID + checkerWabaId = process.env.WHATSAPP_CHECKERS_WABA_ID + userWabaId = process.env.WHATSAPP_USERS_WABA_ID if ( (phoneNumberId === checkerPhoneNumberId && wabaID === checkerWabaId) || (phoneNumberId === userPhoneNumberId && wabaID === userWabaId) ) { - if ( - type == "text" && - message.text.body.startsWith("/") && - runtimeEnvironment.value() !== "PROD" - ) { - //handle db commands - await handleSpecialCommands(message) - } else { - if (message?.id) { - //if message has been processed before, don't even put it in queue. - if (await checkMessageId(message.id)) { - functions.logger.warn(`message ${message.id} already processed`) + if (value.messages && value.messages[0]) { + let message = value.messages[0] + let type = message.type + if ( + type == "text" && + message.text.body.startsWith("/") && + runtimeEnvironment.value() !== "PROD" + ) { + //handle db commands + await handleSpecialCommands(message) + } else { + if (message?.id) { + //if message has been processed before, don't even put it in queue. + if (await checkMessageId(message.id)) { + functions.logger.warn(`message ${message.id} already processed`) + res.sendStatus(200) + return + } + } else { + functions.logger.error(`message ${message.id} has no id`) res.sendStatus(200) return } - } else { - functions.logger.error(`message ${message.id} has no id`) - res.sendStatus(200) - return - } - if ( - (type == "button" || type == "interactive" || type == "text") && - phoneNumberId === checkerPhoneNumberId - ) { - //put into checker queue - await publishToTopic("checkerEvents", message) + if ( + (type == "button" || type == "interactive" || type == "text") && + phoneNumberId === checkerPhoneNumberId + ) { + //put into checker queue + await publishToTopic("checkerEvents", message) + } + if (phoneNumberId === userPhoneNumberId) { + //put into user queue + await publishToTopic("userEvents", message) + } } - if (phoneNumberId === userPhoneNumberId) { - //put into user queue - await publishToTopic("userEvents", message) + res.sendStatus(200) + } else if (value.statuses && value.statuses[0]) { + let status = value.statuses[0] + let bot = phoneNumberId === checkerPhoneNumberId ? "checker" : "user" + if (status.status === "failed") { + const errorObj = { + messageId: status.id, + timestamp: status.timestamp, + recipientId: status.recipient_id, + errors: status.errors, + displayPhoneNumber: value.metadata.displayPhoneNumber, + bot: bot, + } + functions.logger.error( + `Error sending message ${status.id} to ${status.recipient_id} from ${bot} bot`, + errorObj + ) } + res.sendStatus(200) + } else { + functions.logger.log(`Not a message or status update`) + res.sendStatus(200) } - res.sendStatus(200) } else { functions.logger.warn( `Unexpected message source from phoneNumberId ${phoneNumberId}` From e57720863e675d88452f2d4e1986a9a8149a28b4 Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sun, 15 Oct 2023 19:50:03 +0800 Subject: [PATCH 12/15] fixed tests too --- functions/.env.local.test | 6 +----- functions/.secret.local.test | 8 ++++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/functions/.env.local.test b/functions/.env.local.test index ddd6408f..541462fd 100644 --- a/functions/.env.local.test +++ b/functions/.env.local.test @@ -4,8 +4,6 @@ GRAPH_API_VERSION=v15.0 TEST_SERVER_URL=http://resultserver:12345 ENVIRONMENT=SIT SPREADSHEET_ID=SPREADSHEET_ID -WHATSAPP_TEST_USER_BOT_PHONE_NUMBER_ID=WHATSAPP_TEST_USER_BOT_PHONE_NUMBER_ID -WHATSAPP_TEST_CHECKER_BOT_PHONE_NUMBER_ID=WHATSAPP_TEST_CHECKER_BOT_PHONE_NUMBER_ID CHECKER1_PHONE_NUMBER=6511111111 SIMILARITY_THRESHOLD=0.85 TYPESENSE_HOST=typesense-server @@ -14,6 +12,4 @@ TYPESENSE_PROTOCOL=http EMBEDDER_HOST=http://embedder-server:12344 TELEGRAM_REPORT_CHANNEL_ID=111111111 TEST_IMAGE_URL=TEST -HASHIDS_SALT=SALT -WHATSAPP_TEST_USERS_WABA_ID=WHATSAPP_TEST_USER_WABA_ID -WHATSAPP_TEST_CHECKERS_WABA_ID=WHATSAPP_TEST_CHECKER_WABA_ID \ No newline at end of file +HASHIDS_SALT=SALT \ No newline at end of file diff --git a/functions/.secret.local.test b/functions/.secret.local.test index 46910414..82cfc551 100644 --- a/functions/.secret.local.test +++ b/functions/.secret.local.test @@ -1,5 +1,5 @@ -WHATSAPP_USER_BOT_PHONE_NUMBER_ID=WHATSAPP_USER_BOT_PHONE_NUMBER_ID -WHATSAPP_CHECKERS_BOT_PHONE_NUMBER_ID=WHATSAPP_CHECKERS_BOT_PHONE_NUMBER_ID +WHATSAPP_USER_BOT_PHONE_NUMBER_ID=WHATSAPP_TEST_USER_BOT_PHONE_NUMBER_ID +WHATSAPP_CHECKERS_BOT_PHONE_NUMBER_ID=WHATSAPP_TEST_CHECKER_BOT_PHONE_NUMBER_ID WHATSAPP_TOKEN=WHATSAPP_TOKEN TELEGRAM_CHECKER_BOT_TOKEN=TELEGRAM_CHECKER_BOT_TOKEN TELEGRAM_REPORT_BOT_TOKEN=TELEGRAM_REPORT_BOT_TOKEN @@ -8,5 +8,5 @@ BITLY_TOKEN=BITLY_TOKEN TYPESENSE_TOKEN=TYPESENSE_TOKEN ML_SERVER_TOKEN=ML_SERVER_TOKEN TELEGRAM_BOT_TOKEN=TELEGRAM_BOT_TOKEN -WHATSAPP_USERS_WABA_ID=WHATSAPP_USERS_WABA_ID -WHATSAPP_CHECKERS_WABA_ID=WHATSAPP_CHECKERS_WABA_ID \ No newline at end of file +WHATSAPP_USERS_WABA_ID=WHATSAPP_TEST_USER_WABA_ID +WHATSAPP_CHECKERS_WABA_ID=WHATSAPP_TEST_CHECKER_WABA_ID \ No newline at end of file From 63c2f24c2a9d892e97d73323b3a20daf327508ed Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sun, 22 Oct 2023 15:41:20 +0800 Subject: [PATCH 13/15] shortened if checks --- .../src/definitions/webhookHandlers/whatsapp.ts | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/functions/src/definitions/webhookHandlers/whatsapp.ts b/functions/src/definitions/webhookHandlers/whatsapp.ts index dbf58060..d88fc2fa 100644 --- a/functions/src/definitions/webhookHandlers/whatsapp.ts +++ b/functions/src/definitions/webhookHandlers/whatsapp.ts @@ -17,13 +17,7 @@ const app = express() // Accepts POST requests at /webhook endpoint app.post("/whatsapp", async (req, res) => { if (req.body.object) { - if ( - req.body.entry && - req.body.entry[0].id && - req.body.entry[0].changes && - req.body.entry[0].changes[0] && - req.body.entry[0].changes[0].value - ) { + if (req?.body?.entry?.[0]?.changes?.[0]?.value) { let value = req.body.entry[0].changes[0].value let phoneNumberId = value.metadata.phone_number_id let wabaID = req.body.entry[0].id @@ -41,7 +35,7 @@ app.post("/whatsapp", async (req, res) => { (phoneNumberId === checkerPhoneNumberId && wabaID === checkerWabaId) || (phoneNumberId === userPhoneNumberId && wabaID === userWabaId) ) { - if (value.messages && value.messages[0]) { + if (value?.messages?.[0]) { let message = value.messages[0] let type = message.type if ( @@ -77,7 +71,7 @@ app.post("/whatsapp", async (req, res) => { } } res.sendStatus(200) - } else if (value.statuses && value.statuses[0]) { + } else if (value?.statuses?.[0]) { let status = value.statuses[0] let bot = phoneNumberId === checkerPhoneNumberId ? "checker" : "user" if (status.status === "failed") { From 8e9bf1f42c985edeafc8c78a2a295f23faa7925c Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sun, 22 Oct 2023 16:59:33 +0800 Subject: [PATCH 14/15] handle failures of machine learning server --- .../definitions/common/calculateSimilarity.ts | 10 +++++++--- functions/src/definitions/common/classifier.ts | 16 +++++++++++----- .../definitions/eventHandlers/userHandlers.ts | 2 +- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/functions/src/definitions/common/calculateSimilarity.ts b/functions/src/definitions/common/calculateSimilarity.ts index 35453823..3e6ba0f6 100644 --- a/functions/src/definitions/common/calculateSimilarity.ts +++ b/functions/src/definitions/common/calculateSimilarity.ts @@ -25,8 +25,12 @@ async function calculateSimilarity( score?: number parent?: admin.firestore.DocumentReference | null } = {} - const embedding = await getEmbedding(text) - + let embedding = null + try { + embedding = await getEmbedding(text) + } catch (e) { + functions.logger.error(`Error in getEmbedding: ${e}`) + } //try to match db first const matchedInstancesSnap = await db .collectionGroup(CollectionTypes.Instances) @@ -47,7 +51,7 @@ async function calculateSimilarity( // don't bother with vector search if remaining message is too short to be meaningful. functions.logger.log("Remaining message text too short to match") similarity = {} - } else { + } else if (embedding) { const results = await vectorSearch( embedding, CollectionTypes.Instances, diff --git a/functions/src/definitions/common/classifier.ts b/functions/src/definitions/common/classifier.ts index 7d2b5a23..94688541 100644 --- a/functions/src/definitions/common/classifier.ts +++ b/functions/src/definitions/common/classifier.ts @@ -1,14 +1,20 @@ import { getL1Category } from "./machineLearningServer/operations" +import * as functions from "firebase-functions" async function classifyText(text: string): Promise { if (text.length < 8) { return "irrelevant_length" } - const category = await getL1Category(text) - if (category === "trivial") { - return "irrelevant" - } else { - return category + try { + const category = await getL1Category(text) + if (category === "trivial") { + return "irrelevant" + } else { + return category + } + } catch (e) { + functions.logger.error(`Error in classifyText: ${e}`) + return "error" } } diff --git a/functions/src/definitions/eventHandlers/userHandlers.ts b/functions/src/definitions/eventHandlers/userHandlers.ts index 566ab213..d565ba4e 100644 --- a/functions/src/definitions/eventHandlers/userHandlers.ts +++ b/functions/src/definitions/eventHandlers/userHandlers.ts @@ -411,7 +411,7 @@ async function newTextInstanceHandler({ replyTimestamp: null, matchType: matchType, scamShieldConsent: null, - embedding: embedding, + embedding: embedding ?? null, closestMatch: { instanceRef: bestMatchingDocumentRef ?? null, text: bestMatchingText ?? null, From 8f0796b487e1584441d283cba52c6eb20396016d Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Mon, 23 Oct 2023 22:13:27 +0800 Subject: [PATCH 15/15] openAI API key should be in onMessageUpdate --- .../src/definitions/eventHandlers/onMessageUpdate.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/functions/src/definitions/eventHandlers/onMessageUpdate.ts b/functions/src/definitions/eventHandlers/onMessageUpdate.ts index 6fe53e2c..79b2ca7a 100644 --- a/functions/src/definitions/eventHandlers/onMessageUpdate.ts +++ b/functions/src/definitions/eventHandlers/onMessageUpdate.ts @@ -5,7 +5,13 @@ import { rationaliseMessage } from "../common/genAI" const onMessageUpdate = functions .region("asia-southeast1") - .runWith({ secrets: ["WHATSAPP_USER_BOT_PHONE_NUMBER_ID", "WHATSAPP_TOKEN"] }) + .runWith({ + secrets: [ + "WHATSAPP_USER_BOT_PHONE_NUMBER_ID", + "WHATSAPP_TOKEN", + "OPENAI_API_KEY", + ], + }) .firestore.document("/messages/{messageId}") .onUpdate(async (change, context) => { // Grab the current value of what was written to Firestore.