import { OpenAPIHandler } from '@orpc/openapi/fetch' import { OpenAPIReferencePlugin } from '@orpc/openapi/plugins' import { ORPCError, onError, ValidationError } from '@orpc/server' import { ZodToJsonSchemaConverter } from '@orpc/zod/zod4' import { createFileRoute } from '@tanstack/react-router' import { z } from 'zod' import { name, version } from '#server/../package.json' import { router } from '@/server/api/routers' const handler = new OpenAPIHandler(router, { plugins: [ new OpenAPIReferencePlugin({ docsProvider: 'scalar', schemaConverters: [new ZodToJsonSchemaConverter()], specGenerateOptions: { info: { title: name, version, }, components: { securitySchemes: { bearerAuth: { type: 'http', scheme: 'bearer', }, }, }, }, docsPath: '/docs', specPath: '/spec.json', }), ], interceptors: [ onError((error) => { console.error(error) }), ], clientInterceptors: [ onError((error) => { if ( error instanceof ORPCError && error.code === 'BAD_REQUEST' && error.cause instanceof ValidationError ) { // If you only use Zod you can safely cast to ZodIssue[] const zodError = new z.ZodError( error.cause.issues as z.core.$ZodIssue[], ) throw new ORPCError('INPUT_VALIDATION_FAILED', { status: 422, message: z.prettifyError(zodError), data: z.flattenError(zodError), cause: error.cause, }) } if ( error instanceof ORPCError && error.code === 'INTERNAL_SERVER_ERROR' && error.cause instanceof ValidationError ) { throw new ORPCError('OUTPUT_VALIDATION_FAILED', { cause: error.cause, }) } }), ], }) export const Route = createFileRoute('/api/$')({ server: { handlers: { ANY: async ({ request }) => { const { response } = await handler.handle(request, { prefix: '/api', context: { headers: request.headers, }, }) return response ?? new Response('Not Found', { status: 404 }) }, }, }, })