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
+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" />