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==