133 lines
3.6 KiB
TypeScript
133 lines
3.6 KiB
TypeScript
import { logInfo } from "@dpu/shared/dist/logger.js";
|
|
import fastifySwagger from "@fastify/swagger";
|
|
import fastifySwaggerUi from "@fastify/swagger-ui";
|
|
import type { FastifyReply, FastifyRequest } from "fastify";
|
|
import Fastify from "fastify";
|
|
import fastifyAxios from "fastify-axios";
|
|
import {
|
|
jsonSchemaTransform,
|
|
serializerCompiler,
|
|
validatorCompiler,
|
|
type ZodTypeProvider,
|
|
} from "fastify-type-provider-zod";
|
|
import { SwaggerTheme, SwaggerThemeNameEnum } from "swagger-themes";
|
|
import { z } from "zod";
|
|
import { Config } from "./config.js";
|
|
import { HomeAssistantClient } from "./homeassistant/client.js";
|
|
import { homeAssistantRoutes } from "./homeassistant/routes.js";
|
|
import { HomeAssistantService } from "./homeassistant/service.js";
|
|
import { TidalClient } from "./tidal/client.js";
|
|
import { TidalService } from "./tidal/service.js";
|
|
import { tidalRoutes } from "./tidal/routes.js";
|
|
import { sseRoutes } from "./sse/routes.js";
|
|
import { SseService } from "@dpu/shared";
|
|
import { HomepageService } from "./homepage/service.js";
|
|
import { homepageRoutes } from "./homepage/routes.js";
|
|
import fastifySSE from "@fastify/sse";
|
|
|
|
const fastify = Fastify().withTypeProvider<ZodTypeProvider>();
|
|
|
|
fastify.setValidatorCompiler(validatorCompiler);
|
|
fastify.setSerializerCompiler(serializerCompiler);
|
|
|
|
await fastify.register(fastifySwagger, {
|
|
openapi: {
|
|
info: {
|
|
title: "DPU API",
|
|
description: "API Documentation",
|
|
version: "1.0.0",
|
|
},
|
|
servers: [
|
|
{ url: "http://localhost:8080", description: "dev" },
|
|
{ url: "https://dpu.dariusbag.dev/api", description: "prod" },
|
|
],
|
|
},
|
|
transform: jsonSchemaTransform,
|
|
});
|
|
|
|
const theme = new SwaggerTheme();
|
|
const content = theme.getBuffer(SwaggerThemeNameEnum.ONE_DARK);
|
|
|
|
await fastify.register(fastifySwaggerUi, {
|
|
routePrefix: "/docs",
|
|
indexPrefix: `${Config.env_dev ? "" : "/api"}`,
|
|
uiConfig: {
|
|
docExpansion: "list",
|
|
deepLinking: false,
|
|
},
|
|
theme: {
|
|
css: [{ filename: "theme.css", content: content }],
|
|
},
|
|
});
|
|
|
|
await fastify.register(fastifyAxios, {
|
|
clients: {
|
|
homeassistant: {
|
|
baseURL: Config.homeassistant.api_url,
|
|
headers: {
|
|
Authorization: `Bearer ${Config.homeassistant.api_token}`,
|
|
},
|
|
},
|
|
tidal: {
|
|
baseURL: `${Config.tidal.host}:${Config.tidal.port}`,
|
|
},
|
|
},
|
|
});
|
|
|
|
await fastify.register(fastifySSE);
|
|
|
|
const haClient = new HomeAssistantClient(fastify.axios.homeassistant);
|
|
const haService = new HomeAssistantService(haClient);
|
|
|
|
const tidalClient = new TidalClient(fastify.axios.tidal);
|
|
const tidalService = new TidalService(tidalClient);
|
|
|
|
const sseService = new SseService();
|
|
|
|
const hpService = new HomepageService(haService, tidalService, sseService);
|
|
|
|
async function verifyAPIKey(
|
|
request: FastifyRequest,
|
|
reply: FastifyReply,
|
|
): Promise<void> {
|
|
const apiKey = request.headers["x-api-key"];
|
|
|
|
if (!apiKey || apiKey !== Config.api_key) {
|
|
logInfo("POST Request with wrong API key received");
|
|
return reply.code(401).send({ error: "Invalid API key" });
|
|
}
|
|
}
|
|
|
|
const port = parseInt(Config.port, 10);
|
|
|
|
// Register routes
|
|
await fastify.register(homeAssistantRoutes, { haService, verifyAPIKey });
|
|
await fastify.register(tidalRoutes, { tidalService, verifyAPIKey });
|
|
await fastify.register(sseRoutes, { sseService, verifyAPIKey });
|
|
await fastify.register(homepageRoutes, { hpService, verifyAPIKey });
|
|
|
|
fastify.get(
|
|
"/ping",
|
|
{
|
|
schema: {
|
|
description: "Health check endpoint",
|
|
tags: ["default"],
|
|
response: {
|
|
200: z.literal("pong"),
|
|
},
|
|
},
|
|
},
|
|
async (_request, _reply) => {
|
|
return "pong" as const;
|
|
},
|
|
);
|
|
|
|
await fastify.ready();
|
|
fastify.listen({ port: port, host: "0.0.0.0" }, (err, address) => {
|
|
if (err) {
|
|
console.error(err);
|
|
process.exit(1);
|
|
}
|
|
console.log(`Server listening at ${address}`);
|
|
});
|