diff --git a/template/apps/api/package.json b/template/apps/api/package.json index f1240a49..4183979e 100644 --- a/template/apps/api/package.json +++ b/template/apps/api/package.json @@ -23,7 +23,6 @@ "@aws-sdk/lib-storage": "3.540.0", "@aws-sdk/s3-request-presigner": "3.540.0", "@koa/cors": "5.0.0", - "@koa/multer": "3.0.2", "@koa/router": "13.0.0", "@paralect/node-mongo": "3.2.0", "@socket.io/redis-adapter": "8.1.0", @@ -37,6 +36,7 @@ "ioredis": "5.3.2", "jsonwebtoken": "9.0.0", "koa": "2.14.1", + "koa-body": "6.0.1", "koa-bodyparser": "4.3.0", "koa-compose": "4.1.0", "koa-helmet": "6.1.0", @@ -70,7 +70,6 @@ "@types/koa-mount": "4.0.2", "@types/koa-ratelimit": "5.0.0", "@types/koa__cors": "3.3.1", - "@types/koa__multer": "2.0.4", "@types/koa__router": "12.0.0", "@types/lodash": "4.14.191", "@types/module-alias": "2.0.1", diff --git a/template/apps/api/src/app.ts b/template/apps/api/src/app.ts index c107a4f9..98f3d0fd 100644 --- a/template/apps/api/src/app.ts +++ b/template/apps/api/src/app.ts @@ -10,7 +10,8 @@ import 'dotenv/config'; import cors from '@koa/cors'; import http from 'http'; -import bodyParser from 'koa-bodyparser'; +import { koaBody } from 'koa-body'; + import helmet from 'koa-helmet'; import koaLogger from 'koa-logger'; import qs from 'koa-qs'; @@ -34,10 +35,11 @@ const initKoa = () => { app.use(helmet()); qs(app); app.use( - bodyParser({ - enableTypes: ['json', 'form', 'text'], - onerror: (err: Error, ctx) => { - const errText: string = err.stack || err.toString(); + koaBody({ + multipart: true, + onError: (error, ctx) => { + const errText: string = error.stack || error.toString(); + logger.warn(`Unable to parse request body. ${errText}`); ctx.throw(422, 'Unable to parse request JSON.'); }, diff --git a/template/apps/api/src/middlewares/validate.middleware.ts b/template/apps/api/src/middlewares/validate.middleware.ts index 77e624b3..c41facd9 100644 --- a/template/apps/api/src/middlewares/validate.middleware.ts +++ b/template/apps/api/src/middlewares/validate.middleware.ts @@ -20,7 +20,8 @@ const formatError = (zodError: ZodError): ValidationErrors => { const validate = (schema: ZodSchema) => async (ctx: AppKoaContext, next: Next) => { const result = await schema.safeParseAsync({ - ...(ctx.request.body as object), + ...ctx.request.body, + ...ctx.request.files, ...ctx.query, ...ctx.params, }); diff --git a/template/apps/api/src/resources/account/account.routes.ts b/template/apps/api/src/resources/account/account.routes.ts index 39f2bb3d..d1763d68 100644 --- a/template/apps/api/src/resources/account/account.routes.ts +++ b/template/apps/api/src/resources/account/account.routes.ts @@ -3,7 +3,6 @@ import { routeUtil } from 'utils'; import forgotPassword from './actions/forgot-password'; import get from './actions/get'; import google from './actions/google'; -import removeAvatar from './actions/remove-avatar'; import resendEmail from './actions/resend-email'; import resetPassword from './actions/reset-password'; import shadowLogin from './actions/shadow-login'; @@ -11,7 +10,6 @@ import signIn from './actions/sign-in'; import signOut from './actions/sign-out'; import signUp from './actions/sign-up'; import update from './actions/update'; -import uploadAvatar from './actions/upload-avatar'; import verifyEmail from './actions/verify-email'; import verifyResetToken from './actions/verify-reset-token'; @@ -27,7 +25,7 @@ const publicRoutes = routeUtil.getRoutes([ google, ]); -const privateRoutes = routeUtil.getRoutes([get, update, uploadAvatar, removeAvatar]); +const privateRoutes = routeUtil.getRoutes([get, update]); const adminRoutes = routeUtil.getRoutes([shadowLogin]); diff --git a/template/apps/api/src/resources/account/account.utils.ts b/template/apps/api/src/resources/account/account.utils.ts new file mode 100644 index 00000000..83920503 --- /dev/null +++ b/template/apps/api/src/resources/account/account.utils.ts @@ -0,0 +1,25 @@ +import { cloudStorageService } from 'services'; + +import { BackendFile, User } from 'types'; + +export const removeAvatar = async (user: User) => { + if (user.avatarUrl) { + const fileKey = cloudStorageService.getFileKey(user.avatarUrl); + + await cloudStorageService.deleteObject(fileKey); + } +}; + +export const uploadAvatar = async (user: User, file: BackendFile, customFileName?: string): Promise => { + await removeAvatar(user); + + const fileName = customFileName || `${user._id}-${Date.now()}-${file.originalFilename}`; + + const { location: avatarUrl } = await cloudStorageService.uploadPublic(`avatars/${fileName}`, file); + + if (!avatarUrl) { + throw new Error("An error occurred while uploading the user's avatar"); + } + + return avatarUrl; +}; diff --git a/template/apps/api/src/resources/account/actions/remove-avatar.ts b/template/apps/api/src/resources/account/actions/remove-avatar.ts deleted file mode 100644 index 189d649b..00000000 --- a/template/apps/api/src/resources/account/actions/remove-avatar.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { userService } from 'resources/user'; - -import { cloudStorageService } from 'services'; - -import { AppKoaContext, AppRouter, Next } from 'types'; - -async function validator(ctx: AppKoaContext, next: Next) { - const { user } = ctx.state; - - ctx.assertClientError(user.avatarUrl, { global: "You don't have an avatar" }); - - await next(); -} - -async function handler(ctx: AppKoaContext) { - const { user } = ctx.state; - - const fileKey = cloudStorageService.getFileKey(user.avatarUrl); - - const [updatedUser] = await Promise.all([ - userService.updateOne({ _id: user._id }, () => ({ avatarUrl: null })), - cloudStorageService.deleteObject(fileKey), - ]); - - ctx.body = userService.getPublic(updatedUser); -} - -export default (router: AppRouter) => { - router.delete('/avatar', validator, handler); -}; diff --git a/template/apps/api/src/resources/account/actions/update.ts b/template/apps/api/src/resources/account/actions/update.ts index 044080c3..1046112b 100644 --- a/template/apps/api/src/resources/account/actions/update.ts +++ b/template/apps/api/src/resources/account/actions/update.ts @@ -1,14 +1,15 @@ import _ from 'lodash'; +import { accountUtils } from 'resources/account'; import { userService } from 'resources/user'; import { validateMiddleware } from 'middlewares'; import { securityUtil } from 'utils'; import { updateUserSchema } from 'schemas'; -import { AppKoaContext, AppRouter, Next, UpdateUserParams } from 'types'; +import { AppKoaContext, AppRouter, Next, UpdateUserParamsBackend, User } from 'types'; -interface ValidatedData extends UpdateUserParams { +interface ValidatedData extends UpdateUserParamsBackend { passwordHash?: string | null; } @@ -32,11 +33,23 @@ async function validator(ctx: AppKoaContext, next: Next) { } async function handler(ctx: AppKoaContext) { + const { avatar } = ctx.validatedData; const { user } = ctx.state; - const updatedUser = await userService.updateOne({ _id: user._id }, () => _.pickBy(ctx.validatedData)); + const nonEmptyValues = _.pickBy(ctx.validatedData, (value) => !_.isUndefined(value)); + const updateData: Partial = _.omit(nonEmptyValues, 'avatar'); - ctx.body = userService.getPublic(updatedUser); + if (avatar === '') { + await accountUtils.removeAvatar(user); + + updateData.avatarUrl = null; + } + + if (avatar && typeof avatar !== 'string') { + updateData.avatarUrl = await accountUtils.uploadAvatar(user, avatar); + } + + ctx.body = await userService.updateOne({ _id: user._id }, () => updateData).then(userService.getPublic); } export default (router: AppRouter) => { diff --git a/template/apps/api/src/resources/account/actions/upload-avatar.ts b/template/apps/api/src/resources/account/actions/upload-avatar.ts deleted file mode 100644 index 35db0cfa..00000000 --- a/template/apps/api/src/resources/account/actions/upload-avatar.ts +++ /dev/null @@ -1,37 +0,0 @@ -import multer from '@koa/multer'; - -import { userService } from 'resources/user'; - -import { cloudStorageService } from 'services'; - -import { AppKoaContext, AppRouter, Next } from 'types'; - -const upload = multer(); - -async function validator(ctx: AppKoaContext, next: Next) { - const { file } = ctx.request; - - ctx.assertClientError(file, { global: 'File cannot be empty' }); - - await next(); -} - -async function handler(ctx: AppKoaContext) { - const { user } = ctx.state; - const { file } = ctx.request; - - if (user.avatarUrl) { - const fileKey = cloudStorageService.getFileKey(user.avatarUrl); - - await cloudStorageService.deleteObject(fileKey); - } - - const fileName = `${user._id}-${Date.now()}-${file.originalname}`; - const { location: avatarUrl } = await cloudStorageService.uploadPublic(`avatars/${fileName}`, file); - - ctx.body = await userService.updateOne({ _id: user._id }, () => ({ avatarUrl })).then(userService.getPublic); -} - -export default (router: AppRouter) => { - router.post('/avatar', upload.single('file'), validator, handler); -}; diff --git a/template/apps/api/src/resources/account/index.ts b/template/apps/api/src/resources/account/index.ts index ba792e66..054ff439 100644 --- a/template/apps/api/src/resources/account/index.ts +++ b/template/apps/api/src/resources/account/index.ts @@ -1,3 +1,4 @@ import accountRoutes from './account.routes'; +import * as accountUtils from './account.utils'; -export { accountRoutes }; +export { accountRoutes, accountUtils }; diff --git a/template/apps/api/src/services/cloud-storage/cloud-storage.service.ts b/template/apps/api/src/services/cloud-storage/cloud-storage.service.ts index 533803b4..bb7f1378 100644 --- a/template/apps/api/src/services/cloud-storage/cloud-storage.service.ts +++ b/template/apps/api/src/services/cloud-storage/cloud-storage.service.ts @@ -11,13 +11,13 @@ import { import { PutObjectCommandInput } from '@aws-sdk/client-s3/dist-types/commands/PutObjectCommand'; import { Upload } from '@aws-sdk/lib-storage'; import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; -import type { File } from '@koa/multer'; +import fs from 'fs/promises'; import { caseUtil } from 'utils'; import config from 'config'; -import { ToCamelCase } from 'types'; +import { BackendFile, ToCamelCase } from 'types'; import * as helpers from './cloud-storage.helper'; @@ -26,19 +26,20 @@ const client = new S3Client({ region: 'us-east-1', // To successfully create a new bucket, this SDK requires the region to be us-east-1 endpoint: config.CLOUD_STORAGE_ENDPOINT, credentials: { - accessKeyId: config.CLOUD_STORAGE_ACCESS_KEY_ID ?? '', - secretAccessKey: config.CLOUD_STORAGE_SECRET_ACCESS_KEY ?? '', + accessKeyId: config.CLOUD_STORAGE_ACCESS_KEY_ID as string, + secretAccessKey: config.CLOUD_STORAGE_SECRET_ACCESS_KEY as string, }, }); + const bucket = config.CLOUD_STORAGE_BUCKET; type UploadOutput = ToCamelCase; -const upload = async (fileName: string, file: File): Promise => { +const upload = async (fileName: string, file: BackendFile): Promise => { const params: PutObjectCommandInput = { Bucket: bucket, - ContentType: file.mimetype, - Body: file.buffer, + ContentType: file.mimetype as string, + Body: await fs.readFile(file.filepath as string), Key: fileName, ACL: 'private', }; @@ -51,11 +52,11 @@ const upload = async (fileName: string, file: File): Promise => { return multipartUpload.done().then((value) => caseUtil.toCamelCase(value)); }; -const uploadPublic = async (fileName: string, file: File): Promise => { +const uploadPublic = async (fileName: string, file: BackendFile): Promise => { const params: PutObjectCommandInput = { Bucket: bucket, - ContentType: file.mimetype, - Body: file.buffer, + ContentType: file.mimetype as string, + Body: await fs.readFile(file.filepath as string), Key: fileName, ACL: 'public-read', }; diff --git a/template/apps/web/next-env.d.ts b/template/apps/web/next-env.d.ts index 4f11a03d..a4a7b3f5 100644 --- a/template/apps/web/next-env.d.ts +++ b/template/apps/web/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/basic-features/typescript for more information. +// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information. diff --git a/template/apps/web/next.config.js b/template/apps/web/next.config.js index 4c7cd060..270e8158 100644 --- a/template/apps/web/next.config.js +++ b/template/apps/web/next.config.js @@ -25,4 +25,16 @@ module.exports = { }, pageExtensions: ['page.tsx', 'api.ts'], transpilePackages: ['app-constants', 'schemas', 'types'], + i18n: { + locales: ['en-US'], + defaultLocale: 'en-US', + }, + images: { + remotePatterns: [ + { + protocol: 'https', + hostname: '**.digitaloceanspaces.com', + }, + ], + }, }; diff --git a/template/apps/web/package.json b/template/apps/web/package.json index e090351e..609d8f8f 100644 --- a/template/apps/web/package.json +++ b/template/apps/web/package.json @@ -36,7 +36,8 @@ "dotenv-flow": "4.1.0", "lodash": "4.17.21", "mixpanel-browser": "2.53.0", - "next": "14.2.5", + "next": "14.2.10", + "object-to-formdata": "4.5.1", "react": "18.3.1", "react-dom": "18.3.1", "react-hook-form": "7.52.1", diff --git a/template/apps/web/src/pages/_app/PageConfig/MainLayout/Header/components/MenuToggle/index.tsx b/template/apps/web/src/pages/_app/PageConfig/MainLayout/Header/components/MenuToggle/index.tsx index 35c5346c..e5b5f851 100644 --- a/template/apps/web/src/pages/_app/PageConfig/MainLayout/Header/components/MenuToggle/index.tsx +++ b/template/apps/web/src/pages/_app/PageConfig/MainLayout/Header/components/MenuToggle/index.tsx @@ -11,8 +11,8 @@ const MenuToggle = forwardRef((props, ref) => { if (!account) return null; return ( - - + + {account.firstName.charAt(0)} {account.lastName.charAt(0)} @@ -20,6 +20,4 @@ const MenuToggle = forwardRef((props, ref) => { ); }); -MenuToggle.displayName = 'MenuToggle'; - export default MenuToggle; diff --git a/template/apps/web/src/pages/profile/components/AvatarUpload/index.module.css b/template/apps/web/src/pages/profile/components/AvatarUpload/index.module.css new file mode 100644 index 00000000..fd9a6781 --- /dev/null +++ b/template/apps/web/src/pages/profile/components/AvatarUpload/index.module.css @@ -0,0 +1,60 @@ +.root { + --dropzone-size: 100px; + --dropzone-hover-color: var(--mantine-color-gray-5); + + padding: 0; + background-color: transparent; + + border: none; + border-radius: 50%; + + @mixin hover { + .addIcon { + color: var(--dropzone-hover-color); + } + + .browseButton { + border-color: var(--dropzone-hover-color); + } + + .editOverlay { + opacity: 1; + } + } +} + +.browseButton { + width: var(--dropzone-size); + height: var(--dropzone-size); + + border: 1px dashed var(--mantine-primary-color-filled); + border-radius: 50%; + + cursor: pointer; + overflow: hidden; + transition: all 0.2s ease-in-out; +} + +.imageExists { + border-color: transparent !important; +} + +.addIcon { + color: var(--mantine-primary-color-filled); + + transition: all 0.2s ease-in-out; +} + +.pencilIcon { + color: var(--dropzone-hover-color); + + transition: all 0.2s ease-in-out; +} + +.editOverlay { + border-radius: 50%; + background-color: alpha(var(--mantine-color-black), 0.5); + + opacity: 0; + transition: all 0.3s ease-in-out; +} diff --git a/template/apps/web/src/pages/profile/components/AvatarUpload/index.tsx b/template/apps/web/src/pages/profile/components/AvatarUpload/index.tsx new file mode 100644 index 00000000..e5cc1ece --- /dev/null +++ b/template/apps/web/src/pages/profile/components/AvatarUpload/index.tsx @@ -0,0 +1,118 @@ +import { useEffect, useState } from 'react'; +import NextImage from 'next/image'; +import { Box, Button, Center, Group, Image, Stack, Text, Title } from '@mantine/core'; +import { Dropzone } from '@mantine/dropzone'; +import { IconPencil, IconPlus } from '@tabler/icons-react'; +import cx from 'clsx'; +import { Controller, useFormContext } from 'react-hook-form'; + +import { accountApi } from 'resources/account'; + +import { handleDropzoneError } from 'utils'; + +import { USER_AVATAR } from 'app-constants'; +import { UpdateUserParamsFrontend } from 'types'; + +import classes from './index.module.css'; + +const AvatarUpload = () => { + const [imageSrc, setImageSrc] = useState(undefined); + + const { data: account } = accountApi.useGet(); + + const { + control, + watch, + setValue, + formState: { errors }, + } = useFormContext(); + + const avatarValue = watch('avatar'); + const avatarError = errors.avatar?.message; + + useEffect(() => { + if (typeof avatarValue === 'string') { + setImageSrc(''); + return; + } + + const imageUrl = avatarValue ? URL.createObjectURL(avatarValue) : account?.avatarUrl; + + setImageSrc(imageUrl); + }, [avatarValue]); + + return ( + + + + ( + field.onChange(imageFile)} + onReject={handleDropzoneError} + multiple={false} + classNames={classes} + {...field} + > +
+ {imageSrc ? ( + + Avatar + +
+ +
+
+ ) : ( + + )} +
+
+ )} + /> + + {(avatarValue || imageSrc === '') && ( + + )} + + {account?.avatarUrl && avatarValue === undefined && ( + + )} +
+ + + Profile picture + + + JPG, JPEG or PNG + Max size = 5 MB + + +
+ + {avatarError && {avatarError}} +
+ ); +}; + +export default AvatarUpload; diff --git a/template/apps/web/src/pages/profile/components/PhotoUpload/index.module.css b/template/apps/web/src/pages/profile/components/PhotoUpload/index.module.css deleted file mode 100644 index 9ec547a8..00000000 --- a/template/apps/web/src/pages/profile/components/PhotoUpload/index.module.css +++ /dev/null @@ -1,72 +0,0 @@ -.dropzoneRoot { - border: none; - border-radius: 0; - padding: 0; - background-color: transparent; - - &:hover .addIcon { - color: var(--mantine-color-gray-5); - } - - &:hover .browseButton { - border: 1px dashed var(--mantine-color-gray-5); - } - - &:hover .innerAvatar { - opacity: 1; - } -} - -.browseButton { - width: 88px; - height: 88px; - border-radius: 50%; - border: 1px dashed var(--mantine-primary-color-filled); - display: flex; - justify-content: center; - align-items: center; - transition: all 200ms ease-in-out; - cursor: pointer; -} - -.error { - border: 1px dashed var(--mantine-color-red-5); -} - -.addIcon { - color: var(--mantine-primary-color-filled); - transition: all 200ms ease-in-out; -} - -.innerAvatar { - border-radius: 50%; - - opacity: 0; - transition: all 300ms ease-in-out; -} - -.text { - width: 144px; - line-height: 24px; - color: var(--mantine-color-gray-6); - word-wrap: break-word; -} - -.buttonContainer { - display: flex; - align-items: center; -} - -.errorMessage { - margin-top: 4px; - font-size: 14px; - line-height: 17px; - color: var(--mantine-color-red-5); -} - -.avatar { - background-position: center; - background-size: cover; - background-repeat: no-repeat; - border-radius: 50%; -} diff --git a/template/apps/web/src/pages/profile/components/PhotoUpload/index.tsx b/template/apps/web/src/pages/profile/components/PhotoUpload/index.tsx deleted file mode 100644 index 22b8468d..00000000 --- a/template/apps/web/src/pages/profile/components/PhotoUpload/index.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import { memo, useState } from 'react'; -import { BackgroundImage, Button, Center, Group, Stack, Text } from '@mantine/core'; -import { Dropzone, FileWithPath } from '@mantine/dropzone'; -import { IconPencil, IconPlus } from '@tabler/icons-react'; -import cx from 'clsx'; - -import { accountApi } from 'resources/account'; - -import { handleApiError } from 'utils'; - -import classes from './index.module.css'; - -const ONE_MB_IN_BYTES = 1048576; - -const PhotoUpload = () => { - const [errorMessage, setErrorMessage] = useState(null); - - const { data: account } = accountApi.useGet(); - - const { mutate: uploadProfilePhoto } = accountApi.useUploadAvatar(); - const { mutate: removeProfilePhoto } = accountApi.useRemoveAvatar(); - - if (!account) return null; - - const isFileSizeCorrect = (file: FileWithPath) => { - if (file.size / ONE_MB_IN_BYTES > 2) { - setErrorMessage('Sorry, you cannot upload a file larger than 2 MB.'); - return false; - } - return true; - }; - - const isFileFormatCorrect = (file: FileWithPath) => { - if (['image/png', 'image/jpg', 'image/jpeg'].includes(file.type)) return true; - setErrorMessage('Sorry, you can only upload JPG, JPEG or PNG photos.'); - return false; - }; - - const handlePhotoUpload = async ([imageFile]: FileWithPath[]) => { - setErrorMessage(null); - - if (isFileFormatCorrect(imageFile) && isFileSizeCorrect(imageFile) && imageFile) { - const body = new FormData(); - body.append('file', imageFile, imageFile.name); - - uploadProfilePhoto(body, { - onError: (e) => handleApiError(e), - }); - } - }; - - const handlerPhotoRemove = async () => { - setErrorMessage(null); - removeProfilePhoto(); - }; - - return ( - <> - - - - - - - - {account.avatarUrl && ( - - )} - - - - - Profile picture - - - JPG, JPEG or PNG Max size = 2MB - - - - - {!!errorMessage &&

{errorMessage}

} - - ); -}; - -export default memo(PhotoUpload); diff --git a/template/apps/web/src/pages/profile/index.page.tsx b/template/apps/web/src/pages/profile/index.page.tsx index 077df1f5..9fa472e8 100644 --- a/template/apps/web/src/pages/profile/index.page.tsx +++ b/template/apps/web/src/pages/profile/index.page.tsx @@ -3,8 +3,9 @@ import Head from 'next/head'; import { Button, PasswordInput, Stack, TextInput, Title } from '@mantine/core'; import { showNotification } from '@mantine/notifications'; import { zodResolver } from '@hookform/resolvers/zod'; -import pickBy from 'lodash/pickBy'; -import { useForm } from 'react-hook-form'; +import { isUndefined, pickBy } from 'lodash'; +import { serialize } from 'object-to-formdata'; +import { FormProvider, useForm } from 'react-hook-form'; import { accountApi } from 'resources/account'; @@ -13,13 +14,26 @@ import { handleApiError } from 'utils'; import queryClient from 'query-client'; import { updateUserSchema } from 'schemas'; -import { UpdateUserParams } from 'types'; +import { UpdateUserParams, User } from 'types'; -import PhotoUpload from './components/PhotoUpload'; +import AvatarUpload from './components/AvatarUpload'; + +const getFormDefaultValues = (account?: User) => ({ + firstName: account?.firstName, + lastName: account?.lastName, + password: '', + avatar: undefined, +}); const Profile: NextPage = () => { const { data: account } = accountApi.useGet(); + const methods = useForm({ + resolver: zodResolver(updateUserSchema), + mode: 'onBlur', + defaultValues: getFormDefaultValues(account), + }); + const { register, handleSubmit, @@ -27,19 +41,19 @@ const Profile: NextPage = () => { setValue, reset, formState: { errors, isDirty }, - } = useForm({ - resolver: zodResolver(updateUserSchema), - defaultValues: { - firstName: account?.firstName, - lastName: account?.lastName, - password: '', - }, - }); + } = methods; + + const { mutate: updateAccount, isPending: isUpdatePending } = accountApi.useUpdate(); - const { mutate: updateAccount, isPending: isUpdatePending } = accountApi.useUpdate(); + const onSubmit = (submitData: UpdateUserParams) => { + const updateData = pickBy(submitData, (value, key) => { + if (account && account[key as keyof User] === value) return false; + if (key === 'password' && value === '') return false; + + return !isUndefined(value); + }); - const onSubmit = (submitData: UpdateUserParams) => - updateAccount(pickBy(submitData), { + updateAccount(serialize(updateData), { onSuccess: (data) => { queryClient.setQueryData(['account'], data); @@ -49,11 +63,13 @@ const Profile: NextPage = () => { color: 'green', }); - reset(data, { keepDirtyValues: true }); + reset(getFormDefaultValues(data), { keepValues: true }); setValue('password', ''); + setValue('avatar', undefined); }, onError: (e) => handleApiError(e, setError), }); + }; return ( <> @@ -64,15 +80,15 @@ const Profile: NextPage = () => { Profile - + + + -
- @@ -97,7 +113,7 @@ const Profile: NextPage = () => { Update Profile - +
); diff --git a/template/apps/web/src/theme/components/Button/index.module.css b/template/apps/web/src/theme/components/Button/index.module.css index e2158411..bf590249 100644 --- a/template/apps/web/src/theme/components/Button/index.module.css +++ b/template/apps/web/src/theme/components/Button/index.module.css @@ -3,6 +3,8 @@ } .root { + transition: all 0.2s ease-in-out; + &:disabled, &[data-disabled] { background-color: light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4)); diff --git a/template/apps/web/src/utils/handle-error.util.ts b/template/apps/web/src/utils/handle-error.util.ts index dfda88fd..ca79a620 100644 --- a/template/apps/web/src/utils/handle-error.util.ts +++ b/template/apps/web/src/utils/handle-error.util.ts @@ -1,6 +1,8 @@ +import { FileRejection } from '@mantine/dropzone'; import { showNotification } from '@mantine/notifications'; import { FieldValues, Path, UseFormSetError } from 'react-hook-form'; +import { ONE_MB_IN_BYTES } from 'app-constants'; import { ApiError } from 'types'; type ValidationErrors = { @@ -41,3 +43,51 @@ export const handleApiError = ( }); } }; + +enum ErrorCode { + FileInvalidType = 'file-invalid-type', + FileTooLarge = 'file-too-large', +} + +export const handleDropzoneError = (fileRejections: FileRejection[]) => { + fileRejections.forEach((fileRejection) => { + const { errors } = fileRejection; + + errors.forEach((error) => { + let { message } = error; + + switch (error.code) { + case ErrorCode.FileTooLarge: { + const [maxSizeInBytes] = message.split(' ').slice(-2); + + const maxSizeInMb = Number(maxSizeInBytes) / ONE_MB_IN_BYTES; + + message = `Maximum file size allowed is ${maxSizeInMb} MB.`; + break; + } + + case ErrorCode.FileInvalidType: { + const [fileFormats] = message.split(' ').slice(-1); + + const fileExtensions = fileFormats.split(',').map((format) => `.${format.split('/')[1]}`); + + if (fileExtensions.length === 1) { + message = `Only ${fileExtensions[0]} file type is allowed.`; + break; + } + + message = `Allowed file types are ${fileExtensions.join(', ')}.`; + break; + } + default: + break; + } + + showNotification({ + title: 'Error', + message, + color: 'red', + }); + }); + }); +}; diff --git a/template/packages/app-constants/src/file.constants.ts b/template/packages/app-constants/src/file.constants.ts new file mode 100644 index 00000000..690a4f64 --- /dev/null +++ b/template/packages/app-constants/src/file.constants.ts @@ -0,0 +1,8 @@ +export const ONE_MB_IN_BYTES = 1_048_576; + +export const IMAGE_MIME_TYPE = ['image/jpg', 'image/jpeg', 'image/png']; + +export const USER_AVATAR = { + MAX_FILE_SIZE: 3 * ONE_MB_IN_BYTES, + ACCEPTED_FILE_TYPES: IMAGE_MIME_TYPE, +}; diff --git a/template/packages/app-constants/src/index.ts b/template/packages/app-constants/src/index.ts index 02a63c02..14e220d5 100644 --- a/template/packages/app-constants/src/index.ts +++ b/template/packages/app-constants/src/index.ts @@ -1,2 +1,3 @@ export * from './api.constants'; +export * from './file.constants'; export * from './regex.constants'; diff --git a/template/packages/app-types/package.json b/template/packages/app-types/package.json index 82e643fe..9529a41a 100644 --- a/template/packages/app-types/package.json +++ b/template/packages/app-types/package.json @@ -15,6 +15,7 @@ "zod": "*" }, "devDependencies": { + "@types/formidable": "2.0.5", "@types/node": "*", "eslint": "*", "eslint-config-custom": "workspace:*", diff --git a/template/packages/app-types/src/common.types.ts b/template/packages/app-types/src/common.types.ts index 1d29f762..0e0862d9 100644 --- a/template/packages/app-types/src/common.types.ts +++ b/template/packages/app-types/src/common.types.ts @@ -1,3 +1,8 @@ +import type { File as FormidableFile } from 'formidable'; + +export type BackendFile = FormidableFile; +export type FrontendFile = File; + type Path = T extends object ? { [K in keyof T]: K extends string diff --git a/template/packages/app-types/src/user.types.ts b/template/packages/app-types/src/user.types.ts index 68afe674..af4f1345 100644 --- a/template/packages/app-types/src/user.types.ts +++ b/template/packages/app-types/src/user.types.ts @@ -10,6 +10,8 @@ import { userSchema, } from 'schemas'; +import { BackendFile, FrontendFile } from './common.types'; + export type User = z.infer; export type SignInParams = z.infer; @@ -18,3 +20,11 @@ export type ResendEmailParams = z.infer; export type ForgotPasswordParams = z.infer; export type ResetPasswordParams = z.infer; export type UpdateUserParams = z.infer; + +export type UpdateUserParamsFrontend = Omit & { + avatar?: FrontendFile | string; +}; + +export type UpdateUserParamsBackend = Omit & { + avatar?: BackendFile | string; +}; diff --git a/template/packages/schemas/package.json b/template/packages/schemas/package.json index 786397db..bead4209 100644 --- a/template/packages/schemas/package.json +++ b/template/packages/schemas/package.json @@ -15,6 +15,7 @@ "zod": "*" }, "devDependencies": { + "@types/formidable": "*", "@types/node": "*", "eslint": "*", "eslint-config-custom": "workspace:*", diff --git a/template/packages/schemas/src/common.schema.ts b/template/packages/schemas/src/common.schema.ts index 3074e0d2..0ee0175c 100644 --- a/template/packages/schemas/src/common.schema.ts +++ b/template/packages/schemas/src/common.schema.ts @@ -1,6 +1,7 @@ +import type { File as FormidableFile } from 'formidable'; import { z } from 'zod'; -import { EMAIL_REGEX, PASSWORD_REGEX } from 'app-constants'; +import { EMAIL_REGEX, ONE_MB_IN_BYTES, PASSWORD_REGEX } from 'app-constants'; export const paginationSchema = z.object({ page: z.coerce.number().default(1), @@ -22,3 +23,21 @@ export const passwordSchema = z PASSWORD_REGEX, 'The password must contain 6 or more characters with at least one letter (a-z) and one number (0-9).', ); + +export const fileSchema = (fileSize: number, acceptedFileTypes: string[]) => + z + .union([z.custom(), z.custom()]) + .refine((file) => !!file, 'File is required.') + .refine((file) => file.size <= fileSize, `Max file size is ${Math.round(fileSize / ONE_MB_IN_BYTES)}MB.`) + .refine( + (file) => { + if (file) { + const mimetype = 'mimetype' in file ? file.mimetype : file?.type; + + return acceptedFileTypes.includes(mimetype as string); + } + + return false; + }, + `Only ${acceptedFileTypes.map((fileType) => `.${fileType.split('/')[1]}`).join(', ')} file formats are allowed.`, + ); diff --git a/template/packages/schemas/src/user.schema.ts b/template/packages/schemas/src/user.schema.ts index 0589da3b..01556c5f 100644 --- a/template/packages/schemas/src/user.schema.ts +++ b/template/packages/schemas/src/user.schema.ts @@ -1,8 +1,8 @@ import { z } from 'zod'; -import { EMAIL_REGEX } from 'app-constants'; +import { EMAIL_REGEX, USER_AVATAR } from 'app-constants'; -import { emailSchema, passwordSchema } from './common.schema'; +import { emailSchema, fileSchema, passwordSchema } from './common.schema'; import dbSchema from './db.schema'; const oauthSchema = z.object({ @@ -58,6 +58,13 @@ export const resetPasswordSchema = z.object({ export const updateUserSchema = userSchema .pick({ firstName: true, lastName: true }) .extend({ - password: passwordSchema, + password: z.union([ + passwordSchema, + z.literal(''), // Allow empty string when password is unchanged on the front-end + ]), + avatar: z.union([ + fileSchema(USER_AVATAR.MAX_FILE_SIZE, USER_AVATAR.ACCEPTED_FILE_TYPES).nullable(), + z.literal(''), // Allow empty string to indicate removal + ]), }) .partial(); diff --git a/template/pnpm-lock.yaml b/template/pnpm-lock.yaml index b5225910..63ae83cc 100644 --- a/template/pnpm-lock.yaml +++ b/template/pnpm-lock.yaml @@ -48,9 +48,6 @@ importers: '@koa/cors': specifier: 5.0.0 version: 5.0.0 - '@koa/multer': - specifier: 3.0.2 - version: 3.0.2(multer@1.4.5-lts.1) '@koa/router': specifier: 13.0.0 version: 13.0.0 @@ -90,6 +87,9 @@ importers: koa: specifier: 2.14.1 version: 2.14.1 + koa-body: + specifier: 6.0.1 + version: 6.0.1 koa-bodyparser: specifier: 4.3.0 version: 4.3.0 @@ -184,9 +184,6 @@ importers: '@types/koa__cors': specifier: 3.3.1 version: 3.3.1 - '@types/koa__multer': - specifier: 2.0.4 - version: 2.0.4 '@types/koa__router': specifier: 12.0.0 version: 12.0.0 @@ -228,7 +225,7 @@ importers: version: link:../../packages/prettier-config-custom ts-jest: specifier: 29.1.2 - version: 29.1.2(@babel/core@7.21.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.21.0))(jest@29.7.0(@types/node@20.11.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.101(@swc/helpers@0.5.5))(@types/node@20.11.1)(typescript@5.2.2)))(typescript@5.2.2) + version: 29.1.2(@babel/core@7.23.7)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.7))(jest@29.7.0(@types/node@20.11.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.101(@swc/helpers@0.5.5))(@types/node@20.11.1)(typescript@5.2.2)))(typescript@5.2.2) ts-node: specifier: 10.9.1 version: 10.9.1(@swc/core@1.3.101(@swc/helpers@0.5.5))(@types/node@20.11.1)(typescript@5.2.2) @@ -248,26 +245,26 @@ importers: specifier: 3.3.4 version: 3.3.4(react-hook-form@7.52.1(react@18.3.1)) '@mantine/core': - specifier: 7.13.3 - version: 7.13.3(@mantine/hooks@7.13.3(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 7.13.4 + version: 7.13.4(@mantine/hooks@7.13.4(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mantine/dates': - specifier: 7.13.3 - version: 7.13.3(@mantine/core@7.13.3(@mantine/hooks@7.13.3(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.13.3(react@18.3.1))(dayjs@1.11.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 7.13.4 + version: 7.13.4(@mantine/core@7.13.4(@mantine/hooks@7.13.4(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.13.4(react@18.3.1))(dayjs@1.11.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mantine/dropzone': - specifier: 7.13.3 - version: 7.13.3(@mantine/core@7.13.3(@mantine/hooks@7.13.3(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.13.3(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 7.13.4 + version: 7.13.4(@mantine/core@7.13.4(@mantine/hooks@7.13.4(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.13.4(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mantine/hooks': - specifier: 7.13.3 - version: 7.13.3(react@18.3.1) + specifier: 7.13.4 + version: 7.13.4(react@18.3.1) '@mantine/modals': - specifier: 7.13.3 - version: 7.13.3(@mantine/core@7.13.3(@mantine/hooks@7.13.3(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.13.3(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 7.13.4 + version: 7.13.4(@mantine/core@7.13.4(@mantine/hooks@7.13.4(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.13.4(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mantine/next': specifier: 6.0.22 - version: 6.0.22(@emotion/react@11.10.6(@types/react@18.3.3)(react@18.3.1))(@emotion/server@11.10.0)(next@14.2.5(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 6.0.22(@emotion/react@11.10.6(@types/react@18.3.3)(react@18.3.1))(@emotion/server@11.10.0)(next@14.2.10(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mantine/notifications': - specifier: 7.13.3 - version: 7.13.3(@mantine/core@7.13.3(@mantine/hooks@7.13.3(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.13.3(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 7.13.4 + version: 7.13.4(@mantine/core@7.13.4(@mantine/hooks@7.13.4(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.13.4(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@svgr/webpack': specifier: 8.1.0 version: 8.1.0(typescript@5.2.2) @@ -305,8 +302,11 @@ importers: specifier: 2.53.0 version: 2.53.0 next: - specifier: 14.2.5 - version: 14.2.5(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 14.2.10 + version: 14.2.10(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + object-to-formdata: + specifier: 4.5.1 + version: 4.5.1 react: specifier: 18.3.1 version: 18.3.1 @@ -334,7 +334,7 @@ importers: version: 1.0.0(storybook@8.2.0(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(webpack@5.75.0(esbuild@0.19.11)) '@storybook/nextjs': specifier: 8.2.0 - version: 8.2.0(@jest/globals@29.7.0)(@types/jest@29.5.12)(@types/webpack@5.28.5(esbuild@0.19.11))(babel-plugin-macros@3.1.0)(esbuild@0.19.11)(jest@29.7.0(@types/node@20.11.1)(babel-plugin-macros@3.1.0))(next@14.2.5(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.2.0(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(type-fest@4.21.0)(typescript@5.2.2)(webpack-hot-middleware@2.26.0)(webpack@5.75.0(esbuild@0.19.11)) + version: 8.2.0(@jest/globals@29.7.0)(@types/jest@29.5.12)(@types/webpack@5.28.5(esbuild@0.19.11))(babel-plugin-macros@3.1.0)(esbuild@0.19.11)(jest@29.7.0(@types/node@20.11.1)(babel-plugin-macros@3.1.0))(next@14.2.10(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.2.0(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(type-fest@4.21.0)(typescript@5.2.2)(webpack-hot-middleware@2.26.0)(webpack@5.75.0(esbuild@0.19.11)) '@storybook/preview-api': specifier: 8.2.0 version: 8.2.0(storybook@8.2.0(@babel/preset-env@7.24.7(@babel/core@7.24.7))) @@ -441,6 +441,9 @@ importers: specifier: '*' version: 3.21.4 devDependencies: + '@types/formidable': + specifier: 2.0.5 + version: 2.0.5 '@types/node': specifier: '*' version: 20.11.1 @@ -586,6 +589,9 @@ importers: specifier: '*' version: 3.21.4 devDependencies: + '@types/formidable': + specifier: '*' + version: 3.4.5 '@types/node': specifier: '*' version: 20.11.1 @@ -1043,10 +1049,6 @@ packages: resolution: {integrity: sha512-VXAq/Jz8KIrU84+HqsOJhIKZqG0PNTdi6n6PFQ4xJf44ZQHD/5C7ouH4qCFX5XgZXcgbRIcMVVYGC6Jye0dRng==} engines: {node: '>=14.0.0'} - '@babel/code-frame@7.18.6': - resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} - engines: {node: '>=6.9.0'} - '@babel/code-frame@7.23.5': resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} engines: {node: '>=6.9.0'} @@ -1055,10 +1057,6 @@ packages: resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.21.0': - resolution: {integrity: sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==} - engines: {node: '>=6.9.0'} - '@babel/compat-data@7.23.5': resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} engines: {node: '>=6.9.0'} @@ -1067,10 +1065,6 @@ packages: resolution: {integrity: sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==} engines: {node: '>=6.9.0'} - '@babel/core@7.21.0': - resolution: {integrity: sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==} - engines: {node: '>=6.9.0'} - '@babel/core@7.23.7': resolution: {integrity: sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==} engines: {node: '>=6.9.0'} @@ -1083,10 +1077,6 @@ packages: resolution: {integrity: sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==} engines: {node: '>=6.9.0'} - '@babel/generator@7.21.1': - resolution: {integrity: sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==} - engines: {node: '>=6.9.0'} - '@babel/generator@7.23.6': resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} engines: {node: '>=6.9.0'} @@ -1115,12 +1105,6 @@ packages: resolution: {integrity: sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.20.7': - resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-compilation-targets@7.23.6': resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} engines: {node: '>=6.9.0'} @@ -1168,10 +1152,6 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - '@babel/helper-environment-visitor@7.18.9': - resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} - engines: {node: '>=6.9.0'} - '@babel/helper-environment-visitor@7.22.20': resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} engines: {node: '>=6.9.0'} @@ -1180,10 +1160,6 @@ packages: resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} engines: {node: '>=6.9.0'} - '@babel/helper-function-name@7.21.0': - resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==} - engines: {node: '>=6.9.0'} - '@babel/helper-function-name@7.23.0': resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} engines: {node: '>=6.9.0'} @@ -1192,10 +1168,6 @@ packages: resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==} engines: {node: '>=6.9.0'} - '@babel/helper-hoist-variables@7.18.6': - resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} - engines: {node: '>=6.9.0'} - '@babel/helper-hoist-variables@7.22.5': resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} @@ -1212,10 +1184,6 @@ packages: resolution: {integrity: sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.18.6': - resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} - engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.22.15': resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} @@ -1224,10 +1192,6 @@ packages: resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.21.0': - resolution: {integrity: sha512-eD/JQ21IG2i1FraJnTMbUarAUkA7G988ofehG5MDCRXaUU91rEBJuCeSoou2Sk1y4RbLYXzqEg1QLwEmRU4qcQ==} - engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.23.3': resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} @@ -1284,10 +1248,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-simple-access@7.20.2': - resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} - engines: {node: '>=6.9.0'} - '@babel/helper-simple-access@7.22.5': resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} @@ -1304,10 +1264,6 @@ packages: resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} engines: {node: '>=6.9.0'} - '@babel/helper-split-export-declaration@7.18.6': - resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} - engines: {node: '>=6.9.0'} - '@babel/helper-split-export-declaration@7.22.6': resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} @@ -1316,10 +1272,6 @@ packages: resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.19.4': - resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} - engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.23.4': resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} engines: {node: '>=6.9.0'} @@ -1328,10 +1280,6 @@ packages: resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.19.1': - resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.22.20': resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} @@ -1340,10 +1288,6 @@ packages: resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.21.0': - resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.23.5': resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} engines: {node: '>=6.9.0'} @@ -1360,10 +1304,6 @@ packages: resolution: {integrity: sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.21.0': - resolution: {integrity: sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==} - engines: {node: '>=6.9.0'} - '@babel/helpers@7.23.8': resolution: {integrity: sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==} engines: {node: '>=6.9.0'} @@ -1376,10 +1316,6 @@ packages: resolution: {integrity: sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==} engines: {node: '>=6.9.0'} - '@babel/highlight@7.18.6': - resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} - engines: {node: '>=6.9.0'} - '@babel/highlight@7.23.4': resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} engines: {node: '>=6.9.0'} @@ -1388,11 +1324,6 @@ packages: resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.21.1': - resolution: {integrity: sha512-JzhBFpkuhBNYUY7qs+wTzNmyCWUHEaAFpQQD2YfU1rPL38/L43Wvid0fFkiOCnHvsGncRZgEPyGnltABLcVDTg==} - engines: {node: '>=6.0.0'} - hasBin: true - '@babel/parser@7.23.6': resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} engines: {node: '>=6.0.0'} @@ -1450,13 +1381,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-proposal-export-namespace-from@7.18.9': - resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==} - engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead. - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} engines: {node: '>=6.9.0'} @@ -1876,12 +1800,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.20.11': - resolution: {integrity: sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.23.3': resolution: {integrity: sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==} engines: {node: '>=6.9.0'} @@ -2330,10 +2248,6 @@ packages: resolution: {integrity: sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==} engines: {node: '>=6.9.0'} - '@babel/template@7.20.7': - resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} - engines: {node: '>=6.9.0'} - '@babel/template@7.22.15': resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} engines: {node: '>=6.9.0'} @@ -2346,10 +2260,6 @@ packages: resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.21.0': - resolution: {integrity: sha512-Xdt2P1H4LKTO8ApPfnO1KmzYMFpp7D/EinoXzLYN/cHcBNrVCAkAtGUcXnHXrl/VGktureU6fkQrHSBE2URfoA==} - engines: {node: '>=6.9.0'} - '@babel/traverse@7.23.7': resolution: {integrity: sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==} engines: {node: '>=6.9.0'} @@ -2362,10 +2272,6 @@ packages: resolution: {integrity: sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==} engines: {node: '>=6.9.0'} - '@babel/types@7.21.0': - resolution: {integrity: sha512-uR7NWq2VNFnDi7EYqiRz2Jv/VQIu38tu64Zy8TX2nQFQ6etJ9V/Rr2msW8BS132mum2rL645qpDrLtAJtVpuow==} - engines: {node: '>=6.9.0'} - '@babel/types@7.23.6': resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} engines: {node: '>=6.9.0'} @@ -2929,50 +2835,44 @@ packages: resolution: {integrity: sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw==} engines: {node: '>= 14.0.0'} - '@koa/multer@3.0.2': - resolution: {integrity: sha512-Q6WfPpE06mJWyZD1fzxM6zWywaoo+zocAn2YA9QYz4RsecoASr1h/kSzG0c5seDpFVKCMZM9raEfuM7XfqbRLw==} - engines: {node: '>= 8'} - peerDependencies: - multer: '*' - '@koa/router@13.0.0': resolution: {integrity: sha512-P278xb5IoLtDn2inRsCzJVKGxt5RkjOivwxGbniMO1sI8bft1/Dr93UsRP5aByT8C74x8zqxDYyPXrQwRKIhjg==} engines: {node: '>= 18'} - '@mantine/core@7.13.3': - resolution: {integrity: sha512-IV8xSr6rFQefKr2iOEhYYkJ6rZTDEp71qNkAfn90toSNjgT/2bgnqOxXwxqZ3bwo9DyNOAbEDzs1EfdIzln5aA==} + '@mantine/core@7.13.4': + resolution: {integrity: sha512-9I6+SqTq90pnI3WPmOQzQ1PL7IkhQg/5ft8Awhgut8tvk1VaKruDm/K5ysUG3ncHrP+QTI2UHYjNlUrux6HKlw==} peerDependencies: - '@mantine/hooks': 7.13.3 + '@mantine/hooks': 7.13.4 react: ^18.2.0 react-dom: ^18.2.0 - '@mantine/dates@7.13.3': - resolution: {integrity: sha512-IjClxPcenDq2/iAxhaZyjrCpMhc9ybLfvh4YwEmjWg+pSfdIDtc9VkMSnXv2aYChLybUjNQmIcPibU7Vdu4Z8w==} + '@mantine/dates@7.13.4': + resolution: {integrity: sha512-1wmFmng8QBNU3JUoxCva357CD4kX/y9wTQoxfv8giYMzC6bNY3tYWW0CYLtSr80ZroMyZOdyXCBIlYYVil8BUQ==} peerDependencies: - '@mantine/core': 7.13.3 - '@mantine/hooks': 7.13.3 + '@mantine/core': 7.13.4 + '@mantine/hooks': 7.13.4 dayjs: '>=1.0.0' react: ^18.2.0 react-dom: ^18.2.0 - '@mantine/dropzone@7.13.3': - resolution: {integrity: sha512-N3MxrDiMlshqbVQjA52QZqPYhWFs8HPnB48zfHF9Vo+PEPeKT+Kf2q4SR/PSIubFKOyzJkW78kKzAjXmBdqmCw==} + '@mantine/dropzone@7.13.4': + resolution: {integrity: sha512-RmiBfi+u16vh0ZUjJvn8cUfsgScN0o/F/P4mZUFm7AE4ap7jUdIyBWr4aBiHu0v5DXKywNO6ZrsSaoZnpbiUgQ==} peerDependencies: - '@mantine/core': 7.13.3 - '@mantine/hooks': 7.13.3 + '@mantine/core': 7.13.4 + '@mantine/hooks': 7.13.4 react: ^18.2.0 react-dom: ^18.2.0 - '@mantine/hooks@7.13.3': - resolution: {integrity: sha512-r2c+Z8CdvPKFeOwg6mSJmxOp9K/ave5ZFR7eJbgv4wQU8K1CAS5f5ven9K5uUX8Vf9B5dFnSaSgYp9UY3vOWTw==} + '@mantine/hooks@7.13.4': + resolution: {integrity: sha512-B2QCegQyWlLdenVNaLNK8H9cTAjLW9JKJ3xWg+ShhpjZDHT2hjZz4L0Nt071Z7mPvyAaOwKGM0FyqTcTjdECfg==} peerDependencies: react: ^18.2.0 - '@mantine/modals@7.13.3': - resolution: {integrity: sha512-XAx724ZLqQVnsaH72sCoZD7NKcx2haUgAv0G52hq0MbVWWig2rbzN5YBvqGw+kuKgwp20VH+6oLSVvvB+4SMzQ==} + '@mantine/modals@7.13.4': + resolution: {integrity: sha512-CYJVRelRRAZQccdJUsRQONMWdHpV+m1KhgXX7pVcn6nPwKSBxiBVrkoFnXpKMfVMHQR1gvZ4B+hg7y3bmr6QXQ==} peerDependencies: - '@mantine/core': 7.13.3 - '@mantine/hooks': 7.13.3 + '@mantine/core': 7.13.4 + '@mantine/hooks': 7.13.4 react: ^18.2.0 react-dom: ^18.2.0 @@ -2983,11 +2883,11 @@ packages: react: '>=16.8.0' react-dom: '>=16.8.0' - '@mantine/notifications@7.13.3': - resolution: {integrity: sha512-G01Bf0g6zA+K6ZdBOIxhGIlpi3qITs6W5Z0fYTSQkzLcJSfECdR5KgRvNpzcx2ESTT8BfJJMsLySwh+WTzcoxw==} + '@mantine/notifications@7.13.4': + resolution: {integrity: sha512-CKd3tDGDAegkJYJIMHtF0St4hBpBVAujdmtsEin7UYeVq5N0YYe7j2T1Xu7Ry6dfObkuxeig6csxiJyBrZ2bew==} peerDependencies: - '@mantine/core': 7.13.3 - '@mantine/hooks': 7.13.3 + '@mantine/core': 7.13.4 + '@mantine/hooks': 7.13.4 react: ^18.2.0 react-dom: ^18.2.0 @@ -2999,8 +2899,8 @@ packages: react: '>=16.8.0' react-dom: '>=16.8.0' - '@mantine/store@7.13.3': - resolution: {integrity: sha512-95nAgH6APhak1OwP2W3ogdWBiWkIDhDSbQEm2G9LTJLIJxzWSm1mLe5uDWluVEPZW2XFx137McuJb58i1A+QhQ==} + '@mantine/store@7.13.4': + resolution: {integrity: sha512-DUlnXizE7aCjbVg2J3XLLKsOzt2c2qfQl2Xmx9l/BPE4FFZZKUqGDkYaTDbTAmnN3FVZ9xXycL7bAlq9udO8mA==} peerDependencies: react: ^18.2.0 @@ -3017,8 +2917,8 @@ packages: '@next/env@14.0.5-canary.46': resolution: {integrity: sha512-dvNzrArTfe3VY1VIscpb3E2e7SZ1qwFe82WGzpOVbxilT3JcsnVGYF/uq8Jj1qKWPI5C/aePNXwA97JRNAXpRQ==} - '@next/env@14.2.5': - resolution: {integrity: sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA==} + '@next/env@14.2.10': + resolution: {integrity: sha512-dZIu93Bf5LUtluBXIv4woQw2cZVZ2DJTjax5/5DOs3lzEOeKLy7GxRSr4caK9/SCPdaW6bCgpye6+n4Dh9oJPw==} '@next/eslint-plugin-next@14.1.0': resolution: {integrity: sha512-x4FavbNEeXx/baD/zC/SdrvkjSby8nBn8KcCREqk6UuwvwoAPZmaV8TFCAuo/cpovBRTIY67mHhe86MQQm/68Q==} @@ -3029,8 +2929,8 @@ packages: cpu: [arm64] os: [darwin] - '@next/swc-darwin-arm64@14.2.5': - resolution: {integrity: sha512-/9zVxJ+K9lrzSGli1///ujyRfon/ZneeZ+v4ptpiPoOU+GKZnm8Wj8ELWU1Pm7GHltYRBklmXMTUqM/DqQ99FQ==} + '@next/swc-darwin-arm64@14.2.10': + resolution: {integrity: sha512-V3z10NV+cvMAfxQUMhKgfQnPbjw+Ew3cnr64b0lr8MDiBJs3eLnM6RpGC46nhfMZsiXgQngCJKWGTC/yDcgrDQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -3041,8 +2941,8 @@ packages: cpu: [x64] os: [darwin] - '@next/swc-darwin-x64@14.2.5': - resolution: {integrity: sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA==} + '@next/swc-darwin-x64@14.2.10': + resolution: {integrity: sha512-Y0TC+FXbFUQ2MQgimJ/7Ina2mXIKhE7F+GUe1SgnzRmwFY3hX2z8nyVCxE82I2RicspdkZnSWMn4oTjIKz4uzA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -3053,8 +2953,8 @@ packages: cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-gnu@14.2.5': - resolution: {integrity: sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA==} + '@next/swc-linux-arm64-gnu@14.2.10': + resolution: {integrity: sha512-ZfQ7yOy5zyskSj9rFpa0Yd7gkrBnJTkYVSya95hX3zeBG9E55Z6OTNPn1j2BTFWvOVVj65C3T+qsjOyVI9DQpA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -3065,8 +2965,8 @@ packages: cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@14.2.5': - resolution: {integrity: sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==} + '@next/swc-linux-arm64-musl@14.2.10': + resolution: {integrity: sha512-n2i5o3y2jpBfXFRxDREr342BGIQCJbdAUi/K4q6Env3aSx8erM9VuKXHw5KNROK9ejFSPf0LhoSkU/ZiNdacpQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -3077,8 +2977,8 @@ packages: cpu: [x64] os: [linux] - '@next/swc-linux-x64-gnu@14.2.5': - resolution: {integrity: sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==} + '@next/swc-linux-x64-gnu@14.2.10': + resolution: {integrity: sha512-GXvajAWh2woTT0GKEDlkVhFNxhJS/XdDmrVHrPOA83pLzlGPQnixqxD8u3bBB9oATBKB//5e4vpACnx5Vaxdqg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -3089,8 +2989,8 @@ packages: cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@14.2.5': - resolution: {integrity: sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==} + '@next/swc-linux-x64-musl@14.2.10': + resolution: {integrity: sha512-opFFN5B0SnO+HTz4Wq4HaylXGFV+iHrVxd3YvREUX9K+xfc4ePbRrxqOuPOFjtSuiVouwe6uLeDtabjEIbkmDA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -3101,8 +3001,8 @@ packages: cpu: [arm64] os: [win32] - '@next/swc-win32-arm64-msvc@14.2.5': - resolution: {integrity: sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==} + '@next/swc-win32-arm64-msvc@14.2.10': + resolution: {integrity: sha512-9NUzZuR8WiXTvv+EiU/MXdcQ1XUvFixbLIMNQiVHuzs7ZIFrJDLJDaOF1KaqttoTujpcxljM/RNAOmw1GhPPQQ==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] @@ -3113,8 +3013,8 @@ packages: cpu: [ia32] os: [win32] - '@next/swc-win32-ia32-msvc@14.2.5': - resolution: {integrity: sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg==} + '@next/swc-win32-ia32-msvc@14.2.10': + resolution: {integrity: sha512-fr3aEbSd1GeW3YUMBkWAu4hcdjZ6g4NBl1uku4gAn661tcxd1bHs1THWYzdsbTRLcCKLjrDZlNp6j2HTfrw+Bg==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] @@ -3125,8 +3025,8 @@ packages: cpu: [x64] os: [win32] - '@next/swc-win32-x64-msvc@14.2.5': - resolution: {integrity: sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g==} + '@next/swc-win32-x64-msvc@14.2.10': + resolution: {integrity: sha512-UjeVoRGKNL2zfbcQ6fscmgjBAS/inHBh63mjIlfPg/NG8Yn2ztqylXt5qilYb6hoHIwaU2ogHknHWWmahJjgZQ==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -4252,6 +4152,9 @@ packages: '@types/body-parser@1.19.2': resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} + '@types/co-body@6.1.3': + resolution: {integrity: sha512-UhuhrQ5hclX6UJctv5m4Rfp52AfG9o9+d9/HwjxhVB5NjXxr5t9oKgJxN8xRHgr35oo8meUEHUPFWiKg6y71aA==} + '@types/connect@3.4.35': resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} @@ -4303,6 +4206,12 @@ packages: '@types/express@4.17.21': resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + '@types/formidable@2.0.5': + resolution: {integrity: sha512-uvMcdn/KK3maPOaVUAc3HEYbCEhjaGFwww4EsX6IJfWIJ1tzHtDHczuImH3GKdusPnAAmzB07St90uabZeCKPA==} + + '@types/formidable@3.4.5': + resolution: {integrity: sha512-s7YPsNVfnsng5L8sKnG/Gbb2tiwwJTY1conOkJzTMRvJAlLFW1nEua+ADsJQu8N1c0oTHx9+d5nqg10WuT9gHQ==} + '@types/graceful-fs@4.1.6': resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} @@ -4363,9 +4272,6 @@ packages: '@types/koa__cors@3.3.1': resolution: {integrity: sha512-aFGYhTFW7651KhmZZ05VG0QZJre7QxBxDj2LF1lf6GA/wSXEfKVAJxiQQWzRV4ZoMzQIO8vJBXKsUcRuvYK9qw==} - '@types/koa__multer@2.0.4': - resolution: {integrity: sha512-WRkshXhE5rpYFUbbtAjyMhdOOSdbu1XX+2AQlRNM6AZtgxd0/WXMU4lrP7e9tk5HWVTWbx8DOOsVBmfHjSGJ4w==} - '@types/koa__router@12.0.0': resolution: {integrity: sha512-S6eHyZyoWCZLNHyy8j0sMW85cPrpByCbGGU2/BO4IzGiI87aHJ92lZh4E9xfsM9DcbCT469/OIqyC0sSJXSIBQ==} @@ -4742,9 +4648,6 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} - append-field@1.0.0: - resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==} - arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} @@ -4832,6 +4735,9 @@ packages: resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} engines: {node: '>=8'} + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + asn1.js@5.4.1: resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==} @@ -5058,11 +4964,6 @@ packages: browserify-zlib@0.2.0: resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} - browserslist@4.21.5: - resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - browserslist@4.22.2: resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -5391,10 +5292,6 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - concat-stream@1.6.2: - resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} - engines: {'0': node >= 0.8} - config-chain@1.1.13: resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} @@ -5733,6 +5630,9 @@ packages: detect-node-es@1.1.0: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + dezalgo@1.0.4: + resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} + didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} @@ -5836,9 +5736,6 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.4.304: - resolution: {integrity: sha512-6c8M+ojPgDIXN2NyfGn8oHASXYnayj+gSEnGeLMKb9zjsySeVB/j7KkNAAG9yDcv8gNlhvFg5REa1N/kQU6pgA==} - electron-to-chromium@1.4.637: resolution: {integrity: sha512-G7j3UCOukFtxVO1vWrPQUoDk3kL70mtvjc/DC/k2o7lE0wAdq+Vwp1ipagOow+BH0uVztFysLWbkM/RTIrbK3w==} @@ -6360,9 +6257,6 @@ packages: resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - fix-esm@1.0.1: - resolution: {integrity: sha512-EZtb7wPXZS54GaGxaWxMlhd1DUDCnAg5srlYdu/1ZVeW+7wwR3Tp59nu52dXByFs3MBRq+SByx1wDOJpRvLEXw==} - flat-cache@3.0.4: resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -6411,6 +6305,9 @@ packages: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} + formidable@2.1.2: + resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==} + forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -6611,6 +6508,7 @@ packages: google-p12-pem@4.0.1: resolution: {integrity: sha512-WPkN4yGtz05WZ5EhtlxNDWPhC4JIic6G8ePitwUWy4l+XPVYec+a0j0Ts47PDtW59y3RwAhUd9/h9ZZ63px6RQ==} engines: {node: '>=12.0.0'} + deprecated: Package is no longer maintained hasBin: true gopd@1.0.1: @@ -6695,6 +6593,10 @@ packages: resolution: {integrity: sha512-HVqALKZlR95ROkrnesdhbbZJFi/rIVSoNq6f3jA/9u6MIbTsPh3xZwihjeI5+DO/2sOV6HMHooXcEOuwskHpTg==} engines: {node: '>=10.0.0'} + hexoid@1.0.0: + resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} + engines: {node: '>=8'} + hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} @@ -7387,6 +7289,9 @@ packages: known-css-properties@0.34.0: resolution: {integrity: sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==} + koa-body@6.0.1: + resolution: {integrity: sha512-M8ZvMD8r+kPHy28aWP9VxL7kY8oPWA+C7ZgCljrCMeaU7uX6wsIQgDHskyrAr9sw+jqnIXyv4Mlxri5R4InIJg==} + koa-bodyparser@4.3.0: resolution: {integrity: sha512-uyV8G29KAGwZc4q/0WUAjH+Tsmuv9ImfBUF2oZVyZtaeo0husInagyn/JH85xMSxM0hEk/mbCII5ubLDuqW/Rw==} engines: {node: '>=8.0.0'} @@ -7751,10 +7656,6 @@ packages: resolution: {integrity: sha512-DY5WeOy/hmkPrNiiZugJpWR0iMuOwuj1a3u0bgwB2eUFRV6oIew/pIahhpawdbNjb+Bye4a8ID3gefeNPvL81g==} engines: {node: '>=10.0'} - mkdirp@0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} - hasBin: true - mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} @@ -7843,10 +7744,6 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - multer@1.4.5-lts.1: - resolution: {integrity: sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==} - engines: {node: '>= 6.0.0'} - multipipe@1.0.2: resolution: {integrity: sha512-6uiC9OvY71vzSGX8lZvSqscE7ft9nPupJ8fMjrCNRAUy2LREUW42UL+V/NTrogr6rFgRydUrCX4ZitfpSNkSCQ==} @@ -7887,8 +7784,8 @@ packages: sass: optional: true - next@14.2.5: - resolution: {integrity: sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA==} + next@14.2.10: + resolution: {integrity: sha512-sDDExXnh33cY3RkS9JuFEKaS4HmlWmDKP1VJioucCG6z5KuA008DPsDZOzi8UfqEk3Ii+2NCQSJrfbEWtZZfww==} engines: {node: '>=18.17.0'} hasBin: true peerDependencies: @@ -7940,9 +7837,6 @@ packages: peerDependencies: webpack: '>=5' - node-releases@2.0.10: - resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==} - node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} @@ -8082,6 +7976,9 @@ packages: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} + object-to-formdata@4.5.1: + resolution: {integrity: sha512-QiM9D0NiU5jV6J6tjE1g7b4Z2tcUnKs1OPUi4iMb2zH+7jwlcUrASghgkFk9GtzqNNq8rTQJtT8AzjBAvLoNMw==} + object.assign@4.1.4: resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} engines: {node: '>= 0.4'} @@ -8581,10 +8478,6 @@ packages: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} - raw-body@2.5.1: - resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} - engines: {node: '>= 0.8'} - raw-body@2.5.2: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} @@ -9818,9 +9711,6 @@ packages: resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} engines: {node: '>= 0.4'} - typedarray@0.0.6: - resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typescript@5.1.6: resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} engines: {node: '>=14.17'} @@ -9876,12 +9766,6 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - update-browserslist-db@1.0.10: - resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - update-browserslist-db@1.0.13: resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true @@ -11313,10 +11197,6 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.6.2 - '@babel/code-frame@7.18.6': - dependencies: - '@babel/highlight': 7.18.6 - '@babel/code-frame@7.23.5': dependencies: '@babel/highlight': 7.23.4 @@ -11327,32 +11207,10 @@ snapshots: '@babel/highlight': 7.24.7 picocolors: 1.0.1 - '@babel/compat-data@7.21.0': {} - '@babel/compat-data@7.23.5': {} '@babel/compat-data@7.24.7': {} - '@babel/core@7.21.0': - dependencies: - '@ampproject/remapping': 2.2.0 - '@babel/code-frame': 7.18.6 - '@babel/generator': 7.21.1 - '@babel/helper-compilation-targets': 7.20.7(@babel/core@7.21.0) - '@babel/helper-module-transforms': 7.21.0 - '@babel/helpers': 7.21.0 - '@babel/parser': 7.21.1 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.0 - '@babel/types': 7.21.0 - convert-source-map: 1.9.0 - debug: 4.3.5 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/core@7.23.7': dependencies: '@ampproject/remapping': 2.2.0 @@ -11413,13 +11271,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.21.1': - dependencies: - '@babel/types': 7.21.0 - '@jridgewell/gen-mapping': 0.3.2 - '@jridgewell/trace-mapping': 0.3.17 - jsesc: 2.5.2 - '@babel/generator@7.23.6': dependencies: '@babel/types': 7.23.6 @@ -11460,15 +11311,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-compilation-targets@7.20.7(@babel/core@7.21.0)': - dependencies: - '@babel/compat-data': 7.21.0 - '@babel/core': 7.21.0 - '@babel/helper-validator-option': 7.21.0 - browserslist: 4.21.5 - lru-cache: 5.1.1 - semver: 6.3.1 - '@babel/helper-compilation-targets@7.23.6': dependencies: '@babel/compat-data': 7.23.5 @@ -11600,19 +11442,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-environment-visitor@7.18.9': {} - '@babel/helper-environment-visitor@7.22.20': {} '@babel/helper-environment-visitor@7.24.7': dependencies: '@babel/types': 7.24.7 - '@babel/helper-function-name@7.21.0': - dependencies: - '@babel/template': 7.20.7 - '@babel/types': 7.24.7 - '@babel/helper-function-name@7.23.0': dependencies: '@babel/template': 7.22.15 @@ -11623,10 +11458,6 @@ snapshots: '@babel/template': 7.24.7 '@babel/types': 7.24.7 - '@babel/helper-hoist-variables@7.18.6': - dependencies: - '@babel/types': 7.24.7 - '@babel/helper-hoist-variables@7.22.5': dependencies: '@babel/types': 7.23.6 @@ -11646,10 +11477,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-imports@7.18.6': - dependencies: - '@babel/types': 7.24.7 - '@babel/helper-module-imports@7.22.15': dependencies: '@babel/types': 7.23.6 @@ -11661,19 +11488,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.21.0': - dependencies: - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-module-imports': 7.18.6 - '@babel/helper-simple-access': 7.20.2 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/helper-validator-identifier': 7.19.1 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.0 - '@babel/types': 7.21.0 - transitivePeerDependencies: - - supports-color - '@babel/helper-module-transforms@7.23.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -11778,10 +11592,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-simple-access@7.20.2': - dependencies: - '@babel/types': 7.21.0 - '@babel/helper-simple-access@7.22.5': dependencies: '@babel/types': 7.23.6 @@ -11804,10 +11614,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-split-export-declaration@7.18.6': - dependencies: - '@babel/types': 7.24.7 - '@babel/helper-split-export-declaration@7.22.6': dependencies: '@babel/types': 7.23.6 @@ -11816,20 +11622,14 @@ snapshots: dependencies: '@babel/types': 7.24.7 - '@babel/helper-string-parser@7.19.4': {} - '@babel/helper-string-parser@7.23.4': {} '@babel/helper-string-parser@7.24.7': {} - '@babel/helper-validator-identifier@7.19.1': {} - '@babel/helper-validator-identifier@7.22.20': {} '@babel/helper-validator-identifier@7.24.7': {} - '@babel/helper-validator-option@7.21.0': {} - '@babel/helper-validator-option@7.23.5': {} '@babel/helper-validator-option@7.24.7': {} @@ -11849,14 +11649,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helpers@7.21.0': - dependencies: - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.0 - '@babel/types': 7.21.0 - transitivePeerDependencies: - - supports-color - '@babel/helpers@7.23.8': dependencies: '@babel/template': 7.22.15 @@ -11878,12 +11670,6 @@ snapshots: '@babel/template': 7.24.7 '@babel/types': 7.24.7 - '@babel/highlight@7.18.6': - dependencies: - '@babel/helper-validator-identifier': 7.19.1 - chalk: 2.4.2 - js-tokens: 4.0.0 - '@babel/highlight@7.23.4': dependencies: '@babel/helper-validator-identifier': 7.22.20 @@ -11897,10 +11683,6 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/parser@7.21.1': - dependencies: - '@babel/types': 7.21.0 - '@babel/parser@7.23.6': dependencies: '@babel/types': 7.23.6 @@ -11983,12 +11765,6 @@ snapshots: '@babel/helper-environment-visitor': 7.24.7 '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-proposal-export-namespace-from@7.18.9(@babel/core@7.21.0)': - dependencies: - '@babel/core': 7.21.0 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.21.0) - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -11997,12 +11773,6 @@ snapshots: dependencies: '@babel/core': 7.24.7 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.21.0)': - dependencies: - '@babel/core': 7.21.0 - '@babel/helper-plugin-utils': 7.22.5 - optional: true - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -12013,12 +11783,6 @@ snapshots: '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.21.0)': - dependencies: - '@babel/core': 7.21.0 - '@babel/helper-plugin-utils': 7.24.7 - optional: true - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -12029,12 +11793,6 @@ snapshots: '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.21.0)': - dependencies: - '@babel/core': 7.21.0 - '@babel/helper-plugin-utils': 7.22.5 - optional: true - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -12065,11 +11823,6 @@ snapshots: '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.21.0)': - dependencies: - '@babel/core': 7.21.0 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -12115,12 +11868,6 @@ snapshots: '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.21.0)': - dependencies: - '@babel/core': 7.21.0 - '@babel/helper-plugin-utils': 7.22.5 - optional: true - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -12131,12 +11878,6 @@ snapshots: '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.21.0)': - dependencies: - '@babel/core': 7.21.0 - '@babel/helper-plugin-utils': 7.22.5 - optional: true - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -12157,12 +11898,6 @@ snapshots: '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.21.0)': - dependencies: - '@babel/core': 7.21.0 - '@babel/helper-plugin-utils': 7.22.5 - optional: true - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -12173,12 +11908,6 @@ snapshots: '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.21.0)': - dependencies: - '@babel/core': 7.21.0 - '@babel/helper-plugin-utils': 7.22.5 - optional: true - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -12189,12 +11918,6 @@ snapshots: '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.21.0)': - dependencies: - '@babel/core': 7.21.0 - '@babel/helper-plugin-utils': 7.22.5 - optional: true - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -12205,12 +11928,6 @@ snapshots: '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.21.0)': - dependencies: - '@babel/core': 7.21.0 - '@babel/helper-plugin-utils': 7.22.5 - optional: true - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -12221,12 +11938,6 @@ snapshots: '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.21.0)': - dependencies: - '@babel/core': 7.21.0 - '@babel/helper-plugin-utils': 7.22.5 - optional: true - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -12237,12 +11948,6 @@ snapshots: '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.21.0)': - dependencies: - '@babel/core': 7.21.0 - '@babel/helper-plugin-utils': 7.22.5 - optional: true - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -12263,12 +11968,6 @@ snapshots: '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.21.0)': - dependencies: - '@babel/core': 7.21.0 - '@babel/helper-plugin-utils': 7.22.5 - optional: true - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -12747,15 +12446,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.20.11(@babel/core@7.21.0)': - dependencies: - '@babel/core': 7.21.0 - '@babel/helper-module-transforms': 7.21.0 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-simple-access': 7.20.2 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -13685,12 +13375,6 @@ snapshots: dependencies: regenerator-runtime: 0.14.1 - '@babel/template@7.20.7': - dependencies: - '@babel/code-frame': 7.24.7 - '@babel/parser': 7.21.1 - '@babel/types': 7.21.0 - '@babel/template@7.22.15': dependencies: '@babel/code-frame': 7.23.5 @@ -13709,21 +13393,6 @@ snapshots: '@babel/parser': 7.24.7 '@babel/types': 7.24.7 - '@babel/traverse@7.21.0': - dependencies: - '@babel/code-frame': 7.24.7 - '@babel/generator': 7.21.1 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.21.0 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.21.1 - '@babel/types': 7.21.0 - debug: 4.3.5 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - '@babel/traverse@7.23.7': dependencies: '@babel/code-frame': 7.23.5 @@ -13769,12 +13438,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/types@7.21.0': - dependencies: - '@babel/helper-string-parser': 7.19.4 - '@babel/helper-validator-identifier': 7.19.1 - to-fast-properties: 2.0.0 - '@babel/types@7.23.6': dependencies: '@babel/helper-string-parser': 7.23.4 @@ -14377,23 +14040,16 @@ snapshots: dependencies: vary: 1.1.2 - '@koa/multer@3.0.2(multer@1.4.5-lts.1)': - dependencies: - fix-esm: 1.0.1 - multer: 1.4.5-lts.1 - transitivePeerDependencies: - - supports-color - '@koa/router@13.0.0': dependencies: http-errors: 2.0.0 koa-compose: 4.1.0 path-to-regexp: 6.2.2 - '@mantine/core@7.13.3(@mantine/hooks@7.13.3(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@mantine/core@7.13.4(@mantine/hooks@7.13.4(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@floating-ui/react': 0.26.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mantine/hooks': 7.13.3(react@18.3.1) + '@mantine/hooks': 7.13.4(react@18.3.1) clsx: 2.1.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -14404,50 +14060,50 @@ snapshots: transitivePeerDependencies: - '@types/react' - '@mantine/dates@7.13.3(@mantine/core@7.13.3(@mantine/hooks@7.13.3(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.13.3(react@18.3.1))(dayjs@1.11.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@mantine/dates@7.13.4(@mantine/core@7.13.4(@mantine/hooks@7.13.4(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.13.4(react@18.3.1))(dayjs@1.11.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@mantine/core': 7.13.3(@mantine/hooks@7.13.3(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mantine/hooks': 7.13.3(react@18.3.1) + '@mantine/core': 7.13.4(@mantine/hooks@7.13.4(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mantine/hooks': 7.13.4(react@18.3.1) clsx: 2.1.1 dayjs: 1.11.10 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@mantine/dropzone@7.13.3(@mantine/core@7.13.3(@mantine/hooks@7.13.3(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.13.3(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@mantine/dropzone@7.13.4(@mantine/core@7.13.4(@mantine/hooks@7.13.4(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.13.4(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@mantine/core': 7.13.3(@mantine/hooks@7.13.3(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mantine/hooks': 7.13.3(react@18.3.1) + '@mantine/core': 7.13.4(@mantine/hooks@7.13.4(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mantine/hooks': 7.13.4(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) react-dropzone-esm: 15.0.1(react@18.3.1) - '@mantine/hooks@7.13.3(react@18.3.1)': + '@mantine/hooks@7.13.4(react@18.3.1)': dependencies: react: 18.3.1 - '@mantine/modals@7.13.3(@mantine/core@7.13.3(@mantine/hooks@7.13.3(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.13.3(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@mantine/modals@7.13.4(@mantine/core@7.13.4(@mantine/hooks@7.13.4(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.13.4(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@mantine/core': 7.13.3(@mantine/hooks@7.13.3(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mantine/hooks': 7.13.3(react@18.3.1) + '@mantine/core': 7.13.4(@mantine/hooks@7.13.4(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mantine/hooks': 7.13.4(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@mantine/next@6.0.22(@emotion/react@11.10.6(@types/react@18.3.3)(react@18.3.1))(@emotion/server@11.10.0)(next@14.2.5(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@mantine/next@6.0.22(@emotion/react@11.10.6(@types/react@18.3.3)(react@18.3.1))(@emotion/server@11.10.0)(next@14.2.10(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@mantine/ssr': 6.0.22(@emotion/react@11.10.6(@types/react@18.3.3)(react@18.3.1))(@emotion/server@11.10.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mantine/styles': 6.0.22(@emotion/react@11.10.6(@types/react@18.3.3)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - next: 14.2.5(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.10(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) transitivePeerDependencies: - '@emotion/react' - '@emotion/server' - '@mantine/notifications@7.13.3(@mantine/core@7.13.3(@mantine/hooks@7.13.3(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.13.3(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@mantine/notifications@7.13.4(@mantine/core@7.13.4(@mantine/hooks@7.13.4(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.13.4(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@mantine/core': 7.13.3(@mantine/hooks@7.13.3(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mantine/hooks': 7.13.3(react@18.3.1) - '@mantine/store': 7.13.3(react@18.3.1) + '@mantine/core': 7.13.4(@mantine/hooks@7.13.4(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mantine/hooks': 7.13.4(react@18.3.1) + '@mantine/store': 7.13.4(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -14461,7 +14117,7 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@mantine/store@7.13.3(react@18.3.1)': + '@mantine/store@7.13.4(react@18.3.1)': dependencies: react: 18.3.1 @@ -14479,7 +14135,7 @@ snapshots: '@next/env@14.0.5-canary.46': {} - '@next/env@14.2.5': {} + '@next/env@14.2.10': {} '@next/eslint-plugin-next@14.1.0': dependencies: @@ -14488,55 +14144,55 @@ snapshots: '@next/swc-darwin-arm64@14.0.5-canary.46': optional: true - '@next/swc-darwin-arm64@14.2.5': + '@next/swc-darwin-arm64@14.2.10': optional: true '@next/swc-darwin-x64@14.0.5-canary.46': optional: true - '@next/swc-darwin-x64@14.2.5': + '@next/swc-darwin-x64@14.2.10': optional: true '@next/swc-linux-arm64-gnu@14.0.5-canary.46': optional: true - '@next/swc-linux-arm64-gnu@14.2.5': + '@next/swc-linux-arm64-gnu@14.2.10': optional: true '@next/swc-linux-arm64-musl@14.0.5-canary.46': optional: true - '@next/swc-linux-arm64-musl@14.2.5': + '@next/swc-linux-arm64-musl@14.2.10': optional: true '@next/swc-linux-x64-gnu@14.0.5-canary.46': optional: true - '@next/swc-linux-x64-gnu@14.2.5': + '@next/swc-linux-x64-gnu@14.2.10': optional: true '@next/swc-linux-x64-musl@14.0.5-canary.46': optional: true - '@next/swc-linux-x64-musl@14.2.5': + '@next/swc-linux-x64-musl@14.2.10': optional: true '@next/swc-win32-arm64-msvc@14.0.5-canary.46': optional: true - '@next/swc-win32-arm64-msvc@14.2.5': + '@next/swc-win32-arm64-msvc@14.2.10': optional: true '@next/swc-win32-ia32-msvc@14.0.5-canary.46': optional: true - '@next/swc-win32-ia32-msvc@14.2.5': + '@next/swc-win32-ia32-msvc@14.2.10': optional: true '@next/swc-win32-x64-msvc@14.0.5-canary.46': optional: true - '@next/swc-win32-x64-msvc@14.2.5': + '@next/swc-win32-x64-msvc@14.2.10': optional: true '@nodelib/fs.scandir@2.1.5': @@ -15522,7 +15178,7 @@ snapshots: dependencies: storybook: 8.2.0(@babel/preset-env@7.24.7(@babel/core@7.24.7)) - '@storybook/nextjs@8.2.0(@jest/globals@29.7.0)(@types/jest@29.5.12)(@types/webpack@5.28.5(esbuild@0.19.11))(babel-plugin-macros@3.1.0)(esbuild@0.19.11)(jest@29.7.0(@types/node@20.11.1)(babel-plugin-macros@3.1.0))(next@14.2.5(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.2.0(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(type-fest@4.21.0)(typescript@5.2.2)(webpack-hot-middleware@2.26.0)(webpack@5.75.0(esbuild@0.19.11))': + '@storybook/nextjs@8.2.0(@jest/globals@29.7.0)(@types/jest@29.5.12)(@types/webpack@5.28.5(esbuild@0.19.11))(babel-plugin-macros@3.1.0)(esbuild@0.19.11)(jest@29.7.0(@types/node@20.11.1)(babel-plugin-macros@3.1.0))(next@14.2.10(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.2.0(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(type-fest@4.21.0)(typescript@5.2.2)(webpack-hot-middleware@2.26.0)(webpack@5.75.0(esbuild@0.19.11))': dependencies: '@babel/core': 7.24.7 '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.7) @@ -15550,7 +15206,7 @@ snapshots: fs-extra: 11.1.1 image-size: 1.1.1 loader-utils: 3.2.1 - next: 14.2.5(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.10(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) node-polyfill-webpack-plugin: 2.0.1(webpack@5.75.0(esbuild@0.19.11)) pnp-webpack-plugin: 1.7.0(typescript@5.2.2) postcss: 8.4.47 @@ -15956,6 +15612,11 @@ snapshots: '@types/connect': 3.4.35 '@types/node': 20.11.1 + '@types/co-body@6.1.3': + dependencies: + '@types/node': 20.11.1 + '@types/qs': 6.9.11 + '@types/connect@3.4.35': dependencies: '@types/node': 20.11.1 @@ -16021,6 +15682,14 @@ snapshots: '@types/qs': 6.9.11 '@types/serve-static': 1.15.0 + '@types/formidable@2.0.5': + dependencies: + '@types/node': 20.11.1 + + '@types/formidable@3.4.5': + dependencies: + '@types/node': 20.11.1 + '@types/graceful-fs@4.1.6': dependencies: '@types/node': 20.11.1 @@ -16099,10 +15768,6 @@ snapshots: dependencies: '@types/koa': 2.13.5 - '@types/koa__multer@2.0.4': - dependencies: - '@types/koa': 2.13.5 - '@types/koa__router@12.0.0': dependencies: '@types/koa': 2.13.5 @@ -16537,8 +16202,6 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 - append-field@1.0.0: {} - arg@4.1.3: {} arg@5.0.2: {} @@ -16671,6 +16334,8 @@ snapshots: arrify@2.0.1: {} + asap@2.0.6: {} + asn1.js@5.4.1: dependencies: bn.js: 4.12.0 @@ -16746,20 +16411,6 @@ snapshots: dependencies: '@babel/core': 7.24.7 - babel-jest@29.7.0(@babel/core@7.21.0): - dependencies: - '@babel/core': 7.21.0 - '@jest/transform': 29.7.0 - '@types/babel__core': 7.20.0 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.21.0) - chalk: 4.1.2 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - optional: true - babel-jest@29.7.0(@babel/core@7.23.7): dependencies: '@babel/core': 7.23.7 @@ -16875,23 +16526,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-preset-current-node-syntax@1.0.1(@babel/core@7.21.0): - dependencies: - '@babel/core': 7.21.0 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.21.0) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.21.0) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.21.0) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.21.0) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.21.0) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.21.0) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.21.0) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.21.0) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.21.0) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.21.0) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.21.0) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.21.0) - optional: true - babel-preset-current-node-syntax@1.0.1(@babel/core@7.23.7): dependencies: '@babel/core': 7.23.7 @@ -16908,13 +16542,6 @@ snapshots: '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.7) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.7) - babel-preset-jest@29.6.3(@babel/core@7.21.0): - dependencies: - '@babel/core': 7.21.0 - babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.21.0) - optional: true - babel-preset-jest@29.6.3(@babel/core@7.23.7): dependencies: '@babel/core': 7.23.7 @@ -17036,16 +16663,9 @@ snapshots: dependencies: pako: 1.0.11 - browserslist@4.21.5: - dependencies: - caniuse-lite: 1.0.30001641 - electron-to-chromium: 1.4.304 - node-releases: 2.0.10 - update-browserslist-db: 1.0.10(browserslist@4.21.5) - browserslist@4.22.2: dependencies: - caniuse-lite: 1.0.30001579 + caniuse-lite: 1.0.30001641 electron-to-chromium: 1.4.637 node-releases: 2.0.14 update-browserslist-db: 1.0.13(browserslist@4.22.2) @@ -17286,7 +16906,7 @@ snapshots: dependencies: inflation: 2.0.0 qs: 6.11.2 - raw-body: 2.5.1 + raw-body: 2.5.2 type-is: 1.6.18 co@4.6.0: {} @@ -17358,13 +16978,6 @@ snapshots: concat-map@0.0.1: {} - concat-stream@1.6.2: - dependencies: - buffer-from: 1.1.2 - inherits: 2.0.4 - readable-stream: 2.3.7 - typedarray: 0.0.6 - config-chain@1.1.13: dependencies: ini: 1.3.8 @@ -17706,6 +17319,11 @@ snapshots: detect-node-es@1.1.0: {} + dezalgo@1.0.4: + dependencies: + asap: 2.0.6 + wrappy: 1.0.2 + didyoumean@1.2.2: {} diff-sequences@29.4.3: {} @@ -17817,8 +17435,6 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.4.304: {} - electron-to-chromium@1.4.637: {} electron-to-chromium@1.4.823: {} @@ -18666,14 +18282,6 @@ snapshots: locate-path: 7.2.0 path-exists: 5.0.0 - fix-esm@1.0.1: - dependencies: - '@babel/core': 7.21.0 - '@babel/plugin-proposal-export-namespace-from': 7.18.9(@babel/core@7.21.0) - '@babel/plugin-transform-modules-commonjs': 7.20.11(@babel/core@7.21.0) - transitivePeerDependencies: - - supports-color - flat-cache@3.0.4: dependencies: flatted: 3.2.7 @@ -18728,6 +18336,13 @@ snapshots: combined-stream: 1.0.8 mime-types: 2.1.35 + formidable@2.1.2: + dependencies: + dezalgo: 1.0.4 + hexoid: 1.0.0 + once: 1.4.0 + qs: 6.11.2 + forwarded@0.2.0: {} fraction.js@4.2.0: {} @@ -19042,6 +18657,8 @@ snapshots: helmet@4.6.0: {} + hexoid@1.0.0: {} + hmac-drbg@1.0.1: dependencies: hash.js: 1.1.7 @@ -19970,6 +19587,15 @@ snapshots: known-css-properties@0.34.0: {} + koa-body@6.0.1: + dependencies: + '@types/co-body': 6.1.3 + '@types/formidable': 2.0.5 + '@types/koa': 2.13.5 + co-body: 6.1.0 + formidable: 2.1.2 + zod: 3.21.4 + koa-bodyparser@4.3.0: dependencies: co-body: 6.1.0 @@ -20378,10 +20004,6 @@ snapshots: transitivePeerDependencies: - supports-color - mkdirp@0.5.6: - dependencies: - minimist: 1.2.8 - mkdirp@1.0.4: {} module-alias@2.2.2: {} @@ -20489,16 +20111,6 @@ snapshots: ms@2.1.3: {} - multer@1.4.5-lts.1: - dependencies: - append-field: 1.0.0 - busboy: 1.6.0 - concat-stream: 1.6.2 - mkdirp: 0.5.6 - object-assign: 4.1.1 - type-is: 1.6.18 - xtend: 4.0.2 - multipipe@1.0.2: dependencies: duplexer2: 0.1.4 @@ -20549,9 +20161,9 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@14.2.5(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@14.2.10(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@next/env': 14.2.5 + '@next/env': 14.2.10 '@swc/helpers': 0.5.5 busboy: 1.6.0 caniuse-lite: 1.0.30001641 @@ -20561,15 +20173,15 @@ snapshots: react-dom: 18.3.1(react@18.3.1) styled-jsx: 5.1.1(@babel/core@7.23.7)(babel-plugin-macros@3.1.0)(react@18.3.1) optionalDependencies: - '@next/swc-darwin-arm64': 14.2.5 - '@next/swc-darwin-x64': 14.2.5 - '@next/swc-linux-arm64-gnu': 14.2.5 - '@next/swc-linux-arm64-musl': 14.2.5 - '@next/swc-linux-x64-gnu': 14.2.5 - '@next/swc-linux-x64-musl': 14.2.5 - '@next/swc-win32-arm64-msvc': 14.2.5 - '@next/swc-win32-ia32-msvc': 14.2.5 - '@next/swc-win32-x64-msvc': 14.2.5 + '@next/swc-darwin-arm64': 14.2.10 + '@next/swc-darwin-x64': 14.2.10 + '@next/swc-linux-arm64-gnu': 14.2.10 + '@next/swc-linux-arm64-musl': 14.2.10 + '@next/swc-linux-x64-gnu': 14.2.10 + '@next/swc-linux-x64-musl': 14.2.10 + '@next/swc-win32-arm64-msvc': 14.2.10 + '@next/swc-win32-ia32-msvc': 14.2.10 + '@next/swc-win32-x64-msvc': 14.2.10 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -20624,8 +20236,6 @@ snapshots: vm-browserify: 1.1.2 webpack: 5.75.0(esbuild@0.19.11) - node-releases@2.0.10: {} - node-releases@2.0.14: {} node-schedule@2.1.1: @@ -20689,6 +20299,8 @@ snapshots: object-keys@1.1.1: {} + object-to-formdata@4.5.1: {} + object.assign@4.1.4: dependencies: call-bind: 1.0.5 @@ -21065,8 +20677,8 @@ snapshots: postcss@8.4.31: dependencies: nanoid: 3.3.7 - picocolors: 1.0.1 - source-map-js: 1.2.0 + picocolors: 1.1.1 + source-map-js: 1.2.1 postcss@8.4.32: dependencies: @@ -21189,13 +20801,6 @@ snapshots: range-parser@1.2.1: {} - raw-body@2.5.1: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - raw-body@2.5.2: dependencies: bytes: 3.1.2 @@ -22585,7 +22190,7 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.1.2(@babel/core@7.21.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.21.0))(jest@29.7.0(@types/node@20.11.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.101(@swc/helpers@0.5.5))(@types/node@20.11.1)(typescript@5.2.2)))(typescript@5.2.2): + ts-jest@29.1.2(@babel/core@7.23.7)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.7))(jest@29.7.0(@types/node@20.11.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.101(@swc/helpers@0.5.5))(@types/node@20.11.1)(typescript@5.2.2)))(typescript@5.2.2): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 @@ -22598,9 +22203,9 @@ snapshots: typescript: 5.2.2 yargs-parser: 21.1.1 optionalDependencies: - '@babel/core': 7.21.0 + '@babel/core': 7.23.7 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.21.0) + babel-jest: 29.7.0(@babel/core@7.23.7) ts-node-dev@2.0.0(@swc/core@1.3.101(@swc/helpers@0.5.5))(@types/node@20.11.1)(typescript@5.2.2): dependencies: @@ -22797,8 +22402,6 @@ snapshots: is-typed-array: 1.1.13 possible-typed-array-names: 1.0.0 - typedarray@0.0.6: {} - typescript@5.1.6: {} typescript@5.2.2: {} @@ -22837,12 +22440,6 @@ snapshots: unpipe@1.0.0: {} - update-browserslist-db@1.0.10(browserslist@4.21.5): - dependencies: - browserslist: 4.21.5 - escalade: 3.1.1 - picocolors: 1.1.1 - update-browserslist-db@1.0.13(browserslist@4.22.2): dependencies: browserslist: 4.22.2