/* eslint-disable react-hooks/rules-of-hooks */ import { createYoga, Plugin, createSchema } from "graphql-yoga"; import { EnvelopArmorPlugin } from "@escape.tech/graphql-armor"; import resolvers from "@/graphql/resolvers"; import typeDefs from "@/graphql/types"; interface NextContext { params: Promise>; } const environment = process.env.NODE_ENV || "development"; const isValidApiKey = (apiKey: string): boolean => { const envApiKey = process.env.NEXT_PUBLIC_API_TOKEN || process.env.API_TOKEN; return apiKey === envApiKey; }; function useApiKey(): Plugin { return { async onRequest({ request, endResponse, fetchAPI }) { const apiKey = await request.headers.get("x-api-key"); if (environment === "production") { if (!apiKey || apiKey == null) { endResponse( new fetchAPI.Response( JSON.stringify({ message: "No API Key provided" }), { status: 401, headers: { "Content-Type": "application/json" } } ) ); } if (apiKey !== null && !(await isValidApiKey(apiKey))) { endResponse( new fetchAPI.Response( JSON.stringify({ message: "Invalid API Key" }), { status: 403, headers: { "Content-Type": "application/json" } } ) ); } } } }; } const { handleRequest } = createYoga({ schema: createSchema({ typeDefs: typeDefs, resolvers: resolvers }), // While using Next.js file convention for routing, we need to configure Yoga to use the correct endpoint graphqlEndpoint: "/api/graphql", // Yoga needs to know how to create a valid Next response fetchAPI: { Response }, plugins: [useApiKey(), EnvelopArmorPlugin()], graphiql: environment !== "production" ? true : false }); export { handleRequest as GET, handleRequest as POST, handleRequest as OPTIONS };