feat: migrate nextjs to rr7

This commit is contained in:
David Nguyen
2025-01-02 15:33:37 +11:00
parent 9183f668d3
commit 383b5f78f0
898 changed files with 31175 additions and 24615 deletions

View File

@ -1 +0,0 @@
declare module '@documenso/tailwind-config';

View File

@ -1,17 +1,17 @@
export * from '@react-email/body';
export * from '@react-email/button';
export * from '@react-email/column';
export * from '@react-email/container';
export * from '@react-email/font';
export * from '@react-email/head';
export * from '@react-email/heading';
export * from '@react-email/hr';
export * from '@react-email/html';
export * from '@react-email/img';
export * from '@react-email/link';
export * from '@react-email/preview';
export * from '@react-email/render';
export * from '@react-email/row';
export * from '@react-email/section';
export * from '@react-email/tailwind';
export * from '@react-email/text';
export { Body } from '@react-email/body';
export { Button } from '@react-email/button';
export { Column } from '@react-email/column';
export { Container } from '@react-email/container';
export { Font } from '@react-email/font';
export { Head } from '@react-email/head';
export { Heading } from '@react-email/heading';
export { Hr } from '@react-email/hr';
export { Html } from '@react-email/html';
export { Img } from '@react-email/img';
export { Link } from '@react-email/link';
export { Preview } from '@react-email/preview';
export { render } from '@react-email/render';
export { Row } from '@react-email/row';
export { Section } from '@react-email/section';
export { Tailwind } from '@react-email/tailwind';
export { Text } from '@react-email/text';

View File

