diff --git a/.env.example b/.env.example index b8ca0df5c..641d438f7 100644 --- a/.env.example +++ b/.env.example @@ -1 +1,2 @@ +VITE_BASE_URL= VITE_API_BASE_URL= diff --git a/README.md b/README.md index f72cedccf..8dbf74ef9 100644 --- a/README.md +++ b/README.md @@ -53,4 +53,4 @@ _Link to the backend repo:_ https://github.com/chertik77/TaskPro-backend ## Languages and Tools -![Languages and Tools](https://skills.syvixor.com/api/icons?i=ts,react,dndkit,baseui,tanstack,stanjs,axios,datefns,reactdatepicker,reacthookform,valibot,tailwind,tailwindmerge,fusejs,commitlint,eslint,prettier,githubactions,fsd,yarn,vercel,vite,vscode,figma&perline=8) +![Languages and Tools](https://skills.syvixor.com/api/icons?i=ts,react,dndkit,baseui,tanstack,betterauth,stanjs,axios,datefns,reactdatepicker,reacthookform,valibot,tailwind,tailwindmerge,fusejs,commitlint,eslint,prettier,githubactions,fsd,yarn,vercel,vite,vscode,figma&perline=9) diff --git a/package.json b/package.json index a415377e8..ad26795ae 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@vercel/analytics": "^2.0.1", "@vercel/speed-insights": "^2.0.0", "axios": "^1.18.1", - "axios-auth-refresh": "^5.0.2", + "better-auth": "^1.6.23", "chrono-node": "^2.9.1", "clsx": "^2.1.1", "date-fns": "^4.4.0", diff --git a/src/app/providers/RouteProvider.tsx b/src/app/providers/RouteProvider.tsx index 381e035d6..58a614c59 100644 --- a/src/app/providers/RouteProvider.tsx +++ b/src/app/providers/RouteProvider.tsx @@ -1,33 +1,18 @@ -import { useQueryClient } from '@tanstack/react-query' import { RouterProvider as TanStackRouterProvider } from '@tanstack/react-router' -import { sessionService } from '@/entities/session' -import { userQueries } from '@/entities/user' - -import { attachInternalApiMemoryStorage } from '@/shared/api' import { router } from '@/shared/lib' import { GlobalError, Loader } from '@/shared/ui' -export const RouterProvider = () => { - const queryClient = useQueryClient() - - attachInternalApiMemoryStorage({ - refreshTokens: sessionService.refreshTokens, - logout: () => queryClient.resetQueries({ queryKey: userQueries.current() }) - }) - - return ( - ( -
-
- -
+export const RouterProvider = () => ( + ( +
+
+
- )} - defaultErrorComponent={() => } - /> - ) -} +
+ )} + defaultErrorComponent={() => } + /> +) diff --git a/src/entities/session/api/endpoints.ts b/src/entities/session/api/endpoints.ts deleted file mode 100644 index c08d64c38..000000000 --- a/src/entities/session/api/endpoints.ts +++ /dev/null @@ -1,12 +0,0 @@ -class SessionApiEndpoints { - private readonly baseUrl = '/auth' - - signup = `${this.baseUrl}/signup` - signin = `${this.baseUrl}/signin` - refresh = `${this.baseUrl}/refresh` - logout = `${this.baseUrl}/logout` - googleInitiate = `${this.baseUrl}/google/initiate` - microsoftInitiate = `${this.baseUrl}/microsoft/initiate` -} - -export const sessionApiEndpoints = new SessionApiEndpoints() diff --git a/src/entities/session/api/service.ts b/src/entities/session/api/service.ts index f662408e9..84a49e78c 100644 --- a/src/entities/session/api/service.ts +++ b/src/entities/session/api/service.ts @@ -2,27 +2,25 @@ import type { SigninDto, SignupDto } from './types' import { parse } from 'valibot' -import { axiosInstance } from '@/shared/api' +import { authClient } from '@/shared/api' +import { env } from '@/shared/config' import { SessionResponseDtoSchema, SigninDtoSchema, SignupDtoSchema } from './contracts' -import { sessionApiEndpoints } from './endpoints' export const sessionService = { async signup(data: SignupDto) { const signupDto = parse(SignupDtoSchema, data) - console.log(signupDto) + const response = await authClient.signUp.email({ + ...signupDto, + theme: 'light' + }) - const response = await axiosInstance.post( - sessionApiEndpoints.signup, - signupDto - ) - - const parsedData = parse(SessionResponseDtoSchema, response.data) + const parsedData = parse(SessionResponseDtoSchema, response) return parsedData }, @@ -30,22 +28,22 @@ export const sessionService = { async signin(data: SigninDto) { const signinDto = parse(SigninDtoSchema, data) - const response = await axiosInstance.post( - sessionApiEndpoints.signin, - signinDto, - { skipAuthRefresh: true } - ) + const response = await authClient.signIn.email(signinDto) - const parsedData = parse(SessionResponseDtoSchema, response.data) + const parsedData = parse(SessionResponseDtoSchema, response) return parsedData }, - async refreshTokens() { - await axiosInstance.post(sessionApiEndpoints.refresh) + async continueWithSocial(provider: 'google' | 'microsoft') { + await authClient.signIn.social({ + provider, + callbackURL: env.VITE_BASE_URL, + errorCallbackURL: env.VITE_BASE_URL + '?error=oauth_error' + }) }, async logout() { - await axiosInstance.post(sessionApiEndpoints.logout) + await authClient.signOut() } } diff --git a/src/entities/session/index.ts b/src/entities/session/index.ts index 1a6653634..562db740d 100644 --- a/src/entities/session/index.ts +++ b/src/entities/session/index.ts @@ -1,4 +1,3 @@ export * as SessionDtoTypes from './api/types' export * as SessionDtoContracts from './api/contracts' export { sessionService } from './api/service' -export { sessionApiEndpoints } from './api/endpoints' diff --git a/src/entities/task/ui/Task.tsx b/src/entities/task/ui/Task.tsx index 653730909..203bcbe54 100644 --- a/src/entities/task/ui/Task.tsx +++ b/src/entities/task/ui/Task.tsx @@ -45,6 +45,8 @@ const TaskProvider = ({ className={cn( `relative min-h-38.5 overflow-hidden rounded-lg bg-white py-3.5 pr-5 pl-6 dark:bg-black`, + task.completed && + 'opacity-90 brightness-95 saturate-100 dark:brightness-125', className )} {...props}> @@ -77,7 +79,11 @@ const TaskTitle = ({ className, ...props }: ComponentProps<'p'>) => { return (

{task.title}

@@ -93,6 +99,7 @@ const TaskDescription = ({ className, ...props }: ComponentProps<'p'>) => { className={cn( `text-md mb-3.5 line-clamp-2 max-w-68.75 text-balance text-ellipsis text-black/70 dark:text-white/50`, + task.completed && 'text-black/40 dark:text-white/40', className )} {...props}> @@ -154,7 +161,12 @@ const TaskPriority = ({ className }: { className?: string }) => { const { task } = useTaskContext() return ( -
+

Priority

{ return ( task.deadline && ( -
+

Deadline

diff --git a/src/entities/user/api/contracts.ts b/src/entities/user/api/contracts.ts index 60b804bd6..2517ad680 100644 --- a/src/entities/user/api/contracts.ts +++ b/src/entities/user/api/contracts.ts @@ -7,7 +7,7 @@ export const UserDtoSchema = v.object({ name: v.string(), email: v.string(), theme: v.picklist(THEMES), - avatar: v.nullable(v.string()) + image: v.nullable(v.string()) }) export const EditUserDtoSchema = v.partial( @@ -16,7 +16,7 @@ export const EditUserDtoSchema = v.partial( email: v.pipe(v.string(), v.trim(), v.email()), password: v.pipe(v.string(), v.trim(), v.minLength(8), v.maxLength(64)), theme: v.picklist(THEMES), - avatar: v.pipe( + image: v.pipe( v.instance(File), v.mimeType(['image/jpg', 'image/jpeg', 'image/png', 'image/webp']) ) diff --git a/src/entities/user/api/queries.ts b/src/entities/user/api/queries.ts index c502a507a..4e2cf0143 100644 --- a/src/entities/user/api/queries.ts +++ b/src/entities/user/api/queries.ts @@ -1,13 +1,17 @@ import { queryOptions } from '@tanstack/react-query' -import { userService } from './service' +import { authClient } from '@/shared/api' export const userQueries = { current: () => ['me'], me: () => queryOptions({ queryKey: userQueries.current(), - queryFn: userService.getMe, + queryFn: async () => { + const session = await authClient.getSession() + + return session?.user || null + }, staleTime: 1000 * 60 * 10, // 10 minutes retry: false }) diff --git a/src/entities/user/model/contracts.ts b/src/entities/user/model/contracts.ts index 365b4da7e..6fb96e8e7 100644 --- a/src/entities/user/model/contracts.ts +++ b/src/entities/user/model/contracts.ts @@ -6,6 +6,6 @@ export const UserSchema = v.object({ id: v.string(), name: v.string(), email: v.string(), - avatar: v.nullable(v.string()), + image: v.nullable(v.string()), theme: v.picklist(THEMES) }) diff --git a/src/features/user/change-theme/api/useChangeTheme.ts b/src/features/user/change-theme/api/useChangeTheme.ts index 548dc5d95..75451b605 100644 --- a/src/features/user/change-theme/api/useChangeTheme.ts +++ b/src/features/user/change-theme/api/useChangeTheme.ts @@ -1,13 +1,18 @@ +import type { Theme } from '@/shared/config' + import { useMutation, useQueryClient } from '@tanstack/react-query' import { parse } from 'valibot' -import { UserContracts, userQueries, userService } from '@/entities/user' +import { UserContracts, userQueries } from '@/entities/user' + +import { authClient } from '@/shared/api' export const useChangeTheme = () => { const queryClient = useQueryClient() return useMutation({ - mutationFn: userService.editUser, + mutationFn: ({ theme }: { theme: Theme }) => + authClient.updateUser({ theme }), meta: { errorMessage: 'We couldn’t update your theme. Please try again' }, onMutate: async ({ theme }) => { await queryClient.cancelQueries({ queryKey: userQueries.current() }) diff --git a/src/features/user/edit-profile/ui/EditAvatar.tsx b/src/features/user/edit-profile/ui/EditAvatar.tsx index b940d099b..00bdf7d33 100644 --- a/src/features/user/edit-profile/ui/EditAvatar.tsx +++ b/src/features/user/edit-profile/ui/EditAvatar.tsx @@ -21,7 +21,7 @@ export const EditAvatar = () => { ref={ref} accept='image/jpg, image/jpeg, image/png, image/webp' className='hidden' - onChange={e => changeAvatar({ avatar: e.target.files?.[0] })} + onChange={e => changeAvatar({ image: e.target.files?.[0] })} /> {isPending ? (
{ className='focus-visible:styled-outline relative mx-auto mb-6 block size-17'> Avatar
{ const name = user?.name ?? 'Guest' - console.log(user) - return (

{name}

{name.charAt(0).toUpperCase()} diff --git a/src/pages/signin/api/useSigninUser.ts b/src/pages/signin/api/useSigninUser.ts index f5921835d..134e2b1b1 100644 --- a/src/pages/signin/api/useSigninUser.ts +++ b/src/pages/signin/api/useSigninUser.ts @@ -16,7 +16,7 @@ export const useSigninUser = (reset: UseFormReset) => { mutationFn: sessionService.signin, meta: { errorMessage: e => - e?.response?.status === 401 + e?.status === 401 ? 'The email or password you entered is incorrect. Please try again.' : 'An error occurred during sign-in. Our technical team has been notified. Please try again shortly.' }, diff --git a/src/pages/signup/api/useSignupUser.ts b/src/pages/signup/api/useSignupUser.ts index d985d80d5..245881870 100644 --- a/src/pages/signup/api/useSignupUser.ts +++ b/src/pages/signup/api/useSignupUser.ts @@ -16,13 +16,13 @@ export const useSignupUser = (reset: UseFormReset) => { mutationFn: sessionService.signup, meta: { errorMessage: e => - e?.response?.status === 409 + e?.status === 422 ? 'An account with this email address already exists. Please sign in or use a different email.' : 'An error occurred during sign-up. Our technical team has been notified. Please try again shortly.' }, - onSuccess({ user }) { + onSuccess(data) { reset() - queryClient.setQueryData(userQueries.current(), user) + queryClient.setQueryData(userQueries.current(), data?.user) navigate({ to: '/dashboard' }) } }) diff --git a/src/pages/welcome/ui/SocialButton.tsx b/src/pages/welcome/ui/SocialButton.tsx index 4df0d0de1..be7f48277 100644 --- a/src/pages/welcome/ui/SocialButton.tsx +++ b/src/pages/welcome/ui/SocialButton.tsx @@ -1,31 +1,21 @@ -import { sessionApiEndpoints } from '@/entities/session' - -import { env } from '@/shared/config' import { capitalize } from '@/shared/lib' import { Icon } from '@/shared/ui' type SocialButtonProps = { provider: 'google' | 'microsoft' - apiEndpoint: keyof typeof sessionApiEndpoints + onClick: () => void } -export const SocialButton = ({ provider, apiEndpoint }: SocialButtonProps) => { - const handleClick = () => { - const url = env.VITE_API_BASE_URL + sessionApiEndpoints[apiEndpoint] - window.location.href = url - } - - return ( - - ) -} +export const SocialButton = ({ provider, onClick }: SocialButtonProps) => ( + +) diff --git a/src/pages/welcome/ui/WelcomePage.tsx b/src/pages/welcome/ui/WelcomePage.tsx index 51f90b2d0..84b7ae0b4 100644 --- a/src/pages/welcome/ui/WelcomePage.tsx +++ b/src/pages/welcome/ui/WelcomePage.tsx @@ -1,5 +1,7 @@ import { Link } from '@tanstack/react-router' +import { sessionService } from '@/entities/session' + import { Icon } from '@/shared/ui' import { SocialButton } from './SocialButton' @@ -30,11 +32,11 @@ export const WelcomePage = () => (
sessionService.continueWithSocial('google')} /> sessionService.continueWithSocial('microsoft')} /> Promise - logout: () => void -} - -let __internalMemoryStorage: () => ApiMemoryStorage - -export const attachInternalApiMemoryStorage = (data: ApiMemoryStorage) => { - __internalMemoryStorage = () => data -} - -export const refreshTokens = async () => { - const { refreshTokens } = __internalMemoryStorage() - - return await refreshTokens() -} - -export const logUserOut = () => { - const { logout } = __internalMemoryStorage() - - return logout() -} diff --git a/src/shared/api/auth-client.ts b/src/shared/api/auth-client.ts new file mode 100644 index 000000000..8ce068fc0 --- /dev/null +++ b/src/shared/api/auth-client.ts @@ -0,0 +1,12 @@ +import { inferAdditionalFields } from 'better-auth/client/plugins' +import { createAuthClient } from 'better-auth/react' + +import { env, THEMES } from '../config' + +export const authClient = createAuthClient({ + baseURL: env.VITE_API_BASE_URL + '/auth', + fetchOptions: { throw: true }, + plugins: [ + inferAdditionalFields({ user: { theme: { type: THEMES.map(t => t) } } }) + ] +}) diff --git a/src/shared/api/index.ts b/src/shared/api/index.ts index 21eac6304..55b01fcd5 100644 --- a/src/shared/api/index.ts +++ b/src/shared/api/index.ts @@ -1,2 +1,2 @@ -export { attachInternalApiMemoryStorage } from './apiMemoryStorage' export { axiosInstance } from './instance' +export { authClient } from './auth-client' diff --git a/src/shared/api/instance.ts b/src/shared/api/instance.ts index a6b71d1ca..cfd018cad 100644 --- a/src/shared/api/instance.ts +++ b/src/shared/api/instance.ts @@ -1,24 +1,8 @@ import axios from 'axios' -import { createAuthRefresh } from 'axios-auth-refresh' import { env } from '../config' -import { router } from '../lib' -import { logUserOut, refreshTokens } from './apiMemoryStorage' export const axiosInstance = axios.create({ baseURL: env.VITE_API_BASE_URL, withCredentials: true }) - -createAuthRefresh(axiosInstance, async () => { - try { - await refreshTokens() - - return Promise.resolve() - } catch (e) { - logUserOut() - router.navigate({ to: '/' }) - - return Promise.reject(e) - } -}) diff --git a/src/shared/config/env.ts b/src/shared/config/env.ts index 118b83f60..17872ef5c 100644 --- a/src/shared/config/env.ts +++ b/src/shared/config/env.ts @@ -1,6 +1,7 @@ import * as v from 'valibot' const EnvSchema = v.object({ + VITE_BASE_URL: v.pipe(v.string(), v.url()), VITE_API_BASE_URL: v.pipe(v.string(), v.url()) }) diff --git a/yarn.lock b/yarn.lock index a8eefc5c1..369a8cd79 100644 --- a/yarn.lock +++ b/yarn.lock @@ -167,6 +167,57 @@ reselect "^5.2.0" use-sync-external-store "^1.6.0" +"@better-auth/core@1.6.23": + version "1.6.23" + resolved "https://registry.yarnpkg.com/@better-auth/core/-/core-1.6.23.tgz#1a6213ec81a3f7f084aae945736475d2b04c1b7a" + integrity sha512-beEhOs0uVeOxYOZKUfIEBd/nQV2Bd4/6wyLxZ0OFkn6CMTK2Vi+hXuZLnyPBeB6RdHpebEoJWiHqwHxBIxgPDQ== + dependencies: + "@opentelemetry/semantic-conventions" "^1.39.0" + "@standard-schema/spec" "^1.1.0" + zod "^4.3.6" + +"@better-auth/drizzle-adapter@1.6.23": + version "1.6.23" + resolved "https://registry.yarnpkg.com/@better-auth/drizzle-adapter/-/drizzle-adapter-1.6.23.tgz#d9f9f1c974e0e9a1e5fdc6685fad4a267c9d467c" + integrity sha512-2+/PTVfIP9E7iz6af8TB3lhnowHUj9ljC66kECmHaFEdUqPgzHoWux9epotKwO7XDg2ui4ttWQ8CMeNFLvQeKQ== + +"@better-auth/kysely-adapter@1.6.23": + version "1.6.23" + resolved "https://registry.yarnpkg.com/@better-auth/kysely-adapter/-/kysely-adapter-1.6.23.tgz#845a5de0d8e9927e15011908a838951abbfad427" + integrity sha512-zbNJsMbG09exfkGyvFqBLLqWoMPAUWjxCuUnEK5AsjbYoZeIjj/QGZgdf4CapVWryKxjA9Q6Jlr6fbiPpC3VAg== + +"@better-auth/memory-adapter@1.6.23": + version "1.6.23" + resolved "https://registry.yarnpkg.com/@better-auth/memory-adapter/-/memory-adapter-1.6.23.tgz#1295d3c8091cfa2a9beb2e7f9b29e44663dd09e5" + integrity sha512-krIiR0pIVkaKlAzm690n5bcMW4NGbqeMg0HQSD9fz/KcQF/eWLqcq9gG/BhHTj2i/y96qH+W5JWPmaSOS5iTgQ== + +"@better-auth/mongo-adapter@1.6.23": + version "1.6.23" + resolved "https://registry.yarnpkg.com/@better-auth/mongo-adapter/-/mongo-adapter-1.6.23.tgz#21637c529c8bc1b5ff27de8b96059d781acd151f" + integrity sha512-7+QdevitGlKBbP6JbiSk5SBnzPsKV/mDrQBGBn8hwByQLeJwqpqbuBPw7ZI8vzUlFfAAnyFiqwP3Eb8mxnp7pA== + +"@better-auth/prisma-adapter@1.6.23": + version "1.6.23" + resolved "https://registry.yarnpkg.com/@better-auth/prisma-adapter/-/prisma-adapter-1.6.23.tgz#d141a4cc74785392bb0490d37002bd6d75b3b661" + integrity sha512-2qSdzidq4tkb1eS5TTqb4Nzg0mdZWm3Qky9SYeXeb8PpVQbC2sxqJhEM5mK7y12uU6I8hc64wO9f7AFVNL+6UQ== + +"@better-auth/telemetry@1.6.23": + version "1.6.23" + resolved "https://registry.yarnpkg.com/@better-auth/telemetry/-/telemetry-1.6.23.tgz#a232e560c2e7f618c4ad19e01565c0ea8b84740e" + integrity sha512-/R2Kb+z2BpDOOWwVHqOk+c0VNpuwfCv4Hp5Yr9003WIZPax/zyNraGLB9CFE8qF2gZW8Dsz419k4I8CPrGzpDA== + +"@better-auth/utils@0.4.2", "@better-auth/utils@^0.4.0": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@better-auth/utils/-/utils-0.4.2.tgz#265a37e2ceef035e6968a851b13400d1b044e070" + integrity sha512-AUxrvu+HaaODsUyzDxFgwd/8RZ1yZaYo42LXKSrU2oGgR38pS1ij8nqQKNgtTWoYGpNevNXtCfgTy6loHveW9A== + dependencies: + "@noble/hashes" "^2.0.1" + +"@better-fetch/fetch@1.3.1", "@better-fetch/fetch@^1.1.21": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@better-fetch/fetch/-/fetch-1.3.1.tgz#04a0d289de818a0b436bfda48e70b2b19227cc19" + integrity sha512-ABkD1WhyfPZprKRQI3bhATjeiFuNWC9PXhfGWqL+sg/gKrM977oFrYkdb4msM3hgUGonr7KlOsOFT5TU2rht9g== + "@clack/core@0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@clack/core/-/core-0.4.1.tgz#36c8aed3f4904060a39275817e804e7a8ffb7e1c" @@ -769,6 +820,16 @@ dependencies: "@tybys/wasm-util" "^0.10.3" +"@noble/ciphers@^2.1.1": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-2.2.0.tgz#84fb45ac9332925d643b80f89ceb0ea2f21dba95" + integrity sha512-Z6pjIZ/8IJcCGzb2S/0Px5J81yij85xASuk1teLNeg75bfT07MV3a/O2Mtn1I2se43k3lkVEcFaR10N4cgQcZA== + +"@noble/hashes@^2.0.1": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-2.2.0.tgz#22da1d16a469954fce877055d559900a6c73b63b" + integrity sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -790,6 +851,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@opentelemetry/semantic-conventions@^1.39.0": + version "1.41.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.41.1.tgz#b04e7151c5913a7a006d4f465479da75efb98a7a" + integrity sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA== + "@oxc-project/types@=0.137.0": version "0.137.0" resolved "https://registry.yarnpkg.com/@oxc-project/types/-/types-0.137.0.tgz#56e77f8bb221fa05f18b1cd34d73f94f0954a773" @@ -1043,6 +1109,11 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz#719df7fb41766bc143369eaa0dd56d8dc87c9958" integrity sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg== +"@standard-schema/spec@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.1.0.tgz#a79b55dbaf8604812f52d140b2c9ab41bc150bb8" + integrity sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w== + "@standard-schema/utils@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@standard-schema/utils/-/utils-0.3.0.tgz#3d5e608f16c2390c10528e98e59aef6bf73cae7b" @@ -1722,11 +1793,6 @@ axe-core@^4.10.0: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.11.4.tgz#5b535e381ff1e61ffdd615e5483d16186d3b46a5" integrity sha512-KunSNx+TVpkAw/6ULfhnx+HWRecjqZGTOyquAoWHYLRSdK1tB5Ihce1ZW+UY3fj33bYAFWPu7W/GRSmmrCGuxA== -axios-auth-refresh@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/axios-auth-refresh/-/axios-auth-refresh-5.0.2.tgz#a0726f615a2e7d1977429b6d9453db210c692975" - integrity sha512-1UvQMxwCR5Y2V7i7862kIQDbuWqw4LgWRjaxtFg9+bwKPIQW3kvh/Ay6uVYhUInAkPgN0rLzH0sU8ECd3qKPBQ== - axios@^1.18.1: version "1.18.1" resolved "https://registry.yarnpkg.com/axios/-/axios-1.18.1.tgz#d63f9863bcd8938815c86f9e2abd380189d96dfe" @@ -1767,6 +1833,39 @@ baseline-browser-mapping@^2.10.12: resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.33.tgz#27c299b096404978831958d429f48390424c4f9b" integrity sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw== +better-auth@^1.6.23: + version "1.6.23" + resolved "https://registry.yarnpkg.com/better-auth/-/better-auth-1.6.23.tgz#1af5228d94be69fb2e63b5bfd57d843c849cc28a" + integrity sha512-4vOaRd9UiKGKm9R+ej0jjU1es3MiJIiNc9Qq3VCnYqOZ4/nb5272QqTxWYoDxyUXl5x6A2x2we5KZKQO9teTQQ== + dependencies: + "@better-auth/core" "1.6.23" + "@better-auth/drizzle-adapter" "1.6.23" + "@better-auth/kysely-adapter" "1.6.23" + "@better-auth/memory-adapter" "1.6.23" + "@better-auth/mongo-adapter" "1.6.23" + "@better-auth/prisma-adapter" "1.6.23" + "@better-auth/telemetry" "1.6.23" + "@better-auth/utils" "0.4.2" + "@better-fetch/fetch" "1.3.1" + "@noble/ciphers" "^2.1.1" + "@noble/hashes" "^2.0.1" + better-call "1.3.7" + defu "^6.1.4" + jose "^6.1.3" + kysely "^0.28.17 || ^0.29.0" + nanostores "^1.1.1" + zod "^4.3.6" + +better-call@1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/better-call/-/better-call-1.3.7.tgz#2889806d909c1efb636b7e9009e7deba8927106f" + integrity sha512-Al51/hjp2SSp6CRTa3F2ptcx4yQVS1xWKoY6jcVXqNYOap6mHFP2jUBn5EwIL4iIed1/Sq4hlQ+Umm6EflZG+w== + dependencies: + "@better-auth/utils" "^0.4.0" + "@better-fetch/fetch" "^1.1.21" + rou3 "^0.7.12" + set-cookie-parser "^3.0.1" + birecord@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/birecord/-/birecord-0.1.1.tgz#abc07c8187bf24fb1e0055cd9feb18b30e477a03" @@ -2162,6 +2261,11 @@ define-properties@^1.1.3, define-properties@^1.2.1: has-property-descriptors "^1.0.0" object-keys "^1.1.1" +defu@^6.1.4: + version "6.1.7" + resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.7.tgz#72543567c8e9f97ff13ce402b6dbe09ac5ae4d23" + integrity sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -3447,6 +3551,11 @@ jiti@^2.7.0: resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.7.0.tgz#974228f2f4ca2bc21885a1797b45fea68e950c64" integrity sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ== +jose@^6.1.3: + version "6.2.3" + resolved "https://registry.yarnpkg.com/jose/-/jose-6.2.3.tgz#0975197ad973251221c658a3cddc4b951a250c2d" + integrity sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -3511,6 +3620,11 @@ keyv@^4.5.4: dependencies: json-buffer "3.0.1" +"kysely@^0.28.17 || ^0.29.0": + version "0.29.2" + resolved "https://registry.yarnpkg.com/kysely/-/kysely-0.29.2.tgz#4a07da18db3bba2911693c2b3bd4af415104a85f" + integrity sha512-s6WVJyEZrbm6jhBpiKHsGHyePMrVQKJ85wZCFCr9W4QHv6WTjWIrdvTmO9hDEA3bNK0xkrE2DqrHsXMLWuZpQg== + language-subtag-registry@^0.3.20: version "0.3.23" resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz#23529e04d9e3b74679d70142df3fd2eb6ec572e7" @@ -3803,6 +3917,11 @@ nanoid@^3.3.12: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.12.tgz#ab3d912e217a6d0a514f00a72a16543a28982c05" integrity sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ== +nanostores@^1.1.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/nanostores/-/nanostores-1.4.0.tgz#9acc8a6026533dc0410c37cb3b076db00163d277" + integrity sha512-i0tloweeudshAEuddpDxcg9Ik6pkPfVsHIgKyf143JrgG7/MOh0+q7BypdLXZPoOP7fOYt1eTcwGkyiVmhJFkA== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -4259,6 +4378,11 @@ rolldown@~1.1.2: "@rolldown/binding-win32-arm64-msvc" "1.1.3" "@rolldown/binding-win32-x64-msvc" "1.1.3" +rou3@^0.7.12: + version "0.7.12" + resolved "https://registry.yarnpkg.com/rou3/-/rou3-0.7.12.tgz#cac17425c04abddba854a42385cabfe0b971a179" + integrity sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg== + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -4324,6 +4448,11 @@ seroval@^1.5.4: resolved "https://registry.yarnpkg.com/seroval/-/seroval-1.5.4.tgz#9d0cedae244f8213bbbbbcc99c497eb7c945d961" integrity sha512-46uFvgrXTVxZcUorgSSRZ4y+ieqLLQRMlG4bnCZKW3qI6BZm7Rg4ntMW4p1mILEEBZWrFlcpp0AyIIlM6jD9iw== +set-cookie-parser@^3.0.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-3.1.1.tgz#5d80652208e37545aba30ea613d4f797ea405af8" + integrity sha512-vM9SUhjsUYs6UeJUmygc5Ofm5eQGe85riob5ju6XCgFGJI5PLV4nrDAQpQjd+LkFBpAkADn5BQQpZ9EUNkyLuA== + set-function-length@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" @@ -5158,7 +5287,7 @@ zod@3.22.4: resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff" integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg== -"zod@^3.25.0 || ^4.0.0", zod@^4.4.3: +"zod@^3.25.0 || ^4.0.0", zod@^4.3.6, zod@^4.4.3: version "4.4.3" resolved "https://registry.yarnpkg.com/zod/-/zod-4.4.3.tgz#b680f172885d18bbebf21a834ea25e55a1bbf356" integrity sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==