diff --git a/.cspell.json b/.cspell.json index 733671ee..9fece9a7 100644 --- a/.cspell.json +++ b/.cspell.json @@ -47,6 +47,8 @@ "ubiquibot", "UBIQUIBOT", "URLSAFE", + "UUSD", + "vitest", "WXDAI", "XDAI", "xmark" diff --git a/.github/knip.ts b/.github/knip.ts index c70c9889..3abdd87d 100644 --- a/.github/knip.ts +++ b/.github/knip.ts @@ -6,7 +6,7 @@ const config: KnipConfig = { ignore: ["src/types/config.ts", "**/__mocks__/**", "**/__fixtures__/**", "lib/**/*"], ignoreExportsUsedInFile: true, // eslint can also be safely ignored as per the docs: https://knip.dev/guides/handling-issues#eslint--jest - ignoreDependencies: ["eslint-config-prettier", "eslint-plugin-prettier"], + ignoreDependencies: ["eslint-config-prettier", "eslint-plugin-prettier", "cloudflare"], eslint: true, ignoreBinaries: ["forge"], }; diff --git a/.github/workflows/vitest-unit-tests.yml b/.github/workflows/vitest-unit-tests.yml new file mode 100644 index 00000000..d6dde251 --- /dev/null +++ b/.github/workflows/vitest-unit-tests.yml @@ -0,0 +1,26 @@ +name: Run unit tests for pages functions +on: + workflow_dispatch: + pull_request: + push: + +env: + NODE_ENV: "test" + +jobs: + testing: + runs-on: ubuntu-latest + + steps: + - uses: actions/setup-node@v4 + with: + node-version: "20.10.0" + + - name: Checkout code + uses: actions/checkout@v3 + + - name: Install dependencies + run: yarn + + - name: Run tests + run: npx vitest --run diff --git a/functions/get-best-card.ts b/functions/get-best-card.ts index 5bd9e4a1..00703beb 100644 --- a/functions/get-best-card.ts +++ b/functions/get-best-card.ts @@ -1,8 +1,9 @@ import { BigNumber } from "ethers"; -import { getAccessToken, findBestCard } from "./helpers"; -import { Context } from "./types"; -import { validateEnvVars, validateRequestMethod } from "./validators"; import { getBestCardParamsSchema } from "../shared/api-types"; +import { findBestCard } from "./utils/best-card-finder"; +import { getAccessToken } from "./utils/shared"; +import { Context } from "./utils/types"; +import { validateEnvVars, validateRequestMethod } from "./utils/validators"; export async function onRequest(ctx: Context): Promise { try { @@ -20,6 +21,7 @@ export async function onRequest(ctx: Context): Promise { const { country, amount } = result.data; const accessToken = await getAccessToken(ctx.env); + const bestCard = await findBestCard(country, BigNumber.from(amount), accessToken); if (bestCard) { diff --git a/functions/get-order.ts b/functions/get-order.ts index 5f60eccb..3b2631af 100644 --- a/functions/get-order.ts +++ b/functions/get-order.ts @@ -1,8 +1,8 @@ import { OrderTransaction } from "../shared/types"; -import { commonHeaders, getAccessToken, getBaseUrl } from "./helpers"; +import { commonHeaders, getAccessToken, getReloadlyApiBaseUrl } from "./utils/shared"; import { getGiftCardById } from "./post-order"; -import { AccessToken, Context, ReloadlyFailureResponse, ReloadlyGetTransactionResponse } from "./types"; -import { validateEnvVars, validateRequestMethod } from "./validators"; +import { AccessToken, Context, ReloadlyFailureResponse, ReloadlyGetTransactionResponse } from "./utils/types"; +import { validateEnvVars, validateRequestMethod } from "./utils/validators"; import { getOrderParamsSchema } from "../shared/api-types"; export async function onRequest(ctx: Context): Promise { @@ -46,7 +46,7 @@ export async function getTransactionFromOrderId(orderId: string, accessToken: Ac const oneYearAgo = new Date(new Date().setFullYear(new Date().getFullYear() - 1)); const oneYearAgoFormatted = oneYearAgo.toISOString().replace("T", " ").substring(0, 19); - const url = `${getBaseUrl(accessToken.isSandbox)}/reports/transactions?size=1&page=1&customIdentifier=${orderId}&startDate=${oneYearAgoFormatted}&endDate=${nowFormatted}`; + const url = `${getReloadlyApiBaseUrl(accessToken.isSandbox)}/reports/transactions?size=1&page=1&customIdentifier=${orderId}&startDate=${oneYearAgoFormatted}&endDate=${nowFormatted}`; console.log(`Retrieving transaction from ${url}`); const options = { method: "GET", diff --git a/functions/get-redeem-code.ts b/functions/get-redeem-code.ts index 13ab251f..10b7a28b 100644 --- a/functions/get-redeem-code.ts +++ b/functions/get-redeem-code.ts @@ -1,10 +1,10 @@ -import { verifyMessage } from "ethers/lib/utils"; +import { verifyMessage } from "@ethersproject/wallet"; import { getGiftCardOrderId, getMessageToSign } from "../shared/helpers"; import { getRedeemCodeParamsSchema } from "../shared/api-types"; import { getTransactionFromOrderId } from "./get-order"; -import { commonHeaders, getAccessToken, getBaseUrl } from "./helpers"; -import { AccessToken, Context, ReloadlyFailureResponse, ReloadlyRedeemCodeResponse } from "./types"; -import { validateEnvVars, validateRequestMethod } from "./validators"; +import { commonHeaders, getAccessToken, getReloadlyApiBaseUrl } from "./utils/shared"; +import { AccessToken, Context, ReloadlyFailureResponse, ReloadlyRedeemCodeResponse } from "./utils/types"; +import { validateEnvVars, validateRequestMethod } from "./utils/validators"; import { RedeemCode } from "../shared/types"; export async function onRequest(ctx: Context): Promise { @@ -42,12 +42,12 @@ export async function onRequest(ctx: Context): Promise { const orderId = getGiftCardOrderId(wallet, permitSig); const order = await getTransactionFromOrderId(orderId, accessToken); - if (order.transactionId != transactionId) { + if (order?.transactionId != transactionId) { console.error( `Given transaction does not match with retrieved transactionId using generated orderId: ${JSON.stringify({ transactionId, orderId, - transactionIdFromOrder: order.transactionId, + transactionIdFromOrder: order?.transactionId, })}` ); return errorResponse; @@ -62,7 +62,7 @@ export async function onRequest(ctx: Context): Promise { } export async function getRedeemCode(transactionId: number, accessToken: AccessToken): Promise { - const url = `${getBaseUrl(accessToken.isSandbox)}/orders/transactions/${transactionId}/cards`; + const url = `${getReloadlyApiBaseUrl(accessToken.isSandbox)}/orders/transactions/${transactionId}/cards`; console.log(`Retrieving redeem codes from ${url}`); const options = { method: "GET", diff --git a/functions/helpers.ts b/functions/helpers.ts deleted file mode 100644 index cd300a13..00000000 --- a/functions/helpers.ts +++ /dev/null @@ -1,200 +0,0 @@ -import { BigNumberish } from "ethers"; -import { isAllowed } from "../shared/allowed-country-list"; -import { isGiftCardAvailable } from "../shared/helpers"; -import { GiftCard } from "../shared/types"; -import { getGiftCardById } from "./post-order"; -import { fallbackIntlMastercard, fallbackIntlVisa, masterCardIntlSkus, visaIntlSkus } from "./reloadly-lists"; -import { AccessToken, ReloadlyFailureResponse } from "./types"; - -export const commonHeaders = { - "Content-Type": "application/json", - Accept: "application/com.reloadly.giftcards-v1+json", -}; - -export interface Env { - USE_RELOADLY_SANDBOX: string; - RELOADLY_API_CLIENT_ID: string; - RELOADLY_API_CLIENT_SECRET: string; -} - -export interface ReloadlyAuthResponse { - access_token: string; - scope: string; - expires_in: number; - token_type: string; -} - -export async function getAccessToken(env: Env): Promise { - console.log("Using Reloadly Sandbox:", env.USE_RELOADLY_SANDBOX !== "false"); - - const url = "https://auth.reloadly.com/oauth/token"; - const options = { - method: "POST", - headers: { "Content-Type": "application/json", Accept: "application/json" }, - body: JSON.stringify({ - client_id: env.RELOADLY_API_CLIENT_ID, - client_secret: env.RELOADLY_API_CLIENT_SECRET, - grant_type: "client_credentials", - audience: env.USE_RELOADLY_SANDBOX === "false" ? "https://giftcards.reloadly.com" : "https://giftcards-sandbox.reloadly.com", - }), - }; - - const res = await fetch(url, options); - if (res.status == 200) { - const successResponse = (await res.json()) as ReloadlyAuthResponse; - return { - token: successResponse.access_token, - isSandbox: env.USE_RELOADLY_SANDBOX !== "false", - }; - } - throw `Getting access token failed: ${JSON.stringify(await res.json())}`; -} - -export function getBaseUrl(isSandbox: boolean): string { - if (isSandbox === false) { - return "https://web3-gateway-test.com/proxy/reloadly/production"; - } - return "https://giftcards-sandbox.reloadly.com"; -} - -export async function findBestCard(countryCode: string, amount: BigNumberish, accessToken: AccessToken): Promise { - if (!isAllowed(countryCode)) { - throw new Error(`Country ${countryCode} is not in the allowed country list.`); - } - - const masterCards = await getGiftCards("mastercard", countryCode, accessToken); - - const masterCardIntlSku = masterCardIntlSkus.find((sku) => sku.countryCode == countryCode); - if (masterCardIntlSku) { - const tokenizedIntlMastercard = masterCards.find((masterCard) => masterCard.productId == masterCardIntlSku.sku); - if (tokenizedIntlMastercard && isGiftCardAvailable(tokenizedIntlMastercard, amount)) { - return tokenizedIntlMastercard; - } - } - - const fallbackMastercard = await getFallbackIntlMastercard(accessToken); - if (fallbackMastercard && isGiftCardAvailable(fallbackMastercard, amount)) { - return fallbackMastercard; - } - - const visaCards = await getGiftCards("visa", countryCode, accessToken); - const visaIntlSku = visaIntlSkus.find((sku) => sku.countryCode == countryCode); - if (visaIntlSku) { - const intlVisa = visaCards.find((visaCard) => visaCard.productId == visaIntlSku.sku); - if (intlVisa && isGiftCardAvailable(intlVisa, amount)) { - return intlVisa; - } - } - - const fallbackVisa = await getFallbackIntlVisa(accessToken); - if (fallbackVisa && isGiftCardAvailable(fallbackVisa, amount)) { - return fallbackVisa; - } - - const anyMastercard = masterCards.find((masterCard) => isGiftCardAvailable(masterCard, amount)); - if (anyMastercard) { - return anyMastercard; - } - - const anyVisa = visaCards.find((visaCard) => isGiftCardAvailable(visaCard, amount)); - if (anyVisa) { - return anyVisa; - } - - throw new Error(`No suitable card found for country code ${countryCode} and amount ${amount}.`); -} - -async function getFallbackIntlMastercard(accessToken: AccessToken): Promise { - try { - return await getGiftCardById(fallbackIntlMastercard.sku, accessToken); - } catch (e) { - console.error(`Failed to load international US mastercard: ${JSON.stringify(fallbackIntlMastercard)}`, e); - return null; - } -} - -async function getFallbackIntlVisa(accessToken: AccessToken): Promise { - try { - return await getGiftCardById(fallbackIntlVisa.sku, accessToken); - } catch (e) { - console.error(`Failed to load international US visa: ${JSON.stringify(fallbackIntlVisa)}\n${e}`); - return null; - } -} - -export async function getGiftCards(productQuery: string, country: string, accessToken: AccessToken): Promise { - if (accessToken.isSandbox) { - // Load product differently on Reloadly sandbox - // Sandbox doesn't have mastercard, it has only 1 visa card for US. - // This visa card doesn't load with location based url, let's use special url - // for this so that we have something to try on sandbox - return await getSandboxGiftCards(productQuery, country, accessToken); - } - // productCategoryId = 1 = Finance. - // This should prevent mixing of other gift cards with similar keywords - const url = `${getBaseUrl(accessToken.isSandbox)}/countries/${country}/products?productName=${productQuery}&productCategoryId=1`; - - console.log(`Retrieving gift cards from ${url}`); - const options = { - method: "GET", - headers: { - ...commonHeaders, - Authorization: `Bearer ${accessToken.token}`, - }, - }; - - const response = await fetch(url, options); - const responseJson = await response.json(); - - console.log("Response status", response.status); - console.log(`Response from ${url}`, responseJson); - - if (response.status == 404) { - return []; - } - - if (response.status != 200) { - throw new Error( - `Error from Reloadly API: ${JSON.stringify({ - status: response.status, - message: (responseJson as ReloadlyFailureResponse).message, - })}` - ); - } - - return responseJson as GiftCard[]; -} - -async function getSandboxGiftCards(productQuery: string, country: string, accessToken: AccessToken): Promise { - const url = `${getBaseUrl(accessToken.isSandbox)}/products?productName=${productQuery}&productCategoryId=1`; - - console.log(`Retrieving gift cards from ${url}`); - const options = { - method: "GET", - headers: { - ...commonHeaders, - Authorization: `Bearer ${accessToken.token}`, - }, - }; - - const response = await fetch(url, options); - const responseJson = await response.json(); - - console.log("Response status", response.status); - console.log(`Response from ${url}`, responseJson); - - if (response.status == 404) { - return []; - } - - if (response.status != 200) { - throw new Error( - `Error from Reloadly API: ${JSON.stringify({ - status: response.status, - message: (responseJson as ReloadlyFailureResponse).message, - })}` - ); - } - - return (responseJson as { content: GiftCard[] })?.content; -} diff --git a/functions/post-order.ts b/functions/post-order.ts index 01584da4..a01463e3 100644 --- a/functions/post-order.ts +++ b/functions/post-order.ts @@ -1,7 +1,7 @@ -import { TransactionReceipt, TransactionResponse } from "@ethersproject/providers"; -import { JsonRpcProvider } from "@ethersproject/providers/lib/json-rpc-provider"; +import { JsonRpcProvider, TransactionReceipt, TransactionResponse } from "@ethersproject/providers"; + import { BigNumber } from "ethers"; -import { Interface, TransactionDescription } from "ethers/lib/utils"; +import { Interface, TransactionDescription } from "@ethersproject/abi"; import { Tokens, chainIdToRewardTokenMap, giftCardTreasuryAddress, permit2Address } from "../shared/constants"; import { getFastestRpcUrl, getGiftCardOrderId } from "../shared/helpers"; import { getGiftCardValue, isClaimableForAmount } from "../shared/pricing"; @@ -9,11 +9,12 @@ import { ExchangeRate, GiftCard } from "../shared/types"; import { permit2Abi } from "../static/scripts/rewards/abis/permit2-abi"; import { erc20Abi } from "../static/scripts/rewards/abis/erc20-abi"; import { getTransactionFromOrderId } from "./get-order"; -import { commonHeaders, findBestCard, getAccessToken, getBaseUrl } from "./helpers"; -import { AccessToken, Context, ReloadlyFailureResponse, ReloadlyOrderResponse } from "./types"; -import { validateEnvVars, validateRequestMethod } from "./validators"; +import { commonHeaders, getAccessToken, getReloadlyApiBaseUrl } from "./utils/shared"; +import { AccessToken, Context, ReloadlyFailureResponse, ReloadlyOrderResponse } from "./utils/types"; +import { validateEnvVars, validateRequestMethod } from "./utils/validators"; import { postOrderParamsSchema } from "../shared/api-types"; import { permitAllowedChainIds, ubiquityDollarAllowedChainIds, ubiquityDollarChainAddresses } from "../shared/constants"; +import { findBestCard } from "./utils/best-card-finder"; export async function onRequest(ctx: Context): Promise { try { @@ -110,7 +111,7 @@ export async function onRequest(ctx: Context): Promise { } export async function getGiftCardById(productId: number, accessToken: AccessToken): Promise { - const url = `${getBaseUrl(accessToken.isSandbox)}/products/${productId}`; + const url = `${getReloadlyApiBaseUrl(accessToken.isSandbox)}/products/${productId}`; console.log(`Retrieving gift cards from ${url}`); const options = { method: "GET", @@ -138,7 +139,7 @@ export async function getGiftCardById(productId: number, accessToken: AccessToke } async function orderGiftCard(productId: number, cardValue: number, identifier: string, accessToken: AccessToken): Promise { - const url = `${getBaseUrl(accessToken.isSandbox)}/orders`; + const url = `${getReloadlyApiBaseUrl(accessToken.isSandbox)}/orders`; console.log(`Placing order at url: ${url}`); const requestBody = JSON.stringify({ @@ -189,7 +190,7 @@ async function isDuplicateOrder(orderId: string, accessToken: AccessToken): Prom } async function getExchangeRate(usdAmount: number, fromCurrency: string, accessToken: AccessToken): Promise { - const url = `${getBaseUrl(accessToken.isSandbox)}/fx-rate?currencyCode=${fromCurrency}&amount=${usdAmount}`; + const url = `${getReloadlyApiBaseUrl(accessToken.isSandbox)}/fx-rate?currencyCode=${fromCurrency}&amount=${usdAmount}`; console.log(`Retrieving url ${url}`); const options = { method: "GET", diff --git a/functions/utils/best-card-finder.ts b/functions/utils/best-card-finder.ts new file mode 100644 index 00000000..492fc4b4 --- /dev/null +++ b/functions/utils/best-card-finder.ts @@ -0,0 +1,135 @@ +import { BigNumberish } from "ethers"; +import { isAllowed } from "../../shared/allowed-country-list"; +import { isGiftCardAvailable } from "../../shared/helpers"; +import { GiftCard } from "../../shared/types"; +import { commonHeaders, getGiftCards, getReloadlyApiBaseUrl } from "./shared"; +import { getGiftCardById } from "../post-order"; +import { fallbackIntlMastercard, fallbackIntlVisa, masterCardIntlSkus, visaIntlSkus } from "./reloadly-lists"; +import { AccessToken, ReloadlyFailureResponse } from "./types"; + +export async function findBestCard(countryCode: string, amount: BigNumberish, accessToken: AccessToken): Promise { + if (!isAllowed(countryCode)) { + console.error(`Country ${countryCode} is not in the allowed country list.`); + return null; + } + + if (accessToken.isSandbox) { + // Load product differently on Reloadly sandbox + // Sandbox doesn't have mastercard, it has only 1 visa card for US. + // This visa card doesn't load with location based url, let's use special url + // for this so that we have something to try on sandbox + return await getSandboxGiftCard("visa", countryCode, accessToken); + } + const masterCards = await getGiftCards("mastercard", countryCode, accessToken); + const bestMastercard = await findBestMastercard(masterCards, countryCode, amount, accessToken); + if (bestMastercard) { + return bestMastercard; + } + + const visaCards = await getGiftCards("visa", countryCode, accessToken); + const bestVisaCard = await findBestVisaCard(visaCards, countryCode, amount, accessToken); + if (bestVisaCard) { + return bestVisaCard; + } + + const anyMastercard = masterCards?.find((masterCard) => isGiftCardAvailable(masterCard, amount)); + if (anyMastercard) { + return anyMastercard; + } + + const anyVisa = visaCards?.find((visaCard) => isGiftCardAvailable(visaCard, amount)); + if (anyVisa) { + return anyVisa; + } + + console.error(`No suitable card found for country code ${countryCode} and amount ${amount}.`); + return null; +} + +async function findBestMastercard(masterCards: GiftCard[], countryCode: string, amount: BigNumberish, accessToken: AccessToken): Promise { + const masterCardIntlSku = masterCardIntlSkus.find((sku) => sku.countryCode == countryCode); + if (masterCardIntlSku) { + const tokenizedIntlMastercard = masterCards?.find((masterCard) => masterCard.productId == masterCardIntlSku.sku); + if (tokenizedIntlMastercard && isGiftCardAvailable(tokenizedIntlMastercard, amount)) { + return tokenizedIntlMastercard; + } + } + + const fallbackMastercard = await getFallbackIntlMastercard(accessToken); + if (fallbackMastercard && isGiftCardAvailable(fallbackMastercard, amount)) { + return fallbackMastercard; + } + + return null; +} + +async function findBestVisaCard(visaCards: GiftCard[], countryCode: string, amount: BigNumberish, accessToken: AccessToken): Promise { + const visaIntlSku = visaIntlSkus.find((sku) => sku.countryCode == countryCode); + if (visaIntlSku) { + const intlVisa = visaCards?.find((visaCard) => visaCard.productId == visaIntlSku.sku); + if (intlVisa && isGiftCardAvailable(intlVisa, amount)) { + return intlVisa; + } + } + + const fallbackVisa = await getFallbackIntlVisa(accessToken); + if (fallbackVisa && isGiftCardAvailable(fallbackVisa, amount)) { + return fallbackVisa; + } + return null; +} +async function getFallbackIntlMastercard(accessToken: AccessToken): Promise { + try { + return await getGiftCardById(fallbackIntlMastercard.sku, accessToken); + } catch (e) { + console.error(`Failed to load international US mastercard: ${JSON.stringify(fallbackIntlMastercard)}`, e); + return null; + } +} + +async function getFallbackIntlVisa(accessToken: AccessToken): Promise { + try { + return await getGiftCardById(fallbackIntlVisa.sku, accessToken); + } catch (e) { + console.error(`Failed to load international US visa: ${JSON.stringify(fallbackIntlVisa)}\n${e}`); + return null; + } +} + +async function getSandboxGiftCard(productQuery: string, country: string, accessToken: AccessToken): Promise { + if (!accessToken.isSandbox) { + throw new Error("Cannot load sandbox card on production"); + } + + const url = `${getReloadlyApiBaseUrl(accessToken.isSandbox)}/products?productName=${productQuery}&productCategoryId=1`; + + console.log(`Retrieving gift cards from ${url}`); + const options = { + method: "GET", + headers: { + ...commonHeaders, + Authorization: `Bearer ${accessToken.token}`, + }, + }; + + const response = await fetch(url, options); + const responseJson = await response.json(); + + console.log("Response status", response.status); + console.log(`Response from ${url}`, responseJson); + + if (response.status != 200) { + throw new Error( + `Error from Reloadly API: ${JSON.stringify({ + status: response.status, + message: (responseJson as ReloadlyFailureResponse).message, + })}` + ); + } + + const paymentCards = (responseJson as { content: GiftCard[] })?.content; + if (paymentCards.length) { + return paymentCards[0]; + } + throw new Error(`No suitable card found on sandbox for country code ${country}.`); +} diff --git a/functions/reloadly-lists.ts b/functions/utils/reloadly-lists.ts similarity index 100% rename from functions/reloadly-lists.ts rename to functions/utils/reloadly-lists.ts diff --git a/functions/utils/shared.ts b/functions/utils/shared.ts new file mode 100644 index 00000000..80b431d9 --- /dev/null +++ b/functions/utils/shared.ts @@ -0,0 +1,90 @@ +import { GiftCard } from "../../shared/types"; +import { AccessToken, ReloadlyFailureResponse } from "./types"; + +export const commonHeaders = { + "Content-Type": "application/json", + Accept: "application/com.reloadly.giftcards-v1+json", +}; + +export interface Env { + USE_RELOADLY_SANDBOX: string; + RELOADLY_API_CLIENT_ID: string; + RELOADLY_API_CLIENT_SECRET: string; +} + +export interface ReloadlyAuthResponse { + access_token: string; + scope: string; + expires_in: number; + token_type: string; +} + +export const RELOADLY_AUTH_URL = "https://auth.reloadly.com/oauth/token"; +export const RELOADLY_SANDBOX_API_URL = "https://giftcards-sandbox.reloadly.com"; +export const RELOADLY_PRODUCTION_API_URL = "https://web3-gateway-test.com/proxy/reloadly/production"; +export function getReloadlyApiBaseUrl(isSandbox: boolean): string { + if (isSandbox === false) { + return RELOADLY_PRODUCTION_API_URL; + } + return RELOADLY_SANDBOX_API_URL; +} + +export async function getAccessToken(env: Env): Promise { + console.log("Using Reloadly Sandbox:", env.USE_RELOADLY_SANDBOX !== "false"); + const options = { + method: "POST", + headers: { "Content-Type": "application/json", Accept: "application/json" }, + body: JSON.stringify({ + client_id: env.RELOADLY_API_CLIENT_ID, + client_secret: env.RELOADLY_API_CLIENT_SECRET, + grant_type: "client_credentials", + audience: env.USE_RELOADLY_SANDBOX === "false" ? "https://giftcards.reloadly.com" : "https://giftcards-sandbox.reloadly.com", + }), + }; + + const res = await fetch(RELOADLY_AUTH_URL, options); + if (res.status == 200) { + const successResponse = (await res.json()) as ReloadlyAuthResponse; + return { + token: successResponse.access_token, + isSandbox: env.USE_RELOADLY_SANDBOX !== "false", + }; + } + throw `Getting access token failed: ${JSON.stringify(await res.json())}`; +} + +export async function getGiftCards(productQuery: string, country: string, accessToken: AccessToken): Promise { + // productCategoryId = 1 = Finance. + // This should prevent mixing of other gift cards with similar keywords + const url = `${getReloadlyApiBaseUrl(accessToken.isSandbox)}/countries/${country}/products?productName=${productQuery}&productCategoryId=1`; + + console.log(`Retrieving gift cards from ${url}`); + const options = { + method: "GET", + headers: { + ...commonHeaders, + Authorization: `Bearer ${accessToken.token}`, + }, + }; + + const response = await fetch(url, options); + const responseJson = await response.json(); + + console.log("Response status", response.status); + console.log(`Response from ${url}`, responseJson); + + if (response.status == 404) { + return []; + } + + if (response.status != 200) { + throw new Error( + `Error from Reloadly API: ${JSON.stringify({ + status: response.status, + message: (responseJson as ReloadlyFailureResponse).message, + })}` + ); + } + + return responseJson as GiftCard[]; +} diff --git a/functions/types.ts b/functions/utils/types.ts similarity index 96% rename from functions/types.ts rename to functions/utils/types.ts index 97ebd3bb..3e192148 100644 --- a/functions/types.ts +++ b/functions/utils/types.ts @@ -1,5 +1,5 @@ -import { GiftCard, Order, OrderTransaction, RedeemCode } from "../shared/types"; -import { Env } from "./helpers"; +import { GiftCard, Order, OrderTransaction, RedeemCode } from "../../shared/types"; +import { Env } from "./shared"; export interface AccessToken { token: string; diff --git a/functions/validators.ts b/functions/utils/validators.ts similarity index 100% rename from functions/validators.ts rename to functions/utils/validators.ts diff --git a/package.json b/package.json index 42f7aaf0..8fffd879 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "test:run": "cypress run", "test:open": "cypress open", "test:fund": "tsx cypress/scripts/funding.ts", + "test:unit": "npx vitest run", "knip": "knip --config .github/knip.ts", "knip-ci": "knip --no-exit-code --reporter json --config .github/knip.ts", "prepare": "husky install", @@ -43,7 +44,9 @@ "open-source" ], "dependencies": { + "@ethersproject/abi": "^5.7.0", "@ethersproject/providers": "^5.7.2", + "@ethersproject/units": "^5.7.0", "@supabase/supabase-js": "^2.44.4", "@ubiquibot/permit-generation": "^1.4.1", "@ubiquity-dao/rpc-handler": "^1.3.0", @@ -54,6 +57,7 @@ "zod": "^3.23.8" }, "devDependencies": { + "@cloudflare/vitest-pool-workers": "^0.5.22", "@cloudflare/workers-types": "^4.20240423.0", "@commitlint/cli": "^18.6.1", "@commitlint/config-conventional": "^18.6.2", @@ -78,12 +82,14 @@ "jest-md-dashboard": "0.8.0", "knip": "^5.0.1", "lint-staged": "^15.2.2", + "msw": "^2.5.2", "nodemon": "^3.0.3", "npm-run-all": "^4.1.5", "prettier": "^3.2.5", "ts-jest": "29.1.2", "tsx": "^4.7.1", "typescript": "^5.3.3", + "vitest": "2.0.5", "wrangler": "^3.51.2" }, "lint-staged": { diff --git a/shared/pricing.ts b/shared/pricing.ts index 73c70bbf..bf582e8e 100644 --- a/shared/pricing.ts +++ b/shared/pricing.ts @@ -1,5 +1,5 @@ import { BigNumber, BigNumberish } from "ethers"; -import { formatEther, parseEther } from "ethers/lib/utils"; +import { formatEther, parseEther } from "@ethersproject/units"; import { PriceToValueMap, GiftCard } from "./types"; /** diff --git a/static/scripts/shared/api.ts b/static/scripts/shared/api.ts index 24ea4f4d..27aab08e 100644 --- a/static/scripts/shared/api.ts +++ b/static/scripts/shared/api.ts @@ -1,4 +1,4 @@ -import { ReloadlyOrderResponse } from "../../../functions/types"; +import { ReloadlyOrderResponse } from "../../../functions/utils/types"; import { GetBestCardParams, GetOrderParams, GetRedeemCodeParams, PostOrderParams } from "../../../shared/api-types"; import { GiftCard, OrderTransaction, RedeemCode } from "../../../shared/types"; import { getApiBaseUrl } from "../rewards/gift-cards/helpers"; diff --git a/tests/fixtures/get-best-card/best-card-sandbox.json b/tests/fixtures/get-best-card/best-card-sandbox.json new file mode 100644 index 00000000..605b1c3f --- /dev/null +++ b/tests/fixtures/get-best-card/best-card-sandbox.json @@ -0,0 +1,28 @@ +{ + "productId": 13959, + "productName": "Mocked Vanilla® eGift Visa", + "global": false, + "supportsPreOrder": true, + "senderFee": 6, + "senderFeePercentage": 0, + "discountPercentage": 0, + "denominationType": "RANGE", + "recipientCurrencyCode": "USD", + "minRecipientDenomination": 20, + "maxRecipientDenomination": 100, + "senderCurrencyCode": "USD", + "minSenderDenomination": 20, + "maxSenderDenomination": 100, + "fixedRecipientDenominations": [], + "fixedSenderDenominations": null, + "fixedRecipientToSenderDenominationsMap": null, + "metadata": null, + "logoUrls": ["https://cdn.reloadly.com/giftcards/cdf0a915-a88d-4eb5-8cb8-a4fd00accc7eVanilla.jpg"], + "brand": { "brandId": 95, "brandName": "Vanilla® eGift Visa" }, + "category": { "id": 1, "name": "Payment Cards" }, + "country": { "isoName": "US", "name": "United States", "flagUrl": "https://s3.amazonaws.com/rld-flags/us.svg" }, + "redeemInstruction": { + "concise": "To redeem, visit yourrewardcard.com", + "verbose": "Virtual Account is a prepaid Virtual Account loaded by the Corporate Sponsor, redeemable to buy goods and services anywhere Visa debit Virtual Accounts are accepted, as described in the Virtual Account Use and Fees section. The Virtual Account is NOT a credit card. The Virtual Account is not a checking account or connected in any way to any account other than a stored value account where your funds are held. The expiration date of the Virtual Account and the Virtual Account funds is identified on the Virtual Account. eReward Visa Virtual Accountholder Agreement CUSTOMER SERVICE CONTACT INFORMATION: Address: P.O. Box 826 Fortson, GA 31808 Website: YourRewardCard.com Phone Number: 1-833-634-3155" + } +} diff --git a/tests/fixtures/get-best-card/best-master-card-prod.json b/tests/fixtures/get-best-card/best-master-card-prod.json new file mode 100644 index 00000000..b3d44712 --- /dev/null +++ b/tests/fixtures/get-best-card/best-master-card-prod.json @@ -0,0 +1,118 @@ +[ + { + "productId": 18172, + "productName": "Mastercard® Digital Card CAD US", + "global": false, + "supportsPreOrder": false, + "senderFee": 1.0, + "senderFeePercentage": 0.0, + "discountPercentage": 0.0, + "denominationType": "FIXED", + "recipientCurrencyCode": "CAD", + "minRecipientDenomination": null, + "maxRecipientDenomination": null, + "senderCurrencyCode": "USD", + "minSenderDenomination": null, + "maxSenderDenomination": null, + "fixedRecipientDenominations": [150.0], + "fixedSenderDenominations": [112.83], + "fixedRecipientToSenderDenominationsMap": { + "150.0": 112.83 + }, + "metadata": {}, + "logoUrls": ["https://cdn.reloadly.com/giftcards/e39131b3-1686-4d8a-a95a-78fa2817b9fa.jpeg"], + "brand": { + "brandId": 378, + "brandName": "Mastercard" + }, + "category": { + "id": 1, + "name": "Payment Cards" + }, + "country": { + "isoName": "US", + "name": "United States", + "flagUrl": "https://s3.amazonaws.com/rld-flags/us.svg" + }, + "redeemInstruction": { + "concise": "Your Virtual Promotional Prepaid Mastercard can be used online, for phone/mail orders, or in stores that accept mobile wallet where Debit Mastercard is accepted. This card must be used within 6 months from the time you receive your link. Visit MyPrepaidCenter.com for card usage details.\n2% currency conversion fee will apply if the merchant settles in a currency other than USD", + "verbose": "\"Redeem Instruction:\nYour Virtual Promotional Prepaid Mastercard can be used online, for phone/mail orders, or in stores that accept mobile wallet where Debit Mastercard is accepted. This card must be used within 6 months from the time you receive your link. Visit MyPrepaidCenter.com for card usage details.\n2% currency conversion fee will apply if the merchant settles in a currency other than USD...\n\n\n\nTerms and condition:\nVirtual card is issued by Pathward®, N.A., Member FDIC, pursuant to license by Mastercard International Incorporated. Mastercard and the circles design are registered trademarks of Mastercard International Incorporated. No cash access or recurring payments. Can be used where Debit Mastercard is accepted online, for phone/mail orders, or in stores that accept mobile wallet. Valid for up to 6 months; unused funds will forfeit after the valid thru date. Terms and conditions apply. See Cardholder Agreement for details https://www.myprepaidcenter.com/page/mastercard-promo-virtual\n\nMastercard is widely accepted globally*, with the exception of certain countries where credit cards are blocked due to economic sanctions or other regulatory restrictions. Specifically, this includes:\nChina, The Democratic People's Republic of Korea (North Korea), The Islamic Republic of Iran, The Syrian Arab Republic, Ukraine, The Bahamas, Barbados, Benin, Burundi, Burkina Faso, Cambodia, The Cayman Islands, Chad, The Central African Republic, Congo, Comoros, Dominican Republic, Cuba, Guinea, Eritrea, Guinea-Bissau, Haiti, Iraq, Lebanon, Laos, Lesotho, Myanmar, Madagascar, Nicaragua, Panama, Somalia, Sudan, South Sudan, Uganda, Venezuela , Yemen, Zimbabwe, Liberia....\n\n\n\nHow to use:\nGo to =\"\"http://www.MyPrepaidCenter.com/redeem\"\">MyPrepaidCenter.com/redeem and enter code\nComplete the online registration page and accept the cardholder agreement and e-sign agreement, then you will be able to view your 16-digit card number, expiration date, security information, where your card can be used, available balance, transaction history, etc.\nPlastic card available upon request. Requesting a plastic card will reduce the card’s value by $3.00 for manufacturing and fulfillment cost, and can take 7-14 business days. \nRecipient can request a plastic card once they have completed the card registration and activation at MyPrepaidCenter.com\"" + } + }, + { + "productId": 18597, + "productName": "Virtual MasterCard International USD US", + "global": false, + "supportsPreOrder": false, + "senderFee": 1.0, + "senderFeePercentage": 2.0, + "discountPercentage": 0.0, + "denominationType": "RANGE", + "recipientCurrencyCode": "USD", + "minRecipientDenomination": 5.0, + "maxRecipientDenomination": 1000.0, + "senderCurrencyCode": "USD", + "minSenderDenomination": 5.0, + "maxSenderDenomination": 1000.0, + "fixedRecipientDenominations": [], + "fixedSenderDenominations": null, + "fixedRecipientToSenderDenominationsMap": null, + "metadata": null, + "logoUrls": ["https://cdn.reloadly.com/giftcards/08ca41fe-e059-4dea-9dde-aff6ec231303.png"], + "brand": { + "brandId": 378, + "brandName": "Mastercard" + }, + "category": { + "id": 1, + "name": "Payment Cards" + }, + "country": { + "isoName": "US", + "name": "United States", + "flagUrl": "https://s3.amazonaws.com/rld-flags/us.svg" + }, + "redeemInstruction": { + "concise": "Your Virtual Promotional Prepaid Mastercard can be used online, for phone/mail orders, or in stores that accept mobile wallet where Debit Mastercard is accepted. This card must be used within 6 months from the time you receive your link. Visit MyPrepaidCenter.com for card usage details.\n2% currency conversion fee will apply if the merchant settles in a currency other than USD", + "verbose": "Redeem Instruction:\nYour Virtual Promotional Prepaid Mastercard can be used online, for phone/mail orders, or in stores that accept mobile wallet where Debit Mastercard is accepted. This card must be used within 6 months from the time you receive your link. Visit MyPrepaidCenter.com for card usage details.\n2% currency conversion fee will apply if the merchant settles in a currency other than USD\n\nTerms and condition:\nVirtual card is issued by Pathward®, N.A., Member FDIC, pursuant to license by Mastercard International Incorporated. Mastercard and the circles design are registered trademarks of Mastercard International Incorporated. No cash access or recurring payments. Can be used where Debit Mastercard is accepted online, for phone/mail orders, or in stores that accept mobile wallet. Valid for up to 6 months; unused funds will forfeit after the valid thru date. Terms and conditions apply. See Cardholder Agreement for details https://www.myprepaidcenter.com/page/mastercard-promo-virtual\n\nMastercard is widely accepted globally*, with the exception of certain countries where credit cards are blocked due to economic sanctions or other regulatory restrictions. Specifically, this includes:\nChina, The Democratic People's Republic of Korea (North Korea), The Islamic Republic of Iran, The Syrian Arab Republic, Ukraine, The Bahamas, Barbados, Benin, Burundi, Burkina Faso, Cambodia, The Cayman Islands, Chad, The Central African Republic, Congo, Comoros, Dominican Republic, Cuba, Guinea, Eritrea, Guinea-Bissau, Haiti, Iraq, Lebanon, Laos, Lesotho, Myanmar, Madagascar, Nicaragua, Panama, Somalia, Sudan, South Sudan, Uganda, Venezuela , Yemen, Zimbabwe, Liberia\n\nHow to use:\nGo to =\"http://www.MyPrepaidCenter.com/redeem\">MyPrepaidCenter.com/redeem and enter code\nComplete the online registration page and accept the cardholder agreement and e-sign agreement, then you will be able to view your 16-digit card number, expiration date, security information, where your card can be used, available balance, transaction history, etc.\nPlastic card available upon request. Requesting a plastic card will reduce the card’s value by $3.00 for manufacturing and fulfillment cost, and can take 7-14 business days. \nRecipient can request a plastic card once they have completed the card registration and activation at MyPrepaidCenter.com" + } + }, + { + "productId": 18732, + "productName": "Mastercard Prepaid USD Debit (Virtual only) US", + "global": false, + "supportsPreOrder": false, + "senderFee": 1.0, + "senderFeePercentage": 1.0, + "discountPercentage": 0.0, + "denominationType": "RANGE", + "recipientCurrencyCode": "USD", + "minRecipientDenomination": 5.0, + "maxRecipientDenomination": 1000.0, + "senderCurrencyCode": "USD", + "minSenderDenomination": 5.0, + "maxSenderDenomination": 1000.0, + "fixedRecipientDenominations": [], + "fixedSenderDenominations": null, + "fixedRecipientToSenderDenominationsMap": null, + "metadata": null, + "logoUrls": ["https://cdn.reloadly.com/giftcards/1e703d6a-b8a5-4b88-8f11-62cb3e4a5c0d.png"], + "brand": { + "brandId": 378, + "brandName": "Mastercard" + }, + "category": { + "id": 1, + "name": "Payment Cards" + }, + "country": { + "isoName": "US", + "name": "United States", + "flagUrl": "https://s3.amazonaws.com/rld-flags/us.svg" + }, + "redeemInstruction": { + "concise": "Your Virtual Promotional Prepaid Mastercard can be used online, for phone/mail orders, or in stores that accept mobile wallet where Debit Mastercard is accepted. This card must be used within 6 months from the time you receive your link. Visit MyPrepaidCenter.com for card usage details.\n2% currency conversion fee will apply if the merchant settles in a currency other than USD", + "verbose": "Redeem Instruction:\nYour Virtual Promotional Prepaid Mastercard can be used online, for phone/mail orders, or in stores that accept mobile wallet where Debit Mastercard is accepted. This card must be used within 6 months from the time you receive your link. Visit MyPrepaidCenter.com for card usage details.\n2% currency conversion fee will apply if the merchant settles in a currency other than USD\n\nTerms and condition:\nVirtual card is issued by Pathward®, N.A., Member FDIC, pursuant to license by Mastercard International Incorporated. Mastercard and the circles design are registered trademarks of Mastercard International Incorporated. No cash access or recurring payments. Can be used where Debit Mastercard is accepted online, for phone/mail orders, or in stores that accept mobile wallet. Valid for up to 6 months; unused funds will forfeit after the valid thru date. Terms and conditions apply. See Cardholder Agreement for details https://www.myprepaidcenter.com/page/mastercard-promo-virtual\n\nMastercard is widely accepted globally*, with the exception of certain countries where credit cards are blocked due to economic sanctions or other regulatory restrictions. Specifically, this includes:\nChina, The Democratic People's Republic of Korea (North Korea), The Islamic Republic of Iran, The Syrian Arab Republic, Ukraine, The Bahamas, Barbados, Benin, Burundi, Burkina Faso, Cambodia, The Cayman Islands, Chad, The Central African Republic, Congo, Comoros, Dominican Republic, Cuba, Guinea, Eritrea, Guinea-Bissau, Haiti, Iraq, Lebanon, Laos, Lesotho, Myanmar, Madagascar, Nicaragua, Panama, Somalia, Sudan, South Sudan, Uganda, Venezuela , Yemen, Zimbabwe, Liberia\n\nHow to use:\nGo to =\"http://www.MyPrepaidCenter.com/redeem\">MyPrepaidCenter.com/redeem and enter code\nComplete the online registration page and accept the cardholder agreement and e-sign agreement, then you will be able to view your 16-digit card number, expiration date, security information, where your card can be used, available balance, transaction history, etc.\nPlastic card available upon request. Requesting a plastic card will reduce the card’s value by $3.00 for manufacturing and fulfillment cost, and can take 7-14 business days. \nRecipient can request a plastic card once they have completed the card registration and activation at MyPrepaidCenter.com" + } + } +] diff --git a/tests/fixtures/get-best-card/best-visa-card-prod.json b/tests/fixtures/get-best-card/best-visa-card-prod.json new file mode 100644 index 00000000..4e11b338 --- /dev/null +++ b/tests/fixtures/get-best-card/best-visa-card-prod.json @@ -0,0 +1,78 @@ +[ + { + "productId": 18731, + "productName": "Virtual Visa® Reward 6-Month, 90 Days to Redeem US", + "global": false, + "supportsPreOrder": false, + "senderFee": 1.0, + "senderFeePercentage": 1.0, + "discountPercentage": 0.0, + "denominationType": "RANGE", + "recipientCurrencyCode": "USD", + "minRecipientDenomination": 5.0, + "maxRecipientDenomination": 5000.0, + "senderCurrencyCode": "USD", + "minSenderDenomination": 5.0, + "maxSenderDenomination": 5000.0, + "fixedRecipientDenominations": [], + "fixedSenderDenominations": null, + "fixedRecipientToSenderDenominationsMap": null, + "metadata": null, + "logoUrls": ["https://cdn.reloadly.com/giftcards/2b1118dd-8b3e-47a3-9184-35abdb191721.png"], + "brand": { + "brandId": 411, + "brandName": "Virtual Visa" + }, + "category": { + "id": 1, + "name": "Payment Cards" + }, + "country": { + "isoName": "US", + "name": "United States", + "flagUrl": "https://s3.amazonaws.com/rld-flags/us.svg" + }, + "redeemInstruction": { + "concise": "This card is redeemable online anywhere Visa debit cards is accepted. Use the link shared with this Gift Voucher to redeem the card. A valid USA phone number that supports incoming SMS and an address are required. A valid USA phone number that supports incoming SMS and an address are required. Terms and conditions apply. \n\n", + "verbose": "Use the link shared with this Gift Voucher to redeem the card. Card expires in 6-Month, 90 Days to Redeem. The virtual reward is issued by Sutton Bank, member FDIC, pursuant to a license from Visa U.S.A. Inc. and can be used wherever Visa Debit cards are accepted. Terms and conditions apply. A valid USA phone number that supports incoming SMS and an address are required.\n\nUse of your card is prohibited in these countries:\nAfghanistan (AF)\nAlbania (AL)\nBelarus (BY)\nCentral African Republic (CF)\nCuba (CU)\nChina\nDemocratic Republic Of The Congo (CD)\nEritrea (ER)\nEthiopia (ET)\nIran (Islamic Republic Of) (IR)\nIraq (IQ)\nKuwait\nLebanon (LB)\nLibyan Arab Jamahiriya (LY)\nMali (ML)\nMyanmar (Burma) (MM)\nMontenegro\nNicaragua (NI)\nNigeria\nNorth Korea aka Democratic People’s Republic of Korea (KP)\nRussian Federation (RU)\nSomalia (SO)\nSouth Sudan (SS)\nSudan (SD)\nSyrian Arab Republic (SY)\nTunisia (TN)\nTurkey (TR)\nUkraine (UA)\nVenezuela (VE)\nVietnam\nYemen (YE)\nZimbabwe (ZW)" + } + }, + { + "productId": 18598, + "productName": "Visa International USD (Virtual) US", + "global": false, + "supportsPreOrder": false, + "senderFee": 1.0, + "senderFeePercentage": 1.0, + "discountPercentage": 0.0, + "denominationType": "RANGE", + "recipientCurrencyCode": "USD", + "minRecipientDenomination": 5.0, + "maxRecipientDenomination": 1000.0, + "senderCurrencyCode": "USD", + "minSenderDenomination": 5.0, + "maxSenderDenomination": 1000.0, + "fixedRecipientDenominations": [], + "fixedSenderDenominations": null, + "fixedRecipientToSenderDenominationsMap": null, + "metadata": null, + "logoUrls": ["https://cdn.reloadly.com/giftcards/aa1431b0-99fe-4f3d-8c58-ef46baee0c00.png"], + "brand": { + "brandId": 411, + "brandName": "Virtual Visa" + }, + "category": { + "id": 1, + "name": "Payment Cards" + }, + "country": { + "isoName": "US", + "name": "United States", + "flagUrl": "https://s3.amazonaws.com/rld-flags/us.svg" + }, + "redeemInstruction": { + "concise": "his card is redeemable online anywhere Visacard debit is accepted. Use the link shared with this Gift Voucher to redeem the card.", + "verbose": "Use the link shared with this Gift Voucher to redeem the card. Card expires Three (3) years after activation, your Virtual Visa Card does not have to be activated, and it can be used as soon as you receive it." + } + } +] diff --git a/tests/fixtures/get-best-card/card-18597.json b/tests/fixtures/get-best-card/card-18597.json new file mode 100644 index 00000000..92c95a25 --- /dev/null +++ b/tests/fixtures/get-best-card/card-18597.json @@ -0,0 +1,38 @@ +{ + "productId": 18597, + "productName": "Virtual MasterCard International USD US", + "global": false, + "supportsPreOrder": false, + "senderFee": 1.0, + "senderFeePercentage": 2.0, + "discountPercentage": 0.0, + "denominationType": "RANGE", + "recipientCurrencyCode": "USD", + "minRecipientDenomination": 5.0, + "maxRecipientDenomination": 1000.0, + "senderCurrencyCode": "USD", + "minSenderDenomination": 5.0, + "maxSenderDenomination": 1000.0, + "fixedRecipientDenominations": [], + "fixedSenderDenominations": null, + "fixedRecipientToSenderDenominationsMap": null, + "metadata": null, + "logoUrls": ["https://cdn.reloadly.com/giftcards/08ca41fe-e059-4dea-9dde-aff6ec231303.png"], + "brand": { + "brandId": 378, + "brandName": "Mastercard" + }, + "category": { + "id": 1, + "name": "Payment Cards" + }, + "country": { + "isoName": "US", + "name": "United States", + "flagUrl": "https://s3.amazonaws.com/rld-flags/us.svg" + }, + "redeemInstruction": { + "concise": "Your Virtual Promotional Prepaid Mastercard can be used online, for phone/mail orders, or in stores that accept mobile wallet where Debit Mastercard is accepted. This card must be used within 6 months from the time you receive your link. Visit MyPrepaidCenter.com for card usage details.\n2% currency conversion fee will apply if the merchant settles in a currency other than USD", + "verbose": "Redeem Instruction:\nYour Virtual Promotional Prepaid Mastercard can be used online, for phone/mail orders, or in stores that accept mobile wallet where Debit Mastercard is accepted. This card must be used within 6 months from the time you receive your link. Visit MyPrepaidCenter.com for card usage details.\n2% currency conversion fee will apply if the merchant settles in a currency other than USD\n\nTerms and condition:\nVirtual card is issued by Pathward®, N.A., Member FDIC, pursuant to license by Mastercard International Incorporated. Mastercard and the circles design are registered trademarks of Mastercard International Incorporated. No cash access or recurring payments. Can be used where Debit Mastercard is accepted online, for phone/mail orders, or in stores that accept mobile wallet. Valid for up to 6 months; unused funds will forfeit after the valid thru date. Terms and conditions apply. See Cardholder Agreement for details https://www.myprepaidcenter.com/page/mastercard-promo-virtual\n\nMastercard is widely accepted globally*, with the exception of certain countries where credit cards are blocked due to economic sanctions or other regulatory restrictions. Specifically, this includes:\nChina, The Democratic People's Republic of Korea (North Korea), The Islamic Republic of Iran, The Syrian Arab Republic, Ukraine, The Bahamas, Barbados, Benin, Burundi, Burkina Faso, Cambodia, The Cayman Islands, Chad, The Central African Republic, Congo, Comoros, Dominican Republic, Cuba, Guinea, Eritrea, Guinea-Bissau, Haiti, Iraq, Lebanon, Laos, Lesotho, Myanmar, Madagascar, Nicaragua, Panama, Somalia, Sudan, South Sudan, Uganda, Venezuela , Yemen, Zimbabwe, Liberia\n\nHow to use:\nGo to =\"http://www.MyPrepaidCenter.com/redeem\">MyPrepaidCenter.com/redeem and enter code\nComplete the online registration page and accept the cardholder agreement and e-sign agreement, then you will be able to view your 16-digit card number, expiration date, security information, where your card can be used, available balance, transaction history, etc.\nPlastic card available upon request. Requesting a plastic card will reduce the card’s value by $3.00 for manufacturing and fulfillment cost, and can take 7-14 business days. \nRecipient can request a plastic card once they have completed the card registration and activation at MyPrepaidCenter.com" + } +} diff --git a/tests/fixtures/get-best-card/card-18598.json b/tests/fixtures/get-best-card/card-18598.json new file mode 100644 index 00000000..8c1512fe --- /dev/null +++ b/tests/fixtures/get-best-card/card-18598.json @@ -0,0 +1,38 @@ +{ + "productId": 18598, + "productName": "Visa International USD (Virtual) US", + "global": false, + "supportsPreOrder": false, + "senderFee": 1.0, + "senderFeePercentage": 1.0, + "discountPercentage": 0.0, + "denominationType": "RANGE", + "recipientCurrencyCode": "USD", + "minRecipientDenomination": 5.0, + "maxRecipientDenomination": 1000.0, + "senderCurrencyCode": "USD", + "minSenderDenomination": 5.0, + "maxSenderDenomination": 1000.0, + "fixedRecipientDenominations": [], + "fixedSenderDenominations": null, + "fixedRecipientToSenderDenominationsMap": null, + "metadata": null, + "logoUrls": ["https://cdn.reloadly.com/giftcards/aa1431b0-99fe-4f3d-8c58-ef46baee0c00.png"], + "brand": { + "brandId": 411, + "brandName": "Virtual Visa" + }, + "category": { + "id": 1, + "name": "Payment Cards" + }, + "country": { + "isoName": "US", + "name": "United States", + "flagUrl": "https://s3.amazonaws.com/rld-flags/us.svg" + }, + "redeemInstruction": { + "concise": "his card is redeemable online anywhere Visacard debit is accepted. Use the link shared with this Gift Voucher to redeem the card.", + "verbose": "Use the link shared with this Gift Voucher to redeem the card. Card expires Three (3) years after activation, your Virtual Visa Card does not have to be activated, and it can be used as soon as you receive it." + } +} diff --git a/tests/fixtures/get-best-card/no-card-mt.json b/tests/fixtures/get-best-card/no-card-mt.json new file mode 100644 index 00000000..99c14a9b --- /dev/null +++ b/tests/fixtures/get-best-card/no-card-mt.json @@ -0,0 +1,8 @@ +{ + "timeStamp": "2024-10-31 09:18:16", + "message": "No products were found for the given country code. For a list of valid country codes visit https://www.nationsonline.org/oneworld/country_code_list.htm", + "path": "/countries/MT/products", + "errorCode": null, + "infoLink": null, + "details": [] +} diff --git a/tests/fixtures/get-order/no-transaction.json b/tests/fixtures/get-order/no-transaction.json new file mode 100644 index 00000000..d60442e3 --- /dev/null +++ b/tests/fixtures/get-order/no-transaction.json @@ -0,0 +1,28 @@ +{ + "content": [], + "pageable": { + "sort": { + "sorted": false, + "unsorted": true, + "empty": true + }, + "pageNumber": 0, + "pageSize": 1, + "offset": 0, + "unpaged": false, + "paged": true + }, + "totalElements": 0, + "totalPages": 0, + "last": true, + "first": true, + "sort": { + "sorted": false, + "unsorted": true, + "empty": true + }, + "numberOfElements": 0, + "size": 1, + "number": 0, + "empty": true +} diff --git a/tests/fixtures/get-order/order.json b/tests/fixtures/get-order/order.json new file mode 100644 index 00000000..6155abeb --- /dev/null +++ b/tests/fixtures/get-order/order.json @@ -0,0 +1,76 @@ +{ + "transaction": { + "transactionId": 611499, + "amount": 6.1204, + "discount": 0, + "currencyCode": "USD", + "fee": 3, + "smsFee": 0, + "totalFee": 3, + "preOrdered": false, + "recipientEmail": null, + "recipientPhone": null, + "customIdentifier": "0xd89d85e5f65499e03f85cf5d4e69d04ee04d959cc04f8aa6a9fccba52b3c6916", + "status": "SUCCESSFUL", + "transactionCreatedTime": "2024-08-29 18:47:57", + "product": { + "productId": 18597, + "productName": "Virtual MasterCard International USD US", + "countryCode": "US", + "quantity": 1, + "unitPrice": 5.02, + "totalPrice": 5.02, + "currencyCode": "USD", + "brand": { + "brandId": 378, + "brandName": "Mastercard" + } + }, + "balanceInfo": { + "oldBalance": 52.3369, + "newBalance": 46.2165, + "cost": 6.1204, + "currencyCode": "USD", + "currencyName": "US Dollar", + "updatedAt": "2024-08-29 18:42:40" + } + }, + "product": { + "productId": 18597, + "productName": "Virtual MasterCard International USD US", + "global": false, + "supportsPreOrder": false, + "senderFee": 1, + "senderFeePercentage": 2, + "discountPercentage": 0, + "denominationType": "RANGE", + "recipientCurrencyCode": "USD", + "minRecipientDenomination": 5, + "maxRecipientDenomination": 1000, + "senderCurrencyCode": "USD", + "minSenderDenomination": 5, + "maxSenderDenomination": 1000, + "fixedRecipientDenominations": [], + "fixedSenderDenominations": null, + "fixedRecipientToSenderDenominationsMap": null, + "metadata": null, + "logoUrls": ["https://cdn.reloadly.com/giftcards/08ca41fe-e059-4dea-9dde-aff6ec231303.png"], + "brand": { + "brandId": 378, + "brandName": "Mastercard" + }, + "category": { + "id": 1, + "name": "Payment Cards" + }, + "country": { + "isoName": "US", + "name": "United States", + "flagUrl": "https://s3.amazonaws.com/rld-flags/us.svg" + }, + "redeemInstruction": { + "concise": "Your Virtual Promotional Prepaid Mastercard can be used online, for phone/mail orders, or in stores that accept mobile wallet where Debit Mastercard is accepted. This card must be used within 6 months from the time you receive your link. Visit MyPrepaidCenter.com for card usage details.\n2% currency conversion fee will apply if the merchant settles in a currency other than USD", + "verbose": "Redeem Instruction:\nYour Virtual Promotional Prepaid Mastercard can be used online, for phone/mail orders, or in stores that accept mobile wallet where Debit Mastercard is accepted. This card must be used within 6 months from the time you receive your link. Visit MyPrepaidCenter.com for card usage details.\n2% currency conversion fee will apply if the merchant settles in a currency other than USD\n\nTerms and condition:\nVirtual card is issued by Pathward®, N.A., Member FDIC, pursuant to license by Mastercard International Incorporated. Mastercard and the circles design are registered trademarks of Mastercard International Incorporated. No cash access or recurring payments. Can be used where Debit Mastercard is accepted online, for phone/mail orders, or in stores that accept mobile wallet. Valid for up to 6 months; unused funds will forfeit after the valid thru date. Terms and conditions apply. See Cardholder Agreement for details https://www.myprepaidcenter.com/page/mastercard-promo-virtual\n\nMastercard is widely accepted globally*, with the exception of certain countries where credit cards are blocked due to economic sanctions or other regulatory restrictions. Specifically, this includes:\nChina, The Democratic People's Republic of Korea (North Korea), The Islamic Republic of Iran, The Syrian Arab Republic, Ukraine, The Bahamas, Barbados, Benin, Burundi, Burkina Faso, Cambodia, The Cayman Islands, Chad, The Central African Republic, Congo, Comoros, Dominican Republic, Cuba, Guinea, Eritrea, Guinea-Bissau, Haiti, Iraq, Lebanon, Laos, Lesotho, Myanmar, Madagascar, Nicaragua, Panama, Somalia, Sudan, South Sudan, Uganda, Venezuela , Yemen, Zimbabwe, Liberia\n\nHow to use:\nGo to =\"http://www.MyPrepaidCenter.com/redeem\">MyPrepaidCenter.com/redeem and enter code\nComplete the online registration page and accept the cardholder agreement and e-sign agreement, then you will be able to view your 16-digit card number, expiration date, security information, where your card can be used, available balance, transaction history, etc.\nPlastic card available upon request. Requesting a plastic card will reduce the card’s value by $3.00 for manufacturing and fulfillment cost, and can take 7-14 business days. \nRecipient can request a plastic card once they have completed the card registration and activation at MyPrepaidCenter.com" + } + } +} diff --git a/tests/fixtures/get-order/transaction.json b/tests/fixtures/get-order/transaction.json new file mode 100644 index 00000000..ac40ceab --- /dev/null +++ b/tests/fixtures/get-order/transaction.json @@ -0,0 +1,65 @@ +{ + "content": [ + { + "transactionId": 611499, + "amount": 6.1204, + "discount": 0.0, + "currencyCode": "USD", + "fee": 3.0, + "smsFee": 0.0, + "totalFee": 3.0, + "preOrdered": false, + "recipientEmail": null, + "recipientPhone": null, + "customIdentifier": "0xd89d85e5f65499e03f85cf5d4e69d04ee04d959cc04f8aa6a9fccba52b3c6916", + "status": "SUCCESSFUL", + "transactionCreatedTime": "2024-08-29 18:47:57", + "product": { + "productId": 18597, + "productName": "Virtual MasterCard International USD US", + "countryCode": "US", + "quantity": 1, + "unitPrice": 5.02, + "totalPrice": 5.02, + "currencyCode": "USD", + "brand": { + "brandId": 378, + "brandName": "Mastercard" + } + }, + "balanceInfo": { + "oldBalance": 52.3369, + "newBalance": 46.2165, + "cost": 6.1204, + "currencyCode": "USD", + "currencyName": "US Dollar", + "updatedAt": "2024-08-29 18:42:40" + } + } + ], + "pageable": { + "sort": { + "sorted": false, + "unsorted": true, + "empty": true + }, + "pageNumber": 0, + "pageSize": 1, + "offset": 0, + "unpaged": false, + "paged": true + }, + "totalElements": 1, + "totalPages": 1, + "last": true, + "first": true, + "sort": { + "sorted": false, + "unsorted": true, + "empty": true + }, + "numberOfElements": 1, + "size": 1, + "number": 0, + "empty": false +} diff --git a/tests/fixtures/get-redeem-code/card.json b/tests/fixtures/get-redeem-code/card.json new file mode 100644 index 00000000..f7604022 --- /dev/null +++ b/tests/fixtures/get-redeem-code/card.json @@ -0,0 +1 @@ +[{ "cardNumber": "JcrhDtest", "pinCode": "22393test" }] diff --git a/tests/fixtures/get-redeem-code/transaction-0x33f4.json b/tests/fixtures/get-redeem-code/transaction-0x33f4.json new file mode 100644 index 00000000..af85ad3e --- /dev/null +++ b/tests/fixtures/get-redeem-code/transaction-0x33f4.json @@ -0,0 +1,46 @@ +{ + "content": [ + { + "transactionId": 38994, + "amount": 50, + "discount": 0, + "currencyCode": "USD", + "fee": 6, + "smsFee": 0, + "totalFee": 6, + "preOrdered": false, + "recipientEmail": null, + "recipientPhone": null, + "customIdentifier": "0x33f4b8ad8a2d0dda3869566a065602a3d20a31f8ed723013653a5d26a994ceef", + "status": "SUCCESSFUL", + "transactionCreatedTime": "2024-11-01 12:24:15", + "product": ["Object"], + "balanceInfo": ["Object"] + } + ], + "pageable": { + "sort": { + "empty": true, + "sorted": false, + "unsorted": true + }, + "pageNumber": 0, + "pageSize": 1, + "offset": 0, + "unpaged": false, + "paged": true + }, + "totalElements": 1, + "totalPages": 1, + "last": true, + "first": true, + "sort": { + "empty": true, + "sorted": false, + "unsorted": true + }, + "size": 1, + "number": 0, + "numberOfElements": 1, + "empty": false +} diff --git a/tests/fixtures/http-mocks.ts b/tests/fixtures/http-mocks.ts new file mode 100644 index 00000000..d8b4f4c9 --- /dev/null +++ b/tests/fixtures/http-mocks.ts @@ -0,0 +1,116 @@ +import { http, HttpResponse } from "msw"; +import bestCardSandbox from "./get-best-card/best-card-sandbox.json"; +import bestMastercardProd from "./get-best-card/best-master-card-prod.json"; +import bestVisaProd from "./get-best-card/best-visa-card-prod.json"; +import card18597 from "./get-best-card/card-18597.json"; +import card18732 from "./post-order/card-18732.json"; +import card18598 from "./get-best-card/card-18598.json"; +import noCardMt from "./get-best-card/no-card-mt.json"; +import transaction from "./get-order/transaction.json"; + +import noTransaction from "./get-order/no-transaction.json"; +import transaction0x33f4 from "./get-redeem-code/transaction-0x33f4.json"; +import card from "./get-redeem-code/card.json"; +import orderCard13959 from "./post-order/order-card-13959.json"; +import orderCard18597 from "./post-order/order-card-18597.json"; +import { RELOADLY_AUTH_URL, RELOADLY_PRODUCTION_API_URL, RELOADLY_SANDBOX_API_URL } from "../../functions/utils/shared"; + +/** + * Intercepts the routes and returns a custom payload + */ +export const httpMocks = [ + // http.get(`${getBaseUrl(true)}/products**`, () => { + // return HttpResponse.json(bestCard); + // }), + http.post(RELOADLY_AUTH_URL, () => { + return HttpResponse.json({ access_token: "fooBar" }); + }), + http.get(`${RELOADLY_PRODUCTION_API_URL}/products/18597`, () => { + return HttpResponse.json(card18597, { status: 200 }); + }), + http.get(`${RELOADLY_PRODUCTION_API_URL}/products/18598`, () => { + return HttpResponse.json(card18598, { status: 200 }); + }), + http.get(`${RELOADLY_SANDBOX_API_URL}/products`, ({ request }) => { + const url = new URL(request.url); + const productName = url.searchParams.get("productName"); + if (productName == "visa") { + return HttpResponse.json({ content: [bestCardSandbox] }, { status: 200 }); + } + return HttpResponse.json({ content: [] }, { status: 200 }); + }), + http.get(`${RELOADLY_PRODUCTION_API_URL}/countries/US/products`, ({ request }) => { + const url = new URL(request.url); + const productName = url.searchParams.get("productName"); + + if (productName == "mastercard") { + return HttpResponse.json(bestMastercardProd, { status: 200 }); + } + if (productName == "visa") { + return HttpResponse.json(bestVisaProd, { status: 200 }); + } + return HttpResponse.json([], { status: 200 }); + }), + + http.get(`${RELOADLY_PRODUCTION_API_URL}/countries/MT/products`, () => { + return HttpResponse.json(noCardMt, { status: 404 }); + }), + + http.get(`${RELOADLY_PRODUCTION_API_URL}/orders/transactions/38994/cards`, () => { + return HttpResponse.json(card, { status: 200 }); + }), + + http.get(`${RELOADLY_PRODUCTION_API_URL}/reports/transactions`, ({ request }) => { + const url = new URL(request.url); + const customIdentifier = url.searchParams.get("customIdentifier"); + + if (customIdentifier == "0xd89d85e5f65499e03f85cf5d4e69d04ee04d959cc04f8aa6a9fccba52b3c6916") { + return HttpResponse.json(transaction, { status: 200 }); + } else if (customIdentifier == "0x33f4b8ad8a2d0dda3869566a065602a3d20a31f8ed723013653a5d26a994ceef") { + return HttpResponse.json(transaction0x33f4, { status: 200 }); + } + + return HttpResponse.json(noTransaction, { status: 200 }); + }), + + http.post(`${RELOADLY_PRODUCTION_API_URL}/orders`, () => { + return HttpResponse.json(orderCard18597, { status: 200 }); + }), + http.post(`${RELOADLY_SANDBOX_API_URL}/orders`, () => { + return HttpResponse.json(orderCard13959, { status: 200 }); + }), + + http.get(`${RELOADLY_PRODUCTION_API_URL}/products/13959`, () => { + return HttpResponse.json(bestCardSandbox, { status: 200 }); + }), + + http.get(`${RELOADLY_PRODUCTION_API_URL}/products/18732`, () => { + return HttpResponse.json(card18732, { status: 200 }); + }), + + http.get(`${RELOADLY_SANDBOX_API_URL}/products/13959`, () => { + return HttpResponse.json(bestCardSandbox, { status: 200 }); + }), + + http.get(`${RELOADLY_SANDBOX_API_URL}/reports/transactions`, () => { + return HttpResponse.json(noTransaction, { status: 200 }); + }), + + // http.all(`*`, ({ request }) => { + // console.error(`All http requests are expected to be mocked in unit tests. Following request was not mocked. ${request.url}`); + // return HttpResponse.json( + // { msg: `All http requests are expected to be mocked in unit tests. Following request was not mocked. ${request.url}` }, + // { status: 404 } + // ); + // }), + // http.get(`https://giftcards-sandbox.reloadly.com/products?productName=visa&productCategoryId=1`, () => { + // return HttpResponse.json({ content: [bestCard] }); + // }), + + // http.get(`https://giftcards-sandbox.reloadly.com/products**`, () => { + // return HttpResponse.json([]); + // }), + // http.get(`https://giftcards-sandbox.reloadly.com/products/18598`, () => { + // return HttpResponse.json(bestCard); + // }), +]; diff --git a/tests/fixtures/post-order/card-18732.json b/tests/fixtures/post-order/card-18732.json new file mode 100644 index 00000000..0bcc744a --- /dev/null +++ b/tests/fixtures/post-order/card-18732.json @@ -0,0 +1,38 @@ +{ + "productId": 18732, + "productName": "Mastercard Prepaid USD Debit (Virtual only) US", + "global": false, + "supportsPreOrder": false, + "senderFee": 1.0, + "senderFeePercentage": 1.0, + "discountPercentage": 0.0, + "denominationType": "RANGE", + "recipientCurrencyCode": "USD", + "minRecipientDenomination": 5.0, + "maxRecipientDenomination": 1000.0, + "senderCurrencyCode": "USD", + "minSenderDenomination": 5.0, + "maxSenderDenomination": 1000.0, + "fixedRecipientDenominations": [], + "fixedSenderDenominations": null, + "fixedRecipientToSenderDenominationsMap": null, + "metadata": null, + "logoUrls": ["https://cdn.reloadly.com/giftcards/1e703d6a-b8a5-4b88-8f11-62cb3e4a5c0d.png"], + "brand": { + "brandId": 378, + "brandName": "Mastercard" + }, + "category": { + "id": 1, + "name": "Payment Cards" + }, + "country": { + "isoName": "US", + "name": "United States", + "flagUrl": "https://s3.amazonaws.com/rld-flags/us.svg" + }, + "redeemInstruction": { + "concise": "Your Virtual Promotional Prepaid Mastercard can be used online, for phone/mail orders, or in stores that accept mobile wallet where Debit Mastercard is accepted. This card must be used within 6 months from the time you receive your link. Visit MyPrepaidCenter.com for card usage details.\n2% currency conversion fee will apply if the merchant settles in a currency other than USD", + "verbose": "Redeem Instruction:\nYour Virtual Promotional Prepaid Mastercard can be used online, for phone/mail orders, or in stores that accept mobile wallet where Debit Mastercard is accepted. This card must be used within 6 months from the time you receive your link. Visit MyPrepaidCenter.com for card usage details.\n2% currency conversion fee will apply if the merchant settles in a currency other than USD\n\nTerms and condition:\nVirtual card is issued by Pathward®, N.A., Member FDIC, pursuant to license by Mastercard International Incorporated. Mastercard and the circles design are registered trademarks of Mastercard International Incorporated. No cash access or recurring payments. Can be used where Debit Mastercard is accepted online, for phone/mail orders, or in stores that accept mobile wallet. Valid for up to 6 months; unused funds will forfeit after the valid thru date. Terms and conditions apply. See Cardholder Agreement for details https://www.myprepaidcenter.com/page/mastercard-promo-virtual\n\nMastercard is widely accepted globally*, with the exception of certain countries where credit cards are blocked due to economic sanctions or other regulatory restrictions. Specifically, this includes:\nChina, The Democratic People's Republic of Korea (North Korea), The Islamic Republic of Iran, The Syrian Arab Republic, Ukraine, The Bahamas, Barbados, Benin, Burundi, Burkina Faso, Cambodia, The Cayman Islands, Chad, The Central African Republic, Congo, Comoros, Dominican Republic, Cuba, Guinea, Eritrea, Guinea-Bissau, Haiti, Iraq, Lebanon, Laos, Lesotho, Myanmar, Madagascar, Nicaragua, Panama, Somalia, Sudan, South Sudan, Uganda, Venezuela , Yemen, Zimbabwe, Liberia\n\nHow to use:\nGo to =\"http://www.MyPrepaidCenter.com/redeem\">MyPrepaidCenter.com/redeem and enter code\nComplete the online registration page and accept the cardholder agreement and e-sign agreement, then you will be able to view your 16-digit card number, expiration date, security information, where your card can be used, available balance, transaction history, etc.\nPlastic card available upon request. Requesting a plastic card will reduce the card’s value by $3.00 for manufacturing and fulfillment cost, and can take 7-14 business days. \nRecipient can request a plastic card once they have completed the card registration and activation at MyPrepaidCenter.com" + } +} diff --git a/tests/fixtures/post-order/mined-tx-for-mocked-parse.json b/tests/fixtures/post-order/mined-tx-for-mocked-parse.json new file mode 100644 index 00000000..c481a7ac --- /dev/null +++ b/tests/fixtures/post-order/mined-tx-for-mocked-parse.json @@ -0,0 +1,23 @@ +{ + "hash": "0xbef4c18032fbef0453f85191fb0fa91184b42d12ccc37f00eb7ae8c1d88a0233", + "type": 2, + "accessList": [], + "blockHash": "0x0c95167d8eccd0f9583bf50a3f730fce78b2bfafc602098a354cb52f9a25e230", + "blockNumber": 36848219, + "transactionIndex": 0, + "confirmations": 1, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "gasPrice": { "type": "BigNumber", "hex": "0x3b9aca0e" }, + "maxPriorityFeePerGas": { "type": "BigNumber", "hex": "0x3b9aca07" }, + "maxFeePerGas": { "type": "BigNumber", "hex": "0x3b9aca07" }, + "gasLimit": { "type": "BigNumber", "hex": "0x012d3f" }, + "to": "0x000000000022D473030F116dDEE9F6B43aC78BA3", + "value": { "type": "BigNumber", "hex": "0x00" }, + "nonce": 205, + "data": "0xcc53287f000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000004ecaba5870353805a9f068101a40e0f32ed605c600000000000000000000000075fc67473a91335b5b8f8821277262a13b38c9b3", + "r": "0x4188ddd349074c2e4f5567f630b74465369745e6f4c58918b1a6c1f2f3ed937b", + "s": "0x06a4f0551064e7a8bfe88ea5e8f33111527432cd7b4e602c2122d117e106f3f3", + "v": 1, + "creates": null, + "chainId": 31337 +} diff --git a/tests/fixtures/post-order/mined-tx-not-permit2.json b/tests/fixtures/post-order/mined-tx-not-permit2.json new file mode 100644 index 00000000..2e564990 --- /dev/null +++ b/tests/fixtures/post-order/mined-tx-not-permit2.json @@ -0,0 +1,23 @@ +{ + "hash": "0xac3485ce523faa13970412a89ef42d10939b44abd33cbcff1ed84cb566a3a3d5", + "type": 2, + "accessList": [], + "blockHash": "0xbe2ed47ff7925244e1f5779c6e9d41822ed1d0e414c02d8940bde808ad9dee6b", + "blockNumber": 36831713, + "transactionIndex": 0, + "confirmations": 1, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "gasPrice": { "type": "BigNumber", "hex": "0x3b9aca0e" }, + "maxPriorityFeePerGas": { "type": "BigNumber", "hex": "0x3b9aca07" }, + "maxFeePerGas": { "type": "BigNumber", "hex": "0x3b9aca07" }, + "gasLimit": { "type": "BigNumber", "hex": "0x012d3f" }, + "to": "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", + "value": { "type": "BigNumber", "hex": "0x00" }, + "nonce": 207, + "data": "0x30f28b7a000000000000000000000000e91d153e0b41518a2ce8dd3d7944fa863463a97d000000000000000000000000000000000000000000000002b5e3af16b1880000bbd11ba398cf5a4f8a627a8fcb3d8ecdb447913302e83585857d73161aeb5b4effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000d51b09ad92e08b962c994374f4e417d4ad435189000000000000000000000000000000000000000000000002b5e3af16b188000000000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c80000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000004158758fa7c4746df16c39599b95a3e2529d91a7aea6fc1aabb536d915666a6b565be4ae868a48c9ef944e8ed6e3313f429078558a849aebdcc22b56935edddd8c1b00000000000000000000000000000000000000000000000000000000000000", + "r": "0xa06ccc03e14153825203a9548847701d5896b261937abaed3f06582359832c67", + "s": "0x3a283f7e2513cf6b781dbc91f9effaf0bbddd134e19df505c8dac664b6bab173", + "v": 1, + "creates": null, + "chainId": 31337 +} diff --git a/tests/fixtures/post-order/mined-tx-permit-expired.json b/tests/fixtures/post-order/mined-tx-permit-expired.json new file mode 100644 index 00000000..b414e719 --- /dev/null +++ b/tests/fixtures/post-order/mined-tx-permit-expired.json @@ -0,0 +1,23 @@ +{ + "hash": "0xfac827e7448c6578f7a22f7f90ec64693ef54238164d50dd895567f382d3c0bb", + "type": 2, + "accessList": [], + "blockHash": "0x8e8102a5b355a72106518f7af259fda0a959692d24ac9c015836d01639fac0c4", + "blockNumber": 36838665, + "transactionIndex": 0, + "confirmations": 1, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "gasPrice": { "type": "BigNumber", "hex": "0x3b9aca0e" }, + "maxPriorityFeePerGas": { "type": "BigNumber", "hex": "0x3b9aca07" }, + "maxFeePerGas": { "type": "BigNumber", "hex": "0x3b9aca07" }, + "gasLimit": { "type": "BigNumber", "hex": "0x012bef" }, + "to": "0x000000000022D473030F116dDEE9F6B43aC78BA3", + "value": { "type": "BigNumber", "hex": "0x00" }, + "nonce": 205, + "data": "0x30f28b7a000000000000000000000000e91d153e0b41518a2ce8dd3d7944fa863463a97d000000000000000000000000000000000000000000000002b5e3af16b188000049a75d1b9488a1fd13f4d3602947b7df1d6cb884bffba367ef292d329debfe6e000000000000000000000000000000000000000000000000000000006727bcdb000000000000000000000000d51b09ad92e08b962c994374f4e417d4ad435189000000000000000000000000000000000000000000000002b5e3af16b188000000000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c800000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000041abe0ffa5e4f1568772c01efa5e3449293527c9a57c8cead8a077411217fd7c6153076266a0ca91072e9ab65b7668ae937c70d5b9caf819b4ae9ef32a3d60699b1b00000000000000000000000000000000000000000000000000000000000000", + "r": "0xd35b0e7cb997cd8975dd42a0d243e1ce44d5bfbaa2a69cc04964d91e1cb20c20", + "s": "0x3e7e444fa87a9f2278f3765c9cb34cfe61be2584a15973ae0ba20312c31469a6", + "v": 1, + "creates": null, + "chainId": 31337 +} diff --git a/tests/fixtures/post-order/mined-tx-too-high.json b/tests/fixtures/post-order/mined-tx-too-high.json new file mode 100644 index 00000000..2aea36ce --- /dev/null +++ b/tests/fixtures/post-order/mined-tx-too-high.json @@ -0,0 +1,23 @@ +{ + "hash": "0x9c9fd8cde45957741c16f0af4ab191d9b010c6f95d351df8c023e14a2ac80aa2", + "type": 2, + "accessList": [], + "blockHash": "0x31f05e69a2e9a56e0e905812b6af2ce571bb8bc9207af97d970dec6099978b7e", + "blockNumber": 36838251, + "transactionIndex": 0, + "confirmations": 1, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "gasPrice": { "type": "BigNumber", "hex": "0x3b9aca0e" }, + "maxPriorityFeePerGas": { "type": "BigNumber", "hex": "0x3b9aca07" }, + "maxFeePerGas": { "type": "BigNumber", "hex": "0x3b9aca07" }, + "gasLimit": { "type": "BigNumber", "hex": "0x012d3f" }, + "to": "0x000000000022D473030F116dDEE9F6B43aC78BA3", + "value": { "type": "BigNumber", "hex": "0x00" }, + "nonce": 208, + "data": "0x30f28b7a000000000000000000000000e91d153e0b41518a2ce8dd3d7944fa863463a97d00000000000000000000000000000000000000000000006c6b935b8bbd4000004e688e040cc4d8831571638fe3b615106143c04cda994091f9cebe7801892573ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000d51b09ad92e08b962c994374f4e417d4ad43518900000000000000000000000000000000000000000000006c6b935b8bbd40000000000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000417ea7ace98a20233ec812742c32624230b14db856edab1524f21e8530194098cf0ce5ed4dc07eb68f72854aa8263c031b0c51647a1de7b7dd56f4f1e2731b950e1c00000000000000000000000000000000000000000000000000000000000000", + "r": "0xccafcb6a1004b6a9c5e8ee4b811dc1108be3e61b0faad6c7b488ae60174ab416", + "s": "0x5124d4c429004afca89aebb840a14a6a59983a85242a6f2339c464536dfbfcde", + "v": 1, + "creates": null, + "chainId": 31337 +} diff --git a/tests/fixtures/post-order/mined-tx-too-low.json b/tests/fixtures/post-order/mined-tx-too-low.json new file mode 100644 index 00000000..6ff51e6f --- /dev/null +++ b/tests/fixtures/post-order/mined-tx-too-low.json @@ -0,0 +1,23 @@ +{ + "hash": "0xf21e2ce3a5106c6ddd0d70c8925965878a2604ed042990be49b05773196bb6b4", + "type": 2, + "accessList": [], + "blockHash": "0x6615574922a288c8e879a6d75d018fe41ef8004257c57c050038da4bdd632789", + "blockNumber": 36838250, + "transactionIndex": 0, + "confirmations": 1, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "gasPrice": { "type": "BigNumber", "hex": "0x3b9aca0e" }, + "maxPriorityFeePerGas": { "type": "BigNumber", "hex": "0x3b9aca07" }, + "maxFeePerGas": { "type": "BigNumber", "hex": "0x3b9aca07" }, + "gasLimit": { "type": "BigNumber", "hex": "0x012d27" }, + "to": "0x000000000022D473030F116dDEE9F6B43aC78BA3", + "value": { "type": "BigNumber", "hex": "0x00" }, + "nonce": 207, + "data": "0x30f28b7a000000000000000000000000e91d153e0b41518a2ce8dd3d7944fa863463a97d00000000000000000000000000000000000000000000000006f05b59d3b20000fc195ec4cea3ad3ca9fbdb0615ed6a5883ba0585c1a4fe68cf9abc67ce41487cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000d51b09ad92e08b962c994374f4e417d4ad43518900000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c800000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000041cc219f505c7598cfc439b4592bad51490e216c11d424f2d36c09f74f8ca6cac9653aa5972d2c851ec10b1a89673b3de6905574829416fd735c8a250361afdef41c00000000000000000000000000000000000000000000000000000000000000", + "r": "0x3de9b4a534165a089d0b6f60149e9ad1a8c9335256c6a1bef973921b5460157e", + "s": "0x11c5d116c1427c291545c42fd512be87a7bc59b30b511a3c56c271b8a8729022", + "v": 1, + "creates": null, + "chainId": 31337 +} diff --git a/tests/fixtures/post-order/mined-tx-uusd.json b/tests/fixtures/post-order/mined-tx-uusd.json new file mode 100644 index 00000000..c9e1284c --- /dev/null +++ b/tests/fixtures/post-order/mined-tx-uusd.json @@ -0,0 +1,23 @@ +{ + "hash": "0xdf1bf8b6d679e406f43b57692a2dcbb450e38d5de72e5199d836b701d0a4306f", + "type": 2, + "accessList": [], + "blockHash": "0xc388a3d6909e9518a3e63c94a3c008eae13cfad681573a8936947fae431b2b74", + "blockNumber": 36865616, + "transactionIndex": 0, + "confirmations": 1, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "gasPrice": { "type": "BigNumber", "hex": "0x3b9aca10" }, + "maxPriorityFeePerGas": { "type": "BigNumber", "hex": "0x3b9aca08" }, + "maxFeePerGas": { "type": "BigNumber", "hex": "0x3b9aca08" }, + "gasLimit": { "type": "BigNumber", "hex": "0x548c" }, + "to": "0x0F644658510c95CB46955e55D7BA9DDa9E9fBEc6", + "value": { "type": "BigNumber", "hex": "0x00" }, + "nonce": 205, + "data": "0xa9059cbb000000000000000000000000d51b09ad92e08b962c994374f4e417d4ad435189000000000000000000000000000000000000000000000001a055690d9db80000", + "r": "0x57a41b896d3ecf2e9b3cafeeed1fe35e4436d2533f019ab8b7220d2eb80208ac", + "s": "0x7751411973ecffe2712fa28befaa56f0db9ebc2e6e6a69d1a99b6575c2b1ec4e", + "v": 0, + "creates": null, + "chainId": 31337 +} diff --git a/tests/fixtures/post-order/mined-tx.json b/tests/fixtures/post-order/mined-tx.json new file mode 100644 index 00000000..544f0108 --- /dev/null +++ b/tests/fixtures/post-order/mined-tx.json @@ -0,0 +1,23 @@ +{ + "hash": "0xac3485ce523faa13970412a89ef42d10939b44abd33cbcff1ed84cb566a3a3d5", + "type": 2, + "accessList": [], + "blockHash": "0xbe2ed47ff7925244e1f5779c6e9d41822ed1d0e414c02d8940bde808ad9dee6b", + "blockNumber": 36831713, + "transactionIndex": 0, + "confirmations": 1, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "gasPrice": { "type": "BigNumber", "hex": "0x3b9aca0e" }, + "maxPriorityFeePerGas": { "type": "BigNumber", "hex": "0x3b9aca07" }, + "maxFeePerGas": { "type": "BigNumber", "hex": "0x3b9aca07" }, + "gasLimit": { "type": "BigNumber", "hex": "0x012d3f" }, + "to": "0x000000000022D473030F116dDEE9F6B43aC78BA3", + "value": { "type": "BigNumber", "hex": "0x00" }, + "nonce": 207, + "data": "0x30f28b7a000000000000000000000000e91d153e0b41518a2ce8dd3d7944fa863463a97d000000000000000000000000000000000000000000000002b5e3af16b1880000bbd11ba398cf5a4f8a627a8fcb3d8ecdb447913302e83585857d73161aeb5b4effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000d51b09ad92e08b962c994374f4e417d4ad435189000000000000000000000000000000000000000000000002b5e3af16b188000000000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c80000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000004158758fa7c4746df16c39599b95a3e2529d91a7aea6fc1aabb536d915666a6b565be4ae868a48c9ef944e8ed6e3313f429078558a849aebdcc22b56935edddd8c1b00000000000000000000000000000000000000000000000000000000000000", + "r": "0xa06ccc03e14153825203a9548847701d5896b261937abaed3f06582359832c67", + "s": "0x3a283f7e2513cf6b781dbc91f9effaf0bbddd134e19df505c8dac664b6bab173", + "v": 1, + "creates": null, + "chainId": 31337 +} diff --git a/tests/fixtures/post-order/order-card-13959.json b/tests/fixtures/post-order/order-card-13959.json new file mode 100644 index 00000000..468175d5 --- /dev/null +++ b/tests/fixtures/post-order/order-card-13959.json @@ -0,0 +1,33 @@ +{ + "transactionId": 39018, + "amount": 50, + "discount": 0, + "currencyCode": "USD", + "fee": 6, + "smsFee": 0, + "totalFee": 6, + "preOrdered": false, + "recipientEmail": null, + "recipientPhone": null, + "customIdentifier": "0xd670e1f4f47a0104217f30a8804f7e13803da1dbfd9270dcb6d8d3a5ba72a52e", + "status": "SUCCESSFUL", + "transactionCreatedTime": "2024-11-03 03:25:42", + "product": { + "productId": 13959, + "productName": "Vanilla® eGift Visa", + "countryCode": "US", + "quantity": 1, + "unitPrice": 44, + "totalPrice": 44, + "currencyCode": "USD", + "brand": { "brandId": 95, "brandName": "Vanilla® eGift Visa" } + }, + "balanceInfo": { + "oldBalance": 212439823.44865, + "newBalance": 212439773.44865, + "cost": 50, + "currencyCode": "USD", + "currencyName": "US Dollar", + "updatedAt": "2024-11-02 13:46:17" + } +} diff --git a/tests/fixtures/post-order/order-card-18597.json b/tests/fixtures/post-order/order-card-18597.json new file mode 100644 index 00000000..1bf4457a --- /dev/null +++ b/tests/fixtures/post-order/order-card-18597.json @@ -0,0 +1,36 @@ +{ + "transactionId": 39018, + "amount": 50, + "discount": 0, + "currencyCode": "USD", + "fee": 6, + "smsFee": 0, + "totalFee": 6, + "preOrdered": false, + "recipientEmail": null, + "recipientPhone": null, + "customIdentifier": "0xd670e1f4f47a0104217f30a8804f7e13803da1dbfd9270dcb6d8d3a5ba72a52e", + "status": "SUCCESSFUL", + "transactionCreatedTime": "2024-11-03 03:25:42", + "product": { + "productId": 18597, + "productName": "Virtual MasterCard International USD US", + "countryCode": "US", + "quantity": 1, + "unitPrice": 44, + "totalPrice": 44, + "currencyCode": "USD", + "brand": { + "brandId": 378, + "brandName": "Mastercard" + } + }, + "balanceInfo": { + "oldBalance": 212439823.44865, + "newBalance": 212439773.44865, + "cost": 50, + "currencyCode": "USD", + "currencyName": "US Dollar", + "updatedAt": "2024-11-02 13:46:17" + } +} diff --git a/tests/fixtures/post-order/parsed-tx-uusd-wrong-method.json b/tests/fixtures/post-order/parsed-tx-uusd-wrong-method.json new file mode 100644 index 00000000..617e13c1 --- /dev/null +++ b/tests/fixtures/post-order/parsed-tx-uusd-wrong-method.json @@ -0,0 +1,50 @@ +{ + "args": ["0xD51B09ad92e08B962c994374F4e417d4AD435189", "0x01a055690d9db80000"], + "functionFragment": { + "type": "function", + "name": "transferEdited", + "constant": false, + "inputs": [ + { + "name": "dst", + "type": "address", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "address", + "_isParamType": true + }, + { + "name": "wad", + "type": "uint256", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "uint256", + "_isParamType": true + } + ], + "outputs": [ + { + "name": null, + "type": "bool", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "bool", + "_isParamType": true + } + ], + "payable": false, + "stateMutability": "nonpayable", + "gas": null, + "_isFragment": true + }, + "name": "transfer", + "signature": "transfer(address,uint256)", + "sighash": "0xa9059cbb", + "value": { "type": "BigNumber", "hex": "0x00" } +} diff --git a/tests/fixtures/post-order/parsed-tx-uusd-wrong-treasury.json b/tests/fixtures/post-order/parsed-tx-uusd-wrong-treasury.json new file mode 100644 index 00000000..8238d0f2 --- /dev/null +++ b/tests/fixtures/post-order/parsed-tx-uusd-wrong-treasury.json @@ -0,0 +1,50 @@ +{ + "args": ["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "0x01a055690d9db80000"], + "functionFragment": { + "type": "function", + "name": "transfer", + "constant": false, + "inputs": [ + { + "name": "dst", + "type": "address", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "address", + "_isParamType": true + }, + { + "name": "wad", + "type": "uint256", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "uint256", + "_isParamType": true + } + ], + "outputs": [ + { + "name": null, + "type": "bool", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "bool", + "_isParamType": true + } + ], + "payable": false, + "stateMutability": "nonpayable", + "gas": null, + "_isFragment": true + }, + "name": "transfer", + "signature": "transfer(address,uint256)", + "sighash": "0xa9059cbb", + "value": { "type": "BigNumber", "hex": "0x00" } +} diff --git a/tests/fixtures/post-order/parsed-tx-wrong-method.json b/tests/fixtures/post-order/parsed-tx-wrong-method.json new file mode 100644 index 00000000..35094ed8 --- /dev/null +++ b/tests/fixtures/post-order/parsed-tx-wrong-method.json @@ -0,0 +1,151 @@ +{ + "args": { + "permit": { + "0": { "token": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d" }, + "deadline": 33287622343 + }, + "transferDetails": { + "requestedAmount": "0x02b5e3af16b1880000", + "to": "0xD51B09ad92e08B962c994374F4e417d4AD435189" + }, + + "0": [ + ["0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", { "type": "BigNumber", "hex": "0x02b5e3af16b1880000" }], + { "type": "BigNumber", "hex": "0x736d6a935bb4879ae1e94d2ff4ee433a5d705d6cef7b1fa174fa169575bf4a76" }, + { "type": "BigNumber", "hex": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } + ], + "1": ["0xD51B09ad92e08B962c994374F4e417d4AD435189", { "type": "BigNumber", "hex": "0x02b5e3af16b1880000" }], + "2": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", + "3": "0xf65ed5757fdee7f70a5c3b2ac021b7ae4f028293f6a63735fab3e4c973d00af67693d6435f4968ee446491391294e38ae46184e2351b1cc896d4d4e38520e0ec1c" + }, + + "functionFragment": { + "type": "function", + "name": "permitTransferFromEdited", + "constant": false, + "inputs": [ + { + "name": "permit", + "type": "tuple", + "indexed": null, + "components": [ + { + "name": "permitted", + "type": "tuple", + "indexed": null, + "components": [ + { + "name": "token", + "type": "address", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "address", + "_isParamType": true + }, + { + "name": "amount", + "type": "uint256", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "uint256", + "_isParamType": true + } + ], + "arrayLength": null, + "arrayChildren": null, + "baseType": "tuple", + "_isParamType": true + }, + { + "name": "nonce", + "type": "uint256", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "uint256", + "_isParamType": true + }, + { + "name": "deadline", + "type": "uint256", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "uint256", + "_isParamType": true + } + ], + "arrayLength": null, + "arrayChildren": null, + "baseType": "tuple", + "_isParamType": true + }, + { + "name": "transferDetails", + "type": "tuple", + "indexed": null, + "components": [ + { + "name": "to", + "type": "address", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "address", + "_isParamType": true + }, + { + "name": "requestedAmount", + "type": "uint256", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "uint256", + "_isParamType": true + } + ], + "arrayLength": null, + "arrayChildren": null, + "baseType": "tuple", + "_isParamType": true + }, + { + "name": "owner", + "type": "address", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "address", + "_isParamType": true + }, + { + "name": "signature", + "type": "bytes", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "bytes", + "_isParamType": true + } + ], + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "gas": null, + "_isFragment": true + }, + "name": "permitTransferFrom", + "signature": "permitTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes)", + "sighash": "0x30f28b7a", + "value": { "type": "BigNumber", "hex": "0x00" } +} diff --git a/tests/fixtures/post-order/parsed-tx-wrong-token.json b/tests/fixtures/post-order/parsed-tx-wrong-token.json new file mode 100644 index 00000000..7ec927f3 --- /dev/null +++ b/tests/fixtures/post-order/parsed-tx-wrong-token.json @@ -0,0 +1,151 @@ +{ + "args": { + "permit": { + "0": { "token": "0x4ECaBa5870353805a9F068101A40E0f32ed605C6" }, + "deadline": 33287622343 + }, + "transferDetails": { + "requestedAmount": "0x02b5e3af16b1880000", + "to": "0xD51B09ad92e08B962c994374F4e417d4AD435189" + }, + + "0": [ + ["0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", { "type": "BigNumber", "hex": "0x02b5e3af16b1880000" }], + { "type": "BigNumber", "hex": "0x736d6a935bb4879ae1e94d2ff4ee433a5d705d6cef7b1fa174fa169575bf4a76" }, + { "type": "BigNumber", "hex": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } + ], + "1": ["0xD51B09ad92e08B962c994374F4e417d4AD435189", { "type": "BigNumber", "hex": "0x02b5e3af16b1880000" }], + "2": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", + "3": "0xf65ed5757fdee7f70a5c3b2ac021b7ae4f028293f6a63735fab3e4c973d00af67693d6435f4968ee446491391294e38ae46184e2351b1cc896d4d4e38520e0ec1c" + }, + + "functionFragment": { + "type": "function", + "name": "permitTransferFrom", + "constant": false, + "inputs": [ + { + "name": "permit", + "type": "tuple", + "indexed": null, + "components": [ + { + "name": "permitted", + "type": "tuple", + "indexed": null, + "components": [ + { + "name": "token", + "type": "address", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "address", + "_isParamType": true + }, + { + "name": "amount", + "type": "uint256", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "uint256", + "_isParamType": true + } + ], + "arrayLength": null, + "arrayChildren": null, + "baseType": "tuple", + "_isParamType": true + }, + { + "name": "nonce", + "type": "uint256", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "uint256", + "_isParamType": true + }, + { + "name": "deadline", + "type": "uint256", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "uint256", + "_isParamType": true + } + ], + "arrayLength": null, + "arrayChildren": null, + "baseType": "tuple", + "_isParamType": true + }, + { + "name": "transferDetails", + "type": "tuple", + "indexed": null, + "components": [ + { + "name": "to", + "type": "address", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "address", + "_isParamType": true + }, + { + "name": "requestedAmount", + "type": "uint256", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "uint256", + "_isParamType": true + } + ], + "arrayLength": null, + "arrayChildren": null, + "baseType": "tuple", + "_isParamType": true + }, + { + "name": "owner", + "type": "address", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "address", + "_isParamType": true + }, + { + "name": "signature", + "type": "bytes", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "bytes", + "_isParamType": true + } + ], + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "gas": null, + "_isFragment": true + }, + "name": "permitTransferFrom", + "signature": "permitTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes)", + "sighash": "0x30f28b7a", + "value": { "type": "BigNumber", "hex": "0x00" } +} diff --git a/tests/fixtures/post-order/parsed-tx-wrong-treasury.json b/tests/fixtures/post-order/parsed-tx-wrong-treasury.json new file mode 100644 index 00000000..0675b11b --- /dev/null +++ b/tests/fixtures/post-order/parsed-tx-wrong-treasury.json @@ -0,0 +1,151 @@ +{ + "args": { + "permit": { + "0": { "token": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d" }, + "deadline": 33287622343 + }, + "transferDetails": { + "requestedAmount": "0x02b5e3af16b1880000", + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + }, + + "0": [ + ["0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", { "type": "BigNumber", "hex": "0x02b5e3af16b1880000" }], + { "type": "BigNumber", "hex": "0x736d6a935bb4879ae1e94d2ff4ee433a5d705d6cef7b1fa174fa169575bf4a76" }, + { "type": "BigNumber", "hex": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } + ], + "1": ["0xD51B09ad92e08B962c994374F4e417d4AD435189", { "type": "BigNumber", "hex": "0x02b5e3af16b1880000" }], + "2": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", + "3": "0xf65ed5757fdee7f70a5c3b2ac021b7ae4f028293f6a63735fab3e4c973d00af67693d6435f4968ee446491391294e38ae46184e2351b1cc896d4d4e38520e0ec1c" + }, + + "functionFragment": { + "type": "function", + "name": "permitTransferFrom", + "constant": false, + "inputs": [ + { + "name": "permit", + "type": "tuple", + "indexed": null, + "components": [ + { + "name": "permitted", + "type": "tuple", + "indexed": null, + "components": [ + { + "name": "token", + "type": "address", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "address", + "_isParamType": true + }, + { + "name": "amount", + "type": "uint256", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "uint256", + "_isParamType": true + } + ], + "arrayLength": null, + "arrayChildren": null, + "baseType": "tuple", + "_isParamType": true + }, + { + "name": "nonce", + "type": "uint256", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "uint256", + "_isParamType": true + }, + { + "name": "deadline", + "type": "uint256", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "uint256", + "_isParamType": true + } + ], + "arrayLength": null, + "arrayChildren": null, + "baseType": "tuple", + "_isParamType": true + }, + { + "name": "transferDetails", + "type": "tuple", + "indexed": null, + "components": [ + { + "name": "to", + "type": "address", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "address", + "_isParamType": true + }, + { + "name": "requestedAmount", + "type": "uint256", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "uint256", + "_isParamType": true + } + ], + "arrayLength": null, + "arrayChildren": null, + "baseType": "tuple", + "_isParamType": true + }, + { + "name": "owner", + "type": "address", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "address", + "_isParamType": true + }, + { + "name": "signature", + "type": "bytes", + "indexed": null, + "components": null, + "arrayLength": null, + "arrayChildren": null, + "baseType": "bytes", + "_isParamType": true + } + ], + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "gas": null, + "_isFragment": true + }, + "name": "permitTransferFrom", + "signature": "permitTransferFrom(((address,uint256),uint256,uint256),(address,uint256),address,bytes)", + "sighash": "0x30f28b7a", + "value": { "type": "BigNumber", "hex": "0x00" } +} diff --git a/tests/fixtures/post-order/receipt-not-permit2.json b/tests/fixtures/post-order/receipt-not-permit2.json new file mode 100644 index 00000000..3ebefc95 --- /dev/null +++ b/tests/fixtures/post-order/receipt-not-permit2.json @@ -0,0 +1,34 @@ +{ + "to": "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": null, + "transactionIndex": 0, + "root": "0x0000000000000000000000000000000000000000000000000000000000000000", + "gasUsed": { "type": "BigNumber", "hex": "0x012c60" }, + "logsBloom": "0x000000000000000000020000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100100000000000000000000000000000000080000000000000000000000000a0000000000000000000800000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000", + "blockHash": "0xbe2ed47ff7925244e1f5779c6e9d41822ed1d0e414c02d8940bde808ad9dee6b", + "transactionHash": "0xac3485ce523faa13970412a89ef42d10939b44abd33cbcff1ed84cb566a3a3d5", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 36831713, + "transactionHash": "0xac3485ce523faa13970412a89ef42d10939b44abd33cbcff1ed84cb566a3a3d5", + "address": "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", + "0x000000000000000000000000d51b09ad92e08b962c994374f4e417d4ad435189" + ], + "data": "0x000000000000000000000000000000000000000000000002b5e3af16b1880000", + "logIndex": 0, + "blockHash": "0xbe2ed47ff7925244e1f5779c6e9d41822ed1d0e414c02d8940bde808ad9dee6b" + } + ], + "blockNumber": 36831713, + "confirmations": 1, + "cumulativeGasUsed": { "type": "BigNumber", "hex": "0x012c60" }, + "effectiveGasPrice": { "type": "BigNumber", "hex": "0x3b9aca0e" }, + "status": 1, + "type": 2, + "byzantium": true +} diff --git a/tests/fixtures/post-order/receipt-permit-expired.json b/tests/fixtures/post-order/receipt-permit-expired.json new file mode 100644 index 00000000..77747b56 --- /dev/null +++ b/tests/fixtures/post-order/receipt-permit-expired.json @@ -0,0 +1,34 @@ +{ + "to": "0x000000000022D473030F116dDEE9F6B43aC78BA3", + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": null, + "transactionIndex": 0, + "root": "0x0000000000000000000000000000000000000000000000000000000000000000", + "gasUsed": { "type": "BigNumber", "hex": "0x012b10" }, + "logsBloom": "0x000000000000000000020000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100100000000000000000000000000000000080000000000000000000000000a0000000000000000000800000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000", + "blockHash": "0x8e8102a5b355a72106518f7af259fda0a959692d24ac9c015836d01639fac0c4", + "transactionHash": "0xfac827e7448c6578f7a22f7f90ec64693ef54238164d50dd895567f382d3c0bb", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 36838665, + "transactionHash": "0xfac827e7448c6578f7a22f7f90ec64693ef54238164d50dd895567f382d3c0bb", + "address": "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", + "0x000000000000000000000000d51b09ad92e08b962c994374f4e417d4ad435189" + ], + "data": "0x000000000000000000000000000000000000000000000002b5e3af16b1880000", + "logIndex": 0, + "blockHash": "0x8e8102a5b355a72106518f7af259fda0a959692d24ac9c015836d01639fac0c4" + } + ], + "blockNumber": 36838665, + "confirmations": 1, + "cumulativeGasUsed": { "type": "BigNumber", "hex": "0x012b10" }, + "effectiveGasPrice": { "type": "BigNumber", "hex": "0x3b9aca0e" }, + "status": 1, + "type": 2, + "byzantium": true +} diff --git a/tests/fixtures/post-order/receipt-too-high.json b/tests/fixtures/post-order/receipt-too-high.json new file mode 100644 index 00000000..3c0c448b --- /dev/null +++ b/tests/fixtures/post-order/receipt-too-high.json @@ -0,0 +1,34 @@ +{ + "to": "0x000000000022D473030F116dDEE9F6B43aC78BA3", + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": null, + "transactionIndex": 0, + "root": "0x0000000000000000000000000000000000000000000000000000000000000000", + "gasUsed": { "type": "BigNumber", "hex": "0x012c60" }, + "logsBloom": "0x000000000000000000020000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100100000000000000000000000000000000080000000000000000000000000a0000000000000000000800000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000", + "blockHash": "0x31f05e69a2e9a56e0e905812b6af2ce571bb8bc9207af97d970dec6099978b7e", + "transactionHash": "0x9c9fd8cde45957741c16f0af4ab191d9b010c6f95d351df8c023e14a2ac80aa2", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 36838251, + "transactionHash": "0x9c9fd8cde45957741c16f0af4ab191d9b010c6f95d351df8c023e14a2ac80aa2", + "address": "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", + "0x000000000000000000000000d51b09ad92e08b962c994374f4e417d4ad435189" + ], + "data": "0x00000000000000000000000000000000000000000000006c6b935b8bbd400000", + "logIndex": 0, + "blockHash": "0x31f05e69a2e9a56e0e905812b6af2ce571bb8bc9207af97d970dec6099978b7e" + } + ], + "blockNumber": 36838251, + "confirmations": 1, + "cumulativeGasUsed": { "type": "BigNumber", "hex": "0x012c60" }, + "effectiveGasPrice": { "type": "BigNumber", "hex": "0x3b9aca0e" }, + "status": 1, + "type": 2, + "byzantium": true +} diff --git a/tests/fixtures/post-order/receipt-too-low.json b/tests/fixtures/post-order/receipt-too-low.json new file mode 100644 index 00000000..3b13d466 --- /dev/null +++ b/tests/fixtures/post-order/receipt-too-low.json @@ -0,0 +1,34 @@ +{ + "to": "0x000000000022D473030F116dDEE9F6B43aC78BA3", + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": null, + "transactionIndex": 0, + "root": "0x0000000000000000000000000000000000000000000000000000000000000000", + "gasUsed": { "type": "BigNumber", "hex": "0x012c48" }, + "logsBloom": "0x000000000000000000020000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100100000000000000000000000000000000080000000000000000000000000a0000000000000000000800000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000", + "blockHash": "0x6615574922a288c8e879a6d75d018fe41ef8004257c57c050038da4bdd632789", + "transactionHash": "0xf21e2ce3a5106c6ddd0d70c8925965878a2604ed042990be49b05773196bb6b4", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 36838250, + "transactionHash": "0xf21e2ce3a5106c6ddd0d70c8925965878a2604ed042990be49b05773196bb6b4", + "address": "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", + "0x000000000000000000000000d51b09ad92e08b962c994374f4e417d4ad435189" + ], + "data": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000", + "logIndex": 0, + "blockHash": "0x6615574922a288c8e879a6d75d018fe41ef8004257c57c050038da4bdd632789" + } + ], + "blockNumber": 36838250, + "confirmations": 1, + "cumulativeGasUsed": { "type": "BigNumber", "hex": "0x012c48" }, + "effectiveGasPrice": { "type": "BigNumber", "hex": "0x3b9aca0e" }, + "status": 1, + "type": 2, + "byzantium": true +} diff --git a/tests/fixtures/post-order/receipt-tx-for-mocked-parse.json b/tests/fixtures/post-order/receipt-tx-for-mocked-parse.json new file mode 100644 index 00000000..68308d9d --- /dev/null +++ b/tests/fixtures/post-order/receipt-tx-for-mocked-parse.json @@ -0,0 +1,34 @@ +{ + "to": "0x000000000022D473030F116dDEE9F6B43aC78BA3", + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": null, + "transactionIndex": 0, + "root": "0x0000000000000000000000000000000000000000000000000000000000000000", + "gasUsed": { "type": "BigNumber", "hex": "0x012c60" }, + "logsBloom": "0x000000000000000000020000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100100000000000000000000000000000000080000000000000000000000000a0000000000000000000800000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000", + "blockHash": "0x0c95167d8eccd0f9583bf50a3f730fce78b2bfafc602098a354cb52f9a25e230", + "transactionHash": "0xbef4c18032fbef0453f85191fb0fa91184b42d12ccc37f00eb7ae8c1d88a0233", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 36848219, + "transactionHash": "0xbef4c18032fbef0453f85191fb0fa91184b42d12ccc37f00eb7ae8c1d88a0233", + "address": "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", + "0x000000000000000000000000d51b09ad92e08b962c994374f4e417d4ad435189" + ], + "data": "0x000000000000000000000000000000000000000000000002b5e3af16b1880000", + "logIndex": 0, + "blockHash": "0x0c95167d8eccd0f9583bf50a3f730fce78b2bfafc602098a354cb52f9a25e230" + } + ], + "blockNumber": 36848219, + "confirmations": 1, + "cumulativeGasUsed": { "type": "BigNumber", "hex": "0x012c60" }, + "effectiveGasPrice": { "type": "BigNumber", "hex": "0x3b9aca0e" }, + "status": 1, + "type": 2, + "byzantium": true +} diff --git a/tests/fixtures/post-order/receipt-tx-uusd.json b/tests/fixtures/post-order/receipt-tx-uusd.json new file mode 100644 index 00000000..d7573d36 --- /dev/null +++ b/tests/fixtures/post-order/receipt-tx-uusd.json @@ -0,0 +1,19 @@ +{ + "to": "0x0F644658510c95CB46955e55D7BA9DDa9E9fBEc6", + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": null, + "transactionIndex": 0, + "root": "0x0000000000000000000000000000000000000000000000000000000000000000", + "gasUsed": { "type": "BigNumber", "hex": "0x548c" }, + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xc388a3d6909e9518a3e63c94a3c008eae13cfad681573a8936947fae431b2b74", + "transactionHash": "0xdf1bf8b6d679e406f43b57692a2dcbb450e38d5de72e5199d836b701d0a4306f", + "logs": [], + "blockNumber": 36865616, + "confirmations": 1, + "cumulativeGasUsed": { "type": "BigNumber", "hex": "0x548c" }, + "effectiveGasPrice": { "type": "BigNumber", "hex": "0x3b9aca10" }, + "status": 1, + "type": 2, + "byzantium": true +} diff --git a/tests/fixtures/post-order/receipt.json b/tests/fixtures/post-order/receipt.json new file mode 100644 index 00000000..6a65d887 --- /dev/null +++ b/tests/fixtures/post-order/receipt.json @@ -0,0 +1,34 @@ +{ + "to": "0x000000000022D473030F116dDEE9F6B43aC78BA3", + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "contractAddress": null, + "transactionIndex": 0, + "root": "0x0000000000000000000000000000000000000000000000000000000000000000", + "gasUsed": { "type": "BigNumber", "hex": "0x012c60" }, + "logsBloom": "0x000000000000000000020000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100100000000000000000000000000000000080000000000000000000000000a0000000000000000000800000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000", + "blockHash": "0xbe2ed47ff7925244e1f5779c6e9d41822ed1d0e414c02d8940bde808ad9dee6b", + "transactionHash": "0xac3485ce523faa13970412a89ef42d10939b44abd33cbcff1ed84cb566a3a3d5", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 36831713, + "transactionHash": "0xac3485ce523faa13970412a89ef42d10939b44abd33cbcff1ed84cb566a3a3d5", + "address": "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8", + "0x000000000000000000000000d51b09ad92e08b962c994374f4e417d4ad435189" + ], + "data": "0x000000000000000000000000000000000000000000000002b5e3af16b1880000", + "logIndex": 0, + "blockHash": "0xbe2ed47ff7925244e1f5779c6e9d41822ed1d0e414c02d8940bde808ad9dee6b" + } + ], + "blockNumber": 36831713, + "confirmations": 1, + "cumulativeGasUsed": { "type": "BigNumber", "hex": "0x012c60" }, + "effectiveGasPrice": { "type": "BigNumber", "hex": "0x3b9aca0e" }, + "status": 1, + "type": 2, + "byzantium": true +} diff --git a/tests/tsconfig.json b/tests/tsconfig.json new file mode 100644 index 00000000..f8ade877 --- /dev/null +++ b/tests/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "types": ["@cloudflare/workers-types/experimental", "@cloudflare/vitest-pool-workers"] + }, + "include": ["./**/*.ts", "../src/env.d.ts"] +} diff --git a/tests/unit/get-best-card.test.ts b/tests/unit/get-best-card.test.ts new file mode 100644 index 00000000..eea11a08 --- /dev/null +++ b/tests/unit/get-best-card.test.ts @@ -0,0 +1,77 @@ +import { parseEther } from "@ethersproject/units"; +import { createExecutionContext, waitOnExecutionContext } from "cloudflare:test"; +import { setupServer, SetupServerApi } from "msw/node"; +import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest"; +import { onRequest as pagesFunction } from "../../functions/get-best-card"; +import bestCard from "../fixtures/get-best-card/best-card-sandbox.json"; +import card18597 from "../fixtures/get-best-card/card-18597.json"; +import { httpMocks } from "../fixtures/http-mocks"; +import { createEventContext, TESTS_BASE_URL } from "./shared-utils"; + +describe("Get best payment card", () => { + let server: SetupServerApi; + let execContext: ExecutionContext; + + beforeAll(() => { + execContext = createExecutionContext(); + try { + server = setupServer(...httpMocks); + server.listen({ onUnhandledRequest: "error" }); + } catch (e) { + console.log(`Error starting msw server: ${e}`); + } + }); + + afterEach(() => { + server.resetHandlers(); + }); + + afterAll(() => { + server.close(); + }); + + it("should respond with correct payment card on production", async () => { + const request = new Request(`${TESTS_BASE_URL}/get-best-card?country=US&amount=${parseEther("50")}`); + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(200); + expect(await response.json()).toEqual(card18597); + }); + + it("should respond with US International Mastercard for Malta as fallback", async () => { + const request = new Request(`${TESTS_BASE_URL}/get-best-card?country=MT&amount=${parseEther("50")}`); + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(200); + expect(await response.json()).toEqual(card18597); + }); + + it("should respond with no payment card for unsupported country", async () => { + const request = new Request(`${TESTS_BASE_URL}/get-best-card?country=PK&amount=${parseEther("50")}`); + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(404); + expect(await response.json()).toEqual({ message: "There are no gift cards available." }); + }); + + it("should respond with no payment card for low amount permit", async () => { + const request = new Request(`${TESTS_BASE_URL}/get-best-card?country=US&amount=${parseEther("1")}`); + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(404); + expect(await response.json()).toEqual({ message: "There are no gift cards available." }); + }); + + it("should respond with correct payment card for sandbox", async () => { + const request = new Request(`${TESTS_BASE_URL}/get-best-card?country=US&amount=${parseEther("50")}`); + const eventCtx = createEventContext(request, execContext, true); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(200); + expect(await response.json()).toEqual(bestCard); + }); +}); diff --git a/tests/unit/get-order.test.ts b/tests/unit/get-order.test.ts new file mode 100644 index 00000000..13f80ee3 --- /dev/null +++ b/tests/unit/get-order.test.ts @@ -0,0 +1,48 @@ +import { createExecutionContext, waitOnExecutionContext } from "cloudflare:test"; +import { setupServer, SetupServerApi } from "msw/node"; +import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest"; +import { onRequest as pagesFunction } from "../../functions/get-order"; +import order from "../fixtures/get-order/order.json"; +import { httpMocks } from "../fixtures/http-mocks"; +import { createEventContext, TESTS_BASE_URL } from "./shared-utils"; + +describe("Get payment card order", () => { + let server: SetupServerApi; + let execContext: ExecutionContext; + + beforeAll(() => { + execContext = createExecutionContext(); + try { + server = setupServer(...httpMocks); + server.listen({ onUnhandledRequest: "error" }); + } catch (e) { + console.log(`Error starting msw server: ${e}`); + } + }); + + afterEach(() => { + server.resetHandlers(); + }); + + afterAll(() => { + server.close(); + }); + + it("should respond with order details", async () => { + const request = new Request(`${TESTS_BASE_URL}/get-order?orderId=0xd89d85e5f65499e03f85cf5d4e69d04ee04d959cc04f8aa6a9fccba52b3c6916`); + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(200); + expect(await response.json()).toEqual(order); + }); + + it("should respond with error for invalid order id", async () => { + const request = new Request(`${TESTS_BASE_URL}/get-order?orderId=0xd89d85e5f65499e03f85cf5d4e69d04ee04d959cc04f8aa6a9fccba52b3c6917`); + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(404); + expect(await response.json()).toEqual("Order not found."); + }); +}); diff --git a/tests/unit/get-redeem-code.test.ts b/tests/unit/get-redeem-code.test.ts new file mode 100644 index 00000000..157c6619 --- /dev/null +++ b/tests/unit/get-redeem-code.test.ts @@ -0,0 +1,83 @@ +import { createExecutionContext, waitOnExecutionContext } from "cloudflare:test"; +import { setupServer, SetupServerApi } from "msw/node"; +import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest"; +import { onRequest as pagesFunction } from "../../functions/get-redeem-code"; +import card from "../fixtures/get-redeem-code/card.json"; +import { httpMocks } from "../fixtures/http-mocks"; +import { createEventContext, TESTS_BASE_URL } from "./shared-utils"; + +describe("Get payment card redeem code", () => { + let server: SetupServerApi; + let execContext: ExecutionContext; + + beforeAll(() => { + execContext = createExecutionContext(); + try { + server = setupServer(...httpMocks); + server.listen({ onUnhandledRequest: "error" }); + } catch (e) { + console.log(`Error starting msw server: ${e}`); + } + }); + + afterEach(() => { + server.resetHandlers(); + }); + + afterAll(() => { + server.close(); + }); + + it("should return redeem code", async () => { + const transactionId = "38994"; + const signedMessage = + "0x78870c5b97821f4d828d5fea945e331edb0c5938e0820910e7fccaead9179e3030a5d80e123c1e335005b4cc81dbd6509f1a31b71ee18074b8c70aeacad666351b"; + const wallet = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; + const permitSig = "0x4599c64a7e7556976972d50d961058280e752e1d824db0201305852e80601ed51e6a8bbb71047d09e8d4c75d450df1fc073c775426ee13f2006b8ad55ca2e49d1c"; + + const request = new Request( + `${TESTS_BASE_URL}/get-redeem-code?transactionId=${transactionId}&signedMessage=${signedMessage}&wallet=${wallet}&permitSig=${permitSig}` + ); + const eventCtx = createEventContext(request, execContext); + + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(200); + expect(await response.json()).toEqual(card); + }); + + it("should not return redeem code to user who is not actual buyer", async () => { + const transactionId = "38994"; + const signedMessage = + "0xccfa5da9e3ef32b0be38ea7930e7624beec5d4f69d580d0b2ab28b8c0cb1a8cd752b22fe36cd77235f47754298ce1d80ba430c6f7aac67f34a120617a07b21951b"; + const wallet = "0xE97e3b59B9c58a691bdb40De1698Af5fF29C2D71"; + const permitSig = "0x4599c64a7e7556976972d50d961058280e752e1d824db0201305852e80601ed51e6a8bbb71047d09e8d4c75d450df1fc073c775426ee13f2006b8ad55ca2e49d1c"; + + const request = new Request( + `${TESTS_BASE_URL}/get-redeem-code?transactionId=${transactionId}&signedMessage=${signedMessage}&wallet=${wallet}&permitSig=${permitSig}` + ); + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(403); + expect(await response.json()).toEqual({ message: "Given details are not valid to redeem code." }); + }); + + it("should return err when transaction id is empty", async () => { + const transactionId = ""; + const signedMessage = + "0x78870c5b97821f4d828d5fea945e331edb0c5938e0820910e7fccaead9179e3030a5d80e123c1e335005b4cc81dbd6509f1a31b71ee18074b8c70aeacad666351b"; + const wallet = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; + const permitSig = "0x4599c64a7e7556976972d50d961058280e752e1d824db0201305852e80601ed51e6a8bbb71047d09e8d4c75d450df1fc073c775426ee13f2006b8ad55ca2e49d1c"; + + const request = new Request( + `${TESTS_BASE_URL}/get-redeem-code?transactionId=${transactionId}&signedMessage=${signedMessage}&wallet=${wallet}&permitSig=${permitSig}` + ); + const eventCtx = createEventContext(request, execContext); + + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(403); + expect(await response.json()).toEqual({ message: "Given details are not valid to redeem code." }); + }); +}); diff --git a/tests/unit/post-order.test.ts b/tests/unit/post-order.test.ts new file mode 100644 index 00000000..22e0959a --- /dev/null +++ b/tests/unit/post-order.test.ts @@ -0,0 +1,426 @@ +import { TransactionDescription } from "@ethersproject/abi"; +import { TransactionReceipt, TransactionResponse } from "@ethersproject/providers"; +import { createExecutionContext, waitOnExecutionContext } from "cloudflare:test"; +import { setupServer, SetupServerApi } from "msw/node"; +import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, MockInstance, vi } from "vitest"; +import { onRequest as pagesFunction } from "../../functions/post-order"; +import { httpMocks } from "../fixtures/http-mocks"; +import minedTxForMockedParse from "../fixtures/post-order/mined-tx-for-mocked-parse.json"; +import minedTxNotPermit2 from "../fixtures/post-order/mined-tx-not-permit2.json"; +import minedTxPermitExpired from "../fixtures/post-order/mined-tx-permit-expired.json"; +import minedTxTooHigh from "../fixtures/post-order/mined-tx-too-high.json"; +import minedTxTooLow from "../fixtures/post-order/mined-tx-too-low.json"; +import minedTxUusd from "../fixtures/post-order/mined-tx-uusd.json"; +import minedTxGeneric from "../fixtures/post-order/mined-tx.json"; +import orderCard13959 from "../fixtures/post-order/order-card-13959.json"; +import orderCard18597 from "../fixtures/post-order/order-card-18597.json"; +import parsedTxUusdWrongMethod from "../fixtures/post-order/parsed-tx-uusd-wrong-method.json"; +import parsedTxUusdWrongTreasury from "../fixtures/post-order/parsed-tx-uusd-wrong-treasury.json"; +import parsedTxWrongMethod from "../fixtures/post-order/parsed-tx-wrong-method.json"; +import parsedTxWrongToken from "../fixtures/post-order/parsed-tx-wrong-token.json"; +import parsedTxWrongTreasury from "../fixtures/post-order/parsed-tx-wrong-treasury.json"; +import receiptNotPermit2 from "../fixtures/post-order/receipt-not-permit2.json"; +import receiptPermitExpired from "../fixtures/post-order/receipt-permit-expired.json"; +import receiptTooHigh from "../fixtures/post-order/receipt-too-high.json"; +import receiptTooLow from "../fixtures/post-order/receipt-too-low.json"; +import receiptTxForMockedParse from "../fixtures/post-order/receipt-tx-for-mocked-parse.json"; +import receiptUusd from "../fixtures/post-order/receipt-tx-uusd.json"; +import receiptGeneric from "../fixtures/post-order/receipt.json"; +import { createEventContext, TESTS_BASE_URL } from "./shared-utils"; + +describe("Post order for a payment card", () => { + let server: SetupServerApi; + let execContext: ExecutionContext; + let consoleMock: MockInstance; + const generalError = { message: "Transaction is not authorized to purchase gift card." }; + const uusd = "ubiquity-dollar"; + + beforeAll(async () => { + execContext = createExecutionContext(); + try { + server = setupServer(...httpMocks); + server.listen({ onUnhandledRequest: "error" }); + } catch (e) { + console.log(`Error starting msw server: ${e}`); + } + }); + + beforeEach(async () => { + consoleMock = vi.spyOn(console, "error").mockImplementationOnce(() => undefined); + }); + + afterEach(() => { + server.resetHandlers(); + vi.restoreAllMocks(); + }); + + afterAll(() => { + server.close(); + }); + + it("should post order on production with permit", async () => { + await initMocks(); + const request = new Request(`${TESTS_BASE_URL}/post-order`, { + method: "POST", + body: JSON.stringify({ + type: "permit", + chainId: 31337, + txHash: "0xac3485ce523faa13970412a89ef42d10939b44abd33cbcff1ed84cb566a3a3d5", + productId: 18597, + country: "US", + }), + }) as Request>; + + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(200); + expect(await response.json()).toEqual(orderCard18597); + }); + + it("should return err for ordering card that is not best suited", async () => { + await initMocks(); + const request = new Request(`${TESTS_BASE_URL}/post-order`, { + method: "POST", + body: JSON.stringify({ + type: "permit", + chainId: 31337, + txHash: "0xac3485ce523faa13970412a89ef42d10939b44abd33cbcff1ed84cb566a3a3d5", + productId: 18732, + country: "US", + }), + }) as Request>; + + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(500); + expect(await response.json()).toEqual({ message: "There was an error while processing your request." }); + }); + + it("should return err for ordering card for unsupported blockchain", async () => { + await initMocks(); + const request = new Request(`${TESTS_BASE_URL}/post-order`, { + method: "POST", + body: JSON.stringify({ + type: "permit", + chainId: 25, + txHash: "0xac3485ce523faa13970412a89ef42d10939b44abd33cbcff1ed84cb566a3a3d5", + productId: 18597, + country: "US", + }), + }) as Request>; + + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(403); + expect(await response.json()).toEqual({ message: "Unsupported chain" }); + }); + + it("should return err for ordering card with too low permit amount", async () => { + await initMocks(receiptTooLow, minedTxTooLow); + + const request = new Request(`${TESTS_BASE_URL}/post-order`, { + method: "POST", + body: JSON.stringify({ + type: "permit", + chainId: 31337, + txHash: "0xf21e2ce3a5106c6ddd0d70c8925965878a2604ed042990be49b05773196bb6b4", + productId: 18597, + country: "US", + }), + }) as Request>; + + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(403); + expect(await response.json()).toEqual({ message: "Your reward amount is either too high or too low to buy this card." }); + }); + + it("should return err for ordering card with too high permit amount", async () => { + await initMocks(receiptTooHigh, minedTxTooHigh); + + const request = new Request(`${TESTS_BASE_URL}/post-order`, { + method: "POST", + body: JSON.stringify({ + type: "permit", + chainId: 31337, + txHash: "0x9c9fd8cde45957741c16f0af4ab191d9b010c6f95d351df8c023e14a2ac80aa2", + productId: 18597, + country: "US", + }), + }) as Request>; + + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(403); + expect(await response.json()).toEqual({ message: "Your reward amount is either too high or too low to buy this card." }); + }); + + it("should return err for ordering card with expired permit", async () => { + await initMocks(receiptPermitExpired, minedTxPermitExpired); + const request = new Request(`${TESTS_BASE_URL}/post-order`, { + method: "POST", + body: JSON.stringify({ + type: "permit", + chainId: 31337, + txHash: "0xfac827e7448c6578f7a22f7f90ec64693ef54238164d50dd895567f382d3c0bb", + productId: 18597, + country: "US", + }), + }) as Request>; + + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(403); + expect(await response.json()).toEqual({ message: "The reward has expired." }); + }); + + it("should return err order with tx hash that not permit2 interaction", async () => { + await initMocks(receiptNotPermit2, minedTxNotPermit2); + + const request = new Request(`${TESTS_BASE_URL}/post-order`, { + method: "POST", + body: JSON.stringify({ + type: "permit", + chainId: 31337, + txHash: "0xfac827e7448c6578f7a22f7f90ec64693ef54238164d50dd895567f382d3c0bb", + productId: 18597, + country: "US", + }), + }) as Request>; + + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(403); + expect(await response.json()).toEqual(generalError); + expect(consoleMock).toHaveBeenLastCalledWith( + "Given transaction hash is not an interaction with permit2Address", + "txReceipt.to=0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", + "permit2Address=0x000000000022D473030F116dDEE9F6B43aC78BA3" + ); + }); + + it("should return error with tx hash that is not call to permitTransferFrom", async () => { + await initMocks(receiptTxForMockedParse, minedTxForMockedParse, parsedTxWrongMethod); + + const request = new Request(`${TESTS_BASE_URL}/post-order`, { + method: "POST", + body: JSON.stringify({ + type: "permit", + chainId: 31337, + txHash: "0xbef4c18032fbef0453f85191fb0fa91184b42d12ccc37f00eb7ae8c1d88a0233", + productId: 18597, + country: "US", + }), + }) as Request>; + + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(403); + expect(await response.json()).toEqual(generalError); + expect(consoleMock).toHaveBeenLastCalledWith( + "Given transaction hash is not call to contract function permitTransferFrom", + "txParsed.functionFragment.name=permitTransferFromEdited" + ); + }); + + it("should return error with tx hash that transfers wrong token", async () => { + await initMocks(receiptTxForMockedParse, minedTxForMockedParse, parsedTxWrongToken); + + const request = new Request(`${TESTS_BASE_URL}/post-order`, { + method: "POST", + body: JSON.stringify({ + type: "permit", + chainId: 31337, + txHash: "0xbef4c18032fbef0453f85191fb0fa91184b42d12ccc37f00eb7ae8c1d88a0233", + productId: 18597, + country: "US", + }), + }) as Request>; + + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(403); + expect(await response.json()).toEqual(generalError); + expect(consoleMock).toHaveBeenLastCalledWith( + "Given transaction hash is not transferring the required ERC20 token.", + '{"transferredToken":"0x4ECaBa5870353805a9F068101A40E0f32ed605C6","requiredToken":"0xe91d153e0b41518a2ce8dd3d7944fa863463a97d"}' + ); + }); + + it("should return error with tx hash that transfers to wrong treasury", async () => { + await initMocks(receiptTxForMockedParse, minedTxForMockedParse, parsedTxWrongTreasury); + const request = new Request(`${TESTS_BASE_URL}/post-order`, { + method: "POST", + body: JSON.stringify({ + type: "permit", + chainId: 31337, + txHash: "0xbef4c18032fbef0453f85191fb0fa91184b42d12ccc37f00eb7ae8c1d88a0233", + productId: 18597, + country: "US", + }), + }) as Request>; + + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(403); + expect(await response.json()).toEqual(generalError); + + expect(consoleMock).toHaveBeenLastCalledWith( + "Given transaction hash is not a token transfer to giftCardTreasuryAddress", + "txParsed.args.transferDetails.to=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "giftCardTreasuryAddress=0xD51B09ad92e08B962c994374F4e417d4AD435189" + ); + }); + + it("should post order with uusd", async () => { + await initMocks(receiptUusd, minedTxUusd); + const request = new Request(`${TESTS_BASE_URL}/post-order`, { + method: "POST", + body: JSON.stringify({ + type: uusd, + chainId: 31337, + txHash: "0xdf1bf8b6d679e406f43b57692a2dcbb450e38d5de72e5199d836b701d0a4306f", + productId: 18597, + country: "US", + }), + }) as Request>; + + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(200); + expect(await response.json()).toEqual(orderCard18597); + }); + + it("should return err with uusd for unsupported chain", async () => { + await initMocks(receiptUusd, minedTxUusd); + const request = new Request(`${TESTS_BASE_URL}/post-order`, { + method: "POST", + body: JSON.stringify({ + type: uusd, + chainId: 25, + txHash: "0xdf1bf8b6d679e406f43b57692a2dcbb450e38d5de72e5199d836b701d0a4306f", + productId: 18597, + country: "US", + }), + }) as Request>; + + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(403); + expect(await response.json()).toEqual({ message: "Unsupported chain" }); + }); + + it("should return err with uusd for wrong method call", async () => { + await initMocks(receiptUusd, minedTxUusd, parsedTxUusdWrongMethod); + const request = new Request(`${TESTS_BASE_URL}/post-order`, { + method: "POST", + body: JSON.stringify({ + type: uusd, + chainId: 31337, + txHash: "0xdf1bf8b6d679e406f43b57692a2dcbb450e38d5de72e5199d836b701d0a4306f", + productId: 18597, + country: "US", + }), + }) as Request>; + + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(403); + expect(await response.json()).toEqual({ message: "Given transaction is not a token transfer" }); + }); + + it("should return err with uusd for wrong treasury", async () => { + await initMocks(receiptUusd, minedTxUusd, parsedTxUusdWrongTreasury); + const request = new Request(`${TESTS_BASE_URL}/post-order`, { + method: "POST", + body: JSON.stringify({ + type: uusd, + chainId: 31337, + txHash: "0xdf1bf8b6d679e406f43b57692a2dcbb450e38d5de72e5199d836b701d0a4306f", + productId: 18597, + country: "US", + }), + }) as Request>; + + const eventCtx = createEventContext(request, execContext); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(403); + expect(await response.json()).toEqual({ message: "Given transaction is not a token transfer to treasury address" }); + }); + + it("should post order on sandbox with uusd", async () => { + await initMocks(receiptUusd, minedTxUusd); + const request = new Request(`${TESTS_BASE_URL}/post-order`, { + method: "POST", + body: JSON.stringify({ + type: uusd, + chainId: 31337, + txHash: "0xdf1bf8b6d679e406f43b57692a2dcbb450e38d5de72e5199d836b701d0a4306f", + productId: 13959, + country: "US", + }), + }) as Request>; + + const eventCtx = createEventContext(request, execContext, true); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(200); + expect(await response.json()).toEqual(orderCard13959); + }); + + it("should post order on sandbox", async () => { + await initMocks(); + const request = new Request(`${TESTS_BASE_URL}/post-order`, { + method: "POST", + body: JSON.stringify({ + type: "permit", + chainId: 31337, + txHash: "0xac3485ce523faa13970412a89ef42d10939b44abd33cbcff1ed84cb566a3a3d5", + productId: 13959, + country: "US", + }), + }) as Request>; + + const eventCtx = createEventContext(request, execContext, true); + const response = await pagesFunction(eventCtx); + await waitOnExecutionContext(execContext); + expect(response.status).toBe(200); + expect(await response.json()).toEqual(orderCard13959); + }); +}); + +async function initMocks(receipt: object = receiptGeneric, minedTx: object = minedTxGeneric, parsedTx?: object) { + const helpers = await import("../../shared/helpers"); + vi.spyOn(helpers, "getFastestRpcUrl").mockImplementation(async () => { + return "http://127.0.0.1:8545"; + }); + + const providers = await import("@ethersproject/providers"); + vi.spyOn(providers.JsonRpcProvider.prototype, "getTransactionReceipt").mockImplementationOnce(async () => { + return receipt as TransactionReceipt; + }); + vi.spyOn(providers.JsonRpcProvider.prototype, "getTransaction").mockImplementationOnce(async () => { + return minedTx as TransactionResponse; + }); + + if (parsedTx) { + const { Interface } = await import("@ethersproject/abi"); + vi.spyOn(Interface.prototype, "parseTransaction").mockImplementationOnce(() => { + return parsedTx as TransactionDescription; + }); + } +} diff --git a/tests/unit/shared-utils.ts b/tests/unit/shared-utils.ts new file mode 100644 index 00000000..10cc53af --- /dev/null +++ b/tests/unit/shared-utils.ts @@ -0,0 +1,25 @@ +import { env } from "cloudflare:test"; +import { Context } from "../../functions/utils/types"; + +export const TESTS_BASE_URL = "https://localhost"; + +export function createEventContext(request: Request, execContext: ExecutionContext, isSandbox: boolean = false) { + const eventCtx: EventContext> = { + request: request as Request>, + functionPath: "", + waitUntil: execContext.waitUntil.bind(execContext), + passThroughOnException: execContext.passThroughOnException.bind(execContext), + async next() { + return new Response(); + }, + env: { + ...Object.assign({}, env, { USE_RELOADLY_SANDBOX: isSandbox ? "true" : "false" }), + ASSETS: { + fetch, + }, + }, + params: {}, + data: {}, + }; + return eventCtx as Context; +} diff --git a/tests/wrangler-vitest.toml b/tests/wrangler-vitest.toml new file mode 100644 index 00000000..b2ad050f --- /dev/null +++ b/tests/wrangler-vitest.toml @@ -0,0 +1,12 @@ +# This wrangler config is only used in vitest unit tests + +compatibility_flags = [ "nodejs_compat" ] +compatibility_date = "2024-04-05" + +[vars] +USE_RELOADLY_SANDBOX = "true" + +# CAUTION: use dummy credentials for unit tests +# using real credentials may cause tests to place real orders +RELOADLY_API_CLIENT_ID = "foo" +RELOADLY_API_CLIENT_SECRET = "bar" \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 126e1f63..5ae7e435 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,16 @@ { - "include": ["functions", "build", "scripts/typescript", "globals.d.ts", "cypress/**/*.ts", "cypress.config.ts", "static/**/*.ts", ".github/**/*.ts"], + "include": [ + "functions", + "build", + "tests", + "scripts/typescript", + "globals.d.ts", + "cypress/**/*.ts", + "cypress.config.ts", + "static/**/*.ts", + ".github/**/*.ts", + "vitest.config.ts" + ], "compilerOptions": { /* Visit https://aka.ms/tsconfig to read more about this file */ diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 00000000..4ecfa562 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,17 @@ +import { defineWorkersConfig } from "@cloudflare/vitest-pool-workers/config"; + +export default defineWorkersConfig({ + resolve: { + // To deal with "Error: No known conditions for "./node" specifier in "msw" package" + // From https://github.com/solidjs/vite-plugin-solid/issues/125 + alias: [{ find: "msw/node", replacement: "/node_modules/msw/lib/native/index.mjs" }], + }, + test: { + dir: "tests/unit", + poolOptions: { + workers: { + wrangler: { configPath: "./tests/wrangler-vitest.toml" }, + }, + }, + }, +}); diff --git a/yarn.lock b/yarn.lock index cb86e89c..b796b686 100644 --- a/yarn.lock +++ b/yarn.lock @@ -45,7 +45,7 @@ resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== -"@ampproject/remapping@^2.2.0": +"@ampproject/remapping@^2.2.0", "@ampproject/remapping@^2.3.0": version "2.3.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== @@ -334,6 +334,28 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@bundled-es-modules/cookie@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz#c3b82703969a61cf6a46e959a012b2c257f6b164" + integrity sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw== + dependencies: + cookie "^0.5.0" + +"@bundled-es-modules/statuses@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz#761d10f44e51a94902c4da48675b71a76cc98872" + integrity sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg== + dependencies: + statuses "^2.0.1" + +"@bundled-es-modules/tough-cookie@^0.1.6": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz#fa9cd3cedfeecd6783e8b0d378b4a99e52bde5d3" + integrity sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw== + dependencies: + "@types/tough-cookie" "^4.0.5" + tough-cookie "^4.1.4" + "@cloudflare/kv-asset-handler@0.3.4": version "0.3.4" resolved "https://registry.yarnpkg.com/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.3.4.tgz#5cc152847c8ae4d280ec5d7f4f6ba8c976b585c3" @@ -341,31 +363,70 @@ dependencies: mime "^3.0.0" +"@cloudflare/vitest-pool-workers@^0.5.22": + version "0.5.22" + resolved "https://registry.yarnpkg.com/@cloudflare/vitest-pool-workers/-/vitest-pool-workers-0.5.22.tgz#de0b7af71a542c0b6ca6090251cedcb758c87a7d" + integrity sha512-Zynt47hQbITDGDVjuI11/NlLuKCByooIVKbCPG0kIu3C4Wr1QcNmzZyhGVxVWKjQDRjXDgbqVN605G+SXy8twg== + dependencies: + birpc "0.2.14" + cjs-module-lexer "^1.2.3" + devalue "^4.3.0" + esbuild "0.17.19" + miniflare "3.20241022.0" + semver "^7.5.1" + wrangler "3.83.0" + zod "^3.22.3" + "@cloudflare/workerd-darwin-64@1.20241011.1": version "1.20241011.1" resolved "https://registry.yarnpkg.com/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20241011.1.tgz#044845a13492e409a8b49394d9ecd4d49520f94f" integrity sha512-gZ2PrMCQ4WdDCB+V6vsB2U2SyYcmgaGMEa3GGjcUfC79L/8so3Vp/bO0eCoLmvttRs39wascZ+JiWL0HpcZUgA== +"@cloudflare/workerd-darwin-64@1.20241022.0": + version "1.20241022.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20241022.0.tgz#1d22149152ad32672971e3be48ab1491ff236eb3" + integrity sha512-1NNYun37myMTgCUiPQEJ0cMal4mKZVTpkD0b2tx9hV70xji+frVJcSK8YVLeUm1P+Rw1d/ct8DMgQuCpsz3Fsw== + "@cloudflare/workerd-darwin-arm64@1.20241011.1": version "1.20241011.1" resolved "https://registry.yarnpkg.com/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20241011.1.tgz#76750e046df9e2fca3f223ff0e3920766973c436" integrity sha512-c26TYtS0e3WZ09nL/a8YaEqveCsTlgDm12ehPMNua9u68sh1KzETMl2G45O934m8UrI3Rhpv2TTecO0S5b9exA== +"@cloudflare/workerd-darwin-arm64@1.20241022.0": + version "1.20241022.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20241022.0.tgz#6ec4e4fd1427ac09d9cfea38db849799755029e5" + integrity sha512-FOO/0P0U82EsTLTdweNVgw+4VOk5nghExLPLSppdOziq6IR5HVgP44Kmq5LdsUeHUhwUmfOh9hzaTpkNzUqKvw== + "@cloudflare/workerd-linux-64@1.20241011.1": version "1.20241011.1" resolved "https://registry.yarnpkg.com/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20241011.1.tgz#c2369ccbf78f362bef89cbee148d573ac47712ed" integrity sha512-pl4xvHNXnm3cYh5GwHadOTQRWt4Ih/gzCOb6RW4n78oNQQydFvpwqYAjbYk32y485feLhdTKXut/MgZAyWnKyQ== +"@cloudflare/workerd-linux-64@1.20241022.0": + version "1.20241022.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20241022.0.tgz#0297222e46ce8b2c55b591ae87ee2bbb85830e20" + integrity sha512-RsNc19BQJG9yd+ngnjuDeG9ywZG+7t1L4JeglgceyY5ViMNMKVO7Zpbsu69kXslU9h6xyQG+lrmclg3cBpnhYA== + "@cloudflare/workerd-linux-arm64@1.20241011.1": version "1.20241011.1" resolved "https://registry.yarnpkg.com/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20241011.1.tgz#5041be32b98e32e53883110b0d8f92bbf40e341a" integrity sha512-I4HAF2Qe8xgIjAdE53viT2fDdHXkrb3Be0L3eWeeP5SEkOtQ4cHLqsOV7yhUWOJpHiI1XCDcf+wdfn0PB/EngQ== +"@cloudflare/workerd-linux-arm64@1.20241022.0": + version "1.20241022.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20241022.0.tgz#7637092b14129c94ddb87990221d38623e4fd498" + integrity sha512-x5mUXpKxfsosxcFmcq5DaqLs37PejHYVRsNz1cWI59ma7aC4y4Qn6Tf3i0r9MwQTF/MccP4SjVslMU6m4W7IaA== + "@cloudflare/workerd-windows-64@1.20241011.1": version "1.20241011.1" resolved "https://registry.yarnpkg.com/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20241011.1.tgz#1d900eb644bd0289117238693d7a0cda1aebcff1" integrity sha512-oVr1Cb7NkDpukd7v68FdxOH8vaHRSzHkX9uE/IttHd2yPK6mwOS220nIxK9UMcx5CwZmrgphRwtZwSYVk/lREQ== +"@cloudflare/workerd-windows-64@1.20241022.0": + version "1.20241022.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20241022.0.tgz#64f05a2bc475e1450154942c060555184e6350de" + integrity sha512-eBCClx4szCOgKqOlxxbdNszMqQf3MRG1B9BRIqEM/diDfdR9IrZ8l3FaEm+l9gXgPmS6m1NBn40aWuGBl8UTSw== + "@cloudflare/workers-shared@0.6.0": version "0.6.0" resolved "https://registry.yarnpkg.com/@cloudflare/workers-shared/-/workers-shared-0.6.0.tgz#154ed3d496b7276ca9ba8a886437991273a24ee0" @@ -374,6 +435,14 @@ mime "^3.0.0" zod "^3.22.3" +"@cloudflare/workers-shared@0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workers-shared/-/workers-shared-0.7.0.tgz#ecb6a3a1f483989c1ca10d5ed0592d01c7eff0c0" + integrity sha512-LLQRTqx7lKC7o2eCYMpyc5FXV8d0pUX6r3A+agzhqS9aoR5A6zCPefwQGcvbKx83ozX22ATZcemwxQXn12UofQ== + dependencies: + mime "^3.0.0" + zod "^3.22.3" + "@cloudflare/workers-types@^4.20240423.0": version "4.20241018.0" resolved "https://registry.yarnpkg.com/@cloudflare/workers-types/-/workers-types-4.20241018.0.tgz#b37efff883f7533d3719778e2d1d99aa9e47b8b6" @@ -991,6 +1060,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537" integrity sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g== +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== + "@esbuild/aix-ppc64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz#51299374de171dbd80bb7d838e1cfce9af36f353" @@ -1006,6 +1080,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz#db1c9202a5bc92ea04c7b6840f1bbe09ebf9e6b9" integrity sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg== +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== + "@esbuild/android-arm64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz#58565291a1fe548638adb9c584237449e5e14018" @@ -1021,6 +1100,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz#3b488c49aee9d491c2c8f98a909b785870d6e995" integrity sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w== +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== + "@esbuild/android-arm@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.23.1.tgz#5eb8c652d4c82a2421e3395b808e6d9c42c862ee" @@ -1036,6 +1120,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz#3b1628029e5576249d2b2d766696e50768449f98" integrity sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg== +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== + "@esbuild/android-x64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.23.1.tgz#ae19d665d2f06f0f48a6ac9a224b3f672e65d517" @@ -1051,6 +1140,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz#6e8517a045ddd86ae30c6608c8475ebc0c4000bb" integrity sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA== +"@esbuild/darwin-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" + integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== + "@esbuild/darwin-arm64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz#05b17f91a87e557b468a9c75e9d85ab10c121b16" @@ -1066,6 +1160,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz#90ed098e1f9dd8a9381695b207e1cff45540a0d0" integrity sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA== +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== + "@esbuild/darwin-x64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz#c58353b982f4e04f0d022284b8ba2733f5ff0931" @@ -1081,6 +1180,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz#d71502d1ee89a1130327e890364666c760a2a911" integrity sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw== +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== + "@esbuild/freebsd-arm64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz#f9220dc65f80f03635e1ef96cfad5da1f446f3bc" @@ -1096,6 +1200,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz#aa5ea58d9c1dd9af688b8b6f63ef0d3d60cea53c" integrity sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw== +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== + "@esbuild/freebsd-x64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz#69bd8511fa013b59f0226d1609ac43f7ce489730" @@ -1111,6 +1220,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz#055b63725df678379b0f6db9d0fa85463755b2e5" integrity sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A== +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== + "@esbuild/linux-arm64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz#8050af6d51ddb388c75653ef9871f5ccd8f12383" @@ -1126,6 +1240,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz#76b3b98cb1f87936fbc37f073efabad49dcd889c" integrity sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg== +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== + "@esbuild/linux-arm@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz#ecaabd1c23b701070484990db9a82f382f99e771" @@ -1141,6 +1260,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz#c0e5e787c285264e5dfc7a79f04b8b4eefdad7fa" integrity sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig== +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== + "@esbuild/linux-ia32@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz#3ed2273214178109741c09bd0687098a0243b333" @@ -1156,6 +1280,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz#a6184e62bd7cdc63e0c0448b83801001653219c5" integrity sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ== +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== + "@esbuild/linux-loong64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz#a0fdf440b5485c81b0fbb316b08933d217f5d3ac" @@ -1171,6 +1300,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz#d08e39ce86f45ef8fc88549d29c62b8acf5649aa" integrity sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA== +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== + "@esbuild/linux-mips64el@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz#e11a2806346db8375b18f5e104c5a9d4e81807f6" @@ -1186,6 +1320,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz#8d252f0b7756ffd6d1cbde5ea67ff8fd20437f20" integrity sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg== +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== + "@esbuild/linux-ppc64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz#06a2744c5eaf562b1a90937855b4d6cf7c75ec96" @@ -1201,6 +1340,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz#19f6dcdb14409dae607f66ca1181dd4e9db81300" integrity sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg== +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== + "@esbuild/linux-riscv64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz#65b46a2892fc0d1af4ba342af3fe0fa4a8fe08e7" @@ -1216,6 +1360,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz#3c830c90f1a5d7dd1473d5595ea4ebb920988685" integrity sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ== +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== + "@esbuild/linux-s390x@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz#e71ea18c70c3f604e241d16e4e5ab193a9785d6f" @@ -1231,6 +1380,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz#86eca35203afc0d9de0694c64ec0ab0a378f6fff" integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw== +"@esbuild/linux-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" + integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== + "@esbuild/linux-x64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz#d47f97391e80690d4dfe811a2e7d6927ad9eed24" @@ -1246,6 +1400,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz#e771c8eb0e0f6e1877ffd4220036b98aed5915e6" integrity sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ== +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== + "@esbuild/netbsd-x64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz#44e743c9778d57a8ace4b72f3c6b839a3b74a653" @@ -1266,6 +1425,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz#9a795ae4b4e37e674f0f4d716f3e226dd7c39baf" integrity sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ== +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== + "@esbuild/openbsd-x64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz#2e58ae511bacf67d19f9f2dcd9e8c5a93f00c273" @@ -1281,6 +1445,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz#7df23b61a497b8ac189def6e25a95673caedb03f" integrity sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w== +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== + "@esbuild/sunos-x64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz#adb022b959d18d3389ac70769cef5a03d3abd403" @@ -1296,6 +1465,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz#f1ae5abf9ca052ae11c1bc806fb4c0f519bacf90" integrity sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ== +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== + "@esbuild/win32-arm64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz#84906f50c212b72ec360f48461d43202f4c8b9a2" @@ -1311,6 +1485,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz#241fe62c34d8e8461cd708277813e1d0ba55ce23" integrity sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ== +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== + "@esbuild/win32-ia32@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz#5e3eacc515820ff729e90d0cb463183128e82fac" @@ -1326,6 +1505,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz#9c907b21e30a52db959ba4f80bb01a0cc403d5cc" integrity sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ== +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== + "@esbuild/win32-x64@0.23.1": version "0.23.1" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz#81fd50d11e2c32b2d6241470e3185b70c7b30699" @@ -1653,7 +1837,7 @@ "@ethersproject/rlp" "^5.7.0" "@ethersproject/signing-key" "^5.7.0" -"@ethersproject/units@5.7.0": +"@ethersproject/units@5.7.0", "@ethersproject/units@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.7.0.tgz#637b563d7e14f42deeee39245275d477aae1d8b1" integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg== @@ -1729,6 +1913,39 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== +"@inquirer/confirm@^5.0.0": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-5.0.1.tgz#35e0aa0f9fdaadee3acb1c42024e707af308fced" + integrity sha512-6ycMm7k7NUApiMGfVc32yIPp28iPKxhGRMqoNDiUjq2RyTAkbs5Fx0TdzBqhabcKvniDdAAvHCmsRjnNfTsogw== + dependencies: + "@inquirer/core" "^10.0.1" + "@inquirer/type" "^3.0.0" + +"@inquirer/core@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-10.0.1.tgz#22068da87d8f6317452172dfd521e811ccbcb90e" + integrity sha512-KKTgjViBQUi3AAssqjUFMnMO3CM3qwCHvePV9EW+zTKGKafFGFF01sc1yOIYjLJ7QU52G/FbzKc+c01WLzXmVQ== + dependencies: + "@inquirer/figures" "^1.0.7" + "@inquirer/type" "^3.0.0" + ansi-escapes "^4.3.2" + cli-width "^4.1.0" + mute-stream "^2.0.0" + signal-exit "^4.1.0" + strip-ansi "^6.0.1" + wrap-ansi "^6.2.0" + yoctocolors-cjs "^2.1.2" + +"@inquirer/figures@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.7.tgz#d050ccc0eabfacc0248c4ff647a9dfba1b01594b" + integrity sha512-m+Trk77mp54Zma6xLkLuY+mvanPxlE4A7yNKs2HBiyZ4UkVs28Mv5c/pgWrHeInx+USHeX/WEPzjrWrcJiQgjw== + +"@inquirer/type@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-3.0.0.tgz#1762ebe667ec1d838012b20bf0cf90b841ba68bc" + integrity sha512-YYykfbw/lefC7yKj7nanzQXILM7r3suIvyFlCcMskc99axmsSewXWkAfXKwMbgxL76iAFVmRwmYdwNZNc8gjog== + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -1956,7 +2173,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== @@ -1977,6 +2194,18 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@mswjs/interceptors@^0.36.5": + version "0.36.6" + resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.36.6.tgz#97560cca0d7f42c41d185ad404205fe14735cd30" + integrity sha512-issnYydStyH0wPEeU7CMwfO7kI668ffVtzKRMRS7H7BliOYuPuwEZxh9dwiXV+oeHBxT5SXT0wPwV8T7V2PJUA== + dependencies: + "@open-draft/deferred-promise" "^2.2.0" + "@open-draft/logger" "^0.3.0" + "@open-draft/until" "^2.0.0" + is-node-process "^1.2.0" + outvariant "^1.4.3" + strict-event-emitter "^0.5.1" + "@noble/curves@1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" @@ -2157,11 +2386,119 @@ "@octokit/request-error" "^6.0.1" "@octokit/webhooks-methods" "^5.0.0" +"@open-draft/deferred-promise@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz#4a822d10f6f0e316be4d67b4d4f8c9a124b073bd" + integrity sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA== + +"@open-draft/logger@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@open-draft/logger/-/logger-0.3.0.tgz#2b3ab1242b360aa0adb28b85f5d7da1c133a0954" + integrity sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ== + dependencies: + is-node-process "^1.2.0" + outvariant "^1.4.0" + +"@open-draft/until@^2.0.0", "@open-draft/until@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@open-draft/until/-/until-2.1.0.tgz#0acf32f470af2ceaf47f095cdecd40d68666efda" + integrity sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg== + "@pkgr/core@^0.1.0": version "0.1.1" resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== +"@rollup/rollup-android-arm-eabi@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.2.tgz#07db37fcd9d401aae165f662c0069efd61d4ffcc" + integrity sha512-ufoveNTKDg9t/b7nqI3lwbCG/9IJMhADBNjjz/Jn6LxIZxD7T5L8l2uO/wD99945F1Oo8FvgbbZJRguyk/BdzA== + +"@rollup/rollup-android-arm64@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.2.tgz#160975402adf85ecd58a0721ad60ae1779a68147" + integrity sha512-iZoYCiJz3Uek4NI0J06/ZxUgwAfNzqltK0MptPDO4OR0a88R4h0DSELMsflS6ibMCJ4PnLvq8f7O1d7WexUvIA== + +"@rollup/rollup-darwin-arm64@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.2.tgz#2b126f0aa4349694fe2941bcbcc4b0982b7f1a49" + integrity sha512-/UhrIxobHYCBfhi5paTkUDQ0w+jckjRZDZ1kcBL132WeHZQ6+S5v9jQPVGLVrLbNUebdIRpIt00lQ+4Z7ys4Rg== + +"@rollup/rollup-darwin-x64@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.2.tgz#3f4987eff6195532037c50b8db92736e326b5bb2" + integrity sha512-1F/jrfhxJtWILusgx63WeTvGTwE4vmsT9+e/z7cZLKU8sBMddwqw3UV5ERfOV+H1FuRK3YREZ46J4Gy0aP3qDA== + +"@rollup/rollup-freebsd-arm64@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.2.tgz#15fe184ecfafc635879500f6985c954e57697c44" + integrity sha512-1YWOpFcGuC6iGAS4EI+o3BV2/6S0H+m9kFOIlyFtp4xIX5rjSnL3AwbTBxROX0c8yWtiWM7ZI6mEPTI7VkSpZw== + +"@rollup/rollup-freebsd-x64@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.2.tgz#c72d37315d36b6e0763b7aabb6ae53c361b45e05" + integrity sha512-3qAqTewYrCdnOD9Gl9yvPoAoFAVmPJsBvleabvx4bnu1Kt6DrB2OALeRVag7BdWGWLhP1yooeMLEi6r2nYSOjg== + +"@rollup/rollup-linux-arm-gnueabihf@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.2.tgz#f274f81abf845dcca5f1f40d434a09a79a3a73a0" + integrity sha512-ArdGtPHjLqWkqQuoVQ6a5UC5ebdX8INPuJuJNWRe0RGa/YNhVvxeWmCTFQ7LdmNCSUzVZzxAvUznKaYx645Rig== + +"@rollup/rollup-linux-arm-musleabihf@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.2.tgz#9edaeb1a9fa7d4469917cb0614f665f1cf050625" + integrity sha512-B6UHHeNnnih8xH6wRKB0mOcJGvjZTww1FV59HqJoTJ5da9LCG6R4SEBt6uPqzlawv1LoEXSS0d4fBlHNWl6iYw== + +"@rollup/rollup-linux-arm64-gnu@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.2.tgz#6eb6851f594336bfa00f074f58a00a61e9751493" + integrity sha512-kr3gqzczJjSAncwOS6i7fpb4dlqcvLidqrX5hpGBIM1wtt0QEVtf4wFaAwVv8QygFU8iWUMYEoJZWuWxyua4GQ== + +"@rollup/rollup-linux-arm64-musl@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.2.tgz#9d8dc8e80df8f156d2888ecb8d6c96d653580731" + integrity sha512-TDdHLKCWgPuq9vQcmyLrhg/bgbOvIQ8rtWQK7MRxJ9nvaxKx38NvY7/Lo6cYuEnNHqf6rMqnivOIPIQt6H2AoA== + +"@rollup/rollup-linux-powerpc64le-gnu@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.2.tgz#358e3e7dda2d60c46ff7c74f7075045736df5b50" + integrity sha512-xv9vS648T3X4AxFFZGWeB5Dou8ilsv4VVqJ0+loOIgDO20zIhYfDLkk5xoQiej2RiSQkld9ijF/fhLeonrz2mw== + +"@rollup/rollup-linux-riscv64-gnu@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.2.tgz#b08461ace599c3f0b5f27051f1756b6cf1c78259" + integrity sha512-tbtXwnofRoTt223WUZYiUnbxhGAOVul/3StZ947U4A5NNjnQJV5irKMm76G0LGItWs6y+SCjUn/Q0WaMLkEskg== + +"@rollup/rollup-linux-s390x-gnu@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.2.tgz#daab36c9b5c8ac4bfe5a9c4c39ad711464b7dfee" + integrity sha512-gc97UebApwdsSNT3q79glOSPdfwgwj5ELuiyuiMY3pEWMxeVqLGKfpDFoum4ujivzxn6veUPzkGuSYoh5deQ2Q== + +"@rollup/rollup-linux-x64-gnu@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.2.tgz#4cc3a4f31920bdb028dbfd7ce0e972a17424a63c" + integrity sha512-jOG/0nXb3z+EM6SioY8RofqqmZ+9NKYvJ6QQaa9Mvd3RQxlH68/jcB/lpyVt4lCiqr04IyaC34NzhUqcXbB5FQ== + +"@rollup/rollup-linux-x64-musl@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.2.tgz#59800e26c538517ee05f4645315d9e1aded93200" + integrity sha512-XAo7cJec80NWx9LlZFEJQxqKOMz/lX3geWs2iNT5CHIERLFfd90f3RYLLjiCBm1IMaQ4VOX/lTC9lWfzzQm14Q== + +"@rollup/rollup-win32-arm64-msvc@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.2.tgz#c80e2c33c952b6b171fa6ad9a97dfbb2e4ebee44" + integrity sha512-A+JAs4+EhsTjnPQvo9XY/DC0ztaws3vfqzrMNMKlwQXuniBKOIIvAAI8M0fBYiTCxQnElYu7mLk7JrhlQ+HeOw== + +"@rollup/rollup-win32-ia32-msvc@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.2.tgz#a1e9d275cb16f6d5feb9c20aee7e897b1e193359" + integrity sha512-ZhcrakbqA1SCiJRMKSU64AZcYzlZ/9M5LaYil9QWxx9vLnkQ9Vnkve17Qn4SjlipqIIBFKjBES6Zxhnvh0EAEw== + +"@rollup/rollup-win32-x64-msvc@4.24.2": + version "4.24.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.2.tgz#0610af0fb8fec52be779d5b163bbbd6930150467" + integrity sha512-2mLH46K1u3r6uwc95hU+OR9q/ggYMpnS7pSp83Ece1HUQgF9Nh/QwTK5rcgbFnV9j+08yBrU5sA/P0RK2MSBNA== + "@sinclair/typebox@^0.27.8": version "0.27.8" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" @@ -2335,6 +2672,16 @@ dependencies: "@babel/types" "^7.20.7" +"@types/cookie@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.6.0.tgz#eac397f28bf1d6ae0ae081363eca2f425bedf0d5" + integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA== + +"@types/estree@1.0.6", "@types/estree@^1.0.0": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== + "@types/graceful-fs@^4.1.3": version "4.1.9" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" @@ -2417,6 +2764,16 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== +"@types/statuses@^2.0.4": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/statuses/-/statuses-2.0.5.tgz#f61ab46d5352fd73c863a1ea4e1cef3b0b51ae63" + integrity sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A== + +"@types/tough-cookie@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304" + integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA== + "@types/ws@^8.5.10": version "8.5.12" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.12.tgz#619475fe98f35ccca2a2f6c137702d85ec247b7e" @@ -2563,6 +2920,64 @@ ethers "^5.7.0" tiny-invariant "^1.1.0" +"@vitest/expect@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-2.0.5.tgz#f3745a6a2c18acbea4d39f5935e913f40d26fa86" + integrity sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA== + dependencies: + "@vitest/spy" "2.0.5" + "@vitest/utils" "2.0.5" + chai "^5.1.1" + tinyrainbow "^1.2.0" + +"@vitest/pretty-format@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.0.5.tgz#91d2e6d3a7235c742e1a6cc50e7786e2f2979b1e" + integrity sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ== + dependencies: + tinyrainbow "^1.2.0" + +"@vitest/pretty-format@^2.0.5": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.1.3.tgz#48b9b03de75507d1d493df7beb48dc39a1946a3e" + integrity sha512-XH1XdtoLZCpqV59KRbPrIhFCOO0hErxrQCMcvnQete3Vibb9UeIOX02uFPfVn3Z9ZXsq78etlfyhnkmIZSzIwQ== + dependencies: + tinyrainbow "^1.2.0" + +"@vitest/runner@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-2.0.5.tgz#89197e712bb93513537d6876995a4843392b2a84" + integrity sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig== + dependencies: + "@vitest/utils" "2.0.5" + pathe "^1.1.2" + +"@vitest/snapshot@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-2.0.5.tgz#a2346bc5013b73c44670c277c430e0334690a162" + integrity sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew== + dependencies: + "@vitest/pretty-format" "2.0.5" + magic-string "^0.30.10" + pathe "^1.1.2" + +"@vitest/spy@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-2.0.5.tgz#590fc07df84a78b8e9dd976ec2090920084a2b9f" + integrity sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA== + dependencies: + tinyspy "^3.0.0" + +"@vitest/utils@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.0.5.tgz#6f8307a4b6bc6ceb9270007f73c67c915944e926" + integrity sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ== + dependencies: + "@vitest/pretty-format" "2.0.5" + estree-walker "^3.0.3" + loupe "^3.1.1" + tinyrainbow "^1.2.0" + JSONStream@^1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" @@ -2631,7 +3046,7 @@ ansi-colors@^4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== -ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: +ansi-escapes@^4.2.1, ansi-escapes@^4.3.0, ansi-escapes@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -2765,6 +3180,11 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== +assertion-error@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7" + integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA== + astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" @@ -2911,6 +3331,11 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== +birpc@0.2.14: + version "0.2.14" + resolved "https://registry.yarnpkg.com/birpc/-/birpc-0.2.14.tgz#4a5498771e6ff24cf8ae5f47faf90e76ca2fce03" + integrity sha512-37FHE8rqsYM5JEKCnXFyHpBCzvgHEExwVVTq+nUmloInU7l8ezD1TpOhKpS8oe1DTYFqEK27rFZVKG43oTqXRA== + blake3-wasm@^2.1.5: version "2.1.5" resolved "https://registry.yarnpkg.com/blake3-wasm/-/blake3-wasm-2.1.5.tgz#b22dbb84bc9419ed0159caa76af4b1b132e6ba52" @@ -3005,6 +3430,11 @@ buffer@^5.7.1: base64-js "^1.3.1" ieee754 "^1.1.13" +cac@^6.7.14: + version "6.7.14" + resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" + integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== + cachedir@^2.3.0: version "2.4.0" resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.4.0.tgz#7fef9cf7367233d7c88068fe6e34ed0d355a610d" @@ -3063,6 +3493,17 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== +chai@^5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/chai/-/chai-5.1.2.tgz#3afbc340b994ae3610ca519a6c70ace77ad4378d" + integrity sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw== + dependencies: + assertion-error "^2.0.1" + check-error "^2.1.1" + deep-eql "^5.0.1" + loupe "^3.1.0" + pathval "^2.0.0" + chalk-template@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/chalk-template/-/chalk-template-1.1.0.tgz#ffc55db6dd745e9394b85327c8ac8466edb7a7b1" @@ -3079,7 +3520,7 @@ chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.0: +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -3097,6 +3538,11 @@ char-regex@^1.0.2: resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== +check-error@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc" + integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== + check-more-types@^2.24.0: version "2.24.0" resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" @@ -3122,7 +3568,7 @@ ci-info@^3.2.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== -cjs-module-lexer@^1.0.0: +cjs-module-lexer@^1.0.0, cjs-module-lexer@^1.2.3: version "1.4.1" resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz#707413784dbb3a72aa11c2f2b042a0bef4004170" integrity sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA== @@ -3184,6 +3630,11 @@ cli-truncate@^4.0.0: slice-ansi "^5.0.0" string-width "^7.0.0" +cli-width@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" + integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== + cliui@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" @@ -3317,6 +3768,11 @@ convert-source-map@^2.0.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== +cookie@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + cookie@^0.7.1: version "0.7.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" @@ -3605,6 +4061,11 @@ data-view-byte-offset@^1.0.0: es-errors "^1.3.0" is-data-view "^1.0.1" +date-fns@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-4.1.0.tgz#64b3d83fff5aa80438f5b1a633c2e83b8a1c2d14" + integrity sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg== + dayjs@^1.10.4: version "1.11.13" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c" @@ -3617,7 +4078,7 @@ debug@^3.1.0: dependencies: ms "^2.1.1" -debug@^4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.6: +debug@^4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@~4.3.6: version "4.3.7" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== @@ -3649,6 +4110,11 @@ dedent@^1.0.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a" integrity sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ== +deep-eql@^5.0.1: + version "5.0.2" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-5.0.2.tgz#4b756d8d770a9257300825d52a2c2cff99c3a341" + integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q== + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -3704,6 +4170,11 @@ detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== +devalue@^4.3.0: + version "4.3.3" + resolved "https://registry.yarnpkg.com/devalue/-/devalue-4.3.3.tgz#e35df3bdc49136837e77986f629b9fa6fef50726" + integrity sha512-UH8EL6H2ifcY8TbD2QsxwCC/pr5xSwPvv85LrLXVihmHVC3T3YqTCIwnR5ak0yO1KYqlxrPVOA/JVZJYPy2ATg== + diff-sequences@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" @@ -3976,6 +4447,35 @@ esbuild@^0.20.1: "@esbuild/win32-ia32" "0.20.2" "@esbuild/win32-x64" "0.20.2" +esbuild@^0.21.3: + version "0.21.5" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" + integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== + optionalDependencies: + "@esbuild/aix-ppc64" "0.21.5" + "@esbuild/android-arm" "0.21.5" + "@esbuild/android-arm64" "0.21.5" + "@esbuild/android-x64" "0.21.5" + "@esbuild/darwin-arm64" "0.21.5" + "@esbuild/darwin-x64" "0.21.5" + "@esbuild/freebsd-arm64" "0.21.5" + "@esbuild/freebsd-x64" "0.21.5" + "@esbuild/linux-arm" "0.21.5" + "@esbuild/linux-arm64" "0.21.5" + "@esbuild/linux-ia32" "0.21.5" + "@esbuild/linux-loong64" "0.21.5" + "@esbuild/linux-mips64el" "0.21.5" + "@esbuild/linux-ppc64" "0.21.5" + "@esbuild/linux-riscv64" "0.21.5" + "@esbuild/linux-s390x" "0.21.5" + "@esbuild/linux-x64" "0.21.5" + "@esbuild/netbsd-x64" "0.21.5" + "@esbuild/openbsd-x64" "0.21.5" + "@esbuild/sunos-x64" "0.21.5" + "@esbuild/win32-arm64" "0.21.5" + "@esbuild/win32-ia32" "0.21.5" + "@esbuild/win32-x64" "0.21.5" + esbuild@~0.23.0: version "0.23.1" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.23.1.tgz#40fdc3f9265ec0beae6f59824ade1bd3d3d2dab8" @@ -4144,6 +4644,13 @@ estree-walker@^0.6.1: resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== +estree-walker@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" + integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== + dependencies: + "@types/estree" "^1.0.0" + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -4243,7 +4750,7 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -execa@~8.0.1: +execa@^8.0.1, execa@~8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/execa/-/execa-8.0.1.tgz#51f6a5943b580f963c3ca9c6321796db8cc39b8c" integrity sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg== @@ -4739,6 +5246,11 @@ graphemer@^1.4.0: resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== +graphql@^16.8.1: + version "16.9.0" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.9.0.tgz#1c310e63f16a49ce1fbb230bd0a000e99f6f115f" + integrity sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw== + hard-rejection@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" @@ -4803,6 +5315,11 @@ hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: dependencies: function-bind "^1.1.2" +headers-polyfill@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/headers-polyfill/-/headers-polyfill-4.0.3.tgz#922a0155de30ecc1f785bcf04be77844ca95ad07" + integrity sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ== + hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -5056,6 +5573,11 @@ is-negative-zero@^2.0.3: resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== +is-node-process@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-node-process/-/is-node-process-1.2.0.tgz#ea02a1b90ddb3934a19aea414e88edef7e11d134" + integrity sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw== + is-number-object@^1.0.4: version "1.0.7" resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" @@ -5238,6 +5760,11 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +itty-time@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/itty-time/-/itty-time-1.0.6.tgz#a6eeda619f19d2f4c480ceddd013b93acb05714d" + integrity sha512-+P8IZaLLBtFv8hCkIjcymZOp4UJ+xW6bSlQsXGqrkmJh7vSiMFSlNne0mCYagEE0N7HDNR5jJBRxwN0oYv61Rw== + jest-changed-files@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" @@ -5966,6 +6493,11 @@ log-update@^6.1.0: strip-ansi "^7.1.0" wrap-ansi "^9.0.0" +loupe@^3.1.0, loupe@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.1.2.tgz#c86e0696804a02218f2206124c45d8b15291a240" + integrity sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -5987,6 +6519,13 @@ magic-string@^0.25.3: dependencies: sourcemap-codec "^1.4.8" +magic-string@^0.30.10: + version "0.30.12" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.12.tgz#9eb11c9d072b9bcb4940a5b2c2e1a217e4ee1a60" + integrity sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + make-dir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" @@ -6121,6 +6660,24 @@ miniflare@3.20241011.0: youch "^3.2.2" zod "^3.22.3" +miniflare@3.20241022.0: + version "3.20241022.0" + resolved "https://registry.yarnpkg.com/miniflare/-/miniflare-3.20241022.0.tgz#31b8a2bc53b411ac814b55db9c31aebfe475f344" + integrity sha512-x9Fbq1Hmz1f0osIT9Qmj78iX4UpCP2EqlZnA/tzj/3+I49vc3Kq0fNqSSKplcdf6HlCHdL3fOBicmreQF4BUUQ== + dependencies: + "@cspotcode/source-map-support" "0.8.1" + acorn "^8.8.0" + acorn-walk "^8.2.0" + capnp-ts "^0.7.0" + exit-hook "^2.2.1" + glob-to-regexp "^0.4.1" + stoppable "^1.1.0" + undici "^5.28.4" + workerd "1.20241022.0" + ws "^8.17.1" + youch "^3.2.2" + zod "^3.22.3" + minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -6176,12 +6733,40 @@ ms@^2.1.1, ms@^2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +msw@^2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/msw/-/msw-2.5.2.tgz#dfce10b68dbabc2d5dafeb6d7fb82c3c7073a4d1" + integrity sha512-eBsFgU30NYtrfC62XzS1rdAzFK+Br0zKU4ORqD9Qliq86362DWZyPiD6FLfMgy0Ktik83DPTXmqPMz2bqwmJdA== + dependencies: + "@bundled-es-modules/cookie" "^2.0.0" + "@bundled-es-modules/statuses" "^1.0.1" + "@bundled-es-modules/tough-cookie" "^0.1.6" + "@inquirer/confirm" "^5.0.0" + "@mswjs/interceptors" "^0.36.5" + "@open-draft/until" "^2.1.0" + "@types/cookie" "^0.6.0" + "@types/statuses" "^2.0.4" + chalk "^4.1.2" + graphql "^16.8.1" + headers-polyfill "^4.0.2" + is-node-process "^1.2.0" + outvariant "^1.4.3" + path-to-regexp "^6.3.0" + strict-event-emitter "^0.5.1" + type-fest "^4.26.1" + yargs "^17.7.2" + mustache@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64" integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ== -nanoid@^3.3.3: +mute-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-2.0.0.tgz#a5446fc0c512b71c83c44d908d5c7b7b4c493b2b" + integrity sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA== + +nanoid@^3.3.3, nanoid@^3.3.7: version "3.3.7" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== @@ -6365,6 +6950,11 @@ ospath@^1.2.2: resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b" integrity sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA== +outvariant@^1.4.0, outvariant@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/outvariant/-/outvariant-1.4.3.tgz#221c1bfc093e8fec7075497e7799fdbf43d14873" + integrity sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA== + p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -6499,6 +7089,11 @@ pathe@^1.1.2: resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec" integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== +pathval@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-2.0.0.tgz#7e2550b422601d4f6b8e26f1301bc8f15a741a25" + integrity sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA== + pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" @@ -6566,6 +7161,15 @@ possible-typed-array-names@^1.0.0: resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== +postcss@^8.4.43: + version "8.4.47" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365" + integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ== + dependencies: + nanoid "^3.3.7" + picocolors "^1.1.0" + source-map-js "^1.2.1" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -6875,6 +7479,33 @@ rollup-pluginutils@^2.8.1: dependencies: estree-walker "^0.6.1" +rollup@^4.20.0: + version "4.24.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.24.2.tgz#04bbe819c1a0cd933533b79687f5dc43efb7a7f0" + integrity sha512-do/DFGq5g6rdDhdpPq5qb2ecoczeK6y+2UAjdJ5trjQJj5f1AiVdLRWRc9A9/fFukfvJRgM0UXzxBIYMovm5ww== + dependencies: + "@types/estree" "1.0.6" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.24.2" + "@rollup/rollup-android-arm64" "4.24.2" + "@rollup/rollup-darwin-arm64" "4.24.2" + "@rollup/rollup-darwin-x64" "4.24.2" + "@rollup/rollup-freebsd-arm64" "4.24.2" + "@rollup/rollup-freebsd-x64" "4.24.2" + "@rollup/rollup-linux-arm-gnueabihf" "4.24.2" + "@rollup/rollup-linux-arm-musleabihf" "4.24.2" + "@rollup/rollup-linux-arm64-gnu" "4.24.2" + "@rollup/rollup-linux-arm64-musl" "4.24.2" + "@rollup/rollup-linux-powerpc64le-gnu" "4.24.2" + "@rollup/rollup-linux-riscv64-gnu" "4.24.2" + "@rollup/rollup-linux-s390x-gnu" "4.24.2" + "@rollup/rollup-linux-x64-gnu" "4.24.2" + "@rollup/rollup-linux-x64-musl" "4.24.2" + "@rollup/rollup-win32-arm64-msvc" "4.24.2" + "@rollup/rollup-win32-ia32-msvc" "4.24.2" + "@rollup/rollup-win32-x64-msvc" "4.24.2" + fsevents "~2.3.2" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -6948,7 +7579,7 @@ semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.4, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.3: +semver@^7.3.4, semver@^7.5.1, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.3: version "7.6.3" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== @@ -7022,6 +7653,11 @@ side-channel@^1.0.4, side-channel@^1.0.6: get-intrinsic "^1.2.4" object-inspect "^1.13.1" +siginfo@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/siginfo/-/siginfo-2.0.0.tgz#32e76c70b79724e3bb567cb9d543eb858ccfaf30" + integrity sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g== + signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" @@ -7102,6 +7738,11 @@ smol-toml@^1.3.0: resolved "https://registry.yarnpkg.com/smol-toml/-/smol-toml-1.3.0.tgz#5200e251fffadbb72570c84e9776d2a3eca48143" integrity sha512-tWpi2TsODPScmi48b/OQZGi2lgUmBCHy6SZrhi/FdnnHiU1GwebbCfuQuxsC3nHaLwtYeJGPrDZDIeodDOc4pA== +source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + source-map-support@0.5.13: version "0.5.13" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" @@ -7185,6 +7826,11 @@ stack-utils@^2.0.3: dependencies: escape-string-regexp "^2.0.0" +stackback@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/stackback/-/stackback-0.0.2.tgz#1ac8a0d9483848d1695e418b6d031a3c3ce68e3b" + integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw== + stacktracey@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/stacktracey/-/stacktracey-2.1.8.tgz#bf9916020738ce3700d1323b32bd2c91ea71199d" @@ -7193,11 +7839,26 @@ stacktracey@^2.1.8: as-table "^1.0.36" get-source "^2.0.12" +statuses@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +std-env@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.7.0.tgz#c9f7386ced6ecf13360b6c6c55b8aaa4ef7481d2" + integrity sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg== + stoppable@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/stoppable/-/stoppable-1.1.0.tgz#32da568e83ea488b08e4d7ea2c3bcc9d75015d5b" integrity sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw== +strict-event-emitter@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz#1602ece81c51574ca39c6815e09f1a3e8550bd93" + integrity sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ== + string-argv@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" @@ -7410,6 +8071,11 @@ tiny-invariant@^1.1.0: resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== +tinybench@^2.8.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.9.0.tgz#103c9f8ba6d7237a47ab6dd1dcff77251863426b" + integrity sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg== + tinyglobby@^0.2.9: version "0.2.9" resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.9.tgz#6baddd1b0fe416403efb0dd40442c7d7c03c1c66" @@ -7418,6 +8084,21 @@ tinyglobby@^0.2.9: fdir "^6.4.0" picomatch "^4.0.2" +tinypool@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-1.0.1.tgz#c64233c4fac4304e109a64340178760116dbe1fe" + integrity sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA== + +tinyrainbow@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-1.2.0.tgz#5c57d2fc0fb3d1afd78465c33ca885d04f02abb5" + integrity sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ== + +tinyspy@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.2.tgz#86dd3cf3d737b15adcf17d7887c84a75201df20a" + integrity sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q== + tmp@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" @@ -7445,7 +8126,7 @@ touch@^3.1.0: resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.1.tgz#097a23d7b161476435e5c1344a95c0f75b4a5694" integrity sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA== -tough-cookie@^4.1.3: +tough-cookie@^4.1.3, tough-cookie@^4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36" integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag== @@ -7558,6 +8239,11 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^4.26.1: + version "4.26.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.26.1.tgz#a4a17fa314f976dd3e6d6675ef6c775c16d7955e" + integrity sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg== + typed-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz#1867c5d83b20fcb5ccf32649e5e2fc7424474ff3" @@ -7649,6 +8335,16 @@ undici@^5.25.4, undici@^5.28.4: pathe "^1.1.2" ufo "^1.5.4" +"unenv@npm:unenv-nightly@2.0.0-20241018-011344-e666fcf": + version "2.0.0-20241018-011344-e666fcf" + resolved "https://registry.yarnpkg.com/unenv-nightly/-/unenv-nightly-2.0.0-20241018-011344-e666fcf.tgz#75b6d1ab37e6b5edeec80fe8f403e3de8e9bc50e" + integrity sha512-D00bYn8rzkCBOlLx+k1iHQlc69jvtJRT7Eek4yIGQ6461a2tUBjngGZdRpqsoXAJCz/qBW0NgPting7Zvg+ysg== + dependencies: + defu "^6.1.4" + ohash "^1.1.4" + pathe "^1.1.2" + ufo "^1.5.4" + universal-user-agent@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.1.tgz#15f20f55da3c930c57bddbf1734c6654d5fd35aa" @@ -7728,6 +8424,53 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +vite-node@2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-2.0.5.tgz#36d909188fc6e3aba3da5fc095b3637d0d18e27b" + integrity sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q== + dependencies: + cac "^6.7.14" + debug "^4.3.5" + pathe "^1.1.2" + tinyrainbow "^1.2.0" + vite "^5.0.0" + +vite@^5.0.0: + version "5.4.10" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.10.tgz#d358a7bd8beda6cf0f3b7a450a8c7693a4f80c18" + integrity sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ== + dependencies: + esbuild "^0.21.3" + postcss "^8.4.43" + rollup "^4.20.0" + optionalDependencies: + fsevents "~2.3.3" + +vitest@2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-2.0.5.tgz#2f15a532704a7181528e399cc5b754c7f335fd62" + integrity sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA== + dependencies: + "@ampproject/remapping" "^2.3.0" + "@vitest/expect" "2.0.5" + "@vitest/pretty-format" "^2.0.5" + "@vitest/runner" "2.0.5" + "@vitest/snapshot" "2.0.5" + "@vitest/spy" "2.0.5" + "@vitest/utils" "2.0.5" + chai "^5.1.1" + debug "^4.3.5" + execa "^8.0.1" + magic-string "^0.30.10" + pathe "^1.1.2" + std-env "^3.7.0" + tinybench "^2.8.0" + tinypool "^1.0.0" + tinyrainbow "^1.2.0" + vite "^5.0.0" + vite-node "2.0.5" + why-is-node-running "^2.3.0" + vscode-languageserver-textdocument@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz#457ee04271ab38998a093c68c2342f53f6e4a631" @@ -7806,6 +8549,14 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +why-is-node-running@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/why-is-node-running/-/why-is-node-running-2.3.0.tgz#a3f69a97107f494b3cdc3bdddd883a7d65cebf04" + integrity sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w== + dependencies: + siginfo "^2.0.0" + stackback "0.0.2" + word-wrap@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" @@ -7822,6 +8573,44 @@ workerd@1.20241011.1: "@cloudflare/workerd-linux-arm64" "1.20241011.1" "@cloudflare/workerd-windows-64" "1.20241011.1" +workerd@1.20241022.0: + version "1.20241022.0" + resolved "https://registry.yarnpkg.com/workerd/-/workerd-1.20241022.0.tgz#45ab10642009b4573ae78df784e0a8c5b338914e" + integrity sha512-jyGXsgO9DRcJyx6Ovv7gUyDPc3UYC2i/E0p9GFUg6GUzpldw4Y93y9kOmdfsOnKZ3+lY53veSiUniiBPE6Q2NQ== + optionalDependencies: + "@cloudflare/workerd-darwin-64" "1.20241022.0" + "@cloudflare/workerd-darwin-arm64" "1.20241022.0" + "@cloudflare/workerd-linux-64" "1.20241022.0" + "@cloudflare/workerd-linux-arm64" "1.20241022.0" + "@cloudflare/workerd-windows-64" "1.20241022.0" + +wrangler@3.83.0: + version "3.83.0" + resolved "https://registry.yarnpkg.com/wrangler/-/wrangler-3.83.0.tgz#bebe3d0067f3430cf6f0b2e8e4ab648c208e002b" + integrity sha512-qDzdUuTngKqmm2OJUZm7Gk4+Hv37F2nNNAHuhIgItEIhxBdOVDsgKmvpd+f41MFxyuGg3fbGWYANHI+0V2Z5yw== + dependencies: + "@cloudflare/kv-asset-handler" "0.3.4" + "@cloudflare/workers-shared" "0.7.0" + "@esbuild-plugins/node-globals-polyfill" "^0.2.3" + "@esbuild-plugins/node-modules-polyfill" "^0.2.2" + blake3-wasm "^2.1.5" + chokidar "^3.5.3" + date-fns "^4.1.0" + esbuild "0.17.19" + itty-time "^1.0.6" + miniflare "3.20241022.0" + nanoid "^3.3.3" + path-to-regexp "^6.3.0" + resolve "^1.22.8" + resolve.exports "^2.0.2" + selfsigned "^2.0.1" + source-map "^0.6.1" + unenv "npm:unenv-nightly@2.0.0-20241018-011344-e666fcf" + workerd "1.20241022.0" + xxhash-wasm "^1.0.1" + optionalDependencies: + fsevents "~2.3.2" + wrangler@^3.51.2: version "3.81.0" resolved "https://registry.yarnpkg.com/wrangler/-/wrangler-3.81.0.tgz#db3c92651e779516b9d794d1d3c59084125e888f" @@ -7952,7 +8741,7 @@ yargs-parser@^21.0.1, yargs-parser@^21.1.1: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== -yargs@^17.0.0, yargs@^17.3.1: +yargs@^17.0.0, yargs@^17.3.1, yargs@^17.7.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== @@ -7978,6 +8767,11 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +yoctocolors-cjs@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz#f4b905a840a37506813a7acaa28febe97767a242" + integrity sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA== + youch@^3.2.2: version "3.3.4" resolved "https://registry.yarnpkg.com/youch/-/youch-3.3.4.tgz#f13ee0966846c6200e7fb9ece89306d95df5e489"