import fastify from "fastify";
import { routes } from "./routes.js";
import { setupSwagger } from "./swagger.js";
import blippPlugin from "fastify-blipp";
import corsPlugin from "@fastify/cors";
import { getPort } from "./config.js";
import { fastifyRequestContext } from "@fastify/request-context";
import helmet from "@fastify/helmet";
import { bearerAuthentication } from "./authentication.js";
import bearerAuthPlugin from "@fastify/bearer-auth";
import authPlugin from "@fastify/auth";
import { autoSeed, stopData } from "../data/index.js";
import { commitAt, commitShort, name, packageIdentifier } from "../package.js";
import cookie from "@fastify/cookie";
import multipart from "@fastify/multipart";
import formbody from "@fastify/formbody";
import { errorHandler } from "../view/error.js";
import { parseStringFields } from "./body-parser.js";
import { getConfig, withConfig } from "../config/index.js";
import rawBody from "fastify-raw-body";
export async function createFastifyApplication() {
    const { COOKIE_SECRET } = process.env;
    if (!COOKIE_SECRET) {
        console.warn("Warning, COOKIE_SECRET not set in environment variables or .env");
    }
    const app = fastify({
        logger: true,
    });
    const register = app.register.bind(fastify);
    await register(cookie, {
        secret: COOKIE_SECRET || name,
        hook: "onRequest",
        parseOptions: {},
    });
    await register(rawBody, {
        global: false
    });
    await register(multipart);
    await register(formbody, {
        parser: parseStringFields,
    });
    await register(helmet, { contentSecurityPolicy: false });
    app.addHook("preValidation", async (request, response) => {
        if (request.headers.apikey && !request.headers.authorization) {
            request.headers.authorization = `bearer ${request.headers.apikey}`;
        }
    });
    await register(fastifyRequestContext, {
        hook: "preValidation",
        defaultStoreValues: {},
    });
    app.addHook("preValidation", async (request, response) => {
        request.requestContext.set("origin", `${request.protocol}://${request.hostname}`);
        response.header("X-Powered-By", packageIdentifier);
        // Some details about time since commit
        response.header("X-Source-Commit", commitShort);
        response.header("X-Source-Commit-At", commitAt);
    });
    await register(authPlugin);
    await register(bearerAuthPlugin, {
        keys: new Set(),
        auth: bearerAuthentication,
        addHook: false,
    });
    app.setErrorHandler(errorHandler);
    await register(blippPlugin);
    await register(corsPlugin);
    await setupSwagger(app);
    const { routes: providedRoutes, defaultRoutes } = getConfig();
    if (providedRoutes) {
        await register(providedRoutes);
    }
    // Allow removing default routes with config
    await register(defaultRoutes ?? routes);
    return app;
}
export async function listen(config) {
    if (config) {
        return withConfig(getConfig(config), () => listen());
    }
    const app = await createFastifyApplication();
    // Before we start, we should seed
    await autoSeed();
    const port = getPort();
    const { LISTEN_HOST } = process.env;
    await app.listen({ port, host: LISTEN_HOST });
    app.blipp();
    return async () => {
        await app.close();
        // close any opened connections
        await stopData();
    };
}
//# sourceMappingURL=listen.js.map