mirror of
https://github.com/vercel/commerce.git
synced 2025-04-27 13:27:50 +00:00
chore: setting up rapyd api stuff
This commit is contained in:
parent
3e8d97331d
commit
5f4b245ea7
36
app/actions/checkout.ts
Normal file
36
app/actions/checkout.ts
Normal file
@ -0,0 +1,36 @@
|
||||
"use server";
|
||||
|
||||
import {
|
||||
createCheckout,
|
||||
type CreateCheckoutParams,
|
||||
} from "@/lib/rapyd/checkout";
|
||||
import { z } from "zod";
|
||||
|
||||
const checkoutSchema = z.object({
|
||||
amount: z.number().positive(),
|
||||
merchantReferenceId: z.string(),
|
||||
completeCheckoutUrl: z.string().url(),
|
||||
cancelCheckoutUrl: z.string().url(),
|
||||
description: z.string().optional(),
|
||||
});
|
||||
|
||||
export const createCheckoutAction = async (data: CreateCheckoutParams) => {
|
||||
try {
|
||||
// Validate input
|
||||
const validatedData = checkoutSchema.parse(data);
|
||||
|
||||
// Create checkout
|
||||
const checkout = await createCheckout(validatedData);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: checkout,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Checkout creation failed:", error);
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : "Unknown error occurred",
|
||||
};
|
||||
}
|
||||
};
|
48
app/components/checkout-button.tsx
Normal file
48
app/components/checkout-button.tsx
Normal file
@ -0,0 +1,48 @@
|
||||
"use client";
|
||||
|
||||
import { createCheckoutAction } from "@/app/actions/checkout";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useTransition } from "react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
interface CheckoutButtonProps {
|
||||
amount: number;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export const CheckoutButton = ({
|
||||
amount,
|
||||
description,
|
||||
}: CheckoutButtonProps) => {
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const router = useRouter();
|
||||
|
||||
const handleCheckout = () => {
|
||||
startTransition(async () => {
|
||||
const merchantReferenceId = crypto.randomUUID();
|
||||
|
||||
const result = await createCheckoutAction({
|
||||
amount,
|
||||
merchantReferenceId,
|
||||
completeCheckoutUrl: `${window.location.origin}/checkout/complete`,
|
||||
cancelCheckoutUrl: `${window.location.origin}/checkout/cancel`,
|
||||
description,
|
||||
});
|
||||
|
||||
if (!result.success) {
|
||||
toast.error("Failed to create checkout session");
|
||||
return;
|
||||
}
|
||||
|
||||
// Redirect to Rapyd checkout page
|
||||
router.push(result.data.redirect_url);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Button onClick={handleCheckout} disabled={isPending}>
|
||||
{isPending ? "Creating checkout..." : "Proceed to Checkout"}
|
||||
</Button>
|
||||
);
|
||||
};
|
69
lib/rapyd/checkout.ts
Normal file
69
lib/rapyd/checkout.ts
Normal file
@ -0,0 +1,69 @@
|
||||
import { makeRequest } from "@/lib/rapyd/utilities";
|
||||
import { cache } from "react";
|
||||
import "server-only";
|
||||
|
||||
// Icelandic card payment methods
|
||||
const ICELANDIC_PAYMENT_METHODS = [
|
||||
"is_visa_card",
|
||||
"is_mastercard_card",
|
||||
] as const;
|
||||
|
||||
interface CheckoutResponse {
|
||||
id: string;
|
||||
redirect_url: string;
|
||||
status: string;
|
||||
payment: {
|
||||
id: string;
|
||||
amount: number;
|
||||
currency: string;
|
||||
status: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface CreateCheckoutParams {
|
||||
amount: number;
|
||||
merchantReferenceId: string;
|
||||
completeCheckoutUrl: string;
|
||||
cancelCheckoutUrl: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
const DEFAULT_CHECKOUT_CONFIG = {
|
||||
country: "IS",
|
||||
currency: "ISK",
|
||||
} as const;
|
||||
|
||||
export const preloadCheckout = (params: CreateCheckoutParams) => {
|
||||
void createCheckout(params);
|
||||
};
|
||||
|
||||
export const createCheckout = cache(
|
||||
async ({
|
||||
amount,
|
||||
merchantReferenceId,
|
||||
completeCheckoutUrl,
|
||||
cancelCheckoutUrl,
|
||||
description,
|
||||
}: CreateCheckoutParams): Promise<CheckoutResponse> => {
|
||||
const checkoutBody = {
|
||||
amount,
|
||||
merchant_reference_id: merchantReferenceId,
|
||||
complete_checkout_url: completeCheckoutUrl,
|
||||
cancel_checkout_url: cancelCheckoutUrl,
|
||||
country: DEFAULT_CHECKOUT_CONFIG.country,
|
||||
currency: DEFAULT_CHECKOUT_CONFIG.currency,
|
||||
payment_method_types_include: ICELANDIC_PAYMENT_METHODS,
|
||||
...(description && { description }),
|
||||
};
|
||||
|
||||
const response = await makeRequest({
|
||||
method: "post",
|
||||
path: "/v1/checkout",
|
||||
body: checkoutBody,
|
||||
});
|
||||
|
||||
return response as CheckoutResponse;
|
||||
}
|
||||
);
|
||||
|
||||
export type { CheckoutResponse, CreateCheckoutParams };
|
147
lib/rapyd/utilities.ts
Normal file
147
lib/rapyd/utilities.ts
Normal file
@ -0,0 +1,147 @@
|
||||
import crypto from "crypto";
|
||||
|
||||
const BASE_URL = process.env.RAPYD_BASE_URL;
|
||||
const SECRET_KEY = process.env.RAPYD_SECRET_KEY;
|
||||
const ACCESS_KEY = process.env.RAPYD_ACCESS_KEY;
|
||||
|
||||
if (!SECRET_KEY || !ACCESS_KEY) {
|
||||
throw new Error("RAPYD_SECRET_KEY and RAPYD_ACCESS_KEY must be set");
|
||||
}
|
||||
|
||||
type HttpMethod = "get" | "put" | "post" | "delete";
|
||||
|
||||
interface SignatureHeaders {
|
||||
access_key: string;
|
||||
salt: string;
|
||||
timestamp: string;
|
||||
signature: string;
|
||||
idempotency: string;
|
||||
}
|
||||
|
||||
interface RequestConfig {
|
||||
method: HttpMethod;
|
||||
path: string;
|
||||
body?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
const generateSalt = (length = 12): string => {
|
||||
const characters =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
return Array.from(
|
||||
{ length },
|
||||
() => characters[Math.floor(Math.random() * characters.length)]
|
||||
).join("");
|
||||
};
|
||||
|
||||
const getUnixTime = ({
|
||||
days = 0,
|
||||
hours = 0,
|
||||
minutes = 0,
|
||||
seconds = 0,
|
||||
} = {}): number => {
|
||||
const now = new Date();
|
||||
now.setDate(now.getDate() + days);
|
||||
now.setHours(now.getHours() + hours);
|
||||
now.setMinutes(now.getMinutes() + minutes);
|
||||
now.setSeconds(now.getSeconds() + seconds);
|
||||
return Math.floor(now.getTime() / 1000);
|
||||
};
|
||||
|
||||
const updateTimestampSaltSig = ({
|
||||
method,
|
||||
path,
|
||||
body,
|
||||
}: RequestConfig): {
|
||||
salt: string;
|
||||
timestamp: number;
|
||||
signature: string;
|
||||
} => {
|
||||
const normalizedPath = path.startsWith("http")
|
||||
? path.substring(path.indexOf("/v1"))
|
||||
: path;
|
||||
|
||||
const salt = generateSalt();
|
||||
const timestamp = getUnixTime();
|
||||
const bodyString = body ? JSON.stringify(body) : "";
|
||||
|
||||
const toSign = [
|
||||
method,
|
||||
normalizedPath,
|
||||
salt,
|
||||
timestamp.toString(),
|
||||
ACCESS_KEY,
|
||||
SECRET_KEY,
|
||||
bodyString,
|
||||
].join("");
|
||||
|
||||
const hmac = crypto.createHmac("sha256", SECRET_KEY);
|
||||
hmac.update(toSign);
|
||||
const signature = Buffer.from(hmac.digest("hex")).toString("base64url");
|
||||
|
||||
return { salt, timestamp, signature };
|
||||
};
|
||||
|
||||
const createHeaders = ({
|
||||
method,
|
||||
path,
|
||||
body,
|
||||
}: RequestConfig): {
|
||||
headers: SignatureHeaders;
|
||||
body: string;
|
||||
} => {
|
||||
const { salt, timestamp, signature } = updateTimestampSaltSig({
|
||||
method,
|
||||
path,
|
||||
body,
|
||||
});
|
||||
|
||||
const headers: SignatureHeaders = {
|
||||
access_key: ACCESS_KEY,
|
||||
salt,
|
||||
timestamp: timestamp.toString(),
|
||||
signature,
|
||||
idempotency: `${getUnixTime()}${salt}`,
|
||||
};
|
||||
|
||||
return {
|
||||
headers,
|
||||
body: body ? JSON.stringify(body) : "",
|
||||
};
|
||||
};
|
||||
|
||||
const makeRequest = async ({
|
||||
method,
|
||||
path,
|
||||
body,
|
||||
}: RequestConfig): Promise<unknown> => {
|
||||
const { headers, body: stringifiedBody } = createHeaders({
|
||||
method,
|
||||
path,
|
||||
body,
|
||||
});
|
||||
const url = `${BASE_URL}${path}`;
|
||||
|
||||
const requestConfig: RequestInit = {
|
||||
method: method.toUpperCase(),
|
||||
headers: {
|
||||
...headers,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
};
|
||||
|
||||
if (method !== "get" && stringifiedBody) {
|
||||
requestConfig.body = stringifiedBody;
|
||||
}
|
||||
|
||||
const response = await fetch(url, requestConfig);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Request failed: ${response.status} ${response.statusText}`
|
||||
);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
};
|
||||
|
||||
export { makeRequest, type HttpMethod, type RequestConfig };
|
11
package.json
11
package.json
@ -13,10 +13,11 @@
|
||||
"@heroicons/react": "^2.2.0",
|
||||
"clsx": "^2.1.1",
|
||||
"geist": "^1.3.1",
|
||||
"next": "15.2.0-canary.67",
|
||||
"next": "15.3.0-canary.9",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"sonner": "^2.0.1"
|
||||
"sonner": "^2.0.1",
|
||||
"zod": "^3.24.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
@ -30,5 +31,11 @@
|
||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||
"tailwindcss": "^4.0.8",
|
||||
"typescript": "5.7.3"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"@types/react": "19.0.10",
|
||||
"@types/react-dom": "19.0.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
102
pnpm-lock.yaml
generated
102
pnpm-lock.yaml
generated
@ -4,6 +4,10 @@ settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
overrides:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react-dom': 19.0.4
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
@ -19,10 +23,10 @@ importers:
|
||||
version: 2.1.1
|
||||
geist:
|
||||
specifier: ^1.3.1
|
||||
version: 1.3.1(next@15.2.0-canary.67(react-dom@19.0.0(react@19.0.0))(react@19.0.0))
|
||||
version: 1.3.1(next@15.3.0-canary.9(react-dom@19.0.0(react@19.0.0))(react@19.0.0))
|
||||
next:
|
||||
specifier: 15.2.0-canary.67
|
||||
version: 15.2.0-canary.67(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
specifier: 15.3.0-canary.9
|
||||
version: 15.3.0-canary.9(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
react:
|
||||
specifier: 19.0.0
|
||||
version: 19.0.0
|
||||
@ -32,6 +36,9 @@ importers:
|
||||
sonner:
|
||||
specifier: ^2.0.1
|
||||
version: 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
zod:
|
||||
specifier: ^3.24.2
|
||||
version: 3.24.2
|
||||
devDependencies:
|
||||
'@tailwindcss/container-queries':
|
||||
specifier: ^0.1.1
|
||||
@ -214,53 +221,53 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@next/env@15.2.0-canary.67':
|
||||
resolution: {integrity: sha512-Is8AU8GcBrDoyXTmEKPTM+K87Xb5SA545jkw0E6+51Zb/1sg5MSCH9OmQf2KlvbqSrkiVuQ8UA23pY5+xGFGpw==}
|
||||
'@next/env@15.3.0-canary.9':
|
||||
resolution: {integrity: sha512-kvABHn6GmJbyf02wozUzrC4evHdVSmc6FYV8I7Q4g3qZW1x64v6ppi3Hw1KEUzKieC1Car/maGT+r3oRalCg4Q==}
|
||||
|
||||
'@next/swc-darwin-arm64@15.2.0-canary.67':
|
||||
resolution: {integrity: sha512-BNBt0qWhnZR2pSxlofSBsmy5PYRa7/t4txnYH5z41lSs0B9OlhlsYyiokefmiw6EKKLxzT23hmb+ZPtxTCjiFw==}
|
||||
'@next/swc-darwin-arm64@15.3.0-canary.9':
|
||||
resolution: {integrity: sha512-llJnHJGXQGux7sHJ4t0q5HbMnID+M3+s5ghvYBw79uP4QDkH5XVXRC2oQUwTvEPzHXUhWpB/kf6KUpWmOEI8xQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@next/swc-darwin-x64@15.2.0-canary.67':
|
||||
resolution: {integrity: sha512-ZPC0/iL3dhexN+MQ6QOfaOO6y3WMhyxns01KA9mae0V0sp/uC+KwpSbNCVXptjmiZQ9j0Q9TYjqQBQ4KwtBK8Q==}
|
||||
'@next/swc-darwin-x64@15.3.0-canary.9':
|
||||
resolution: {integrity: sha512-igGqAeBB/3tJ4XLqbdcuzbgwgdNh9kRp2AFSME/Ok4jyetSPmcQFX43+C6piuMj2gQ06Q6gDWj3qib0MNf5IWw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@next/swc-linux-arm64-gnu@15.2.0-canary.67':
|
||||
resolution: {integrity: sha512-t+i9tRB0uYj3OoZS2qhPwDrlcf5bRTKQY5GtFwboyCzBLv9KcU1xa3cwXulNxq1soo8wTiWRnhq8CkvUT+Fbvw==}
|
||||
'@next/swc-linux-arm64-gnu@15.3.0-canary.9':
|
||||
resolution: {integrity: sha512-Ym9FxqbBmQyUjoe2bW7MsDkrYV3sSR8WXCEqJQthETjAqSsG6zwUfL86dMAKe2RUetqlNzWlXDH/+FM9fdPVOw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@next/swc-linux-arm64-musl@15.2.0-canary.67':
|
||||
resolution: {integrity: sha512-9jffwDN4X2ER5eqj16XJHCf4MmRI3QI0L52JLYH9/3OPxD86bDeQlH/+NK3iEu/3X4KX1rDb7cF9uulB9hjfXw==}
|
||||
'@next/swc-linux-arm64-musl@15.3.0-canary.9':
|
||||
resolution: {integrity: sha512-aB9umTo1HHcQWRTXffWSrt6wTMvhg+fYbtZ8PR7h28gBrQaYL6Lu8Kg7BQynYEx8Ze42GqVcS0MlwVsTQrpwMw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@next/swc-linux-x64-gnu@15.2.0-canary.67':
|
||||
resolution: {integrity: sha512-pWp5NIAbMLKy6tfZF22tsDC3A9IJm/p+UQf9l906NClYKtMXLYDFmapXVpTUB7fdb9xDOvB+DtAX11nQk5bukw==}
|
||||
'@next/swc-linux-x64-gnu@15.3.0-canary.9':
|
||||
resolution: {integrity: sha512-d+tU/H5SaPAuHcxGJ9fiqt0qzXpkOmksu1lF9JQNHd6WKtBnnJMzpYL8onLLYXThrIPaETVSLpBiv1wvwIgwFg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@next/swc-linux-x64-musl@15.2.0-canary.67':
|
||||
resolution: {integrity: sha512-RjSu9pEgQuUmkt1FINCCvpV0SHYrLpf7LaF7pZPem1N2lgDySnazt4ag7ZDaWL0XMBiTKGmNxkk185HeST2PSg==}
|
||||
'@next/swc-linux-x64-musl@15.3.0-canary.9':
|
||||
resolution: {integrity: sha512-b+V+36WIopplWQI2/xOIqzuRGCRGTDLVe2luhhtjcwewRqUujktGnphHW5zRcEVD9nNwwPCisxC01XLL3geggg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@next/swc-win32-arm64-msvc@15.2.0-canary.67':
|
||||
resolution: {integrity: sha512-DM+ysK87Q10MkoxgZeFOZsRx4Yt1WtynDVZoogdEjikfxZrMLCEo22O2uFVNh2E0kHCdE89K3dODO9rQz9EjAw==}
|
||||
'@next/swc-win32-arm64-msvc@15.3.0-canary.9':
|
||||
resolution: {integrity: sha512-6YbKTAP1Z+dnFtEoPQc4NuQ9J3VIN0vc8gHmZHBl5qfBQgF9f4DfBwcTrXMXEKIFVkQN4YMZU83v+2DSzT+7FQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@next/swc-win32-x64-msvc@15.2.0-canary.67':
|
||||
resolution: {integrity: sha512-gI3Hk/6YrFXMJn018ZjZo832Pxrsj2DpyXbLc9Vxs4wOZ0x3ChVk2yhFA/SJZY7yhdD3vwG9Srdn8gfCuO4xHg==}
|
||||
'@next/swc-win32-x64-msvc@15.3.0-canary.9':
|
||||
resolution: {integrity: sha512-Ujf4+i1memQV3Qk0EjY00C4bzumV6jOZze9kCdi4PnpPjzEefTj88CFGR7ACmYgu1qDHOKaZQxR08MALy/yvIw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
@ -406,7 +413,7 @@ packages:
|
||||
'@types/react-dom@19.0.4':
|
||||
resolution: {integrity: sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==}
|
||||
peerDependencies:
|
||||
'@types/react': ^19.0.0
|
||||
'@types/react': 19.0.10
|
||||
|
||||
'@types/react@19.0.10':
|
||||
resolution: {integrity: sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==}
|
||||
@ -553,8 +560,8 @@ packages:
|
||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||
hasBin: true
|
||||
|
||||
next@15.2.0-canary.67:
|
||||
resolution: {integrity: sha512-hKZjcmngKiY/HzHXNN0SGXR9Xio6pirraWu8GqRD24pMiGueY0ykxTbOp0SrqgHDsgWGTOxy3hXCriGiyyVb8w==}
|
||||
next@15.3.0-canary.9:
|
||||
resolution: {integrity: sha512-R9+FanTpLPN4cez/lJurj/kedcOERPCQebl/F5kevPSzCQzp8Dj/LCv6L10wTqBH3zBgqepp0eytzsVrjW8VjA==}
|
||||
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@ -724,6 +731,9 @@ packages:
|
||||
util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
zod@3.24.2:
|
||||
resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@alloc/quick-lru@5.2.0': {}
|
||||
@ -846,30 +856,30 @@ snapshots:
|
||||
'@img/sharp-win32-x64@0.33.5':
|
||||
optional: true
|
||||
|
||||
'@next/env@15.2.0-canary.67': {}
|
||||
'@next/env@15.3.0-canary.9': {}
|
||||
|
||||
'@next/swc-darwin-arm64@15.2.0-canary.67':
|
||||
'@next/swc-darwin-arm64@15.3.0-canary.9':
|
||||
optional: true
|
||||
|
||||
'@next/swc-darwin-x64@15.2.0-canary.67':
|
||||
'@next/swc-darwin-x64@15.3.0-canary.9':
|
||||
optional: true
|
||||
|
||||
'@next/swc-linux-arm64-gnu@15.2.0-canary.67':
|
||||
'@next/swc-linux-arm64-gnu@15.3.0-canary.9':
|
||||
optional: true
|
||||
|
||||
'@next/swc-linux-arm64-musl@15.2.0-canary.67':
|
||||
'@next/swc-linux-arm64-musl@15.3.0-canary.9':
|
||||
optional: true
|
||||
|
||||
'@next/swc-linux-x64-gnu@15.2.0-canary.67':
|
||||
'@next/swc-linux-x64-gnu@15.3.0-canary.9':
|
||||
optional: true
|
||||
|
||||
'@next/swc-linux-x64-musl@15.2.0-canary.67':
|
||||
'@next/swc-linux-x64-musl@15.3.0-canary.9':
|
||||
optional: true
|
||||
|
||||
'@next/swc-win32-arm64-msvc@15.2.0-canary.67':
|
||||
'@next/swc-win32-arm64-msvc@15.3.0-canary.9':
|
||||
optional: true
|
||||
|
||||
'@next/swc-win32-x64-msvc@15.2.0-canary.67':
|
||||
'@next/swc-win32-x64-msvc@15.3.0-canary.9':
|
||||
optional: true
|
||||
|
||||
'@react-aria/focus@3.19.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
@ -1059,9 +1069,9 @@ snapshots:
|
||||
graceful-fs: 4.2.11
|
||||
tapable: 2.2.1
|
||||
|
||||
geist@1.3.1(next@15.2.0-canary.67(react-dom@19.0.0(react@19.0.0))(react@19.0.0)):
|
||||
geist@1.3.1(next@15.3.0-canary.9(react-dom@19.0.0(react@19.0.0))(react@19.0.0)):
|
||||
dependencies:
|
||||
next: 15.2.0-canary.67(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
next: 15.3.0-canary.9(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
|
||||
graceful-fs@4.2.11: {}
|
||||
|
||||
@ -1123,9 +1133,9 @@ snapshots:
|
||||
|
||||
nanoid@3.3.8: {}
|
||||
|
||||
next@15.2.0-canary.67(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
|
||||
next@15.3.0-canary.9(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
|
||||
dependencies:
|
||||
'@next/env': 15.2.0-canary.67
|
||||
'@next/env': 15.3.0-canary.9
|
||||
'@swc/counter': 0.1.3
|
||||
'@swc/helpers': 0.5.15
|
||||
busboy: 1.6.0
|
||||
@ -1135,14 +1145,14 @@ snapshots:
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
styled-jsx: 5.1.6(react@19.0.0)
|
||||
optionalDependencies:
|
||||
'@next/swc-darwin-arm64': 15.2.0-canary.67
|
||||
'@next/swc-darwin-x64': 15.2.0-canary.67
|
||||
'@next/swc-linux-arm64-gnu': 15.2.0-canary.67
|
||||
'@next/swc-linux-arm64-musl': 15.2.0-canary.67
|
||||
'@next/swc-linux-x64-gnu': 15.2.0-canary.67
|
||||
'@next/swc-linux-x64-musl': 15.2.0-canary.67
|
||||
'@next/swc-win32-arm64-msvc': 15.2.0-canary.67
|
||||
'@next/swc-win32-x64-msvc': 15.2.0-canary.67
|
||||
'@next/swc-darwin-arm64': 15.3.0-canary.9
|
||||
'@next/swc-darwin-x64': 15.3.0-canary.9
|
||||
'@next/swc-linux-arm64-gnu': 15.3.0-canary.9
|
||||
'@next/swc-linux-arm64-musl': 15.3.0-canary.9
|
||||
'@next/swc-linux-x64-gnu': 15.3.0-canary.9
|
||||
'@next/swc-linux-x64-musl': 15.3.0-canary.9
|
||||
'@next/swc-win32-arm64-msvc': 15.3.0-canary.9
|
||||
'@next/swc-win32-x64-msvc': 15.3.0-canary.9
|
||||
sharp: 0.33.5
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
@ -1244,3 +1254,5 @@ snapshots:
|
||||
undici-types@6.20.0: {}
|
||||
|
||||
util-deprecate@1.0.2: {}
|
||||
|
||||
zod@3.24.2: {}
|
||||
|
@ -21,7 +21,10 @@
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
]
|
||||
],
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
|
Loading…
x
Reference in New Issue
Block a user