diff --git a/next.config.mjs b/next.config.mjs index 4678774..12d8a12 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,4 +1,11 @@ +import './src/envVars.js'; + /** @type {import('next').NextConfig} */ -const nextConfig = {}; +const nextConfig = { + reactStrictMode: true, + swcMinify: true, + output: 'standalone', // for Docker + trailingSlash: false, +}; export default nextConfig; diff --git a/package.json b/package.json index 1ace801..6905afe 100644 --- a/package.json +++ b/package.json @@ -16,20 +16,25 @@ ], "scripts": { "dev": "next dev", - "build": "NODE_ENV=production next build", + "build": "NODE_ENV=production next build && npm run copy:assets", + "comment": "TODO_DEPLOYMENT - serve assets from CDN instead", + "copy:assets": "cp -rn public .next/standalone && cp -rn .next/static .next/standalone/.next/static", "test": "echo 'No tests added yet' && exit 0", - "start": "next start", + "start": "node .next/standalone/server.js", "lint": "next lint" }, "dependencies": { + "@stripe/react-stripe-js": "^2.8.1", "fuse.js": "^7.0.0", "next": "14.2.11", - "printify-sdk-js": "^1.0.1", + "printify-sdk-js": "1.0.2", "react": "^18", "react-dom": "^18", - "sharp": "^0.33.5", + "sharp": "0.32.6", "stripe": "^16.9.0", - "use-shopping-cart": "^3.2.0" + "use-shopping-cart": "^3.2.0", + "winston": "^3.15.0", + "zod": "^3.23.8" }, "devDependencies": { "@types/node": "^20", diff --git a/src/app/api/v1/checkout/route.ts b/src/app/api/v1/checkout/route.ts index dd92414..d49e5ac 100644 --- a/src/app/api/v1/checkout/route.ts +++ b/src/app/api/v1/checkout/route.ts @@ -1,98 +1,28 @@ -import logger from '@/lib/logger'; -import { createDraftOrder } from '@/lib/printify'; +import { NextResponse } from 'next/server'; import { createCheckoutSession } from '@/lib/stripe'; import { UserError } from '@/utils/errors'; +import logger from '@/lib/logger'; +import { retrieveShippingCost } from '@/lib/printify'; import validateCartItems from '@/utils/validateCartItems'; -import { NextRequest, NextResponse } from 'next/server'; -/** - * @openapi - * /v1/checkout: - * post: - * summary: Creates a Stripe checkout session. - * tags: - * - Checkout - * requestBody: - * required: true - * content: - * application/json: - * schema: - * type: object - * properties: - * cartItems: - * type: array - * items: - * type: object - * properties: - * id: - * type: string - * name: - * type: string - * description: - * type: string - * quantity: - * type: integer - * price: - * type: number - * image: - * type: string - * currency: - * type: string - * price_data: - * type: object - * product_data: - * type: object - * properties: - * size: - * type: string - * productId: - * type: string - * category: - * type: string - * type: string - * responses: - * 200: - * description: Checkout session created successfully. - * content: - * application/json: - * schema: - * type: object - * properties: - * checkoutUrl: - * type: string - * 400: - * description: Error creating checkout session. - * content: - * application/json: - * schema: - * type: object - * properties: - * message: - * type: string - */ -export const POST = async (request: NextRequest) => { +export async function POST(request: Request) { const correlationId = request.headers.get('x-correlation-id'); try { - logger.info('[Checkout] Processing checkout request', { correlationId }); - const body = await request.json(); const { cartItems: clientCartItems } = body; logger.info('[Checkout] Validating cart items', { correlationId }); const cartItems = validateCartItems(clientCartItems); - // TODO_PRINTIFY (move this to final webhook) - logger.info('[Printify] Creating Printify draft order', { correlationId }); - const { id: printifyOrderId } = await createDraftOrder(cartItems); - - // TODO_PRINTIFY (calulateShipping()) + logger.info('[Printify] calculating shipping methods', { correlationId }); + const shippingMethods = await retrieveShippingCost(); - logger.info('[Stripe] Creating checkout session', { correlationId, printifyOrderId }); - const session = await createCheckoutSession(cartItems, { printifyOrderId }); + const swagOrderId = crypto.randomUUID(); + logger.info('[Stripe] Creating checkout session', { correlationId, swagOrderId }); + const session = await createCheckoutSession(cartItems, shippingMethods, { swagOrderId }); - logger.info('[Checkout] Checkout session created successfully', { checkoutUrl: session.url, correlationId, printifyOrderId, sessionId: session.id }); - return NextResponse.json({ checkoutUrl: session.url }); + return NextResponse.json({ id: session.id, client_secret: session.client_secret }); } catch (error) { if (error instanceof UserError) { return NextResponse.json({ error: error.message }, { status: 400 }); @@ -101,4 +31,4 @@ export const POST = async (request: NextRequest) => { logger.error('[Checkout] Error processing checkout request', { error }); return NextResponse.json({ error: 'Internal server error' }, { status: 500 }); } -}; +} diff --git a/src/app/api/v1/webhook/checkout/route.ts b/src/app/api/v1/webhook/checkout/route.ts index 9a6defa..8bb0ee8 100644 --- a/src/app/api/v1/webhook/checkout/route.ts +++ b/src/app/api/v1/webhook/checkout/route.ts @@ -1,24 +1,14 @@ import type { Stripe as StripeType } from 'stripe'; -import { retrieveCheckoutSession, stripe } from '@/lib/stripe'; +import { stripe } from '@/lib/stripe'; import { NextRequest, NextResponse } from 'next/server'; -import { sendOrderToProduction } from '@/lib/printify'; import logger from '@/lib/logger'; +import { createDraftOrder } from '@/lib/printify'; export const POST = async (request: NextRequest) => { - const correlationId = request.headers.get('x-correlation-id'); - try { - logger.info('[Stripe Webhook] Processing Stripe webhook request'); - - const secret = process.env.STRIPE_WEBHOOK_SECRET || ''; - if (!secret) { - logger.error('[Stripe Webhook] Missing STRIPE_WEBHOOK_SECRET environment variable'); - throw new Error('Missing STRIPE_WEBHOOK_SECRET environment variable'); - } - const body = await (await request.blob()).text(); const signature = request.headers.get('stripe-signature') as string; - const event: StripeType.Event = stripe.webhooks.constructEvent(body, signature, secret); + const event: StripeType.Event = stripe.webhooks.constructEvent(body, signature, process.env.STRIPE_WEBHOOK_SECRET as string); const permittedEvents: string[] = ['checkout.session.completed', 'payment_intent.succeeded', 'payment_intent.payment_failed']; if (permittedEvents.includes(event.type)) { @@ -27,45 +17,49 @@ export const POST = async (request: NextRequest) => { switch (event.type) { case 'checkout.session.completed': data = event.data.object as StripeType.Checkout.Session; + logger.info('[Stripe Webhook] Checkout succeeded', { eventType: event.type, sessionId: data.id, eventId: event.id }); - const printifyOrderId = event.data.object?.metadata?.printifyOrderId; - if (!printifyOrderId) { - logger.warn(`[Stripe Webhook] Missing printifyOrderId in metadata for session ${data.id}. Unable to fullfil order`, { sessionId: data.id, correlationId }); - throw new Error(`missing printifyOrderId on metadata, ${data.id}`); - } + logger.info('[Stripe Webhook] Retrieving line_items', { sessionId: data.id }); + const line_items = await stripe.checkout.sessions.listLineItems(data.id, { + expand: ['data.price.product'], + }); + const email = data?.customer_details?.email || ''; + const phone = data?.customer_details?.phone || ''; - logger.info('[Stripe Webhook] Verifying payment status for Checkout Session', { sessionId: data.id, correlationId }); - const checkoutSession = await retrieveCheckoutSession(data.id); - if (checkoutSession.payment_status === 'unpaid') { - logger.warn('[Stripe Webhook] Cannot fulfill an unpaid order', { sessionId: data.id, correlationId }); - return NextResponse.json({ message: 'Cannot fullfil an unpaid order' }, { status: 400 }); + const swagOrderId = data.metadata?.swagOrderId; + if (!swagOrderId) { + logger.warn(`[Stripe Webhook] Missing swagOrderId in metadata for session ${data.id}. Unable to fullfil order`, { sessionId: data.id, eventId: event.id }); + throw new Error(`missing swagOrderId on metadata, ${data.id}`); } - logger.info('[Printify] Sending order to production', { sessionId: data.id, correlationId, printifyOrderId }); - await sendOrderToProduction(printifyOrderId); + logger.info('[Printify] Creating Printify draft order'); + const { id: printifyOrderId } = await createDraftOrder(line_items.data, data.shipping_details, swagOrderId, data.id, email, phone); - logger.info('[Stripe Webhook] Successfully fulfilled order', { sessionId: data.id, correlationId, printifyOrderId }); - return NextResponse.json({ result: event, ok: true }); + await new Promise(r => setTimeout(r, 3000)); + + // TODO_PRINTIFY - validate publish endpoint! - curl request always works.. + logger.info('[Printify] Fullfilling order', { eventType: event.type, sessionId: data.id, printifyOrderId, eventId: event.id }); + // await sendOrderToProduction(printifyOrderId); + break; case 'payment_intent.payment_failed': data = event.data.object as StripeType.PaymentIntent; - logger.error('[Stripe Webhook] Payment failed', { message: data.last_payment_error?.message, sessionId: data.id }); + logger.error('[Stripe Webhook] Payment failed', { message: data.last_payment_error?.message, eventType: event.type, sessionId: data.id, eventId: event.id }); break; case 'payment_intent.succeeded': data = event.data.object as StripeType.PaymentIntent; - logger.info('[Stripe Webhook] PaymentIntent succeeded', { status: data.status, sessionId: data.id }); + logger.info('[Stripe Webhook] PaymentIntent succeeded', { eventType: event.type, status: data.status, sessionId: data.id, eventId: event.id }); break; default: + // fallback, not used data = (event.data.object as unknown) || {}; - // @ts-expect-error - ignore "Property 'id' does not exist on type '{}'.ts(2339)" - logger.warn('[Stripe Webhook] Unhandled event type', { eventType: event.type, sessionId: data?.id }); return NextResponse.json({ result: event, ok: true }); } } - logger.info('[Stripe Webhook] Webhook processing complete', { eventId: event.id }); + logger.info('[Stripe Webhook] Processed request', { eventType: event.type }); return NextResponse.json({ result: event, ok: true }); } catch (error) { logger.error('[Stripe Webhook] Error processing webhook request', { error }); diff --git a/src/app/cart/page.tsx b/src/app/cart/page.tsx index e2fa624..53bf47d 100644 --- a/src/app/cart/page.tsx +++ b/src/app/cart/page.tsx @@ -1,15 +1,20 @@ 'use client'; +import React, { useState } from 'react'; +import { loadStripe } from '@stripe/stripe-js'; +import { EmbeddedCheckoutProvider, EmbeddedCheckout } from '@stripe/react-stripe-js'; import CartItemCard from '@/components/CartItemCard'; import formatPriceForDisplay from '@/utils/formatPriceForDisplay'; import { useShoppingCart } from 'use-shopping-cart'; import { CartItem } from '@/types'; -import CheckoutButton from '@/components/CheckoutBtn'; export default function CartPage() { const { cartCount, cartDetails, removeItem, totalPrice, addItem, decrementItem } = useShoppingCart(); const cartItems = Object.values(cartDetails ?? {}); + const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_KEY!); + const [showCheckout, setShowCheckout] = useState(false); + const handleRemove = (cartItem: CartItem) => { if (cartItem.quantity === 1) { removeItem(cartItem.id); @@ -18,12 +23,42 @@ export default function CartPage() { } }; + const fetchClientSecret = () => { + return fetch('/api/v1/checkout', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ cartItems }), + }) + .then(res => res.json()) + .then(data => data.client_secret); + }; + + const options = { fetchClientSecret }; + + const handleCheckoutClick = () => { + setShowCheckout(true); + }; + + if (showCheckout) { + return ( +
+ + + +
+ ); + } + const subtotal = formatPriceForDisplay(totalPrice); return (
Subtotal: {subtotal} - +
{!cartItems || diff --git a/src/app/order-confirmation/page.tsx b/src/app/order-confirmation/page.tsx index 4c64e6f..c0e44f5 100644 --- a/src/app/order-confirmation/page.tsx +++ b/src/app/order-confirmation/page.tsx @@ -1,20 +1,38 @@ -import { memo } from 'react'; import OrderConfirmation from '@/components/OrderConfirmation'; -import { validateStripeSession } from '@/lib/stripe'; +import { stripe } from '@/lib/stripe'; import { notFound } from 'next/navigation'; +async function getSession(sessionId: string) { + try { + const session = await stripe.checkout.sessions.retrieve(sessionId!); + return session; + } catch (error) { + return null; + } +} + // Redirect page after successful checkout // /order-confirmation?session_id=cs_test_b1FKoQomBOaQFgMqW1lU6oYXRwIruD6AbGV804gMZRrptJr1bF91sDmK5T const OrderConfirmationPage: React.FC<{ searchParams: { [key: string]: string | undefined } }> = async ({ searchParams }) => { const sessionId = searchParams['session_id']; - const { validSession } = await validateStripeSession(sessionId); - if (!validSession) return notFound(); + if (!sessionId) return notFound(); + + const session = await getSession(sessionId); + if (!session) return notFound(); + + if (session?.status === 'open') { + return

Payment did not work.

; + } + + if (session?.status === 'complete') { + return ( +
+ +
+ ); + } - return ( -
- -
- ); + return notFound(); }; -export default memo(OrderConfirmationPage); +export default OrderConfirmationPage; diff --git a/src/components/CheckoutBtn.tsx b/src/components/CheckoutBtn.tsx deleted file mode 100644 index 116500a..0000000 --- a/src/components/CheckoutBtn.tsx +++ /dev/null @@ -1,46 +0,0 @@ -'use client'; - -import { useRouter } from 'next/navigation'; -import { useRef, useState } from 'react'; -import { CartEntry } from 'use-shopping-cart/core'; - -const CheckoutButton: React.FC<{ cartCount?: number; cartItems: CartEntry[] }> = ({ cartCount, cartItems }) => { - const router = useRouter(); - const isProcessing = useRef(false); - const [error, setError] = useState(''); - - const handleCheckoutClick = async () => { - if (!cartCount || cartCount === 0 || isProcessing.current) { - return; - } - - isProcessing.current = true; - - try { - const res = await fetch('/api/v1/checkout', { - method: 'POST', - body: JSON.stringify({ cartItems }), - }); - - const { checkoutUrl } = await res.json(); - if (!checkoutUrl) { - setError('Unable to checkout at this time. Please try again later.'); - return; - } - router.push(checkoutUrl); - } catch (err) { - console.error('Checkout request threw an error', err, error); - setError('An error occurred during checkout. Please try again later.'); - } finally { - isProcessing.current = false; - } - }; - - return ( - - ); -}; - -export default CheckoutButton; diff --git a/src/envVars.js b/src/envVars.js new file mode 100644 index 0000000..66d58f9 --- /dev/null +++ b/src/envVars.js @@ -0,0 +1,16 @@ +/* eslint @typescript-eslint/no-var-requires: 0 */ +const { z } = require('zod'); + +const EnvVars = z.object({ + NEXT_PUBLIC_URL: z.string(), + NEXT_PUBLIC_STRIPE_KEY: z.string(), + STRIPE_SECRET_KEY: z.string(), + STRIPE_WEBHOOK_SECRET: z.string(), + PRINTIFY_API_TOKEN: z.string(), + PRINTIFY_SHOP_ID: z.string(), +}); + +const secrets = EnvVars.parse(process.env); +console.log('Validated .env secrets'); + +module.exports.config = secrets; diff --git a/src/lib/printify.ts b/src/lib/printify.ts index e7776cd..979e9f6 100644 --- a/src/lib/printify.ts +++ b/src/lib/printify.ts @@ -1,6 +1,7 @@ import Printify from 'printify-sdk-js'; -import { retrieveStickerPNGFileUrl, STICKER_SIZES } from '@/lib/products'; -import { CartItem, PrintifyLineItem, SubmitOrderData } from '@/types'; +import { PRODUCT_CONFIG, retrieveStickerPNGFileUrl, STICKER_SIZES } from '@/lib/products'; +import { PrintifyLineItem, PrintifyShippingProfile, StripeShippingDetails, SubmitOrderData, VariantShippingData } from '@/types'; +import type { Stripe as StripeType } from 'stripe'; import logger from './logger'; // docs: https://developers.printify.com/ @@ -21,55 +22,88 @@ const PRINTIFY_VARIANT_IDS = { [STICKER_SIZES.FOUR_BY_FOUR_IN]: 95745, }; -export const formatCartItemsForPrintify = (cartItems: CartItem[]): PrintifyLineItem[] => { - return cartItems.map(cartItem => ({ +// export const formatCartItemsForPrintify = (cartItems: CartItem[]): PrintifyLineItem[] => { +// return cartItems.map(cartItem => ({ +// print_provider_id: PRINTIFY_PRINT_PROVIDER_ID, +// blueprint_id: PRINTIFY_BLUEPRINT_ID, +// variant_id: PRINTIFY_VARIANT_IDS[cartItem.product_data.size], +// print_areas: { +// front: retrieveStickerPNGFileUrl(cartItem.product_data.productId), +// }, +// quantity: cartItem.quantity, +// })); +// }; + +export const formatCartItemsForPrintify = (lineItems: StripeType.LineItem[]): PrintifyLineItem[] => { + return lineItems.map(item => ({ print_provider_id: PRINTIFY_PRINT_PROVIDER_ID, blueprint_id: PRINTIFY_BLUEPRINT_ID, - variant_id: PRINTIFY_VARIANT_IDS[cartItem.product_data.size], + // @ts-expect-error - metadata is valid, hard to find stripe type tho + variant_id: PRINTIFY_VARIANT_IDS[item.price?.product?.metadata?.size], print_areas: { - front: retrieveStickerPNGFileUrl(cartItem.product_data.productId), + // @ts-expect-error - metadata is valid, hard to find stripe type tho + front: retrieveStickerPNGFileUrl(item.price?.product?.metadata?.productId), }, - quantity: cartItem.quantity, + quantity: item.quantity || 1, })); }; -export async function createDraftOrder(cartItems: CartItem[]): Promise<{ id: string }> { - logger.info('[Printify] Formatting cart items for Printify'); - const printifyLineItems: PrintifyLineItem[] = formatCartItemsForPrintify(cartItems); - - const randomId = crypto.randomUUID(); - const randomLabel = Math.floor(Math.random() * 100000) - .toString() - .padStart(5, '0'); +const formatStripeAddress = (stripeAddress: StripeShippingDetails, email: string | null, phone: string | null) => ({ + first_name: stripeAddress.name.split(' ')[0], + last_name: stripeAddress.name.split(' ')[1], + email: email || 'placeholder@gmail.com', + phone: phone || '0574 69 21 90', + country: stripeAddress.address.country, + region: stripeAddress.address.state, + // state: stripeAddress.address.state, // Printify is European startup, they don't use "state" + address1: stripeAddress.address.line1, + address2: stripeAddress.address.line2, + city: stripeAddress.address.city, + zip: stripeAddress.address.postal_code, +}); +export async function createDraftOrder( + cartItems: StripeType.LineItem[], + stripeShippingDetails: StripeType.Checkout.Session.ShippingDetails | null, + swagOrderId: string, + stripeSessionId: string, + email: string | null, + phone: string | null +): Promise<{ id: string }> { + const printifyLineItems: PrintifyLineItem[] = formatCartItemsForPrintify(cartItems); + console.log(printifyLineItems); + const address = formatStripeAddress(stripeShippingDetails as StripeShippingDetails, email, phone); const orderData: SubmitOrderData = { - external_id: randomId, - label: `shipment_${randomLabel}`, - // TODO_PRINTIFY (pull/format from stripe) + external_id: stripeSessionId, + label: `swagOrderId_${swagOrderId}`, line_items: printifyLineItems, shipping_method: 1, is_printify_express: false, is_economy_shipping: false, - send_shipping_notification: false, - // TODO_PRINTIFY (pull address from stripe) - address_to: { - first_name: 'John', - last_name: 'Doe', - email: 'testing@beta.com', - phone: '0574 69 21 90', - country: 'BE', - region: '', - address1: 'ExampleBaan 121', - address2: '45', - city: 'Retie', - zip: '2470', - }, + send_shipping_notification: true, + address_to: address, }; const order = await printify.orders.submit(orderData); return order; } +export async function retrieveShippingCost(): Promise { + logger.info('[Printify] retrieving shipping options'); + const shipping: VariantShippingData = await printify.catalog.getVariantShipping(PRINTIFY_BLUEPRINT_ID.toString(), PRINTIFY_PRINT_PROVIDER_ID.toString()); + + const fallbackShippingOptions = { + variant_ids: [95743, 95744, 95745, 95746], + first_item: { cost: 509, currency: 'USD' }, + additional_items: { cost: 9, currency: 'USD' }, + countries: ['US'], + }; + + // US-only + // 1 option, "Standard" only + return shipping.profiles.find(profile => profile.countries.includes(PRODUCT_CONFIG.allowCountries[0])) || fallbackShippingOptions; +} + export async function sendOrderToProduction(printifyOrderId: string) { logger.info('[Printify] Sending order to production', { printifyOrderId }); await printify.orders.sendToProduction(printifyOrderId); diff --git a/src/lib/products.ts b/src/lib/products.ts index 7b90106..2bac911 100644 --- a/src/lib/products.ts +++ b/src/lib/products.ts @@ -7,6 +7,7 @@ export const STICKER_SIZES = { }; export const PRODUCT_CONFIG = { + // US-only language: 'en-US', allowCountries: ['US'], // e.g. ['US', 'GB', 'CA']; currency: 'USD', diff --git a/src/lib/stripe.ts b/src/lib/stripe.ts index 0e6402c..61ad13a 100644 --- a/src/lib/stripe.ts +++ b/src/lib/stripe.ts @@ -1,8 +1,7 @@ import Stripe from 'stripe'; import { PRODUCT_CONFIG } from '@/lib/products'; -import { CartItem } from '@/types'; +import { CartItem, PrintifyShippingProfile, StripeShippingMethod } from '@/types'; import logger from './logger'; -import { UserError } from '@/utils/errors'; // docs: https://docs.stripe.com // keys: https://dashboard.stripe.com/apikeys @@ -22,8 +21,9 @@ export const formatCartItemsForStripe = (cartItems: CartItem[]): Stripe.Checkout currency: cartItem.currency, product_data: { name: cartItem.name, - description: cartItem.description, - images: [`${process.env.NEXT_PUBLIC_URL}${cartItem.image}`], // up to 8 images + description: 'cartItem.description', // cartItem.description, + // images: [`${process.env.NEXT_PUBLIC_URL}${cartItem.image}`], // up to 8 images + images: [`https://swagsticker.com${cartItem.image}`], // up to 8 images metadata: { // pass metadata to stripe, (productId, size, category, ...) ...(cartItem.product_data || {}), @@ -42,101 +42,59 @@ export const formatCartItemsForStripe = (cartItems: CartItem[]): Stripe.Checkout }); }; +const calculateStripeShipping = (cartItemCount: number, shippingMethod: PrintifyShippingProfile): StripeShippingMethod => { + const additionalItemCount = cartItemCount - 1; + const totalShippingCost = shippingMethod.first_item.cost + additionalItemCount * shippingMethod.additional_items.cost; + + return { + shipping_rate_data: { + type: 'fixed_amount', + fixed_amount: { + amount: totalShippingCost, + currency: shippingMethod.first_item.currency, + }, + display_name: `Shipping to US (Standard)`, + delivery_estimate: { + minimum: { + unit: 'business_day', + value: 2, // hard-coded, based on website (could pull from shippingMethod.handling_time) + }, + maximum: { + unit: 'business_day', + value: 5, // hard-coded, based on website (could pull from shippingMethod.handling_time) + }, + }, + }, + }; +}; + // docs: https://docs.stripe.com/api/checkout/sessions/create -export async function createCheckoutSession(cartItems: CartItem[], metadata: { [key: string]: string } = {}): Promise> { +export async function createCheckoutSession( + cartItems: CartItem[], + shippingMethod: PrintifyShippingProfile, + metadata: { [key: string]: string } = {} +): Promise> { + logger.info('[Stripe] Formatting shipping methods for Stripe'); + const stripeShippingMethod: StripeShippingMethod = calculateStripeShipping(cartItems.length, shippingMethod); + logger.info('[Stripe] Formatting cart items for Stripe'); const stripeLineItems: Stripe.Checkout.SessionCreateParams.LineItem[] = formatCartItemsForStripe(cartItems); - const session = await stripe.checkout.sessions.create({ + ui_mode: 'embedded', + payment_method_types: ['card'], line_items: stripeLineItems, metadata: metadata, mode: 'payment', - success_url: `${process.env.NEXT_PUBLIC_URL}/order-confirmation?session_id={CHECKOUT_SESSION_ID}`, - cancel_url: `${process.env.NEXT_PUBLIC_URL}/cart`, - // customer: 'customerId', - // customer_email: 'customer@gmail.com', + return_url: `${process.env.NEXT_PUBLIC_URL}/order-confirmation?session_id={CHECKOUT_SESSION_ID}`, shipping_address_collection: { + // US-only allowed_countries: PRODUCT_CONFIG.allowCountries as Stripe.Checkout.SessionCreateParams.ShippingAddressCollection.AllowedCountry[], }, - // TODO_PRINTIFY - calculate this dynamically with Printify request + USD 0.09 per item! - shipping_options: [ - { - shipping_rate_data: { - type: 'fixed_amount', - fixed_amount: { - amount: 459, - currency: PRODUCT_CONFIG.currency, - }, - display_name: 'Standard', - delivery_estimate: { - minimum: { - unit: 'business_day', - value: 2, - }, - maximum: { - unit: 'business_day', - value: 5, - }, - }, - }, - }, - // { - // shipping_rate_data: { - // type: 'fixed_amount', - // fixed_amount: { - // amount: 429, - // currency: 'usd', - // }, - // display_name: 'Economy', - // delivery_estimate: { - // minimum: { - // unit: 'business_day', - // value: 4, - // }, - // maximum: { - // unit: 'business_day', - // value: 8, - // }, - // }, - // }, - // }, - ], - automatic_tax: { - enabled: true, // Enable tax based on location - }, - }); - - if (!session || !session.url) { - logger.error('[Stripe] Error creating checkout session', { session }); - throw new UserError('Unable to process checkout request'); - } - - return session; -} - -export async function retrieveCheckoutSession(sessionId: string) { - const session = await stripe.checkout.sessions.retrieve(sessionId, { - expand: ['line_items'], + shipping_options: [stripeShippingMethod], + automatic_tax: { enabled: true }, + // customer: 'customerId', + // customer_email: 'customer@gmail.com', }); - if (!session) { - logger.error('[Stripe] Failed to process stripe checkout session'); - throw new UserError('Unable to process stripe checkout session'); - } - return session; } - -export async function validateStripeSession(sessionId?: string) { - if (!sessionId) return { validSession: false }; - - try { - const session = await retrieveCheckoutSession(sessionId); - - if (session.object !== 'checkout.session') return { validSession: false }; - - return { validSession: true }; - } catch (error) { - return { validSession: false }; - } -} diff --git a/src/types/index.ts b/src/types/index.ts index 417f9db..02e2452 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -100,3 +100,55 @@ export interface SubmitOrderData { send_shipping_notification: boolean; address_to: PrintifyAddress; } + +export interface PrintifyShippingProfile { + variant_ids: number[]; + first_item: { + cost: number; + currency: string; + }; + additional_items: { + cost: number; + currency: string; + }; + countries: string[]; +} + +export interface VariantShippingData { + profiles: PrintifyShippingProfile[]; +} + +export interface StripeShippingMethod { + shipping_rate_data: { + type: 'fixed_amount'; + fixed_amount: { + amount: number; + currency: string; // Assuming PRODUCT_CONFIG.currency is of type string + }; + display_name: string; + delivery_estimate: { + minimum: { + unit: 'business_day'; // You could also make this a union type if there are other units + value: number; + }; + maximum: { + unit: 'business_day'; // Same as above + value: number; + }; + }; + }; +} + +interface Address { + city: string; + country: string; + line1: string; + line2?: string; + postal_code: string; + state: string; +} + +export interface StripeShippingDetails { + address: Address; + name: string; +} diff --git a/yarn.lock b/yarn.lock index a698718..9df6068 100644 --- a/yarn.lock +++ b/yarn.lock @@ -51,13 +51,6 @@ enabled "2.0.x" kuler "^2.0.0" -"@emnapi/runtime@^1.2.0": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.3.1.tgz#0fcaa575afc31f455fd33534c19381cfce6c6f60" - integrity sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw== - dependencies: - tslib "^2.4.0" - "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" @@ -109,119 +102,6 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== -"@img/sharp-darwin-arm64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz#ef5b5a07862805f1e8145a377c8ba6e98813ca08" - integrity sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ== - optionalDependencies: - "@img/sharp-libvips-darwin-arm64" "1.0.4" - -"@img/sharp-darwin-x64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz#e03d3451cd9e664faa72948cc70a403ea4063d61" - integrity sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q== - optionalDependencies: - "@img/sharp-libvips-darwin-x64" "1.0.4" - -"@img/sharp-libvips-darwin-arm64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz#447c5026700c01a993c7804eb8af5f6e9868c07f" - integrity sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg== - -"@img/sharp-libvips-darwin-x64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz#e0456f8f7c623f9dbfbdc77383caa72281d86062" - integrity sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ== - -"@img/sharp-libvips-linux-arm64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz#979b1c66c9a91f7ff2893556ef267f90ebe51704" - integrity sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA== - -"@img/sharp-libvips-linux-arm@1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz#99f922d4e15216ec205dcb6891b721bfd2884197" - integrity sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g== - -"@img/sharp-libvips-linux-s390x@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz#f8a5eb1f374a082f72b3f45e2fb25b8118a8a5ce" - integrity sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA== - -"@img/sharp-libvips-linux-x64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz#d4c4619cdd157774906e15770ee119931c7ef5e0" - integrity sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw== - -"@img/sharp-libvips-linuxmusl-arm64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz#166778da0f48dd2bded1fa3033cee6b588f0d5d5" - integrity sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA== - -"@img/sharp-libvips-linuxmusl-x64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz#93794e4d7720b077fcad3e02982f2f1c246751ff" - integrity sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw== - -"@img/sharp-linux-arm64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz#edb0697e7a8279c9fc829a60fc35644c4839bb22" - integrity sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA== - optionalDependencies: - "@img/sharp-libvips-linux-arm64" "1.0.4" - -"@img/sharp-linux-arm@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz#422c1a352e7b5832842577dc51602bcd5b6f5eff" - integrity sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ== - optionalDependencies: - "@img/sharp-libvips-linux-arm" "1.0.5" - -"@img/sharp-linux-s390x@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz#f5c077926b48e97e4a04d004dfaf175972059667" - integrity sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q== - optionalDependencies: - "@img/sharp-libvips-linux-s390x" "1.0.4" - -"@img/sharp-linux-x64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz#d806e0afd71ae6775cc87f0da8f2d03a7c2209cb" - integrity sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA== - optionalDependencies: - "@img/sharp-libvips-linux-x64" "1.0.4" - -"@img/sharp-linuxmusl-arm64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz#252975b915894fb315af5deea174651e208d3d6b" - integrity sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g== - optionalDependencies: - "@img/sharp-libvips-linuxmusl-arm64" "1.0.4" - -"@img/sharp-linuxmusl-x64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz#3f4609ac5d8ef8ec7dadee80b560961a60fd4f48" - integrity sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw== - optionalDependencies: - "@img/sharp-libvips-linuxmusl-x64" "1.0.4" - -"@img/sharp-wasm32@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz#6f44f3283069d935bb5ca5813153572f3e6f61a1" - integrity sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg== - dependencies: - "@emnapi/runtime" "^1.2.0" - -"@img/sharp-win32-ia32@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz#1a0c839a40c5351e9885628c85f2e5dfd02b52a9" - integrity sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ== - -"@img/sharp-win32-x64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz#56f00962ff0c4e0eb93d34a047d29fa995e3e342" - integrity sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg== - "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" @@ -374,6 +254,13 @@ resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz#427d5549943a9c6fce808e39ea64dbe60d4047f1" integrity sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA== +"@stripe/react-stripe-js@^2.8.1": + version "2.8.1" + resolved "https://registry.yarnpkg.com/@stripe/react-stripe-js/-/react-stripe-js-2.8.1.tgz#63d9a666749f818b1bf4eb788eb1bc57eb496f3d" + integrity sha512-C410jVKOATinXLalWotab6E6jlWAlbqUDWL9q1km0p5UHrvnihjjYzA8imYXc4xc4Euf9GeKDQc4n35HKZvgwg== + dependencies: + prop-types "^15.7.2" + "@stripe/stripe-js@^1.54.2": version "1.54.2" resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-1.54.2.tgz#0665848e22cbda936cfd05256facdfbba121438d" @@ -792,11 +679,49 @@ axobject-query@^4.1.0: resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-4.1.0.tgz#28768c76d0e3cff21bc62a9e2d0b6ac30042a1ee" integrity sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ== +b4a@^1.6.4: + version "1.6.7" + resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.7.tgz#a99587d4ebbfbd5a6e3b21bdb5d5fa385767abe4" + integrity sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg== + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +bare-events@^2.0.0, bare-events@^2.2.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/bare-events/-/bare-events-2.5.0.tgz#305b511e262ffd8b9d5616b056464f8e1b3329cc" + integrity sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A== + +bare-fs@^2.1.1: + version "2.3.5" + resolved "https://registry.yarnpkg.com/bare-fs/-/bare-fs-2.3.5.tgz#05daa8e8206aeb46d13c2fe25a2cd3797b0d284a" + integrity sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw== + dependencies: + bare-events "^2.0.0" + bare-path "^2.0.0" + bare-stream "^2.0.0" + +bare-os@^2.1.0: + version "2.4.4" + resolved "https://registry.yarnpkg.com/bare-os/-/bare-os-2.4.4.tgz#01243392eb0a6e947177bb7c8a45123d45c9b1a9" + integrity sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ== + +bare-path@^2.0.0, bare-path@^2.1.0: + version "2.1.3" + resolved "https://registry.yarnpkg.com/bare-path/-/bare-path-2.1.3.tgz#594104c829ef660e43b5589ec8daef7df6cedb3e" + integrity sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA== + dependencies: + bare-os "^2.1.0" + +bare-stream@^2.0.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/bare-stream/-/bare-stream-2.3.2.tgz#3bc62b429bcf850d2f265719b7a49ee0630a3ae4" + integrity sha512-EFZHSIBkDgSHIwj2l2QZfP4U5OcD4xFAOwhSb/vlr9PIqyGJGvB/nfClJbcnh3EY4jtPE4zsb5ztae96bVF79A== + dependencies: + streamx "^2.20.0" + base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" @@ -807,6 +732,15 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -829,6 +763,14 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" +buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + buffer@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" @@ -902,6 +844,11 @@ chokidar@^3.5.3: optionalDependencies: fsevents "~2.3.2" +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -1096,6 +1043,13 @@ debug@^4.2.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5: dependencies: ms "^2.1.3" +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" @@ -1125,6 +1079,11 @@ deep-equal@^2.0.5: which-collection "^1.0.1" which-typed-array "^1.1.13" +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -1148,7 +1107,7 @@ define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: has-property-descriptors "^1.0.0" object-keys "^1.1.1" -detect-libc@^2.0.3: +detect-libc@^2.0.0, detect-libc@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== @@ -1204,7 +1163,7 @@ enabled@2.0.x: resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== -end-of-stream@^1.1.0: +end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -1611,11 +1570,21 @@ execa@^4.1.0: signal-exit "^3.0.2" strip-final-newline "^2.0.0" +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-fifo@^1.2.0, fast-fifo@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" + integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== + fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" @@ -1712,6 +1681,11 @@ foreground-child@^3.1.0: cross-spawn "^7.0.0" signal-exit "^4.0.1" +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -1786,6 +1760,11 @@ get-tsconfig@^4.7.5: dependencies: resolve-pkg-maps "^1.0.0" +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -1953,7 +1932,7 @@ husky@4.3.8: slash "^3.0.0" which-pm-runs "^1.0.0" -ieee754@^1.2.1: +ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -1994,11 +1973,16 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3: +inherits@2, inherits@^2.0.3, inherits@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + internal-slot@^1.0.4, internal-slot@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802" @@ -2487,6 +2471,11 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + minimatch@9.0.3: version "9.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" @@ -2508,7 +2497,7 @@ minimatch@^9.0.1, minimatch@^9.0.4: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.0, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -2518,6 +2507,11 @@ minimist@^1.2.0, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" @@ -2537,6 +2531,11 @@ nanoid@^3.3.6, nanoid@^3.3.7: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -2565,6 +2564,18 @@ next@14.2.11: "@next/swc-win32-ia32-msvc" "14.2.11" "@next/swc-win32-x64-msvc" "14.2.11" +node-abi@^3.3.0: + version "3.71.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.71.0.tgz#52d84bbcd8575efb71468fbaa1f9a49b2c242038" + integrity sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw== + dependencies: + semver "^7.3.5" + +node-addon-api@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76" + integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA== + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -2867,6 +2878,24 @@ postcss@^8, postcss@^8.4.23: picocolors "^1.1.0" source-map-js "^1.2.1" +prebuild-install@^7.1.1: + version "7.1.2" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.2.tgz#a5fd9986f5a6251fbc47e1e5c65de71e68c0a056" + integrity sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -2921,6 +2950,21 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +queue-tick@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142" + integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag== + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + react-dom@^17.0.2: version "17.0.2" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" @@ -2974,7 +3018,7 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" -readable-stream@^3.4.0: +readable-stream@^3.1.1, readable-stream@^3.4.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -3128,7 +3172,7 @@ safe-array-concat@^1.1.2: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@~5.2.0: +safe-buffer@^5.0.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -3177,7 +3221,7 @@ semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.5.4, semver@^7.6.3: +semver@^7.3.5, semver@^7.5.4, 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== @@ -3204,34 +3248,19 @@ set-function-name@^2.0.1, set-function-name@^2.0.2: functions-have-names "^1.2.3" has-property-descriptors "^1.0.2" -sharp@^0.33.5: - version "0.33.5" - resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.33.5.tgz#13e0e4130cc309d6a9497596715240b2ec0c594e" - integrity sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw== +sharp@0.32.6: + version "0.32.6" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.32.6.tgz#6ad30c0b7cd910df65d5f355f774aa4fce45732a" + integrity sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w== dependencies: color "^4.2.3" - detect-libc "^2.0.3" - semver "^7.6.3" - optionalDependencies: - "@img/sharp-darwin-arm64" "0.33.5" - "@img/sharp-darwin-x64" "0.33.5" - "@img/sharp-libvips-darwin-arm64" "1.0.4" - "@img/sharp-libvips-darwin-x64" "1.0.4" - "@img/sharp-libvips-linux-arm" "1.0.5" - "@img/sharp-libvips-linux-arm64" "1.0.4" - "@img/sharp-libvips-linux-s390x" "1.0.4" - "@img/sharp-libvips-linux-x64" "1.0.4" - "@img/sharp-libvips-linuxmusl-arm64" "1.0.4" - "@img/sharp-libvips-linuxmusl-x64" "1.0.4" - "@img/sharp-linux-arm" "0.33.5" - "@img/sharp-linux-arm64" "0.33.5" - "@img/sharp-linux-s390x" "0.33.5" - "@img/sharp-linux-x64" "0.33.5" - "@img/sharp-linuxmusl-arm64" "0.33.5" - "@img/sharp-linuxmusl-x64" "0.33.5" - "@img/sharp-wasm32" "0.33.5" - "@img/sharp-win32-ia32" "0.33.5" - "@img/sharp-win32-x64" "0.33.5" + detect-libc "^2.0.2" + node-addon-api "^6.1.0" + prebuild-install "^7.1.1" + semver "^7.5.4" + simple-get "^4.0.1" + tar-fs "^3.0.4" + tunnel-agent "^0.6.0" shebang-command@^2.0.0: version "2.0.0" @@ -3265,6 +3294,20 @@ signal-exit@^4.0.1: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.0, simple-get@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" @@ -3317,6 +3360,17 @@ streamsearch@^1.1.0: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== +streamx@^2.15.0, streamx@^2.20.0: + version "2.20.1" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.20.1.tgz#471c4f8b860f7b696feb83d5b125caab2fdbb93c" + integrity sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA== + dependencies: + fast-fifo "^1.3.2" + queue-tick "^1.0.1" + text-decoder "^1.1.0" + optionalDependencies: + bare-events "^2.2.0" + string-argv@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" @@ -3463,6 +3517,11 @@ strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + stripe@^16.9.0: version "16.12.0" resolved "https://registry.yarnpkg.com/stripe/-/stripe-16.12.0.tgz#75e3d8f0f35bea14885cb3605a41d6afc182aa66" @@ -3543,6 +3602,52 @@ tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tar-fs@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-fs@^3.0.4: + version "3.0.6" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.6.tgz#eaccd3a67d5672f09ca8e8f9c3d2b89fa173f217" + integrity sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w== + dependencies: + pump "^3.0.0" + tar-stream "^3.1.5" + optionalDependencies: + bare-fs "^2.1.1" + bare-path "^2.1.0" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +tar-stream@^3.1.5: + version "3.1.7" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.7.tgz#24b3fb5eabada19fe7338ed6d26e5f7c482e792b" + integrity sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ== + dependencies: + b4a "^1.6.4" + fast-fifo "^1.2.0" + streamx "^2.15.0" + +text-decoder@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/text-decoder/-/text-decoder-1.2.1.tgz#e173f5121d97bfa3ff8723429ad5ba92e1ead67e" + integrity sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ== + text-hex@1.0.x: version "1.0.0" resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" @@ -3609,6 +3714,13 @@ tslib@^2.1.0, tslib@^2.4.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -3874,3 +3986,8 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zod@^3.23.8: + version "3.23.8" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" + integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==