Upgrade frontend toolchain to latest majors

Bump React 19.2, Relay 21, React Router 8, Vite 8 with
@vitejs/plugin-react 6, ESLint 10, GraphQL 17, TypeScript 6,
@types/node 24, and Tailwind 4.3 across the workspaces.

vite-plugin-react 6 (Vite 8) no longer runs Babel, so the Relay
tagged-template transform now runs through @rolldown/plugin-babel
in the console and trust Vite configs.

Relay 21 ships first-party types and enables the ambiguous-alias
check by default; disable that flag to preserve existing queries
and add explicit usePreloadedQuery type arguments where the new
types no longer infer the operation. TypeScript 6 deprecations and
stricter inference are addressed in tsconfigs and call sites.

Keep n8n-node on ESLint 9 and eslint-plugin-react on 7.37.5, the
newest releases compatible with their toolchains.

Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
Émile Ré
2026-06-18 19:10:00 +02:00
parent f1fc2dc0e0
commit f98b73f073
130 changed files with 2228 additions and 1763 deletions

View File

@@ -18,33 +18,34 @@
"@probo/routes": "^1.0.0",
"@probo/ui": "1.0.0",
"clsx": "^2.1.1",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"react-error-boundary": "^6.0.0",
"react-hook-form": "^7.56.4",
"react-pdf": "^10.3.0",
"react-relay": "^20.1.1",
"react-router": "^7.17.0",
"relay-runtime": "^20.1.1",
"react-relay": "^21.0.1",
"react-router": "^8.0.0",
"relay-runtime": "^21.0.1",
"usehooks-ts": "^3.1.1",
"zod": "^3.25.71"
},
"devDependencies": {
"@babel/core": "^7.29.0",
"@probo/eslint-config": "1.0.0",
"@probo/eslint-plugin-relay-types": "^1.0.0",
"@tailwindcss/vite": "^4.1.7",
"@types/node": "^22.15.21",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
"@types/react-relay": "^18.2.1",
"@types/relay-runtime": "^20.1.1",
"@vitejs/plugin-react": "^5.1.4",
"babel-plugin-relay": "^20.1.1",
"eslint": "^9.39.2",
"graphql": "^16.11.0",
"tailwindcss": "^4.1.7",
"typescript": "~5.8.3",
"vite": "^7.3.2"
"@rolldown/plugin-babel": "^0.2.3",
"@tailwindcss/vite": "^4.3.1",
"@types/babel__core": "^7.20.5",
"@types/node": "^24",
"@types/react": "^19.2.17",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.2",
"babel-plugin-relay": "^21.0.1",
"eslint": "^10.5.0",
"graphql": "^17.0.1",
"tailwindcss": "^4.3.1",
"typescript": "~6.0.3",
"vite": "^8.0.16"
},
"volta": {
"node": "24.4.0"

View File

@@ -30,7 +30,7 @@ type Props = {
export function MainLayout(props: Props) {
const { __ } = useTranslate();
const data = usePreloadedQuery(currentTrustGraphQuery, props.queryRef);
const data = usePreloadedQuery<TrustGraphCurrentQuery>(currentTrustGraphQuery, props.queryRef);
const trustCenter = data.currentTrustCenter;
const isAuthenticated = data.viewer != null;

View File

@@ -218,7 +218,7 @@ export function DocumentPage({ queryRef }: Props) {
const [fileData, setFileData] = useState<string | null>(null);
const [exportError, setExportError] = useState<string | null>(null);
const data = usePreloadedQuery(documentPageQuery, queryRef);
const data = usePreloadedQuery<DocumentPageQueryType>(documentPageQuery, queryRef);
const trustCenter = data.currentTrustCenter;
const node = data.node;

View File

@@ -104,7 +104,7 @@ export function NDAPage(props: {
const isMobile = width < 1100;
const isDesktop = !isMobile;
const queryData = usePreloadedQuery(ndaPageQuery, props.queryRef);
const queryData = usePreloadedQuery<NDAPageQueryType>(ndaPageQuery, props.queryRef);
const trustCenter = queryData.currentTrustCenter;
const viewer = queryData.viewer;

View File

@@ -27,7 +27,7 @@ type Props = {
export function SubprocessorsPage({ queryRef }: Props) {
const { __ } = useTranslate();
const data = usePreloadedQuery(currentTrustSubprocessorsQuery, queryRef);
const data = usePreloadedQuery<TrustGraphCurrentSubprocessorsQuery>(currentTrustSubprocessorsQuery, queryRef);
const subprocessors
= data.currentTrustCenter?.subprocessors.edges.map(edge => edge.node) ?? [];

View File

@@ -67,7 +67,7 @@ export function ConnectPage(props: {
const { __ } = useTranslate();
const { toast } = useToast();
const [magicLinkSent, setMagicLinkSent] = useState<boolean>(false);
const interval = useRef<NodeJS.Timeout>(undefined);
const interval = useRef<ReturnType<typeof setTimeout>>(undefined);
const [timer, setTimer] = useState<number>(timerDurationSeconds);
const safeContinueUrl = useSafeContinueUrl();

View File

@@ -14,9 +14,8 @@
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
"baseUrl": ".",
"paths": {
"#/*": ["src/*"]
"#/*": ["./src/*"]
},
/* Linting */

View File

@@ -14,13 +14,20 @@
import { fileURLToPath, URL } from "node:url";
import babel from "@rolldown/plugin-babel";
import tailwindcss from "@tailwindcss/vite";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
// https://vite.dev/config/
// @vitejs/plugin-react@6 (Vite 8) no longer runs Babel, so the Relay tagged
// template transform is applied via @rolldown/plugin-babel instead.
export default defineConfig({
plugins: [react({ babel: { plugins: ["relay"] } }), tailwindcss()],
plugins: [
react(),
babel({ plugins: ["relay"] }),
tailwindcss(),
],
build: {
assetsDir: "assets",
},