From 057aab9ec5df67433462ac37b2157e07674410eb Mon Sep 17 00:00:00 2001 From: gloginov Date: Fri, 27 Sep 2024 10:37:18 +0500 Subject: [PATCH 1/7] [SOK-16] +add backendApi +create axios interceptors +add userReducer and create function for use yandex api +add env *update SignIn.tsx for use backendApi *update SignUp.tsx for use backendApi *format and lint --- .env.sample | 5 + package.json | 5 - packages/client/package.json | 12 ++- packages/client/src/api/backendApi.ts | 29 +++++ packages/client/src/app/App.test.tsx | 8 +- packages/client/src/app/App.tsx | 2 +- .../src/components/ui/Button/Button.tsx | 35 ++++-- packages/client/src/index.css | 0 .../client/src/layouts/private-layout.tsx | 22 ++++ packages/client/src/main.tsx | 9 +- packages/client/src/pages/Game/Game.tsx | 9 +- packages/client/src/pages/Profile/Profile.tsx | 12 ++- packages/client/src/pages/SignIn/SignIn.tsx | 49 ++++++++- packages/client/src/pages/SignUp/SignUp.tsx | 79 +++++++++++++- packages/client/src/store/index.ts | 30 ++++++ .../client/src/store/reducers/user-reducer.ts | 101 ++++++++++++++++++ packages/client/vite.config.ts | 1 + 17 files changed, 377 insertions(+), 31 deletions(-) create mode 100644 packages/client/src/api/backendApi.ts delete mode 100644 packages/client/src/index.css create mode 100644 packages/client/src/layouts/private-layout.tsx create mode 100644 packages/client/src/store/index.ts create mode 100644 packages/client/src/store/reducers/user-reducer.ts diff --git a/.env.sample b/.env.sample index 2b2b0e0..4840240 100644 --- a/.env.sample +++ b/.env.sample @@ -4,3 +4,8 @@ POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres POSTGRES_DB=postgres POSTGRES_PORT=5432 + +TRAEFIK_NETWORK_NAME=traefik_traefik +DOCKER_BUILDKIT=1 #Build only stages required for target +COMPOSE_FILE=docker-compose.yml:docker-compose.dev.yml +VITE_AUTH_URL='https://ya-praktikum.tech/api/v2' diff --git a/package.json b/package.json index b2cb0a8..b354d47 100644 --- a/package.json +++ b/package.json @@ -27,10 +27,5 @@ "husky": "^6.0.0", "lefthook": "^1.7.15", "lerna": "^5.4.3" - }, - "dependencies": { - "normalize": "^0.3.1", - "react-router-dom": "^6.26.2", - "sass": "^1.79.1" } } diff --git a/packages/client/package.json b/packages/client/package.json index 7947a09..e0895fb 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,5 +1,5 @@ { - "name": "Falcon-Tanks", + "name": "falcon-tanks", "version": "1.0.0", "type": "module", "scripts": { @@ -18,6 +18,9 @@ "react-dom": "^18.2.0" }, "devDependencies": { + "react-redux": "^9.1.2", + "axios": "^1.7.7", + "@reduxjs/toolkit": "^2.2.7", "@testing-library/react": "^13.3.0", "@types/jest": "^28.1.8", "@types/react": "^18.0.17", @@ -28,11 +31,14 @@ "eslint": "^8.23.0", "jest": "^28", "jest-environment-jsdom": "^29.0.1", - "lefthook": "^1.3.9", + "lefthook": "^1.7.15", "prettier": "^2.7.1", "ts-jest": "^28.0.8", "typescript": "^4.8.2", - "vite": "^3.0.7" + "vite": "^3.0.7", + "normalize": "^0.3.1", + "react-router-dom": "^6.26.2", + "sass": "^1.79.1" }, "license": "MIT" } diff --git a/packages/client/src/api/backendApi.ts b/packages/client/src/api/backendApi.ts new file mode 100644 index 0000000..7dee2ee --- /dev/null +++ b/packages/client/src/api/backendApi.ts @@ -0,0 +1,29 @@ +import axios, { AxiosError, AxiosResponse } from 'axios' + +const instance = axios.create({ + baseURL: import.meta.env.VITE_AUTH_URL, + headers: { + 'Content-Type': 'application/json', + }, + withCredentials: true, +}) + +instance.interceptors.response.use( + function (response: AxiosResponse) { + return response + }, + function (error: AxiosError) { + // if app get response code 401 (died token), redirect user to sign-in form + if (error.response?.status === 401) { + localStorage.removeItem('user') + // save page where we get 401 and redirect after login + window.location.href = '/sign-in?redirectUrl=' + window.location.pathname + } + + if (axios.isCancel(error)) return Promise.reject(error) + + return Promise.reject(error) + } +) + +export default instance diff --git a/packages/client/src/app/App.test.tsx b/packages/client/src/app/App.test.tsx index ad5ab4d..ccc7648 100644 --- a/packages/client/src/app/App.test.tsx +++ b/packages/client/src/app/App.test.tsx @@ -1,10 +1,9 @@ -/* eslint-disable */ -import App from './App' -import { render, screen } from '@testing-library/react' +// import App from './App' +// import { render, screen } from '@testing-library/react' // const appContent = 'Вот тут будет жить ваше приложение :)' -// @ts-ignore +// @ts-ignore @typescript-eslint/ban-ts-comment global.fetch = jest.fn(() => Promise.resolve({ json: () => Promise.resolve('hey') }) ) @@ -14,6 +13,5 @@ test('Example test', async () => { // expect(screen.getByText(appContent)).toBeDefined() // const { getByAltText } = await render(); // const image = getByAltText('promoImage'); - // @ts-ignore // expect(image.src).toContain('FT-promo'); }) diff --git a/packages/client/src/app/App.tsx b/packages/client/src/app/App.tsx index dae0732..681d6c9 100644 --- a/packages/client/src/app/App.tsx +++ b/packages/client/src/app/App.tsx @@ -1,3 +1,4 @@ +import '@/app/App.scss' import AuthLayout from '@/layouts/AuthLayout/AuthLayout' import PrivateLayout from '@/layouts/PrivateLayout/PrivateLayout' import PublicLayout from '@/layouts/PublicLayout/PublicLayout' @@ -13,7 +14,6 @@ import { Profile } from '@/pages/Profile/Profile' import { SignIn } from '@/pages/SignIn/SignIn' import { SignUp } from '@/pages/SignUp/SignUp' import { Thread } from '@/pages/Thread/Thread' -import '@/scss/styles.scss' import { createBrowserRouter, RouterProvider } from 'react-router-dom' const routerConfig = createBrowserRouter([ diff --git a/packages/client/src/components/ui/Button/Button.tsx b/packages/client/src/components/ui/Button/Button.tsx index 84670b3..2f7a774 100644 --- a/packages/client/src/components/ui/Button/Button.tsx +++ b/packages/client/src/components/ui/Button/Button.tsx @@ -3,18 +3,31 @@ import './Button.scss' export const Button = (props: { text: string - className: string - useFixWidth: boolean - href?: string + className?: string | undefined + useFixWidth?: boolean | undefined + href?: string | undefined + onClick?: (() => Promise) | (() => any) | undefined }) => { - const { text, className, useFixWidth = false, href = '/' } = props + const { text, className, useFixWidth = false, href = '/', onClick } = props return ( - - {text} - + <> + {onClick && typeof onClick === 'function' ? ( + + ) : ( + + {text} + + )} + ) } diff --git a/packages/client/src/index.css b/packages/client/src/index.css deleted file mode 100644 index e69de29..0000000 diff --git a/packages/client/src/layouts/private-layout.tsx b/packages/client/src/layouts/private-layout.tsx new file mode 100644 index 0000000..6b2091c --- /dev/null +++ b/packages/client/src/layouts/private-layout.tsx @@ -0,0 +1,22 @@ +import { useSelector } from 'react-redux' +import { Outlet } from 'react-router-dom' +import { RootState } from '@/store' +import { getUser, UserType } from '@/store/reducers/user-reducer' +import { useEffect } from 'react' +import { useAppDispatch } from '@/store' + +export default function PrivateLayout() { + // get user from store + const user = useSelector(state => state.UserReducer.user) + const dispatch = useAppDispatch() + + useEffect(() => { + // if user is empty call backend + if (user === null) { + dispatch(getUser()) + } + }, [user]) + + // if the user is full, show page + return user === null ?

