From 686f8988bcca30946707c43e23699779b23c48c6 Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Sat, 26 Jul 2025 19:34:36 +0800 Subject: [PATCH] api: use node api endpoint for iap verifying (#1683) --- apps/readest-app/package.json | 8 +- .../public/locales/ar/translation.json | 3 +- .../public/locales/de/translation.json | 3 +- .../public/locales/el/translation.json | 3 +- .../public/locales/es/translation.json | 3 +- .../public/locales/fr/translation.json | 3 +- .../public/locales/hi/translation.json | 3 +- .../public/locales/id/translation.json | 3 +- .../public/locales/it/translation.json | 3 +- .../public/locales/ja/translation.json | 3 +- .../public/locales/ko/translation.json | 3 +- .../public/locales/nl/translation.json | 3 +- .../public/locales/pl/translation.json | 3 +- .../public/locales/pt/translation.json | 3 +- .../public/locales/ru/translation.json | 3 +- .../public/locales/th/translation.json | 3 +- .../public/locales/tr/translation.json | 3 +- .../public/locales/uk/translation.json | 3 +- .../public/locales/vi/translation.json | 3 +- .../public/locales/zh-CN/translation.json | 3 +- .../public/locales/zh-TW/translation.json | 3 +- .../__tests__/integration/apple-iap.test.ts | 4 +- .../src/app/api/apple/iap-verify/route.ts | 3 +- apps/readest-app/src/app/user/page.tsx | 24 +- .../app/user/subscription/success/page.tsx | 10 +- .../src/libs/iap/apple/verifier.ts | 26 +- apps/readest-app/src/services/constants.ts | 1 + apps/readest-app/src/services/environment.ts | 12 +- apps/readest-app/tsconfig.json | 2 +- pnpm-lock.yaml | 467 ++++++++++++------ 30 files changed, 428 insertions(+), 189 deletions(-) diff --git a/apps/readest-app/package.json b/apps/readest-app/package.json index 77dd44f3..c6696040 100644 --- a/apps/readest-app/package.json +++ b/apps/readest-app/package.json @@ -33,7 +33,7 @@ "release-ios-appstore": "dotenv -e .env.ios-appstore.local -- bash scripts/release-ios-appstore.sh", "release-google-play": "dotenv -e .env.google-play.local -- bash scripts/release-google-play.sh", "config-wrangler": "sed -i \"s/\\${TRANSLATIONS_KV_ID}/$TRANSLATIONS_KV_ID/g\" wrangler.toml", - "preview": "NEXT_PUBLIC_APP_PLATFORM=web opennextjs-cloudflare build && opennextjs-cloudflare preview", + "preview": "NEXT_PUBLIC_APP_PLATFORM=web opennextjs-cloudflare build && opennextjs-cloudflare preview --ip 0.0.0.0", "deploy": "NEXT_PUBLIC_APP_PLATFORM=web opennextjs-cloudflare build && opennextjs-cloudflare deploy", "upload": "NEXT_PUBLIC_APP_PLATFORM=web opennextjs-cloudflare build && opennextjs-cloudflare upload", "cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts", @@ -46,7 +46,7 @@ "@aws-sdk/s3-request-presigner": "^3.735.0", "@ducanh2912/next-pwa": "^10.2.9", "@fabianlars/tauri-plugin-oauth": "2", - "@opennextjs/cloudflare": "^1.3.1", + "@opennextjs/cloudflare": "^1.6.1", "@stripe/react-stripe-js": "^3.7.0", "@stripe/stripe-js": "^7.4.0", "@supabase/auth-ui-react": "^0.4.7", @@ -106,7 +106,7 @@ "@testing-library/react": "^16.3.0", "@types/cors": "^2.8.17", "@types/cssbeautify": "^0.3.5", - "@types/node": "^22.10.1", + "@types/node": "^22.15.31", "@types/react": "18.3.12", "@types/react-color": "^3.0.13", "@types/react-dom": "18.3.1", @@ -132,6 +132,6 @@ "typescript": "^5.7.2", "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.2.4", - "wrangler": "^4.21.0" + "wrangler": "^4.26.0" } } diff --git a/apps/readest-app/public/locales/ar/translation.json b/apps/readest-app/public/locales/ar/translation.json index 57fae79e..6373b542 100644 --- a/apps/readest-app/public/locales/ar/translation.json +++ b/apps/readest-app/public/locales/ar/translation.json @@ -474,5 +474,6 @@ "Failed to restore purchases.": "فشل في استعادة المشتريات.", "Failed to manage subscription.": "فشل في إدارة الاشتراك.", "Failed to load subscription plans.": "فشل في تحميل خطط الاشتراك.", - "year": "سنة" + "year": "سنة", + "Failed to create checkout session": "فشل في إنشاء جلسة الدفع" } diff --git a/apps/readest-app/public/locales/de/translation.json b/apps/readest-app/public/locales/de/translation.json index 83503b71..90ab342f 100644 --- a/apps/readest-app/public/locales/de/translation.json +++ b/apps/readest-app/public/locales/de/translation.json @@ -458,5 +458,6 @@ "Failed to restore purchases.": "Wiederherstellung der Käufe fehlgeschlagen.", "Failed to manage subscription.": "Verwaltung des Abonnements fehlgeschlagen.", "Failed to load subscription plans.": "Laden der Abonnementpläne fehlgeschlagen.", - "year": "Jahr" + "year": "Jahr", + "Failed to create checkout session": "Fehler beim Erstellen der Checkout-Sitzung" } diff --git a/apps/readest-app/public/locales/el/translation.json b/apps/readest-app/public/locales/el/translation.json index 08b748e3..cc54f305 100644 --- a/apps/readest-app/public/locales/el/translation.json +++ b/apps/readest-app/public/locales/el/translation.json @@ -458,5 +458,6 @@ "Failed to restore purchases.": "Αποτυχία επαναφοράς αγορών.", "Failed to manage subscription.": "Αποτυχία διαχείρισης συνδρομής.", "Failed to load subscription plans.": "Αποτυχία φόρτωσης σχεδίων συνδρομής.", - "year": "έτος" + "year": "έτος", + "Failed to create checkout session": "Αποτυχία δημιουργίας συνεδρίας πληρωμής" } diff --git a/apps/readest-app/public/locales/es/translation.json b/apps/readest-app/public/locales/es/translation.json index 4592bef4..4c61bba8 100644 --- a/apps/readest-app/public/locales/es/translation.json +++ b/apps/readest-app/public/locales/es/translation.json @@ -462,5 +462,6 @@ "Failed to restore purchases.": "Error al restaurar compras.", "Failed to manage subscription.": "Error al gestionar la suscripción.", "Failed to load subscription plans.": "Error al cargar los planes de suscripción.", - "year": "año" + "year": "año", + "Failed to create checkout session": "Error al crear la sesión de pago" } diff --git a/apps/readest-app/public/locales/fr/translation.json b/apps/readest-app/public/locales/fr/translation.json index 1a9ee080..1a845d64 100644 --- a/apps/readest-app/public/locales/fr/translation.json +++ b/apps/readest-app/public/locales/fr/translation.json @@ -462,5 +462,6 @@ "Failed to restore purchases.": "Échec de la restauration des achats.", "Failed to manage subscription.": "Échec de la gestion de l'abonnement.", "Failed to load subscription plans.": "Échec du chargement des plans d'abonnement.", - "year": "année" + "year": "année", + "Failed to create checkout session": "Échec de la création de la session de paiement" } diff --git a/apps/readest-app/public/locales/hi/translation.json b/apps/readest-app/public/locales/hi/translation.json index 2268e477..b1d78586 100644 --- a/apps/readest-app/public/locales/hi/translation.json +++ b/apps/readest-app/public/locales/hi/translation.json @@ -458,5 +458,6 @@ "Failed to restore purchases.": "खरीदारी पुनर्स्थापित करने में विफल।", "Failed to manage subscription.": "सदस्यता प्रबंधित करने में विफल।", "Failed to load subscription plans.": "सदस्यता योजनाएँ लोड करने में विफल।", - "year": "वर्ष" + "year": "वर्ष", + "Failed to create checkout session": "चेकआउट सत्र बनाने में विफल" } diff --git a/apps/readest-app/public/locales/id/translation.json b/apps/readest-app/public/locales/id/translation.json index c803bc89..4c9896c2 100644 --- a/apps/readest-app/public/locales/id/translation.json +++ b/apps/readest-app/public/locales/id/translation.json @@ -454,5 +454,6 @@ "Failed to restore purchases.": "Gagal memulihkan pembelian.", "Failed to manage subscription.": "Gagal mengelola langganan.", "Failed to load subscription plans.": "Gagal memuat rencana langganan.", - "year": "tahun" + "year": "tahun", + "Failed to create checkout session": "Failed to create checkout session" } diff --git a/apps/readest-app/public/locales/it/translation.json b/apps/readest-app/public/locales/it/translation.json index db25788b..c012df64 100644 --- a/apps/readest-app/public/locales/it/translation.json +++ b/apps/readest-app/public/locales/it/translation.json @@ -462,5 +462,6 @@ "Failed to restore purchases.": "Impossibile ripristinare gli acquisti.", "Failed to manage subscription.": "Impossibile gestire l'abbonamento.", "Failed to load subscription plans.": "Impossibile caricare i piani di abbonamento.", - "year": "anno" + "year": "anno", + "Failed to create checkout session": "Impossibile creare la sessione di checkout" } diff --git a/apps/readest-app/public/locales/ja/translation.json b/apps/readest-app/public/locales/ja/translation.json index dfcf2fbc..b02d083c 100644 --- a/apps/readest-app/public/locales/ja/translation.json +++ b/apps/readest-app/public/locales/ja/translation.json @@ -454,5 +454,6 @@ "Failed to restore purchases.": "購入の復元に失敗しました。", "Failed to manage subscription.": "サブスクリプションの管理に失敗しました。", "Failed to load subscription plans.": "サブスクリプションプランの読み込みに失敗しました。", - "year": "年" + "year": "年", + "Failed to create checkout session": "チェックアウトセッションの作成に失敗しました" } diff --git a/apps/readest-app/public/locales/ko/translation.json b/apps/readest-app/public/locales/ko/translation.json index 060a1f77..c41b6bff 100644 --- a/apps/readest-app/public/locales/ko/translation.json +++ b/apps/readest-app/public/locales/ko/translation.json @@ -454,5 +454,6 @@ "Failed to restore purchases.": "구매 복원에 실패했습니다.", "Failed to manage subscription.": "구독 관리에 실패했습니다.", "Failed to load subscription plans.": "구독 플랜 로드에 실패했습니다.", - "year": "년" + "year": "년", + "Failed to create checkout session": "체크아웃 세션 생성 실패" } diff --git a/apps/readest-app/public/locales/nl/translation.json b/apps/readest-app/public/locales/nl/translation.json index 14af5d4a..27ee6ea4 100644 --- a/apps/readest-app/public/locales/nl/translation.json +++ b/apps/readest-app/public/locales/nl/translation.json @@ -458,5 +458,6 @@ "Failed to restore purchases.": "Herstellen van aankopen is mislukt.", "Failed to manage subscription.": "Beheren van abonnement is mislukt.", "Failed to load subscription plans.": "Laden van abonnement plannen is mislukt.", - "year": "jaar" + "year": "jaar", + "Failed to create checkout session": "Kon de afreken sessie niet aanmaken" } diff --git a/apps/readest-app/public/locales/pl/translation.json b/apps/readest-app/public/locales/pl/translation.json index aeeb3cc1..0fe4e06d 100644 --- a/apps/readest-app/public/locales/pl/translation.json +++ b/apps/readest-app/public/locales/pl/translation.json @@ -466,5 +466,6 @@ "Failed to restore purchases.": "Nie udało się przywrócić zakupów.", "Failed to manage subscription.": "Nie udało się zarządzać subskrypcją.", "Failed to load subscription plans.": "Nie udało się załadować planów subskrypcyjnych.", - "year": "rok" + "year": "rok", + "Failed to create checkout session": "Nie udało się utworzyć sesji zakupu" } diff --git a/apps/readest-app/public/locales/pt/translation.json b/apps/readest-app/public/locales/pt/translation.json index 4a63efba..7d510fe4 100644 --- a/apps/readest-app/public/locales/pt/translation.json +++ b/apps/readest-app/public/locales/pt/translation.json @@ -462,5 +462,6 @@ "Failed to restore purchases.": "Falha ao restaurar compras.", "Failed to manage subscription.": "Falha ao gerenciar assinatura.", "Failed to load subscription plans.": "Falha ao carregar planos de assinatura.", - "year": "ano" + "year": "ano", + "Failed to create checkout session": "Falha ao criar sessão de checkout" } diff --git a/apps/readest-app/public/locales/ru/translation.json b/apps/readest-app/public/locales/ru/translation.json index d3ffb3b3..8b4ce8de 100644 --- a/apps/readest-app/public/locales/ru/translation.json +++ b/apps/readest-app/public/locales/ru/translation.json @@ -466,5 +466,6 @@ "Failed to restore purchases.": "Не удалось восстановить покупки.", "Failed to manage subscription.": "Не удалось управлять подпиской.", "Failed to load subscription plans.": "Не удалось загрузить планы подписки.", - "year": "год" + "year": "год", + "Failed to create checkout session": "Не удалось создать сессию оформления заказа" } diff --git a/apps/readest-app/public/locales/th/translation.json b/apps/readest-app/public/locales/th/translation.json index 11d378bc..2037272e 100644 --- a/apps/readest-app/public/locales/th/translation.json +++ b/apps/readest-app/public/locales/th/translation.json @@ -454,5 +454,6 @@ "Failed to restore purchases.": "ไม่สามารถกู้คืนการซื้อได้", "Failed to manage subscription.": "ไม่สามารถจัดการการสมัครสมาชิกได้", "Failed to load subscription plans.": "ไม่สามารถโหลดแผนการสมัครสมาชิกได้", - "year": "ปี" + "year": "ปี", + "Failed to create checkout session": "ไม่สามารถสร้างเซสชันการชำระเงินได้" } diff --git a/apps/readest-app/public/locales/tr/translation.json b/apps/readest-app/public/locales/tr/translation.json index c8675720..9b012cef 100644 --- a/apps/readest-app/public/locales/tr/translation.json +++ b/apps/readest-app/public/locales/tr/translation.json @@ -458,5 +458,6 @@ "Failed to restore purchases.": "Satın alımları geri yükleme başarısız oldu.", "Failed to manage subscription.": "Aboneliği yönetme başarısız oldu.", "Failed to load subscription plans.": "Abonelik planlarını yükleme başarısız oldu.", - "year": "yıl" + "year": "yıl", + "Failed to create checkout session": "Ödeme oturumu oluşturma başarısız oldu" } diff --git a/apps/readest-app/public/locales/uk/translation.json b/apps/readest-app/public/locales/uk/translation.json index 8eda56e9..ca33c5e3 100644 --- a/apps/readest-app/public/locales/uk/translation.json +++ b/apps/readest-app/public/locales/uk/translation.json @@ -466,5 +466,6 @@ "Failed to restore purchases.": "Не вдалося відновити покупки.", "Failed to manage subscription.": "Не вдалося керувати підпискою.", "Failed to load subscription plans.": "Не вдалося завантажити плани підписки.", - "year": "рік" + "year": "рік", + "Failed to create checkout session": "Не вдалося створити сесію оформлення замовлення" } diff --git a/apps/readest-app/public/locales/vi/translation.json b/apps/readest-app/public/locales/vi/translation.json index 5419936f..ac88c29a 100644 --- a/apps/readest-app/public/locales/vi/translation.json +++ b/apps/readest-app/public/locales/vi/translation.json @@ -454,5 +454,6 @@ "Failed to restore purchases.": "Khôi phục giao dịch mua không thành công.", "Failed to manage subscription.": "Quản lý đăng ký không thành công.", "Failed to load subscription plans.": "Tải kế hoạch đăng ký không thành công.", - "year": "năm" + "year": "năm", + "Failed to create checkout session": "Không thể tạo phiên làm việc thanh toán" } diff --git a/apps/readest-app/public/locales/zh-CN/translation.json b/apps/readest-app/public/locales/zh-CN/translation.json index e0b911f8..ed89b9d4 100644 --- a/apps/readest-app/public/locales/zh-CN/translation.json +++ b/apps/readest-app/public/locales/zh-CN/translation.json @@ -454,5 +454,6 @@ "Failed to restore purchases.": "恢复购买失败。", "Failed to manage subscription.": "管理订阅失败。", "Failed to load subscription plans.": "加载订阅计划失败。", - "year": "年" + "year": "年", + "Failed to create checkout session": "创建结账会话失败" } diff --git a/apps/readest-app/public/locales/zh-TW/translation.json b/apps/readest-app/public/locales/zh-TW/translation.json index 678bd4d1..6d243888 100644 --- a/apps/readest-app/public/locales/zh-TW/translation.json +++ b/apps/readest-app/public/locales/zh-TW/translation.json @@ -454,5 +454,6 @@ "Failed to restore purchases.": "恢復購買失敗。", "Failed to manage subscription.": "管理訂閱失敗。", "Failed to load subscription plans.": "加載訂閱計劃失敗。", - "year": "年" + "year": "年", + "Failed to create checkout session": "創建結帳會話失敗" } diff --git a/apps/readest-app/src/__tests__/integration/apple-iap.test.ts b/apps/readest-app/src/__tests__/integration/apple-iap.test.ts index 85b8527d..bb02b046 100644 --- a/apps/readest-app/src/__tests__/integration/apple-iap.test.ts +++ b/apps/readest-app/src/__tests__/integration/apple-iap.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, beforeAll } from 'vitest'; -import { AppleIAPVerifier } from '@/libs/iap/apple/verifier'; +import { AppleIAPVerifier, createAppleIAPVerifier } from '@/libs/iap/apple/verifier'; const SKIP_IAP_API_TESTS = !process.env['ENABLE_IAP_API_TESTS']; const REAL_TEST_DATA = { @@ -26,7 +26,7 @@ describe.skipIf(SKIP_IAP_API_TESTS)('Apple IAP Integration Tests', () => { let verifier: AppleIAPVerifier; beforeAll(() => { - verifier = new AppleIAPVerifier({ + verifier = createAppleIAPVerifier({ keyId: process.env['APPLE_IAP_KEY_ID']!, issuerId: process.env['APPLE_IAP_ISSUER_ID']!, bundleId: process.env['APPLE_IAP_BUNDLE_ID']!, diff --git a/apps/readest-app/src/app/api/apple/iap-verify/route.ts b/apps/readest-app/src/app/api/apple/iap-verify/route.ts index 9d2bf023..731a8c65 100644 --- a/apps/readest-app/src/app/api/apple/iap-verify/route.ts +++ b/apps/readest-app/src/app/api/apple/iap-verify/route.ts @@ -1,6 +1,6 @@ import { z } from 'zod'; import { NextResponse } from 'next/server'; -import { defaultIAPVerifier } from '@/libs/iap/apple/verifier'; +import { getAppleIAPVerifier } from '@/libs/iap/apple/verifier'; import { createSupabaseAdminClient } from '@/utils/supabase'; import { validateUserAndToken } from '@/utils/access'; import { IAPError } from '@/types/error'; @@ -169,6 +169,7 @@ export async function POST(request: Request) { }); } + const defaultIAPVerifier = getAppleIAPVerifier(); const verificationResult = await defaultIAPVerifier.verifyTransaction(originalTransactionId); if (!verificationResult.success) { console.error('Apple verification failed:', verificationResult.error); diff --git a/apps/readest-app/src/app/user/page.tsx b/apps/readest-app/src/app/user/page.tsx index faf695b8..18b9584a 100644 --- a/apps/readest-app/src/app/user/page.tsx +++ b/apps/readest-app/src/app/user/page.tsx @@ -112,15 +112,27 @@ const ProfilePage = () => { } setLoading(true); const isEmbeddedCheckout = isTauriAppPlatform(); - const { sessionId, clientSecret, url } = await fetch(WEB_STRIPE_CHECKOUT_URL, { + const response = await fetch(WEB_STRIPE_CHECKOUT_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}`, }, body: JSON.stringify({ priceId, embedded: isEmbeddedCheckout }), - }).then((res) => res.json()); + }); setLoading(false); + if (!response.ok) { + console.error('Failed to create Stripe checkout session'); + posthog.capture('checkout_error', { + error: 'Failed to create Stripe checkout session', + }); + eventDispatcher.dispatch('toast', { + type: 'info', + message: _('Failed to create checkout session'), + }); + return; + } + const { sessionId, clientSecret, url } = await response.json(); const selectedPlan = availablePlans.find((plan) => plan.price_id === priceId)!; const planName = selectedPlan.product?.name || selectedPlan.productName; @@ -193,6 +205,9 @@ const ProfilePage = () => { try { const purchases = await iapService.restorePurchases(); if (purchases.length > 0) { + purchases.sort( + (a, b) => new Date(a.purchaseDate).getTime() - new Date(b.purchaseDate).getTime(), + ); const purchase = purchases[0]!; const params = new URLSearchParams({ payment: 'iap', @@ -285,7 +300,10 @@ const ProfilePage = () => { } else { fetch(WEB_STRIPE_PLANS_URL) .then((res) => res.json()) - .then((data) => setAvailablePlans(data || [])); + .then((data) => { + const availablePlans = data && data instanceof Array ? data : []; + setAvailablePlans(availablePlans); + }); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [appService]); diff --git a/apps/readest-app/src/app/user/subscription/success/page.tsx b/apps/readest-app/src/app/user/subscription/success/page.tsx index 021ebee3..f9182ccd 100644 --- a/apps/readest-app/src/app/user/subscription/success/page.tsx +++ b/apps/readest-app/src/app/user/subscription/success/page.tsx @@ -2,13 +2,13 @@ import { Suspense, useEffect, useState } from 'react'; import { useSearchParams, useRouter } from 'next/navigation'; import { useTranslation } from '@/hooks/useTranslation'; -import { getAPIBaseUrl } from '@/services/environment'; +import { getAPIBaseUrl, getNodeAPIBaseUrl } from '@/services/environment'; import { getAccessToken } from '@/utils/access'; import { supabase } from '@/utils/supabase'; import Spinner from '@/components/Spinner'; -const WEB_STRIPE_CHECK_URL = `${getAPIBaseUrl()}/stripe/check`; -const WEB_APPLE_IAP_VERIFY_URL = `${getAPIBaseUrl()}/apple/iap-verify`; +const STRIPE_CHECK_URL = `${getAPIBaseUrl()}/stripe/check`; +const APPLE_IAP_VERIFY_URL = `${getNodeAPIBaseUrl()}/apple/iap-verify`; interface SessionStatus { status: 'loading' | 'complete' | 'failed' | 'processing'; @@ -40,7 +40,7 @@ const SuccessPageWithSearchParams = () => { const updateStripeSessionStatus = async () => { try { const token = await getAccessToken(); - const response = await fetch(WEB_STRIPE_CHECK_URL, { + const response = await fetch(STRIPE_CHECK_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -93,7 +93,7 @@ const SuccessPageWithSearchParams = () => { if (platform === 'ios') { try { const token = await getAccessToken(); - const response = await fetch(WEB_APPLE_IAP_VERIFY_URL, { + const response = await fetch(APPLE_IAP_VERIFY_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/apps/readest-app/src/libs/iap/apple/verifier.ts b/apps/readest-app/src/libs/iap/apple/verifier.ts index c29bc74b..b22b48d0 100644 --- a/apps/readest-app/src/libs/iap/apple/verifier.ts +++ b/apps/readest-app/src/libs/iap/apple/verifier.ts @@ -118,13 +118,19 @@ export class AppleIAPVerifier { export const createAppleIAPVerifier = (config: AppleIAPConfig) => new AppleIAPVerifier(config); -export const defaultIAPVerifier = new AppleIAPVerifier({ - keyId: process.env['APPLE_IAP_KEY_ID']!, - issuerId: process.env['APPLE_IAP_ISSUER_ID']!, - bundleId: process.env['APPLE_IAP_BUNDLE_ID']!, - privateKey: Buffer.from(process.env['APPLE_IAP_PRIVATE_KEY_BASE64']! || '', 'base64').toString( - 'utf-8', - ), - environment: 'sandbox', - // environment: process.env.NODE_ENV === 'production' ? 'production' : 'sandbox', -}); +let defaultIAPVerifier: AppleIAPVerifier | undefined; +export const getAppleIAPVerifier = () => { + if (!defaultIAPVerifier) { + defaultIAPVerifier = createAppleIAPVerifier({ + keyId: process.env['APPLE_IAP_KEY_ID']!, + issuerId: process.env['APPLE_IAP_ISSUER_ID']!, + bundleId: process.env['APPLE_IAP_BUNDLE_ID']!, + privateKey: Buffer.from( + process.env['APPLE_IAP_PRIVATE_KEY_BASE64']! || '', + 'base64', + ).toString('utf-8'), + environment: process.env.NODE_ENV === 'production' ? 'production' : 'sandbox', + }); + } + return defaultIAPVerifier; +}; diff --git a/apps/readest-app/src/services/constants.ts b/apps/readest-app/src/services/constants.ts index 6187f25a..5cfb6e4f 100644 --- a/apps/readest-app/src/services/constants.ts +++ b/apps/readest-app/src/services/constants.ts @@ -535,6 +535,7 @@ export const BOOK_IDS_SEPARATOR = '+'; export const DOWNLOAD_READEST_URL = 'https://readest.com?utm_source=readest_web'; export const READEST_WEB_BASE_URL = 'https://web.readest.com'; +export const READEST_NODE_BASE_URL = 'https://node.readest.com'; const LATEST_DOWNLOAD_BASE_URL = 'https://download.readest.com/releases'; diff --git a/apps/readest-app/src/services/environment.ts b/apps/readest-app/src/services/environment.ts index beed8644..902b429d 100644 --- a/apps/readest-app/src/services/environment.ts +++ b/apps/readest-app/src/services/environment.ts @@ -1,5 +1,5 @@ import { AppService } from '@/types/system'; -import { READEST_WEB_BASE_URL } from './constants'; +import { READEST_NODE_BASE_URL, READEST_WEB_BASE_URL } from './constants'; declare global { interface Window { @@ -12,12 +12,18 @@ export const isWebAppPlatform = () => process.env['NEXT_PUBLIC_APP_PLATFORM'] == export const hasCli = () => window.__READEST_CLI_ACCESS === true; export const isPWA = () => window.matchMedia('(display-mode: standalone)').matches; export const getBaseUrl = () => process.env['NEXT_PUBLIC_API_BASE_URL'] ?? READEST_WEB_BASE_URL; +export const getNodeBaseUrl = () => + process.env['NEXT_PUBLIC_NODE_BASE_URL'] ?? READEST_NODE_BASE_URL; + +const isWebDevMode = () => process.env['NODE_ENV'] === 'development' && isWebAppPlatform(); // Dev API only in development mode and web platform // with command `pnpm dev-web` // for production build or tauri app use the production Web API -export const getAPIBaseUrl = () => - process.env['NODE_ENV'] === 'development' && isWebAppPlatform() ? '/api' : `${getBaseUrl()}/api`; +export const getAPIBaseUrl = () => (isWebDevMode() ? '/api' : `${getBaseUrl()}/api`); + +// For Node.js API that currently not supported in some edge runtimes +export const getNodeAPIBaseUrl = () => (isWebDevMode() ? '/api' : `${getNodeBaseUrl()}/api`); export interface EnvConfigType { getAppService: () => Promise; diff --git a/apps/readest-app/tsconfig.json b/apps/readest-app/tsconfig.json index ae1a0cdb..7547826b 100644 --- a/apps/readest-app/tsconfig.json +++ b/apps/readest-app/tsconfig.json @@ -29,7 +29,7 @@ ], "@pdfjs/*": [ "./public/vendor/pdfjs/*" - ] + ], } }, "include": [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 44b71534..289260c4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -51,8 +51,8 @@ importers: specifier: '2' version: 2.0.0 '@opennextjs/cloudflare': - specifier: ^1.3.1 - version: 1.3.1(wrangler@4.21.0) + specifier: ^1.6.1 + version: 1.6.1(wrangler@4.26.0) '@stripe/react-stripe-js': specifier: ^3.7.0 version: 3.7.0(@stripe/stripe-js@7.4.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -226,7 +226,7 @@ importers: specifier: ^0.3.5 version: 0.3.5 '@types/node': - specifier: ^22.10.1 + specifier: ^22.15.31 version: 22.15.31 '@types/react': specifier: 18.3.12 @@ -304,8 +304,8 @@ importers: specifier: ^3.2.4 version: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.31)(jiti@1.21.6)(jsdom@26.1.0)(terser@5.43.1)(yaml@2.7.0) wrangler: - specifier: ^4.21.0 - version: 4.21.0 + specifier: ^4.26.0 + version: 4.26.0 packages/foliate-js: dependencies: @@ -1331,41 +1331,41 @@ packages: resolution: {integrity: sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==} engines: {node: '>=18.0.0'} - '@cloudflare/unenv-preset@2.3.3': - resolution: {integrity: sha512-/M3MEcj3V2WHIRSW1eAQBPRJ6JnGQHc6JKMAPLkDb7pLs3m6X9ES/+K3ceGqxI6TKeF32AWAi7ls0AYzVxCP0A==} + '@cloudflare/unenv-preset@2.4.1': + resolution: {integrity: sha512-70mk5GPv+ozJ5XcIhFpq4ps7HvQYu+As7vwasUy9LcBadsTcWA2iFis/7aFJmQehfKerDwVOHfMYpgTTC+u24Q==} peerDependencies: unenv: 2.0.0-rc.17 - workerd: ^1.20250508.0 + workerd: ^1.20250521.0 peerDependenciesMeta: workerd: optional: true - '@cloudflare/workerd-darwin-64@1.20250617.0': - resolution: {integrity: sha512-toG8JUKVLIks4oOJLe9FeuixE84pDpMZ32ip7mCpE7JaFc5BqGFvevk0YC/db3T71AQlialjRwioH3jS/dzItA==} + '@cloudflare/workerd-darwin-64@1.20250712.0': + resolution: {integrity: sha512-M6S6a/LQ0Jb0R+g0XhlYi1adGifvYmxA5mD/i9TuZZgjs2bIm5ELuka/n3SCnI98ltvlx3HahRaHagAtOilsFg==} engines: {node: '>=16'} cpu: [x64] os: [darwin] - '@cloudflare/workerd-darwin-arm64@1.20250617.0': - resolution: {integrity: sha512-JTX0exbC9/ZtMmQQA8tDZEZFMXZrxOpTUj2hHnsUkErWYkr5SSZH04RBhPg6dU4VL8bXuB5/eJAh7+P9cZAp7g==} + '@cloudflare/workerd-darwin-arm64@1.20250712.0': + resolution: {integrity: sha512-7sFzn6rvAcnLy7MktFL42dYtzL0Idw/kiUmNf2P3TvsBRoShhLK5ZKhbw+NAhvU8e4pXWm5lkE0XmpieA0zNjw==} engines: {node: '>=16'} cpu: [arm64] os: [darwin] - '@cloudflare/workerd-linux-64@1.20250617.0': - resolution: {integrity: sha512-8jkSoVRJ+1bOx3tuWlZCGaGCV2ew7/jFMl6V3CPXOoEtERUHsZBQLVkQIGKcmC/LKSj7f/mpyBUeu2EPTo2HEg==} + '@cloudflare/workerd-linux-64@1.20250712.0': + resolution: {integrity: sha512-EFRrGe/bqK7NHtht7vNlbrDpfvH3eRvtJOgsTpEQEysDjVmlK6pVJxSnLy9Hg1zlLY15IfhfGC+K2qisseHGJQ==} engines: {node: '>=16'} cpu: [x64] os: [linux] - '@cloudflare/workerd-linux-arm64@1.20250617.0': - resolution: {integrity: sha512-YAzcOyu897z5dQKFzme1oujGWMGEJCR7/Wrrm1nSP6dqutxFPTubRADM8BHn2CV3ij//vaPnAeLmZE3jVwOwig==} + '@cloudflare/workerd-linux-arm64@1.20250712.0': + resolution: {integrity: sha512-rG8JUleddhUHQVwpXOYv0VbL0S9kOtR9PNKecgVhFpxEhC8aTeg2HNBBjo8st7IfcUvY8WaW3pD3qdAMZ05UwQ==} engines: {node: '>=16'} cpu: [arm64] os: [linux] - '@cloudflare/workerd-windows-64@1.20250617.0': - resolution: {integrity: sha512-XWM/6sagDrO0CYDKhXhPjM23qusvIN1ju9ZEml6gOQs8tNOFnq6Cn6X9FAmnyapRFCGUSEC3HZYJAm7zwVKaMA==} + '@cloudflare/workerd-windows-64@1.20250712.0': + resolution: {integrity: sha512-qS8H5RCYwE21Om9wo5/F807ClBJIfknhuLBj16eYxvJcj9JqgAKWi12BGgjyGxHuJJjeoQ63lr4wHAdbFntDDg==} engines: {node: '>=16'} cpu: [x64] os: [win32] @@ -1422,9 +1422,6 @@ packages: peerDependencies: '@noble/ciphers': ^1.0.0 - '@emnapi/runtime@1.4.3': - resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} - '@emnapi/runtime@1.4.5': resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} @@ -1623,10 +1620,6 @@ packages: '@fabianlars/tauri-plugin-oauth@2.0.0': resolution: {integrity: sha512-I1s08ZXrsFuYfNWusAcpLyiCfr5TCvaBrRuKfTG+XQrcaqnAcwjdWH0U5J9QWuMDLwCUMnVxdobtMJzPR8raxQ==} - '@fastify/busboy@2.1.1': - resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} - engines: {node: '>=14'} - '@gulpjs/to-absolute-glob@4.0.0': resolution: {integrity: sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA==} engines: {node: '>=10.13.0'} @@ -2116,15 +2109,15 @@ packages: resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} engines: {node: '>=12.4.0'} - '@opennextjs/aws@3.6.6': - resolution: {integrity: sha512-JtwwzDLI4g9Upqhkn4dgaNtCIjNuE8po7seFqkgXLR5qeUgJ7qI+3RPr0wSDnC/c2FaIMN6Zrm3bFi+6hpLttQ==} + '@opennextjs/aws@3.7.0': + resolution: {integrity: sha512-JXUZice+CedEQW20hnBVqzBEj+jfr4Oe2LVYSE4RNKdfHVIeYG+WJAop14TxRJ+NugKWGcJx6opf944l+ZG7XQ==} hasBin: true - '@opennextjs/cloudflare@1.3.1': - resolution: {integrity: sha512-1cWOqWiG5FZJ6PIAywwWRidGhWcDSKroHdAtKHceLTWpDPnn3LlilpMN7xGtU/3jVRN7uHonC/5wkdSfQgDo0w==} + '@opennextjs/cloudflare@1.6.1': + resolution: {integrity: sha512-rpTFHzdFh5kZpt8vX+uzsEvdrDvPF2UMn4/1muub93pTXbx+XqignEiGV4loZSPQv12UUT422o3eLPI1LRHWHA==} hasBin: true peerDependencies: - wrangler: ^4.19.1 + wrangler: ^4.24.4 '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} @@ -2133,6 +2126,15 @@ packages: '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + '@poppinss/colors@4.1.5': + resolution: {integrity: sha512-FvdDqtcRCtz6hThExcFOgW0cWX+xwSMWcRuQe5ZEb2m7cVQOAVZOIMt+/v9RxGiD9/OY16qJBXK4CVKWAPalBw==} + + '@poppinss/dumper@0.6.4': + resolution: {integrity: sha512-iG0TIdqv8xJ3Lt9O8DrPRxw1MRLjNpoqiSGU03P/wNLP/s0ra0udPJ1J2Tx5M0J3H/cVyEgpbn8xUKRY9j59kQ==} + + '@poppinss/exception@1.2.2': + resolution: {integrity: sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg==} + '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} @@ -2401,6 +2403,10 @@ packages: '@rushstack/eslint-patch@1.10.4': resolution: {integrity: sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==} + '@sindresorhus/is@7.0.2': + resolution: {integrity: sha512-d9xRovfKNz1SKieM0qJdO+PQonjnnIfSNWfHYnBSJ9hkjm0ZPw6HlxscDXYstp3z+7V2GOFHc+J0CYrYTjqCJw==} + engines: {node: '>=18'} + '@sindresorhus/merge-streams@2.3.0': resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} engines: {node: '>=18'} @@ -2821,6 +2827,9 @@ packages: resolution: {integrity: sha512-piUTHyp2Axx3p/kc2CIJkYSv0BAaheBQmbACZgQSSfWUumWNW+R1lL+H9PDBxKJkvOeEX+hKYEFiwO8xagL8AQ==} engines: {node: '>=18.0.0'} + '@speed-highlight/core@1.2.7': + resolution: {integrity: sha512-0dxmVj4gxg3Jg879kvFS/msl4s9F3T9UXC1InxgOf7t5NvcPD97u/WTA5vL/IxWHMn7qSxBozqrnnE2wvl1m8g==} + '@stitches/core@1.2.8': resolution: {integrity: sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg==} @@ -3087,9 +3096,15 @@ packages: '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + '@types/node-fetch@2.6.12': + resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} + '@types/node@10.17.60': resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} + '@types/node@18.19.120': + resolution: {integrity: sha512-WtCGHFXnVI8WHLxDAt5TbnCM4eSE+nI0QN2NJtwzcgMhht2eNz6V9evJrk+lwC8bCY8OWV5Ym8Jz7ZEyGnKnMA==} + '@types/node@22.15.31': resolution: {integrity: sha512-jnVe5ULKl6tijxUhvQeNbQG/84fHfg+yMak02cT8QVhBx/F05rAVxCGBYYTh2EKz22D6JF5ktXuNwdx7b9iEGw==} @@ -3297,6 +3312,10 @@ packages: resolution: {integrity: sha512-G6Bl5wN9EXXVaTUIox71vIX5Z454zEBe+akKpV4m1tUboIctT5h7ID3QXCJd/Lfy2rSvmkTmZIucf1jGRR4f5A==} engines: {bun: '>=0.7.0', deno: '>=1.0.0', node: '>=16.5.0'} + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + accepts@2.0.0: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} @@ -3358,6 +3377,10 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} + agentkeepalive@4.6.0: + resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} + engines: {node: '>= 8.0.0'} + ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} peerDependencies: @@ -3464,9 +3487,6 @@ packages: resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} engines: {node: '>= 0.4'} - as-table@1.0.55: - resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} - assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -3477,6 +3497,9 @@ packages: async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + at-least-node@1.0.0: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} @@ -3652,6 +3675,10 @@ packages: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + cliui@9.0.1: + resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} + engines: {node: '>=20'} + clone-deep@4.0.1: resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} engines: {node: '>=6'} @@ -3663,6 +3690,9 @@ packages: resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} engines: {node: '>=0.8'} + cloudflare@4.5.0: + resolution: {integrity: sha512-fPcbPKx4zF45jBvQ0z7PCdgejVAPBBCZxwqk1k7krQNfpM07Cfj97/Q6wBzvYqlWXx/zt1S9+m8vnfCe06umbQ==} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -3681,6 +3711,10 @@ packages: resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} engines: {node: '>=12.5.0'} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + commander@11.1.0: resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} @@ -3798,9 +3832,6 @@ packages: damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} - data-uri-to-buffer@2.0.2: - resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} - data-urls@5.0.0: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} @@ -3900,6 +3931,10 @@ packages: defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -3981,6 +4016,9 @@ packages: electron-to-chromium@1.5.84: resolution: {integrity: sha512-I+DQ8xgafao9Ha6y0qjHHvpZ9OfyA1qKlkHkjywxzniORU2awxyz7f/iVJcULmrF2yrM3nHQf+iDjJtbbexd/g==} + emoji-regex@10.4.0: + resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -4017,6 +4055,9 @@ packages: eol@0.9.1: resolution: {integrity: sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==} + error-stack-parser-es@1.0.5: + resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} + es-abstract@1.23.5: resolution: {integrity: sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ==} engines: {node: '>= 0.4'} @@ -4052,6 +4093,10 @@ packages: resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} engines: {node: '>= 0.4'} + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + es-shim-unscopables@1.0.2: resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} @@ -4223,6 +4268,10 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} @@ -4283,14 +4332,6 @@ packages: fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} - fdir@6.4.3: - resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - fdir@6.4.6: resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} peerDependencies: @@ -4345,6 +4386,17 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} + form-data-encoder@1.7.2: + resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} + + form-data@4.0.4: + resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + engines: {node: '>= 6'} + + formdata-node@4.4.1: + resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==} + engines: {node: '>= 12.20'} + forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -4398,6 +4450,10 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-east-asian-width@1.3.0: + resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} + engines: {node: '>=18'} + get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -4413,9 +4469,6 @@ packages: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} - get-source@2.0.12: - resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} - get-stdin@9.0.0: resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==} engines: {node: '>=12'} @@ -4571,6 +4624,9 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + husky@9.1.7: resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} engines: {node: '>=18'} @@ -4925,6 +4981,10 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -5088,8 +5148,8 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - miniflare@4.20250617.3: - resolution: {integrity: sha512-j+LZycT11UdlVeNdaqD0XdNnYnqAL+wXmboz+tNPFgTq6zhD489Ujj3BfSDyEHDCA9UFBLbkc5ByGWBh+pYZ5Q==} + miniflare@4.20250712.2: + resolution: {integrity: sha512-cZ8WyQBwqfjYLjd61fDR4/j0nAVbjB3Wxbun/brL9S5FAi4RlTR0LyMTKsIVA0s+nL4Pg9VjVMki4M/Jk2cz+Q==} engines: {node: '>=18.0.0'} hasBin: true @@ -5146,10 +5206,6 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - mustache@4.2.0: - resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} - hasBin: true - mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -5194,6 +5250,10 @@ packages: sass: optional: true + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + node-env-run@4.0.2: resolution: {integrity: sha512-qAGmXrM32xUGdaCBmkQG8RIgm+8Oj22rURkAoX9HuKDQiM0Vm66QebkWEnU5nozYgPbO/PFPrPmerI6ZEPp8UQ==} hasBin: true @@ -5604,9 +5664,6 @@ packages: resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==} engines: {node: '>= 0.8'} - printable-characters@1.0.42: - resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} - process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -6003,9 +6060,6 @@ packages: stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - stacktracey@2.1.8: - resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} - statuses@2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} @@ -6035,6 +6089,10 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + string.prototype.includes@2.0.1: resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} engines: {node: '>= 0.4'} @@ -6127,6 +6185,10 @@ packages: engines: {node: '>=16 || 14 >=14.17'} hasBin: true + supports-color@10.0.0: + resolution: {integrity: sha512-HRVVSbCCMbj7/kdWF9Q+bbckjBHLtHMEoJWlkmYzzdwhYMkjkOwubLM6t7NbWKjgKamGDrWL1++KrjUO1t9oAQ==} + engines: {node: '>=18'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -6362,12 +6424,15 @@ packages: unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici@5.29.0: - resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} - engines: {node: '>=14.0'} + undici@7.12.0: + resolution: {integrity: sha512-GrKEsc3ughskmGA9jevVlIOPMiiAHJ4OFUtaAH+NhfTUSiZ1wMPIQqQvAJUrJspFXJt3EBWgpAeoHEDVT1IBug==} + engines: {node: '>=20.18.1'} unenv@2.0.0-rc.17: resolution: {integrity: sha512-B06u0wXkEd+o5gOCMl/ZHl5cfpYbDZKAT+HWTL+Hws6jWu7dCiqBBXXXzMFcFVJb8D4ytAnYmxJA83uwOQRSsg==} @@ -6551,6 +6616,10 @@ packages: resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==} engines: {node: '>=10.13.0'} + web-streams-polyfill@4.0.0-beta.3: + resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} + engines: {node: '>= 14'} + web-vitals@4.2.4: resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==} @@ -6700,17 +6769,17 @@ packages: workbox-window@7.1.0: resolution: {integrity: sha512-ZHeROyqR+AS5UPzholQRDttLFqGMwP0Np8MKWAdyxsDETxq3qOAyXvqessc3GniohG6e0mAqSQyKOHmT8zPF7g==} - workerd@1.20250617.0: - resolution: {integrity: sha512-Uv6p0PYUHp/W/aWfUPLkZVAoAjapisM27JJlwcX9wCPTfCfnuegGOxFMvvlYpmNaX4YCwEdLCwuNn3xkpSkuZw==} + workerd@1.20250712.0: + resolution: {integrity: sha512-7h+k1OxREpiZW0849g0uQNexRWMcs5i5gUGhJzCY8nIx6Tv4D/ndlXJ47lEFj7/LQdp165IL9dM2D5uDiedZrg==} engines: {node: '>=16'} hasBin: true - wrangler@4.21.0: - resolution: {integrity: sha512-37xm0CG2qMvsJUNZYQKje6HbCsJFYuE8dQSnu7981iDRT4DLrEIL1DAUnZJG9HiXteKPvrSj96AkZyomi5sYHw==} + wrangler@4.26.0: + resolution: {integrity: sha512-EXuwyWlgYQZv6GJlyE0lVGk9hHqASssuECECT1XC5aIijTwNLQhsj/TOZ0hKSFlMbVr1E+OAdevAxd0kaF4ovA==} engines: {node: '>=18.0.0'} hasBin: true peerDependencies: - '@cloudflare/workers-types': ^4.20250617.0 + '@cloudflare/workers-types': ^4.20250712.0 peerDependenciesMeta: '@cloudflare/workers-types': optional: true @@ -6727,6 +6796,10 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} + wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -6805,6 +6878,10 @@ packages: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yargs@15.4.1: resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} engines: {node: '>=8'} @@ -6813,6 +6890,10 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} + yargs@18.0.0: + resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'} @@ -6821,8 +6902,11 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - youch@3.3.4: - resolution: {integrity: sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==} + youch-core@0.3.3: + resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} + + youch@4.1.0-beta.10: + resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} zod@3.22.3: resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} @@ -8240,7 +8324,7 @@ snapshots: '@babel/core': 7.26.7 '@babel/helper-compilation-targets': 7.26.5 '@babel/helper-plugin-utils': 7.26.5 - debug: 4.4.0 + debug: 4.4.1 lodash.debounce: 4.0.8 resolve: 1.22.8 transitivePeerDependencies: @@ -8865,25 +8949,25 @@ snapshots: dependencies: mime: 3.0.0 - '@cloudflare/unenv-preset@2.3.3(unenv@2.0.0-rc.17)(workerd@1.20250617.0)': + '@cloudflare/unenv-preset@2.4.1(unenv@2.0.0-rc.17)(workerd@1.20250712.0)': dependencies: unenv: 2.0.0-rc.17 optionalDependencies: - workerd: 1.20250617.0 + workerd: 1.20250712.0 - '@cloudflare/workerd-darwin-64@1.20250617.0': + '@cloudflare/workerd-darwin-64@1.20250712.0': optional: true - '@cloudflare/workerd-darwin-arm64@1.20250617.0': + '@cloudflare/workerd-darwin-arm64@1.20250712.0': optional: true - '@cloudflare/workerd-linux-64@1.20250617.0': + '@cloudflare/workerd-linux-64@1.20250712.0': optional: true - '@cloudflare/workerd-linux-arm64@1.20250617.0': + '@cloudflare/workerd-linux-arm64@1.20250712.0': optional: true - '@cloudflare/workerd-windows-64@1.20250617.0': + '@cloudflare/workerd-windows-64@1.20250712.0': optional: true '@cspotcode/source-map-support@0.8.1': @@ -8918,10 +9002,10 @@ snapshots: dotenv: 16.4.5 eciesjs: 0.4.14 execa: 5.1.1 - fdir: 6.4.3(picomatch@4.0.2) + fdir: 6.4.6(picomatch@4.0.3) ignore: 5.3.2 object-treeify: 1.1.33 - picomatch: 4.0.2 + picomatch: 4.0.3 which: 4.0.0 '@ducanh2912/next-pwa@10.2.9(@types/babel__core@7.20.5)(next@15.3.3(@babel/core@7.26.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(webpack@5.97.1)': @@ -8942,11 +9026,6 @@ snapshots: dependencies: '@noble/ciphers': 1.2.1 - '@emnapi/runtime@1.4.3': - dependencies: - tslib: 2.8.1 - optional: true - '@emnapi/runtime@1.4.5': dependencies: tslib: 2.8.1 @@ -9079,8 +9158,6 @@ snapshots: dependencies: '@tauri-apps/api': 2.6.0 - '@fastify/busboy@2.1.1': {} - '@gulpjs/to-absolute-glob@4.0.0': dependencies: is-negated-glob: 1.0.0 @@ -9240,7 +9317,7 @@ snapshots: '@img/sharp-wasm32@0.33.5': dependencies: - '@emnapi/runtime': 1.4.3 + '@emnapi/runtime': 1.4.5 optional: true '@img/sharp-wasm32@0.34.3': @@ -9432,7 +9509,7 @@ snapshots: '@nolyfill/is-core-module@1.0.39': {} - '@opennextjs/aws@3.6.6': + '@opennextjs/aws@3.7.0': dependencies: '@ast-grep/napi': 0.35.0 '@aws-sdk/client-cloudfront': 3.398.0 @@ -9455,16 +9532,19 @@ snapshots: - aws-crt - supports-color - '@opennextjs/cloudflare@1.3.1(wrangler@4.21.0)': + '@opennextjs/cloudflare@1.6.1(wrangler@4.26.0)': dependencies: '@dotenvx/dotenvx': 1.31.0 - '@opennextjs/aws': 3.6.6 + '@opennextjs/aws': 3.7.0 + cloudflare: 4.5.0 enquirer: 2.4.1 glob: 11.0.0 ts-tqdm: 0.8.6 - wrangler: 4.21.0 + wrangler: 4.26.0 + yargs: 18.0.0 transitivePeerDependencies: - aws-crt + - encoding - supports-color '@pkgjs/parseargs@0.11.0': @@ -9472,6 +9552,18 @@ snapshots: '@polka/url@1.0.0-next.29': {} + '@poppinss/colors@4.1.5': + dependencies: + kleur: 4.1.5 + + '@poppinss/dumper@0.6.4': + dependencies: + '@poppinss/colors': 4.1.5 + '@sindresorhus/is': 7.0.2 + supports-color: 10.0.0 + + '@poppinss/exception@1.2.2': {} + '@rolldown/pluginutils@1.0.0-beta.27': {} '@rollup/plugin-babel@5.3.1(@babel/core@7.26.7)(@types/babel__core@7.20.5)(rollup@2.79.2)': @@ -9668,6 +9760,8 @@ snapshots: '@rushstack/eslint-patch@1.10.4': {} + '@sindresorhus/is@7.0.2': {} + '@sindresorhus/merge-streams@2.3.0': {} '@sindresorhus/tsconfig@6.0.0': {} @@ -10381,6 +10475,8 @@ snapshots: '@smithy/types': 4.1.0 tslib: 2.8.1 + '@speed-highlight/core@1.2.7': {} + '@stitches/core@1.2.8': {} '@stripe/react-stripe-js@3.7.0(@stripe/stripe-js@7.4.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': @@ -10664,8 +10760,17 @@ snapshots: '@types/ms@0.7.34': {} + '@types/node-fetch@2.6.12': + dependencies: + '@types/node': 22.16.5 + form-data: 4.0.4 + '@types/node@10.17.60': {} + '@types/node@18.19.120': + dependencies: + undici-types: 5.26.5 + '@types/node@22.15.31': dependencies: undici-types: 6.21.0 @@ -10938,6 +11043,10 @@ snapshots: '@zip.js/zip.js@2.7.53': {} + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + accepts@2.0.0: dependencies: mime-types: 3.0.0 @@ -10989,6 +11098,10 @@ snapshots: agent-base@7.1.4: {} + agentkeepalive@4.6.0: + dependencies: + humanize-ms: 1.2.1 + ajv-formats@2.1.1(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 @@ -11119,16 +11232,14 @@ snapshots: is-array-buffer: 3.0.4 is-shared-array-buffer: 1.0.3 - as-table@1.0.55: - dependencies: - printable-characters: 1.0.42 - assertion-error@2.0.1: {} ast-types-flow@0.0.8: {} async@3.2.6: {} + asynckit@0.4.0: {} + at-least-node@1.0.0: {} autoprefixer@10.4.20(postcss@8.4.49): @@ -11200,7 +11311,7 @@ snapshots: dependencies: bytes: 3.1.2 content-type: 1.0.5 - debug: 4.4.0 + debug: 4.4.1 http-errors: 2.0.0 iconv-lite: 0.5.2 on-finished: 2.4.1 @@ -11327,6 +11438,12 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + cliui@9.0.1: + dependencies: + string-width: 7.2.0 + strip-ansi: 7.1.0 + wrap-ansi: 9.0.0 + clone-deep@4.0.1: dependencies: is-plain-object: 2.0.4 @@ -11337,6 +11454,18 @@ snapshots: clone@2.1.2: {} + cloudflare@4.5.0: + dependencies: + '@types/node': 18.19.120 + '@types/node-fetch': 2.6.12 + abort-controller: 3.0.0 + agentkeepalive: 4.6.0 + form-data-encoder: 1.7.2 + formdata-node: 4.4.1 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + clsx@2.1.1: {} color-convert@2.0.1: @@ -11355,6 +11484,10 @@ snapshots: color-convert: 2.0.1 color-string: 1.9.1 + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + commander@11.1.0: {} commander@2.20.3: {} @@ -11464,8 +11597,6 @@ snapshots: damerau-levenshtein@1.0.8: {} - data-uri-to-buffer@2.0.2: {} - data-urls@5.0.0: dependencies: whatwg-mimetype: 4.0.0 @@ -11539,6 +11670,8 @@ snapshots: defu@6.1.4: {} + delayed-stream@1.0.0: {} + depd@2.0.0: {} dependency-graph@0.11.0: {} @@ -11602,6 +11735,8 @@ snapshots: electron-to-chromium@1.5.84: {} + emoji-regex@10.4.0: {} + emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -11631,6 +11766,8 @@ snapshots: eol@0.9.1: {} + error-stack-parser-es@1.0.5: {} + es-abstract@1.23.5: dependencies: array-buffer-byte-length: 1.0.1 @@ -11722,6 +11859,13 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + es-shim-unscopables@1.0.2: dependencies: hasown: 2.0.2 @@ -11990,6 +12134,8 @@ snapshots: etag@1.8.1: {} + event-target-shim@5.0.1: {} + events@3.3.0: {} execa@5.1.1: @@ -12087,10 +12233,6 @@ snapshots: dependencies: reusify: 1.0.4 - fdir@6.4.3(picomatch@4.0.2): - optionalDependencies: - picomatch: 4.0.2 - fdir@6.4.6(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 @@ -12117,7 +12259,7 @@ snapshots: finalhandler@2.1.0: dependencies: - debug: 4.4.0 + debug: 4.4.1 encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 @@ -12154,6 +12296,21 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + form-data-encoder@1.7.2: {} + + form-data@4.0.4: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + + formdata-node@4.4.1: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 4.0.0-beta.3 + forwarded@0.2.0: {} fraction.js@4.3.7: {} @@ -12200,6 +12357,8 @@ snapshots: get-caller-file@2.0.5: {} + get-east-asian-width@1.3.0: {} + get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 @@ -12228,11 +12387,6 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 - get-source@2.0.12: - dependencies: - data-uri-to-buffer: 2.0.2 - source-map: 0.6.1 - get-stdin@9.0.0: {} get-stream@6.0.1: {} @@ -12404,6 +12558,10 @@ snapshots: human-signals@2.1.0: {} + humanize-ms@1.2.1: + dependencies: + ms: 2.1.3 + husky@9.1.7: {} hyphenate-style-name@1.1.0: {} @@ -12745,6 +12903,8 @@ snapshots: kind-of@6.0.3: {} + kleur@4.1.5: {} + language-subtag-registry@0.3.23: {} language-tags@1.0.9: @@ -12866,7 +13026,7 @@ snapshots: mimic-fn@2.1.0: {} - miniflare@4.20250617.3: + miniflare@4.20250712.2: dependencies: '@cspotcode/source-map-support': 0.8.1 acorn: 8.14.0 @@ -12875,10 +13035,10 @@ snapshots: glob-to-regexp: 0.4.1 sharp: 0.33.5 stoppable: 1.1.0 - undici: 5.29.0 - workerd: 1.20250617.0 + undici: 7.12.0 + workerd: 1.20250712.0 ws: 8.18.0 - youch: 3.3.4 + youch: 4.1.0-beta.10 zod: 3.22.3 transitivePeerDependencies: - bufferutil @@ -12924,8 +13084,6 @@ snapshots: ms@2.1.3: {} - mustache@4.2.0: {} - mz@2.7.0: dependencies: any-promise: 1.3.0 @@ -12967,6 +13125,8 @@ snapshots: - '@babel/core' - babel-plugin-macros + node-domexception@1.0.0: {} + node-env-run@4.0.2: dependencies: '@types/common-tags': 1.8.4 @@ -13288,8 +13448,6 @@ snapshots: pretty-hrtime@1.0.3: {} - printable-characters@1.0.42: {} - process-nextick-args@2.0.1: {} prop-types@15.8.1: @@ -13619,7 +13777,7 @@ snapshots: send@1.1.0: dependencies: - debug: 4.4.0 + debug: 4.4.1 destroy: 1.2.0 encodeurl: 2.0.0 escape-html: 1.0.3 @@ -13806,11 +13964,6 @@ snapshots: stackback@0.0.2: {} - stacktracey@2.1.8: - dependencies: - as-table: 1.0.55 - get-source: 2.0.12 - statuses@2.0.1: {} std-env@3.9.0: {} @@ -13843,6 +13996,12 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.1.0 + string-width@7.2.0: + dependencies: + emoji-regex: 10.4.0 + get-east-asian-width: 1.3.0 + strip-ansi: 7.1.0 + string.prototype.includes@2.0.1: dependencies: call-bind: 1.0.7 @@ -13951,6 +14110,8 @@ snapshots: pirates: 4.0.6 ts-interface-checker: 0.1.13 + supports-color@10.0.0: {} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -14018,7 +14179,7 @@ snapshots: terser@5.16.9: dependencies: - '@jridgewell/source-map': 0.3.6 + '@jridgewell/source-map': 0.3.10 acorn: 8.15.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -14207,11 +14368,11 @@ snapshots: has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 + undici-types@5.26.5: {} + undici-types@6.21.0: {} - undici@5.29.0: - dependencies: - '@fastify/busboy': 2.1.1 + undici@7.12.0: {} unenv@2.0.0-rc.17: dependencies: @@ -14415,6 +14576,8 @@ snapshots: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 + web-streams-polyfill@4.0.0-beta.3: {} + web-vitals@4.2.4: {} webidl-conversions@3.0.1: {} @@ -14725,24 +14888,24 @@ snapshots: '@types/trusted-types': 2.0.7 workbox-core: 7.1.0 - workerd@1.20250617.0: + workerd@1.20250712.0: optionalDependencies: - '@cloudflare/workerd-darwin-64': 1.20250617.0 - '@cloudflare/workerd-darwin-arm64': 1.20250617.0 - '@cloudflare/workerd-linux-64': 1.20250617.0 - '@cloudflare/workerd-linux-arm64': 1.20250617.0 - '@cloudflare/workerd-windows-64': 1.20250617.0 + '@cloudflare/workerd-darwin-64': 1.20250712.0 + '@cloudflare/workerd-darwin-arm64': 1.20250712.0 + '@cloudflare/workerd-linux-64': 1.20250712.0 + '@cloudflare/workerd-linux-arm64': 1.20250712.0 + '@cloudflare/workerd-windows-64': 1.20250712.0 - wrangler@4.21.0: + wrangler@4.26.0: dependencies: '@cloudflare/kv-asset-handler': 0.4.0 - '@cloudflare/unenv-preset': 2.3.3(unenv@2.0.0-rc.17)(workerd@1.20250617.0) + '@cloudflare/unenv-preset': 2.4.1(unenv@2.0.0-rc.17)(workerd@1.20250712.0) blake3-wasm: 2.1.5 esbuild: 0.25.4 - miniflare: 4.20250617.3 + miniflare: 4.20250712.2 path-to-regexp: 6.3.0 unenv: 2.0.0-rc.17 - workerd: 1.20250617.0 + workerd: 1.20250712.0 optionalDependencies: fsevents: 2.3.3 transitivePeerDependencies: @@ -14767,6 +14930,12 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.0 + wrap-ansi@9.0.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 7.2.0 + strip-ansi: 7.1.0 + wrappy@1.0.2: {} ws@7.5.10: {} @@ -14798,6 +14967,8 @@ snapshots: yargs-parser@21.1.1: {} + yargs-parser@22.0.0: {} + yargs@15.4.1: dependencies: cliui: 6.0.0 @@ -14822,16 +14993,32 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 + yargs@18.0.0: + dependencies: + cliui: 9.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + string-width: 7.2.0 + y18n: 5.0.8 + yargs-parser: 22.0.0 + yn@3.1.1: optional: true yocto-queue@0.1.0: {} - youch@3.3.4: + youch-core@0.3.3: dependencies: - cookie: 0.7.1 - mustache: 4.2.0 - stacktracey: 2.1.8 + '@poppinss/exception': 1.2.2 + error-stack-parser-es: 1.0.5 + + youch@4.1.0-beta.10: + dependencies: + '@poppinss/colors': 4.1.5 + '@poppinss/dumper': 0.6.4 + '@speed-highlight/core': 1.2.7 + cookie: 1.0.2 + youch-core: 0.3.3 zod@3.22.3: {}