mirror of
https://github.com/vercel/commerce.git
synced 2025-05-12 20:57:51 +00:00
add useAuth context
This commit is contained in:
parent
cc9def4035
commit
19065c1d82
@ -1,5 +1,7 @@
|
||||
import { headers } from 'next/headers';
|
||||
|
||||
export const runtime = 'edge';
|
||||
|
||||
export default async function AuthorizationPage() {
|
||||
const headersList = headers();
|
||||
const access = headersList.get('x-shop-access');
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { LoginMessage } from 'components/auth/login-message';
|
||||
export const runtime = 'edge'; //this needs to be here on thie page. I don't know why
|
||||
|
||||
export const runtime = 'edge';
|
||||
|
||||
export default async function LoginPage() {
|
||||
return (
|
||||
|
@ -4,6 +4,7 @@ import { GeistSans } from 'geist/font/sans';
|
||||
import { ensureStartsWith } from 'lib/utils';
|
||||
import { ReactNode, Suspense } from 'react';
|
||||
import './globals.css';
|
||||
import { AuthProvider } from 'contexts/auth-context';
|
||||
|
||||
const { TWITTER_CREATOR, TWITTER_SITE, SITE_NAME } = process.env;
|
||||
const baseUrl = process.env.NEXT_PUBLIC_VERCEL_URL
|
||||
@ -36,13 +37,17 @@ export default async function RootLayout({ children }: { children: ReactNode })
|
||||
return (
|
||||
<html lang="en" className={GeistSans.variable}>
|
||||
<body className="bg-white text-black selection:bg-teal-300 dark:bg-neutral-900 dark:text-white dark:selection:bg-pink-500 dark:selection:text-white">
|
||||
<header>
|
||||
<Banner />
|
||||
<Navbar />
|
||||
</header>
|
||||
<Suspense>
|
||||
<main>{children}</main>
|
||||
</Suspense>
|
||||
<AuthProvider>
|
||||
<div>
|
||||
<header>
|
||||
<Banner />
|
||||
<Navbar />
|
||||
</header>
|
||||
<Suspense>
|
||||
<main>{children}</main>
|
||||
</Suspense>
|
||||
</div>
|
||||
</AuthProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
@ -1,5 +1,3 @@
|
||||
//See https://react.dev/reference/react-dom/hooks/useFormState
|
||||
//https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#forms
|
||||
'use server';
|
||||
|
||||
import { redirect } from 'next/navigation';
|
||||
@ -18,10 +16,8 @@ export async function doLogin(_: any) {
|
||||
const clientId = CUSTOMER_API_CLIENT_ID;
|
||||
const origin = ORIGIN_URL;
|
||||
const loginUrl = new URL(`${customerAccountApiUrl}/auth/oauth/authorize`);
|
||||
//console.log ("previous", prevState)
|
||||
|
||||
try {
|
||||
//await addToCart(cartId, [{ merchandiseId: selectedVariantId, quantity: 1 }]);
|
||||
loginUrl.searchParams.set('client_id', clientId);
|
||||
loginUrl.searchParams.append('response_type', 'code');
|
||||
loginUrl.searchParams.append('redirect_uri', `${origin}/authorize`);
|
||||
@ -30,34 +26,33 @@ export async function doLogin(_: any) {
|
||||
'openid email https://api.customers.com/auth/customer.graphql'
|
||||
);
|
||||
const verifier = await generateCodeVerifier();
|
||||
//const newVerifier = verifier.replace("+", '_').replace("-",'_').replace("/",'_').trim()
|
||||
|
||||
const challenge = await generateCodeChallenge(verifier);
|
||||
cookies().set('shop_verifier', verifier as string, {
|
||||
// @ts-ignore
|
||||
//expires: auth?.expires, //not necessary here
|
||||
});
|
||||
cookies().set('shop_verifier', verifier as string, {});
|
||||
const state = await generateRandomString();
|
||||
const nonce = await generateRandomString();
|
||||
cookies().set('shop_state', state as string, {
|
||||
// @ts-ignore
|
||||
//expires: auth?.expires, //not necessary here
|
||||
});
|
||||
cookies().set('shop_nonce', nonce as string, {
|
||||
// @ts-ignore
|
||||
//expires: auth?.expires, //not necessary here
|
||||
});
|
||||
cookies().set('shop_state', state as string, {});
|
||||
cookies().set('shop_nonce', nonce as string, {});
|
||||
|
||||
loginUrl.searchParams.append('state', state);
|
||||
loginUrl.searchParams.append('nonce', nonce);
|
||||
loginUrl.searchParams.append('code_challenge', challenge);
|
||||
loginUrl.searchParams.append('code_challenge_method', 'S256');
|
||||
//console.log ("loginURL", loginUrl)
|
||||
//throw new Error ("Error") //this is how you throw an error, if you want to. Then the catch will execute
|
||||
} catch (e) {
|
||||
console.log('Error', e);
|
||||
//you can throw error here or return - return goes back to form b/c of state, throw will throw the error boundary
|
||||
//throw new Error ("Error")
|
||||
return 'Error logging in. Please try again';
|
||||
}
|
||||
|
||||
redirect(`${loginUrl}`); // Navigate to the new post page
|
||||
}
|
||||
|
||||
export async function isLoggedIn() {
|
||||
const customerToken = cookies().get('shop_customer_token')?.value;
|
||||
const refreshToken = cookies().get('shop_refresh_token')?.value;
|
||||
|
||||
if (!customerToken && !refreshToken) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,6 @@ export default async function Login() {
|
||||
const customerToken = cookies().get('shop_customer_token')?.value;
|
||||
const refreshToken = cookies().get('shop_refresh_token')?.value;
|
||||
let isLoggedIn;
|
||||
//obviously just checking for the cookies without verifying the cookie itself is not ideal. However, the cookie is validated on the
|
||||
//account page, so a "fake" cookie does nothing, except show the UI and then it would be deleted when clicking on account
|
||||
//so for now, just checking the cookie for the UI is sufficient. Alternatively, we can do a query here, or a custom JWT
|
||||
if (!customerToken && !refreshToken) {
|
||||
isLoggedIn = false;
|
||||
} else {
|
||||
|
@ -1,6 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { Popover, PopoverButton, PopoverPanel, Transition } from '@headlessui/react';
|
||||
import { CloseButton, Popover, PopoverButton, PopoverPanel, Transition } from '@headlessui/react';
|
||||
import { ArrowRightIcon } from '@heroicons/react/16/solid';
|
||||
import { Menu } from 'lib/shopify/types';
|
||||
import { Fragment } from 'react';
|
||||
@ -8,6 +7,8 @@ import OpenProfile from './open-profile';
|
||||
import { useFormState, useFormStatus } from 'react-dom';
|
||||
import { doLogin } from 'components/auth/actions';
|
||||
import { Button } from 'components/button';
|
||||
import useAuth from 'hooks/use-auth';
|
||||
import Link from 'next/link';
|
||||
|
||||
type ProfilePopoverProps = {
|
||||
menu: Menu[];
|
||||
@ -34,7 +35,8 @@ function SubmitButton(props: any) {
|
||||
);
|
||||
}
|
||||
const ProfilePopover = ({ menu }: ProfilePopoverProps) => {
|
||||
const [message, formAction] = useFormState(doLogin, null);
|
||||
const [message] = useFormState(doLogin, null);
|
||||
const { isAuthenticated, loading } = useAuth();
|
||||
|
||||
return (
|
||||
<Popover className="relative">
|
||||
@ -53,22 +55,29 @@ const ProfilePopover = ({ menu }: ProfilePopoverProps) => {
|
||||
<PopoverPanel className="absolute -right-10 z-50 mt-2 w-72 max-w-lg px-4 sm:px-0 lg:right-0">
|
||||
<div className="flex flex-col gap-2 overflow-hidden rounded-md bg-white px-4 py-3 text-black shadow-xl ring-1 ring-black/5">
|
||||
<span className="text-sm font-medium">My Account</span>
|
||||
<form action={formAction}>
|
||||
<SubmitButton message={message} />
|
||||
<p aria-live="polite" className="sr-only" role="status">
|
||||
{message}
|
||||
</p>
|
||||
</form>
|
||||
{!isAuthenticated && !loading && <SubmitButton message={message} />}
|
||||
{menu.length ? (
|
||||
<ul className="mt-2 flex w-full flex-col divide-y text-sm">
|
||||
<ul className="flex w-full flex-col divide-y text-sm">
|
||||
{isAuthenticated && (
|
||||
<li className="cursor-pointer py-2 hover:underline">
|
||||
<CloseButton
|
||||
as={Link}
|
||||
className="flex w-full flex-row items-center justify-between"
|
||||
href="/account"
|
||||
>
|
||||
My Orders <ArrowRightIcon className="h-3" />
|
||||
</CloseButton>
|
||||
</li>
|
||||
)}
|
||||
{menu.map((menuItem) => (
|
||||
<li className="cursor-pointer py-2 hover:underline" key={menuItem.title}>
|
||||
<a
|
||||
<CloseButton
|
||||
as={Link}
|
||||
className="flex w-full flex-row items-center justify-between"
|
||||
href={menuItem.path}
|
||||
>
|
||||
{menuItem.title} <ArrowRightIcon className="h-3" />
|
||||
</a>
|
||||
</CloseButton>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
38
contexts/auth-context.tsx
Normal file
38
contexts/auth-context.tsx
Normal file
@ -0,0 +1,38 @@
|
||||
'use client';
|
||||
import { isLoggedIn } from 'components/auth/actions';
|
||||
import { createContext, useState, useEffect } from 'react';
|
||||
|
||||
type AuthContextType = {
|
||||
isAuthenticated: boolean;
|
||||
loading: boolean;
|
||||
};
|
||||
|
||||
const AuthContext = createContext<AuthContextType>({
|
||||
isAuthenticated: false,
|
||||
loading: true
|
||||
});
|
||||
|
||||
type AuthProviderProps = {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
export function AuthProvider({ children }: AuthProviderProps) {
|
||||
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
async function checkAuth() {
|
||||
const isLogged = await isLoggedIn();
|
||||
setIsAuthenticated(isLogged);
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
checkAuth();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{ isAuthenticated, loading }}>{children}</AuthContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export default AuthContext;
|
11
hooks/use-auth.ts
Normal file
11
hooks/use-auth.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import AuthContext from 'contexts/auth-context';
|
||||
import { useContext } from 'react';
|
||||
|
||||
export default function useAuth() {
|
||||
const context = useContext(AuthContext);
|
||||
|
||||
if (context === undefined) {
|
||||
throw new Error('useAuth must be used within an AuthProvider');
|
||||
}
|
||||
return context;
|
||||
}
|
@ -105,14 +105,13 @@ export async function initialAccessToken(
|
||||
headersNew.append('User-Agent', userAgent);
|
||||
headersNew.append('Origin', newOrigin || '');
|
||||
const tokenRequestUrl = `${customerAccountApiUrl}/auth/oauth/token`;
|
||||
console.log('sending request to', tokenRequestUrl);
|
||||
|
||||
const response = await fetch(tokenRequestUrl, {
|
||||
method: 'POST',
|
||||
headers: headersNew,
|
||||
body
|
||||
});
|
||||
console.log('ok', response.ok);
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
console.log('data response error auth', error);
|
||||
@ -336,7 +335,6 @@ export async function isLoggedIn(request: NextRequest, origin: string) {
|
||||
const refreshToken = request.cookies.get('shop_refresh_token');
|
||||
const refreshTokenValue = refreshToken?.value;
|
||||
|
||||
console.log('customer token', customerTokenValue);
|
||||
const newHeaders = new Headers(request.headers);
|
||||
if (!customerTokenValue && !refreshTokenValue) {
|
||||
const redirectUrl = new URL(`${origin}`);
|
||||
|
@ -2,7 +2,7 @@
|
||||
"private": true,
|
||||
"packageManager": "pnpm@9.1.2",
|
||||
"engines": {
|
||||
"node": ">=18",
|
||||
"node": ">=20",
|
||||
"pnpm": ">=7"
|
||||
},
|
||||
"scripts": {
|
||||
@ -32,7 +32,7 @@
|
||||
"lodash.get": "^4.4.2",
|
||||
"lodash.kebabcase": "^4.1.1",
|
||||
"lodash.startcase": "^4.4.0",
|
||||
"next": "14.1.4",
|
||||
"next": "14.2.4",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-hook-form": "^7.51.5",
|
||||
@ -55,7 +55,7 @@
|
||||
"@vercel/git-hooks": "^1.0.0",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-next": "^14.1.4",
|
||||
"eslint-config-next": "^14.2.4",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-unicorn": "^51.0.1",
|
||||
"lint-staged": "^15.2.2",
|
||||
|
132
pnpm-lock.yaml
generated
132
pnpm-lock.yaml
generated
@ -28,7 +28,7 @@ importers:
|
||||
version: 2.1.0
|
||||
geist:
|
||||
specifier: ^1.3.0
|
||||
version: 1.3.0(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))
|
||||
version: 1.3.0(next@14.2.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))
|
||||
lodash.get:
|
||||
specifier: ^4.4.2
|
||||
version: 4.4.2
|
||||
@ -39,8 +39,8 @@ importers:
|
||||
specifier: ^4.4.0
|
||||
version: 4.4.0
|
||||
next:
|
||||
specifier: 14.1.4
|
||||
version: 14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
specifier: 14.2.4
|
||||
version: 14.2.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
react:
|
||||
specifier: 18.2.0
|
||||
version: 18.2.0
|
||||
@ -103,8 +103,8 @@ importers:
|
||||
specifier: ^8.57.0
|
||||
version: 8.57.0
|
||||
eslint-config-next:
|
||||
specifier: ^14.1.4
|
||||
version: 14.1.4(eslint@8.57.0)(typescript@5.4.3)
|
||||
specifier: ^14.2.4
|
||||
version: 14.2.4(eslint@8.57.0)(typescript@5.4.3)
|
||||
eslint-config-prettier:
|
||||
specifier: ^9.1.0
|
||||
version: 9.1.0(eslint@8.57.0)
|
||||
@ -245,62 +245,62 @@ packages:
|
||||
'@jridgewell/trace-mapping@0.3.25':
|
||||
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
|
||||
|
||||
'@next/env@14.1.4':
|
||||
resolution: {integrity: sha512-e7X7bbn3Z6DWnDi75UWn+REgAbLEqxI8Tq2pkFOFAMpWAWApz/YCUhtWMWn410h8Q2fYiYL7Yg5OlxMOCfFjJQ==}
|
||||
'@next/env@14.2.4':
|
||||
resolution: {integrity: sha512-3EtkY5VDkuV2+lNmKlbkibIJxcO4oIHEhBWne6PaAp+76J9KoSsGvNikp6ivzAT8dhhBMYrm6op2pS1ApG0Hzg==}
|
||||
|
||||
'@next/eslint-plugin-next@14.1.4':
|
||||
resolution: {integrity: sha512-n4zYNLSyCo0Ln5b7qxqQeQ34OZKXwgbdcx6kmkQbywr+0k6M3Vinft0T72R6CDAcDrne2IAgSud4uWCzFgc5HA==}
|
||||
'@next/eslint-plugin-next@14.2.4':
|
||||
resolution: {integrity: sha512-svSFxW9f3xDaZA3idQmlFw7SusOuWTpDTAeBlO3AEPDltrraV+lqs7mAc6A27YdnpQVVIA3sODqUAAHdWhVWsA==}
|
||||
|
||||
'@next/swc-darwin-arm64@14.1.4':
|
||||
resolution: {integrity: sha512-ubmUkbmW65nIAOmoxT1IROZdmmJMmdYvXIe8211send9ZYJu+SqxSnJM4TrPj9wmL6g9Atvj0S/2cFmMSS99jg==}
|
||||
'@next/swc-darwin-arm64@14.2.4':
|
||||
resolution: {integrity: sha512-AH3mO4JlFUqsYcwFUHb1wAKlebHU/Hv2u2kb1pAuRanDZ7pD/A/KPD98RHZmwsJpdHQwfEc/06mgpSzwrJYnNg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@next/swc-darwin-x64@14.1.4':
|
||||
resolution: {integrity: sha512-b0Xo1ELj3u7IkZWAKcJPJEhBop117U78l70nfoQGo4xUSvv0PJSTaV4U9xQBLvZlnjsYkc8RwQN1HoH/oQmLlQ==}
|
||||
'@next/swc-darwin-x64@14.2.4':
|
||||
resolution: {integrity: sha512-QVadW73sWIO6E2VroyUjuAxhWLZWEpiFqHdZdoQ/AMpN9YWGuHV8t2rChr0ahy+irKX5mlDU7OY68k3n4tAZTg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@next/swc-linux-arm64-gnu@14.1.4':
|
||||
resolution: {integrity: sha512-457G0hcLrdYA/u1O2XkRMsDKId5VKe3uKPvrKVOyuARa6nXrdhJOOYU9hkKKyQTMru1B8qEP78IAhf/1XnVqKA==}
|
||||
'@next/swc-linux-arm64-gnu@14.2.4':
|
||||
resolution: {integrity: sha512-KT6GUrb3oyCfcfJ+WliXuJnD6pCpZiosx2X3k66HLR+DMoilRb76LpWPGb4tZprawTtcnyrv75ElD6VncVamUQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@next/swc-linux-arm64-musl@14.1.4':
|
||||
resolution: {integrity: sha512-l/kMG+z6MB+fKA9KdtyprkTQ1ihlJcBh66cf0HvqGP+rXBbOXX0dpJatjZbHeunvEHoBBS69GYQG5ry78JMy3g==}
|
||||
'@next/swc-linux-arm64-musl@14.2.4':
|
||||
resolution: {integrity: sha512-Alv8/XGSs/ytwQcbCHwze1HmiIkIVhDHYLjczSVrf0Wi2MvKn/blt7+S6FJitj3yTlMwMxII1gIJ9WepI4aZ/A==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@next/swc-linux-x64-gnu@14.1.4':
|
||||
resolution: {integrity: sha512-BapIFZ3ZRnvQ1uWbmqEGJuPT9cgLwvKtxhK/L2t4QYO7l+/DxXuIGjvp1x8rvfa/x1FFSsipERZK70pewbtJtw==}
|
||||
'@next/swc-linux-x64-gnu@14.2.4':
|
||||
resolution: {integrity: sha512-ze0ShQDBPCqxLImzw4sCdfnB3lRmN3qGMB2GWDRlq5Wqy4G36pxtNOo2usu/Nm9+V2Rh/QQnrRc2l94kYFXO6Q==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@next/swc-linux-x64-musl@14.1.4':
|
||||
resolution: {integrity: sha512-mqVxTwk4XuBl49qn2A5UmzFImoL1iLm0KQQwtdRJRKl21ylQwwGCxJtIYo2rbfkZHoSKlh/YgztY0qH3wG1xIg==}
|
||||
'@next/swc-linux-x64-musl@14.2.4':
|
||||
resolution: {integrity: sha512-8dwC0UJoc6fC7PX70csdaznVMNr16hQrTDAMPvLPloazlcaWfdPogq+UpZX6Drqb1OBlwowz8iG7WR0Tzk/diQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@next/swc-win32-arm64-msvc@14.1.4':
|
||||
resolution: {integrity: sha512-xzxF4ErcumXjO2Pvg/wVGrtr9QQJLk3IyQX1ddAC/fi6/5jZCZ9xpuL9Tzc4KPWMFq8GGWFVDMshZOdHGdkvag==}
|
||||
'@next/swc-win32-arm64-msvc@14.2.4':
|
||||
resolution: {integrity: sha512-jxyg67NbEWkDyvM+O8UDbPAyYRZqGLQDTPwvrBBeOSyVWW/jFQkQKQ70JDqDSYg1ZDdl+E3nkbFbq8xM8E9x8A==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@next/swc-win32-ia32-msvc@14.1.4':
|
||||
resolution: {integrity: sha512-WZiz8OdbkpRw6/IU/lredZWKKZopUMhcI2F+XiMAcPja0uZYdMTZQRoQ0WZcvinn9xZAidimE7tN9W5v9Yyfyw==}
|
||||
'@next/swc-win32-ia32-msvc@14.2.4':
|
||||
resolution: {integrity: sha512-twrmN753hjXRdcrZmZttb/m5xaCBFa48Dt3FbeEItpJArxriYDunWxJn+QFXdJ3hPkm4u7CKxncVvnmgQMY1ag==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@next/swc-win32-x64-msvc@14.1.4':
|
||||
resolution: {integrity: sha512-4Rto21sPfw555sZ/XNLqfxDUNeLhNYGO2dlPqsnuCg8N8a2a9u1ltqBOPQ4vj1Gf7eJC0W2hHG2eYUHuiXgY2w==}
|
||||
'@next/swc-win32-x64-msvc@14.2.4':
|
||||
resolution: {integrity: sha512-tkLrjBzqFTP8DVrAAQmZelEahfR9OxWpFR++vAI9FBhCiIxtwHwBHC23SBHCTURBtwB4kc/x44imVOnkKGNVGg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
@ -469,9 +469,15 @@ packages:
|
||||
'@rushstack/eslint-patch@1.8.0':
|
||||
resolution: {integrity: sha512-0HejFckBN2W+ucM6cUOlwsByTKt9/+0tWhqUffNIcHqCXkthY/mZ7AuYPK/2IIaGWhdl0h+tICDO0ssLMd6XMQ==}
|
||||
|
||||
'@swc/counter@0.1.3':
|
||||
resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
|
||||
|
||||
'@swc/helpers@0.5.2':
|
||||
resolution: {integrity: sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==}
|
||||
|
||||
'@swc/helpers@0.5.5':
|
||||
resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==}
|
||||
|
||||
'@tailwindcss/aspect-ratio@0.4.2':
|
||||
resolution: {integrity: sha512-8QPrypskfBa7QIMuKHg2TA7BqES6vhBrDLOv8Unb6FcFyd3TjKbc6lcmb9UPQHxfl24sXoJ41ux/H7qQQvfaSQ==}
|
||||
peerDependencies:
|
||||
@ -939,8 +945,8 @@ packages:
|
||||
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
eslint-config-next@14.1.4:
|
||||
resolution: {integrity: sha512-cihIahbhYAWwXJwZkAaRPpUi5t9aOi/HdfWXOjZeUOqNWXHD8X22kd1KG58Dc3MVaRx3HoR/oMGk2ltcrqDn8g==}
|
||||
eslint-config-next@14.2.4:
|
||||
resolution: {integrity: sha512-Qr0wMgG9m6m4uYy2jrYJmyuNlYZzPRQq5Kvb9IDlYwn+7yq6W6sfMNFgb+9guM1KYwuIo6TIaiFhZJ6SnQ/Efw==}
|
||||
peerDependencies:
|
||||
eslint: ^7.23.0 || ^8.0.0
|
||||
typescript: '>=3.3.1'
|
||||
@ -1568,18 +1574,21 @@ packages:
|
||||
natural-compare@1.4.0:
|
||||
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
||||
|
||||
next@14.1.4:
|
||||
resolution: {integrity: sha512-1WTaXeSrUwlz/XcnhGTY7+8eiaFvdet5z9u3V2jb+Ek1vFo0VhHKSAIJvDWfQpttWjnyw14kBeq28TPq7bTeEQ==}
|
||||
next@14.2.4:
|
||||
resolution: {integrity: sha512-R8/V7vugY+822rsQGQCjoLhMuC9oFj9SOi4Cl4b2wjDrseD0LRZ10W7R6Czo4w9ZznVSshKjuIomsRjvm9EKJQ==}
|
||||
engines: {node: '>=18.17.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.1.0
|
||||
'@playwright/test': ^1.41.2
|
||||
react: ^18.2.0
|
||||
react-dom: ^18.2.0
|
||||
sass: ^1.3.0
|
||||
peerDependenciesMeta:
|
||||
'@opentelemetry/api':
|
||||
optional: true
|
||||
'@playwright/test':
|
||||
optional: true
|
||||
sass:
|
||||
optional: true
|
||||
|
||||
@ -2406,37 +2415,37 @@ snapshots:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
|
||||
'@next/env@14.1.4': {}
|
||||
'@next/env@14.2.4': {}
|
||||
|
||||
'@next/eslint-plugin-next@14.1.4':
|
||||
'@next/eslint-plugin-next@14.2.4':
|
||||
dependencies:
|
||||
glob: 10.3.10
|
||||
|
||||
'@next/swc-darwin-arm64@14.1.4':
|
||||
'@next/swc-darwin-arm64@14.2.4':
|
||||
optional: true
|
||||
|
||||
'@next/swc-darwin-x64@14.1.4':
|
||||
'@next/swc-darwin-x64@14.2.4':
|
||||
optional: true
|
||||
|
||||
'@next/swc-linux-arm64-gnu@14.1.4':
|
||||
'@next/swc-linux-arm64-gnu@14.2.4':
|
||||
optional: true
|
||||
|
||||
'@next/swc-linux-arm64-musl@14.1.4':
|
||||
'@next/swc-linux-arm64-musl@14.2.4':
|
||||
optional: true
|
||||
|
||||
'@next/swc-linux-x64-gnu@14.1.4':
|
||||
'@next/swc-linux-x64-gnu@14.2.4':
|
||||
optional: true
|
||||
|
||||
'@next/swc-linux-x64-musl@14.1.4':
|
||||
'@next/swc-linux-x64-musl@14.2.4':
|
||||
optional: true
|
||||
|
||||
'@next/swc-win32-arm64-msvc@14.1.4':
|
||||
'@next/swc-win32-arm64-msvc@14.2.4':
|
||||
optional: true
|
||||
|
||||
'@next/swc-win32-ia32-msvc@14.1.4':
|
||||
'@next/swc-win32-ia32-msvc@14.2.4':
|
||||
optional: true
|
||||
|
||||
'@next/swc-win32-x64-msvc@14.1.4':
|
||||
'@next/swc-win32-x64-msvc@14.2.4':
|
||||
optional: true
|
||||
|
||||
'@nodelib/fs.scandir@2.1.5':
|
||||
@ -2597,10 +2606,17 @@ snapshots:
|
||||
|
||||
'@rushstack/eslint-patch@1.8.0': {}
|
||||
|
||||
'@swc/counter@0.1.3': {}
|
||||
|
||||
'@swc/helpers@0.5.2':
|
||||
dependencies:
|
||||
tslib: 2.6.2
|
||||
|
||||
'@swc/helpers@0.5.5':
|
||||
dependencies:
|
||||
'@swc/counter': 0.1.3
|
||||
tslib: 2.6.2
|
||||
|
||||
'@tailwindcss/aspect-ratio@0.4.2(tailwindcss@3.4.1)':
|
||||
dependencies:
|
||||
tailwindcss: 3.4.1
|
||||
@ -3148,9 +3164,9 @@ snapshots:
|
||||
|
||||
escape-string-regexp@4.0.0: {}
|
||||
|
||||
eslint-config-next@14.1.4(eslint@8.57.0)(typescript@5.4.3):
|
||||
eslint-config-next@14.2.4(eslint@8.57.0)(typescript@5.4.3):
|
||||
dependencies:
|
||||
'@next/eslint-plugin-next': 14.1.4
|
||||
'@next/eslint-plugin-next': 14.2.4
|
||||
'@rushstack/eslint-patch': 1.8.0
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.3)
|
||||
eslint: 8.57.0
|
||||
@ -3454,9 +3470,9 @@ snapshots:
|
||||
|
||||
functions-have-names@1.2.3: {}
|
||||
|
||||
geist@1.3.0(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)):
|
||||
geist@1.3.0(next@14.2.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)):
|
||||
dependencies:
|
||||
next: 14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
next: 14.2.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
|
||||
get-east-asian-width@1.2.0: {}
|
||||
|
||||
@ -3869,10 +3885,10 @@ snapshots:
|
||||
|
||||
natural-compare@1.4.0: {}
|
||||
|
||||
next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
|
||||
next@14.2.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
|
||||
dependencies:
|
||||
'@next/env': 14.1.4
|
||||
'@swc/helpers': 0.5.2
|
||||
'@next/env': 14.2.4
|
||||
'@swc/helpers': 0.5.5
|
||||
busboy: 1.6.0
|
||||
caniuse-lite: 1.0.30001600
|
||||
graceful-fs: 4.2.11
|
||||
@ -3881,15 +3897,15 @@ snapshots:
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
styled-jsx: 5.1.1(react@18.2.0)
|
||||
optionalDependencies:
|
||||
'@next/swc-darwin-arm64': 14.1.4
|
||||
'@next/swc-darwin-x64': 14.1.4
|
||||
'@next/swc-linux-arm64-gnu': 14.1.4
|
||||
'@next/swc-linux-arm64-musl': 14.1.4
|
||||
'@next/swc-linux-x64-gnu': 14.1.4
|
||||
'@next/swc-linux-x64-musl': 14.1.4
|
||||
'@next/swc-win32-arm64-msvc': 14.1.4
|
||||
'@next/swc-win32-ia32-msvc': 14.1.4
|
||||
'@next/swc-win32-x64-msvc': 14.1.4
|
||||
'@next/swc-darwin-arm64': 14.2.4
|
||||
'@next/swc-darwin-x64': 14.2.4
|
||||
'@next/swc-linux-arm64-gnu': 14.2.4
|
||||
'@next/swc-linux-arm64-musl': 14.2.4
|
||||
'@next/swc-linux-x64-gnu': 14.2.4
|
||||
'@next/swc-linux-x64-musl': 14.2.4
|
||||
'@next/swc-win32-arm64-msvc': 14.2.4
|
||||
'@next/swc-win32-ia32-msvc': 14.2.4
|
||||
'@next/swc-win32-x64-msvc': 14.2.4
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- babel-plugin-macros
|
||||
|
Loading…
x
Reference in New Issue
Block a user