= (data) => {
+ if (data.password !== data.confirmPassword) {
+ alert('Passwords do not match.');
+ return;
+ }
+ onSuccess();
+ };
+
+ return (
+
+ );
+};
+
+export default ResetPasswordForm;
diff --git a/src/app/(auth)/resetpasswor/_components/success.test.tsx b/src/app/(auth)/resetpasswor/_components/success.test.tsx
new file mode 100644
index 0000000..4cfbae4
--- /dev/null
+++ b/src/app/(auth)/resetpasswor/_components/success.test.tsx
@@ -0,0 +1,34 @@
+import { render, screen } from '@testing-library/react';
+import ResetPasswordSuccess from '../_components/success';
+import React, { ReactNode } from 'react';
+
+jest.mock('styled-theming', () => ({
+ theme: jest.fn().mockImplementation((_, values) => values.mode),
+}));
+
+jest.mock('@/shared/components/account/AccountElements', () => ({
+ AccountContent: ({ children }: { children: ReactNode }) => {children}
,
+ AccountHead: ({ children }: { children: ReactNode }) => {children}
,
+ AccountLogo: ({ children }: { children: ReactNode }) => {children}
,
+ AccountLogoAccent: ({ children }: { children: ReactNode }) => (
+ {children}
+ ),
+ AccountTitle: ({ children }: { children: ReactNode }) => {children}
,
+ AccountButton: ({ children, ...props }: { children: ReactNode }) => (
+
+ ),
+}));
+
+jest.mock('next/link', () => {
+ return ({ children, ...props }: { children: ReactNode }) => {children};
+});
+
+describe('PasswordResetSuccess', () => {
+ it('navigates back to login on button click', () => {
+ render();
+
+ // Find the link by text and check its href attribute
+ const backButtonLink = screen.getByRole('link', { name: /back to login/i });
+ expect(backButtonLink).toHaveAttribute('href', '/login');
+ });
+});
diff --git a/src/app/(auth)/resetpasswor/_components/success.tsx b/src/app/(auth)/resetpasswor/_components/success.tsx
new file mode 100644
index 0000000..d1fda14
--- /dev/null
+++ b/src/app/(auth)/resetpasswor/_components/success.tsx
@@ -0,0 +1,36 @@
+import {
+ AccountContent,
+ AccountHead,
+ AccountLogo,
+ AccountLogoAccent,
+ AccountTitle,
+ AccountButton,
+} from '@/shared/components/account/AccountElements';
+import successImage from '@/shared/img/success.png';
+import Link from 'next/link';
+
+const ResetPasswordSuccess = () => {
+ return (
+
+

+
+
+
+
+
+ Cool!
+
+
+ Your password has been reset
+
+
+
+
+
+ Back to Login
+
+
+ );
+};
+
+export default ResetPasswordSuccess;
diff --git a/src/app/(auth)/resetpasswor/page.test.tsx b/src/app/(auth)/resetpasswor/page.test.tsx
new file mode 100644
index 0000000..0267e48
--- /dev/null
+++ b/src/app/(auth)/resetpasswor/page.test.tsx
@@ -0,0 +1,116 @@
+import { act } from 'react-dom/test-utils';
+import { screen, render, fireEvent } from '@testing-library/react';
+import { BrowserRouter as Router } from 'react-router-dom';
+import ResetPasswordInitiationPage from './page';
+
+interface IconProps {
+ className?: string;
+}
+
+jest.mock('mdi-react/TrendingUpIcon', () => {
+ return {
+ __esModule: true,
+ default: ({ className }: IconProps) => Mocked Trending Up Icon
,
+ };
+});
+
+jest.mock('mdi-react/TrendingDownIcon', () => {
+ return {
+ __esModule: true,
+ default: ({ className }: IconProps) => (
+ Mocked Trending Down Icon
+ ),
+ };
+});
+
+jest.mock('mdi-react/AccountOutlineIcon', () => {
+ return {
+ __esModule: true,
+ default: () => Mocked Account Outline Icon
,
+ };
+});
+
+jest.mock('./_components/form', () => ({
+ __esModule: true,
+ default: ({ onSuccess }: { onSuccess: () => void }) => (
+
+ Mocked Reset Password Form
+
+
+ ),
+}));
+
+jest.mock('./_components/success', () => ({
+ __esModule: true,
+ default: () => Mocked Reset Password Success
,
+}));
+
+describe('ResetPasswordInitiationPage', () => {
+ it('should render the page and show the correct title', async () => {
+ render(
+
+
+
+ );
+
+ const title = screen.getByText(/Enter Your Email/i);
+ expect(title).toBeInTheDocument();
+ });
+
+ it('should allow user to enter email', async () => {
+ render(
+
+
+
+ );
+ const input = screen.getByPlaceholderText('Email');
+
+ await act(async () => {
+ fireEvent.change(input, { target: { value: 'user@example.com' } });
+ });
+ expect(screen.getByDisplayValue('user@example.com')).toBeInTheDocument();
+ });
+
+ it('should navigate to the reset password form page on submit', async () => {
+ render(
+
+
+
+ );
+
+ const input = screen.getByPlaceholderText('Email');
+ const button = screen.getByRole('button', { name: 'Submit' });
+
+ await act(async () => {
+ fireEvent.change(input, { target: { value: 'user@example.com' } });
+ fireEvent.click(button);
+ });
+
+ const form = screen.getByText('Mocked Reset Password Form');
+ expect(form).toBeInTheDocument();
+ });
+
+ it('should navigate to the success page after form submission', async () => {
+ render(
+
+
+
+ );
+
+ const input = screen.getByPlaceholderText('Email');
+ const button = screen.getByRole('button', { name: 'Submit' });
+
+ await act(async () => {
+ fireEvent.change(input, { target: { value: 'user@example.com' } });
+ fireEvent.click(button);
+ });
+
+ const formButton = screen.getByText('Mock Submit');
+ await act(async () => {
+ fireEvent.click(formButton);
+ });
+
+ const successMessage = screen.getByText('Mocked Reset Password Success');
+ expect(successMessage).toBeInTheDocument();
+ });
+});
diff --git a/src/app/(auth)/resetpasswor/page.tsx b/src/app/(auth)/resetpasswor/page.tsx
new file mode 100644
index 0000000..25362ed
--- /dev/null
+++ b/src/app/(auth)/resetpasswor/page.tsx
@@ -0,0 +1,119 @@
+'use client';
+
+import { useState, Suspense } from 'react';
+import {
+ AccountWrap,
+ AccountContent,
+ AccountCard,
+ AccountHead,
+ AccountLogo,
+ AccountLogoAccent,
+ AccountTitle,
+ AccountButton,
+} from '@/shared/components/account/AccountElements';
+import {
+ FormGroup,
+ FormGroupField,
+ FormGroupIcon,
+ FormGroupLabel,
+} from '@/shared/components/form/FormElements';
+import AccountOutlineIcon from 'mdi-react/AccountOutlineIcon';
+import FormField from '@/shared/components/form/FormHookField';
+import { useForm } from 'react-hook-form';
+import { emailPattern } from '@/shared/utils/helpers';
+import { EMAIL } from '@/shared/constants/storage';
+import Link from 'next/link';
+import dynamic from 'next/dynamic';
+
+const ResetPasswordForm = dynamic(() => import('./_components/form'), { ssr: false });
+const ResetPasswordSuccess = dynamic(() => import('./_components/success'), { ssr: false });
+
+interface FormData {
+ email: string;
+}
+
+const ResetPasswordInitiationPage = () => {
+ const [showEmailHint, setShowEmailHint] = useState(false);
+ const [step, setStep] = useState('init'); // 使用状态控制显示的步骤
+ const {
+ control,
+ formState: { errors },
+ handleSubmit,
+ } = useForm();
+
+ const onSubmit = (data: FormData) => {
+ setStep('form');
+ };
+
+ return (
+
+
+
+ {step !== 'success' && (
+
+
+ {step === 'init' ? 'Enter Your Email' : 'Reset Password'}
+
+
+ BeeQuant
+ AI
+
+
+ Trading smart, trading with BeeQuant AI
+
+ )}
+ {step === 'init' ? (
+
+ ) : step === 'form' ? (
+ Loading...}>
+ setStep('success')} />
+
+ ) : (
+ Loading...}>
+
+
+ )}
+
+
+
+ );
+};
+
+export default ResetPasswordInitiationPage;
diff --git a/src/graphql/auth.ts b/src/graphql/auth.ts
index d874837..a67147d 100644
--- a/src/graphql/auth.ts
+++ b/src/graphql/auth.ts
@@ -19,3 +19,13 @@ export const USER_REGISTER = gql`
}
}
`;
+
+export const USER_RESETPASSWOR = gql`
+ mutation Resetpasswor($input: CreateUserInput!) {
+ resetpasswor(input: $input) {
+ code
+ message
+ data
+ }
+ }
+`;
diff --git a/src/routes/routeConfig.ts b/src/routes/routeConfig.ts
index 11968d1..e947641 100644
--- a/src/routes/routeConfig.ts
+++ b/src/routes/routeConfig.ts
@@ -13,6 +13,9 @@ import ExchangeDetails from 'app/(protected)/crypto/exchange/details/page';
import PriceDetails from 'app/(protected)/crypto/price/details/page';
import BotDetail from 'app/(protected)/bot/details/page';
import BotCreate from 'app/(protected)/bot/create/page';
+import ResetPassword from 'app/(auth)/resetpasswor/page';
+import ResetPasswordForm from 'app/(auth)/resetpasswor/_components/form';
+import PasswordResetSuccess from 'app/(auth)/resetpasswor/_components/success';
interface IRoute {
path: string;
@@ -30,6 +33,9 @@ export const ROUTE_KEY = {
LOGIN: 'login',
REGISTER: 'register',
SETTINGS: 'settings',
+ RESET_PASSWORD: 'resetpasswor',
+ RESET_PASSWORD_FORM: 'reset_password_form',
+ PASSWORD_RESET_SUCCESS: 'password_reset_success',
BOT_DASHBOARD: 'bot_dashboard',
BOT_MANAGEMENT: 'bot_management',
BOT_CREATE: 'bot_create',
@@ -53,6 +59,28 @@ export const PUBLIC_ROUTE_CONFIG: Record = {
title: 'Register - BeeQuant',
component: Register,
},
+
+ [ROUTE_KEY.RESET_PASSWORD]: {
+ path: '/resetpasswor',
+ name: 'resetpasswor',
+ title: 'Register - BeeQuant',
+ component: ResetPassword,
+ },
+
+ [ROUTE_KEY.RESET_PASSWORD_FORM]: {
+ path: '/resetpasswor/form',
+ name: 'Reset Password Form',
+ title: 'Enter New Password - BeeQuant',
+ component: ResetPasswordForm,
+ },
+
+ [ROUTE_KEY.PASSWORD_RESET_SUCCESS]: {
+ path: '/resetpasswor/success',
+ name: 'Password Reset Success',
+ title: 'Password Reset Success - BeeQuant',
+ component: PasswordResetSuccess,
+ },
+
[ROUTE_KEY.PAGE_404]: {
path: '/404',
name: '404',
diff --git a/yarn.lock b/yarn.lock
index 94ee1b9..5036730 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1170,10 +1170,10 @@
"@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14"
-"@next/env@14.1.3":
- version "14.1.3"
- resolved "https://registry.npmjs.org/@next/env/-/env-14.1.3.tgz"
- integrity sha512-VhgXTvrgeBRxNPjyfBsDIMvgsKDxjlpw4IAUsHCX8Gjl1vtHUYRT3+xfQ/wwvLPDd/6kqfLqk9Pt4+7gysuCKQ==
+"@next/env@14.2.3":
+ version "14.2.3"
+ resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.3.tgz#d6def29d1c763c0afb397343a15a82e7d92353a0"
+ integrity sha512-W7fd7IbkfmeeY2gXrzJYDx8D2lWKbVoTIj1o1ScPHNzvp30s1AuoEFSdr39bC5sjxJaxTtq3OTCZboNp0lNWHA==
"@next/eslint-plugin-next@14.1.3":
version "14.1.3"
@@ -1182,50 +1182,50 @@
dependencies:
glob "10.3.10"
-"@next/swc-darwin-arm64@14.1.3":
- version "14.1.3"
- resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.3.tgz#b4c218fdb49275972d91e9a9a0ccadba243b6739"
- integrity sha512-LALu0yIBPRiG9ANrD5ncB3pjpO0Gli9ZLhxdOu6ZUNf3x1r3ea1rd9Q+4xxUkGrUXLqKVK9/lDkpYIJaCJ6AHQ==
-
-"@next/swc-darwin-x64@14.1.3":
- version "14.1.3"
- resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.3.tgz#aa0d4357179d68daaa6f400708b76666708ffec9"
- integrity sha512-E/9WQeXxkqw2dfcn5UcjApFgUq73jqNKaE5bysDm58hEUdUGedVrnRhblhJM7HbCZNhtVl0j+6TXsK0PuzXTCg==
-
-"@next/swc-linux-arm64-gnu@14.1.3":
- version "14.1.3"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.3.tgz#1ba8df39c04368ede185f268c3a817a8f4290e4c"
- integrity sha512-USArX9B+3rZSXYLFvgy0NVWQgqh6LHWDmMt38O4lmiJNQcwazeI6xRvSsliDLKt+78KChVacNiwvOMbl6g6BBw==
-
-"@next/swc-linux-arm64-musl@14.1.3":
- version "14.1.3"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.3.tgz#2fa8fe435862eb186aca6d6068c8aef2126ab11e"
- integrity sha512-esk1RkRBLSIEp1qaQXv1+s6ZdYzuVCnDAZySpa62iFTMGTisCyNQmqyCTL9P+cLJ4N9FKCI3ojtSfsyPHJDQNw==
-
-"@next/swc-linux-x64-gnu@14.1.3":
- version "14.1.3"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.3.tgz#57a687b44337af219e07a79ecc8c63a3c1b2d020"
- integrity sha512-8uOgRlYEYiKo0L8YGeS+3TudHVDWDjPVDUcST+z+dUzgBbTEwSSIaSgF/vkcC1T/iwl4QX9iuUyUdQEl0Kxalg==
-
-"@next/swc-linux-x64-musl@14.1.3":
- version "14.1.3"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.3.tgz#8c057f8f7fb9679915df25eda6ab0ea1b7af85ff"
- integrity sha512-DX2zqz05ziElLoxskgHasaJBREC5Y9TJcbR2LYqu4r7naff25B4iXkfXWfcp69uD75/0URmmoSgT8JclJtrBoQ==
-
-"@next/swc-win32-arm64-msvc@14.1.3":
- version "14.1.3"
- resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.3.tgz#5367333e701f722009592013502aa8e735bee782"
- integrity sha512-HjssFsCdsD4GHstXSQxsi2l70F/5FsRTRQp8xNgmQs15SxUfUJRvSI9qKny/jLkY3gLgiCR3+6A7wzzK0DBlfA==
-
-"@next/swc-win32-ia32-msvc@14.1.3":
- version "14.1.3"
- resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.3.tgz#dc455021fee85e037f6fb4134e85895dce5a0495"
- integrity sha512-DRuxD5axfDM1/Ue4VahwSxl1O5rn61hX8/sF0HY8y0iCbpqdxw3rB3QasdHn/LJ6Wb2y5DoWzXcz3L1Cr+Thrw==
-
-"@next/swc-win32-x64-msvc@14.1.3":
- version "14.1.3"
- resolved "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.3.tgz"
- integrity sha512-uC2DaDoWH7h1P/aJ4Fok3Xiw6P0Lo4ez7NbowW2VGNXw/Xv6tOuLUcxhBYZxsSUJtpeknCi8/fvnSpyCFp4Rcg==
+"@next/swc-darwin-arm64@14.2.3":
+ version "14.2.3"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.3.tgz#db1a05eb88c0224089b815ad10ac128ec79c2cdb"
+ integrity sha512-3pEYo/RaGqPP0YzwnlmPN2puaF2WMLM3apt5jLW2fFdXD9+pqcoTzRk+iZsf8ta7+quAe4Q6Ms0nR0SFGFdS1A==
+
+"@next/swc-darwin-x64@14.2.3":
+ version "14.2.3"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.3.tgz#a3f8af05b5f9a52ac3082e66ac29e125ab1d7b9c"
+ integrity sha512-6adp7waE6P1TYFSXpY366xwsOnEXM+y1kgRpjSRVI2CBDOcbRjsJ67Z6EgKIqWIue52d2q/Mx8g9MszARj8IEA==
+
+"@next/swc-linux-arm64-gnu@14.2.3":
+ version "14.2.3"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.3.tgz#4e63f43879285b52554bfd39e6e0cc78a9b27bbf"
+ integrity sha512-cuzCE/1G0ZSnTAHJPUT1rPgQx1w5tzSX7POXSLaS7w2nIUJUD+e25QoXD/hMfxbsT9rslEXugWypJMILBj/QsA==
+
+"@next/swc-linux-arm64-musl@14.2.3":
+ version "14.2.3"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.3.tgz#ebdaed26214448b1e6f2c3e8b3cd29bfba387990"
+ integrity sha512-0D4/oMM2Y9Ta3nGuCcQN8jjJjmDPYpHX9OJzqk42NZGJocU2MqhBq5tWkJrUQOQY9N+In9xOdymzapM09GeiZw==
+
+"@next/swc-linux-x64-gnu@14.2.3":
+ version "14.2.3"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.3.tgz#19e3bcc137c3b582a1ab867106817e5c90a20593"
+ integrity sha512-ENPiNnBNDInBLyUU5ii8PMQh+4XLr4pG51tOp6aJ9xqFQ2iRI6IH0Ds2yJkAzNV1CfyagcyzPfROMViS2wOZ9w==
+
+"@next/swc-linux-x64-musl@14.2.3":
+ version "14.2.3"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.3.tgz#794a539b98e064169cf0ff7741b2a4fb16adec7d"
+ integrity sha512-BTAbq0LnCbF5MtoM7I/9UeUu/8ZBY0i8SFjUMCbPDOLv+un67e2JgyN4pmgfXBwy/I+RHu8q+k+MCkDN6P9ViQ==
+
+"@next/swc-win32-arm64-msvc@14.2.3":
+ version "14.2.3"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.3.tgz#eda9fa0fbf1ff9113e87ac2668ee67ce9e5add5a"
+ integrity sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==
+
+"@next/swc-win32-ia32-msvc@14.2.3":
+ version "14.2.3"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.3.tgz#7c1190e3f640ab16580c6bdbd7d0e766b9920457"
+ integrity sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==
+
+"@next/swc-win32-x64-msvc@14.2.3":
+ version "14.2.3"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.3.tgz#2be4e39ee25bfbd85be78eea17c0e7751dc4323c"
+ integrity sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
@@ -1372,11 +1372,17 @@
dependencies:
"@sinonjs/commons" "^3.0.0"
-"@swc/helpers@0.5.2":
- version "0.5.2"
- resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz"
- integrity sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==
+"@swc/counter@^0.1.3":
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.3.tgz#cc7463bd02949611c6329596fccd2b0ec782b0e9"
+ integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==
+
+"@swc/helpers@0.5.5":
+ version "0.5.5"
+ resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.5.tgz#12689df71bfc9b21c4f4ca00ae55f2f16c8b77c0"
+ integrity sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==
dependencies:
+ "@swc/counter" "^0.1.3"
tslib "^2.4.0"
"@swc/helpers@^0.5.0":
@@ -5550,28 +5556,28 @@ negotiator@0.6.3, negotiator@^0.6.3:
resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz"
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
-next@^14.1.3:
- version "14.1.3"
- resolved "https://registry.npmjs.org/next/-/next-14.1.3.tgz"
- integrity sha512-oexgMV2MapI0UIWiXKkixF8J8ORxpy64OuJ/J9oVUmIthXOUCcuVEZX+dtpgq7wIfIqtBwQsKEDXejcjTsan9g==
+next@^14.2.3:
+ version "14.2.3"
+ resolved "https://registry.yarnpkg.com/next/-/next-14.2.3.tgz#f117dd5d5f20c307e7b8e4f9c1c97d961008925d"
+ integrity sha512-dowFkFTR8v79NPJO4QsBUtxv0g9BrS/phluVpMAt2ku7H+cbcBJlopXjkWlwxrk/xGqMemr7JkGPGemPrLLX7A==
dependencies:
- "@next/env" "14.1.3"
- "@swc/helpers" "0.5.2"
+ "@next/env" "14.2.3"
+ "@swc/helpers" "0.5.5"
busboy "1.6.0"
caniuse-lite "^1.0.30001579"
graceful-fs "^4.2.11"
postcss "8.4.31"
styled-jsx "5.1.1"
optionalDependencies:
- "@next/swc-darwin-arm64" "14.1.3"
- "@next/swc-darwin-x64" "14.1.3"
- "@next/swc-linux-arm64-gnu" "14.1.3"
- "@next/swc-linux-arm64-musl" "14.1.3"
- "@next/swc-linux-x64-gnu" "14.1.3"
- "@next/swc-linux-x64-musl" "14.1.3"
- "@next/swc-win32-arm64-msvc" "14.1.3"
- "@next/swc-win32-ia32-msvc" "14.1.3"
- "@next/swc-win32-x64-msvc" "14.1.3"
+ "@next/swc-darwin-arm64" "14.2.3"
+ "@next/swc-darwin-x64" "14.2.3"
+ "@next/swc-linux-arm64-gnu" "14.2.3"
+ "@next/swc-linux-arm64-musl" "14.2.3"
+ "@next/swc-linux-x64-gnu" "14.2.3"
+ "@next/swc-linux-x64-musl" "14.2.3"
+ "@next/swc-win32-arm64-msvc" "14.2.3"
+ "@next/swc-win32-ia32-msvc" "14.2.3"
+ "@next/swc-win32-x64-msvc" "14.2.3"
node-abort-controller@^3.1.1:
version "3.1.1"