build: standardise on react 19 and deduplicate deps

Eliminates dual React ecosystems and reduces dependency
duplication by consolidating on a single React version and
expanding the pnpm workspace catalog.

- Upgrade all packages from React 18 to React 19
- Remove @types/react and @types/node overrides (no longer
  needed with single React version)
- Standardise @types/node to ^22 across all packages
- Add prisma-kysely>@prisma/internals override to eliminate
  old prisma 6.16.x subtree
- Fix React 19 type changes: useRef requires initial value,
  JSX namespace needs explicit import, RefObject includes null
- Expand catalog with 14 new entries (ai, dotenv, pino,
  playwright, prisma tooling, nodemailer, pdfjs-dist, etc.)
- Catalog radix-ui, next, lucide-react, postcss, and
  typescript for docs/openpage-api alignment
- Run pnpm dedupe to collapse peer-dep context duplicates
This commit is contained in:
Lucas Smith
2026-03-01 13:01:26 +11:00
parent 960217c78d
commit f66f01a09a
15 changed files with 10996 additions and 5001 deletions
+10 -10
View File
@@ -10,27 +10,27 @@
"postinstall": "fumadocs-mdx"
},
"dependencies": {
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-tabs": "catalog:",
"fumadocs-core": "16.5.0",
"fumadocs-mdx": "14.2.6",
"fumadocs-ui": "16.5.0",
"lucide-react": "^0.563.0",
"lucide-react": "catalog:",
"mermaid": "^11.12.2",
"next": "16.1.6",
"next": "catalog:",
"next-plausible": "^3.12.5",
"next-themes": "^0.4.6",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react": "catalog:",
"react-dom": "catalog:",
"tailwind-merge": "^3.4.0"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.18",
"@types/mdx": "^2.0.13",
"@types/node": "^25.1.0",
"@types/react": "^19.2.10",
"@types/react-dom": "^19.2.3",
"postcss": "^8.5.6",
"@types/node": "catalog:",
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
"postcss": "catalog:",
"tailwindcss": "^4.1.18",
"typescript": "^5.9.3"
"typescript": "catalog:"
}
}
+3 -1
View File
@@ -12,7 +12,9 @@
"dependencies": {
"@documenso/prisma": "workspace:*",
"luxon": "catalog:",
"next": "16.1.6"
"next": "catalog:",
"react": "catalog:",
"react-dom": "catalog:"
},
"devDependencies": {
"@types/node": "catalog:",
+17 -18
View File
@@ -51,39 +51,39 @@
"@ts-rest/core": "catalog:",
"@ts-rest/open-api": "catalog:",
"@ts-rest/serverless": "catalog:",
"dotenv": "^17.2.3",
"dotenv-cli": "^11.0.0",
"dotenv": "catalog:",
"dotenv-cli": "catalog:",
"eslint": "catalog:",
"husky": "^9.1.7",
"inngest-cli": "^1.16.1",
"lint-staged": "^16.2.7",
"nanoid": "catalog:",
"nodemailer": "^7.0.10",
"pdfjs-dist": "5.4.296",
"pino": "^9.14.0",
"pino-pretty": "^13.1.2",
"playwright": "1.56.1",
"nodemailer": "catalog:",
"pdfjs-dist": "catalog:",
"pino": "catalog:",
"pino-pretty": "catalog:",
"playwright": "catalog:",
"prettier": "catalog:",
"prisma": "catalog:",
"prisma-extension-kysely": "^3.0.0",
"prisma-json-types-generator": "^3.6.2",
"prisma-kysely": "^2.3.0",
"prisma-extension-kysely": "catalog:",
"prisma-json-types-generator": "catalog:",
"prisma-kysely": "catalog:",
"rimraf": "^6.1.2",
"superjson": "catalog:",
"turbo": "^2.8.12",
"vite": "catalog:",
"vite-plugin-static-copy": "^3.1.4",
"zod-openapi": "^4.2.4",
"zod-prisma-types": "3.3.5"
"zod-openapi": "catalog:",
"zod-prisma-types": "catalog:"
},
"dependencies": {
"@ai-sdk/google-vertex": "3.0.81",
"@ai-sdk/google-vertex": "catalog:",
"@documenso/prisma": "workspace:*",
"@libpdf/core": "^0.2.12",
"@lingui/conf": "^5.6.0",
"@lingui/core": "catalog:",
"@prisma/extension-read-replicas": "^0.4.1",
"ai": "^5.0.104",
"ai": "catalog:",
"cron-parser": "^5.5.0",
"luxon": "catalog:",
"posthog-node": "catalog:",
@@ -94,13 +94,12 @@
"pnpm": {
"overrides": {
"lodash": "4.17.23",
"pdfjs-dist": "5.4.296",
"pdfjs-dist": "$pdfjs-dist",
"typescript": "5.6.2",
"zod": "$zod",
"fumadocs-mdx>zod": "^4.3.5",
"@types/react": "18.3.27",
"@types/node": "20.19.25",
"jiti": "2.6.1"
"jiti": "2.6.1",
"prisma-kysely>@prisma/internals": "^6.19.0"
},
"patchedDependencies": {
"@ai-sdk/google-vertex@3.0.81": "patches/@ai-sdk__google-vertex@3.0.81.patch"
+1 -1
View File
@@ -37,7 +37,7 @@
"@react-email/section": "0.0.16",
"@react-email/tailwind": "^2.0.1",
"@react-email/text": "0.1.5",
"nodemailer": "^7.0.10",
"nodemailer": "catalog:",
"react-email": "^5.0.6",
"resend": "^6.5.2"
},
@@ -11,7 +11,7 @@ export const useAutoSave = <T, R = void>(
) => {
const { delay = 2000 } = options;
const saveTimeoutRef = useRef<NodeJS.Timeout>();
const saveTimeoutRef = useRef<NodeJS.Timeout>(undefined);
const saveQueueRef = useRef<SaveRequest<T, R>[]>([]);
const isProcessingRef = useRef(false);
+5 -5
View File
@@ -15,7 +15,7 @@
"clean": "rimraf node_modules"
},
"dependencies": {
"@ai-sdk/google-vertex": "3.0.81",
"@ai-sdk/google-vertex": "catalog:",
"@aws-sdk/client-s3": "catalog:",
"@aws-sdk/client-sesv2": "catalog:",
"@aws-sdk/cloudfront-signer": "catalog:",
@@ -38,7 +38,7 @@
"@sindresorhus/slugify": "^3.0.0",
"@team-plain/typescript-sdk": "^5.11.0",
"@vvo/tzdb": "^6.196.0",
"ai": "^5.0.104",
"ai": "catalog:",
"csv-parse": "^6.1.0",
"inngest": "^3.45.1",
"jose": "^6.1.2",
@@ -49,9 +49,9 @@
"oslo": "^0.17.0",
"p-map": "^7.0.4",
"pg": "^8.16.3",
"pino": "^9.14.0",
"pino-pretty": "^13.1.2",
"playwright": "1.56.1",
"pino": "catalog:",
"pino-pretty": "catalog:",
"playwright": "catalog:",
"posthog-js": "catalog:",
"posthog-node": "catalog:",
"react": "catalog:",
+6 -6
View File
@@ -25,16 +25,16 @@
"kysely": "catalog:",
"nanoid": "catalog:",
"prisma": "catalog:",
"prisma-extension-kysely": "^3.0.0",
"prisma-kysely": "^2.3.0",
"prisma-json-types-generator": "^3.6.2",
"prisma-extension-kysely": "catalog:",
"prisma-kysely": "catalog:",
"prisma-json-types-generator": "catalog:",
"ts-pattern": "catalog:",
"zod": "catalog:",
"zod-prisma-types": "3.3.5"
"zod-prisma-types": "catalog:"
},
"devDependencies": {
"dotenv": "^17.2.3",
"dotenv-cli": "^11.0.0",
"dotenv": "catalog:",
"dotenv-cli": "catalog:",
"tsx": "catalog:",
"typescript": "catalog:"
}
+1 -1
View File
@@ -11,7 +11,7 @@
"@tailwindcss/container-queries": "^0.1.1",
"@tailwindcss/typography": "^0.5.19",
"autoprefixer": "catalog:",
"postcss": "^8.5.6",
"postcss": "catalog:",
"tailwindcss": "catalog:",
"tailwindcss-animate": "catalog:"
},
+1 -1
View File
@@ -25,7 +25,7 @@
"ts-pattern": "catalog:",
"zod": "catalog:",
"zod-form-data": "^2.0.8",
"zod-openapi": "^4.2.4"
"zod-openapi": "catalog:"
},
"devDependencies": {
"@types/formidable": "catalog:"
+3 -3
View File
@@ -48,7 +48,7 @@ export const SigningCard3D = ({
const [trackMouse, setTrackMouse] = useState(false);
const timeoutRef = useRef<number | undefined>();
const timeoutRef = useRef<number | undefined>(undefined);
const cardX = useMotionValue(0);
const cardY = useMotionValue(0);
@@ -184,7 +184,7 @@ const SigningCardContent = ({ className, name, signature }: SigningCardContentPr
))
.with({ typedSignature: P.string }, (signature) => (
<span
className="text-muted-foreground/60 group-hover:text-primary/80 break-all font-semibold duration-300"
className="text-muted-foreground/60 group-hover:text-primary/80 font-semibold break-all duration-300"
style={{
fontSize: `max(min(4rem, ${(100 / signature.typedSignature.length / 2).toFixed(
4,
@@ -196,7 +196,7 @@ const SigningCardContent = ({ className, name, signature }: SigningCardContentPr
))
.otherwise(() => (
<span
className="text-muted-foreground/60 group-hover:text-primary/80 break-all font-semibold duration-300"
className="text-muted-foreground/60 group-hover:text-primary/80 font-semibold break-all duration-300"
style={{
fontSize: `max(min(4rem, ${(100 / name.length / 2).toFixed(4)}cqw), 1.875rem)`,
}}
+28 -28
View File
@@ -31,33 +31,33 @@
"@hookform/resolvers": "catalog:",
"@lingui/macro": "catalog:",
"@lingui/react": "catalog:",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-alert-dialog": "^1.1.15",
"@radix-ui/react-aspect-ratio": "^1.1.8",
"@radix-ui/react-avatar": "^1.1.11",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-context-menu": "^2.2.16",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-hover-card": "^1.1.15",
"@radix-ui/react-label": "^2.1.8",
"@radix-ui/react-menubar": "^1.1.16",
"@radix-ui/react-navigation-menu": "^1.2.14",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-progress": "^1.1.8",
"@radix-ui/react-radio-group": "^1.3.8",
"@radix-ui/react-scroll-area": "^1.2.10",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-separator": "^1.1.8",
"@radix-ui/react-slider": "^1.3.6",
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-toast": "^1.2.15",
"@radix-ui/react-toggle": "^1.1.10",
"@radix-ui/react-toggle-group": "^1.1.11",
"@radix-ui/react-tooltip": "^1.2.8",
"@radix-ui/react-accordion": "catalog:",
"@radix-ui/react-alert-dialog": "catalog:",
"@radix-ui/react-aspect-ratio": "catalog:",
"@radix-ui/react-avatar": "catalog:",
"@radix-ui/react-checkbox": "catalog:",
"@radix-ui/react-collapsible": "catalog:",
"@radix-ui/react-context-menu": "catalog:",
"@radix-ui/react-dialog": "catalog:",
"@radix-ui/react-dropdown-menu": "catalog:",
"@radix-ui/react-hover-card": "catalog:",
"@radix-ui/react-label": "catalog:",
"@radix-ui/react-menubar": "catalog:",
"@radix-ui/react-navigation-menu": "catalog:",
"@radix-ui/react-popover": "catalog:",
"@radix-ui/react-progress": "catalog:",
"@radix-ui/react-radio-group": "catalog:",
"@radix-ui/react-scroll-area": "catalog:",
"@radix-ui/react-select": "catalog:",
"@radix-ui/react-separator": "catalog:",
"@radix-ui/react-slider": "catalog:",
"@radix-ui/react-slot": "catalog:",
"@radix-ui/react-switch": "catalog:",
"@radix-ui/react-tabs": "catalog:",
"@radix-ui/react-toast": "catalog:",
"@radix-ui/react-toggle": "catalog:",
"@radix-ui/react-toggle-group": "catalog:",
"@radix-ui/react-tooltip": "catalog:",
"@scure/base": "catalog:",
"@tanstack/react-table": "^8.21.3",
"class-variance-authority": "^0.7.1",
@@ -67,7 +67,7 @@
"lucide-react": "catalog:",
"luxon": "catalog:",
"perfect-freehand": "^1.2.2",
"pdfjs-dist": "5.4.296",
"pdfjs-dist": "catalog:",
"react": "catalog:",
"react-colorful": "^5.6.1",
"react-day-picker": "^8.10.1",
@@ -1,7 +1,9 @@
import React from 'react';
import type { RecipientRole } from '@prisma/client';
import { BadgeCheck, Copy, Eye, PencilLine, User } from 'lucide-react';
export const ROLE_ICONS: Record<RecipientRole, JSX.Element> = {
export const ROLE_ICONS: Record<RecipientRole, React.ReactNode> = {
SIGNER: <PencilLine className="h-4 w-4" />,
APPROVER: <BadgeCheck className="h-4 w-4" />,
CC: <Copy className="h-4 w-4" />,
@@ -17,7 +17,7 @@ import { getSvgPathFromStroke } from './helper';
import { Point } from './point';
import { SignaturePadColorPicker } from './signature-pad-color-picker';
const checkSignatureValidity = (element: RefObject<HTMLCanvasElement>) => {
const checkSignatureValidity = (element: RefObject<HTMLCanvasElement | null>) => {
if (!element.current) {
return false;
}
@@ -291,10 +291,10 @@ export const SignaturePadDraw = ({
<SignaturePadColorPicker selectedColor={selectedColor} setSelectedColor={setSelectedColor} />
<div className="absolute bottom-3 right-3 flex gap-2">
<div className="absolute right-3 bottom-3 flex gap-2">
<button
type="button"
className="rounded-full p-0 text-[0.688rem] text-muted-foreground/60 ring-offset-background hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
className="text-muted-foreground/60 ring-offset-background hover:text-muted-foreground focus-visible:ring-ring rounded-full p-0 text-[0.688rem] focus-visible:ring-2 focus-visible:outline-none"
onClick={() => onClearClick()}
>
<Trans>Clear Signature</Trans>
@@ -303,7 +303,7 @@ export const SignaturePadDraw = ({
{isSignatureValid === false && (
<div className="absolute bottom-4 left-4 flex gap-2">
<span className="text-xs text-destructive">
<span className="text-destructive text-xs">
<Trans>Signature is too small</Trans>
</span>
</div>
@@ -314,7 +314,7 @@ export const SignaturePadDraw = ({
<button
type="button"
title="undo"
className="rounded-full p-0 text-[0.688rem] text-muted-foreground/60 ring-offset-background hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
className="text-muted-foreground/60 ring-offset-background hover:text-muted-foreground focus-visible:ring-ring rounded-full p-0 text-[0.688rem] focus-visible:ring-2 focus-visible:outline-none"
onClick={onUndoClick}
>
<Undo2 className="h-4 w-4" />
+10853 -4914
View File
File diff suppressed because it is too large Load Diff
+59 -6
View File
@@ -4,8 +4,8 @@ packages:
catalog:
# Core
react: ^18
react-dom: ^18
react: ^19.2.4
react-dom: ^19.2.4
typescript: 5.6.2
zod: ^3.25.76
@@ -24,6 +24,7 @@ catalog:
'@aws-sdk/signature-v4-crt': ^3.998.0
# Framework
next: 16.1.6
hono: ^4.12.2
'@hono/standard-validator': ^0.2.0
'@tanstack/react-query': 5.90.10
@@ -36,12 +37,40 @@ catalog:
# UI
framer-motion: ^12.23.24
lucide-react: ^0.554.0
lucide-react: ^0.563.0
react-hook-form: ^7.66.1
'@hookform/resolvers': ^3
'@radix-ui/react-accordion': ^1.2.12
'@radix-ui/react-alert-dialog': ^1.1.15
'@radix-ui/react-aspect-ratio': ^1.1.8
'@radix-ui/react-avatar': ^1.1.11
'@radix-ui/react-checkbox': ^1.3.3
'@radix-ui/react-collapsible': ^1.1.12
'@radix-ui/react-context-menu': ^2.2.16
'@radix-ui/react-dialog': ^1.1.15
'@radix-ui/react-dropdown-menu': ^2.1.16
'@radix-ui/react-hover-card': ^1.1.15
'@radix-ui/react-label': ^2.1.8
'@radix-ui/react-menubar': ^1.1.16
'@radix-ui/react-navigation-menu': ^1.2.14
'@radix-ui/react-popover': ^1.1.15
'@radix-ui/react-progress': ^1.1.8
'@radix-ui/react-radio-group': ^1.3.8
'@radix-ui/react-scroll-area': ^1.2.10
'@radix-ui/react-select': ^2.2.6
'@radix-ui/react-separator': ^1.1.8
'@radix-ui/react-slider': ^1.3.6
'@radix-ui/react-slot': ^1.2.4
'@radix-ui/react-switch': ^1.2.6
'@radix-ui/react-tabs': ^1.1.13
'@radix-ui/react-toast': ^1.2.15
'@radix-ui/react-toggle': ^1.1.10
'@radix-ui/react-toggle-group': ^1.1.11
'@radix-ui/react-tooltip': ^1.2.8
react-rnd: ^10.5.2
konva: ^10.0.9
'@napi-rs/canvas': ^0.1.83
postcss: ^8.5.6
tailwindcss: ^3.4.18
autoprefixer: ^10.4.22
tailwindcss-animate: ^1.0.7
@@ -59,24 +88,48 @@ catalog:
# Crypto
'@scure/base': ^1.2.6
# AI
'@ai-sdk/google-vertex': 3.0.81
ai: ^5.0.104
# Email
nodemailer: ^7.0.10
# Observability
posthog-node: 4.18.0
posthog-js: ^1.297.2
pino: ^9.14.0
pino-pretty: ^13.1.2
# Database
kysely: 0.28.8
'@prisma/client': ^6.19.0
prisma: ^6.19.0
prisma-extension-kysely: ^3.0.0
prisma-json-types-generator: ^3.6.2
prisma-kysely: ^2.3.0
zod-prisma-types: 3.3.5
# Build tools
tsx: ^4.20.6
vite: ^7.2.4
eslint: ^8.57.0
prettier: ^3.6.2
dotenv: ^17.2.3
dotenv-cli: ^11.0.0
# PDF / Documents
pdfjs-dist: 5.4.296
# Testing
playwright: 1.56.1
# API
zod-openapi: ^4.2.4
# Types
'@types/react': 18.3.27
'@types/react-dom': ^18
'@types/node': ^20
'@types/react': ^19
'@types/react-dom': ^19
'@types/node': ^22
'@types/luxon': ^3.7.1
'@types/formidable': ^3.4.6