import { ApolloServer } from '@apollo/server'; import { expressMiddleware } from '@apollo/server/express4'; import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer'; import cors from 'cors'; import 'dotenv/config'; import express, { Request, Response } from 'express'; import fs from 'fs'; import http from 'http'; import jwt from 'jsonwebtoken'; import path from 'path'; import ViteExpress from 'vite-express'; import { Mutation, Query } from './graphql/graphql'; import { prisma } from './prisma/client'; 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 app = express(); const server = http.createServer(app); const typeDefs = fs.readFileSync(path.join(__dirname, 'graphql', 'schema.graphql'), 'utf8'); const resolvers = { Query, Mutation // Subscription, }; interface IdentityContext { authScope?: String; } const apollo = new ApolloServer({ typeDefs, resolvers, plugins: [ApolloServerPluginDrainHttpServer({ httpServer: server })] }); await apollo.start(); app.use( '/graphql', cors(), express.json(), expressMiddleware(apollo, { context: getUser }) ); await new Promise(resolve => server.listen({ hostname: HOST, port: PORT }, resolve)); process.stdout.write(MOTD); ViteExpress.bind(app, server); async function getUser({ req, res }: { req: Request; res: Response }) { const authHeader = req.headers.authorization; if (!authHeader) return { identity: null }; const token = authHeader.split(' ')[1]; const accessTokenSecret = process.env.ACCESS_TOKEN_SECRET; if (accessTokenSecret == null) throw Error('No `accessToken`'); const decoded = jwt.verify(token, accessTokenSecret) as { userId: string }; const identity = await prisma.user.findUnique({ where: { id: decoded.userId } }); return { identity }; }