diff --git a/.nvmrc b/.nvmrc
index 3c032078a..209e3ef4b 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-18
+20
diff --git a/app/(auth)/authorize/page.tsx b/app/(auth)/authorize/page.tsx
index 723f8befb..806e5c47e 100644
--- a/app/(auth)/authorize/page.tsx
+++ b/app/(auth)/authorize/page.tsx
@@ -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');
diff --git a/app/(auth)/login/page.tsx b/app/(auth)/login/page.tsx
index dce7c33dd..d8748e347 100644
--- a/app/(auth)/login/page.tsx
+++ b/app/(auth)/login/page.tsx
@@ -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 (
diff --git a/app/layout.tsx b/app/layout.tsx
index df9c59c6f..468672c3d 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -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 (
-
-
- {children}
-
+
+
+
+
+ {children}
+
+
+
);
diff --git a/components/auth/actions.ts b/components/auth/actions.ts
index 0692e039e..9f5542d4d 100644
--- a/components/auth/actions.ts
+++ b/components/auth/actions.ts
@@ -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;
+ }
+}
diff --git a/components/auth/login.tsx b/components/auth/login.tsx
index 8346013e1..f63123e45 100644
--- a/components/auth/login.tsx
+++ b/components/auth/login.tsx
@@ -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 {
diff --git a/components/profile/popover.tsx b/components/profile/popover.tsx
index 2af579db1..7f969a433 100644
--- a/components/profile/popover.tsx
+++ b/components/profile/popover.tsx
@@ -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 (
@@ -53,22 +55,29 @@ const ProfilePopover = ({ menu }: ProfilePopoverProps) => {
My Account
-
+ {!isAuthenticated && !loading &&
}
{menu.length ? (
-
+
+ {isAuthenticated && (
+ -
+
+ My Orders
+
+
+ )}
{menu.map((menuItem) => (
-
-
{menuItem.title}
-
+
))}
diff --git a/contexts/auth-context.tsx b/contexts/auth-context.tsx
new file mode 100644
index 000000000..0034a0b21
--- /dev/null
+++ b/contexts/auth-context.tsx
@@ -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({
+ 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 (
+ {children}
+ );
+}
+
+export default AuthContext;
diff --git a/hooks/use-auth.ts b/hooks/use-auth.ts
new file mode 100644
index 000000000..75fb4d7f0
--- /dev/null
+++ b/hooks/use-auth.ts
@@ -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;
+}
diff --git a/lib/shopify/auth.ts b/lib/shopify/auth.ts
index e115b4b20..b29024857 100644
--- a/lib/shopify/auth.ts
+++ b/lib/shopify/auth.ts
@@ -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}`);
diff --git a/package.json b/package.json
index f7c29d18a..976bad353 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3125ab071..a8d1f95f5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -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