You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
2.0 KiB
TypeScript

import type { TSchema } from "@sinclair/typebox";
import { TypeCompiler } from "@sinclair/typebox/compiler";
import { initTRPC, TRPCError } from "@trpc/server";
import type { getDbClient } from "../../database/postgres";
import type { getOpenrouter } from "@server/provider.js";
import type { JWT } from "@auth/core/jwt";
/**
* Initialization of tRPC backend
* Should be done only once per backend!
*/
const t = initTRPC
.context<
object & {
dbClient: ReturnType<typeof getDbClient>;
openrouter: ReturnType<typeof getOpenrouter>;
jwt?: JWT | null;
}
>()
.create(/*{
sse: {
maxDurationMs: 5 * 60 * 1_000, // 5 minutes
ping: {
enabled: true,
intervalMs: 3_000,
},
client: {
reconnectAfterInactivityMs: 5_000,
},
},
}*/);
/**
* Export reusable router and procedure helpers
* that can be used throughout the router
*/
export const router = t.router;
export const publicProcedure = t.procedure;
export const authProcedure = publicProcedure.use(
async ({ ctx: { jwt }, next }) => {
if (!jwt) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: JSON.stringify(jwt),
});
}
if (!jwt.id) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
return await next({
ctx: { jwt },
});
}
);
/**
* Generate a TRPC-compatible validator function given a Typebox schema.
* This was copied from [https://github.com/sinclairzx81/typebox/blob/6cfcdc02cc813af2f1be57407c771fc4fadfc34a/example/trpc/readme.md].
* @param schema A Typebox schema
* @returns A TRPC-compatible validator function
*/
export function Validator<T extends TSchema>(schema: T) {
const check = TypeCompiler.Compile(schema);
return (value: unknown) => {
if (check.Check(value)) return value;
const err = check.Errors(value).First();
throw new TRPCError({
message: `${err?.message} for ${err?.path}`,
code: "BAD_REQUEST",
});
};
}
export const createCallerFactory = t.createCallerFactory;