@ -1,6 +1,7 @@
import type { Transporter } from 'nodemailer';
import { createTransport } from 'nodemailer';
import { env } from '@documenso/lib/utils/env';
import { ResendTransport } from '@documenso/nodemailer-resend';
import { MailChannelsTransport } from './transports/mailchannels';
@ -51,13 +52,13 @@ import { MailChannelsTransport } from './transports/mailchannels';
* - `NEXT_PRIVATE_SMTP_SERVICE` is optional and used specifically for well-known services like Gmail.
*/
const getTransport = (): Transporter => {
const transport = process.env.NEXT_PRIVATE_SMTP_TRANSPORT ?? 'smtp-auth';
const transport = env('NEXT_PRIVATE_SMTP_TRANSPORT') ?? 'smtp-auth';
if (transport === 'mailchannels') {
return createTransport(
MailChannelsTransport.makeTransport({
apiKey: process.env.NEXT_PRIVATE_MAILCHANNELS_API_KEY,
endpoint: process.env.NEXT_PRIVATE_MAILCHANNELS_ENDPOINT,
apiKey: env('NEXT_PRIVATE_MAILCHANNELS_API_KEY'),
endpoint: env('NEXT_PRIVATE_MAILCHANNELS_ENDPOINT'),
}),
);
}
@ -65,43 +66,41 @@ const getTransport = (): Transporter => {
if (transport === 'resend') {
return createTransport(
ResendTransport.makeTransport({
apiKey: process.env.NEXT_PRIVATE_RESEND_API_KEY || '',
apiKey: env('NEXT_PRIVATE_RESEND_API_KEY') || '',
}),
);
}
if (transport === 'smtp-api') {
if (!process.env.NEXT_PRIVATE_SMTP_HOST || !process.env.NEXT_PRIVATE_SMTP_APIKEY) {
if (!env('NEXT_PRIVATE_SMTP_HOST') || !env('NEXT_PRIVATE_SMTP_APIKEY')) {
throw new Error(
'SMTP API transport requires NEXT_PRIVATE_SMTP_HOST and NEXT_PRIVATE_SMTP_APIKEY',
);
}
return createTransport({
host: process.env.NEXT_PRIVATE_SMTP_HOST,
port: Number(process.env.NEXT_PRIVATE_SMTP_PORT) || 587,
secure: process.env.NEXT_PRIVATE_SMTP_SECURE === 'true',
host: env('NEXT_PRIVATE_SMTP_HOST'),
port: Number(env('NEXT_PRIVATE_SMTP_PORT')) || 587,
secure: env('NEXT_PRIVATE_SMTP_SECURE') === 'true',
auth: {
user: process.env.NEXT_PRIVATE_SMTP_APIKEY_USER ?? 'apikey',
pass: process.env.NEXT_PRIVATE_SMTP_APIKEY ?? '',
user: env('NEXT_PRIVATE_SMTP_APIKEY_USER') ?? 'apikey',
pass: env('NEXT_PRIVATE_SMTP_APIKEY') ?? '',
},
});
}
return createTransport({
host: process.env.NEXT_PRIVATE_SMTP_HOST ?? 'localhost:2500',
port: Number(process.env.NEXT_PRIVATE_SMTP_PORT) || 587,
secure: process.env.NEXT_PRIVATE_SMTP_SECURE === 'true',
ignoreTLS: process.env.NEXT_PRIVATE_SMTP_UNSAFE_IGNORE_TLS === 'true',
auth: process.env.NEXT_PRIVATE_SMTP_USERNAME
host: env('NEXT_PRIVATE_SMTP_HOST') ?? '127.0.0.1:2500',
port: Number(env('NEXT_PRIVATE_SMTP_PORT')) || 587,
secure: env('NEXT_PRIVATE_SMTP_SECURE') === 'true',
ignoreTLS: env('NEXT_PRIVATE_SMTP_UNSAFE_IGNORE_TLS') === 'true',
auth: env('NEXT_PRIVATE_SMTP_USERNAME')
? {
user: process.env.NEXT_PRIVATE_SMTP_USERNAME,
pass: process.env.NEXT_PRIVATE_SMTP_PASSWORD ?? '',
user: env('NEXT_PRIVATE_SMTP_USERNAME'),
pass: env('NEXT_PRIVATE_SMTP_PASSWORD') ?? '',
}
: undefined,
...(process.env.NEXT_PRIVATE_SMTP_SERVICE
? { service: process.env.NEXT_PRIVATE_SMTP_SERVICE }
: {}),
...(env('NEXT_PRIVATE_SMTP_SERVICE') ? { service: env('NEXT_PRIVATE_SMTP_SERVICE') } : {}),
});
};

View File

@ -35,9 +35,9 @@
"@react-email/section": "0.0.10",
"@react-email/tailwind": "0.0.9",
"@react-email/text": "0.0.6",
"nodemailer": "^6.9.9",
"react-email": "^1.9.5",
"resend": "^2.0.0"
"nodemailer": "6.9.9",
"react-email": "1.9.5",
"resend": "2.0.0"
},
"devDependencies": {
"@documenso/tailwind-config": "*",

View File

@ -1,5 +1,3 @@
'use client';
import { createContext, useContext } from 'react';
type BrandingContextValue = {

View File

@ -9,6 +9,9 @@ export type RenderOptions = ReactEmail.Options & {
branding?: BrandingSettings;
};
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const colors = (config.theme?.extend?.colors || {}) as Record<string, string>;
export const render = (element: React.ReactNode, options?: RenderOptions) => {
const { branding, ...otherOptions } = options ?? {};
@ -17,7 +20,7 @@ export const render = (element: React.ReactNode, options?: RenderOptions) => {
config={{
theme: {
extend: {
colors: config.theme.extend.colors,
colors,
},
},
}}
@ -36,7 +39,7 @@ export const renderAsync = async (element: React.ReactNode, options?: RenderOpti
config={{
theme: {
extend: {
colors: config.theme.extend.colors,
colors,
},
},
}}

View File

@ -1,4 +1,4 @@
import { Trans } from '@lingui/macro';
import { Trans } from '@lingui/react/macro';
import { Button, Section, Text } from '../components';
import { TemplateDocumentImage } from './template-document-image';

View File

@ -1,4 +1,4 @@
import { Trans } from '@lingui/macro';
import { Trans } from '@lingui/react/macro';
import { Section, Text } from '../components';
import { TemplateDocumentImage } from './template-document-image';

View File

@ -1,4 +1,4 @@
import { Trans } from '@lingui/macro';
import { Trans } from '@lingui/react/macro';
import { Button, Column, Img, Section, Text } from '../components';
import { TemplateDocumentImage } from './template-document-image';

View File

@ -1,7 +1,7 @@
import { useMemo } from 'react';
import { Trans } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import { match } from 'ts-pattern';
import { RECIPIENT_ROLES_DESCRIPTION } from '@documenso/lib/constants/recipient-roles';

View File

@ -1,4 +1,4 @@
import { Trans } from '@lingui/macro';
import { Trans } from '@lingui/react/macro';
import { Column, Img, Section, Text } from '../components';
import { TemplateDocumentImage } from './template-document-image';

View File

@ -1,4 +1,4 @@
import { Trans } from '@lingui/macro';
import { Trans } from '@lingui/react/macro';
import { Column, Img, Section, Text } from '../components';
import { TemplateDocumentImage } from './template-document-image';

View File

@ -1,4 +1,4 @@
import { Trans } from '@lingui/macro';
import { Trans } from '@lingui/react/macro';
import { Button, Heading, Text } from '../components';

View File

@ -1,4 +1,4 @@
import { Trans } from '@lingui/macro';
import { Trans } from '@lingui/react/macro';
import { Container, Heading, Section, Text } from '../components';

View File

@ -1,5 +1,6 @@
import { Trans } from '@lingui/macro';
import { env } from 'next-runtime-env';
import { Trans } from '@lingui/react/macro';
import { env } from '@documenso/lib/utils/env';
import { Button, Column, Img, Link, Section, Text } from '../components';
import { TemplateDocumentImage } from './template-document-image';

View File

@ -1,4 +1,4 @@
import { Trans } from '@lingui/macro';
import { Trans } from '@lingui/react/macro';
import { Section, Text } from '../components';
import { TemplateDocumentImage } from './template-document-image';

View File

@ -1,4 +1,4 @@
import { Trans } from '@lingui/macro';
import { Trans } from '@lingui/react/macro';
import { Link, Section, Text } from '../components';
import { useBranding } from '../providers/branding';

View File

@ -1,4 +1,4 @@
import { Trans } from '@lingui/macro';
import { Trans } from '@lingui/react/macro';
import { Button, Section, Text } from '../components';
import { TemplateDocumentImage } from './template-document-image';

View File

@ -1,5 +1,6 @@
import { Trans } from '@lingui/macro';
import { env } from 'next-runtime-env';
import { Trans } from '@lingui/react/macro';
import { env } from '@documenso/lib/utils/env';
import { Button, Section, Text } from '../components';
import { TemplateDocumentImage } from './template-document-image';

View File

@ -1,4 +1,4 @@
import { msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Body, Container, Head, Html, Img, Preview, Section } from '../components';

View File

@ -1,5 +1,6 @@
import { Trans, msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import { formatTeamUrl } from '@documenso/lib/utils/teams';

View File

@ -1,4 +1,4 @@
import { msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Body, Container, Head, Hr, Html, Img, Preview, Section } from '../components';

View File

@ -1,4 +1,4 @@
import { msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Body, Container, Head, Html, Img, Preview, Section } from '../components';

View File

@ -1,13 +1,14 @@
import { Trans, msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import { RECIPIENT_ROLES_DESCRIPTION } from '@documenso/lib/constants/recipient-roles';
import { RecipientRole } from '@documenso/prisma/client';
import { Body, Button, Container, Head, Html, Img, Preview, Section, Text } from '../components';
import { useBranding } from '../providers/branding';
import TemplateDocumentImage from '../template-components/template-document-image';
import { TemplateFooter } from '../template-components/template-footer';
import { RecipientRole } from '.prisma/client';
export type DocumentCompletedEmailTemplateProps = {
recipientName?: string;

View File

@ -1,5 +1,6 @@
import { Trans, msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import { RECIPIENT_ROLES_DESCRIPTION } from '@documenso/lib/constants/recipient-roles';
import type { RecipientRole } from '@documenso/prisma/client';
@ -30,7 +31,7 @@ export const DocumentInviteEmailTemplate = ({
role,
selfSigner = false,
isTeamInvite = false,
teamName,
teamName = '',
includeSenderDetails,
}: DocumentInviteEmailTemplateProps) => {
const { _ } = useLingui();

View File

@ -1,4 +1,4 @@
import { msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Body, Container, Head, Html, Img, Preview, Section } from '../components';

View File

@ -1,4 +1,4 @@
import { msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Body, Container, Head, Html, Img, Preview, Section } from '../components';

View File

@ -1,4 +1,4 @@
import { msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Body, Container, Head, Html, Img, Preview, Section } from '../components';

View File

@ -1,4 +1,4 @@
import { msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Body, Container, Head, Html, Img, Preview, Section } from '../components';

View File

@ -1,4 +1,4 @@
import { msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Body, Container, Head, Html, Img, Preview, Section } from '../components';

View File

@ -1,4 +1,4 @@
import { msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Body, Container, Head, Hr, Html, Img, Preview, Section } from '../components';

View File

@ -1,4 +1,4 @@
import { msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Body, Container, Head, Html, Img, Preview, Section } from '../components';

View File

@ -1,5 +1,6 @@
import { Trans, msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import { Body, Container, Head, Hr, Html, Img, Preview, Section, Text } from '../components';
import { useBranding } from '../providers/branding';

View File

@ -1,5 +1,6 @@
import { Trans, msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import { Body, Container, Head, Hr, Html, Img, Link, Preview, Section, Text } from '../components';
import { useBranding } from '../providers/branding';

View File

@ -1,4 +1,4 @@
import { msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { formatTeamUrl } from '@documenso/lib/utils/teams';

View File

@ -1,5 +1,6 @@
import { Trans, msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import { formatTeamUrl } from '@documenso/lib/utils/teams';

View File

@ -1,5 +1,6 @@
import { Trans, msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import { formatTeamUrl } from '@documenso/lib/utils/teams';

View File

@ -1,5 +1,6 @@
import { Trans, msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import { formatTeamUrl } from '@documenso/lib/utils/teams';

View File

@ -1,5 +1,6 @@
import { Trans, msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import { formatTeamUrl } from '@documenso/lib/utils/teams';

View File

@ -1,5 +1,6 @@
import { Trans, msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import { formatTeamUrl } from '@documenso/lib/utils/teams';

View File

@ -1,7 +1,9 @@
import { SentMessageInfo, Transport } from 'nodemailer';
import type { SentMessageInfo, Transport } from 'nodemailer';
import type { Address } from 'nodemailer/lib/mailer';
import type MailMessage from 'nodemailer/lib/mailer/mail-message';
import { env } from '@documenso/lib/utils/env';
const VERSION = '1.0.0';
type NodeMailerAddress = string | Address | Array<string | Address> | undefined;
@ -79,9 +81,9 @@ export class MailChannelsTransport implements Transport<SentMessageInfo> {
to: mailTo,
cc: mailCc.length > 0 ? mailCc : undefined,
bcc: mailBcc.length > 0 ? mailBcc : undefined,
dkim_domain: process.env.NEXT_PRIVATE_MAILCHANNELS_DKIM_DOMAIN || undefined,
dkim_selector: process.env.NEXT_PRIVATE_MAILCHANNELS_DKIM_SELECTOR || undefined,
dkim_private_key: process.env.NEXT_PRIVATE_MAILCHANNELS_DKIM_PRIVATE_KEY || undefined,
dkim_domain: env('NEXT_PRIVATE_MAILCHANNELS_DKIM_DOMAIN') || undefined,
dkim_selector: env('NEXT_PRIVATE_MAILCHANNELS_DKIM_SELECTOR') || undefined,
dkim_private_key: env('NEXT_PRIVATE_MAILCHANNELS_DKIM_PRIVATE_KEY') || undefined,
},
],
content: [