mirror of
https://github.com/documenso/documenso.git
synced 2025-11-19 19:21:39 +10:00
fix: minimal vite config
This commit is contained in:
@ -25,4 +25,5 @@ async function main() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void main();
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
|
main();
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
import NextPlausibleProvider from 'next-plausible';
|
|
||||||
|
|
||||||
export type PlausibleProviderProps = {
|
|
||||||
children: React.ReactNode;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const PlausibleProvider = ({ children }: PlausibleProviderProps) => {
|
|
||||||
return <NextPlausibleProvider domain="documenso.com">{children}</NextPlausibleProvider>;
|
|
||||||
};
|
|
||||||
@ -2,7 +2,7 @@ import { Trans } from '@lingui/macro';
|
|||||||
import { DocumentStatus, SigningStatus } from '@prisma/client';
|
import { DocumentStatus, SigningStatus } from '@prisma/client';
|
||||||
import { Clock8 } from 'lucide-react';
|
import { Clock8 } from 'lucide-react';
|
||||||
import { Link, redirect } from 'react-router';
|
import { Link, redirect } from 'react-router';
|
||||||
import { getOptionalLoaderSession } from 'server/utils/get-loader-session';
|
import { getOptionalLoaderContext } from 'server/utils/get-loader-session';
|
||||||
|
|
||||||
import signingCelebration from '@documenso/assets/images/signing-celebration.png';
|
import signingCelebration from '@documenso/assets/images/signing-celebration.png';
|
||||||
import { useOptionalSession } from '@documenso/lib/client-only/providers/session';
|
import { useOptionalSession } from '@documenso/lib/client-only/providers/session';
|
||||||
@ -27,7 +27,7 @@ import { superLoaderJson, useSuperLoaderData } from '~/utils/super-json-loader';
|
|||||||
import type { Route } from './+types/_index';
|
import type { Route } from './+types/_index';
|
||||||
|
|
||||||
export async function loader({ params }: Route.LoaderArgs) {
|
export async function loader({ params }: Route.LoaderArgs) {
|
||||||
const session = getOptionalLoaderSession();
|
const { session, requestMetadata } = getOptionalLoaderContext();
|
||||||
|
|
||||||
const { token } = params;
|
const { token } = params;
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ export async function loader({ params }: Route.LoaderArgs) {
|
|||||||
|
|
||||||
await viewedDocument({
|
await viewedDocument({
|
||||||
token,
|
token,
|
||||||
requestMetadata: context.requestMetadata,
|
requestMetadata,
|
||||||
recipientAccessAuth: derivedRecipientAccessAuth,
|
recipientAccessAuth: derivedRecipientAccessAuth,
|
||||||
}).catch(() => null);
|
}).catch(() => null);
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Todo: This relies on NextJS
|
// Todo: Test, used AI to migrate this component from NextJS to Remix.
|
||||||
import { ImageResponse } from 'next/og';
|
import satori from 'satori';
|
||||||
|
import sharp from 'sharp';
|
||||||
import { P, match } from 'ts-pattern';
|
import { P, match } from 'ts-pattern';
|
||||||
|
|
||||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||||
@ -25,7 +25,7 @@ export const loader = async ({ params }: Route.LoaderArgs) => {
|
|||||||
|
|
||||||
const baseUrl = NEXT_PUBLIC_WEBAPP_URL();
|
const baseUrl = NEXT_PUBLIC_WEBAPP_URL();
|
||||||
|
|
||||||
const [interSemiBold, interRegular, caveatRegular, shareFrameImage] = await Promise.all([
|
const [interSemiBold, interRegular, caveatRegular] = await Promise.all([
|
||||||
fetch(new URL(`${baseUrl}/fonts/inter-semibold.ttf`, import.meta.url)).then(async (res) =>
|
fetch(new URL(`${baseUrl}/fonts/inter-semibold.ttf`, import.meta.url)).then(async (res) =>
|
||||||
res.arrayBuffer(),
|
res.arrayBuffer(),
|
||||||
),
|
),
|
||||||
@ -35,9 +35,6 @@ export const loader = async ({ params }: Route.LoaderArgs) => {
|
|||||||
fetch(new URL(`${baseUrl}/fonts/caveat-regular.ttf`, import.meta.url)).then(async (res) =>
|
fetch(new URL(`${baseUrl}/fonts/caveat-regular.ttf`, import.meta.url)).then(async (res) =>
|
||||||
res.arrayBuffer(),
|
res.arrayBuffer(),
|
||||||
),
|
),
|
||||||
fetch(new URL(`${baseUrl}/static/og-share-frame2.png`, import.meta.url)).then(async (res) =>
|
|
||||||
res.arrayBuffer(),
|
|
||||||
),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const recipientOrSender: ShareHandlerAPIResponse = await fetch(
|
const recipientOrSender: ShareHandlerAPIResponse = await fetch(
|
||||||
@ -66,65 +63,100 @@ export const loader = async ({ params }: Route.LoaderArgs) => {
|
|||||||
return sender.name || sender.email;
|
return sender.name || sender.email;
|
||||||
});
|
});
|
||||||
|
|
||||||
return new ImageResponse(
|
// Generate SVG using Satori
|
||||||
(
|
const svg = await satori(
|
||||||
<div tw="relative flex h-full w-full bg-white">
|
<div
|
||||||
{/* @ts-expect-error Lack of typing from ImageResponse */}
|
style={{
|
||||||
<img src={shareFrameImage} alt="og-share-frame" tw="absolute inset-0 w-full h-full" />
|
display: 'flex',
|
||||||
|
height: '100%',
|
||||||
{signatureImage ? (
|
width: '100%',
|
||||||
<div
|
backgroundColor: 'white',
|
||||||
tw="absolute py-6 px-12 flex items-center justify-center text-center"
|
position: 'relative',
|
||||||
style={{
|
}}
|
||||||
top: `${CARD_OFFSET_TOP}px`,
|
>
|
||||||
left: `${CARD_OFFSET_LEFT}px`,
|
<img
|
||||||
width: `${CARD_WIDTH}px`,
|
src={`${baseUrl}/static/og-share-frame2.png`}
|
||||||
height: `${CARD_HEIGHT}px`,
|
alt="og-share-frame"
|
||||||
}}
|
style={{
|
||||||
>
|
position: 'absolute',
|
||||||
<img src={signatureImage} alt="signature" tw="opacity-60 h-full max-w-[100%]" />
|
inset: 0,
|
||||||
</div>
|
width: '100%',
|
||||||
) : (
|
height: '100%',
|
||||||
<p
|
}}
|
||||||
tw="absolute py-6 px-12 -mt-2 flex items-center justify-center text-center text-slate-500"
|
/>
|
||||||
style={{
|
|
||||||
fontFamily: 'Caveat',
|
|
||||||
fontSize: `${Math.max(
|
|
||||||
Math.min((CARD_WIDTH * 1.5) / signatureName.length, 80),
|
|
||||||
36,
|
|
||||||
)}px`,
|
|
||||||
top: `${CARD_OFFSET_TOP}px`,
|
|
||||||
left: `${CARD_OFFSET_LEFT}px`,
|
|
||||||
width: `${CARD_WIDTH}px`,
|
|
||||||
height: `${CARD_HEIGHT}px`,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{signatureName}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
|
{signatureImage ? (
|
||||||
<div
|
<div
|
||||||
tw="absolute flex w-full"
|
|
||||||
style={{
|
style={{
|
||||||
top: `${CARD_OFFSET_TOP - 78}px`,
|
position: 'absolute',
|
||||||
left: `${CARD_OFFSET_LEFT}px`,
|
padding: '24px 48px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
textAlign: 'center',
|
||||||
|
top: CARD_OFFSET_TOP,
|
||||||
|
left: CARD_OFFSET_LEFT,
|
||||||
|
width: CARD_WIDTH,
|
||||||
|
height: CARD_HEIGHT,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<h2
|
<img
|
||||||
tw="text-xl"
|
src={signatureImage}
|
||||||
|
alt="signature"
|
||||||
style={{
|
style={{
|
||||||
color: '#828282',
|
opacity: 0.6,
|
||||||
fontFamily: 'Inter',
|
height: '100%',
|
||||||
fontWeight: 700,
|
maxWidth: '100%',
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
{isRecipient ? 'Document Signed!' : 'Document Sent!'}
|
|
||||||
</h2>
|
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
padding: '24px 48px',
|
||||||
|
marginTop: '-8px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
textAlign: 'center',
|
||||||
|
color: '#64748b',
|
||||||
|
fontFamily: 'Caveat',
|
||||||
|
fontSize: Math.max(Math.min((CARD_WIDTH * 1.5) / signatureName.length, 80), 36),
|
||||||
|
top: CARD_OFFSET_TOP,
|
||||||
|
left: CARD_OFFSET_LEFT,
|
||||||
|
width: CARD_WIDTH,
|
||||||
|
height: CARD_HEIGHT,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{signatureName}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
display: 'flex',
|
||||||
|
width: '100%',
|
||||||
|
top: CARD_OFFSET_TOP - 78,
|
||||||
|
left: CARD_OFFSET_LEFT,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
style={{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#828282',
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: 700,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{isRecipient ? 'Document Signed!' : 'Document Sent!'}
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
),
|
</div>,
|
||||||
{
|
{
|
||||||
...IMAGE_SIZE,
|
width: IMAGE_SIZE.width,
|
||||||
|
height: IMAGE_SIZE.height,
|
||||||
fonts: [
|
fonts: [
|
||||||
{
|
{
|
||||||
name: 'Caveat',
|
name: 'Caveat',
|
||||||
@ -134,20 +166,27 @@ export const loader = async ({ params }: Route.LoaderArgs) => {
|
|||||||
{
|
{
|
||||||
name: 'Inter',
|
name: 'Inter',
|
||||||
data: interRegular,
|
data: interRegular,
|
||||||
style: 'normal',
|
|
||||||
weight: 400,
|
weight: 400,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Inter',
|
name: 'Inter',
|
||||||
data: interSemiBold,
|
data: interSemiBold,
|
||||||
style: 'normal',
|
|
||||||
weight: 600,
|
weight: 600,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
headers: {
|
|
||||||
'Access-Control-Allow-Origin': '*',
|
|
||||||
'Access-Control-Allow-Methods': 'GET, OPTIONS',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Convert SVG to PNG using sharp
|
||||||
|
const pngBuffer = await sharp(Buffer.from(svg)).toFormat('png').toBuffer();
|
||||||
|
|
||||||
|
return new Response(pngBuffer, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'image/png',
|
||||||
|
'Content-Length': pngBuffer.length.toString(),
|
||||||
|
'Cache-Control': 'public, max-age=31536000, immutable',
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
'Access-Control-Allow-Methods': 'GET, OPTIONS',
|
||||||
|
},
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,9 +3,8 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "cross-env NODE_ENV=production bunx --bun vite build",
|
"build": "cross-env NODE_ENV=production react-router build",
|
||||||
"dev": "bunx --bun vite",
|
"dev": "react-router dev",
|
||||||
"dev:node": "react-router dev",
|
|
||||||
"start": "cross-env NODE_ENV=production node dist/server/index.js",
|
"start": "cross-env NODE_ENV=production node dist/server/index.js",
|
||||||
"clean": "rimraf .react-router && rimraf node_modules",
|
"clean": "rimraf .react-router && rimraf node_modules",
|
||||||
"typecheck": "react-router typegen && tsc",
|
"typecheck": "react-router typegen && tsc",
|
||||||
@ -26,10 +25,10 @@
|
|||||||
"@hono/trpc-server": "^0.3.4",
|
"@hono/trpc-server": "^0.3.4",
|
||||||
"@hono/zod-validator": "^0.4.2",
|
"@hono/zod-validator": "^0.4.2",
|
||||||
"@hookform/resolvers": "^3.1.0",
|
"@hookform/resolvers": "^3.1.0",
|
||||||
"@lingui/core": "^4.11.3",
|
"@lingui/core": "^5.2.0",
|
||||||
"@lingui/detect-locale": "^4.11.1",
|
"@lingui/detect-locale": "^5.2.0",
|
||||||
"@lingui/macro": "^4.11.3",
|
"@lingui/macro": "^5.2.0",
|
||||||
"@lingui/react": "^4.11.3",
|
"@lingui/react": "^5.2.0",
|
||||||
"@oslojs/crypto": "^1.0.1",
|
"@oslojs/crypto": "^1.0.1",
|
||||||
"@oslojs/encoding": "^1.1.0",
|
"@oslojs/encoding": "^1.1.0",
|
||||||
"@react-router/node": "^7.1.5",
|
"@react-router/node": "^7.1.5",
|
||||||
@ -62,6 +61,7 @@
|
|||||||
"recharts": "^2.7.2",
|
"recharts": "^2.7.2",
|
||||||
"remeda": "^2.17.3",
|
"remeda": "^2.17.3",
|
||||||
"remix-themes": "^2.0.4",
|
"remix-themes": "^2.0.4",
|
||||||
|
"satori": "^0.12.1",
|
||||||
"sharp": "0.32.6",
|
"sharp": "0.32.6",
|
||||||
"tailwindcss": "^3.4.15",
|
"tailwindcss": "^3.4.15",
|
||||||
"ts-pattern": "^5.0.5",
|
"ts-pattern": "^5.0.5",
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import handle from 'hono-react-router-adapter/node';
|
|||||||
|
|
||||||
import server from '.';
|
import server from '.';
|
||||||
import * as build from '../build/server';
|
import * as build from '../build/server';
|
||||||
import { getLoadContext } from './load-context';
|
|
||||||
|
|
||||||
server.use(
|
server.use(
|
||||||
serveStatic({
|
serveStatic({
|
||||||
@ -13,6 +12,6 @@ server.use(
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const handler = handle(build, server, { getLoadContext });
|
const handler = handle(build, server);
|
||||||
|
|
||||||
serve({ fetch: handler.fetch, port: 3000 });
|
serve({ fetch: handler.fetch, port: 3000 });
|
||||||
|
|||||||
@ -1,9 +1,30 @@
|
|||||||
import { getContext } from 'hono/context-storage';
|
import { getContext } from 'hono/context-storage';
|
||||||
import { redirect } from 'react-router';
|
import { redirect } from 'react-router';
|
||||||
import type { HonoEnv } from 'server';
|
import type { HonoEnv } from 'server';
|
||||||
|
import type { AppContext } from 'server/context';
|
||||||
|
|
||||||
import type { AppSession } from '@documenso/lib/client-only/providers/session';
|
import type { AppSession } from '@documenso/lib/client-only/providers/session';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the full context passed to the loader.
|
||||||
|
*
|
||||||
|
* @returns The full app context.
|
||||||
|
*/
|
||||||
|
export const getOptionalLoaderContext = (): AppContext => {
|
||||||
|
const { context } = getContext<HonoEnv>().var;
|
||||||
|
return context;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the session extracted from the app context.
|
||||||
|
*
|
||||||
|
* @returns The session, or null if not authenticated.
|
||||||
|
*/
|
||||||
|
export const getOptionalLoaderSession = (): AppSession | null => {
|
||||||
|
const { context } = getContext<HonoEnv>().var;
|
||||||
|
return context.session;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the session context or throws a redirect to signin if it is not present.
|
* Returns the session context or throws a redirect to signin if it is not present.
|
||||||
*/
|
*/
|
||||||
@ -17,11 +38,6 @@ export const getLoaderSession = (): AppSession => {
|
|||||||
return session;
|
return session;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getOptionalLoaderSession = (): AppSession | null => {
|
|
||||||
const { context } = getContext<HonoEnv>().var;
|
|
||||||
return context.session;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the team session context or throws a redirect to signin if it is not present.
|
* Returns the team session context or throws a redirect to signin if it is not present.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -22,50 +22,59 @@ export default defineConfig({
|
|||||||
plugins: [tailwindcss, autoprefixer],
|
plugins: [tailwindcss, autoprefixer],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ssr: {
|
|
||||||
noExternal: [
|
|
||||||
'react-dropzone',
|
|
||||||
'recharts',
|
|
||||||
'superjson',
|
|
||||||
// '@node-rs/bcrypt-wasm32-wasi',
|
|
||||||
// '@noble/ciphers/chacha',
|
|
||||||
// '@noble/ciphers/utils',
|
|
||||||
// '@noble/ciphers/webcrypto/utils',
|
|
||||||
// '@noble/hashes/sha256a',
|
|
||||||
// '@node-rs/bcrypt',
|
|
||||||
// 'crypto',
|
|
||||||
// '@documenso/assets',
|
|
||||||
// '@documenso/ee',
|
|
||||||
// '@documenso/lib',
|
|
||||||
// '@documenso/prisma',
|
|
||||||
// '@documenso/tailwind-config',
|
|
||||||
// '@documenso/trpc',
|
|
||||||
// '@documenso/ui',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
server: {
|
server: {
|
||||||
port: 3000,
|
port: 3000,
|
||||||
strictPort: true,
|
strictPort: true,
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
reactRouter(),
|
reactRouter(),
|
||||||
lingui(),
|
|
||||||
macrosPlugin(),
|
macrosPlugin(),
|
||||||
|
lingui(),
|
||||||
|
tsconfigPaths(),
|
||||||
serverAdapter({
|
serverAdapter({
|
||||||
entry: 'server/index.ts',
|
entry: 'server/index.ts',
|
||||||
}),
|
}),
|
||||||
tsconfigPaths(),
|
|
||||||
],
|
],
|
||||||
|
ssr: {
|
||||||
|
noExternal: ['react-dropzone', 'plausible-tracker', 'pdfjs-dist'],
|
||||||
|
external: ['@node-rs/bcrypt'],
|
||||||
|
},
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
exclude: ['superjson'],
|
exclude: ['@node-rs/bcrypt'],
|
||||||
// force: true,
|
|
||||||
},
|
|
||||||
build: {
|
|
||||||
commonjsOptions: {
|
|
||||||
include: ['superjson'],
|
|
||||||
},
|
|
||||||
rollupOptions: {
|
|
||||||
external: ['@node-rs/bcrypt'],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Throwing shit at a wall to see what sticks for building below onwards.
|
||||||
|
*/
|
||||||
|
// resolve: {
|
||||||
|
// alias: {
|
||||||
|
// // https: 'node:https',
|
||||||
|
// // '.prisma/client/default': '../../node_modules/.prisma/client/default.js',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// optimizeDeps: {
|
||||||
|
// include: [],
|
||||||
|
// },
|
||||||
|
// ssr: {
|
||||||
|
// // noExternal: true,
|
||||||
|
// noExternal: [
|
||||||
|
// '@documenso/assets',
|
||||||
|
// '@documenso/ee',
|
||||||
|
// '@documenso/lib',
|
||||||
|
// '@documenso/prisma',
|
||||||
|
// '@documenso/tailwind-config',
|
||||||
|
// '@documenso/trpc',
|
||||||
|
// '@documenso/ui',
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
// build: {
|
||||||
|
// rollupOptions: {
|
||||||
|
// external: [
|
||||||
|
// '@node-rs/bcrypt',
|
||||||
|
// '@documenso/pdf-sign',
|
||||||
|
// 'nodemailer',
|
||||||
|
// 'playwright',
|
||||||
|
// '@aws-sdk/cloudfront-signer',
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
// },
|
||||||
});
|
});
|
||||||
|
|||||||
@ -9,7 +9,7 @@ const config: LinguiConfig = {
|
|||||||
catalogs: [
|
catalogs: [
|
||||||
{
|
{
|
||||||
path: '<rootDir>/packages/lib/translations/{locale}/web',
|
path: '<rootDir>/packages/lib/translations/{locale}/web',
|
||||||
include: ['apps/web/src', 'packages/ui', 'packages/lib', 'packages/email'],
|
include: ['apps/remix/src', 'packages/ui', 'packages/lib', 'packages/email'],
|
||||||
exclude: ['**/node_modules/**'],
|
exclude: ['**/node_modules/**'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
1738
package-lock.json
generated
1738
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -43,7 +43,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^17.7.1",
|
"@commitlint/cli": "^17.7.1",
|
||||||
"@commitlint/config-conventional": "^17.7.0",
|
"@commitlint/config-conventional": "^17.7.0",
|
||||||
"@lingui/cli": "^4.11.3",
|
"@lingui/cli": "^5.2.0",
|
||||||
"@trigger.dev/cli": "^2.3.18",
|
"@trigger.dev/cli": "^2.3.18",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
"dotenv-cli": "^7.3.0",
|
"dotenv-cli": "^7.3.0",
|
||||||
@ -65,7 +65,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@documenso/pdf-sign": "^0.1.0",
|
"@documenso/pdf-sign": "^0.1.0",
|
||||||
"@documenso/prisma": "^0.0.0",
|
"@documenso/prisma": "^0.0.0",
|
||||||
"@lingui/core": "^4.11.3",
|
"@lingui/conf": "^5.2.0",
|
||||||
|
"@lingui/core": "^5.2.0",
|
||||||
"inngest-cli": "^0.29.1",
|
"inngest-cli": "^0.29.1",
|
||||||
"luxon": "^3.5.0",
|
"luxon": "^3.5.0",
|
||||||
"mupdf": "^1.0.0",
|
"mupdf": "^1.0.0",
|
||||||
|
|||||||
@ -35,6 +35,8 @@
|
|||||||
"@react-email/section": "0.0.10",
|
"@react-email/section": "0.0.10",
|
||||||
"@react-email/tailwind": "0.0.9",
|
"@react-email/tailwind": "0.0.9",
|
||||||
"@react-email/text": "0.0.6",
|
"@react-email/text": "0.0.6",
|
||||||
|
"@lingui/macro": "^5.2.0",
|
||||||
|
"@lingui/react": "^5.2.0",
|
||||||
"nodemailer": "^6.9.9",
|
"nodemailer": "^6.9.9",
|
||||||
"react-email": "^1.9.5",
|
"react-email": "^1.9.5",
|
||||||
"resend": "^2.0.0"
|
"resend": "^2.0.0"
|
||||||
|
|||||||
@ -25,9 +25,9 @@
|
|||||||
"@documenso/prisma": "*",
|
"@documenso/prisma": "*",
|
||||||
"@documenso/signing": "*",
|
"@documenso/signing": "*",
|
||||||
"@honeybadger-io/js": "^6.10.1",
|
"@honeybadger-io/js": "^6.10.1",
|
||||||
"@lingui/core": "^4.11.3",
|
"@lingui/core": "^5.2.0",
|
||||||
"@lingui/macro": "^4.11.3",
|
"@lingui/macro": "^5.2.0",
|
||||||
"@lingui/react": "^4.11.3",
|
"@lingui/react": "^5.2.0",
|
||||||
"@noble/ciphers": "0.4.0",
|
"@noble/ciphers": "0.4.0",
|
||||||
"@noble/hashes": "1.3.2",
|
"@noble/hashes": "1.3.2",
|
||||||
"@node-rs/bcrypt": "^1.10.0",
|
"@node-rs/bcrypt": "^1.10.0",
|
||||||
|
|||||||
@ -5,6 +5,9 @@ import type { PDFDocument } from 'pdf-lib';
|
|||||||
import { RotationTypes, degrees, radiansToDegrees } from 'pdf-lib';
|
import { RotationTypes, degrees, radiansToDegrees } from 'pdf-lib';
|
||||||
import { P, match } from 'ts-pattern';
|
import { P, match } from 'ts-pattern';
|
||||||
|
|
||||||
|
// Todo: Check if this is okay to do compared to the old approach.
|
||||||
|
import fontCaveat from '@documenso/assets/fonts/caveat.ttf?inline';
|
||||||
|
import fontNoto from '@documenso/assets/fonts/noto-sans.ttf?inline';
|
||||||
import {
|
import {
|
||||||
DEFAULT_HANDWRITING_FONT_SIZE,
|
DEFAULT_HANDWRITING_FONT_SIZE,
|
||||||
DEFAULT_STANDARD_FONT_SIZE,
|
DEFAULT_STANDARD_FONT_SIZE,
|
||||||
@ -25,20 +28,8 @@ import {
|
|||||||
ZRadioFieldMeta,
|
ZRadioFieldMeta,
|
||||||
ZTextFieldMeta,
|
ZTextFieldMeta,
|
||||||
} from '../../types/field-meta';
|
} from '../../types/field-meta';
|
||||||
import { env } from '../../utils/env';
|
|
||||||
|
|
||||||
export const insertFieldInPDF = async (pdf: PDFDocument, field: FieldWithSignature) => {
|
export const insertFieldInPDF = async (pdf: PDFDocument, field: FieldWithSignature) => {
|
||||||
const fontCaveatUri = env('FONT_CAVEAT_URI');
|
|
||||||
const fontNotoSansUri = env('FONT_NOTO_SANS_URI');
|
|
||||||
|
|
||||||
if (!fontCaveatUri || !fontNotoSansUri) {
|
|
||||||
throw new Error('Missing font URI');
|
|
||||||
}
|
|
||||||
|
|
||||||
const fontCaveat = await fetch(fontCaveatUri).then(async (res) => res.arrayBuffer());
|
|
||||||
|
|
||||||
const fontNoto = await fetch(fontNotoSansUri).then(async (res) => res.arrayBuffer());
|
|
||||||
|
|
||||||
const isSignatureField = isSignatureFieldType(field.type);
|
const isSignatureField = isSignatureFieldType(field.type);
|
||||||
|
|
||||||
pdf.registerFontkit(fontkit);
|
pdf.registerFontkit(fontkit);
|
||||||
|
|||||||
@ -29,8 +29,8 @@
|
|||||||
"@documenso/lib": "*",
|
"@documenso/lib": "*",
|
||||||
"@hello-pangea/dnd": "^16.6.0",
|
"@hello-pangea/dnd": "^16.6.0",
|
||||||
"@hookform/resolvers": "^3.3.0",
|
"@hookform/resolvers": "^3.3.0",
|
||||||
"@lingui/macro": "^4.11.3",
|
"@lingui/macro": "^5.2.0",
|
||||||
"@lingui/react": "^4.11.3",
|
"@lingui/react": "^5.2.0",
|
||||||
"@radix-ui/react-accordion": "^1.1.1",
|
"@radix-ui/react-accordion": "^1.1.1",
|
||||||
"@radix-ui/react-alert-dialog": "^1.0.3",
|
"@radix-ui/react-alert-dialog": "^1.0.3",
|
||||||
"@radix-ui/react-aspect-ratio": "^1.0.2",
|
"@radix-ui/react-aspect-ratio": "^1.0.2",
|
||||||
|
|||||||
Reference in New Issue
Block a user