feat: add next-runtime-env

This commit is contained in:
Catalin Pit
2024-01-25 10:48:20 +02:00
parent bc1d5cea0a
commit d451a7acce
34 changed files with 192 additions and 56 deletions

View File

@ -61,7 +61,7 @@ export const EditDocumentForm = ({
const { mutateAsync: setPasswordForDocument } =
trpc.document.setPasswordForDocument.useMutation();
const documentFlow: Record<EditDocumentStep, DocumentFlowStep> = {
const documentFlow: Record<EditDocumentStep, DcumentFlowStep> = {
title: {
title: 'Add Title',
description: 'Add the title to the document.',

View File

@ -1,16 +1,20 @@
'use server';
import { env } from 'next-runtime-env';
import { getStripeCustomerByUser } from '@documenso/ee/server-only/stripe/get-customer';
import { getPortalSession } from '@documenso/ee/server-only/stripe/get-portal-session';
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
export const createBillingPortal = async () => {
const NEXT_PUBLIC_WEBAPP_URL = env('NEXT_PUBLIC_WEBAPP_URL');
const { user } = await getRequiredServerComponentSession();
const { stripeCustomer } = await getStripeCustomerByUser(user);
return getPortalSession({
customerId: stripeCustomer.id,
returnUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL}/settings/billing`,
returnUrl: `${NEXT_PUBLIC_WEBAPP_URL}/settings/billing`,
});
};

View File

@ -1,5 +1,7 @@
'use server';
import { env } from 'next-runtime-env';
import { getCheckoutSession } from '@documenso/ee/server-only/stripe/get-checkout-session';
import { getStripeCustomerByUser } from '@documenso/ee/server-only/stripe/get-customer';
import { getPortalSession } from '@documenso/ee/server-only/stripe/get-portal-session';
@ -11,6 +13,8 @@ export type CreateCheckoutOptions = {
};
export const createCheckout = async ({ priceId }: CreateCheckoutOptions) => {
const NEXT_PUBLIC_WEBAPP_URL = env('NEXT_PUBLIC_WEBAPP_URL');
const session = await getRequiredServerComponentSession();
const { user, stripeCustomer } = await getStripeCustomerByUser(session.user);
@ -27,13 +31,13 @@ export const createCheckout = async ({ priceId }: CreateCheckoutOptions) => {
if (foundSubscription) {
return getPortalSession({
customerId: stripeCustomer.id,
returnUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL}/settings/billing`,
returnUrl: `${NEXT_PUBLIC_WEBAPP_URL}/settings/billing`,
});
}
return getCheckoutSession({
customerId: stripeCustomer.id,
priceId,
returnUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL}/settings/billing`,
returnUrl: `${NEXT_PUBLIC_WEBAPP_URL}/settings/billing`,
});
};

View File

@ -1,6 +1,7 @@
import { ImageResponse } from 'next/og';
import { NextResponse } from 'next/server';
import { env } from 'next-runtime-env';
import { P, match } from 'ts-pattern';
import type { ShareHandlerAPIResponse } from '~/pages/api/share';
@ -22,6 +23,8 @@ type SharePageOpenGraphImageProps = {
};
export async function GET(_request: Request, { params: { slug } }: SharePageOpenGraphImageProps) {
const NEXT_PUBLIC_WEBAPP_URL = env('NEXT_PUBLIC_WEBAPP_URL');
const [interSemiBold, interRegular, caveatRegular, shareFrameImage] = await Promise.all([
fetch(new URL('@documenso/assets/fonts/inter-semibold.ttf', import.meta.url)).then(
async (res) => res.arrayBuffer(),
@ -37,7 +40,7 @@ export async function GET(_request: Request, { params: { slug } }: SharePageOpen
),
]);
const baseUrl = process.env.NEXT_PUBLIC_WEBAPP_URL || 'http://localhost:3000';
const baseUrl = NEXT_PUBLIC_WEBAPP_URL || 'http://localhost:3000';
const recipientOrSender: ShareHandlerAPIResponse = await fetch(
new URL(`/api/share?slug=${slug}`, baseUrl),

View File

@ -1,7 +1,9 @@
import { Metadata } from 'next';
import type { Metadata } from 'next';
import { headers } from 'next/headers';
import { redirect } from 'next/navigation';
import { env } from 'next-runtime-env';
import { APP_BASE_URL } from '@documenso/lib/constants/app';
type SharePageProps = {
@ -28,6 +30,8 @@ export function generateMetadata({ params: { slug } }: SharePageProps) {
}
export default function SharePage() {
const NEXT_PUBLIC_MARKETING_URL = env('NEXT_PUBLIC_MARKETING_URL');
const userAgent = headers().get('User-Agent') ?? '';
// https://stackoverflow.com/questions/47026171/how-to-detect-bots-for-open-graph-with-user-agent
@ -35,5 +39,5 @@ export default function SharePage() {
return null;
}
redirect(process.env.NEXT_PUBLIC_MARKETING_URL ?? 'http://localhost:3001');
redirect(NEXT_PUBLIC_MARKETING_URL ?? 'http://localhost:3001');
}

View File

@ -1,10 +1,14 @@
import Link from 'next/link';
import { env } from 'next-runtime-env';
import { IS_GOOGLE_SSO_ENABLED } from '@documenso/lib/constants/auth';
import { SignInForm } from '~/components/forms/signin';
export default function SignInPage() {
const NEXT_PUBLIC_DISABLE_SIGNUP = env('NEXT_PUBLIC_DISABLE_SIGNUP');
return (
<div>
<h1 className="text-4xl font-semibold">Sign in to your account</h1>
@ -15,7 +19,7 @@ export default function SignInPage() {
<SignInForm className="mt-4" isGoogleSSOEnabled={IS_GOOGLE_SSO_ENABLED} />
{process.env.NEXT_PUBLIC_DISABLE_SIGNUP !== 'true' && (
{NEXT_PUBLIC_DISABLE_SIGNUP !== 'true' && (
<p className="text-muted-foreground mt-6 text-center text-sm">
Don't have an account?{' '}
<Link href="/signup" className="text-primary duration-200 hover:opacity-70">

View File

@ -1,10 +1,14 @@
import Link from 'next/link';
import { redirect } from 'next/navigation';
import { env } from 'next-runtime-env';
import { SignUpForm } from '~/components/forms/signup';
export default function SignUpPage() {
if (process.env.NEXT_PUBLIC_DISABLE_SIGNUP === 'true') {
const NEXT_PUBLIC_DISABLE_SIGNUP = env('NEXT_PUBLIC_DISABLE_SIGNUP');
if (NEXT_PUBLIC_DISABLE_SIGNUP === 'true') {
redirect('/signin');
}

View File

@ -2,6 +2,8 @@ import { Suspense } from 'react';
import { Caveat, Inter } from 'next/font/google';
import { PublicEnvScript, env } from 'next-runtime-env';
import { FeatureFlagProvider } from '@documenso/lib/client-only/providers/feature-flag';
import { LocaleProvider } from '@documenso/lib/client-only/providers/locale';
import { getServerComponentAllFlags } from '@documenso/lib/server-only/feature-flags/get-server-component-feature-flag';
@ -19,6 +21,8 @@ import './globals.css';
const fontInter = Inter({ subsets: ['latin'], variable: '--font-sans' });
const fontCaveat = Caveat({ subsets: ['latin'], variable: '--font-signature' });
const NEXT_PUBLIC_WEBAPP_URL = env('NEXT_PUBLIC_WEBAPP_URL');
export const metadata = {
title: 'Documenso - The Open Source DocuSign Alternative',
description:
@ -32,12 +36,12 @@ export const metadata = {
description:
'Join Documenso, the open signing infrastructure, and get a 10x better signing experience. Pricing starts at $30/mo. forever! Sign in now and enjoy a faster, smarter, and more beautiful document signing process. Integrates with your favorite tools, customizable, and expandable. Support our mission and become a part of our open-source community.',
type: 'website',
images: [`${process.env.NEXT_PUBLIC_WEBAPP_URL}/opengraph-image.jpg`],
images: [`${NEXT_PUBLIC_WEBAPP_URL}/opengraph-image.jpg`],
},
twitter: {
site: '@documenso',
card: 'summary_large_image',
images: [`${process.env.NEXT_PUBLIC_WEBAPP_URL}/opengraph-image.jpg`],
images: [`${NEXT_PUBLIC_WEBAPP_URL}/opengraph-image.jpg`],
description:
'Join Documenso, the open signing infrastructure, and get a 10x better signing experience. Pricing starts at $30/mo. forever! Sign in now and enjoy a faster, smarter, and more beautiful document signing process. Integrates with your favorite tools, customizable, and expandable. Support our mission and become a part of our open-source community.',
},
@ -59,6 +63,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/site.webmanifest" />
<PublicEnvScript />
</head>
<Suspense>

View File

@ -2,6 +2,8 @@
import React from 'react';
import { env } from 'next-runtime-env';
import { useCopyToClipboard } from '@documenso/lib/client-only/hooks/use-copy-to-clipboard';
import { getRecipientType } from '@documenso/lib/client-only/recipient-type';
import { recipientAbbreviation } from '@documenso/lib/utils/recipient-formatter';
@ -16,6 +18,8 @@ export type AvatarWithRecipientProps = {
};
export function AvatarWithRecipient({ recipient }: AvatarWithRecipientProps) {
const NEXT_PUBLIC_WEBAPP_URL = env('NEXT_PUBLIC_WEBAPP_URL');
const [, copy] = useCopyToClipboard();
const { toast } = useToast();
@ -24,7 +28,7 @@ export function AvatarWithRecipient({ recipient }: AvatarWithRecipientProps) {
return;
}
void copy(`${process.env.NEXT_PUBLIC_WEBAPP_URL}/sign/${recipient.token}`).then(() => {
void copy(`${NEXT_PUBLIC_WEBAPP_URL}/sign/${recipient.token}`).then(() => {
toast({
title: 'Copied to clipboard',
description: 'The signing link has been copied to your clipboard.',

View File

@ -1,3 +1,5 @@
import { env } from 'next-runtime-env';
/**
* getAssetBuffer is used to retrieve array buffers for various assets
* that are hosted in the `public` folder.
@ -8,7 +10,9 @@
* @param path The path to the asset, relative to the `public` folder.
*/
export const getAssetBuffer = async (path: string) => {
const baseUrl = process.env.NEXT_PUBLIC_WEBAPP_URL || 'http://localhost:3000';
const NEXT_PUBLIC_WEBAPP_URL = env('NEXT_PUBLIC_WEBAPP_URL');
const baseUrl = NEXT_PUBLIC_WEBAPP_URL || 'http://localhost:3000';
return fetch(new URL(path, baseUrl)).then(async (res) => res.arrayBuffer());
};