Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { FastifyInstance } from "fastify";
- import fastifySwagger from "@fastify/swagger";
- import fastifySwaggerUI from "@fastify/swagger-ui";
- import {
- serializerCompiler,
- validatorCompiler,
- fastifyZodOpenApiPlugin,
- fastifyZodOpenApiTransform,
- fastifyZodOpenApiTransformObject,
- } from "fastify-zod-openapi";
- import {
- MessageCode,
- InternalMessageCode,
- createErrorResponse,
- } from "../types/api-resource";
- import dbClient from "../db";
- import { logtoFastifyPlugin } from "./logto-fastify";
- export async function setupFastify(
- fastify: FastifyInstance,
- options: {
- serviceName: string;
- serviceVersion: string;
- setupRepositories?: (
- fastify: FastifyInstance,
- db: Awaited<ReturnType<typeof dbClient>>
- ) => void;
- logtoConfig?: {
- jwksUrl: string;
- issuer: string;
- audience: string;
- };
- }
- ) {
- // Register plugins
- await fastify.register(fastifyZodOpenApiPlugin);
- await fastify.register(fastifySwagger, {
- openapi: {
- info: {
- title: `${options.serviceName} API`,
- version: options.serviceVersion,
- },
- openapi: "3.0.3",
- components: {
- securitySchemes: {
- bearerAuth: {
- type: "http",
- scheme: "bearer",
- bearerFormat: "JWT",
- },
- },
- },
- },
- transform: fastifyZodOpenApiTransform,
- transformObject: fastifyZodOpenApiTransformObject,
- });
- await fastify.register(fastifySwaggerUI, {
- routePrefix: "/documentation",
- });
- // Register Logto plugin if config is provided
- if (options.logtoConfig) {
- await fastify.register(logtoFastifyPlugin, options.logtoConfig);
- }
- fastify.setValidatorCompiler(validatorCompiler);
- fastify.setSerializerCompiler(serializerCompiler);
- // Add this before registering routes
- fastify.addHook("onReady", async () => {
- const db = await dbClient();
- fastify.decorate("db", db);
- // Setup service-specific repositories
- if (options.setupRepositories) {
- options.setupRepositories(fastify, db);
- }
- });
- // Error handler
- fastify.setErrorHandler((error, request, reply) => {
- if (error.validation) {
- return reply.status(400).send(
- createErrorResponse(
- "Validation error",
- MessageCode.BAD_REQUEST,
- 400,
- InternalMessageCode.VALIDATION_ERROR,
- error.validation.map((err) => ({
- field: err.instancePath,
- message: err.message || "Invalid value",
- }))
- )
- );
- }
- // Check for authentication errors
- if (
- error.name === "LogtoAuthenticationError" ||
- (error as any).statusCode === 401
- ) {
- return reply
- .status(401)
- .send(
- createErrorResponse(
- error.message || "Unauthorized",
- MessageCode.UNAUTHORIZED,
- 401,
- InternalMessageCode.UNAUTHORIZED_REQUEST
- )
- );
- }
- console.error("Error:", error);
- return reply
- .status(500)
- .send(
- createErrorResponse(
- "Internal server error",
- MessageCode.INTERNAL_ERROR,
- 500,
- InternalMessageCode.INTERNAL_ERROR
- )
- );
- });
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement