From 071ce70292f0d9e4333acf47324edd2d488a4e01 Mon Sep 17 00:00:00 2001 From: David Nguyen Date: Sun, 5 Jan 2025 15:44:16 +1100 Subject: [PATCH] wip: test --- apps/remix/app/lib/auth-client.ts | 13 + apps/remix/app/lib/auth.server.ts | 112 ++++++ .../app/lib/auth/passkey-plugin/client.ts | 24 ++ .../app/lib/auth/passkey-plugin/index.ts | 165 ++++++++ apps/remix/app/routes.ts | 5 +- apps/remix/app/routes/_index.tsx | 193 ++++++++++ apps/remix/app/routes/api.auth.$.ts | 12 + apps/remix/app/routes/home.tsx | 13 - apps/remix/app/routes/signin.tsx | 40 ++ apps/remix/app/welcome/logo-dark.svg | 23 -- apps/remix/app/welcome/logo-light.svg | 23 -- apps/remix/app/welcome/welcome.tsx | 81 ---- apps/remix/package.json | 9 + apps/remix/vite.config.ts | 3 + package-lock.json | 351 ++++++++---------- .../migration.sql | 11 + .../migration.sql | 36 ++ .../migration.sql | 28 ++ .../migration.sql | 32 ++ packages/prisma/schema.prisma | 78 +++- 20 files changed, 903 insertions(+), 349 deletions(-) create mode 100644 apps/remix/app/lib/auth-client.ts create mode 100644 apps/remix/app/lib/auth.server.ts create mode 100644 apps/remix/app/lib/auth/passkey-plugin/client.ts create mode 100644 apps/remix/app/lib/auth/passkey-plugin/index.ts create mode 100644 apps/remix/app/routes/_index.tsx create mode 100644 apps/remix/app/routes/api.auth.$.ts delete mode 100644 apps/remix/app/routes/home.tsx create mode 100644 apps/remix/app/routes/signin.tsx delete mode 100644 apps/remix/app/welcome/logo-dark.svg delete mode 100644 apps/remix/app/welcome/logo-light.svg delete mode 100644 apps/remix/app/welcome/welcome.tsx create mode 100644 packages/prisma/migrations/20250104024352_add_user_secondary_id/migration.sql create mode 100644 packages/prisma/migrations/20250104055239_add_better_auth_fields/migration.sql create mode 100644 packages/prisma/migrations/20250104055250_migrate_documenso_users_to_accounts/migration.sql create mode 100644 packages/prisma/migrations/20250104070109_extract_two_factor_into_table/migration.sql diff --git a/apps/remix/app/lib/auth-client.ts b/apps/remix/app/lib/auth-client.ts new file mode 100644 index 000000000..47b073e66 --- /dev/null +++ b/apps/remix/app/lib/auth-client.ts @@ -0,0 +1,13 @@ +import { twoFactor } from 'better-auth/plugins'; +import { createAuthClient } from 'better-auth/react'; + +import { passkeyClientPlugin } from './auth/passkey-plugin/client'; + +// make sure to import from better-auth/react + +export const authClient = createAuthClient({ + baseURL: 'http://localhost:3000', + plugins: [twoFactor(), passkeyClientPlugin()], +}); + +export const { signIn, signOut, useSession } = authClient; diff --git a/apps/remix/app/lib/auth.server.ts b/apps/remix/app/lib/auth.server.ts new file mode 100644 index 000000000..8067cd5ca --- /dev/null +++ b/apps/remix/app/lib/auth.server.ts @@ -0,0 +1,112 @@ +import { compare, hash } from '@node-rs/bcrypt'; +import { betterAuth } from 'better-auth'; +import { prismaAdapter } from 'better-auth/adapters/prisma'; +import { twoFactor } from 'better-auth/plugins'; + +import { getAuthenticatorOptions } from '@documenso/lib/utils/authenticator'; +import { prisma } from '@documenso/prisma'; + +import { passkeyPlugin } from './auth/passkey-plugin'; + +// todo: import from @documenso/lib/constants/auth +export const SALT_ROUNDS = 12; + +const passkeyOptions = getAuthenticatorOptions(); + +export const auth = betterAuth({ + appName: 'Documenso', + plugins: [ + twoFactor({ + issuer: 'Documenso', + skipVerificationOnEnable: true, + // totpOptions: { + + // }, + schema: { + twoFactor: { + modelName: 'TwoFactor', + fields: { + userId: 'userId', + secret: 'secret', + backupCodes: 'backupCodes', + }, + }, + }, + // todo: add options + }), + passkeyPlugin(), + // passkey({ + // rpID: passkeyOptions.rpId, + // rpName: passkeyOptions.rpName, + // origin: passkeyOptions.origin, + // schema: { + // passkey: { + // fields: { + // publicKey: 'credentialPublicKey', + // credentialID: 'credentialId', + // deviceType: 'credentialDeviceType', + // backedUp: 'credentialBackedUp', + // // transports: '', + // }, + // }, + // }, + // }), + ], + secret: 'secret', // todo + database: prismaAdapter(prisma, { + provider: 'postgresql', + }), + databaseHooks: { + account: { + create: { + before: (session) => { + return { + data: { + ...session, + accountId: session.accountId.toString(), + }, + }; + }, + }, + }, + }, + session: { + fields: { + token: 'sessionToken', + expiresAt: 'expires', + }, + }, + user: { + fields: { + emailVerified: 'isEmailVerified', + }, + }, + account: { + fields: { + providerId: 'provider', + accountId: 'providerAccountId', + refreshToken: 'refresh_token', + accessToken: 'access_token', + idToken: 'id_token', + }, + }, + advanced: { + generateId: false, + }, + socialProviders: { + google: { + clientId: '', + clientSecret: '', + }, + }, + emailAndPassword: { + enabled: true, + requireEmailVerification: false, + // maxPasswordLength: 128, + // minPasswordLength: 8, + password: { + hash: async (password) => hash(password, SALT_ROUNDS), + verify: async ({ hash, password }) => compare(password, hash), + }, + }, +}); diff --git a/apps/remix/app/lib/auth/passkey-plugin/client.ts b/apps/remix/app/lib/auth/passkey-plugin/client.ts new file mode 100644 index 000000000..1b29ba72f --- /dev/null +++ b/apps/remix/app/lib/auth/passkey-plugin/client.ts @@ -0,0 +1,24 @@ +import type { BetterAuthClientPlugin } from 'better-auth'; + +import type { passkeyPlugin } from './index'; + +type PasskeyPlugin = typeof passkeyPlugin; + +export const passkeyClientPlugin = () => { + const passkeySignin = () => { + // + // credential: JSON.stringify(credential), + // callbackUrl, + }; + + return { + id: 'passkeyPlugin', + getActions: () => ({ + signIn: { + passkey: () => passkeySignin, + }, + }), + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + $InferServerPlugin: {} as ReturnType, + } satisfies BetterAuthClientPlugin; +}; diff --git a/apps/remix/app/lib/auth/passkey-plugin/index.ts b/apps/remix/app/lib/auth/passkey-plugin/index.ts new file mode 100644 index 000000000..1adac51ba --- /dev/null +++ b/apps/remix/app/lib/auth/passkey-plugin/index.ts @@ -0,0 +1,165 @@ +import type { BetterAuthPlugin } from 'better-auth'; +import { createAuthEndpoint, createAuthMiddleware } from 'better-auth/plugins'; + +export const passkeyPlugin = () => + ({ + id: 'passkeyPlugin', + schema: { + user: { + fields: { + // twoFactorEnabled: { + // type: 'boolean', + // required: false, + // }, + // twoFactorBackupCodes: { + // type: 'string', + // required: false, + // }, + // twoFactorSecret: { + // type: 'string', + // required: false, + // }, + // birthday: { + // type: 'date', // string, number, boolean, date + // required: true, // if the field should be required on a new record. (default: false) + // unique: false, // if the field should be unique. (default: false) + // reference: null, // if the field is a reference to another table. (default: null) + // }, + }, + }, + }, + endpoints: { + authorize: createAuthEndpoint( + '/passkey/authorize', + { + method: 'POST', + // use: [], + }, + async (ctx) => { + const csrfToken = credentials?.csrfToken; + + if (typeof csrfToken !== 'string' || csrfToken.length === 0) { + throw new AppError(AppErrorCode.INVALID_REQUEST); + } + + let requestBodyCrediential: TAuthenticationResponseJSONSchema | null = null; + + try { + const parsedBodyCredential = JSON.parse(req.body?.credential); + requestBodyCrediential = ZAuthenticationResponseJSONSchema.parse(parsedBodyCredential); + } catch { + throw new AppError(AppErrorCode.INVALID_REQUEST); + } + + const challengeToken = await prisma.anonymousVerificationToken + .delete({ + where: { + id: csrfToken, + }, + }) + .catch(() => null); + + if (!challengeToken) { + return null; + } + + if (challengeToken.expiresAt < new Date()) { + throw new AppError(AppErrorCode.EXPIRED_CODE); + } + + const passkey = await prisma.passkey.findFirst({ + where: { + credentialId: Buffer.from(requestBodyCrediential.id, 'base64'), + }, + include: { + User: { + select: { + id: true, + email: true, + name: true, + emailVerified: true, + }, + }, + }, + }); + + if (!passkey) { + throw new AppError(AppErrorCode.NOT_SETUP); + } + + const user = passkey.User; + + const { rpId, origin } = getAuthenticatorOptions(); + + const verification = await verifyAuthenticationResponse({ + response: requestBodyCrediential, + expectedChallenge: challengeToken.token, + expectedOrigin: origin, + expectedRPID: rpId, + authenticator: { + credentialID: new Uint8Array(Array.from(passkey.credentialId)), + credentialPublicKey: new Uint8Array(passkey.credentialPublicKey), + counter: Number(passkey.counter), + }, + }).catch(() => null); + + const requestMetadata = extractNextAuthRequestMetadata(req); + + if (!verification?.verified) { + await prisma.userSecurityAuditLog.create({ + data: { + userId: user.id, + ipAddress: requestMetadata.ipAddress, + userAgent: requestMetadata.userAgent, + type: UserSecurityAuditLogType.SIGN_IN_PASSKEY_FAIL, + }, + }); + + return null; + } + + await prisma.passkey.update({ + where: { + id: passkey.id, + }, + data: { + lastUsedAt: new Date(), + counter: verification.authenticationInfo.newCounter, + }, + }); + + return { + id: Number(user.id), + email: user.email, + name: user.name, + emailVerified: user.emailVerified?.toISOString() ?? null, + } satisfies User; + }, + ), + }, + hooks: { + before: [ + { + matcher: (context) => context.path.startsWith('/sign-in/email'), + handler: createAuthMiddleware(async (ctx) => { + console.log('here...'); + + const { birthday } = ctx.body; + + if ((!birthday) instanceof Date) { + throw new APIError('BAD_REQUEST', { message: 'Birthday must be of type Date.' }); + } + + const today = new Date(); + const fiveYearsAgo = new Date(today.setFullYear(today.getFullYear() - 5)); + + if (birthday >= fiveYearsAgo) { + throw new APIError('BAD_REQUEST', { message: 'User must be above 5 years old.' }); + } + + return { context: ctx }; + }), + }, + ], + }, + }) satisfies BetterAuthPlugin; diff --git a/apps/remix/app/routes.ts b/apps/remix/app/routes.ts index 205ff3ccb..b3fe2c3bc 100644 --- a/apps/remix/app/routes.ts +++ b/apps/remix/app/routes.ts @@ -1,3 +1,4 @@ -import { type RouteConfig, index } from '@react-router/dev/routes'; +import { type RouteConfig } from '@react-router/dev/routes'; +import { flatRoutes } from '@react-router/fs-routes'; -export default [index('routes/home.tsx')] satisfies RouteConfig; +export default flatRoutes() satisfies RouteConfig; diff --git a/apps/remix/app/routes/_index.tsx b/apps/remix/app/routes/_index.tsx new file mode 100644 index 000000000..849d33700 --- /dev/null +++ b/apps/remix/app/routes/_index.tsx @@ -0,0 +1,193 @@ +import { useState } from 'react'; + +import { Button } from '@documenso/ui/primitives/button'; + +import { authClient, signOut, useSession } from '~/lib/auth-client'; +import { auth } from '~/lib/auth.server'; + +import type { Route } from '../+types/root'; + +export function meta({}: Route.MetaArgs) { + return [ + { title: 'New React Router App' }, + { name: 'description', content: 'Welcome to React Router!' }, + ]; +} + +export async function loader({ params, request, context }: Route.LoaderArgs) { + const session = await auth.api.getSession({ + query: { + disableCookieCache: true, + }, + headers: request.headers, // pass the headers + }); + + return { + session, + }; +} + +export function clientLoader({ params }: Route.ClientLoaderArgs) { + return { + session: authClient.getSession(), + }; +} + +export default function Home({ loaderData }: Route.ComponentProps) { + const { data } = useSession(); + + const [email, setEmail] = useState('deepfriedcoconut@gmail.com'); + const [password, setPassword] = useState('password'); + + const signIn = async () => { + await authClient.signIn.email( + { + email, + password, + }, + { + onRequest: (ctx) => { + // show loading state + }, + onSuccess: (ctx) => { + console.log('success'); + // redirect to home + }, + onError: (ctx) => { + console.log(ctx.error); + alert(ctx.error); + }, + }, + ); + }; + + const signUp = async () => { + await authClient.signUp.email( + { + email, + password, + name: '', + }, + { + onRequest: (ctx) => { + // show loading state + }, + onSuccess: (ctx) => { + console.log(ctx); + // redirect to home + }, + onError: (ctx) => { + console.log(ctx.error); + alert(ctx.error); + }, + }, + ); + }; + + return ( +
+

Status: {data ? 'Authenticated' : 'Not Authenticated'}

+ + {data ? ( + <> +
+

Session data

+

{JSON.stringify(data, null, 2)}

+
+ +
+ + + +
+ + + + ) : ( + <> +
+

Sign In

+ setEmail(e.target.value)} + /> + setPassword(e.target.value)} + /> + + +
+ +
+

Sign Up

+ + setEmail(e.target.value)} + placeholder="Email" + /> + setPassword(e.target.value)} + placeholder="Password" + /> + +
+ + + + + + )} +
+ ); +} diff --git a/apps/remix/app/routes/api.auth.$.ts b/apps/remix/app/routes/api.auth.$.ts new file mode 100644 index 000000000..405cb1b6f --- /dev/null +++ b/apps/remix/app/routes/api.auth.$.ts @@ -0,0 +1,12 @@ +// Adjust the path as necessary +import type { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node'; + +import { auth } from '~/lib/auth.server'; + +export function loader({ request }: LoaderFunctionArgs) { + return auth.handler(request); +} + +export function action({ request }: ActionFunctionArgs) { + return auth.handler(request); +} diff --git a/apps/remix/app/routes/home.tsx b/apps/remix/app/routes/home.tsx deleted file mode 100644 index bf62d13d7..000000000 --- a/apps/remix/app/routes/home.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { Welcome } from '../welcome/welcome'; -import type { Route } from './+types/home'; - -export function meta({}: Route.MetaArgs) { - return [ - { title: 'New React Router App' }, - { name: 'description', content: 'Welcome to React Router!' }, - ]; -} - -export default function Home() { - return ; -} diff --git a/apps/remix/app/routes/signin.tsx b/apps/remix/app/routes/signin.tsx new file mode 100644 index 000000000..d6c5ed5e6 --- /dev/null +++ b/apps/remix/app/routes/signin.tsx @@ -0,0 +1,40 @@ +import { useState } from 'react'; + +import { authClient } from '~/lib/auth-client'; + +export default function SignIn() { + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + + const signIn = async () => { + await authClient.signIn.email( + { + email, + password, + }, + { + onRequest: (ctx) => { + // show loading state + }, + onSuccess: (ctx) => { + // redirect to home + }, + onError: (ctx) => { + alert(ctx.error); + }, + }, + ); + }; + + return ( +
+

