-
Notifications
You must be signed in to change notification settings - Fork 189
Expand file tree
/
Copy pathindex.ts
More file actions
116 lines (104 loc) · 3.47 KB
/
Copy pathindex.ts
File metadata and controls
116 lines (104 loc) · 3.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import "./polyfills/compression";
import { env as apiEnv } from "@databuddy/env/api";
import cors from "@elysiajs/cors";
import { Elysia } from "elysia";
import { evlog } from "evlog/elysia";
import { handleAutumnRequest } from "@/billing/autumn";
import { configureApiInstrumentation } from "@/bootstrap/instrumentation";
import { configureApiLogger } from "@/bootstrap/logger";
import { registerProcessErrorHandlers } from "@/bootstrap/process-errors";
import { registerShutdownHooks, warmPostgresPool } from "@/bootstrap/shutdown";
import { isAllowedApiOrigin } from "@/http/cors";
import { handleAppError } from "@/http/errors";
import { AUTUMN_API_PREFIX } from "@/lib/autumn-mount";
import { enrichApiWideEvent } from "@/lib/evlog-api";
import { enrichRequestAuthWideEvent } from "@/middleware/auth-wide-event";
import {
handleAnonymousOrpcRequest,
handleAuthenticatedOrpcRequest,
type OrpcContext,
rpcHandler,
} from "@/rpc/handlers";
import { openApiHandler } from "@/rpc/openapi";
import { agent } from "./routes/agent";
import { discovery } from "./routes/discovery";
import { health } from "./routes/health";
import { integrations } from "./routes/integrations";
import { mcp } from "./routes/mcp";
import { publicApi } from "./routes/public";
import { query } from "./routes/query";
import { webhooks } from "./routes/webhooks/index";
configureApiLogger();
configureApiInstrumentation();
registerProcessErrorHandlers();
const BUN_IDLE_TIMEOUT_SECONDS = 255;
interface RequestContext {
request: Request;
}
function handleRpcEndpoint({ request }: RequestContext) {
return handleAuthenticatedOrpcRequest(request, (orpcRequest, context) =>
rpcHandler.handle(orpcRequest, {
prefix: "/rpc",
context,
})
);
}
function handleOpenApiReference({ request }: RequestContext) {
return handleAnonymousOrpcRequest(request, handleOpenApiRequest);
}
function handleOpenApiEndpoint({ request }: RequestContext) {
return handleAuthenticatedOrpcRequest(request, handleOpenApiRequest);
}
function handleOpenApiJson({ request }: RequestContext) {
const url = new URL(request.url);
url.pathname = "/spec.json";
const specRequest = new Request(url, {
headers: request.headers,
method: request.method,
signal: request.signal,
});
return handleOpenApiReference({ request: specRequest });
}
function handleOpenApiRequest(orpcRequest: Request, context: OrpcContext) {
return openApiHandler.handle(orpcRequest, {
prefix: "/",
context,
});
}
const app = new Elysia({ precompile: true })
.use(
evlog({
enrich: enrichApiWideEvent,
})
)
.onBeforeHandle(({ request }) => enrichRequestAuthWideEvent(request))
.use(
cors({
credentials: true,
origin: isAllowedApiOrigin,
})
)
.use(publicApi)
.use(health)
.use(discovery)
.use(webhooks)
.mount(AUTUMN_API_PREFIX, handleAutumnRequest)
.use(query)
.use(agent)
.use(integrations)
.use(mcp)
.all("/rpc/*", handleRpcEndpoint, { parse: "none" })
.all("/", handleOpenApiReference, { parse: "none" })
.all("/openapi.json", handleOpenApiJson, { parse: "none" })
.all("/spec.json", handleOpenApiReference, { parse: "none" })
.all("/*", handleOpenApiEndpoint, { parse: "none" })
.onError(handleAppError);
warmPostgresPool();
registerShutdownHooks();
export default {
fetch: app.fetch,
// In development env validation is skipped, so zod defaults never apply and
// apiEnv.PORT can be undefined — fall back explicitly or Bun binds a random port.
port: Number.parseInt(apiEnv.PORT ?? "3001", 10) || 3001,
idleTimeout: BUN_IDLE_TIMEOUT_SECONDS,
};