Advertisement
AdzeB

fastify-setup.ts

Mar 9th, 2025
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { FastifyInstance } from "fastify";
  2. import fastifySwagger from "@fastify/swagger";
  3. import fastifySwaggerUI from "@fastify/swagger-ui";
  4. import {
  5.   serializerCompiler,
  6.   validatorCompiler,
  7.   fastifyZodOpenApiPlugin,
  8.   fastifyZodOpenApiTransform,
  9.   fastifyZodOpenApiTransformObject,
  10. } from "fastify-zod-openapi";
  11. import {
  12.   MessageCode,
  13.   InternalMessageCode,
  14.   createErrorResponse,
  15. } from "../types/api-resource";
  16. import dbClient from "../db";
  17. import { logtoFastifyPlugin } from "./logto-fastify";
  18.  
  19. export async function setupFastify(
  20.   fastify: FastifyInstance,
  21.   options: {
  22.     serviceName: string;
  23.     serviceVersion: string;
  24.     setupRepositories?: (
  25.       fastify: FastifyInstance,
  26.       db: Awaited<ReturnType<typeof dbClient>>
  27.     ) => void;
  28.     logtoConfig?: {
  29.       jwksUrl: string;
  30.       issuer: string;
  31.       audience: string;
  32.     };
  33.   }
  34. ) {
  35.   // Register plugins
  36.   await fastify.register(fastifyZodOpenApiPlugin);
  37.   await fastify.register(fastifySwagger, {
  38.     openapi: {
  39.       info: {
  40.         title: `${options.serviceName} API`,
  41.         version: options.serviceVersion,
  42.       },
  43.       openapi: "3.0.3",
  44.       components: {
  45.         securitySchemes: {
  46.           bearerAuth: {
  47.             type: "http",
  48.             scheme: "bearer",
  49.             bearerFormat: "JWT",
  50.           },
  51.         },
  52.       },
  53.     },
  54.     transform: fastifyZodOpenApiTransform,
  55.     transformObject: fastifyZodOpenApiTransformObject,
  56.   });
  57.   await fastify.register(fastifySwaggerUI, {
  58.     routePrefix: "/documentation",
  59.   });
  60.  
  61.   // Register Logto plugin if config is provided
  62.   if (options.logtoConfig) {
  63.     await fastify.register(logtoFastifyPlugin, options.logtoConfig);
  64.   }
  65.  
  66.   fastify.setValidatorCompiler(validatorCompiler);
  67.   fastify.setSerializerCompiler(serializerCompiler);
  68.  
  69.   // Add this before registering routes
  70.   fastify.addHook("onReady", async () => {
  71.     const db = await dbClient();
  72.     fastify.decorate("db", db);
  73.  
  74.     // Setup service-specific repositories
  75.     if (options.setupRepositories) {
  76.       options.setupRepositories(fastify, db);
  77.     }
  78.   });
  79.  
  80.   // Error handler
  81.   fastify.setErrorHandler((error, request, reply) => {
  82.     if (error.validation) {
  83.       return reply.status(400).send(
  84.         createErrorResponse(
  85.           "Validation error",
  86.           MessageCode.BAD_REQUEST,
  87.           400,
  88.           InternalMessageCode.VALIDATION_ERROR,
  89.           error.validation.map((err) => ({
  90.             field: err.instancePath,
  91.             message: err.message || "Invalid value",
  92.           }))
  93.         )
  94.       );
  95.     }
  96.  
  97.     // Check for authentication errors
  98.     if (
  99.       error.name === "LogtoAuthenticationError" ||
  100.       (error as any).statusCode === 401
  101.     ) {
  102.       return reply
  103.         .status(401)
  104.         .send(
  105.           createErrorResponse(
  106.             error.message || "Unauthorized",
  107.             MessageCode.UNAUTHORIZED,
  108.             401,
  109.             InternalMessageCode.UNAUTHORIZED_REQUEST
  110.           )
  111.         );
  112.     }
  113.  
  114.     console.error("Error:", error);
  115.  
  116.     return reply
  117.       .status(500)
  118.       .send(
  119.         createErrorResponse(
  120.           "Internal server error",
  121.           MessageCode.INTERNAL_ERROR,
  122.           500,
  123.           InternalMessageCode.INTERNAL_ERROR
  124.         )
  125.       );
  126.   });
  127. }
  128.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement