feat(api): setting up

This commit is contained in:
2025-11-09 16:28:36 +02:00
parent d72f3871a4
commit 4b82a11207
35 changed files with 2280 additions and 1516 deletions
+40
View File
@@ -0,0 +1,40 @@
import path from "node:path";
import { loadConfig as defineConfig } from "@devscast/config";
import { z } from "zod";
export const PROJECT_DIR = path.resolve(__dirname, "../");
const ServerConfigurationSchema = z.object({
cors: z.object({
allowedHeaders: z.array(z.string()).optional(),
allowMethods: z.array(z.string()).optional(),
exposeHeaders: z.array(z.string()).optional(),
maxAge: z.number().int().min(0).optional(),
origin: z.array(z.string()).default([]),
}),
server: z.object({
host: z.string().default("localhost"),
port: z.number().int().min(1).max(65535).default(4000),
version: z.string().default("1.0.0"),
}),
});
export const { env, config } = defineConfig({
env: {
knownKeys: [
"BASANGO_API_HOST",
"BASANGO_API_PORT",
"BASANGO_API_ALLOWED_ORIGINS",
"BASANGO_API_KEY",
],
path: path.join(PROJECT_DIR, ".env"),
},
schema: ServerConfigurationSchema,
sources: [
path.join(PROJECT_DIR, "config", "server.json"),
path.join(PROJECT_DIR, "config", "cors.json"),
],
});
export type ServerConfiguration = z.infer<typeof ServerConfigurationSchema>;
+15
View File
@@ -0,0 +1,15 @@
{
"allowedHeaders": [
"Authorization",
"Content-Type",
"accept-language",
"x-trpc-source",
"x-user-locale",
"x-user-timezone",
"x-user-country"
],
"allowMethods": ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"],
"exposeHeaders": ["Content-Length"],
"maxAge": 86400,
"origin": "%env(BASANGO_API_ALLOWED_ORIGINS)%"
}
+5
View File
@@ -0,0 +1,5 @@
{
"host": "%env(BASANGO_API_HOST)%",
"port": "%env(number:BASANGO_API_PORT)%",
"version": "1.0.0"
}
+14 -15
View File
@@ -3,6 +3,7 @@ import { Scalar } from "@scalar/hono-api-reference";
import { cors } from "hono/cors";
import { secureHeaders } from "hono/secure-headers";
import { config, env } from "@/config";
import { checkHealth } from "@/utils/health";
const app = new OpenAPIHono();
@@ -12,19 +13,11 @@ app.use(secureHeaders());
app.use(
"*",
cors({
allowHeaders: [
"Authorization",
"Content-Type",
"accept-language",
"x-trpc-source",
"x-user-locale",
"x-user-timezone",
"x-user-country",
],
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"],
exposeHeaders: ["Content-Length"],
maxAge: 86400,
origin: process.env.BASANGO_API_ALLOWED_ORIGINS?.split(",") ?? [],
allowHeaders: config.cors.allowedHeaders,
allowMethods: config.cors.allowMethods,
exposeHeaders: config.cors.exposeHeaders,
maxAge: config.cors.maxAge,
origin: config.cors.origin,
}),
);
@@ -54,7 +47,7 @@ app.doc("/openapi", {
description: "Basango is a platform that leverages AI to revolutionize news curation.",
license: {
name: "AGPL-3.0 license",
url: "https://github.com/midday-ai/midday/blob/main/LICENSE",
url: "https://github.com/bernard-ng/basango/blob/main/LICENSE",
},
title: "Basango API",
version: "0.0.1",
@@ -79,7 +72,13 @@ app.openAPIRegistry.registerComponent("securitySchemes", "token", {
description: "Default authentication mechanism",
scheme: "bearer",
type: "http",
"x-speakeasy-example": "BASANGO_API_KEY",
"x-speakeasy-example": env("BASANGO_API_KEY"),
});
app.get("/", Scalar({ pageTitle: "Basango API", theme: "saturn", url: "/openapi" }));
export default {
fetch: app.fetch,
hostname: config.server.host,
port: config.server.port,
};