Загрузка...

: +} diff --git a/packages/client/src/main.tsx b/packages/client/src/main.tsx index dbcdb7c..d3075e7 100644 --- a/packages/client/src/main.tsx +++ b/packages/client/src/main.tsx @@ -1,10 +1,15 @@ import React from 'react' import ReactDOM from 'react-dom/client' +import { Provider } from 'react-redux' +import { store } from '@/store' + import App from './app/App' -import './index.css' +import '@/scss/styles.scss' ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( - + + + ) diff --git a/packages/client/src/pages/Game/Game.tsx b/packages/client/src/pages/Game/Game.tsx index 908d885..6e8b4fc 100644 --- a/packages/client/src/pages/Game/Game.tsx +++ b/packages/client/src/pages/Game/Game.tsx @@ -1,3 +1,10 @@ +import { Link } from 'react-router-dom' + export const Game = () => { - return <>Тут будет игра + return ( + <> + Тут будет игра + Forum + + ) } diff --git a/packages/client/src/pages/Profile/Profile.tsx b/packages/client/src/pages/Profile/Profile.tsx index 275e581..84fd01e 100644 --- a/packages/client/src/pages/Profile/Profile.tsx +++ b/packages/client/src/pages/Profile/Profile.tsx @@ -1,3 +1,13 @@ +import { logoutUser } from '@/store/reducers/user-reducer' +import { useAppDispatch } from '@/store' + export const Profile = () => { - return <>Страница профиля + const dispatch = useAppDispatch() + + return ( + <> + Страница профиля + + + ) } diff --git a/packages/client/src/pages/SignIn/SignIn.tsx b/packages/client/src/pages/SignIn/SignIn.tsx index 9e97854..dbc3c1b 100644 --- a/packages/client/src/pages/SignIn/SignIn.tsx +++ b/packages/client/src/pages/SignIn/SignIn.tsx @@ -1,3 +1,50 @@ +import { useState } from 'react' +import { useAppDispatch } from '@/store' +import { signInUser } from '@/store/reducers/user-reducer' +import { Button } from '@/components/ui/Button/Button' +import { useSearchParams } from 'react-router-dom' + export const SignIn = () => { - return <>Тут форма входа + const [form, setForm] = useState({ login: '', password: '' }) + const [searchParams] = useSearchParams() + const [query] = useState(searchParams.get('redirectUrl')) + const dispatch = useAppDispatch() + + const handleForm = (name: string, value: string) => { + setForm({ ...form, [name]: value }) + } + + const handleSubmit = () => dispatch(signInUser(form, query)) + + return ( + <> +
{ + e.preventDefault() + }}> + + +
+ + + ) } diff --git a/packages/client/src/store/index.ts b/packages/client/src/store/index.ts new file mode 100644 index 0000000..1af12dc --- /dev/null +++ b/packages/client/src/store/index.ts @@ -0,0 +1,30 @@ +import { configureStore } from '@reduxjs/toolkit' +import UserReducer from '@/store/reducers/user-reducer' +import { useDispatch } from 'react-redux' + +import { combineReducers } from '@reduxjs/toolkit' + +const rootReducer = combineReducers({ + UserReducer, +}) +export const store = configureStore({ + reducer: rootReducer, +}) + +window.store = store +declare global { + interface Window { + store: typeof store + } +} + +// Infer the `RootState` and `AppDispatch` types from the store itself +export type RootState = ReturnType +// Inferred type: {posts: PostsState, comment: CommentsState, users: UsersState} +export type AppDispatch = typeof store.dispatch +export const useAppDispatch = useDispatch.withTypes() +export type InferAppActions = T extends { + [keys: string]: (...args: unknown[]) => infer U +} + ? U + : never diff --git a/packages/client/src/store/reducers/user-reducer.ts b/packages/client/src/store/reducers/user-reducer.ts new file mode 100644 index 0000000..a6783b1 --- /dev/null +++ b/packages/client/src/store/reducers/user-reducer.ts @@ -0,0 +1,101 @@ +import { createSlice } from '@reduxjs/toolkit' +import { AppDispatch, InferAppActions } from '@/store' +import backendApi from '@/api/backendApi' + +export type UserType = { + avatar: string | null + display_name: string | null + email: string | null + first_name: string | null + id: string | null + login: string | null + phone: string | null + second_name: string | null +} + +const initialState = { + user: null as unknown as UserType, +} + +const slice = createSlice({ + name: 'UserReducer', + initialState, + reducers: { + setUser(state, actions) { + state.user = actions.payload + }, + }, +}) + +const UserReducer = slice.reducer +export const { actions } = slice + +export const getUser = () => async (dispatch: AppDispatch) => { + await backendApi({ + method: 'get', + url: `${import.meta.env.VITE_AUTH_URL}/auth/user`, + }) + .then((data: any) => { + if (data) { + dispatch(actions.setUser(data.data)) + } + }) + .catch(() => {}) +} + +export const logoutUser = () => async (dispatch: AppDispatch) => { + await backendApi({ + method: 'post', + url: `${import.meta.env.VITE_AUTH_URL}/auth/logout`, + }) + .then((data: any) => { + if (data) { + dispatch(actions.setUser(null)) + + window.location.href = '/' + } + }) + .catch(() => {}) +} + +export const signInUser = + (form: { login: string; password: string }, query?: string | null) => + (dispatch: AppDispatch) => { + return backendApi({ + method: 'post', + url: `${import.meta.env.VITE_AUTH_URL}/auth/signin`, + data: form, + }) + .then(data => { + if (data) { + dispatch(actions.setUser(data)) + dispatch(getUser()) + + if (query) { + window.location.href = query + } else { + window.location.href = '/game' + } + } + }) + .catch(() => {}) + } + +export const signUpUser = + (form: { login: string; password: string }) => (dispatch: AppDispatch) => { + backendApi({ + method: 'post', + url: `${import.meta.env.VITE_AUTH_URL}/auth/signup`, + data: form, + }) + .then(data => { + if (data) { + dispatch(actions.setUser(data)) + dispatch(getUser()) + } + }) + .catch(() => {}) + } + +export type ActionsType = InferAppActions +export default UserReducer diff --git a/packages/client/vite.config.ts b/packages/client/vite.config.ts index d273804..3ac4356 100644 --- a/packages/client/vite.config.ts +++ b/packages/client/vite.config.ts @@ -22,4 +22,5 @@ export default defineConfig({ }, }, plugins: [react()], + envDir: '../../', }) From cf1f851728713ccac50f81a455885ad665264d51 Mon Sep 17 00:00:00 2001 From: gloginov Date: Fri, 27 Sep 2024 10:57:44 +0500 Subject: [PATCH 2/7] [SOK-16] *fix lint error *add types from yandex api for user --- packages/client/src/app/App.test.tsx | 1 + .../src/components/ui/Button/Button.tsx | 1 + .../client/src/store/reducers/user-reducer.ts | 31 +++++++++++-------- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/packages/client/src/app/App.test.tsx b/packages/client/src/app/App.test.tsx index ccc7648..b8a177d 100644 --- a/packages/client/src/app/App.test.tsx +++ b/packages/client/src/app/App.test.tsx @@ -3,6 +3,7 @@ // const appContent = 'Вот тут будет жить ваше приложение :)' +// eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore @typescript-eslint/ban-ts-comment global.fetch = jest.fn(() => Promise.resolve({ json: () => Promise.resolve('hey') }) diff --git a/packages/client/src/components/ui/Button/Button.tsx b/packages/client/src/components/ui/Button/Button.tsx index 2f7a774..e0e7c4d 100644 --- a/packages/client/src/components/ui/Button/Button.tsx +++ b/packages/client/src/components/ui/Button/Button.tsx @@ -6,6 +6,7 @@ export const Button = (props: { className?: string | undefined useFixWidth?: boolean | undefined href?: string | undefined + /* eslint-disable @typescript-eslint/no-explicit-any */ onClick?: (() => Promise) | (() => any) | undefined }) => { const { text, className, useFixWidth = false, href = '/', onClick } = props diff --git a/packages/client/src/store/reducers/user-reducer.ts b/packages/client/src/store/reducers/user-reducer.ts index a6783b1..97c1219 100644 --- a/packages/client/src/store/reducers/user-reducer.ts +++ b/packages/client/src/store/reducers/user-reducer.ts @@ -35,12 +35,14 @@ export const getUser = () => async (dispatch: AppDispatch) => { method: 'get', url: `${import.meta.env.VITE_AUTH_URL}/auth/user`, }) - .then((data: any) => { + .then((data: { data: UserType }) => { if (data) { dispatch(actions.setUser(data.data)) } }) - .catch(() => {}) + .catch((error) => { + console.error(error) + }) } export const logoutUser = () => async (dispatch: AppDispatch) => { @@ -48,14 +50,13 @@ export const logoutUser = () => async (dispatch: AppDispatch) => { method: 'post', url: `${import.meta.env.VITE_AUTH_URL}/auth/logout`, }) - .then((data: any) => { - if (data) { - dispatch(actions.setUser(null)) - - window.location.href = '/' - } + .then(() => { + dispatch(actions.setUser(null)) + window.location.href = '/' + }) + .catch((error) => { + console.error(error) }) - .catch(() => {}) } export const signInUser = @@ -78,7 +79,9 @@ export const signInUser = } } }) - .catch(() => {}) + .catch((error) => { + console.error(error) + }) } export const signUpUser = @@ -88,13 +91,15 @@ export const signUpUser = url: `${import.meta.env.VITE_AUTH_URL}/auth/signup`, data: form, }) - .then(data => { + .then((data: { data: UserType }) => { if (data) { - dispatch(actions.setUser(data)) + dispatch(actions.setUser(data.data)) dispatch(getUser()) } }) - .catch(() => {}) + .catch((error) => { + console.error(error) + }) } export type ActionsType = InferAppActions From d993cc14782da7900bd4b900267addb8647639ba Mon Sep 17 00:00:00 2001 From: gloginov Date: Fri, 27 Sep 2024 13:39:05 +0500 Subject: [PATCH 3/7] [SOK-16] *rename UserReducer to AuthReducer *rename methods in auth-reducer.ts -remove origin host from methods in auth-reducer.ts because base url set in backendApi --- packages/client/src/layouts/private-layout.tsx | 4 ++-- packages/client/src/pages/Profile/Profile.tsx | 2 +- packages/client/src/pages/SignIn/SignIn.tsx | 2 +- packages/client/src/pages/SignUp/SignUp.tsx | 2 +- packages/client/src/store/index.ts | 4 ++-- .../reducers/{user-reducer.ts => auth-reducer.ts} | 14 +++++++------- 6 files changed, 14 insertions(+), 14 deletions(-) rename packages/client/src/store/reducers/{user-reducer.ts => auth-reducer.ts} (87%) diff --git a/packages/client/src/layouts/private-layout.tsx b/packages/client/src/layouts/private-layout.tsx index 6b2091c..932c508 100644 --- a/packages/client/src/layouts/private-layout.tsx +++ b/packages/client/src/layouts/private-layout.tsx @@ -1,13 +1,13 @@ import { useSelector } from 'react-redux' import { Outlet } from 'react-router-dom' import { RootState } from '@/store' -import { getUser, UserType } from '@/store/reducers/user-reducer' +import { getUser, UserType } from '@/store/reducers/auth-reducer' import { useEffect } from 'react' import { useAppDispatch } from '@/store' export default function PrivateLayout() { // get user from store - const user = useSelector(state => state.UserReducer.user) + const user = useSelector(state => state.AuthReducer.user) const dispatch = useAppDispatch() useEffect(() => { diff --git a/packages/client/src/pages/Profile/Profile.tsx b/packages/client/src/pages/Profile/Profile.tsx index 84fd01e..f20e3d4 100644 --- a/packages/client/src/pages/Profile/Profile.tsx +++ b/packages/client/src/pages/Profile/Profile.tsx @@ -1,4 +1,4 @@ -import { logoutUser } from '@/store/reducers/user-reducer' +import { logoutUser } from '@/store/reducers/auth-reducer' import { useAppDispatch } from '@/store' export const Profile = () => { diff --git a/packages/client/src/pages/SignIn/SignIn.tsx b/packages/client/src/pages/SignIn/SignIn.tsx index dbc3c1b..292bea7 100644 --- a/packages/client/src/pages/SignIn/SignIn.tsx +++ b/packages/client/src/pages/SignIn/SignIn.tsx @@ -1,6 +1,6 @@ import { useState } from 'react' import { useAppDispatch } from '@/store' -import { signInUser } from '@/store/reducers/user-reducer' +import { signInUser } from '@/store/reducers/auth-reducer' import { Button } from '@/components/ui/Button/Button' import { useSearchParams } from 'react-router-dom' diff --git a/packages/client/src/pages/SignUp/SignUp.tsx b/packages/client/src/pages/SignUp/SignUp.tsx index 1ce849e..37d1bd5 100644 --- a/packages/client/src/pages/SignUp/SignUp.tsx +++ b/packages/client/src/pages/SignUp/SignUp.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { signUpUser } from '@/store/reducers/user-reducer' +import { signUpUser } from '@/store/reducers/auth-reducer' import { useAppDispatch } from '@/store' export const SignUp = () => { diff --git a/packages/client/src/store/index.ts b/packages/client/src/store/index.ts index 1af12dc..fff2154 100644 --- a/packages/client/src/store/index.ts +++ b/packages/client/src/store/index.ts @@ -1,11 +1,11 @@ import { configureStore } from '@reduxjs/toolkit' -import UserReducer from '@/store/reducers/user-reducer' +import AuthReducer from '@/store/reducers/auth-reducer' import { useDispatch } from 'react-redux' import { combineReducers } from '@reduxjs/toolkit' const rootReducer = combineReducers({ - UserReducer, + AuthReducer, }) export const store = configureStore({ reducer: rootReducer, diff --git a/packages/client/src/store/reducers/user-reducer.ts b/packages/client/src/store/reducers/auth-reducer.ts similarity index 87% rename from packages/client/src/store/reducers/user-reducer.ts rename to packages/client/src/store/reducers/auth-reducer.ts index 97c1219..402600a 100644 --- a/packages/client/src/store/reducers/user-reducer.ts +++ b/packages/client/src/store/reducers/auth-reducer.ts @@ -18,7 +18,7 @@ const initialState = { } const slice = createSlice({ - name: 'UserReducer', + name: 'AuthReducer', initialState, reducers: { setUser(state, actions) { @@ -27,13 +27,13 @@ const slice = createSlice({ }, }) -const UserReducer = slice.reducer +const AuthReducer = slice.reducer export const { actions } = slice export const getUser = () => async (dispatch: AppDispatch) => { await backendApi({ method: 'get', - url: `${import.meta.env.VITE_AUTH_URL}/auth/user`, + url: '/auth/user', }) .then((data: { data: UserType }) => { if (data) { @@ -48,7 +48,7 @@ export const getUser = () => async (dispatch: AppDispatch) => { export const logoutUser = () => async (dispatch: AppDispatch) => { await backendApi({ method: 'post', - url: `${import.meta.env.VITE_AUTH_URL}/auth/logout`, + url: '/auth/logout', }) .then(() => { dispatch(actions.setUser(null)) @@ -64,7 +64,7 @@ export const signInUser = (dispatch: AppDispatch) => { return backendApi({ method: 'post', - url: `${import.meta.env.VITE_AUTH_URL}/auth/signin`, + url: '/auth/signin', data: form, }) .then(data => { @@ -88,7 +88,7 @@ export const signUpUser = (form: { login: string; password: string }) => (dispatch: AppDispatch) => { backendApi({ method: 'post', - url: `${import.meta.env.VITE_AUTH_URL}/auth/signup`, + url: '/auth/signup', data: form, }) .then((data: { data: UserType }) => { @@ -103,4 +103,4 @@ export const signUpUser = } export type ActionsType = InferAppActions -export default UserReducer +export default AuthReducer From 9960d7c6f3d9a61a74a158aa646634c7488f890e Mon Sep 17 00:00:00 2001 From: gloginov Date: Tue, 1 Oct 2024 21:33:12 +0500 Subject: [PATCH 4/7] [SOK-16] *update backendApi *change reducer for async/await *redirects with router (spa) +add toast for error message --- package-lock.json | 1365 ++++++++++++----- packages/client/package.json | 16 +- packages/client/src/api/backendApi.ts | 20 +- .../src/components/ui/Button/Button.tsx | 26 +- .../src/layouts/AuthLayout/AuthLayout.tsx | 21 +- .../client/src/layouts/private-layout.tsx | 35 +- packages/client/src/main.tsx | 4 +- packages/client/src/pages/Profile/Profile.tsx | 11 +- packages/client/src/pages/SignIn/SignIn.tsx | 22 +- packages/client/src/pages/SignUp/SignUp.tsx | 21 +- .../client/src/store/reducers/auth-reducer.ts | 146 +- yarn.lock | 518 +++---- 12 files changed, 1422 insertions(+), 783 deletions(-) diff --git a/package-lock.json b/package-lock.json index fd496d3..ddc1c5d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,11 +9,6 @@ "workspaces": [ "packages/*" ], - "dependencies": { - "normalize": "^0.3.1", - "react-router-dom": "^6.26.2", - "sass": "^1.79.1" - }, "devDependencies": { "@evilmartians/lefthook": "^1.3.9", "eslint-plugin-react": "^7.37.0", @@ -30,6 +25,7 @@ "version": "4.3.3", "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.3.tgz", "integrity": "sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==", + "dev": true, "license": "MIT" }, "node_modules/@ampproject/remapping": { @@ -45,11 +41,14 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -93,9 +92,9 @@ } }, "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -103,12 +102,15 @@ } }, "node_modules/@babel/generator": { - "version": "7.18.13", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.18.13", - "@jridgewell/gen-mapping": "^0.3.2", + "@babel/types": "^7.25.6", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { @@ -116,13 +118,15 @@ } }, "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -159,9 +163,9 @@ } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -176,29 +180,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.18.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.18.6", - "@babel/types": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-module-imports": { "version": "7.18.6", "dev": true, @@ -261,7 +242,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.18.10", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "dev": true, "license": "MIT", "engines": { @@ -269,7 +252,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, "license": "MIT", "engines": { @@ -298,13 +283,16 @@ } }, "node_modules/@babel/highlight": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -325,6 +313,8 @@ }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "license": "MIT", "dependencies": { @@ -377,9 +367,14 @@ } }, "node_modules/@babel/parser": { - "version": "7.18.13", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.6" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -660,32 +655,33 @@ } }, "node_modules/@babel/template": { - "version": "7.18.10", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.18.13", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.13", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.18.13", - "@babel/types": "^7.18.13", - "debug": "^4.1.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -703,12 +699,14 @@ } }, "node_modules/@babel/types": { - "version": "7.18.13", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -746,6 +744,40 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@esbuild/android-arm": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.18.tgz", + "integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz", + "integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint/eslintrc": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", @@ -1222,7 +1254,9 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "license": "MIT", "engines": { @@ -1237,12 +1271,14 @@ "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.15", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@lerna/add": { @@ -2930,10 +2966,36 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/@reduxjs/toolkit": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.7.tgz", + "integrity": "sha512-faI3cZbSdFb8yv9dhDTmGwclW0vk0z5o1cia+kf7gCbaCwHI5e+7tP57mJUv22pNcNbeA62GSrPpfrUfdXcQ6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, "node_modules/@remix-run/router": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz", "integrity": "sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==", + "dev": true, "license": "MIT", "engines": { "node": ">=14.0.0" @@ -3340,14 +3402,13 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "18.0.17", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.17.tgz", - "integrity": "sha512-38ETy4tL+rn4uQQi7mB81G7V1g0u2ryquNmsVIOKUAEIDK+3CUjZ6rSRpdvS99dNBnkLFL83qfmtLacGOTIhwQ==", + "version": "18.3.9", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.9.tgz", + "integrity": "sha512-+BpAVyTpJkNWWSSnaLBk6ePpHLOGJKnEQNbINNovPWzvEUyAe3e+/d494QdEh71RekM/qV7lw6jzf1HGrJyAtQ==", "dev": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "*", "csstype": "^3.0.2" } }, @@ -3361,13 +3422,6 @@ "@types/react": "*" } }, - "node_modules/@types/scheduler": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", @@ -3393,6 +3447,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/yargs": { "version": "17.0.11", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.11.tgz", @@ -4147,169 +4208,38 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/babel-jest": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.0.1.tgz", - "integrity": "sha512-wyI9r8tqwsZEMWiIaYjdUJ6ztZIO4DMWpGq7laW34wR71WtRS+D/iBEtXOP5W2aSYCVUQMsypRl/xiJYZznnTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "^29.0.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-jest/node_modules/@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "node_modules/axios": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "dev": true, "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.24.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, - "node_modules/babel-jest/node_modules/@jest/transform": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.0.1.tgz", - "integrity": "sha512-6UxXtqrPScFdDhoip8ys60dQAIYppQinyR87n9nlasR/ZnFfJohKToqzM29KK4gb9gHRv5oDFChdqZKE0SIhsg==", + "node_modules/babel-jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", + "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.0.1", - "@jridgewell/trace-mapping": "^0.3.15", + "@jest/transform": "^28.1.3", + "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^28.1.3", "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.1", - "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-jest/node_modules/@jest/types": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", - "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.0.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-jest/node_modules/jest-haste-map": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.0.1.tgz", - "integrity": "sha512-gcKOAydafpGoSBvcj/mGCfhOKO8fRLkAeee1KXGdcJ1Pb9O2nnOl4I8bQSIID2MaZeMHtLLgNboukh/pUGkBtg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.0.1", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.1", - "jest-worker": "^29.0.1", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/babel-jest/node_modules/jest-regex-util": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.0.0.tgz", - "integrity": "sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-jest/node_modules/jest-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", - "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.0.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-jest/node_modules/jest-worker": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.0.1.tgz", - "integrity": "sha512-+B/2/8WW7goit7qVezG9vnI1QP3dlmuzi2W0zxazAQQ8dcDIA63dDn6j4pjOGBARha/ZevcwYQtNIzCySbS7fQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-jest/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" + "slash": "^3.0.0" }, "engines": { - "node": ">=10" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "peerDependencies": { + "@babel/core": "^7.8.0" } }, "node_modules/babel-plugin-istanbul": { @@ -4330,9 +4260,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.0.0.tgz", - "integrity": "sha512-B9oaXrlxXHFWeWqhDPg03iqQd2UN/mg/VdZOsLaqAVBkztru3ctTryAI4zisxLEEgmcUnLTKewqx0gGifoXD3A==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", + "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", "dev": true, "license": "MIT", "dependencies": { @@ -4342,7 +4272,7 @@ "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/babel-preset-current-node-syntax": { @@ -4370,17 +4300,17 @@ } }, "node_modules/babel-preset-jest": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.0.0.tgz", - "integrity": "sha512-B5Ke47Xcs8rDF3p1korT3LoilpADCwbG93ALqtvqu6Xpf4d8alKkrCBTExbNzdHJcIuEPpfYvEaFFRGee2kUgQ==", - "dev": true, + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", + "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", + "dev": true, "license": "MIT", "dependencies": { - "babel-plugin-jest-hoist": "^29.0.0", + "babel-plugin-jest-hoist": "^28.1.3", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -4510,12 +4440,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -4994,6 +4924,15 @@ "node": ">=0.10.0" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/cmd-shim": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-5.0.0.tgz", @@ -6170,9 +6109,9 @@ } }, "node_modules/esbuild": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", - "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.18.tgz", + "integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -6183,33 +6122,85 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/linux-loong64": "0.14.54", - "esbuild-android-64": "0.14.54", - "esbuild-android-arm64": "0.14.54", - "esbuild-darwin-64": "0.14.54", - "esbuild-darwin-arm64": "0.14.54", - "esbuild-freebsd-64": "0.14.54", - "esbuild-freebsd-arm64": "0.14.54", - "esbuild-linux-32": "0.14.54", - "esbuild-linux-64": "0.14.54", - "esbuild-linux-arm": "0.14.54", - "esbuild-linux-arm64": "0.14.54", - "esbuild-linux-mips64le": "0.14.54", - "esbuild-linux-ppc64le": "0.14.54", - "esbuild-linux-riscv64": "0.14.54", - "esbuild-linux-s390x": "0.14.54", - "esbuild-netbsd-64": "0.14.54", - "esbuild-openbsd-64": "0.14.54", - "esbuild-sunos-64": "0.14.54", - "esbuild-windows-32": "0.14.54", - "esbuild-windows-64": "0.14.54", - "esbuild-windows-arm64": "0.14.54" + "@esbuild/android-arm": "0.15.18", + "@esbuild/linux-loong64": "0.15.18", + "esbuild-android-64": "0.15.18", + "esbuild-android-arm64": "0.15.18", + "esbuild-darwin-64": "0.15.18", + "esbuild-darwin-arm64": "0.15.18", + "esbuild-freebsd-64": "0.15.18", + "esbuild-freebsd-arm64": "0.15.18", + "esbuild-linux-32": "0.15.18", + "esbuild-linux-64": "0.15.18", + "esbuild-linux-arm": "0.15.18", + "esbuild-linux-arm64": "0.15.18", + "esbuild-linux-mips64le": "0.15.18", + "esbuild-linux-ppc64le": "0.15.18", + "esbuild-linux-riscv64": "0.15.18", + "esbuild-linux-s390x": "0.15.18", + "esbuild-netbsd-64": "0.15.18", + "esbuild-openbsd-64": "0.15.18", + "esbuild-sunos-64": "0.15.18", + "esbuild-windows-32": "0.15.18", + "esbuild-windows-64": "0.15.18", + "esbuild-windows-arm64": "0.15.18" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz", + "integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz", + "integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz", + "integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" } }, "node_modules/esbuild-darwin-arm64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", - "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz", + "integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==", "cpu": [ "arm64" ], @@ -6223,6 +6214,276 @@ "node": ">=12" } }, + "node_modules/esbuild-freebsd-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz", + "integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz", + "integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz", + "integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz", + "integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz", + "integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz", + "integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz", + "integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz", + "integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz", + "integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz", + "integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz", + "integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz", + "integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz", + "integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz", + "integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz", + "integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz", + "integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/escalade": { "version": "3.1.1", "dev": true, @@ -6815,7 +7076,7 @@ "node": ">=0.6.0" } }, - "node_modules/Falcon-Tanks": { + "node_modules/falcon-tanks": { "resolved": "packages/client", "link": true }, @@ -6902,9 +7163,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -6989,6 +7250,27 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -7848,10 +8130,22 @@ "node": ">=10" } }, + "node_modules/immer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz", + "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/immutable": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "dev": true, "license": "MIT" }, "node_modules/import-fresh": { @@ -8652,9 +8946,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -8876,83 +9170,28 @@ "jest-regex-util": "^28.0.2", "jest-resolve": "^28.1.3", "jest-runner": "^28.1.3", - "jest-util": "^28.1.3", - "jest-validate": "^28.1.3", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-config/node_modules/babel-jest": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", - "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "^28.1.3", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^28.1.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/jest-config/node_modules/babel-plugin-jest-hoist": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", - "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-config/node_modules/babel-preset-jest": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", - "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "^28.1.3", - "babel-preset-current-node-syntax": "^1.0.0" + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } } }, "node_modules/jest-diff": { @@ -9683,7 +9922,9 @@ "license": "ISC" }, "node_modules/json5": { - "version": "2.2.1", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "license": "MIT", "bin": { @@ -10186,9 +10427,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -10440,12 +10681,12 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -10729,10 +10970,16 @@ "license": "ISC" }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" @@ -10958,6 +11205,7 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/normalize/-/normalize-0.3.1.tgz", "integrity": "sha512-DfyFcERXw4cjxUBgmATdxnCipRFoRvj0tNo+MWwjhebV9GZz2HYoNkXodEqS565uomk0CxEs90nEwrmj+aI9RQ==", + "dev": true, "dependencies": { "stylus": "*" }, @@ -12227,7 +12475,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true, "license": "ISC" }, @@ -12289,9 +12539,9 @@ } }, "node_modules/postcss": { - "version": "8.4.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", - "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "dev": true, "funding": [ { @@ -12301,13 +12551,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -12532,6 +12786,13 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "license": "MIT" + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -12674,6 +12935,30 @@ "dev": true, "license": "MIT" }, + "node_modules/react-redux": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz", + "integrity": "sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.3", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25", + "react": "^18.0", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, "node_modules/react-refresh": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", @@ -12688,6 +12973,7 @@ "version": "6.26.2", "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.2.tgz", "integrity": "sha512-tvN1iuT03kHgOFnLPfLJ8V95eijteveqdOSk+srqfePtQvqCExB8eHOYnlilbOcyJyKnYkr1vJvf7YqotAJu1A==", + "dev": true, "license": "MIT", "dependencies": { "@remix-run/router": "1.19.2" @@ -12703,6 +12989,7 @@ "version": "6.26.2", "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.2.tgz", "integrity": "sha512-z7YkaEW0Dy35T3/QKPYB1LjMK2R1fxnHO8kWpUMTBdfVzZrWOiY9a7CtN8HqdWtDUWd5FY6Dl8HFsqVwH4uOtQ==", + "dev": true, "license": "MIT", "dependencies": { "@remix-run/router": "1.19.2", @@ -12716,6 +13003,19 @@ "react-dom": ">=16.8" } }, + "node_modules/react-toastify": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz", + "integrity": "sha512-mNKt2jBXJg4O7pSdbNUfDdTsK9FIdikfsIE/yUCxbAEXl4HMyJaivrVFcn3Elvt5xvCQYhUZm+hqTIu1UXM3Pw==", + "license": "MIT", + "dependencies": { + "clsx": "^2.1.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", @@ -13068,6 +13368,23 @@ "node": ">=8" } }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "dev": true, + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", @@ -13143,6 +13460,13 @@ "dev": true, "license": "MIT" }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "dev": true, + "license": "MIT" + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -13244,9 +13568,9 @@ } }, "node_modules/rollup": { - "version": "2.77.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.3.tgz", - "integrity": "sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==", + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "dev": true, "license": "MIT", "bin": { @@ -13358,6 +13682,7 @@ }, "node_modules/sass": { "version": "1.79.2", + "dev": true, "license": "MIT", "dependencies": { "chokidar": "^4.0.0", @@ -13375,6 +13700,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.0.tgz", "integrity": "sha512-mxIojEAQcuEvT/lyXq+jf/3cO/KoA6z4CeNDGGevTybECPOMFCnQy3OPahluUkbqgPNGw5Bi78UC7Po6Lhy+NA==", + "dev": true, "license": "MIT", "dependencies": { "readdirp": "^4.0.1" @@ -13390,6 +13716,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.1.tgz", "integrity": "sha512-GkMg9uOTpIWWKbSsgwb5fA4EavTR+SG/PMPoAY8hkhHfEEY0/vqljY+XHqtDf2cr2IJtoNRDbrrEpZUiZCkYRw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 14.16.0" @@ -13403,6 +13730,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==", + "dev": true, "license": "ISC" }, "node_modules/saxes": { @@ -13428,14 +13756,11 @@ } }, "node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -13711,9 +14036,10 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -14072,6 +14398,7 @@ "version": "0.63.0", "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.63.0.tgz", "integrity": "sha512-OMlgrTCPzE/ibtRMoeLVhOY0RcNuNWh0rhAVqeKnk/QwcuUKQbnqhZ1kg2vzD8VU/6h3FoPTq4RJPHgLBvX6Bw==", + "dev": true, "license": "MIT", "dependencies": { "@adobe/css-tools": "~4.3.3", @@ -14094,6 +14421,7 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">= 8" @@ -14333,9 +14661,9 @@ } }, "node_modules/tough-cookie": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", - "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -14839,6 +15167,16 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -14928,16 +15266,16 @@ } }, "node_modules/vite": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-3.0.9.tgz", - "integrity": "sha512-waYABTM+G6DBTCpYAxvevpG50UOlZuynR0ckTK5PawNVt7ebX6X7wNXHaGIO6wYYFXSM7/WcuFuO2QzhBB6aMw==", + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-3.2.11.tgz", + "integrity": "sha512-K/jGKL/PgbIgKCiJo5QbASQhFiV02X9Jh+Qq0AKCRCRKZtOTVi4t6wh75FDpGf2N9rYOnzH87OEFQNaFy6pdxQ==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.14.47", - "postcss": "^8.4.16", + "esbuild": "^0.15.9", + "postcss": "^8.4.18", "resolve": "^1.22.1", - "rollup": ">=2.75.6 <2.77.0 || ~2.77.0" + "rollup": "^2.79.1" }, "bin": { "vite": "bin/vite.js" @@ -14949,12 +15287,17 @@ "fsevents": "~2.3.2" }, "peerDependencies": { + "@types/node": ">= 14", "less": "*", "sass": "*", "stylus": "*", + "sugarss": "*", "terser": "^5.4.0" }, "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, "less": { "optional": true }, @@ -14964,6 +15307,9 @@ "stylus": { "optional": true }, + "sugarss": { + "optional": true + }, "terser": { "optional": true } @@ -15190,9 +15536,9 @@ } }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -15403,9 +15749,9 @@ } }, "node_modules/ws": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", - "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, "license": "MIT", "engines": { @@ -15413,7 +15759,7 @@ }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -15527,17 +15873,20 @@ } }, "packages/client": { - "name": "Falcon-Tanks", + "name": "falcon-tanks", "version": "1.0.0", "license": "MIT", "dependencies": { "dotenv": "^16.0.2", + "esbuild-linux-64": "^0.15.18", "eslint-config-prettier": "^8.5.0", "prettier": "^2.7.1", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-toastify": "^10.0.5" }, "devDependencies": { + "@reduxjs/toolkit": "^2.2.7", "@testing-library/react": "^13.3.0", "@types/jest": "^28.1.8", "@types/react": "^18.0.17", @@ -15545,11 +15894,16 @@ "@typescript-eslint/eslint-plugin": "^5.35.1", "@typescript-eslint/parser": "^5.35.1", "@vitejs/plugin-react": "^2.0.1", + "axios": "^1.7.7", "eslint": "^8.23.0", "jest": "^28", "jest-environment-jsdom": "^29.0.1", - "lefthook": "^1.3.9", + "lefthook": "^1.7.15", + "normalize": "^0.3.1", "prettier": "^2.7.1", + "react-redux": "^9.1.2", + "react-router-dom": "^6.26.2", + "sass": "^1.79.1", "ts-jest": "^28.0.8", "typescript": "^4.8.2", "vite": "^3.0.7" @@ -15583,6 +15937,219 @@ "ts-node": "^10.9.1", "typescript": "^4.8.2" } + }, + "packages/server/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/server/node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/server/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/server/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, + "packages/server/node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "packages/server/node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/server/node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "packages/server/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "packages/server/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "packages/server/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/server/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/server/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/server/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } } } } diff --git a/packages/client/package.json b/packages/client/package.json index e0895fb..1d058fb 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -12,14 +12,14 @@ }, "dependencies": { "dotenv": "^16.0.2", + "esbuild-linux-64": "^0.15.18", "eslint-config-prettier": "^8.5.0", "prettier": "^2.7.1", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-toastify": "^10.0.5" }, "devDependencies": { - "react-redux": "^9.1.2", - "axios": "^1.7.7", "@reduxjs/toolkit": "^2.2.7", "@testing-library/react": "^13.3.0", "@types/jest": "^28.1.8", @@ -28,17 +28,19 @@ "@typescript-eslint/eslint-plugin": "^5.35.1", "@typescript-eslint/parser": "^5.35.1", "@vitejs/plugin-react": "^2.0.1", + "axios": "^1.7.7", "eslint": "^8.23.0", "jest": "^28", "jest-environment-jsdom": "^29.0.1", "lefthook": "^1.7.15", + "normalize": "^0.3.1", "prettier": "^2.7.1", + "react-redux": "^9.1.2", + "react-router-dom": "^6.26.2", + "sass": "^1.79.1", "ts-jest": "^28.0.8", "typescript": "^4.8.2", - "vite": "^3.0.7", - "normalize": "^0.3.1", - "react-router-dom": "^6.26.2", - "sass": "^1.79.1" + "vite": "^3.0.7" }, "license": "MIT" } diff --git a/packages/client/src/api/backendApi.ts b/packages/client/src/api/backendApi.ts index 7dee2ee..b4364cc 100644 --- a/packages/client/src/api/backendApi.ts +++ b/packages/client/src/api/backendApi.ts @@ -1,4 +1,4 @@ -import axios, { AxiosError, AxiosResponse } from 'axios' +import axios from 'axios' const instance = axios.create({ baseURL: import.meta.env.VITE_AUTH_URL, @@ -8,22 +8,4 @@ const instance = axios.create({ withCredentials: true, }) -instance.interceptors.response.use( - function (response: AxiosResponse) { - return response - }, - function (error: AxiosError) { - // if app get response code 401 (died token), redirect user to sign-in form - if (error.response?.status === 401) { - localStorage.removeItem('user') - // save page where we get 401 and redirect after login - window.location.href = '/sign-in?redirectUrl=' + window.location.pathname - } - - if (axios.isCancel(error)) return Promise.reject(error) - - return Promise.reject(error) - } -) - export default instance diff --git a/packages/client/src/components/ui/Button/Button.tsx b/packages/client/src/components/ui/Button/Button.tsx index e0e7c4d..8a36aa8 100644 --- a/packages/client/src/components/ui/Button/Button.tsx +++ b/packages/client/src/components/ui/Button/Button.tsx @@ -11,24 +11,12 @@ export const Button = (props: { }) => { const { text, className, useFixWidth = false, href = '/', onClick } = props return ( - <> - {onClick && typeof onClick === 'function' ? ( - - ) : ( - - {text} - - )} - + ) } diff --git a/packages/client/src/layouts/AuthLayout/AuthLayout.tsx b/packages/client/src/layouts/AuthLayout/AuthLayout.tsx index 7aaf88a..7b6dd30 100644 --- a/packages/client/src/layouts/AuthLayout/AuthLayout.tsx +++ b/packages/client/src/layouts/AuthLayout/AuthLayout.tsx @@ -1,5 +1,24 @@ -import { Outlet } from 'react-router-dom' +import { Outlet, useNavigate } from 'react-router-dom' +import {useSelector} from "react-redux"; +import {RootState, useAppDispatch} from "@/store"; +import {actions, getUser, UserType} from "@/store/reducers/auth-reducer"; +import { toast } from 'react-toastify'; +import {useEffect} from "react"; export default function AuthLayout() { + const user = useSelector(state => state.AuthReducer.user) + const navigate = useNavigate(); + + useEffect(() => { + if (window.sessionStorage.getItem('userIsLogged') === '1') { + toast.success('Вы уже авторизованы', { + autoClose: 1500, + onClose: () => { + navigate('/game') + } + }) + } + }, [user]) + return } diff --git a/packages/client/src/layouts/private-layout.tsx b/packages/client/src/layouts/private-layout.tsx index 932c508..28e6188 100644 --- a/packages/client/src/layouts/private-layout.tsx +++ b/packages/client/src/layouts/private-layout.tsx @@ -1,22 +1,39 @@ import { useSelector } from 'react-redux' -import { Outlet } from 'react-router-dom' -import { RootState } from '@/store' -import { getUser, UserType } from '@/store/reducers/auth-reducer' +import {Outlet, useNavigate} from 'react-router-dom' +import {RootState, useAppDispatch} from '@/store' +import {actions, getUser, UserType} from '@/store/reducers/auth-reducer' import { useEffect } from 'react' -import { useAppDispatch } from '@/store' +import {toast} from "react-toastify"; export default function PrivateLayout() { - // get user from store const user = useSelector(state => state.AuthReducer.user) + const navigate = useNavigate(); + const userIsLogged = window.sessionStorage.getItem('userIsLogged') === '1'; const dispatch = useAppDispatch() useEffect(() => { - // if user is empty call backend - if (user === null) { + if (!userIsLogged) { dispatch(getUser()) + .unwrap() + .then((data) => { + dispatch(actions.setUser(data.data)) + window.sessionStorage.setItem('userIsLogged', '1') // 0 + }) + .catch(() => { + window.sessionStorage.setItem('userIsLogged', '0') // 0 + + toast.error('Необходимо авторизоваться', { + autoClose: 1500, + onClose: () => { + navigate('/sign-in') + } + }) + }) } - }, [user]) + }, []) - // if the user is full, show page + if (userIsLogged) { + return + } return user === null ?

