mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 16:23:06 +10:00
feat: migrate nextjs to rr7
This commit is contained in:
40
apps/remix/app/routes/api+/avatar.$id.tsx
Normal file
40
apps/remix/app/routes/api+/avatar.$id.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
import { getAvatarImage } from '@documenso/lib/server-only/profile/get-avatar-image';
|
||||
|
||||
import type { Route } from './+types/avatar.$id';
|
||||
|
||||
export async function loader({ params }: Route.LoaderArgs) {
|
||||
const { id } = params;
|
||||
|
||||
if (typeof id !== 'string') {
|
||||
return Response.json(
|
||||
{
|
||||
status: 'error',
|
||||
message: 'Missing id',
|
||||
},
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
const result = await getAvatarImage({ id });
|
||||
|
||||
if (!result) {
|
||||
return Response.json(
|
||||
{
|
||||
status: 'error',
|
||||
message: 'Not found',
|
||||
},
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
// res.setHeader('Content-Type', result.contentType);
|
||||
// res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
|
||||
// res.send(result.content);
|
||||
|
||||
return new Response(result.content, {
|
||||
headers: {
|
||||
'Content-Type': result.contentType,
|
||||
'Cache-Control': 'public, max-age=31536000, immutable',
|
||||
},
|
||||
});
|
||||
}
|
||||
73
apps/remix/app/routes/api+/branding.logo.team.$teamId.ts
Normal file
73
apps/remix/app/routes/api+/branding.logo.team.$teamId.ts
Normal file
@ -0,0 +1,73 @@
|
||||
import sharp from 'sharp';
|
||||
|
||||
import { getFile } from '@documenso/lib/universal/upload/get-file';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import type { Route } from './+types/branding.logo.team.$teamId';
|
||||
|
||||
export async function loader({ params }: Route.LoaderArgs) {
|
||||
const teamId = Number(params.teamId);
|
||||
|
||||
if (teamId === 0 || Number.isNaN(teamId)) {
|
||||
return Response.json(
|
||||
{
|
||||
status: 'error',
|
||||
message: 'Invalid team ID',
|
||||
},
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
const settings = await prisma.teamGlobalSettings.findFirst({
|
||||
where: {
|
||||
teamId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!settings || !settings.brandingEnabled) {
|
||||
return Response.json(
|
||||
{
|
||||
status: 'error',
|
||||
message: 'Not found',
|
||||
},
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
if (!settings.brandingLogo) {
|
||||
return Response.json(
|
||||
{
|
||||
status: 'error',
|
||||
message: 'Not found',
|
||||
},
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
const file = await getFile(JSON.parse(settings.brandingLogo)).catch(() => null);
|
||||
|
||||
if (!file) {
|
||||
return Response.json(
|
||||
{
|
||||
status: 'error',
|
||||
message: 'Not found',
|
||||
},
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
const img = await sharp(file)
|
||||
.toFormat('png', {
|
||||
quality: 80,
|
||||
})
|
||||
.toBuffer();
|
||||
|
||||
return new Response(img, {
|
||||
headers: {
|
||||
'Content-Type': 'image/png',
|
||||
'Content-Length': img.length.toString(),
|
||||
// Stale while revalidate for 1 hours to 24 hours
|
||||
'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate=86400',
|
||||
},
|
||||
});
|
||||
}
|
||||
22
apps/remix/app/routes/api+/health.ts
Normal file
22
apps/remix/app/routes/api+/health.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
export async function loader() {
|
||||
try {
|
||||
await prisma.$queryRaw`SELECT 1`;
|
||||
|
||||
return Response.json({
|
||||
status: 'ok',
|
||||
message: 'All systems operational',
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
return Response.json(
|
||||
{
|
||||
status: 'error',
|
||||
message: err instanceof Error ? err.message : 'Unknown error',
|
||||
},
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
7
apps/remix/app/routes/api+/limits.tsx
Normal file
7
apps/remix/app/routes/api+/limits.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
import { limitsHandler } from '@documenso/ee/server-only/limits/handler';
|
||||
|
||||
import type { Route } from './+types/limits';
|
||||
|
||||
export async function loader({ request }: Route.LoaderArgs) {
|
||||
return limitsHandler(request);
|
||||
}
|
||||
19
apps/remix/app/routes/api+/locale.tsx
Normal file
19
apps/remix/app/routes/api+/locale.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import type { ActionFunctionArgs } from 'react-router';
|
||||
|
||||
import { APP_I18N_OPTIONS } from '@documenso/lib/constants/i18n';
|
||||
|
||||
import { langCookie } from '~/storage/lang-cookie.server';
|
||||
|
||||
export const action = async ({ request }: ActionFunctionArgs) => {
|
||||
const formData = await request.formData();
|
||||
const lang = formData.get('lang') || '';
|
||||
|
||||
if (!APP_I18N_OPTIONS.supportedLangs.find((l) => l === lang)) {
|
||||
throw new Response('Unsupported language', { status: 400 });
|
||||
}
|
||||
|
||||
return new Response('OK', {
|
||||
status: 200,
|
||||
headers: { 'Set-Cookie': await langCookie.serialize(lang) },
|
||||
});
|
||||
};
|
||||
27
apps/remix/app/routes/api+/share.ts
Normal file
27
apps/remix/app/routes/api+/share.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { getRecipientOrSenderByShareLinkSlug } from '@documenso/lib/server-only/share/get-recipient-or-sender-by-share-link-slug';
|
||||
|
||||
import type { Route } from './+types/share';
|
||||
|
||||
export type ShareHandlerAPIResponse =
|
||||
| Awaited<ReturnType<typeof getRecipientOrSenderByShareLinkSlug>>
|
||||
| { error: string };
|
||||
|
||||
// Todo: Test
|
||||
export async function loader({ request }: Route.LoaderArgs) {
|
||||
try {
|
||||
const url = new URL(request.url);
|
||||
const slug = url.searchParams.get('slug');
|
||||
|
||||
if (typeof slug !== 'string') {
|
||||
throw new Error('Invalid slug');
|
||||
}
|
||||
|
||||
const data = await getRecipientOrSenderByShareLinkSlug({
|
||||
slug,
|
||||
});
|
||||
|
||||
return Response.json(data);
|
||||
} catch (error) {
|
||||
return Response.json({ error: 'Not found' }, { status: 404 });
|
||||
}
|
||||
}
|
||||
11
apps/remix/app/routes/api+/stripe.webhook.ts
Normal file
11
apps/remix/app/routes/api+/stripe.webhook.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { stripeWebhookHandler } from '@documenso/ee/server-only/stripe/webhook/handler';
|
||||
|
||||
// Todo
|
||||
// export const config = {
|
||||
// api: { bodyParser: false },
|
||||
// };
|
||||
import type { Route } from './+types/webhook.trigger';
|
||||
|
||||
export async function action({ request }: Route.ActionArgs) {
|
||||
return stripeWebhookHandler(request);
|
||||
}
|
||||
5
apps/remix/app/routes/api+/theme.tsx
Normal file
5
apps/remix/app/routes/api+/theme.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import { createThemeAction } from 'remix-themes';
|
||||
|
||||
import { themeSessionResolver } from '~/storage/theme-session.server';
|
||||
|
||||
export const action = createThemeAction(themeSessionResolver);
|
||||
17
apps/remix/app/routes/api+/webhook.trigger.ts
Normal file
17
apps/remix/app/routes/api+/webhook.trigger.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { handlerTriggerWebhooks } from '@documenso/lib/server-only/webhooks/trigger/handler';
|
||||
|
||||
import type { Route } from './+types/webhook.trigger';
|
||||
|
||||
// Todo
|
||||
// export const config = {
|
||||
// maxDuration: 300,
|
||||
// api: {
|
||||
// bodyParser: {
|
||||
// sizeLimit: '50mb',
|
||||
// },
|
||||
// },
|
||||
// };
|
||||
|
||||
export async function action({ request }: Route.ActionArgs) {
|
||||
return handlerTriggerWebhooks(request);
|
||||
}
|
||||
Reference in New Issue
Block a user