From c190d368de004dcb37ce7eee0227916df49fe483 Mon Sep 17 00:00:00 2001 From: lnn0q Date: Sun, 6 Apr 2025 19:57:14 +0300 Subject: [PATCH] fixed 'added 'refreshToken', converted to 'httpOnly', added SSL fixed 'gql-types' generator --- .gitignore | 12 + .opinionatedignore | 32 ++- app/client/fragments.tsx | 15 +- app/client/hooks/useIdentity.tsx | 4 +- app/client/main.tsx | 38 ++- app/client/pages/register.tsx | 2 +- app/server/graphql/resolvers/auth/login.ts | 25 +- app/server/graphql/resolvers/auth/logout.ts | 0 .../graphql/resolvers/auth/refreshToken.ts | 36 +++ app/server/graphql/resolvers/auth/signUp.ts | 4 +- .../graphql/resolvers/booksManyResolver.ts | 2 +- app/server/graphql/schema.graphql | 5 +- app/server/identity.ts | 18 +- app/server/main.ts | 17 +- app/server/prisma/schema.prisma | 2 +- codegen.ts | 2 +- package-lock.json | 268 +++++++++--------- package.json | 6 +- tsconfig.json | 2 +- vite.config.ts | 3 + 20 files changed, 314 insertions(+), 179 deletions(-) create mode 100644 app/server/graphql/resolvers/auth/logout.ts create mode 100644 app/server/graphql/resolvers/auth/refreshToken.ts diff --git a/.gitignore b/.gitignore index 6c4888e..2e25ea2 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ lerna-debug.log* node_modules dist dist-ssr +certs/* *.local .env __generated__/ @@ -26,3 +27,14 @@ vite.config.ts.timestamp-*.mjs *.njsproj *.sln *.sw? + +app/client/components/ui +app/client/assets + +vite.config.ts.timestamp-* + +dist + +__generated__/ + +certs diff --git a/.opinionatedignore b/.opinionatedignore index 8eae475..1ee498e 100644 --- a/.opinionatedignore +++ b/.opinionatedignore @@ -1,4 +1,32 @@ -app/client/components/ui -app/client/assets +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* +logs/ + +dist/ +dist-ssr/ +__generated__/ + +node_modules/ +certs/ + +.env +*.local + +.vscode/* +!.vscode/extensions.json +.idea/ +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +app/client/components/ui/ +app/client/assets/ vite.config.ts.timestamp-*.mjs diff --git a/app/client/fragments.tsx b/app/client/fragments.tsx index 9ca33e2..0d12ce3 100644 --- a/app/client/fragments.tsx +++ b/app/client/fragments.tsx @@ -3,12 +3,13 @@ import { gql } from '@apollo/client'; export const sessionFragment = gql` fragment Session on Session { accessToken - refreshToken { - token - maxAge - secure - httpOnly - sameSite - } } `; + +// refreshToken { +// token +// maxAge +// secure +// httpOnly +// sameSite +// } diff --git a/app/client/hooks/useIdentity.tsx b/app/client/hooks/useIdentity.tsx index 0ff2f7a..59e890f 100644 --- a/app/client/hooks/useIdentity.tsx +++ b/app/client/hooks/useIdentity.tsx @@ -1,3 +1,3 @@ -interface UseIdentityProps {} +// interface UseIdentityProps {} -export function useIdentity(props: UseIdentityProps) {} +// export function useIdentity(props: UseIdentityProps) {} diff --git a/app/client/main.tsx b/app/client/main.tsx index 1ec19c3..895b468 100644 --- a/app/client/main.tsx +++ b/app/client/main.tsx @@ -1,4 +1,5 @@ -import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client'; +import { ApolloClient, ApolloProvider, HttpLink, InMemoryCache, from } from '@apollo/client'; +import { onError } from '@apollo/client/link/error'; import '@client/assets/styles/index.css'; import '@client/assets/styles/nerd-fonts-icons.css'; import { Provider } from '@client/components/ui/provider'; @@ -8,8 +9,8 @@ import { StrictMode, createContext, useState } from 'react'; import ReactDOM from 'react-dom/client'; // TanStackRouter - Import the generated route tree -import { routeTree } from './routeTree.gen'; import { Session } from 'inspector'; +import { routeTree } from './routeTree.gen'; // Create a new router instance const router = createRouter({ routeTree }); @@ -22,25 +23,43 @@ declare module '@tanstack/react-router' { } // Environment +const MODE = import.meta.env.VITE_MODE || 'prod'; +const isProd = MODE === 'prod'; + const HOST = import.meta.env.VITE_HOST || 'localhost'; const PORT = import.meta.env.VITE_PORT || '3000'; -const uri = `http://${HOST}:${PORT}/graphql`; +const uri = `https://${HOST}:${PORT}/graphql`; // Auth context export const AuthContext = createContext(null); function App() { - const sessionRaw = localStorage.getItem('session'); - const session: Session | null = sessionRaw !== null ? JSON.parse(sessionRaw) : null; - - const [authHeaders, setAuthHeaders] = useState(session); + const [authHeaders, setAuthHeaders] = useState(null); const AuthProvider = AuthContext.Provider; + // if (authHeaders == null) refreshToken(); + + const httpLink = new HttpLink({ + uri, + credentials: 'include', + headers: authHeaders != null ? { authorization: JSON.stringify(authHeaders) } : undefined + }); + + const errorLink = onError(({ graphQLErrors, networkError }) => { + if (graphQLErrors) + graphQLErrors.forEach(({ message, locations, path }) => + console.error(`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`) + ); + + if (networkError) console.error(`[Network error]: ${networkError}`); + }); + const client = new ApolloClient({ uri, + link: isProd ? undefined : from([errorLink, httpLink]), cache: new InMemoryCache(), - connectToDevTools: true, - headers: authHeaders != null ? { authorization: JSON.stringify(authHeaders) } : undefined + connectToDevTools: !isProd, + credentials: 'include' }); return ( @@ -49,7 +68,6 @@ function App() { value={{ authHeaders, setHeaders: (session: Session) => { - localStorage.setItem('session', JSON.stringify(session)); setAuthHeaders(session); } }} diff --git a/app/client/pages/register.tsx b/app/client/pages/register.tsx index 5ba7b0e..b008f05 100644 --- a/app/client/pages/register.tsx +++ b/app/client/pages/register.tsx @@ -109,7 +109,7 @@ function SignUpForm() { } const mutation = gql` - mutation AuthSignUp($input: RegisterInput!) { + mutation AuthSignUp($input: SignUpInput!) { signUp(input: $input) } `; diff --git a/app/server/graphql/resolvers/auth/login.ts b/app/server/graphql/resolvers/auth/login.ts index cd8d25c..c43c8ba 100644 --- a/app/server/graphql/resolvers/auth/login.ts +++ b/app/server/graphql/resolvers/auth/login.ts @@ -7,7 +7,7 @@ import jwt from 'jsonwebtoken'; export async function LoginResolver( _: any, { input }: MutationLoginArgs, - { identity }: IdentityContext + { req, res, identity }: IdentityContext ): Promise { const error = 'Invalid password or email'; @@ -36,14 +36,21 @@ export async function LoginResolver( data: { refreshToken } }); + res.cookie('jwt', refreshToken, { + httpOnly: true, + sameSite: 'none', + secure: true, + maxAge: 24 * 60 * 60 * 1000 + }); + return { - accessToken, - refreshToken: { - token: refreshToken, - httpOnly: true, - secure: true, - maxAge: 24 * 60 * 60 * 1000, - sameSite: 'None' - } + accessToken + // refreshToken: { + // token: refreshToken, + // httpOnly: true, + // secure: true, + // maxAge: 24 * 60 * 60 * 1000, + // sameSite: 'None' + // } }; } diff --git a/app/server/graphql/resolvers/auth/logout.ts b/app/server/graphql/resolvers/auth/logout.ts new file mode 100644 index 0000000..e69de29 diff --git a/app/server/graphql/resolvers/auth/refreshToken.ts b/app/server/graphql/resolvers/auth/refreshToken.ts new file mode 100644 index 0000000..a52c6fa --- /dev/null +++ b/app/server/graphql/resolvers/auth/refreshToken.ts @@ -0,0 +1,36 @@ +import { IdentityContext } from '@app/server/identity'; +import { prisma } from '@app/server/prisma/client'; +import { Session } from '@generated/types'; +import jwt from 'jsonwebtoken'; + +export async function RefreshTokenResolver( + _: any, + { req, res, identity }: IdentityContext +): Promise { + const accessTokenSecret = process.env.ACCESS_TOKEN_SECRET; + const refreshTokenSecret = process.env.REFRESH_TOKEN_SECRET; + if (accessTokenSecret == null || refreshTokenSecret == null) throw new Error('No secrets found.'); + + const cookie: { jwt?: string | null } = req.cookies; + if (cookie == null || cookie.jwt == null) throw new Error('Unauthorized.'); + + const refreshToken = cookie.jwt; + + const user = await prisma.user.findUniqueOrThrow({ + where: { refreshToken }, + select: { id: true } + }); + + const decoded = jwt.verify(refreshToken, accessTokenSecret) as { + userId: string; + iat: number; + exp: number; + }; + + if (user.id !== decoded.userId) throw new Error('Invalid token.'); + const accessToken = jwt.sign({ userId: user.id }, accessTokenSecret, { + expiresIn: '30s' + }); + + return { accessToken }; +} diff --git a/app/server/graphql/resolvers/auth/signUp.ts b/app/server/graphql/resolvers/auth/signUp.ts index 7f9d3f5..a2ad7b6 100644 --- a/app/server/graphql/resolvers/auth/signUp.ts +++ b/app/server/graphql/resolvers/auth/signUp.ts @@ -1,11 +1,11 @@ import { IdentityContext } from '@app/server/identity'; import { prisma, uuid } from '@app/server/prisma/client'; -import { MutationRegisterArgs } from '@generated/types'; +import { MutationSignUpArgs } from '@generated/types'; import bcrypt from 'bcrypt'; export async function SignUpResolver( _: any, - { input }: MutationRegisterArgs, + { input }: MutationSignUpArgs, { identity }: IdentityContext ): Promise { const existingUsername = await prisma.user.findUnique({ diff --git a/app/server/graphql/resolvers/booksManyResolver.ts b/app/server/graphql/resolvers/booksManyResolver.ts index 84dc218..b4ac9ec 100644 --- a/app/server/graphql/resolvers/booksManyResolver.ts +++ b/app/server/graphql/resolvers/booksManyResolver.ts @@ -19,6 +19,6 @@ export async function BooksManyResolver( __: any, { identity }: IdentityContext ): Promise { - if (identity == null) throw Error('Unauthorized'); + if (identity == null) throw new Error('Unauthorized'); return books; } diff --git a/app/server/graphql/schema.graphql b/app/server/graphql/schema.graphql index cd3151c..ef31561 100644 --- a/app/server/graphql/schema.graphql +++ b/app/server/graphql/schema.graphql @@ -7,7 +7,7 @@ type Query { type Mutation { login(input: LoginInput!): Session! - signUp(input: RegisterInput!): Void + signUp(input: SignUpInput!): Void } input LoginInput { @@ -15,7 +15,7 @@ input LoginInput { password: String! } -input RegisterInput { +input SignUpInput { email: String! username: String! password: String! @@ -23,7 +23,6 @@ input RegisterInput { type Session { accessToken: String! - refreshToken: RefreshToken! } type RefreshToken { diff --git a/app/server/identity.ts b/app/server/identity.ts index 42cbde3..8472388 100644 --- a/app/server/identity.ts +++ b/app/server/identity.ts @@ -5,6 +5,8 @@ import { prisma } from './prisma/client'; import { Session } from '@generated/types'; export interface IdentityContext { + req: Request; + res: Response; identity?: { id: string; username: string; @@ -19,11 +21,10 @@ export async function getIdentityContext({ res: Response; }): Promise { const authHeaders = req.headers.authorization; - if (authHeaders == null) return {}; + if (authHeaders == null) return { req, res }; const session: Session = JSON.parse(authHeaders); - console.log(session); - const accessToken = session.accessToken; + const { accessToken } = session; const accessTokenSecret = process.env.ACCESS_TOKEN_SECRET; if (accessTokenSecret == null) throw new Error('No `accessToken`.'); @@ -43,5 +44,14 @@ export async function getIdentityContext({ } }); if (identity == null) throw new Error("Couldn't find the user."); - return { identity }; + return { req, res, identity }; } + +/* throw new GraphQLError('User is not authenticated', { + extensions: { + code: 'UNAUTHENTICATED', + http: { status: 401 } + } + }); */ + +// throw new GraphQLError(`${error}`); diff --git a/app/server/main.ts b/app/server/main.ts index 27c7163..25a731b 100644 --- a/app/server/main.ts +++ b/app/server/main.ts @@ -5,20 +5,25 @@ import cors from 'cors'; import 'dotenv/config'; import express from 'express'; import fs from 'fs'; -import http from 'http'; +import https from 'https'; import path from 'path'; import ViteExpress from 'vite-express'; +import { Mutation, Query } from './graphql/graphql'; import { getIdentityContext, IdentityContext } from './identity'; -import { Mutation, Query } from './graphql/graphql'; +const MODE = process.env.VITE_MODE || 'prod'; +const isProd = MODE === 'prod'; const __dirname = import.meta.dirname; const HOST = process.env.VITE_HOST || 'localhost'; const PORT = parseInt(process.env.VITE_PORT || '3000'); const MOTD = `\n\n\n\x1b[35m-server is listening at...-\x1b[0m\n\nhttp://${HOST}:${PORT}\nhttp://localhost:${PORT}\n\n\n`; +const key = fs.readFileSync(path.join(__dirname + '../../../certs/selfsigned.key')); +const cert = fs.readFileSync(path.join(__dirname + '../../../certs/selfsigned.crt')); + const app = express(); -const server = http.createServer(app); +const server = https.createServer({ key, cert }, app); const typeDefs = fs.readFileSync(path.join(__dirname, 'graphql', 'schema.graphql'), 'utf8'); @@ -31,12 +36,12 @@ const resolvers = { const apollo = new ApolloServer({ typeDefs, resolvers, + introspection: !isProd, plugins: [ApolloServerPluginDrainHttpServer({ httpServer: server })], - formatError: (formattedError, error) => { + formatError: formattedError => { process.stdout.write('\n```\n'); - console.error(`${error}`); + console.error(formattedError); process.stdout.write('\n```\n'); - return formattedError; } }); diff --git a/app/server/prisma/schema.prisma b/app/server/prisma/schema.prisma index 060e28b..7c46089 100644 --- a/app/server/prisma/schema.prisma +++ b/app/server/prisma/schema.prisma @@ -14,7 +14,7 @@ model User { username String @unique @db.VarChar(255) password String - refreshToken String? @db.VarChar(255) + refreshToken String? @unique @db.VarChar(255) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt diff --git a/codegen.ts b/codegen.ts index 791979e..3928afd 100644 --- a/codegen.ts +++ b/codegen.ts @@ -7,8 +7,8 @@ const config: CodegenConfig = { documents: ['app/client/fragments', 'app/client/**/*.tsx'], generates: { './__generated__/': { + preset: 'client', presetConfig: { - preset: 'client', gqlTagName: 'gql' }, plugins: ['typescript', 'typescript-resolvers', 'typescript-resolvers'] diff --git a/package-lock.json b/package-lock.json index 7d49fd7..a55198a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@tanstack/react-router": "^1.85.0", "@tanstack/router-vite-plugin": "^1.84.4", "@types/cors": "^2.8.17", + "apollo-link-logger": "^2.0.1", "bcrypt": "^5.1.1", "cookie-parser": "^1.4.7", "cors": "^2.8.5", @@ -800,25 +801,25 @@ } }, "node_modules/@babel/helpers": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", - "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", + "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", "license": "MIT", "dependencies": { - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.0" + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", - "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", + "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", "license": "MIT", "dependencies": { - "@babel/types": "^7.26.0" + "@babel/types": "^7.27.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -1324,9 +1325,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", - "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", + "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -1336,14 +1337,14 @@ } }, "node_modules/@babel/template": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", - "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", + "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" @@ -1368,9 +1369,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", - "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", + "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -2409,9 +2410,9 @@ "license": "MIT" }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", - "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", + "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", "cpu": [ "ppc64" ], @@ -2425,9 +2426,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", - "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz", + "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", "cpu": [ "arm" ], @@ -2441,9 +2442,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", - "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz", + "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", "cpu": [ "arm64" ], @@ -2457,9 +2458,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", - "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz", + "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", "cpu": [ "x64" ], @@ -2473,9 +2474,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", - "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz", + "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", "cpu": [ "arm64" ], @@ -2489,9 +2490,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", - "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz", + "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", "cpu": [ "x64" ], @@ -2505,9 +2506,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", - "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz", + "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", "cpu": [ "arm64" ], @@ -2521,9 +2522,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", - "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz", + "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", "cpu": [ "x64" ], @@ -2537,9 +2538,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", - "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz", + "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", "cpu": [ "arm" ], @@ -2553,9 +2554,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", - "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz", + "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", "cpu": [ "arm64" ], @@ -2569,9 +2570,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", - "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz", + "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", "cpu": [ "ia32" ], @@ -2585,9 +2586,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", - "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz", + "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", "cpu": [ "loong64" ], @@ -2601,9 +2602,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", - "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz", + "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", "cpu": [ "mips64el" ], @@ -2617,9 +2618,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", - "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz", + "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", "cpu": [ "ppc64" ], @@ -2633,9 +2634,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", - "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz", + "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", "cpu": [ "riscv64" ], @@ -2649,9 +2650,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", - "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz", + "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", "cpu": [ "s390x" ], @@ -2665,9 +2666,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", - "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz", + "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", "cpu": [ "x64" ], @@ -2681,9 +2682,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", - "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz", + "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", "cpu": [ "arm64" ], @@ -2697,9 +2698,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", - "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz", + "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", "cpu": [ "x64" ], @@ -2713,9 +2714,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", - "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz", + "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", "cpu": [ "arm64" ], @@ -2729,9 +2730,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", - "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz", + "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", "cpu": [ "x64" ], @@ -2745,9 +2746,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", - "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz", + "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", "cpu": [ "x64" ], @@ -2761,9 +2762,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", - "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz", + "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", "cpu": [ "arm64" ], @@ -2777,9 +2778,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", - "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz", + "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", "cpu": [ "ia32" ], @@ -2793,9 +2794,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", - "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz", + "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", "cpu": [ "x64" ], @@ -7342,6 +7343,19 @@ "node": ">= 8" } }, + "node_modules/apollo-link-logger": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/apollo-link-logger/-/apollo-link-logger-2.0.1.tgz", + "integrity": "sha512-4KkdwCqWtlOc0vx0W/5o+UfotyZtcJZicraKNyo2KTaCmAGSJ8vDnNRyDlv6o5XtSgdv4NA36cSe6dt49OkGWA==", + "license": "MIT", + "engines": { + "node": ">= 10", + "npm": "> 3" + }, + "peerDependencies": { + "@apollo/client": "^3.0.0" + } + }, "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -9223,9 +9237,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", - "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", + "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", "hasInstallScript": true, "license": "MIT", "bin": { @@ -9235,31 +9249,31 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.1", - "@esbuild/android-arm": "0.25.1", - "@esbuild/android-arm64": "0.25.1", - "@esbuild/android-x64": "0.25.1", - "@esbuild/darwin-arm64": "0.25.1", - "@esbuild/darwin-x64": "0.25.1", - "@esbuild/freebsd-arm64": "0.25.1", - "@esbuild/freebsd-x64": "0.25.1", - "@esbuild/linux-arm": "0.25.1", - "@esbuild/linux-arm64": "0.25.1", - "@esbuild/linux-ia32": "0.25.1", - "@esbuild/linux-loong64": "0.25.1", - "@esbuild/linux-mips64el": "0.25.1", - "@esbuild/linux-ppc64": "0.25.1", - "@esbuild/linux-riscv64": "0.25.1", - "@esbuild/linux-s390x": "0.25.1", - "@esbuild/linux-x64": "0.25.1", - "@esbuild/netbsd-arm64": "0.25.1", - "@esbuild/netbsd-x64": "0.25.1", - "@esbuild/openbsd-arm64": "0.25.1", - "@esbuild/openbsd-x64": "0.25.1", - "@esbuild/sunos-x64": "0.25.1", - "@esbuild/win32-arm64": "0.25.1", - "@esbuild/win32-ia32": "0.25.1", - "@esbuild/win32-x64": "0.25.1" + "@esbuild/aix-ppc64": "0.25.2", + "@esbuild/android-arm": "0.25.2", + "@esbuild/android-arm64": "0.25.2", + "@esbuild/android-x64": "0.25.2", + "@esbuild/darwin-arm64": "0.25.2", + "@esbuild/darwin-x64": "0.25.2", + "@esbuild/freebsd-arm64": "0.25.2", + "@esbuild/freebsd-x64": "0.25.2", + "@esbuild/linux-arm": "0.25.2", + "@esbuild/linux-arm64": "0.25.2", + "@esbuild/linux-ia32": "0.25.2", + "@esbuild/linux-loong64": "0.25.2", + "@esbuild/linux-mips64el": "0.25.2", + "@esbuild/linux-ppc64": "0.25.2", + "@esbuild/linux-riscv64": "0.25.2", + "@esbuild/linux-s390x": "0.25.2", + "@esbuild/linux-x64": "0.25.2", + "@esbuild/netbsd-arm64": "0.25.2", + "@esbuild/netbsd-x64": "0.25.2", + "@esbuild/openbsd-arm64": "0.25.2", + "@esbuild/openbsd-x64": "0.25.2", + "@esbuild/sunos-x64": "0.25.2", + "@esbuild/win32-arm64": "0.25.2", + "@esbuild/win32-ia32": "0.25.2", + "@esbuild/win32-x64": "0.25.2" } }, "node_modules/esbuild-register": { @@ -15401,9 +15415,9 @@ } }, "node_modules/vite": { - "version": "5.4.14", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", - "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", + "version": "5.4.16", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.16.tgz", + "integrity": "sha512-Y5gnfp4NemVfgOTDQAunSD4346fal44L9mszGGY/e+qxsRT5y1sMlS/8tiQ8AFAp+MFgYNSINdfEchJiPm41vQ==", "devOptional": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index f6b700a..a9f64ec 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,10 @@ "version": "0.0.0", "type": "module", "scripts": { - "dev": "nodemon -w app/server -x tsx app/server/main.ts", - "start": "NODE_ENV=production tsx app/server/main.ts", + "dev": "VITE_MODE=dev nodemon -w app/server -x tsx app/server/main.ts", + "start": "NODE_ENV=production VITE_MODE=prod tsx app/server/main.ts", "build": "vite build", + "genssl": "openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./certs/selfsigned.key -out ./certs/selfsigned.crt", "gql-types": "graphql-codegen --config codegen.ts", "checkup": "opinionated checkup", "prisma": "prisma", @@ -24,6 +25,7 @@ "@tanstack/react-router": "^1.85.0", "@tanstack/router-vite-plugin": "^1.84.4", "@types/cors": "^2.8.17", + "apollo-link-logger": "^2.0.1", "bcrypt": "^5.1.1", "cookie-parser": "^1.4.7", "cors": "^2.8.5", diff --git a/tsconfig.json b/tsconfig.json index ffbe4d4..5582c57 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,5 +23,5 @@ "@root/*": ["./*"] } }, - "exclude": ["./app/client/components/ui", "./app/client/assets", "./__generated__/graphql.ts"] + "exclude": ["./app/client/components/ui", "./app/client/assets", "./__generated__/*", "./dist"] } diff --git a/vite.config.ts b/vite.config.ts index 199d875..62b5f67 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -6,5 +6,8 @@ import tsConfigPaths from 'vite-tsconfig-paths'; // https://vitejs.dev/config/ export default defineConfig({ + build: { + sourcemap: true + }, plugins: [TanStackRouterVite(), viteReact(), tsConfigPaths()] });