mirror of
https://github.com/documenso/documenso.git
synced 2025-11-14 00:32:43 +10:00
wip
This commit is contained in:
21
apps/remix/server/index.ts
Normal file
21
apps/remix/server/index.ts
Normal file
@ -0,0 +1,21 @@
|
||||
// server/index.ts
|
||||
import { Hono } from 'hono';
|
||||
|
||||
import { auth } from '@documenso/auth/server';
|
||||
import { jobsClient } from '@documenso/lib/jobs/client';
|
||||
|
||||
import { openApiTrpcServerHandler } from './trpc/hono-trpc-open-api';
|
||||
import { reactRouterTrpcServer } from './trpc/hono-trpc-remix';
|
||||
|
||||
const app = new Hono();
|
||||
|
||||
// Auth server.
|
||||
app.route('/api/auth', auth);
|
||||
|
||||
// API servers. Todo: Configure max durations, etc?
|
||||
app.use('/api/jobs/*', jobsClient.getHonoApiHandler());
|
||||
app.use('/api/v1/*', reactRouterTrpcServer); // Todo: ts-rest
|
||||
app.use('/api/v2/*', async (c) => openApiTrpcServerHandler(c));
|
||||
app.use('/api/trpc/*', reactRouterTrpcServer);
|
||||
|
||||
export default app;
|
||||
18
apps/remix/server/node.ts
Normal file
18
apps/remix/server/node.ts
Normal file
@ -0,0 +1,18 @@
|
||||
// main.ts
|
||||
import { serve } from '@hono/node-server';
|
||||
import { serveStatic } from '@hono/node-server/serve-static';
|
||||
import handle from 'hono-react-router-adapter/node';
|
||||
|
||||
import server from '.';
|
||||
import * as build from '../build/server';
|
||||
import { getLoadContext } from './load-context';
|
||||
|
||||
server.use(
|
||||
serveStatic({
|
||||
root: './build/client',
|
||||
}),
|
||||
);
|
||||
|
||||
const handler = handle(build, server, { getLoadContext });
|
||||
|
||||
serve({ fetch: handler.fetch, port: 3010 });
|
||||
33
apps/remix/server/trpc/hono-trpc-open-api.ts
Normal file
33
apps/remix/server/trpc/hono-trpc-open-api.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { Context } from 'hono';
|
||||
import { createOpenApiFetchHandler } from 'trpc-to-openapi';
|
||||
|
||||
import { AppError, genericErrorCodeToTrpcErrorCodeMap } from '@documenso/lib/errors/app-error';
|
||||
import { appRouter } from '@documenso/trpc/server/router';
|
||||
import { handleTrpcRouterError } from '@documenso/trpc/utils/trpc-error-handler';
|
||||
|
||||
import { createHonoTrpcContext } from './trpc-context';
|
||||
|
||||
export const openApiTrpcServerHandler = async (c: Context) => {
|
||||
return createOpenApiFetchHandler<typeof appRouter>({
|
||||
endpoint: '/v2/api',
|
||||
router: appRouter,
|
||||
// Todo: Test this, since it's not using the createContext params.
|
||||
createContext: async () => createHonoTrpcContext({ c, requestSource: 'apiV2' }),
|
||||
req: c.req.raw,
|
||||
onError: (opts) => handleTrpcRouterError(opts, 'apiV2'),
|
||||
// Not sure why we need to do this since we handle it in errorFormatter which runs after this.
|
||||
responseMeta: (opts) => {
|
||||
if (opts.errors[0]?.cause instanceof AppError) {
|
||||
const appError = AppError.parseError(opts.errors[0].cause);
|
||||
|
||||
const httpStatus = genericErrorCodeToTrpcErrorCodeMap[appError.code]?.status ?? 400;
|
||||
|
||||
return {
|
||||
status: httpStatus,
|
||||
};
|
||||
}
|
||||
|
||||
return {};
|
||||
},
|
||||
});
|
||||
};
|
||||
25
apps/remix/server/trpc/hono-trpc-remix.ts
Normal file
25
apps/remix/server/trpc/hono-trpc-remix.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { trpcServer } from '@hono/trpc-server';
|
||||
|
||||
import { appRouter } from '@documenso/trpc/server/router';
|
||||
import { handleTrpcRouterError } from '@documenso/trpc/utils/trpc-error-handler';
|
||||
|
||||
import { createHonoTrpcContext } from './trpc-context';
|
||||
|
||||
// export const config = {
|
||||
// maxDuration: 120,
|
||||
// api: {
|
||||
// bodyParser: {
|
||||
// sizeLimit: '50mb',
|
||||
// },
|
||||
// },
|
||||
// };
|
||||
|
||||
/**
|
||||
* Trpc server for internal routes like /api/trpc/*
|
||||
*/
|
||||
export const reactRouterTrpcServer = trpcServer({
|
||||
router: appRouter,
|
||||
endpoint: '/api/trpc',
|
||||
createContext: async (_, c) => createHonoTrpcContext({ c, requestSource: 'app' }),
|
||||
onError: (opts) => handleTrpcRouterError(opts, 'trpc'),
|
||||
});
|
||||
66
apps/remix/server/trpc/trpc-context.ts
Normal file
66
apps/remix/server/trpc/trpc-context.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import type { Context } from 'hono';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { getSession } from '@documenso/auth/server/lib/utils/get-session';
|
||||
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
import { extractRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
import type { TrpcContext } from '@documenso/trpc/server/context';
|
||||
|
||||
type CreateTrpcContextOptions = {
|
||||
c: Context;
|
||||
requestSource: 'app' | 'apiV1' | 'apiV2';
|
||||
};
|
||||
|
||||
/**
|
||||
* For trpc that uses @documenso/auth and Hono.
|
||||
*/
|
||||
export const createHonoTrpcContext = async ({
|
||||
c,
|
||||
requestSource,
|
||||
}: CreateTrpcContextOptions): Promise<TrpcContext> => {
|
||||
const { session, user } = await getSession(c);
|
||||
|
||||
const req = c.req.raw;
|
||||
|
||||
const metadata: ApiRequestMetadata = {
|
||||
requestMetadata: extractRequestMetadata(req),
|
||||
source: requestSource,
|
||||
auth: null,
|
||||
};
|
||||
|
||||
const rawTeamId = req.headers.get('x-team-id') || undefined;
|
||||
|
||||
const teamId = z.coerce
|
||||
.number()
|
||||
.optional()
|
||||
.catch(() => undefined)
|
||||
.parse(rawTeamId);
|
||||
|
||||
if (!session) {
|
||||
return {
|
||||
session: null,
|
||||
user: null,
|
||||
teamId,
|
||||
req,
|
||||
metadata,
|
||||
};
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
return {
|
||||
session: null,
|
||||
user: null,
|
||||
teamId,
|
||||
req,
|
||||
metadata,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
session,
|
||||
user, // Todo
|
||||
teamId,
|
||||
req,
|
||||
metadata,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user