Files
no-twitter-bot-stats/src/app/api/graphql/route.ts
Lucid 9146a0c340
All checks were successful
Main / build-and-push-docker-image (20.x) (push) Successful in 11m57s
Fixed env variables
2025-12-06 22:19:22 -05:00

73 lines
2.0 KiB
TypeScript

/* 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<Record<string, string>>;
}
const environment = process.env.NODE_ENV || "development";
const isValidApiKey = (apiKey: string): boolean => {
const envApiKey =
process.env.API_TOKEN || process.env.NEXT_PUBLIC_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<NextContext>({
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
};