Загрузка...

: } diff --git a/packages/client/src/main.tsx b/packages/client/src/main.tsx index d3075e7..ac938c1 100644 --- a/packages/client/src/main.tsx +++ b/packages/client/src/main.tsx @@ -2,7 +2,8 @@ import React from 'react' import ReactDOM from 'react-dom/client' import { Provider } from 'react-redux' import { store } from '@/store' - +import { ToastContainer } from 'react-toastify'; +import 'react-toastify/dist/ReactToastify.css'; import App from './app/App' import '@/scss/styles.scss' @@ -10,6 +11,7 @@ ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( + ) diff --git a/packages/client/src/pages/Profile/Profile.tsx b/packages/client/src/pages/Profile/Profile.tsx index f20e3d4..b519979 100644 --- a/packages/client/src/pages/Profile/Profile.tsx +++ b/packages/client/src/pages/Profile/Profile.tsx @@ -1,13 +1,22 @@ import { logoutUser } from '@/store/reducers/auth-reducer' import { useAppDispatch } from '@/store' +import {useNavigate} from "react-router-dom"; export const Profile = () => { const dispatch = useAppDispatch() + const navigate = useNavigate(); + const onLogoutUser = () => { + dispatch(logoutUser()) + .then(() => { + window.sessionStorage.setItem('userIsLogged', '0') // 0 + navigate('/') + }) + } return ( <> Страница профиля - + ) } diff --git a/packages/client/src/pages/SignIn/SignIn.tsx b/packages/client/src/pages/SignIn/SignIn.tsx index 292bea7..a69eeec 100644 --- a/packages/client/src/pages/SignIn/SignIn.tsx +++ b/packages/client/src/pages/SignIn/SignIn.tsx @@ -3,18 +3,30 @@ import { useAppDispatch } from '@/store' import { signInUser } from '@/store/reducers/auth-reducer' import { Button } from '@/components/ui/Button/Button' import { useSearchParams } from 'react-router-dom' +import { useNavigate } from "react-router-dom"; +import { toast } from 'react-toastify'; export const SignIn = () => { const [form, setForm] = useState({ login: '', password: '' }) const [searchParams] = useSearchParams() const [query] = useState(searchParams.get('redirectUrl')) + const navigate = useNavigate(); const dispatch = useAppDispatch() const handleForm = (name: string, value: string) => { setForm({ ...form, [name]: value }) } - const handleSubmit = () => dispatch(signInUser(form, query)) + const handleSubmit = () => { + dispatch(signInUser({form: form, query: query})) + .unwrap() + .then((response: any) => { + navigate('/game') + }) + .catch((error?: any, code?: any) => { + toast.error(error.reason) + }) + } return ( <> @@ -28,6 +40,7 @@ export const SignIn = () => { onChange={e => handleForm('login', e.target.value)} type="text" name={'login'} + value={form.login} /> +