Sign In

+ setEmail(e.target.value)} /> + setPassword(e.target.value)} /> + + +
+ ); +} diff --git a/apps/remix/app/welcome/logo-dark.svg b/apps/remix/app/welcome/logo-dark.svg deleted file mode 100644 index dd8202894..000000000 --- a/apps/remix/app/welcome/logo-dark.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/remix/app/welcome/logo-light.svg b/apps/remix/app/welcome/logo-light.svg deleted file mode 100644 index 73284929d..000000000 --- a/apps/remix/app/welcome/logo-light.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/remix/app/welcome/welcome.tsx b/apps/remix/app/welcome/welcome.tsx deleted file mode 100644 index 8229e34a1..000000000 --- a/apps/remix/app/welcome/welcome.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import logoDark from './logo-dark.svg'; -import logoLight from './logo-light.svg'; - -export function Welcome() { - return ( -
-
-
-
- React Router - React Router -
-
-
- -
-
-
- ); -} - -const resources = [ - { - href: 'https://reactrouter.com/docs', - text: 'React Router Docs', - icon: ( - - - - ), - }, - { - href: 'https://rmx.as/discord', - text: 'Join Discord', - icon: ( - - - - ), - }, -]; diff --git a/apps/remix/package.json b/apps/remix/package.json index ab29f5b03..7477ad8c9 100644 --- a/apps/remix/package.json +++ b/apps/remix/package.json @@ -9,10 +9,19 @@ "typecheck": "react-router typegen && tsc" }, "dependencies": { + "@documenso/api": "*", + "@documenso/assets": "*", + "@documenso/ee": "*", + "@documenso/lib": "*", + "@documenso/prisma": "*", + "@documenso/trpc": "*", + "@documenso/ui": "*", "@epic-web/remember": "^1.1.0", "@hono/node-server": "^1.13.7", + "@react-router/fs-routes": "^7.1.1", "@react-router/node": "^7.1.1", "@react-router/serve": "^7.1.1", + "better-auth": "^1.1.9", "hono": "^4.6.15", "isbot": "^5.1.17", "react": "^18", diff --git a/apps/remix/vite.config.ts b/apps/remix/vite.config.ts index 76a0b1add..7ee462952 100644 --- a/apps/remix/vite.config.ts +++ b/apps/remix/vite.config.ts @@ -11,4 +11,7 @@ export default defineConfig({ }, }, plugins: [reactRouter(), tsconfigPaths()], + optimizeDeps: { + exclude: ['@node-rs/bcrypt'], + }, }); diff --git a/package-lock.json b/package-lock.json index 555380b41..64bc29110 100644 --- a/package-lock.json +++ b/package-lock.json @@ -135,10 +135,19 @@ "apps/remix": { "name": "@documenso/remix", "dependencies": { + "@documenso/api": "*", + "@documenso/assets": "*", + "@documenso/ee": "*", + "@documenso/lib": "*", + "@documenso/prisma": "*", + "@documenso/trpc": "*", + "@documenso/ui": "*", "@epic-web/remember": "^1.1.0", "@hono/node-server": "^1.13.7", + "@react-router/fs-routes": "^7.1.1", "@react-router/node": "^7.1.1", "@react-router/serve": "^7.1.1", + "better-auth": "^1.1.9", "hono": "^4.6.15", "isbot": "^5.1.17", "react": "^18", @@ -158,6 +167,75 @@ "vite-tsconfig-paths": "^5.1.4" } }, + "apps/remix/node_modules/@noble/ciphers": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.6.0.tgz", + "integrity": "sha512-mIbq/R9QXk5/cTfESb1OKtyFnk7oc1Om/8onA1158K9/OZUQFDEVy55jVTato+xmp3XX6F6Qh0zz0Nc1AxAlRQ==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "apps/remix/node_modules/@noble/hashes": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.0.tgz", + "integrity": "sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "apps/remix/node_modules/@simplewebauthn/browser": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@simplewebauthn/browser/-/browser-13.0.0.tgz", + "integrity": "sha512-7d/+gxoFoDQxq2EkLl/PuTIQ/rnSrA3bmr8L2Ij7bRyicJoCJX/NDGUNExyctB9nSDrEkkcrJMDkwpCYOGU3Lg==" + }, + "apps/remix/node_modules/@simplewebauthn/server": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@simplewebauthn/server/-/server-13.0.0.tgz", + "integrity": "sha512-Tb3hJRpeT4cgT2uPORc465qu9LGXcDoIegFmkIgqw7XNZtsaoHzn3xI1DiFH7ukzs6JbhfQBRyY4rlfCdTwkNw==", + "dependencies": { + "@hexagon/base64": "^1.1.27", + "@levischuck/tiny-cbor": "^0.2.2", + "@peculiar/asn1-android": "^2.3.10", + "@peculiar/asn1-ecc": "^2.3.8", + "@peculiar/asn1-rsa": "^2.3.8", + "@peculiar/asn1-schema": "^2.3.8", + "@peculiar/asn1-x509": "^2.3.8", + "cross-fetch": "^4.0.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "apps/remix/node_modules/better-auth": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/better-auth/-/better-auth-1.1.9.tgz", + "integrity": "sha512-giGua5RtMLLAEkEOrOBJqzk4yyH8I8Vzj+XegW+JkKci99T6RqdW/N6phzpYyy/37xH1ara8E4Ho7ZDgtChzSA==", + "dependencies": { + "@better-auth/utils": "0.2.3", + "@better-fetch/fetch": "1.1.12", + "@noble/ciphers": "^0.6.0", + "@noble/hashes": "^1.6.1", + "@simplewebauthn/browser": "^13.0.0", + "@simplewebauthn/server": "^13.0.0", + "better-call": "0.3.3", + "defu": "^6.1.4", + "jose": "^5.9.6", + "kysely": "^0.27.4", + "uncrypto": "^0.1.3", + "zod": "^3.24.1" + } + }, + "apps/remix/node_modules/jose": { + "version": "5.9.6", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.9.6.tgz", + "integrity": "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "apps/remix/node_modules/remix-hono": { "version": "0.0.18", "resolved": "https://registry.npmjs.org/remix-hono/-/remix-hono-0.0.18.tgz", @@ -322,7 +400,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -1259,7 +1336,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -1268,7 +1344,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", - "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", @@ -1298,7 +1373,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", - "dev": true, "dependencies": { "@babel/types": "^7.24.7", "@jridgewell/gen-mapping": "^0.3.5", @@ -1313,7 +1387,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/generator": "^7.24.7", @@ -1334,7 +1407,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", - "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", @@ -1348,7 +1420,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "engines": { "node": ">=4" } @@ -1357,7 +1428,6 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, "bin": { "json5": "lib/cli.js" }, @@ -1369,7 +1439,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -1399,7 +1468,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.25.9" @@ -1412,7 +1480,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -1426,7 +1493,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", - "dev": true, "dependencies": { "@babel/compat-data": "^7.24.7", "@babel/helper-validator-option": "^7.24.7", @@ -1442,7 +1508,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, "dependencies": { "yallist": "^3.0.2" } @@ -1451,7 +1516,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -1459,14 +1523,12 @@ "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", @@ -1488,7 +1550,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.26.3", @@ -1505,7 +1566,6 @@ "version": "7.26.4", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", @@ -1524,7 +1584,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -1538,7 +1597,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -1548,7 +1606,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -1561,7 +1618,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -1644,7 +1700,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.25.9", @@ -1658,7 +1713,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.26.3", @@ -1675,7 +1729,6 @@ "version": "7.26.4", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", @@ -1694,7 +1747,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -1708,7 +1760,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -1718,7 +1769,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -1731,7 +1781,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.25.9", @@ -1745,7 +1794,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.26.3", @@ -1762,7 +1810,6 @@ "version": "7.26.4", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", @@ -1781,7 +1828,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -1795,7 +1841,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -1805,7 +1850,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -1818,7 +1862,6 @@ "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.25.9", @@ -1836,7 +1879,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.26.3", @@ -1853,7 +1895,6 @@ "version": "7.26.4", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", @@ -1872,7 +1913,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -1886,7 +1926,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -1896,7 +1935,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -1909,7 +1947,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.25.9" @@ -1922,7 +1959,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -1936,7 +1972,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1946,7 +1981,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-member-expression-to-functions": "^7.25.9", @@ -1964,7 +1998,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.26.3", @@ -1981,7 +2014,6 @@ "version": "7.26.4", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", @@ -2000,7 +2032,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -2014,7 +2045,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -2024,7 +2054,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -2037,7 +2066,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.25.9", @@ -2051,7 +2079,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.26.3", @@ -2068,7 +2095,6 @@ "version": "7.26.4", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", @@ -2087,7 +2113,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -2101,7 +2126,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -2111,7 +2135,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -2166,7 +2189,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -2176,7 +2198,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", - "dev": true, "dependencies": { "@babel/template": "^7.24.7", "@babel/types": "^7.24.7" @@ -2189,7 +2210,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", - "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", @@ -2231,7 +2251,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.25.9.tgz", "integrity": "sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" @@ -2247,7 +2266,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" @@ -2263,7 +2281,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" @@ -2279,7 +2296,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.26.0", @@ -2296,7 +2312,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.3.tgz", "integrity": "sha512-6+5hpdr6mETwSKjmJUdYw0EIkATiQhnELWlE3kJFBwSg/BGIVwVaVbX+gOXBCdc7Ln1RXZxyWGecIXhUfnl7oA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", @@ -2316,7 +2331,6 @@ "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", @@ -2449,6 +2463,19 @@ "node": ">=6.9.0" } }, + "node_modules/@better-auth/utils": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@better-auth/utils/-/utils-0.2.3.tgz", + "integrity": "sha512-Ap1GaSmo6JYhJhxJOpUB0HobkKPTNzfta+bLV89HfpyCAHN7p8ntCrmNFHNAVD0F6v0mywFVEUg1FUhNCc81Rw==", + "dependencies": { + "uncrypto": "^0.1.3" + } + }, + "node_modules/@better-fetch/fetch": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@better-fetch/fetch/-/fetch-1.1.12.tgz", + "integrity": "sha512-B3bfloI/2UBQWIATRN6qmlORrvx3Mp0kkNjmXLv0b+DtbtR+pP4/I5kQA/rDUv+OReLywCCldf6co4LdDmh8JA==" + }, "node_modules/@braintree/sanitize-url": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.0.0.tgz", @@ -2997,7 +3024,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3014,7 +3040,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3031,7 +3056,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3048,7 +3072,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3081,7 +3104,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3098,7 +3120,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3115,7 +3136,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3132,7 +3152,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3149,7 +3168,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3166,7 +3184,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3183,7 +3200,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3200,7 +3216,6 @@ "cpu": [ "mips64el" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3217,7 +3232,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3234,7 +3248,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3251,7 +3264,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3268,7 +3280,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3285,7 +3296,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3302,7 +3312,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3319,7 +3328,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3336,7 +3344,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3353,7 +3360,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3370,7 +3376,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3802,7 +3807,7 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dev": true, + "devOptional": true, "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -5670,7 +5675,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-4.1.0.tgz", "integrity": "sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==", - "dev": true, "dependencies": { "@npmcli/promise-spawn": "^6.0.0", "lru-cache": "^7.4.4", @@ -5689,7 +5693,6 @@ "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, "engines": { "node": ">=12" } @@ -5698,7 +5701,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -5788,7 +5790,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-4.0.1.tgz", "integrity": "sha512-lRCEGdHZomFsURroh522YvA/2cVb9oPIJrjHanCJZkiasz1BzcnLr3tBJhlV7S86MBJBuAQ33is2D60YitZL2Q==", - "dev": true, "license": "ISC", "dependencies": { "@npmcli/git": "^4.1.0", @@ -5807,7 +5808,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -5817,7 +5817,6 @@ "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -5838,7 +5837,6 @@ "version": "6.1.3", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.3.tgz", "integrity": "sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==", - "dev": true, "license": "ISC", "dependencies": { "lru-cache": "^7.5.1" @@ -5851,7 +5849,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -5867,7 +5864,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", - "dev": true, "license": "MIT", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -5877,7 +5873,6 @@ "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, "license": "ISC", "engines": { "node": ">=12" @@ -5887,7 +5882,6 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -5903,7 +5897,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" @@ -5913,7 +5906,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^6.0.0", @@ -5929,7 +5921,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz", "integrity": "sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==", - "dev": true, "dependencies": { "which": "^3.0.0" }, @@ -5941,7 +5932,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -8306,7 +8296,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/@react-router/dev/-/dev-7.1.1.tgz", "integrity": "sha512-+UCrQZBAmdRcC7Bx1ho89T/DeP+FzEErkzrTvdBCpstr8AzOQ6mKlaglXGty15o3fgihBSFF4/J67jGveYIR8Q==", - "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.21.8", @@ -8368,7 +8357,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.26.3", @@ -8385,7 +8373,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -8399,14 +8386,12 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true, "license": "MIT" }, "node_modules/@react-router/dev/node_modules/chokidar": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, "license": "MIT", "dependencies": { "readdirp": "^4.0.1" @@ -8422,7 +8407,6 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -8440,7 +8424,6 @@ "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", @@ -8455,7 +8438,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", - "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -8468,14 +8450,12 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/@react-router/dev/node_modules/prettier": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, "license": "MIT", "bin": { "prettier": "bin-prettier.js" @@ -8491,7 +8471,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 14.16.0" @@ -8505,7 +8484,6 @@ "version": "3.0.0-beta.2", "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.0-beta.2.tgz", "integrity": "sha512-ofTf6cfRdL30Wbl9n/BX81EyIR5s4PReLmSurrxQ+koLaWUNOEo8E0lCM53OJkb8vpa2URM2nSrxZsIFyvY1rg==", - "dev": true, "license": "MIT", "dependencies": { "cac": "^6.7.14", @@ -8546,6 +8524,48 @@ } } }, + "node_modules/@react-router/fs-routes": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@react-router/fs-routes/-/fs-routes-7.1.1.tgz", + "integrity": "sha512-FXe4d5sKRwa3Yj1xz4rtnxpmwG1IENr+Jd8fQd4IxbC6u/HJrIURacq1l83cTr62Uerf5N4h3v3pGgDEmmGwcg==", + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@react-router/dev": "^7.1.1", + "typescript": "^5.1.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@react-router/fs-routes/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@react-router/fs-routes/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@react-router/node": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@react-router/node/-/node-7.1.1.tgz", @@ -8610,7 +8630,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8624,7 +8643,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8638,7 +8656,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8652,7 +8669,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8666,7 +8682,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8680,7 +8695,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8694,7 +8708,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8708,7 +8721,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8722,7 +8734,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8736,7 +8747,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8750,7 +8760,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8764,7 +8773,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8778,7 +8786,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8792,7 +8799,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8806,7 +8812,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8820,7 +8825,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8834,7 +8838,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8848,7 +8851,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8862,7 +8864,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -12615,7 +12616,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/babel-dead-code-elimination/-/babel-dead-code-elimination-1.0.8.tgz", "integrity": "sha512-og6HQERk0Cmm+nTT4Od2wbPtgABXFMPaHACjbKLulZIFMkYyXZLkUGuAxdgpMJBrxyt/XFpSz++lNzjbcMnPkQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.23.7", @@ -12628,7 +12628,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.26.3", @@ -12645,7 +12644,6 @@ "version": "7.26.4", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", @@ -12664,7 +12662,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -12678,7 +12675,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -12688,7 +12684,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -12845,6 +12840,17 @@ "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" }, + "node_modules/better-call": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/better-call/-/better-call-0.3.3.tgz", + "integrity": "sha512-N4lDVm0NGmFfDJ0XMQ4O83Zm/3dPlvIQdxvwvgSLSkjFX5PM4GUYSVAuxNzXN27QZMHDkrJTWUqxBrm4tPC3eA==", + "dependencies": { + "@better-fetch/fetch": "^1.1.4", + "rou3": "^0.5.1", + "uncrypto": "^0.1.3", + "zod": "^3.24.1" + } + }, "node_modules/big-integer": { "version": "1.6.52", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", @@ -13120,7 +13126,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", "integrity": "sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==", - "dev": true, "license": "MIT", "dependencies": { "pako": "~0.2.0" @@ -13130,7 +13135,6 @@ "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", - "dev": true, "license": "MIT" }, "node_modules/browserslist": { @@ -13263,7 +13267,6 @@ "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, "engines": { "node": ">=8" } @@ -14884,8 +14887,7 @@ "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "node_modules/cookie": { "version": "0.5.0", @@ -15724,7 +15726,6 @@ "version": "1.5.3", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", - "dev": true, "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -16419,8 +16420,7 @@ "node_modules/err-code": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "dev": true + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==" }, "node_modules/error-ex": { "version": "1.3.2", @@ -16523,8 +16523,7 @@ "node_modules/es-module-lexer": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", - "dev": true + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==" }, "node_modules/es-object-atoms": { "version": "1.0.0", @@ -17861,7 +17860,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-2.2.1.tgz", "integrity": "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -18809,7 +18807,6 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -19289,7 +19286,6 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz", "integrity": "sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==", - "dev": true, "license": "MIT", "dependencies": { "browserify-zlib": "^0.1.4", @@ -19307,14 +19303,12 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, "license": "MIT" }, "node_modules/gunzip-maybe/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", @@ -19330,14 +19324,12 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, "license": "MIT" }, "node_modules/gunzip-maybe/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" @@ -19347,7 +19339,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, "license": "MIT", "dependencies": { "readable-stream": "~2.3.6", @@ -20845,7 +20836,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-deflate/-/is-deflate-1.0.0.tgz", "integrity": "sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==", - "dev": true, "license": "MIT" }, "node_modules/is-docker": { @@ -20930,7 +20920,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-1.0.0.tgz", "integrity": "sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -21860,9 +21849,9 @@ } }, "node_modules/kysely": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/kysely/-/kysely-0.27.3.tgz", - "integrity": "sha512-lG03Ru+XyOJFsjH3OMY6R/9U38IjDPfnOfDgO3ynhbDr+Dz8fak+X6L62vqu3iybQnj+lG84OttBuU9KY3L9kA==", + "version": "0.27.5", + "resolved": "https://registry.npmjs.org/kysely/-/kysely-0.27.5.tgz", + "integrity": "sha512-s7hZHcQeSNKpzCkHRm8yA+0JPLjncSWnjb+2TIElwS2JAqYr+Kv3Ess+9KFfJS0C1xcQ1i9NkNHpWwCYpHMWsA==", "engines": { "node": ">=14.0.0" } @@ -25721,7 +25710,6 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", - "dev": true, "dependencies": { "semver": "^7.1.1" }, @@ -25742,7 +25730,6 @@ "version": "10.1.0", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", - "dev": true, "dependencies": { "hosted-git-info": "^6.0.0", "proc-log": "^3.0.0", @@ -25757,7 +25744,6 @@ "version": "6.1.1", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", - "dev": true, "dependencies": { "lru-cache": "^7.5.1" }, @@ -25769,7 +25755,6 @@ "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, "engines": { "node": ">=12" } @@ -25836,7 +25821,6 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz", "integrity": "sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==", - "dev": true, "dependencies": { "npm-install-checks": "^6.0.0", "npm-normalize-package-bin": "^3.0.0", @@ -25851,7 +25835,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", - "dev": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -27139,7 +27122,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/peek-stream/-/peek-stream-1.1.3.tgz", "integrity": "sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==", - "dev": true, "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", @@ -27151,14 +27133,12 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, "license": "MIT" }, "node_modules/peek-stream/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", @@ -27174,14 +27154,12 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, "license": "MIT" }, "node_modules/peek-stream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" @@ -27191,7 +27169,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, "license": "MIT", "dependencies": { "readable-stream": "~2.3.6", @@ -28086,7 +28063,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", - "dev": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -28116,14 +28092,12 @@ "node_modules/promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "dev": true + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==" }, "node_modules/promise-retry": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dev": true, "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" @@ -28136,7 +28110,6 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true, "engines": { "node": ">= 4" } @@ -28368,7 +28341,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, "license": "MIT", "dependencies": { "duplexify": "^3.6.0", @@ -28380,7 +28352,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -29354,7 +29325,6 @@ "version": "0.14.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -31123,6 +31093,11 @@ "fsevents": "~2.3.2" } }, + "node_modules/rou3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/rou3/-/rou3-0.5.1.tgz", + "integrity": "sha512-OXMmJ3zRk2xeXFGfA3K+EOPHC5u7RDFG7lIOx0X1pdnhUkI8MdVrbV+sNsD80ElpUZ+MRHdyxPnFthq9VHs8uQ==" + }, "node_modules/run-async": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", @@ -33110,7 +33085,7 @@ "version": "5.31.1", "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", - "dev": true, + "devOptional": true, "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -33164,7 +33139,7 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, + "devOptional": true, "peer": true }, "node_modules/text-decoder": { @@ -35059,7 +35034,6 @@ "version": "0.41.0", "resolved": "https://registry.npmjs.org/valibot/-/valibot-0.41.0.tgz", "integrity": "sha512-igDBb8CTYr8YTQlOKgaN9nSS0Be7z+WRuaeYqGf3Cjz3aKmSnqEmYnkfVjzIuumGqfHpa3fLIvMEAfhrpqN8ng==", - "dev": true, "license": "MIT", "peerDependencies": { "typescript": ">=5" @@ -35083,7 +35057,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", - "dev": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -35164,7 +35137,6 @@ "version": "5.4.11", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", - "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.21.3", @@ -35268,7 +35240,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -35282,7 +35253,6 @@ "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, "hasInstallScript": true, "license": "MIT", "bin": { @@ -35321,7 +35291,6 @@ "version": "4.29.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.29.1.tgz", "integrity": "sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==", - "dev": true, "license": "MIT", "dependencies": { "@types/estree": "1.0.6" diff --git a/packages/prisma/migrations/20250104024352_add_user_secondary_id/migration.sql b/packages/prisma/migrations/20250104024352_add_user_secondary_id/migration.sql new file mode 100644 index 000000000..b56409d70 --- /dev/null +++ b/packages/prisma/migrations/20250104024352_add_user_secondary_id/migration.sql @@ -0,0 +1,11 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "secondaryId" TEXT; + +-- Set all null secondaryId fields to a uuid +UPDATE "User" SET "secondaryId" = gen_random_uuid()::text WHERE "secondaryId" IS NULL; + +-- Restrict the User to required +ALTER TABLE "User" ALTER COLUMN "secondaryId" SET NOT NULL; + +-- CreateIndex +CREATE UNIQUE INDEX "User_secondaryId_key" ON "User"("secondaryId"); diff --git a/packages/prisma/migrations/20250104055239_add_better_auth_fields/migration.sql b/packages/prisma/migrations/20250104055239_add_better_auth_fields/migration.sql new file mode 100644 index 000000000..4750be24c --- /dev/null +++ b/packages/prisma/migrations/20250104055239_add_better_auth_fields/migration.sql @@ -0,0 +1,36 @@ +/* + Warnings: + + - Added the required column `updatedAt` to the `Account` table without a default value. This is not possible if the table is not empty. + - Added the required column `updatedAt` to the `Session` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "Account" ADD COLUMN "accessTokenExpiresAt" TIMESTAMP(3), +ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, +ADD COLUMN "password" TEXT, +ADD COLUMN "refreshTokenExpiresAt" TIMESTAMP(3), +ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL, +ALTER COLUMN "type" SET DEFAULT 'legacy'; + +-- AlterTable +ALTER TABLE "Session" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, +ADD COLUMN "ipAddress" TEXT, +ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL, +ADD COLUMN "userAgent" TEXT; + +-- AlterTable +ALTER TABLE "User" ADD COLUMN "image" TEXT, +ADD COLUMN "isEmailVerified" BOOLEAN NOT NULL DEFAULT false; + +-- CreateTable +CREATE TABLE "verification" ( + "id" TEXT NOT NULL, + "identifier" TEXT NOT NULL, + "value" TEXT NOT NULL, + "expiresAt" TIMESTAMP(3) NOT NULL, + "createdAt" TIMESTAMP(3), + "updatedAt" TIMESTAMP(3), + + CONSTRAINT "verification_pkey" PRIMARY KEY ("id") +); diff --git a/packages/prisma/migrations/20250104055250_migrate_documenso_users_to_accounts/migration.sql b/packages/prisma/migrations/20250104055250_migrate_documenso_users_to_accounts/migration.sql new file mode 100644 index 000000000..cf6185fba --- /dev/null +++ b/packages/prisma/migrations/20250104055250_migrate_documenso_users_to_accounts/migration.sql @@ -0,0 +1,28 @@ +-- Migrate DOCUMENSO users to have proper Account records +DO $$ +BEGIN + INSERT INTO "Account" ( + "id", + "userId", + "type", + "provider", + "providerAccountId", + "password", + "createdAt", + "updatedAt" + ) + SELECT + gen_random_uuid()::text, + u.id, + 'legacy', + 'credential', + u.email, + u.password, + CURRENT_TIMESTAMP, + CURRENT_TIMESTAMP + FROM "User" u + LEFT JOIN "Account" a ON a."userId" = u.id AND a."provider" = 'documenso' + WHERE + u."identityProvider" = 'DOCUMENSO' + AND a.id IS NULL; +END $$; diff --git a/packages/prisma/migrations/20250104070109_extract_two_factor_into_table/migration.sql b/packages/prisma/migrations/20250104070109_extract_two_factor_into_table/migration.sql new file mode 100644 index 000000000..61b97413c --- /dev/null +++ b/packages/prisma/migrations/20250104070109_extract_two_factor_into_table/migration.sql @@ -0,0 +1,32 @@ +-- CreateTable +CREATE TABLE "TwoFactor" ( + "id" TEXT NOT NULL, + "secret" TEXT NOT NULL, + "backupCodes" TEXT NOT NULL, + "userId" INTEGER NOT NULL, + + CONSTRAINT "TwoFactor_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "TwoFactor" ADD CONSTRAINT "TwoFactor_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +DO $$ +BEGIN + -- Then migrate two factor data + INSERT INTO "TwoFactor" ( + "secret", + "backupCodes", + "userId" + ) + SELECT + u."twoFactorSecret", + COALESCE(u."twoFactorBackupCodes", ''), + u.id + FROM "User" u + LEFT JOIN "TwoFactor" tf ON tf."userId" = u.id + WHERE + u."twoFactorSecret" IS NOT NULL + AND u."twoFactorEnabled" = true + AND tf.id IS NULL; +END $$; diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index efafbb3e6..446a9b26a 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -29,10 +29,12 @@ enum Role { model User { id Int @id @default(autoincrement()) + secondaryId String @unique @default(cuid()) name String? customerId String? @unique email String @unique emailVerified DateTime? + isEmailVerified Boolean @default(false) password String? source String? signature String? @@ -44,18 +46,22 @@ model User { avatarImageId String? disabled Boolean @default(false) - accounts Account[] - sessions Session[] - Document Document[] - Subscription Subscription[] - PasswordResetToken PasswordResetToken[] - ownedTeams Team[] - ownedPendingTeams TeamPending[] - teamMembers TeamMember[] - twoFactorSecret String? - twoFactorEnabled Boolean @default(false) + accounts Account[] + sessions Session[] + Document Document[] + Subscription Subscription[] + PasswordResetToken PasswordResetToken[] + ownedTeams Team[] + ownedPendingTeams TeamPending[] + teamMembers TeamMember[] + twoFactorEnabled Boolean @default(false) + + // Todo: Delete these after full auth migration. twoFactorBackupCodes String? - url String? @unique + twoFactorSecret String? + // End of Todo. + + url String? @unique profile UserProfile? VerificationToken VerificationToken[] @@ -67,9 +73,21 @@ model User { passkeys Passkey[] avatarImage AvatarImage? @relation(fields: [avatarImageId], references: [id], onDelete: SetNull) + image String? + + twofactors TwoFactor[] + @@index([email]) } +model TwoFactor { + id String @id @default(cuid()) + secret String + backupCodes String + userId Int + user User @relation(fields: [userId], references: [id], onDelete: Cascade) +} + model UserProfile { id String @id @default(cuid()) enabled Boolean @default(false) @@ -248,7 +266,6 @@ model Subscription { model Account { id String @id @default(cuid()) userId Int - type String provider String providerAccountId String refresh_token String? @db.Text @@ -256,12 +273,24 @@ model Account { expires_at Int? // Some providers return created_at so we need to make it optional created_at Int? - // Stops next-auth from crashing when dealing with AzureAD - ext_expires_in Int? - token_type String? scope String? id_token String? @db.Text - session_state String? + + // Betterauth + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + accessTokenExpiresAt DateTime? + refreshTokenExpiresAt DateTime? + password String? + + // Stops next-auth from crashing when dealing with AzureAD + ext_expires_in Int? + + // Todo: Remove these fields after auth migration. + type String @default("legacy") + token_type String? + session_state String? + // End of Todo. user User? @relation(fields: [userId], references: [id], onDelete: Cascade) @@ -274,6 +303,23 @@ model Session { userId Int expires DateTime user User? @relation(fields: [userId], references: [id], onDelete: Cascade) + + // Better auth fields. + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + ipAddress String? + userAgent String? +} + +model Verification { + id String @id @default(cuid()) + identifier String + value String + expiresAt DateTime + createdAt DateTime? + updatedAt DateTime? + + @@map("verification") } enum DocumentStatus {