import fastify from 'fastify' import formBodyPlugin from '@fastify/formbody' import urlDataPlugin from '@fastify/url-data' import fastifySwagger from '@fastify/swagger' import fastifyMetrics from 'fastify-metrics' import helmet from '@fastify/helmet' import yaml from 'js-yaml' import fs from 'fs' import versionHandler from './handlers/version.js' import manifestsPlugin from './plugins/manifests.js' import metadataPlugin from './plugins/metadata.js' import redirectsPlugin from './plugins/redirects.js' import serveFilePlugin from './plugins/serve-files.js' import { logger } from './logger.js' const swaggerDocument = yaml.load(fs.readFileSync('./src/swagger.yaml', 'utf8')) export async function createApp (basePath) { const app = fastify({ logger, connectionTimeout: 30000, disableRequestLogging: true }) app.addHook('onError', (req, reply, err, done) => { const responseTime = reply.getResponseTime() reply.log.error({ res: reply, err, responseTime }, 'request errored') done() }) app.addHook('onResponse', (req, reply, done) => { const responseTime = reply.getResponseTime() reply.log.debug({ res: reply, responseTime }, 'request completed') done() }) await app.register(formBodyPlugin) await app.register(urlDataPlugin) await app.register(helmet, { contentSecurityPolicy: false, crossOriginEmbedderPolicy: false, originAgentCluster: false, crossOriginOpenerPolicy: { policy: 'same-origin-allow-popups' } }) const swaggerConfiguration = { exposeRoute: process.env.EXPOSE_API_DOCS === 'true', routePrefix: '/api-docs', prefix: process.env.APP_ROOT, swagger: swaggerDocument } await app.register(fastifySwagger, swaggerConfiguration) await app.register(fastifyMetrics, { // do not expose metrics endpoint endpoint: null, routeMetrics: { routeBlacklist: ['/api-docs'] } }) await app.addHook('preHandler', versionHandler) await app.register(manifestsPlugin, { prefix: process.env.APP_ROOT }) await app.register(metadataPlugin, { prefix: process.env.APP_ROOT }) await app.register(redirectsPlugin, { prefix: process.env.APP_ROOT }) if (process.env.APP_ROOT.length > 1) { app.get(process.env.APP_ROOT.slice(0, -1), async (req, res) => { res.redirect(process.env.APP_ROOT) }) } await app.register(serveFilePlugin) return app }