From 9e75995d1e06e8ad2e86569f6fbe9be78bfadf6a Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Tue, 17 Feb 2026 11:26:22 +0100 Subject: [PATCH 01/49] upgrade zod --- package.json | 2 +- packages/mcp/package.json | 2 +- packages/template-audiogram/package.json | 2 +- packages/template-code-hike/package.json | 2 +- packages/template-helloworld/package.json | 2 +- packages/template-javascript/package.json | 2 +- packages/template-music-visualization/package.json | 2 +- packages/template-next-app-tailwind/package.json | 2 +- packages/template-next-app/package.json | 2 +- packages/template-next-pages/package.json | 2 +- packages/template-prompt-to-motion-graphics/package.json | 2 +- packages/template-prompt-to-video/package.json | 2 +- packages/template-react-router/package.json | 2 +- packages/template-recorder/package.json | 2 +- packages/template-render-server/package.json | 2 +- packages/template-skia/package.json | 2 +- packages/template-stargazer/package.json | 2 +- packages/template-still/package.json | 2 +- packages/template-three/package.json | 2 +- packages/template-tiktok/package.json | 2 +- packages/template-tts-azure/package.json | 2 +- packages/template-tts-google/package.json | 2 +- packages/template-vercel/package.json | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index 2deb7ac3177..6def162a556 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "react-dom": "19.2.3", "eslint": "9.19.0", "prettier": "3.6.0", - "zod": "3.22.3", + "zod": "4.3.6", "@types/react": "19.2.7", "@types/react-dom": "19.2.3", "@types/node": "20.12.14", diff --git a/packages/mcp/package.json b/packages/mcp/package.json index ef67b3c3ebd..888bcb12d43 100644 --- a/packages/mcp/package.json +++ b/packages/mcp/package.json @@ -25,7 +25,7 @@ "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "1.26.0", - "zod": "4.1.13" + "zod": "4.3.6" }, "peerDependencies": {}, "devDependencies": { diff --git a/packages/template-audiogram/package.json b/packages/template-audiogram/package.json index 2d4f2910f51..c4b4032f4cc 100644 --- a/packages/template-audiogram/package.json +++ b/packages/template-audiogram/package.json @@ -24,7 +24,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", diff --git a/packages/template-code-hike/package.json b/packages/template-code-hike/package.json index 15a54ffd085..384c9548137 100644 --- a/packages/template-code-hike/package.json +++ b/packages/template-code-hike/package.json @@ -17,7 +17,7 @@ "remotion": "workspace:*", "twoslash-cdn": "0.3.1", "polished": "4.3.1", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", diff --git a/packages/template-helloworld/package.json b/packages/template-helloworld/package.json index fef8b70332d..932b6209125 100644 --- a/packages/template-helloworld/package.json +++ b/packages/template-helloworld/package.json @@ -16,7 +16,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", diff --git a/packages/template-javascript/package.json b/packages/template-javascript/package.json index 740393c3e35..29341c5cc93 100644 --- a/packages/template-javascript/package.json +++ b/packages/template-javascript/package.json @@ -15,7 +15,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", diff --git a/packages/template-music-visualization/package.json b/packages/template-music-visualization/package.json index 5f234874d9d..09705d8f2a4 100644 --- a/packages/template-music-visualization/package.json +++ b/packages/template-music-visualization/package.json @@ -21,7 +21,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", diff --git a/packages/template-next-app-tailwind/package.json b/packages/template-next-app-tailwind/package.json index cf69b424d74..927a53087ff 100644 --- a/packages/template-next-app-tailwind/package.json +++ b/packages/template-next-app-tailwind/package.json @@ -31,7 +31,7 @@ "react-dom": "19.2.3", "remotion": "workspace:*", "tailwind-merge": "3.0.1", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@tailwindcss/postcss": "4.1.1", diff --git a/packages/template-next-app/package.json b/packages/template-next-app/package.json index 3626846dcee..90df5ce32c2 100644 --- a/packages/template-next-app/package.json +++ b/packages/template-next-app/package.json @@ -23,7 +23,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", diff --git a/packages/template-next-pages/package.json b/packages/template-next-pages/package.json index 1eea1a70c0f..bc2ed64b4b7 100644 --- a/packages/template-next-pages/package.json +++ b/packages/template-next-pages/package.json @@ -23,7 +23,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@eslint/eslintrc": "3.1.0", diff --git a/packages/template-prompt-to-motion-graphics/package.json b/packages/template-prompt-to-motion-graphics/package.json index 23905015142..b6615007a67 100644 --- a/packages/template-prompt-to-motion-graphics/package.json +++ b/packages/template-prompt-to-motion-graphics/package.json @@ -51,7 +51,7 @@ "remotion": "workspace:*", "tailwind-merge": "3.4.0", "three": "0.178.0", - "zod": "4.1.13" + "zod": "4.3.6" }, "devDependencies": { "@eslint/eslintrc": "3.1.0", diff --git a/packages/template-prompt-to-video/package.json b/packages/template-prompt-to-video/package.json index 7dd521f3a91..062fe2d9502 100644 --- a/packages/template-prompt-to-video/package.json +++ b/packages/template-prompt-to-video/package.json @@ -21,7 +21,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@elevenlabs/elevenlabs-js": "^2.20.0", diff --git a/packages/template-react-router/package.json b/packages/template-react-router/package.json index c0f34fb517a..43caa348d07 100644 --- a/packages/template-react-router/package.json +++ b/packages/template-react-router/package.json @@ -37,7 +37,7 @@ "@tailwindcss/vite": "4.1.1", "vite": "5.4.21", "vite-tsconfig-paths": "^4.2.1", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@react-router/dev": "7.12.0", diff --git a/packages/template-recorder/package.json b/packages/template-recorder/package.json index 5dcc2134a26..1a412f0f478 100644 --- a/packages/template-recorder/package.json +++ b/packages/template-recorder/package.json @@ -44,7 +44,7 @@ "react-dom": "19.2.3", "tailwind-merge": "1.14.0", "tailwindcss-animate": "1.0.7", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", diff --git a/packages/template-render-server/package.json b/packages/template-render-server/package.json index 6ef55e5a107..a5bd14cc822 100644 --- a/packages/template-render-server/package.json +++ b/packages/template-render-server/package.json @@ -21,7 +21,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", diff --git a/packages/template-skia/package.json b/packages/template-skia/package.json index e18c774417a..d691c361ab2 100644 --- a/packages/template-skia/package.json +++ b/packages/template-skia/package.json @@ -19,7 +19,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", diff --git a/packages/template-stargazer/package.json b/packages/template-stargazer/package.json index bafcf19c15c..f3bfd09db76 100644 --- a/packages/template-stargazer/package.json +++ b/packages/template-stargazer/package.json @@ -14,7 +14,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", diff --git a/packages/template-still/package.json b/packages/template-still/package.json index 2a41f18aa24..21bf691029a 100644 --- a/packages/template-still/package.json +++ b/packages/template-still/package.json @@ -32,7 +32,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", diff --git a/packages/template-three/package.json b/packages/template-three/package.json index 15921ba08ed..81c44f253eb 100644 --- a/packages/template-three/package.json +++ b/packages/template-three/package.json @@ -20,7 +20,7 @@ "react-dom": "19.2.3", "remotion": "workspace:*", "three": "0.178.0", - "zod": "3.22.3", + "zod": "4.3.6", "mediabunny": "1.34.2" }, "devDependencies": { diff --git a/packages/template-tiktok/package.json b/packages/template-tiktok/package.json index 598b490879c..6818daa199d 100644 --- a/packages/template-tiktok/package.json +++ b/packages/template-tiktok/package.json @@ -20,7 +20,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", diff --git a/packages/template-tts-azure/package.json b/packages/template-tts-azure/package.json index f81af5280d8..ae77d7c51e3 100644 --- a/packages/template-tts-azure/package.json +++ b/packages/template-tts-azure/package.json @@ -32,6 +32,6 @@ "prettier": "3.6.0", "tsx": "4.19.3", "typescript": "5.9.3", - "zod": "3.22.3" + "zod": "4.3.6" } } diff --git a/packages/template-tts-google/package.json b/packages/template-tts-google/package.json index c4b955fc9e9..02b6a9f9399 100644 --- a/packages/template-tts-google/package.json +++ b/packages/template-tts-google/package.json @@ -37,7 +37,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3" + "zod": "4.3.6" }, "private": true } diff --git a/packages/template-vercel/package.json b/packages/template-vercel/package.json index 2e4f7e8eefd..8dd567159aa 100644 --- a/packages/template-vercel/package.json +++ b/packages/template-vercel/package.json @@ -29,7 +29,7 @@ "react-dom": "19.2.3", "remotion": "workspace:*", "tailwind-merge": "3.0.1", - "zod": "3.22.3" + "zod": "4.3.6" }, "devDependencies": { "@tailwindcss/postcss": "4.1.1", From dd4b86ea648b1cd3c62f293a8622f6f232c941c2 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Tue, 17 Feb 2026 11:28:33 +0100 Subject: [PATCH 02/49] get rid of zod requirement --- bun.lock | 64 ++++++++----------- packages/cli/src/extra-packages.ts | 2 - packages/docs/docs/5-0-migration.mdx | 6 -- packages/docs/docs/schemas.mdx | 2 +- packages/docs/docs/zod-types/index.mdx | 1 - .../src/templates/validate-templates.test.ts | 6 -- .../skills/remotion/rules/parameters.md | 31 ++++++--- packages/studio-shared/src/package-info.ts | 6 -- 8 files changed, 48 insertions(+), 70 deletions(-) diff --git a/bun.lock b/bun.lock index 923e2f43f7f..61090570dce 100644 --- a/bun.lock +++ b/bun.lock @@ -923,7 +923,7 @@ }, "dependencies": { "@modelcontextprotocol/sdk": "1.26.0", - "zod": "4.1.13", + "zod": "4.3.6", }, "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", @@ -1449,7 +1449,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", @@ -1494,7 +1494,7 @@ "react-dom": "19.2.3", "remotion": "workspace:*", "twoslash-cdn": "0.3.1", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", @@ -1514,7 +1514,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", @@ -1533,7 +1533,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", @@ -1554,7 +1554,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", @@ -1580,7 +1580,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@eslint/eslintrc": "3.1.0", @@ -1620,7 +1620,7 @@ "react-dom": "19.2.3", "remotion": "workspace:*", "tailwind-merge": "3.0.1", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@eslint/eslintrc": "3.1.0", @@ -1660,7 +1660,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@eslint/eslintrc": "3.1.0", @@ -1738,7 +1738,7 @@ "remotion": "workspace:*", "tailwind-merge": "3.4.0", "three": "0.178.0", - "zod": "4.1.13", + "zod": "4.3.6", }, "devDependencies": { "@eslint/eslintrc": "3.1.0", @@ -1780,7 +1780,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@elevenlabs/elevenlabs-js": "^2.20.0", @@ -1827,7 +1827,7 @@ "tailwindcss": "4.0.0", "vite": "5.4.21", "vite-tsconfig-paths": "^4.2.1", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@react-router/dev": "7.12.0", @@ -1880,7 +1880,7 @@ "remotion": "workspace:*", "tailwind-merge": "1.14.0", "tailwindcss-animate": "1.0.7", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", @@ -1914,7 +1914,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", @@ -1939,7 +1939,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", @@ -1960,7 +1960,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", @@ -1991,7 +1991,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", @@ -2015,7 +2015,7 @@ "react-dom": "19.2.3", "remotion": "workspace:*", "three": "0.178.0", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", @@ -2039,7 +2039,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@remotion/captions": "workspace:*", @@ -2076,7 +2076,7 @@ "prettier": "3.6.0", "tsx": "4.19.3", "typescript": "5.9.3", - "zod": "3.22.3", + "zod": "4.3.6", }, }, "packages/template-tts-google": { @@ -2099,7 +2099,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "remotion": "workspace:*", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@remotion/eslint-config-flat": "workspace:*", @@ -2132,7 +2132,7 @@ "react-dom": "19.2.3", "remotion": "workspace:*", "tailwind-merge": "3.0.1", - "zod": "3.22.3", + "zod": "4.3.6", }, "devDependencies": { "@eslint/eslintrc": "3.1.0", @@ -2333,7 +2333,7 @@ "sharp": "0.34.5", "three": "0.178.0", "vitest": "4.0.9", - "zod": "3.22.3", + "zod": "4.3.6", }, "packages": { "@aashutoshrathi/word-wrap": ["@aashutoshrathi/word-wrap@1.2.6", "", {}, "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA=="], @@ -7738,7 +7738,7 @@ "zip-stream": ["zip-stream@6.0.1", "", { "dependencies": { "archiver-utils": "5.0.2", "compress-commons": "6.0.2", "readable-stream": "4.7.0" } }, "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA=="], - "zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="], + "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], "zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="], @@ -7752,12 +7752,6 @@ "@ai-sdk/gateway/@vercel/oidc": ["@vercel/oidc@3.0.5", "", {}, "sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw=="], - "@ai-sdk/gateway/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@ai-sdk/openai/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@ai-sdk/provider-utils/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "@algolia/autocomplete-preset-algolia/@algolia/client-search": ["@algolia/client-search@5.24.0", "", { "dependencies": { "@algolia/client-common": "5.24.0", "@algolia/requester-browser-xhr": "5.24.0", "@algolia/requester-fetch": "5.24.0", "@algolia/requester-node-http": "5.24.0" } }, "sha512-k+nuciQuq7WERNNE+hsx3DX636zIy+9R4xdtvW3PANT2a2BDGOv3fv2mta8+QUMcVTVcGe/Mo3QCb4pc1HNoxA=="], "@algolia/autocomplete-preset-algolia/algoliasearch": ["algoliasearch@5.18.0", "", { "dependencies": { "@algolia/client-abtesting": "5.18.0", "@algolia/client-analytics": "5.18.0", "@algolia/client-common": "5.18.0", "@algolia/client-insights": "5.18.0", "@algolia/client-personalization": "5.18.0", "@algolia/client-query-suggestions": "5.18.0", "@algolia/client-search": "5.18.0", "@algolia/ingestion": "1.18.0", "@algolia/monitoring": "1.18.0", "@algolia/recommend": "5.18.0", "@algolia/requester-browser-xhr": "5.18.0", "@algolia/requester-fetch": "5.18.0", "@algolia/requester-node-http": "5.18.0" } }, "sha512-/tfpK2A4FpS0o+S78o3YSdlqXr0MavJIDlFK3XZrlXLy7vaRXJvW5jYg3v5e/wCaF8y0IpMjkYLhoV6QqfpOgw=="], @@ -8828,8 +8822,6 @@ "@remotion/lambda-client/@types/express": ["@types/express@5.0.1", "", { "dependencies": { "@types/body-parser": "1.19.1", "@types/express-serve-static-core": "5.0.4", "@types/serve-static": "1.13.10" } }, "sha512-UZUw8vjpWFXuDnjFTh7/5c2TWDlQqeXHi6hcN7F2XSVT5P+WmUnnbFS3KA6Jnc6IsEqI2qCVu2bK0R0J4A8ZQQ=="], - "@remotion/mcp/zod": ["zod@4.1.13", "", {}, "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig=="], - "@remotion/promo-pages/hls.js": ["hls.js@1.5.19", "", {}, "sha512-C020dKWEJcyvLnrqsFKW4q6D/6IEzKWdhktIS5bgoyEFE8lHgrFBq4RIngdy113abJOlIruhv8qjg7UX8hwxOw=="], "@remotion/promo-pages/tailwindcss": ["tailwindcss@4.1.1", "", {}, "sha512-QNbdmeS979Efzim2g/bEvfuh+fTcIdp1y7gA+sb6OYSW74rt7Cr7M78AKdf6HqWT3d5AiTb7SwTT3sLQxr4/qw=="], @@ -9364,8 +9356,6 @@ "acorn-jsx/acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="], - "ai/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "ajv-formats/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], "ansi-align/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "8.0.0", "is-fullwidth-code-point": "3.0.0", "strip-ansi": "6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], @@ -10020,6 +10010,8 @@ "openai/@types/node": ["@types/node@18.14.6", "", {}, "sha512-93+VvleD3mXwlLI/xASjw0FzKcwzl3OdTCzm1LaRfqgS21gfFtK3zDXM5Op9TeeMsJVOaJ2VRDpT9q4Y3d0AvA=="], + "openai/zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="], + "ora/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], "ora/strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], @@ -10452,8 +10444,6 @@ "template-prompt-to-motion-graphics/typescript-eslint": ["typescript-eslint@8.46.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.46.0", "@typescript-eslint/parser": "8.46.0", "@typescript-eslint/typescript-estree": "8.46.0", "@typescript-eslint/utils": "8.46.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-6+ZrB6y2bT2DX3K+Qd9vn7OFOJR+xSLDj+Aw/N3zBwUt27uTw2sw2TE2+UcY1RiyBZkaGbTkVg9SSdPNUG6aUw=="], - "template-prompt-to-motion-graphics/zod": ["zod@4.1.13", "", {}, "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig=="], - "template-react-router/dotenv": ["dotenv@16.0.3", "", {}, "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ=="], "template-react-router/tailwind-merge": ["tailwind-merge@3.0.1", "", {}, "sha512-AvzE8FmSoXC7nC+oU5GlQJbip2UO7tmOhOfQyOmPhrStOGXHU08j8mZEHZ4BmCqY5dWTCo4ClWkNyRNx1wpT0g=="], @@ -10702,8 +10692,6 @@ "zip-stream/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "3.0.0", "buffer": "6.0.3", "events": "3.3.0", "process": "0.11.10", "string_decoder": "1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], - "zod-to-json-schema/zod": ["zod@4.1.13", "", {}, "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig=="], - "zod-to-ts/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "zustand/react": ["react@19.0.0", "", {}, "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ=="], diff --git a/packages/cli/src/extra-packages.ts b/packages/cli/src/extra-packages.ts index ec1a47652ce..2c03d703565 100644 --- a/packages/cli/src/extra-packages.ts +++ b/packages/cli/src/extra-packages.ts @@ -1,9 +1,7 @@ export const EXTRA_PACKAGES: Record = { - zod: '3.22.3', mediabunny: '1.34.2', }; export const EXTRA_PACKAGES_DOCS: Record = { - zod: 'https://www.remotion.dev/docs/schemas#prerequisites', mediabunny: 'https://www.remotion.dev/docs/mediabunny/version', }; diff --git a/packages/docs/docs/5-0-migration.mdx b/packages/docs/docs/5-0-migration.mdx index 06fef8476a9..cc9787184af 100644 --- a/packages/docs/docs/5-0-migration.mdx +++ b/packages/docs/docs/5-0-migration.mdx @@ -55,12 +55,6 @@ It never made sense to have this prop as transitioned elements need to be positi **Required action**: Remove the `layout` prop. -## Zod should be upgraded to 3.23.8 - -Remotion previously used the types of Zod 3.22.3. With Remotion 5.0, the types of 3.23.8 are used. - -**Required action**: If you use Zod, Upgrade Zod to 3.23.8. - ## `measureSpring()` does not accept `from` and `to` options anymore The values passed in there did not influence the calculation at all. Therefore we removed those options. diff --git a/packages/docs/docs/schemas.mdx b/packages/docs/docs/schemas.mdx index 00a3e80b226..07b858fb1d5 100644 --- a/packages/docs/docs/schemas.mdx +++ b/packages/docs/docs/schemas.mdx @@ -10,7 +10,7 @@ As an alternative to [using TypeScript types](/docs/parameterized-rendering) to ## Prerequisites -If you want to use this feature, install `zod@3.22.3` and [`@remotion/zod-types`](/docs/zod-types) for Remotion-specific types: +If you want to use this feature, install `zod` and [`@remotion/zod-types`](/docs/zod-types) for Remotion-specific types: ```bash npx remotion add @remotion/zod-types zod diff --git a/packages/docs/docs/zod-types/index.mdx b/packages/docs/docs/zod-types/index.mdx index f8404ae8513..aa5c8a9dfa5 100644 --- a/packages/docs/docs/zod-types/index.mdx +++ b/packages/docs/docs/zod-types/index.mdx @@ -10,7 +10,6 @@ import TabItem from '@theme/TabItem'; import {ZodTypesTableOfContents} from './TableOfContents'; Includes utility types and Remotion-specific types for [Zod](https://github.com/colinhacks/zod). -Currently, only Zod version 3.22.3 is supported. In the next major version of Remotion, the Zod version will be updated. ## Installation diff --git a/packages/it-tests/src/templates/validate-templates.test.ts b/packages/it-tests/src/templates/validate-templates.test.ts index 1276c9aa0da..3ecdc50f37a 100644 --- a/packages/it-tests/src/templates/validate-templates.test.ts +++ b/packages/it-tests/src/templates/validate-templates.test.ts @@ -38,12 +38,6 @@ describe('Templates should be valid', () => { expect(body.dependencies.react).toMatch(/^\^?19/); expect(body.dependencies['react-dom']).toMatch(/^\^?19/); - if ( - body.dependencies['zod'] && - !template.shortName.includes('Prompt to Motion Graphics') - ) { - expect(body.dependencies['zod']).toBe('3.22.3'); - } if (body.dependencies['@types/web']) { expect(body.dependencies['@types/web']).toInclude('0.0.166'); } diff --git a/packages/skills/skills/remotion/rules/parameters.md b/packages/skills/skills/remotion/rules/parameters.md index 6ee45788a03..8860800662b 100644 --- a/packages/skills/skills/remotion/rules/parameters.md +++ b/packages/skills/skills/remotion/rules/parameters.md @@ -7,38 +7,38 @@ metadata: To make a video parametrizable, a Zod schema can be added to a composition. -First, `zod` must be installed - it must be exactly version `3.22.3`. +First, `zod` must be installed . Search the project for lockfiles and run the correct command depending on the package manager: If `package-lock.json` is found, use the following command: ```bash -npm i zod@3.22.3 +npm i zod ``` If `bun.lockb` is found, use the following command: ```bash -bun i zod@3.22.3 +bun i zod ``` If `yarn.lock` is found, use the following command: ```bash -yarn add zod@3.22.3 +yarn add zod ``` If `pnpm-lock.yaml` is found, use the following command: ```bash -pnpm i zod@3.22.3 +pnpm i zod ``` Then, a Zod schema can be defined alongside the component: ```tsx title="src/MyComposition.tsx" -import {z} from 'zod'; +import { z } from "zod"; export const MyCompositionSchema = z.object({ title: z.string(), @@ -56,11 +56,22 @@ const MyComponent: React.FC> = () => { In the root file, the schema can be passed to the composition: ```tsx title="src/Root.tsx" -import {Composition} from 'remotion'; -import {MycComponent, MyCompositionSchema} from './MyComposition'; +import { Composition } from "remotion"; +import { MycComponent, MyCompositionSchema } from "./MyComposition"; export const RemotionRoot = () => { - return ; + return ( + + ); }; ``` @@ -86,7 +97,7 @@ pnpm exec remotion add @remotion/zod-types # If project uses pnpm Then import `zColor` from `@remotion/zod-types`: ```tsx -import {zColor} from '@remotion/zod-types'; +import { zColor } from "@remotion/zod-types"; ``` Then use it in the schema: diff --git a/packages/studio-shared/src/package-info.ts b/packages/studio-shared/src/package-info.ts index bdd2abf82c0..bbf4265e4ab 100644 --- a/packages/studio-shared/src/package-info.ts +++ b/packages/studio-shared/src/package-info.ts @@ -94,12 +94,6 @@ export type ExtraPackage = { }; export const extraPackages: ExtraPackage[] = [ - { - name: 'zod', - version: '3.22.3', - description: 'Schema validation library for defining component props', - docsUrl: 'https://www.remotion.dev/docs/schemas', - }, { name: 'mediabunny', version: '1.34.2', From e002c9282992d771fb82b56f5bbe50a1b0f97a41 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Tue, 17 Feb 2026 11:40:43 +0100 Subject: [PATCH 03/49] Update package.json --- packages/mcp/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mcp/package.json b/packages/mcp/package.json index 888bcb12d43..ef67b3c3ebd 100644 --- a/packages/mcp/package.json +++ b/packages/mcp/package.json @@ -25,7 +25,7 @@ "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "1.26.0", - "zod": "4.3.6" + "zod": "4.1.13" }, "peerDependencies": {}, "devDependencies": { From f376e26c19ec418ee20adc8a9511d193edd8fba8 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Tue, 17 Feb 2026 11:40:45 +0100 Subject: [PATCH 04/49] Update bun.lock --- bun.lock | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bun.lock b/bun.lock index 61090570dce..0f2359e1d36 100644 --- a/bun.lock +++ b/bun.lock @@ -923,7 +923,7 @@ }, "dependencies": { "@modelcontextprotocol/sdk": "1.26.0", - "zod": "4.3.6", + "zod": "4.1.13", }, "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", @@ -8822,6 +8822,8 @@ "@remotion/lambda-client/@types/express": ["@types/express@5.0.1", "", { "dependencies": { "@types/body-parser": "1.19.1", "@types/express-serve-static-core": "5.0.4", "@types/serve-static": "1.13.10" } }, "sha512-UZUw8vjpWFXuDnjFTh7/5c2TWDlQqeXHi6hcN7F2XSVT5P+WmUnnbFS3KA6Jnc6IsEqI2qCVu2bK0R0J4A8ZQQ=="], + "@remotion/mcp/zod": ["zod@4.1.13", "", {}, "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig=="], + "@remotion/promo-pages/hls.js": ["hls.js@1.5.19", "", {}, "sha512-C020dKWEJcyvLnrqsFKW4q6D/6IEzKWdhktIS5bgoyEFE8lHgrFBq4RIngdy113abJOlIruhv8qjg7UX8hwxOw=="], "@remotion/promo-pages/tailwindcss": ["tailwindcss@4.1.1", "", {}, "sha512-QNbdmeS979Efzim2g/bEvfuh+fTcIdp1y7gA+sb6OYSW74rt7Cr7M78AKdf6HqWT3d5AiTb7SwTT3sLQxr4/qw=="], From 74aae689abaef23ec70faba311fbdd0018d55b89 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Tue, 17 Feb 2026 11:58:30 +0100 Subject: [PATCH 05/49] alright --- packages/core/src/Composition.tsx | 13 +++++++------ packages/core/src/CompositionManager.tsx | 2 +- packages/core/src/CompositionManagerContext.tsx | 2 +- packages/core/src/CompositionManagerProvider.tsx | 2 +- packages/core/src/Still.tsx | 2 +- packages/core/src/any-zod-type.ts | 4 ++++ packages/core/src/index.ts | 1 + packages/core/src/props-if-has-props.ts | 6 +++--- packages/core/src/resolve-video-config.ts | 2 +- packages/player/src/Player.tsx | 2 +- packages/player/src/Thumbnail.tsx | 2 +- packages/player/src/utils/props-if-has-props.ts | 8 ++++---- packages/studio/src/api/create-composition.tsx | 2 +- packages/studio/src/api/helpers/calc-new-props.ts | 2 +- packages/web-renderer/src/create-scaffold.tsx | 2 +- packages/web-renderer/src/props-if-has-props.ts | 12 ++++++------ packages/web-renderer/src/render-media-on-web.tsx | 8 ++++---- packages/web-renderer/src/render-still-on-web.tsx | 2 +- 18 files changed, 40 insertions(+), 34 deletions(-) create mode 100644 packages/core/src/any-zod-type.ts diff --git a/packages/core/src/Composition.tsx b/packages/core/src/Composition.tsx index c183b2a35dc..11bde1371d8 100644 --- a/packages/core/src/Composition.tsx +++ b/packages/core/src/Composition.tsx @@ -1,18 +1,15 @@ import type {ComponentType} from 'react'; import React, {Suspense, useContext, useEffect} from 'react'; import {createPortal} from 'react-dom'; -import type {AnyZodObject, z} from 'zod'; +import type {z} from 'zod'; +import type {AnyZodObject} from './any-zod-type.js'; import { CanUseRemotionHooks, CanUseRemotionHooksProvider, } from './CanUseRemotionHooks.js'; +import type {Codec} from './codec.js'; import {CompositionSetters} from './CompositionManagerContext.js'; import {FolderContext} from './Folder.js'; -import { - PROPS_UPDATED_EXTERNALLY, - useResolvedVideoConfig, -} from './ResolveCompositionConfig.js'; -import type {Codec} from './codec.js'; import {serializeThenDeserializeInStudio} from './input-props-serialization.js'; import {useIsPlayer} from './is-player.js'; import {Loading} from './loading-indicator.js'; @@ -21,6 +18,10 @@ import {portalNode} from './portal-node.js'; import type {InferProps, PropsIfHasProps} from './props-if-has-props.js'; import type {ProResProfile} from './prores-profile.js'; import type {PixelFormat, VideoImageFormat} from './render-types.js'; +import { + PROPS_UPDATED_EXTERNALLY, + useResolvedVideoConfig, +} from './ResolveCompositionConfig.js'; import {useDelayRender} from './use-delay-render.js'; import {useLazyComponent} from './use-lazy-component.js'; import {useRemotionEnvironment} from './use-remotion-environment.js'; diff --git a/packages/core/src/CompositionManager.tsx b/packages/core/src/CompositionManager.tsx index f32c6a4f998..39e770a424c 100644 --- a/packages/core/src/CompositionManager.tsx +++ b/packages/core/src/CompositionManager.tsx @@ -1,6 +1,6 @@ import type {ComponentType, LazyExoticComponent} from 'react'; import React from 'react'; -import type {AnyZodObject} from 'zod'; +import type {AnyZodObject} from './any-zod-type.js'; import type {CalculateMetadataFunction} from './Composition.js'; import type {DownloadBehavior} from './download-behavior.js'; import type {InferProps, PropsIfHasProps} from './props-if-has-props.js'; diff --git a/packages/core/src/CompositionManagerContext.tsx b/packages/core/src/CompositionManagerContext.tsx index d8781fbadbb..a37cb513b0d 100644 --- a/packages/core/src/CompositionManagerContext.tsx +++ b/packages/core/src/CompositionManagerContext.tsx @@ -1,6 +1,6 @@ import type React from 'react'; import {createContext} from 'react'; -import type {AnyZodObject} from 'zod'; +import type {AnyZodObject} from './any-zod-type.js'; import type {AnyComposition, TComposition} from './CompositionManager.js'; import type {TFolder} from './Folder.js'; import type {VideoConfig} from './video-config.js'; diff --git a/packages/core/src/CompositionManagerProvider.tsx b/packages/core/src/CompositionManagerProvider.tsx index 4c7bdfb25a7..6ca4d395c3f 100644 --- a/packages/core/src/CompositionManagerProvider.tsx +++ b/packages/core/src/CompositionManagerProvider.tsx @@ -5,7 +5,7 @@ import { useRef, useState, } from 'react'; -import type {AnyZodObject} from 'zod'; +import type {AnyZodObject} from './any-zod-type.js'; import type {TComposition} from './CompositionManager'; import {compositionsRef, type AnyComposition} from './CompositionManager'; import type { diff --git a/packages/core/src/Still.tsx b/packages/core/src/Still.tsx index d643e2021a0..51d855c4613 100644 --- a/packages/core/src/Still.tsx +++ b/packages/core/src/Still.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import type {AnyZodObject} from 'zod'; +import type {AnyZodObject} from './any-zod-type.js'; import type {CompositionProps, StillProps} from './Composition.js'; import {Composition} from './Composition.js'; diff --git a/packages/core/src/any-zod-type.ts b/packages/core/src/any-zod-type.ts new file mode 100644 index 00000000000..978b721fbe5 --- /dev/null +++ b/packages/core/src/any-zod-type.ts @@ -0,0 +1,4 @@ +import type * as z3 from 'zod/v3'; +import type * as z4 from 'zod/v4/core'; + +export type AnyZodObject = z3.AnyZodObject | z4.$ZodObject; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index be1e55584e3..328231365bf 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -172,6 +172,7 @@ export {Series} from './series/index.js'; export * from './spring/index.js'; export {staticFile} from './static-file.js'; export * from './Still.js'; +export type {AnyZodObject} from './any-zod-type.js'; export type {PlayableMediaTag} from './timeline-position-state.js'; export {useBufferState} from './use-buffer-state'; export {useCurrentFrame} from './use-current-frame.js'; diff --git a/packages/core/src/props-if-has-props.ts b/packages/core/src/props-if-has-props.ts index eec1c3335e5..211a9e0fccc 100644 --- a/packages/core/src/props-if-has-props.ts +++ b/packages/core/src/props-if-has-props.ts @@ -1,4 +1,4 @@ -import type {AnyZodObject, z} from 'zod'; +import type {AnyZodObject} from './any-zod-type.js'; type And = A extends true ? B extends true @@ -34,6 +34,6 @@ export type InferProps< Props : {} extends Props ? // Only schema specified - z.input + Record : // Props and schema specified - z.input & Props; + Record & Props; diff --git a/packages/core/src/resolve-video-config.ts b/packages/core/src/resolve-video-config.ts index e2fc474e71b..9a7856a8d22 100644 --- a/packages/core/src/resolve-video-config.ts +++ b/packages/core/src/resolve-video-config.ts @@ -1,4 +1,4 @@ -import type {AnyZodObject} from 'zod'; +import type {AnyZodObject} from './any-zod-type.js'; import type { CalcMetadataReturnType, CalculateMetadataFunction, diff --git a/packages/player/src/Player.tsx b/packages/player/src/Player.tsx index 67661b6338a..18c58faad7a 100644 --- a/packages/player/src/Player.tsx +++ b/packages/player/src/Player.tsx @@ -16,7 +16,7 @@ import type { TimelineContextValue, } from 'remotion'; import {Composition, Internals} from 'remotion'; -import type {AnyZodObject} from 'zod'; +import type {AnyZodObject} from 'remotion'; import {PlayerEmitterProvider} from './EmitterProvider.js'; import type {RenderMuteButton} from './MediaVolumeSlider.js'; import type { diff --git a/packages/player/src/Thumbnail.tsx b/packages/player/src/Thumbnail.tsx index 22cb0d721a3..296cf9a2695 100644 --- a/packages/player/src/Thumbnail.tsx +++ b/packages/player/src/Thumbnail.tsx @@ -14,7 +14,7 @@ import { } from 'react'; import type {CompProps, LogLevel, TimelineContextValue} from 'remotion'; import {Internals, random} from 'remotion'; -import type {AnyZodObject} from 'zod'; +import type {AnyZodObject} from 'remotion'; import {ThumbnailEmitterContext} from './emitter-context.js'; import {ThumbnailEmitter} from './event-emitter.js'; import type {ThumbnailMethods} from './player-methods.js'; diff --git a/packages/player/src/utils/props-if-has-props.ts b/packages/player/src/utils/props-if-has-props.ts index 1431a9172c5..1fe5641cdb7 100644 --- a/packages/player/src/utils/props-if-has-props.ts +++ b/packages/player/src/utils/props-if-has-props.ts @@ -1,4 +1,4 @@ -import type {AnyZodObject, z} from 'zod'; +import type {AnyZodObject} from 'remotion'; export type PropsIfHasProps< Schema extends AnyZodObject, @@ -7,7 +7,7 @@ export type PropsIfHasProps< ? {} extends Props ? { // Neither props nor schema specified - inputProps?: z.input & Props; + inputProps?: Record & Props; } : { // Only props specified @@ -16,9 +16,9 @@ export type PropsIfHasProps< : {} extends Props ? { // Only schema specified - inputProps: z.input; + inputProps: Record; } : { // Props and schema specified - inputProps: z.input & Props; + inputProps: Record & Props; }; diff --git a/packages/studio/src/api/create-composition.tsx b/packages/studio/src/api/create-composition.tsx index 4c50a684a57..dec8c1db3a8 100644 --- a/packages/studio/src/api/create-composition.tsx +++ b/packages/studio/src/api/create-composition.tsx @@ -1,6 +1,6 @@ import type {CompositionProps, StillProps} from 'remotion'; import {Composition, Still} from 'remotion'; -import type {AnyZodObject} from 'zod'; +import type {AnyZodObject} from 'remotion'; export const createComposition = >({ diff --git a/packages/studio/src/api/helpers/calc-new-props.ts b/packages/studio/src/api/helpers/calc-new-props.ts index 2df7d8c5b4a..93cfd40fa2e 100644 --- a/packages/studio/src/api/helpers/calc-new-props.ts +++ b/packages/studio/src/api/helpers/calc-new-props.ts @@ -1,6 +1,6 @@ import type {_InternalTypes} from 'remotion'; import {Internals, getRemotionEnvironment} from 'remotion'; -import type {AnyZodObject} from 'zod'; +import type {AnyZodObject} from 'remotion'; export type UpdateDefaultPropsFunction = (currentValues: { schema: AnyZodObject | null; diff --git a/packages/web-renderer/src/create-scaffold.tsx b/packages/web-renderer/src/create-scaffold.tsx index 130a8487a95..a1320a5d22b 100644 --- a/packages/web-renderer/src/create-scaffold.tsx +++ b/packages/web-renderer/src/create-scaffold.tsx @@ -3,7 +3,7 @@ import {flushSync} from 'react-dom'; import ReactDOM from 'react-dom/client'; import type {Codec, DelayRenderScope, LogLevel, TRenderAsset} from 'remotion'; import {Internals} from 'remotion'; -import type {AnyZodObject} from 'zod'; +import type {AnyZodObject} from 'remotion'; import type {TimeUpdaterRef} from './update-time'; import {UpdateTime} from './update-time'; diff --git a/packages/web-renderer/src/props-if-has-props.ts b/packages/web-renderer/src/props-if-has-props.ts index 370eaf9932c..bfca486bbcf 100644 --- a/packages/web-renderer/src/props-if-has-props.ts +++ b/packages/web-renderer/src/props-if-has-props.ts @@ -1,6 +1,6 @@ import type {ComponentType} from 'react'; import type {CalculateMetadataFunction} from 'remotion'; -import type {AnyZodObject, z} from 'zod'; +import type {AnyZodObject} from 'remotion'; export type InferProps< Schema extends AnyZodObject, @@ -13,9 +13,9 @@ export type InferProps< Props : {} extends Props ? // Only schema specified - z.input + Record : // Props and schema specified - z.input & Props; + Record & Props; export type DefaultPropsIfHasProps< Schema extends AnyZodObject, @@ -24,7 +24,7 @@ export type DefaultPropsIfHasProps< ? {} extends Props ? { // Neither props nor schema specified - defaultProps?: z.input & Props; + defaultProps?: Record & Props; } : { // Only props specified @@ -33,11 +33,11 @@ export type DefaultPropsIfHasProps< : {} extends Props ? { // Only schema specified - defaultProps: z.input; + defaultProps: Record; } : { // Props and schema specified - defaultProps: z.input & Props; + defaultProps: Record & Props; }; type LooseComponentType = ComponentType | ((props: T) => React.ReactNode); diff --git a/packages/web-renderer/src/render-media-on-web.tsx b/packages/web-renderer/src/render-media-on-web.tsx index e34b7f920a1..e139aa3286b 100644 --- a/packages/web-renderer/src/render-media-on-web.tsx +++ b/packages/web-renderer/src/render-media-on-web.tsx @@ -2,7 +2,7 @@ import {BufferTarget, StreamTarget} from 'mediabunny'; import type {CalculateMetadataFunction} from 'remotion'; import {Internals, type LogLevel} from 'remotion'; import {VERSION} from 'remotion/version'; -import type {AnyZodObject, z} from 'zod'; +import type {AnyZodObject} from 'remotion'; import {addAudioSample, addVideoSampleAndCloseFrame} from './add-sample'; import {handleArtifacts, type WebRendererOnArtifact} from './artifact'; import {onlyInlineAudio} from './audio'; @@ -53,7 +53,7 @@ export type InputPropsIfHasProps< ? {} extends Props ? { // Neither props nor schema specified - inputProps?: z.input & Props; + inputProps?: Record & Props; } : { // Only props specified @@ -62,11 +62,11 @@ export type InputPropsIfHasProps< : {} extends Props ? { // Only schema specified - inputProps: z.input; + inputProps: Record; } : { // Props and schema specified - inputProps: z.input & Props; + inputProps: Record & Props; }; type MandatoryRenderMediaOnWebOptions< diff --git a/packages/web-renderer/src/render-still-on-web.tsx b/packages/web-renderer/src/render-still-on-web.tsx index e969c632b85..413098a8138 100644 --- a/packages/web-renderer/src/render-still-on-web.tsx +++ b/packages/web-renderer/src/render-still-on-web.tsx @@ -3,7 +3,7 @@ import { type CalculateMetadataFunction, type LogLevel, } from 'remotion'; -import type {AnyZodObject} from 'zod'; +import type {AnyZodObject} from 'remotion'; import type {WebRendererOnArtifact} from './artifact'; import {handleArtifacts} from './artifact'; import {checkForError, createScaffold} from './create-scaffold'; From 3ebb1febfdab54f0d30c9886a596c4bf9b7abcfa Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Tue, 17 Feb 2026 12:54:21 +0100 Subject: [PATCH 06/49] Make studio schema editor compatible with zod v3 and v4 - Add zod-schema-type.ts helper for normalized v3/v4 type detection - Replace all z.ZodTypeAny, z.ZodFirstPartyTypeKind, z.Zod*Def with version-agnostic helpers and `any` types - Update cloudrun payloads for v4 z.record() API (requires 2 args) - Add v4 schema test composition in example package - Add v3 schema test composition in react18-tests package Co-Authored-By: Claude Opus 4.6 --- bun.lock | 1 + .../src/functions/helpers/payloads.ts | 12 +- packages/example/src/Root.tsx | 19 ++ packages/example/src/ZodV4SchemaTest.tsx | 53 ++++ packages/react18-tests/package.json | 3 +- packages/react18-tests/src/test/Root.tsx | 35 ++- .../src/test/ZodV3SchemaTest.tsx | 46 ++++ .../src/components/RenderModal/DataEditor.tsx | 15 +- .../RenderModalJSONPropsEditor.tsx | 7 +- .../RenderModal/SchemaEditor/SchemaEditor.tsx | 14 +- .../SchemaEditor/SchemaErrorMessages.tsx | 8 +- .../SchemaEditor/SchemaSeparationLine.tsx | 11 +- .../SchemaEditor/ZodArrayEditor.tsx | 16 +- .../SchemaEditor/ZodArrayItemEditor.tsx | 6 +- .../SchemaEditor/ZodBooleanEditor.tsx | 4 +- .../SchemaEditor/ZodColorEditor.tsx | 4 +- .../SchemaEditor/ZodDateEditor.tsx | 4 +- .../SchemaEditor/ZodDefaultEditor.tsx | 7 +- .../ZodDiscriminatedUnionEditor.tsx | 51 ++-- .../SchemaEditor/ZodEffectEditor.tsx | 20 +- .../SchemaEditor/ZodEnumEditor.tsx | 22 +- .../SchemaEditor/ZodErrorMessages.tsx | 8 +- .../SchemaEditor/ZodFieldValidation.tsx | 2 +- .../SchemaEditor/ZodMatrixEditor.tsx | 11 +- .../SchemaEditor/ZodNullableEditor.tsx | 7 +- .../SchemaEditor/ZodNumberEditor.tsx | 98 ++++--- .../SchemaEditor/ZodObjectEditor.tsx | 21 +- .../SchemaEditor/ZodOptionalEditor.tsx | 7 +- .../SchemaEditor/ZodOrNullishEditor.tsx | 7 +- .../SchemaEditor/ZodStaticFileEditor.tsx | 17 +- .../SchemaEditor/ZodStringEditor.tsx | 4 +- .../RenderModal/SchemaEditor/ZodSwitch.tsx | 73 +++-- .../SchemaEditor/ZodTextareaEditor.tsx | 4 +- .../SchemaEditor/ZodTupleEditor.tsx | 11 +- .../SchemaEditor/ZodUnionEditor.tsx | 40 ++- .../SchemaEditor/create-zod-values.ts | 215 ++++++++------- .../SchemaEditor/extract-enum-json-paths.ts | 166 +++++------- .../RenderModal/SchemaEditor/local-state.tsx | 7 +- .../SchemaEditor/zod-schema-type.ts | 254 ++++++++++++++++++ .../src/components/get-zod-if-possible.tsx | 25 +- .../studio/src/test/create-zod-values.test.ts | 7 +- .../studio/src/test/extract-zod-enums.test.ts | 4 +- .../src/visual-controls/VisualControls.tsx | 11 +- 43 files changed, 867 insertions(+), 490 deletions(-) create mode 100644 packages/example/src/ZodV4SchemaTest.tsx create mode 100644 packages/react18-tests/src/test/ZodV3SchemaTest.tsx create mode 100644 packages/studio/src/components/RenderModal/SchemaEditor/zod-schema-type.ts diff --git a/bun.lock b/bun.lock index 0f2359e1d36..43ee62cac79 100644 --- a/bun.lock +++ b/bun.lock @@ -1129,6 +1129,7 @@ "version": "4.0.423", "dependencies": { "remotion": "workspace:*", + "zod": "catalog:", }, "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", diff --git a/packages/cloudrun/src/functions/helpers/payloads.ts b/packages/cloudrun/src/functions/helpers/payloads.ts index 0f0b416dbe6..1100331f6ef 100644 --- a/packages/cloudrun/src/functions/helpers/payloads.ts +++ b/packages/cloudrun/src/functions/helpers/payloads.ts @@ -57,7 +57,7 @@ export const CloudRunPayload = z.discriminatedUnion('type', [ .tuple([z.number(), z.number().nullable()]) .or(z.number()) .nullable(), - envVariables: z.record(z.string()), + envVariables: z.record(z.string(), z.string()), chromiumOptions: chromiumOptions.optional(), muted: z.boolean(), outputBucket: z.string(), @@ -74,12 +74,12 @@ export const CloudRunPayload = z.discriminatedUnion('type', [ colorSpace: z.enum(BrowserSafeApis.validColorSpaces).nullable(), clientVersion: z.string(), downloadBehavior, - metadata: z.record(z.string()).optional().nullable(), + metadata: z.record(z.string(), z.string()).optional().nullable(), renderIdOverride: z.string().optional().nullable(), renderStatusWebhook: z .object({ url: z.string(), - headers: z.record(z.string()), + headers: z.record(z.string(), z.string()), data: z.any(), webhookProgressInterval: z.number().min(0).max(1).optional().nullable(), }) @@ -97,7 +97,7 @@ export const CloudRunPayload = z.discriminatedUnion('type', [ imageFormat: stillImageFormat, scale: z.number(), privacy: z.enum(['public', 'private', 'no-acl']), - envVariables: z.record(z.string()), + envVariables: z.record(z.string(), z.string()), chromiumOptions: chromiumOptions.optional(), outputBucket: z.string(), outName: z.string().nullable(), @@ -109,12 +109,12 @@ export const CloudRunPayload = z.discriminatedUnion('type', [ offthreadVideoThreads: z.number().nullable(), clientVersion: z.string(), downloadBehavior, - metadata: z.record(z.string()).optional().nullable(), + metadata: z.record(z.string(), z.string()).optional().nullable(), renderIdOverride: z.string().optional().nullable(), renderStatusWebhook: z .object({ url: z.string(), - headers: z.record(z.string()), + headers: z.record(z.string(), z.string()), data: z.any(), webhookProgressInterval: z.number().min(0).max(1).optional().nullable(), }) diff --git a/packages/example/src/Root.tsx b/packages/example/src/Root.tsx index 321665220f6..6912bfe2728 100644 --- a/packages/example/src/Root.tsx +++ b/packages/example/src/Root.tsx @@ -66,6 +66,7 @@ import { schemaArrayTestSchema, schemaTestSchema, } from './SchemaTest'; +import {ZodV4SchemaTest, zodV4Schema} from './ZodV4SchemaTest'; import {Scripts} from './Scripts'; import {WidthHeightSequences} from './Sequence/WidthHeightSequences'; import CircleTest from './Shapes/CircleTest'; @@ -1508,6 +1509,24 @@ export const Index: React.FC = () => { schema={schemaArrayTestSchema} defaultProps={{}} /> + > = ({ + greeting, + count, + enabled, + items, + mode, +}) => { + return ( + +
{greeting}
+
+ Count: {count} | Enabled: {String(enabled)} +
+
    + {items.map((item) => ( +
  • + {item.label}: {item.value} +
  • + ))} +
+
+ ); +}; diff --git a/packages/react18-tests/package.json b/packages/react18-tests/package.json index b0a7ea5cd25..be7be080267 100644 --- a/packages/react18-tests/package.json +++ b/packages/react18-tests/package.json @@ -16,7 +16,8 @@ "author": "Remotion ", "license": "UNLICENSED", "dependencies": { - "remotion": "workspace:*" + "remotion": "workspace:*", + "zod": "catalog:" }, "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", diff --git a/packages/react18-tests/src/test/Root.tsx b/packages/react18-tests/src/test/Root.tsx index 04561d70344..3cc28e0964e 100644 --- a/packages/react18-tests/src/test/Root.tsx +++ b/packages/react18-tests/src/test/Root.tsx @@ -1,6 +1,7 @@ // bun run studio import React from 'react'; import {Composition} from 'remotion'; +import {ZodV3SchemaTest, zodV3Schema} from './ZodV3SchemaTest'; const TestComponent: React.FC = () => { return ( @@ -21,13 +22,31 @@ const TestComponent: React.FC = () => { export const Root: React.FC = () => { return ( - + <> + + + ); }; diff --git a/packages/react18-tests/src/test/ZodV3SchemaTest.tsx b/packages/react18-tests/src/test/ZodV3SchemaTest.tsx new file mode 100644 index 00000000000..cf2c94f9fc4 --- /dev/null +++ b/packages/react18-tests/src/test/ZodV3SchemaTest.tsx @@ -0,0 +1,46 @@ +/** + * Test composition using zod v3 schema (via zod/v3 import). + * Verifies that the studio schema editor works with zod v3 schemas. + */ +import React from 'react'; +import {z} from 'zod/v3'; + +export const zodV3Schema = z.object({ + title: z.string(), + count: z.number().min(0).max(100), + enabled: z.boolean(), + tags: z.array(z.string()), + level: z.enum(['beginner', 'intermediate', 'advanced']), +}); + +export const ZodV3SchemaTest: React.FC> = ({ + title, + count, + enabled, + tags, + level, +}) => { + return ( +
+
{title}
+
+ Count: {count} | Enabled: {String(enabled)} | Level: {level} +
+
+ Tags: {tags.join(', ')} +
+
+ ); +}; diff --git a/packages/studio/src/components/RenderModal/DataEditor.tsx b/packages/studio/src/components/RenderModal/DataEditor.tsx index 9f6301a89e9..3b06ce1fbc8 100644 --- a/packages/studio/src/components/RenderModal/DataEditor.tsx +++ b/packages/studio/src/components/RenderModal/DataEditor.tsx @@ -8,7 +8,7 @@ import React, { import type {_InternalTypes, SerializedJSONWithCustomFields} from 'remotion'; import {getInputProps, Internals} from 'remotion'; import {NoReactInternals} from 'remotion/no-react'; -import {type z} from 'zod'; +import {getZodSchemaType} from './SchemaEditor/zod-schema-type'; import {FastRefreshContext} from '../../fast-refresh-context'; import {StudioServerConnectionCtx} from '../../helpers/client-id'; import {BACKGROUND, BORDER_COLOR, LIGHT_TEXT} from '../../helpers/colors'; @@ -48,7 +48,8 @@ export type State = str: string; value: Record; validJSON: true; - zodValidation: Zod.SafeParseReturnType; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + zodValidation: {success: boolean; error?: any}; } | { str: string; @@ -173,7 +174,7 @@ export const DataEditor: React.FC<{ return 'no-schema' as const; } - if (!(typeof unresolvedComposition.schema.safeParse === 'function')) { + if (!(typeof (unresolvedComposition.schema as {safeParse?: unknown}).safeParse === 'function')) { throw new Error( 'A value which is not a Zod schema was passed to `schema`', ); @@ -191,7 +192,7 @@ export const DataEditor: React.FC<{ return 'no-schema' as const; } - return schema.safeParse(defaultProps); + return (schema as {safeParse: (v: unknown) => {success: boolean; error?: unknown}}).safeParse(defaultProps); }, [defaultProps, schema]); const setShowWarning: React.Dispatch> = @@ -422,11 +423,9 @@ export const DataEditor: React.FC<{ throw new Error('expected schema'); } - const def: z.ZodTypeDef = schema._def; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const typeName = (def as any).typeName as z.ZodFirstPartyTypeKind; + const typeName = getZodSchemaType(schema); - if (typeName === z.ZodFirstPartyTypeKind.ZodAny) { + if (typeName === 'any') { return ; } diff --git a/packages/studio/src/components/RenderModal/RenderModalJSONPropsEditor.tsx b/packages/studio/src/components/RenderModal/RenderModalJSONPropsEditor.tsx index 16d82b629c0..06cc8bcdaea 100644 --- a/packages/studio/src/components/RenderModal/RenderModalJSONPropsEditor.tsx +++ b/packages/studio/src/components/RenderModal/RenderModalJSONPropsEditor.tsx @@ -1,7 +1,6 @@ import React, {useCallback, useEffect, useMemo} from 'react'; import type {SerializedJSONWithCustomFields} from 'remotion'; import {NoReactInternals} from 'remotion/no-react'; -import type {z} from 'zod'; import {FAIL_COLOR} from '../../helpers/colors'; import {setUnsavedProps} from '../../helpers/document-title'; import {useKeybinding} from '../../helpers/use-keybinding'; @@ -25,7 +24,8 @@ const scrollable: React.CSSProperties = { flex: 1, }; -const parseJSON = (str: string, schema: z.ZodTypeAny): State => { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const parseJSON = (str: string, schema: any): State => { try { const value = NoReactInternals.deserializeJSONWithSpecialTypes(str); const zodValidation = schema.safeParse(value); @@ -44,7 +44,8 @@ export const RenderModalJSONPropsEditor: React.FC<{ readonly showSaveButton: boolean; readonly serializedJSON: SerializedJSONWithCustomFields | null; readonly defaultProps: Record; - readonly schema: z.ZodTypeAny; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly schema: any; }> = ({ setValue, value, diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/SchemaEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/SchemaEditor.tsx index da4c6440815..6abb1e93a0e 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/SchemaEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/SchemaEditor.tsx @@ -1,6 +1,6 @@ import React, {useCallback, useEffect, useMemo, useState} from 'react'; import {Internals} from 'remotion'; -import type {AnyZodObject, z} from 'zod'; +import {getZodSchemaType} from './zod-schema-type'; import {setUnsavedProps} from '../../../helpers/document-title'; import {useKeybinding} from '../../../helpers/use-keybinding'; import {VERTICAL_SCROLLBAR_CLASSNAME} from '../../Menu/is-menu-item'; @@ -22,13 +22,15 @@ const scrollable: React.CSSProperties = { overflowY: 'auto', }; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const SchemaEditor: React.FC<{ - readonly schema: AnyZodObject; + readonly schema: any; readonly unsavedDefaultProps: Record; readonly setValue: React.Dispatch< React.SetStateAction> >; - readonly zodValidationResult: z.SafeParseReturnType; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly zodValidationResult: {success: boolean; error?: any}; readonly savedDefaultProps: Record; readonly onSave: ( updater: (oldState: Record) => Record, @@ -108,9 +110,7 @@ export const SchemaEditor: React.FC<{ }; }, [keybindings, onQuickSave, onSave]); - const def: z.ZodTypeDef = schema._def; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const typeName = (def as any).typeName as z.ZodFirstPartyTypeKind; + const typeName = getZodSchemaType(schema); const reset = useCallback(() => { setValue(savedDefaultProps); @@ -128,7 +128,7 @@ export const SchemaEditor: React.FC<{ ); } - if (typeName !== z.ZodFirstPartyTypeKind.ZodObject) { + if (typeName !== 'object') { return ; } diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/SchemaErrorMessages.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/SchemaErrorMessages.tsx index b66bde28306..0fee096d7de 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/SchemaErrorMessages.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/SchemaErrorMessages.tsx @@ -1,4 +1,4 @@ -import type {z} from 'zod'; +// Schema error messages for studio editor import {BACKGROUND, BLUE, LIGHT_TEXT} from '../../../helpers/colors'; import {Button} from '../../Button'; import {inlineCodeSnippet} from '../../Menu/styles'; @@ -86,7 +86,8 @@ export const NoDefaultProps = () => { }; export const InvalidDefaultProps: React.FC<{ - zodValidationResult: z.SafeParseReturnType; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + zodValidationResult: {success: boolean; error?: any}; }> = ({zodValidationResult}) => { return (
@@ -111,7 +112,8 @@ export const InvalidDefaultProps: React.FC<{ }; export const InvalidSchema: React.FC<{ - zodValidationResult: z.SafeParseReturnType; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + zodValidationResult: {success: boolean; error?: any}; reset: () => void; }> = ({zodValidationResult, reset}) => { return ( diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/SchemaSeparationLine.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/SchemaSeparationLine.tsx index af806dc1937..16fbcf005d0 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/SchemaSeparationLine.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/SchemaSeparationLine.tsx @@ -1,5 +1,5 @@ import React, {useCallback, useMemo, useState} from 'react'; -import type {z} from 'zod'; +import {getArrayElement} from './zod-schema-type'; import {BACKGROUND, LIGHT_TEXT, LINE_COLOR} from '../../../helpers/colors'; import {Plus} from '../../../icons/plus'; import { @@ -35,7 +35,8 @@ export const SchemaArrayItemSeparationLine: React.FC<{ increment: boolean, ) => void; readonly index: number; - readonly schema: z.ZodTypeAny; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly schema: any; readonly showAddButton: boolean; readonly isLast: boolean; }> = ({onChange, index, schema, isLast, showAddButton}) => { @@ -48,21 +49,21 @@ export const SchemaArrayItemSeparationLine: React.FC<{ throw new Error('expected zod'); } - const def = schema._def as z.ZodArrayDef; + const arrayElement = getArrayElement(schema); const onAdd = useCallback(() => { onChange( (oldV) => { return [ ...oldV.slice(0, index + 1), - createZodValues(def.type, z, zodTypes), + createZodValues(arrayElement, z, zodTypes), ...oldV.slice(index + 1), ]; }, false, true, ); - }, [def.type, index, onChange, z, zodTypes]); + }, [arrayElement, index, onChange, z, zodTypes]); const dynamicAddButtonStyle: React.CSSProperties = useMemo(() => { return { diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodArrayEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodArrayEditor.tsx index 4414f027819..6a18785a8b6 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodArrayEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodArrayEditor.tsx @@ -1,5 +1,5 @@ import React, {useMemo, useState} from 'react'; -import type {z} from 'zod'; +import {getArrayElement} from './zod-schema-type'; import { useZodIfPossible, useZodTypesIfPossible, @@ -16,8 +16,9 @@ import {deepEqual} from './deep-equal'; import {useLocalState} from './local-state'; import type {JSONPath} from './zod-types'; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodArrayEditor: React.FC<{ - readonly schema: z.ZodTypeAny; + readonly schema: any; readonly jsonPath: JSONPath; readonly value: unknown[]; readonly defaultValue: unknown[]; @@ -50,7 +51,7 @@ export const ZodArrayEditor: React.FC<{ const [expanded, setExpanded] = useState(true); - const def = schema._def as z.ZodArrayDef; + const arrayElement = getArrayElement(schema); const suffix = useMemo(() => { return expanded ? ' [' : ' [...] '; @@ -62,11 +63,6 @@ export const ZodArrayEditor: React.FC<{ const zodTypes = useZodTypesIfPossible(); - const typeName = def.typeName as z.ZodFirstPartyTypeKind; - if (typeName !== z.ZodFirstPartyTypeKind.ZodArray) { - throw new Error('expected object'); - } - const isDefaultValue = useMemo(() => { return deepEqual(localValue.value, defaultValue); }, [defaultValue, localValue]); @@ -106,12 +102,12 @@ export const ZodArrayEditor: React.FC<{ ; // eslint-disable-next-line @typescript-eslint/no-explicit-any - def: any; + elementSchema: any; index: number; value: unknown; defaultValue: unknown; @@ -19,7 +19,7 @@ export const ZodArrayItemEditor: React.FC<{ mayPad: boolean; mayRemove: boolean; }> = ({ - def, + elementSchema, onChange, jsonPath, index, @@ -81,7 +81,7 @@ export const ZodArrayItemEditor: React.FC<{
; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodColorEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodColorEditor.tsx index e6dd3a8dcf1..402b6be4101 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodColorEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodColorEditor.tsx @@ -1,5 +1,4 @@ import React, {useCallback, useMemo} from 'react'; -import type {z} from 'zod'; import {colorWithNewOpacity} from '../../../helpers/color-math'; import {InputDragger} from '../../NewComposition/InputDragger'; import {RemotionInput} from '../../NewComposition/RemInput'; @@ -21,7 +20,8 @@ const fullWidth: React.CSSProperties = { }; export const ZodColorEditor: React.FC<{ - readonly schema: z.ZodTypeAny; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly schema: any; readonly jsonPath: JSONPath; readonly value: string; readonly defaultValue: string; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodDateEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodDateEditor.tsx index 2464ce050f6..511d4432e58 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodDateEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodDateEditor.tsx @@ -1,5 +1,4 @@ import React, {useCallback} from 'react'; -import type {z} from 'zod'; import {VERY_LIGHT_TEXT} from '../../../helpers/colors'; import {RemotionInput} from '../../NewComposition/RemInput'; import {Spacing} from '../../layout'; @@ -50,7 +49,8 @@ const formatDate = (date: Date) => { }; export const ZodDateEditor: React.FC<{ - readonly schema: z.ZodTypeAny; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly schema: any; readonly jsonPath: JSONPath; readonly value: Date; readonly defaultValue: Date; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodDefaultEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodDefaultEditor.tsx index f44d038a7c1..700335311ac 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodDefaultEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodDefaultEditor.tsx @@ -1,15 +1,16 @@ import React from 'react'; -import type {z} from 'zod'; +import {getInnerType} from './zod-schema-type'; import type {UpdaterFunction} from './ZodSwitch'; import {ZodSwitch} from './ZodSwitch'; import type {JSONPath} from './zod-types'; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodDefaultEditor: React.FC<{ readonly showSaveButton: boolean; readonly jsonPath: JSONPath; readonly value: unknown; readonly defaultValue: unknown; - readonly schema: z.ZodTypeAny; + readonly schema: any; readonly setValue: UpdaterFunction; readonly onSave: UpdaterFunction; readonly onRemove: null | (() => void); @@ -29,7 +30,7 @@ export const ZodDefaultEditor: React.FC<{ saveDisabledByParent, mayPad, }) => { - const {innerType} = schema._def as z.ZodDefaultDef; + const innerType = getInnerType(schema); return ( >; value: Record; defaultValue: Record; @@ -48,10 +53,10 @@ export const ZodDiscriminatedUnionEditor: React.FC<{ const zodTypes = useZodTypesIfPossible(); - const typedSchema = schema._def as z.ZodDiscriminatedUnionDef; + const discriminator = getDiscriminator(schema); const options = useMemo( - () => [...typedSchema.optionsMap.keys()], - [typedSchema.optionsMap], + () => getDiscriminatedOptionKeys(schema), + [schema], ) as string[]; const { @@ -73,12 +78,11 @@ export const ZodDiscriminatedUnionEditor: React.FC<{ id: option, keyHint: null, leftItem: - option === value[typedSchema.discriminator] ? : null, + option === value[discriminator] ? : null, onClick: () => { + const optionSchema = getDiscriminatedOption(schema, option); const val = createZodValues( - typedSchema.optionsMap.get( - option, - ) as ZodDiscriminatedUnionOption, + optionSchema, z, zodTypes, ) as Record; @@ -92,8 +96,8 @@ export const ZodDiscriminatedUnionEditor: React.FC<{ }, [ options, setLocalValue, - typedSchema.discriminator, - typedSchema.optionsMap, + discriminator, + schema, value, z, zodTypes, @@ -106,16 +110,16 @@ export const ZodDiscriminatedUnionEditor: React.FC<{ const discriminatedUnionReplacement: ObjectDiscrimatedUnionReplacement = useMemo(() => { return { - discriminator: typedSchema.discriminator, + discriminator, markup: (
), @@ -146,14 +150,19 @@ export const ZodDiscriminatedUnionEditor: React.FC<{ saveDisabledByParent, saving, showSaveButton, - typedSchema.discriminator, + discriminator, value, ]); + const currentOptionSchema = getDiscriminatedOption( + schema, + value[discriminator] as string, + ); + return ( >} saveDisabledByParent={saveDisabledByParent} saving={saving} - schema={ - typedSchema.optionsMap.get( - value[typedSchema.discriminator] as string, - ) as ZodDiscriminatedUnionOption - } + schema={currentOptionSchema} setValue={setLocalValue} showSaveButton={showSaveButton} unsavedValue={value} diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodEffectEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodEffectEditor.tsx index 5374f1cf806..ab4f9106baa 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodEffectEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodEffectEditor.tsx @@ -1,6 +1,5 @@ import React from 'react'; -import type {z} from 'zod'; -import {useZodIfPossible} from '../../get-zod-if-possible'; +import {getEffectsInner, getZodSchemaType} from './zod-schema-type'; import {Fieldset} from './Fieldset'; import {ZodFieldValidation} from './ZodFieldValidation'; import type {UpdaterFunction} from './ZodSwitch'; @@ -12,8 +11,9 @@ const fullWidth: React.CSSProperties = { width: '100%', }; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodEffectEditor: React.FC<{ - readonly schema: z.ZodTypeAny; + readonly schema: any; readonly jsonPath: JSONPath; readonly value: unknown; readonly setValue: UpdaterFunction; @@ -35,9 +35,9 @@ export const ZodEffectEditor: React.FC<{ saving, mayPad, }) => { - const z = useZodIfPossible(); - if (!z) { - throw new Error('expected zod'); + const typeName = getZodSchemaType(schema); + if (typeName !== 'effects') { + throw new Error('expected effect'); } const {localValue, onChange} = useLocalState({ @@ -47,11 +47,7 @@ export const ZodEffectEditor: React.FC<{ savedValue: defaultValue, }); - const def = schema._def; - const typeName = def.typeName as z.ZodFirstPartyTypeKind; - if (typeName !== z.ZodFirstPartyTypeKind.ZodEffects) { - throw new Error('expected effect'); - } + const innerSchema = getEffectsInner(schema); return (
@@ -60,7 +56,7 @@ export const ZodEffectEditor: React.FC<{ value={value} setValue={onChange} jsonPath={jsonPath} - schema={def.schema} + schema={innerSchema} defaultValue={defaultValue} onSave={onSave} showSaveButton={showSaveButton} diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodEnumEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodEnumEditor.tsx index 85024a4b2bb..8caf0af415f 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodEnumEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodEnumEditor.tsx @@ -1,22 +1,22 @@ import React, {useCallback, useMemo} from 'react'; -import type {z} from 'zod'; import {Checkmark} from '../../../icons/Checkmark'; import type {ComboboxValue} from '../../NewComposition/ComboBox'; import {Combobox} from '../../NewComposition/ComboBox'; -import {useZodIfPossible} from '../../get-zod-if-possible'; import {Fieldset} from './Fieldset'; import {SchemaLabel} from './SchemaLabel'; import {ZodFieldValidation} from './ZodFieldValidation'; import type {UpdaterFunction} from './ZodSwitch'; import {useLocalState} from './local-state'; import type {JSONPath} from './zod-types'; +import {getEnumValues} from './zod-schema-type'; const container: React.CSSProperties = { width: '100%', }; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodEnumEditor: React.FC<{ - readonly schema: z.ZodTypeAny; + readonly schema: any; readonly jsonPath: JSONPath; readonly value: string; readonly defaultValue: string; @@ -36,11 +36,6 @@ export const ZodEnumEditor: React.FC<{ onRemove, saving, }) => { - const z = useZodIfPossible(); - if (!z) { - throw new Error('expected zod'); - } - const { localValue, onChange: setLocalValue, @@ -52,17 +47,12 @@ export const ZodEnumEditor: React.FC<{ savedValue: defaultValue, }); - const def = schema._def; - - const typeName = def.typeName as z.ZodFirstPartyTypeKind; - if (typeName !== z.ZodFirstPartyTypeKind.ZodEnum) { - throw new Error('expected enum'); - } + const enumValues = getEnumValues(schema); const isRoot = jsonPath.length === 0; const comboBoxValues = useMemo(() => { - return def.values.map((option: string): ComboboxValue => { + return enumValues.map((option: string): ComboboxValue => { return { value: option, label: option, @@ -77,7 +67,7 @@ export const ZodEnumEditor: React.FC<{ type: 'item', }; }); - }, [def.values, setLocalValue, value]); + }, [enumValues, setLocalValue, value]); const save = useCallback(() => { onSave(() => value, false, false); diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodErrorMessages.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodErrorMessages.tsx index 0e5b39489ec..e8ed7d8f405 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodErrorMessages.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodErrorMessages.tsx @@ -1,5 +1,4 @@ import React, {useMemo} from 'react'; -import type {z} from 'zod'; import {FAIL_COLOR, LIGHT_TEXT} from '../../../helpers/colors'; import {WarningTriangle} from '../../NewComposition/ValidationMessage'; import {Spacing} from '../../layout'; @@ -25,7 +24,8 @@ const triangleStyle: React.CSSProperties = { }; export const ZodErrorMessages: React.FC<{ - readonly zodValidationResult: z.SafeParseReturnType; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly zodValidationResult: {success: boolean; error?: any}; readonly viewTab: 'schema' | 'json'; }> = ({zodValidationResult, viewTab}) => { if (zodValidationResult.success) { @@ -46,7 +46,7 @@ export const ZodErrorMessages: React.FC<{ if (viewTab === 'json') { return (
- {zodValidationResult.error.errors.map((error) => { + {zodValidationResult.error.errors.map((error: {path: (string | number)[]; message: string}) => { return (
@@ -62,7 +62,7 @@ export const ZodErrorMessages: React.FC<{ return (
- {zodValidationResult.error.errors.map((error) => { + {zodValidationResult.error.errors.map((error: {path: (string | number)[]; message: string}) => { return (
-{' '} diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodFieldValidation.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodFieldValidation.tsx index a9e82601761..04ce1d848a7 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodFieldValidation.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodFieldValidation.tsx @@ -37,7 +37,7 @@ export const ZodFieldValidation: React.FC<{
Zod Validation has failed:
- {localValue.zodValidation.error.errors.map((error, index) => ( + {localValue.zodValidation.error.errors.map((error: {code: string; message: string}, index: number) => ( // eslint-disable-next-line react/no-array-index-key
Type: {error.code}
diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodMatrixEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodMatrixEditor.tsx index fe290e13195..31159e49a57 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodMatrixEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodMatrixEditor.tsx @@ -1,9 +1,9 @@ import React, {useMemo, useState} from 'react'; -import type {z} from 'zod'; import { useZodIfPossible, useZodTypesIfPossible, } from '../../get-zod-if-possible'; +import {getArrayElement} from './zod-schema-type'; import {Fieldset} from './Fieldset'; import {SchemaLabel} from './SchemaLabel'; import {SchemaArrayItemSeparationLine} from './SchemaSeparationLine'; @@ -22,8 +22,9 @@ const rowStyle: React.CSSProperties = { width: '100%', }; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodMatrixEditor: React.FC<{ - readonly schema: z.ZodTypeAny; + readonly schema: any; readonly jsonPath: JSONPath; readonly value: unknown[]; readonly defaultValue: unknown[]; @@ -56,7 +57,7 @@ export const ZodMatrixEditor: React.FC<{ const [expanded, setExpanded] = useState(true); - const def = schema._def as z.ZodArrayDef; + const arrayElement = getArrayElement(schema); const suffix = useMemo(() => { return expanded ? ' [' : ' [...] '; @@ -128,12 +129,12 @@ export const ZodMatrixEditor: React.FC<{ ; onSave: UpdaterFunction; onRemove: null | (() => void); @@ -28,7 +28,8 @@ export const ZodNullableEditor: React.FC<{ saveDisabledByParent, mayPad, }) => { - const {innerType} = schema._def as z.ZodOptionalDef; + // Both v3 and v4 have _def.innerType + const {innerType} = schema._def; return ( { - const minCheck = (schema as z.ZodNumber)._def.checks.find( - (c) => c.kind === 'min', - ); - if (!minCheck) { - return -Infinity; - } - - if (minCheck.kind !== 'min') { - throw new Error('Expected min check'); +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const getMinValue = (schema: any) => { + const checks = schema._def.checks; + if (!checks) return -Infinity; + + if (isZodV3Schema(schema)) { + // v3: {kind: "min", value: 0, inclusive: true} + const minCheck = checks.find( + (c: {kind: string}) => c.kind === 'min', + ); + if (!minCheck || !minCheck.inclusive) return -Infinity; + return minCheck.value; } - if (!minCheck.inclusive) { - return -Infinity; + // v4: check objects with _zod.def = {check: "greater_than", value: 0, inclusive: true} + for (const c of checks) { + const def = c._zod?.def; + if (def?.check === 'greater_than' && def.inclusive) { + return def.value; + } } - return minCheck.value; + return -Infinity; }; -const getMaxValue = (schema: z.ZodTypeAny) => { - const maxCheck = (schema as z.ZodNumber)._def.checks.find( - (c) => c.kind === 'max', - ); - if (!maxCheck) { - return Infinity; - } - - if (maxCheck.kind !== 'max') { - throw new Error('Expected max check'); +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const getMaxValue = (schema: any) => { + const checks = schema._def.checks; + if (!checks) return Infinity; + + if (isZodV3Schema(schema)) { + // v3: {kind: "max", value: 100, inclusive: true} + const maxCheck = checks.find( + (c: {kind: string}) => c.kind === 'max', + ); + if (!maxCheck || !maxCheck.inclusive) return Infinity; + return maxCheck.value; } - if (!maxCheck.inclusive) { - return Infinity; + // v4: check objects with _zod.def = {check: "less_than", value: 100, inclusive: true} + for (const c of checks) { + const def = c._zod?.def; + if (def?.check === 'less_than' && def.inclusive) { + return def.value; + } } - return maxCheck.value; + return Infinity; }; -const getStep = (schema: z.ZodTypeAny): number | undefined => { - const multipleStep = (schema as z.ZodNumber)._def.checks.find( - (c) => c.kind === 'multipleOf', - ); - - if (!multipleStep) { - return undefined; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const getStep = (schema: any): number | undefined => { + const checks = schema._def.checks; + if (!checks) return undefined; + + if (isZodV3Schema(schema)) { + // v3: {kind: "multipleOf", value: 5} + const multipleStep = checks.find( + (c: {kind: string}) => c.kind === 'multipleOf', + ); + if (!multipleStep) return undefined; + return multipleStep.value; } - if (multipleStep.kind !== 'multipleOf') { - throw new Error('Expected multipleOf check'); + // v4: check objects with _zod.def = {check: "multiple_of", value: 5} + for (const c of checks) { + const def = c._zod?.def; + if (def?.check === 'multiple_of') { + return def.value; + } } - return multipleStep.value; + return undefined; }; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodNumberEditor: React.FC<{ - readonly schema: z.ZodTypeAny; + readonly schema: any; readonly jsonPath: JSONPath; readonly value: number; readonly setValue: UpdaterFunction; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodObjectEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodObjectEditor.tsx index 1dbff01d5d0..d2771003e31 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodObjectEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodObjectEditor.tsx @@ -1,6 +1,5 @@ import React, {useMemo, useState} from 'react'; -import type {z} from 'zod'; -import {useZodIfPossible} from '../../get-zod-if-possible'; +import {isZodV3Schema, getZodSchemaType} from './zod-schema-type'; import {fieldsetLabel} from '../layout'; import {Fieldset} from './Fieldset'; import {SchemaLabel} from './SchemaLabel'; @@ -17,8 +16,9 @@ export type ObjectDiscrimatedUnionReplacement = { markup: React.ReactNode; }; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodObjectEditor: React.FC<{ - readonly schema: z.ZodTypeAny; + readonly schema: any; readonly jsonPath: JSONPath; readonly unsavedValue: Record; readonly savedValue: Record; @@ -44,11 +44,6 @@ export const ZodObjectEditor: React.FC<{ mayPad, discriminatedUnionReplacement, }) => { - const z = useZodIfPossible(); - if (!z) { - throw new Error('expected zod'); - } - const [expanded, setExpanded] = useState(true); const {localValue, onChange, RevisionContextProvider, reset} = useLocalState({ schema, @@ -59,12 +54,16 @@ export const ZodObjectEditor: React.FC<{ const def = schema._def; - const typeName = def.typeName as z.ZodFirstPartyTypeKind; - if (typeName !== z.ZodFirstPartyTypeKind.ZodObject) { + const typeName = getZodSchemaType(schema); + if (typeName !== 'object') { throw new Error('expected object'); } - const shape = def.shape(); + // v3: _def.shape() is a function, v4: _def.shape is an object + const shape = + isZodV3Schema(schema) && typeof def.shape === 'function' + ? def.shape() + : def.shape; const keys = Object.keys(shape); const isRoot = jsonPath.length === 0; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodOptionalEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodOptionalEditor.tsx index 0c000b3adda..1d1ac4a3a91 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodOptionalEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodOptionalEditor.tsx @@ -1,14 +1,14 @@ -import type {z} from 'zod'; import {ZodOrNullishEditor} from './ZodOrNullishEditor'; import type {UpdaterFunction} from './ZodSwitch'; import type {JSONPath} from './zod-types'; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodOptionalEditor: React.FC<{ showSaveButton: boolean; jsonPath: JSONPath; value: unknown; defaultValue: unknown; - schema: z.ZodTypeAny; + schema: any; setValue: UpdaterFunction; onSave: UpdaterFunction; onRemove: null | (() => void); @@ -28,7 +28,8 @@ export const ZodOptionalEditor: React.FC<{ saveDisabledByParent, mayPad, }) => { - const {innerType} = schema._def as z.ZodOptionalDef; + // Both v3 and v4 have _def.innerType + const {innerType} = schema._def; return ( ; onSave: UpdaterFunction; onRemove: null | (() => void); diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodStaticFileEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodStaticFileEditor.tsx index 8fe0d5acca7..4ceffc6b23e 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodStaticFileEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodStaticFileEditor.tsx @@ -1,9 +1,7 @@ import React, {useCallback, useMemo} from 'react'; -import type {z} from 'zod'; import {Checkmark} from '../../../icons/Checkmark'; import type {ComboboxValue} from '../../NewComposition/ComboBox'; import {Combobox} from '../../NewComposition/ComboBox'; -import {useZodIfPossible} from '../../get-zod-if-possible'; import {useStaticFiles} from '../../use-static-files'; import {Fieldset} from './Fieldset'; import {SchemaLabel} from './SchemaLabel'; @@ -16,8 +14,9 @@ const container: React.CSSProperties = { width: '100%', }; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodStaticFileEditor: React.FC<{ - readonly schema: z.ZodTypeAny; + readonly schema: any; readonly jsonPath: JSONPath; readonly value: string; readonly defaultValue: string; @@ -41,11 +40,6 @@ export const ZodStaticFileEditor: React.FC<{ saveDisabledByParent, mayPad, }) => { - const z = useZodIfPossible(); - if (!z) { - throw new Error('expected zod'); - } - const { localValue, onChange: setLocalValue, @@ -57,13 +51,6 @@ export const ZodStaticFileEditor: React.FC<{ savedValue: defaultValue, }); - const def = schema._def; - - const typeName = def.typeName as z.ZodFirstPartyTypeKind; - if (typeName !== z.ZodFirstPartyTypeKind.ZodString) { - throw new Error('expected enum'); - } - const isRoot = jsonPath.length === 0; const staticFiles = useStaticFiles(); diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodStringEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodStringEditor.tsx index 604ffc43570..a6eaa864921 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodStringEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodStringEditor.tsx @@ -1,5 +1,4 @@ import React, {useCallback} from 'react'; -import type {z} from 'zod'; import {RemotionInput} from '../../NewComposition/RemInput'; import {useZodIfPossible} from '../../get-zod-if-possible'; import {Fieldset} from './Fieldset'; @@ -14,7 +13,8 @@ const fullWidth: React.CSSProperties = { }; export const ZodStringEditor: React.FC<{ - readonly schema: z.ZodTypeAny; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly schema: any; readonly jsonPath: JSONPath; readonly value: string; readonly defaultValue: string; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodSwitch.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodSwitch.tsx index fa94301c16b..7016be331c3 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodSwitch.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodSwitch.tsx @@ -1,9 +1,9 @@ import React from 'react'; -import type {z} from 'zod'; +import {useZodTypesIfPossible} from '../../get-zod-if-possible'; import { - useZodIfPossible, - useZodTypesIfPossible, -} from '../../get-zod-if-possible'; + getZodSchemaDescription, + getZodSchemaType, +} from './zod-schema-type'; import type {JSONPath} from './zod-types'; import {ZodArrayEditor} from './ZodArrayEditor'; import {ZodBooleanEditor} from './ZodBooleanEditor'; @@ -31,8 +31,11 @@ export type UpdaterFunction = ( increment: boolean, ) => void; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type AnySchema = any; + export const ZodSwitch: React.FC<{ - readonly schema: z.ZodTypeAny; + readonly schema: AnySchema; readonly jsonPath: JSONPath; readonly value: unknown; readonly defaultValue: unknown; @@ -56,18 +59,11 @@ export const ZodSwitch: React.FC<{ saveDisabledByParent, mayPad, }) => { - const def: z.ZodTypeDef = schema._def; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const typeName = (def as any).typeName as z.ZodFirstPartyTypeKind; - - const z = useZodIfPossible(); - if (!z) { - throw new Error('expected zod'); - } - + const typeName = getZodSchemaType(schema); + const description = getZodSchemaDescription(schema); const zodTypes = useZodTypesIfPossible(); - if (typeName === z.ZodFirstPartyTypeKind.ZodObject) { + if (typeName === 'object') { return ( >} @@ -86,7 +82,7 @@ export const ZodSwitch: React.FC<{ ); } - if (typeName === z.ZodFirstPartyTypeKind.ZodString) { + if (typeName === 'string') { if ((value as string).startsWith(window.remotion_staticBase)) { return ( } @@ -276,7 +271,7 @@ export const ZodSwitch: React.FC<{ ); } - if (typeName === z.ZodFirstPartyTypeKind.ZodEnum) { + if (typeName === 'enum') { return ( } @@ -292,11 +287,12 @@ export const ZodSwitch: React.FC<{ ); } - if (typeName === z.ZodFirstPartyTypeKind.ZodEffects) { + // In v3, effects wrap schemas (e.g. .refine(), .transform()). + // In v4, refine/transform are embedded as checks, so this only applies to v3. + if (typeName === 'effects') { if ( zodTypes && - schema._def.description === - zodTypes.ZodZypesInternals.REMOTION_COLOR_BRAND + description === zodTypes.ZodZypesInternals.REMOTION_COLOR_BRAND ) { return ( } @@ -443,7 +438,7 @@ export const ZodSwitch: React.FC<{ ); } - if (typeName === z.ZodFirstPartyTypeKind.ZodTuple) { + if (typeName === 'tuple') { return ( } diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodTextareaEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodTextareaEditor.tsx index 49febf3c57f..94d99552483 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodTextareaEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodTextareaEditor.tsx @@ -1,5 +1,4 @@ import React, {useCallback} from 'react'; -import type {z} from 'zod'; import {RemTextarea} from '../../NewComposition/RemTextarea'; import { useZodIfPossible, @@ -22,7 +21,8 @@ const textareaStyle: React.CSSProperties = { }; export const ZodTextareaEditor: React.FC<{ - readonly schema: z.ZodTypeAny; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly schema: any; readonly jsonPath: JSONPath; readonly value: string; readonly defaultValue: string; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodTupleEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodTupleEditor.tsx index 6a902ef983f..9891adffad0 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodTupleEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodTupleEditor.tsx @@ -1,5 +1,4 @@ import React, {useMemo, useState} from 'react'; -import type {z} from 'zod'; import { useZodIfPossible, useZodTypesIfPossible, @@ -16,8 +15,9 @@ import {ZodFieldValidation} from './ZodFieldValidation'; import type {UpdaterFunction} from './ZodSwitch'; import {ZodTupleItemEditor} from './ZodTupleItemEditor'; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodTupleEditor: React.FC<{ - readonly schema: z.ZodTypeAny; + readonly schema: any; readonly jsonPath: JSONPath; readonly value: unknown[]; readonly defaultValue: unknown[]; @@ -49,7 +49,7 @@ export const ZodTupleEditor: React.FC<{ }); const [expanded, setExpanded] = useState(true); - const def = schema._def as z.ZodTupleDef; + const def = schema._def; const suffix = useMemo(() => { return expanded ? ' [' : ' [...] '; @@ -61,11 +61,6 @@ export const ZodTupleEditor: React.FC<{ const zodTypes = useZodTypesIfPossible(); - const typeName = def.typeName as z.ZodFirstPartyTypeKind; - if (typeName !== z.ZodFirstPartyTypeKind.ZodTuple) { - throw new Error('expected object'); - } - const isDefaultValue = useMemo(() => { return deepEqual(localValue.value, defaultValue); }, [defaultValue, localValue]); diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodUnionEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodUnionEditor.tsx index 62b89002637..6b69ee10d9e 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodUnionEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodUnionEditor.tsx @@ -1,33 +1,27 @@ -import type {z} from 'zod'; -import type {ZodType} from '../../get-zod-if-possible'; -import {useZodIfPossible} from '../../get-zod-if-possible'; import {ZonNonEditableValue} from './ZodNonEditableValue'; import {ZodOrNullishEditor} from './ZodOrNullishEditor'; import type {UpdaterFunction} from './ZodSwitch'; import type {JSONPath} from './zod-types'; -const findNull = ( - value: readonly [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]], - zodType: ZodType, -) => { - const nullIndex = value.findIndex( - (v) => - v._def.typeName === zodType.ZodFirstPartyTypeKind.ZodNull || - v._def.typeName === zodType.ZodFirstPartyTypeKind.ZodUndefined, - ); +import {getZodSchemaType} from './zod-schema-type'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const findNull = (value: readonly any[]) => { + const nullIndex = value.findIndex((v) => { + const type = getZodSchemaType(v); + return type === 'null' || type === 'undefined'; + }); if (nullIndex === -1) { return null; } const nullishValue = - value[nullIndex]._def.typeName === zodType.ZodFirstPartyTypeKind.ZodNull - ? null - : undefined; + getZodSchemaType(value[nullIndex]) === 'null' ? null : undefined; const otherSchema = value[nullIndex === 0 ? 1 : 0]; + const otherType = getZodSchemaType(otherSchema); const otherSchemaIsAlsoNullish = - otherSchema._def.typeName === zodType.ZodFirstPartyTypeKind.ZodNull || - otherSchema._def.typeName === zodType.ZodFirstPartyTypeKind.ZodUndefined; + otherType === 'null' || otherType === 'undefined'; return { nullIndex, @@ -37,12 +31,13 @@ const findNull = ( }; }; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodUnionEditor: React.FC<{ showSaveButton: boolean; jsonPath: JSONPath; value: unknown; defaultValue: unknown; - schema: z.ZodTypeAny; + schema: any; setValue: UpdaterFunction; onSave: UpdaterFunction; onRemove: null | (() => void); @@ -62,12 +57,7 @@ export const ZodUnionEditor: React.FC<{ saveDisabledByParent, mayPad, }) => { - const {options} = schema._def as z.ZodUnionDef; - - const z = useZodIfPossible(); - if (!z) { - throw new Error('expected zod'); - } + const {options} = schema._def; if (options.length > 2) { return ( @@ -93,7 +83,7 @@ export const ZodUnionEditor: React.FC<{ ); } - const nullResult = findNull(options, z); + const nullResult = findNull(options); if (!nullResult) { return ( diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/create-zod-values.ts b/packages/studio/src/components/RenderModal/SchemaEditor/create-zod-values.ts index 483705be4f5..6a69d9fe9b0 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/create-zod-values.ts +++ b/packages/studio/src/components/RenderModal/SchemaEditor/create-zod-values.ts @@ -1,9 +1,24 @@ -import type {z} from 'zod'; -import type {ZodType, ZodTypesType} from '../../get-zod-if-possible'; +import type {ZodTypesType} from '../../get-zod-if-possible'; +import { + getArrayElement, + getDefaultValue, + getEffectsInner, + getEnumValues, + getInnerType, + getLiteralValue, + getObjectShape, + getUnionOptions, + getZodSchemaDescription, + getZodSchemaType, + isZodV3Schema, +} from './zod-schema-type'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type AnySchema = any; export const createZodValues = ( - schema: Zod.ZodTypeAny, - zodRuntime: ZodType, + schema: AnySchema, + zodRuntime: unknown, zodTypes: ZodTypesType | null, ): unknown => { if (!schema) { @@ -11,53 +26,64 @@ export const createZodValues = ( } const def = schema._def; - const typeName = def.typeName as z.ZodFirstPartyTypeKind; + const typeName = getZodSchemaType(schema); switch (typeName) { - case zodRuntime.ZodFirstPartyTypeKind.ZodString: + case 'string': return ''; - case zodRuntime.ZodFirstPartyTypeKind.ZodNumber: { - for (const check of (def as z.ZodNumberDef).checks) { - if (check.kind === 'min') { - return check.value; - } - - if (check.kind === 'max' && check.value < 0) { - return check.value; + case 'number': { + const checks = def.checks; + if (checks) { + if (isZodV3Schema(schema)) { + for (const check of checks) { + if (check.kind === 'min') return check.value; + if (check.kind === 'max' && check.value < 0) + return check.value; + } + } else { + for (const check of checks) { + const cd = check._zod?.def; + if (cd?.check === 'greater_than') return cd.value; + if (cd?.check === 'less_than' && cd.value < 0) + return cd.value; + } } } return 0; } - case zodRuntime.ZodFirstPartyTypeKind.ZodBigInt: + case 'bigint': return BigInt(0); - case zodRuntime.ZodFirstPartyTypeKind.ZodBoolean: + case 'boolean': return false; - case zodRuntime.ZodFirstPartyTypeKind.ZodNaN: + case 'nan': return NaN; - case zodRuntime.ZodFirstPartyTypeKind.ZodDate: + case 'date': return new Date(); - case zodRuntime.ZodFirstPartyTypeKind.ZodSymbol: + case 'symbol': return Symbol('remotion'); - case zodRuntime.ZodFirstPartyTypeKind.ZodUndefined: + case 'undefined': + case 'void': return undefined; - case zodRuntime.ZodFirstPartyTypeKind.ZodNull: + case 'null': return null; - case zodRuntime.ZodFirstPartyTypeKind.ZodAny: + case 'any': throw new Error('Cannot create a value for type z.any()'); - case zodRuntime.ZodFirstPartyTypeKind.ZodUnknown: + case 'unknown': throw new Error('Cannot create a value for type z.unknown()'); - case zodRuntime.ZodFirstPartyTypeKind.ZodNever: + case 'never': throw new Error('Cannot create a value for type z.never()'); - case zodRuntime.ZodFirstPartyTypeKind.ZodVoid: - return undefined; - case zodRuntime.ZodFirstPartyTypeKind.ZodObject: { - const shape = (def as z.ZodObjectDef).shape(); + case 'object': { + const shape = getObjectShape(schema); const keys = Object.keys(shape); const returnValue = keys.reduce( (existing, key) => { - existing[key] = createZodValues(shape[key], zodRuntime, zodTypes); + existing[key] = createZodValues( + shape[key], + zodRuntime, + zodTypes, + ); return existing; }, {} as Record, @@ -65,49 +91,45 @@ export const createZodValues = ( return returnValue; } - case zodRuntime.ZodFirstPartyTypeKind.ZodArray: { - return [ - createZodValues((def as z.ZodArrayDef).type, zodRuntime, zodTypes), - ]; + case 'array': { + return [createZodValues(getArrayElement(schema), zodRuntime, zodTypes)]; } - case zodRuntime.ZodFirstPartyTypeKind.ZodUnion: { - const firstOptions = (def as z.ZodUnionDef).options[0]; - return firstOptions - ? createZodValues(firstOptions, zodRuntime, zodTypes) + case 'union': { + const firstOption = getUnionOptions(schema)[0]; + return firstOption + ? createZodValues(firstOption, zodRuntime, zodTypes) : undefined; } - case zodRuntime.ZodFirstPartyTypeKind.ZodDiscriminatedUnion: { - const options = (def as z.ZodDiscriminatedUnionDef).options[0]; + case 'discriminatedUnion': { + const options = getUnionOptions(schema)[0]; return createZodValues(options, zodRuntime, zodTypes); } - case zodRuntime.ZodFirstPartyTypeKind.ZodLiteral: { - return (def as z.ZodLiteralDef).value; + case 'literal': { + return getLiteralValue(schema); } - case zodRuntime.ZodFirstPartyTypeKind.ZodEffects: { + case 'effects': { + const description = getZodSchemaDescription(schema); if ( zodTypes && - schema._def.description === - zodTypes.ZodZypesInternals.REMOTION_COLOR_BRAND + description === zodTypes.ZodZypesInternals.REMOTION_COLOR_BRAND ) { return '#ffffff'; } if ( zodTypes && - schema._def.description === - zodTypes.ZodZypesInternals.REMOTION_TEXTAREA_BRAND + description === zodTypes.ZodZypesInternals.REMOTION_TEXTAREA_BRAND ) { return ''; } if ( zodTypes && - schema._def.description === - zodTypes.ZodZypesInternals.REMOTION_MATRIX_BRAND + description === zodTypes.ZodZypesInternals.REMOTION_MATRIX_BRAND ) { return [ [1, 0, 0], @@ -116,15 +138,11 @@ export const createZodValues = ( ]; } - return createZodValues( - (def as z.ZodEffectsDef).schema, - zodRuntime, - zodTypes, - ); + return createZodValues(getEffectsInner(schema), zodRuntime, zodTypes); } - case zodRuntime.ZodFirstPartyTypeKind.ZodIntersection: { - const {left, right} = def as z.ZodIntersectionDef; + case 'intersection': { + const {left, right} = def; const leftValue = createZodValues(left, zodRuntime, zodTypes); if (typeof leftValue !== 'object') { throw new Error( @@ -143,95 +161,72 @@ export const createZodValues = ( return {...leftValue, ...rightValue}; } - case zodRuntime.ZodFirstPartyTypeKind.ZodTuple: { - const items = (def as z.ZodTupleDef).items.map((item) => + case 'tuple': { + const items = def.items.map((item: AnySchema) => createZodValues(item, zodRuntime, zodTypes), ); return items; } - case zodRuntime.ZodFirstPartyTypeKind.ZodRecord: { - const values = createZodValues( - (def as z.ZodRecordDef).valueType, - zodRuntime, - zodTypes, - ); + case 'record': { + const values = createZodValues(def.valueType, zodRuntime, zodTypes); return {key: values}; } - case zodRuntime.ZodFirstPartyTypeKind.ZodMap: { - const defType = def as z.ZodMapDef; - const values = createZodValues(defType.valueType, zodRuntime, zodTypes); - const key = createZodValues(defType.keyType, zodRuntime, zodTypes); + case 'map': { + const values = createZodValues(def.valueType, zodRuntime, zodTypes); + const key = createZodValues(def.keyType, zodRuntime, zodTypes); return new Map([[key, values]]); } - case zodRuntime.ZodFirstPartyTypeKind.ZodLazy: { - const defType = def as z.ZodLazyDef; - const type = defType.getter(); + case 'lazy': { + const type = def.getter(); return createZodValues(type, zodRuntime, zodTypes); } - case zodRuntime.ZodFirstPartyTypeKind.ZodSet: { - const defType = def as z.ZodSetDef; - const values = createZodValues(defType.valueType, zodRuntime, zodTypes); + case 'set': { + const values = createZodValues(def.valueType, zodRuntime, zodTypes); return new Set([values]); } - case zodRuntime.ZodFirstPartyTypeKind.ZodFunction: { + case 'function': { throw new Error('Cannot create a value for type function'); } - case zodRuntime.ZodFirstPartyTypeKind.ZodEnum: { - const {values} = def as z.ZodEnumDef; - return values[0]; + case 'enum': { + return getEnumValues(schema)[0]; } - case zodRuntime.ZodFirstPartyTypeKind.ZodNativeEnum: { + case 'nativeEnum': { return 0; } - case zodRuntime.ZodFirstPartyTypeKind.ZodOptional: { - const defType = def as z.ZodOptionalDef; - const value = createZodValues(defType.innerType, zodRuntime, zodTypes); - return value; - } - - case zodRuntime.ZodFirstPartyTypeKind.ZodNullable: { - const defType = def as z.ZodNullableDef; - const value = createZodValues(defType.innerType, zodRuntime, zodTypes); - return value; - } - - case zodRuntime.ZodFirstPartyTypeKind.ZodDefault: { - const defType = def as z.ZodDefaultDef; - return defType.defaultValue(); + case 'optional': + case 'nullable': + case 'catch': { + return createZodValues(getInnerType(schema), zodRuntime, zodTypes); } - case zodRuntime.ZodFirstPartyTypeKind.ZodCatch: { - const defType = def as z.ZodCatchDef; - const value = createZodValues(defType.innerType, zodRuntime, zodTypes); - return value; + case 'default': { + return getDefaultValue(schema); } - case zodRuntime.ZodFirstPartyTypeKind.ZodPromise: { - const defType = def as z.ZodPromiseDef; - const value = createZodValues(defType.type, zodRuntime, zodTypes); + case 'promise': { + // v3: _def.type, v4: _def.innerType + const inner = isZodV3Schema(schema) ? def.type : def.innerType; + const value = createZodValues(inner, zodRuntime, zodTypes); return Promise.resolve(value); } - case zodRuntime.ZodFirstPartyTypeKind.ZodBranded: { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const defType = def as z.ZodBrandedDef; - const value = createZodValues(defType.type, zodRuntime, zodTypes); - return value; + case 'branded': { + // v3: _def.type, v4: schema is the base type (branded doesn't wrap in v4) + const inner = isZodV3Schema(schema) ? def.type : schema; + return createZodValues(inner, zodRuntime, zodTypes); } - case zodRuntime.ZodFirstPartyTypeKind.ZodPipeline: { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const defType = def as z.ZodPipelineDef; - const value = createZodValues(defType.out, zodRuntime, zodTypes); - return value; + case 'pipeline': { + // v3: _def.out, v4: _def.out + return createZodValues(def.out, zodRuntime, zodTypes); } default: diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/extract-enum-json-paths.ts b/packages/studio/src/components/RenderModal/SchemaEditor/extract-enum-json-paths.ts index d11448fcbea..74999f6e766 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/extract-enum-json-paths.ts +++ b/packages/studio/src/components/RenderModal/SchemaEditor/extract-enum-json-paths.ts @@ -1,5 +1,17 @@ -import type {z} from 'zod'; -import type {ZodType, ZodTypesType} from '../../get-zod-if-possible'; +import type {ZodTypesType} from '../../get-zod-if-possible'; +import { + getArrayElement, + getEffectsInner, + getInnerType, + getObjectShape, + getUnionOptions, + getZodSchemaDescription, + getZodSchemaType, + isZodV3Schema, +} from './zod-schema-type'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type AnySchema = any; export const extractEnumJsonPaths = ({ schema, @@ -7,17 +19,17 @@ export const extractEnumJsonPaths = ({ currentPath, zodTypes, }: { - schema: Zod.ZodTypeAny; - zodRuntime: ZodType; + schema: AnySchema; + zodRuntime: unknown; zodTypes: ZodTypesType | null; currentPath: (string | number)[]; }): (string | number)[][] => { const def = schema._def; - const typeName = def.typeName as z.ZodFirstPartyTypeKind; + const typeName = getZodSchemaType(schema); switch (typeName) { - case zodRuntime.ZodFirstPartyTypeKind.ZodObject: { - const shape = (def as z.ZodObjectDef).shape(); + case 'object': { + const shape = getObjectShape(schema); const keys = Object.keys(shape); return keys .map((key) => { @@ -31,18 +43,18 @@ export const extractEnumJsonPaths = ({ .flat(1); } - case zodRuntime.ZodFirstPartyTypeKind.ZodArray: { + case 'array': { return extractEnumJsonPaths({ - schema: (def as z.ZodArrayDef).type, + schema: getArrayElement(schema), zodRuntime, currentPath: [...currentPath, '[]'], zodTypes, }); } - case zodRuntime.ZodFirstPartyTypeKind.ZodUnion: { - return (def as z.ZodUnionDef).options - .map((option) => { + case 'union': { + return getUnionOptions(schema) + .map((option: AnySchema) => { return extractEnumJsonPaths({ schema: option, zodRuntime, @@ -53,9 +65,9 @@ export const extractEnumJsonPaths = ({ .flat(1); } - case zodRuntime.ZodFirstPartyTypeKind.ZodDiscriminatedUnion: { - return (def as z.ZodDiscriminatedUnionDef).options - .map((op) => { + case 'discriminatedUnion': { + return getUnionOptions(schema) + .map((op: AnySchema) => { return extractEnumJsonPaths({ schema: op, zodRuntime, @@ -66,29 +78,29 @@ export const extractEnumJsonPaths = ({ .flat(1); } - case zodRuntime.ZodFirstPartyTypeKind.ZodLiteral: { + case 'literal': { return [currentPath]; } - case zodRuntime.ZodFirstPartyTypeKind.ZodEffects: { + case 'effects': { + const description = getZodSchemaDescription(schema); if ( zodTypes && - schema._def.description === - zodTypes.ZodZypesInternals.REMOTION_MATRIX_BRAND + description === zodTypes.ZodZypesInternals.REMOTION_MATRIX_BRAND ) { return [currentPath]; } return extractEnumJsonPaths({ - schema: (def as z.ZodEffectsDef).schema, + schema: getEffectsInner(schema), zodRuntime, currentPath, zodTypes, }); } - case zodRuntime.ZodFirstPartyTypeKind.ZodIntersection: { - const {left, right} = def as z.ZodIntersectionDef; + case 'intersection': { + const {left, right} = def; const leftValue = extractEnumJsonPaths({ schema: left, zodRuntime, @@ -106,9 +118,9 @@ export const extractEnumJsonPaths = ({ return [...leftValue, ...rightValue]; } - case zodRuntime.ZodFirstPartyTypeKind.ZodTuple: { - return (def as z.ZodTupleDef).items - .map((item, i) => + case 'tuple': { + return def.items + .map((item: AnySchema, i: number) => extractEnumJsonPaths({ schema: item, zodRuntime, @@ -119,116 +131,86 @@ export const extractEnumJsonPaths = ({ .flat(1); } - case zodRuntime.ZodFirstPartyTypeKind.ZodRecord: { - const values = extractEnumJsonPaths({ - schema: (def as z.ZodRecordDef).valueType, + case 'record': { + return extractEnumJsonPaths({ + schema: def.valueType, zodRuntime, currentPath: [...currentPath, '{}'], zodTypes, }); - return values; } - case zodRuntime.ZodFirstPartyTypeKind.ZodFunction: { + case 'function': { throw new Error('Cannot create a value for type function'); } - case zodRuntime.ZodFirstPartyTypeKind.ZodEnum: { + case 'enum': { return [currentPath]; } - case zodRuntime.ZodFirstPartyTypeKind.ZodNativeEnum: { + case 'nativeEnum': { return []; } - case zodRuntime.ZodFirstPartyTypeKind.ZodOptional: { - const defType = def as z.ZodOptionalDef; - const value = extractEnumJsonPaths({ - schema: defType.innerType, - zodRuntime, - currentPath, - zodTypes, - }); - return value; - } - - case zodRuntime.ZodFirstPartyTypeKind.ZodNullable: { - const defType = def as z.ZodNullableDef; - const value = extractEnumJsonPaths({ - schema: defType.innerType, - zodRuntime, - currentPath, - zodTypes, - }); - return value; - } - - case zodRuntime.ZodFirstPartyTypeKind.ZodDefault: { - const defType = def as z.ZodDefaultDef; + case 'optional': + case 'nullable': + case 'catch': { return extractEnumJsonPaths({ - schema: defType.innerType, + schema: getInnerType(schema), zodRuntime, currentPath, zodTypes, }); } - case zodRuntime.ZodFirstPartyTypeKind.ZodCatch: { - const defType = def as z.ZodCatchDef; + case 'default': { return extractEnumJsonPaths({ - schema: defType.innerType, + schema: getInnerType(schema), zodRuntime, currentPath, zodTypes, }); } - case zodRuntime.ZodFirstPartyTypeKind.ZodPromise: { + case 'promise': { return []; } - case zodRuntime.ZodFirstPartyTypeKind.ZodBranded: { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const defType = def as z.ZodBrandedDef; - const value = extractEnumJsonPaths({ - schema: defType.type, + case 'branded': { + const inner = isZodV3Schema(schema) ? def.type : schema; + return extractEnumJsonPaths({ + schema: inner, zodRuntime, currentPath, zodTypes, }); - return value; } - case zodRuntime.ZodFirstPartyTypeKind.ZodPipeline: { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const defType = def as z.ZodPipelineDef; - const value = extractEnumJsonPaths({ - schema: defType.out, + case 'pipeline': { + return extractEnumJsonPaths({ + schema: def.out, zodRuntime, currentPath, zodTypes, }); - return value; - } - - case zodRuntime.ZodFirstPartyTypeKind.ZodString: - case zodRuntime.ZodFirstPartyTypeKind.ZodNumber: - case zodRuntime.ZodFirstPartyTypeKind.ZodBigInt: - case zodRuntime.ZodFirstPartyTypeKind.ZodBoolean: - case zodRuntime.ZodFirstPartyTypeKind.ZodNaN: - case zodRuntime.ZodFirstPartyTypeKind.ZodDate: - case zodRuntime.ZodFirstPartyTypeKind.ZodSymbol: - case zodRuntime.ZodFirstPartyTypeKind.ZodUndefined: - case zodRuntime.ZodFirstPartyTypeKind.ZodNull: - case zodRuntime.ZodFirstPartyTypeKind.ZodAny: - case zodRuntime.ZodFirstPartyTypeKind.ZodUnknown: - case zodRuntime.ZodFirstPartyTypeKind.ZodNever: - case zodRuntime.ZodFirstPartyTypeKind.ZodVoid: - case zodRuntime.ZodFirstPartyTypeKind.ZodMap: // Maps are not serializable - case zodRuntime.ZodFirstPartyTypeKind.ZodLazy: - case zodRuntime.ZodFirstPartyTypeKind.ZodSet: { - // Sets are not serializable + } + case 'string': + case 'number': + case 'bigint': + case 'boolean': + case 'nan': + case 'date': + case 'symbol': + case 'undefined': + case 'null': + case 'any': + case 'unknown': + case 'never': + case 'void': + case 'map': + case 'lazy': + case 'set': { return []; } diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/local-state.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/local-state.tsx index 636b6c7698e..02042cccaa5 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/local-state.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/local-state.tsx @@ -8,13 +8,13 @@ import React, { useState, } from 'react'; import {Internals} from 'remotion'; -import type {z} from 'zod'; import type {UpdaterFunction} from './ZodSwitch'; import {deepEqual} from './deep-equal'; export type LocalState = { value: T; - zodValidation: z.SafeParseReturnType; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + zodValidation: {success: boolean; error?: any}; keyStabilityRevision: number; }; @@ -34,7 +34,8 @@ export const useLocalState = ({ savedValue, }: { unsavedValue: T; - schema: z.ZodTypeAny; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + schema: any; setValue: UpdaterFunction; savedValue: T; }) => { diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/zod-schema-type.ts b/packages/studio/src/components/RenderModal/SchemaEditor/zod-schema-type.ts new file mode 100644 index 00000000000..aa4cfe492c4 --- /dev/null +++ b/packages/studio/src/components/RenderModal/SchemaEditor/zod-schema-type.ts @@ -0,0 +1,254 @@ +/** + * Normalizes zod schema type detection across v3 and v4. + * + * v3 schemas have `_def.typeName` (e.g. "ZodString") + * v4 schemas have `_def.type` (e.g. "string") and `_zod` property + * + * This module provides a unified type name using v4-style lowercase strings, + * and accessor helpers that abstract v3/v4 `_def` property differences. + */ + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type AnySchema = any; + +export type ZodSchemaType = + | 'string' + | 'number' + | 'boolean' + | 'object' + | 'array' + | 'enum' + | 'union' + | 'discriminatedUnion' + | 'optional' + | 'nullable' + | 'default' + | 'tuple' + | 'date' + | 'any' + | 'unknown' + | 'bigint' + | 'null' + | 'undefined' + | 'effects' + | 'literal' + | 'record' + | 'never' + | (string & {}); + +const v3TypeNameMap: Record = { + ZodString: 'string', + ZodNumber: 'number', + ZodBoolean: 'boolean', + ZodObject: 'object', + ZodArray: 'array', + ZodEnum: 'enum', + ZodUnion: 'union', + ZodDiscriminatedUnion: 'discriminatedUnion', + ZodOptional: 'optional', + ZodNullable: 'nullable', + ZodDefault: 'default', + ZodTuple: 'tuple', + ZodDate: 'date', + ZodAny: 'any', + ZodUnknown: 'unknown', + ZodBigInt: 'bigint', + ZodNull: 'null', + ZodUndefined: 'undefined', + ZodEffects: 'effects', + ZodLiteral: 'literal', + ZodRecord: 'record', + ZodNever: 'never', + ZodVoid: 'void', + ZodNaN: 'nan', + ZodSymbol: 'symbol', + ZodIntersection: 'intersection', + ZodMap: 'map', + ZodSet: 'set', + ZodLazy: 'lazy', + ZodFunction: 'function', + ZodNativeEnum: 'nativeEnum', + ZodCatch: 'catch', + ZodPromise: 'promise', + ZodBranded: 'branded', + ZodPipeline: 'pipeline', +}; + +export const isZodV3Schema = (schema: AnySchema): boolean => { + return '_def' in schema && 'typeName' in schema._def; +}; + +/** + * Get the normalized type name for a zod schema (v3 or v4). + * + * In v4, discriminatedUnion is a union with a `discriminator` property on `_def`. + * This function returns 'discriminatedUnion' for that case. + */ +export const getZodSchemaType = (schema: AnySchema): ZodSchemaType => { + if (isZodV3Schema(schema)) { + const typeName: string = schema._def.typeName; + return v3TypeNameMap[typeName] ?? typeName; + } + + // v4 schema: _def.type is a string like "string", "number", etc. + const type: string = schema._def.type; + + // In v4, discriminatedUnion has _def.type === "union" with _def.discriminator + if (type === 'union' && schema._def.discriminator !== undefined) { + return 'discriminatedUnion'; + } + + return type; +}; + +/** + * Get the description of a schema, handling v3 vs v4 differences. + * + * v3: schema._def.description + * v4: schema.description + */ +export const getZodSchemaDescription = ( + schema: AnySchema, +): string | undefined => { + if (isZodV3Schema(schema)) { + return schema._def.description; + } + + return schema.description; +}; + +/** + * Get the shape of an object schema. + * v3: _def.shape() (function) + * v4: _def.shape (plain object) + */ +export const getObjectShape = (schema: AnySchema): Record => { + const shape = schema._def.shape; + return typeof shape === 'function' ? shape() : shape; +}; + +/** + * Get the element schema of an array. + * v3: _def.type + * v4: _def.element + */ +export const getArrayElement = (schema: AnySchema): AnySchema => { + return isZodV3Schema(schema) ? schema._def.type : schema._def.element; +}; + +/** + * Get the inner type for wrappers like optional, nullable, default, catch. + * Both v3 and v4 use _def.innerType. + */ +export const getInnerType = (schema: AnySchema): AnySchema => { + return schema._def.innerType; +}; + +/** + * Get the inner schema for effects (v3 only - v4 doesn't wrap). + * v3: _def.schema + */ +export const getEffectsInner = (schema: AnySchema): AnySchema => { + return schema._def.schema; +}; + +/** + * Get the literal value. + * v3: _def.value (single value) + * v4: _def.values (array of values) - take the first + */ +export const getLiteralValue = (schema: AnySchema): unknown => { + if (isZodV3Schema(schema)) { + return schema._def.value; + } + + return schema._def.values?.[0]; +}; + +/** + * Get enum values as an array of strings. + * v3: _def.values (string[]) + * v4: _def.entries (Record) - convert to values array + */ +export const getEnumValues = (schema: AnySchema): string[] => { + if (isZodV3Schema(schema)) { + return schema._def.values; + } + + const entries = schema._def.entries; + return Object.values(entries); +}; + +/** + * Get the union/discriminatedUnion options array. + * Both v3 and v4 use _def.options. + */ +export const getUnionOptions = (schema: AnySchema): AnySchema[] => { + return schema._def.options; +}; + +/** + * Get the default value from a ZodDefault. + * v3: _def.defaultValue() (function) + * v4: _def.defaultValue (plain value) + */ +export const getDefaultValue = (schema: AnySchema): unknown => { + const dv = schema._def.defaultValue; + return typeof dv === 'function' ? dv() : dv; +}; + +/** + * Get the discriminator key from a discriminated union. + * v3: _def.discriminator + * v4: _def.discriminator + */ +export const getDiscriminator = (schema: AnySchema): string => { + return schema._def.discriminator; +}; + +/** + * Get all discriminator option keys from a discriminated union. + * v3: [..._def.optionsMap.keys()] + * v4: iterate options and extract literal values from discriminator field + */ +export const getDiscriminatedOptionKeys = (schema: AnySchema): string[] => { + const discriminator = getDiscriminator(schema); + + // v3 has optionsMap + if (isZodV3Schema(schema) && schema._def.optionsMap) { + return [...schema._def.optionsMap.keys()]; + } + + // v4: iterate options + const options = getUnionOptions(schema); + return options.map((option: AnySchema) => { + const shape = getObjectShape(option); + const discriminatorSchema = shape[discriminator] as AnySchema; + return getLiteralValue(discriminatorSchema) as string; + }); +}; + +/** + * Get the option schema matching a discriminator value. + * v3: _def.optionsMap.get(value) + * v4: find matching option by inspecting literal values + */ +export const getDiscriminatedOption = ( + schema: AnySchema, + discriminatorValue: string, +): AnySchema => { + const discriminator = getDiscriminator(schema); + + // v3 has optionsMap + if (isZodV3Schema(schema) && schema._def.optionsMap) { + return schema._def.optionsMap.get(discriminatorValue); + } + + // v4: iterate options + const options = getUnionOptions(schema); + return options.find((option: AnySchema) => { + const shape = getObjectShape(option); + const discriminatorSchema = shape[discriminator] as AnySchema; + return getLiteralValue(discriminatorSchema) === discriminatorValue; + }); +}; diff --git a/packages/studio/src/components/get-zod-if-possible.tsx b/packages/studio/src/components/get-zod-if-possible.tsx index 06f6943f225..1d604eb9b69 100644 --- a/packages/studio/src/components/get-zod-if-possible.tsx +++ b/packages/studio/src/components/get-zod-if-possible.tsx @@ -8,6 +8,8 @@ import React, { // eslint-disable-next-line @typescript-eslint/consistent-type-imports export type ZodType = Awaited['z']; +// eslint-disable-next-line @typescript-eslint/consistent-type-imports +export type ZodV3Type = Awaited; export type ZodTypesType = Awaited< // eslint-disable-next-line @typescript-eslint/consistent-type-imports typeof import('@remotion/zod-types') @@ -22,6 +24,15 @@ export const getZodIfPossible = async (): Promise => { } }; +export const getZodV3IfPossible = async (): Promise => { + try { + const mod = await import('zod/v3'); + return mod; + } catch { + return null; + } +}; + export const getZTypesIfPossible = async (): Promise => { try { const mod = await import('@remotion/zod-types'); @@ -36,6 +47,11 @@ export const useZodIfPossible = () => { return context?.zod ?? null; }; +export const useZodV3IfPossible = () => { + const context = useContext(ZodContext); + return context?.zodV3 ?? null; +}; + export const useZodTypesIfPossible = () => { const context = useContext(ZodContext); return context?.zodTypes ?? null; @@ -43,6 +59,7 @@ export const useZodTypesIfPossible = () => { type ContextType = { zod: ZodType | null; + zodV3: ZodV3Type | null; zodTypes: ZodTypesType | null; }; @@ -52,12 +69,17 @@ export const ZodProvider: React.FC<{ readonly children: React.ReactNode; }> = ({children}) => { const [zod, setZod] = useState(null); + const [zodV3, setZodV3] = useState(null); const [zodTypes, setZodTypes] = useState(null); useEffect(() => { getZodIfPossible().then((z) => setZod(z)); }, []); + useEffect(() => { + getZodV3IfPossible().then((z) => setZodV3(z)); + }, []); + useEffect(() => { getZTypesIfPossible().then((z) => setZodTypes(z)); }, []); @@ -65,9 +87,10 @@ export const ZodProvider: React.FC<{ const contextValue = useMemo(() => { return { zod, + zodV3, zodTypes, }; - }, [zod, zodTypes]); + }, [zod, zodV3, zodTypes]); return ( {children} diff --git a/packages/studio/src/test/create-zod-values.test.ts b/packages/studio/src/test/create-zod-values.test.ts index 417176d99a6..b680cf78894 100644 --- a/packages/studio/src/test/create-zod-values.test.ts +++ b/packages/studio/src/test/create-zod-values.test.ts @@ -72,8 +72,7 @@ test('Should be able to create a union', async () => { expect(createZodValues(z.union([z.number(), z.string()]), z, zodTypes)).toBe( 0, ); - // @ts-expect-error union - expect(createZodValues(z.union([]), z, zodTypes)).toBe(undefined); + expect(createZodValues(z.union([]) as never, z, zodTypes)).toBe(undefined); }); test('Zod literal', async () => { @@ -155,7 +154,7 @@ test('Zod record', async () => { const z = await getZ(); const zodTypes = await getZodTypes(); - const Record = z.record(z.string()); + const Record = z.record(z.string(), z.string()); expect(createZodValues(Record, z, zodTypes)).toEqual({key: ''}); }); @@ -267,7 +266,7 @@ test('Zod promise', async () => { const z = await getZ(); const zodTypes = await getZodTypes(); - const undef = z.string().promise(); + const undef = z.promise(z.string()); (createZodValues(undef, z, zodTypes) as Promise).then((v) => { expect(v).toBe(''); }); diff --git a/packages/studio/src/test/extract-zod-enums.test.ts b/packages/studio/src/test/extract-zod-enums.test.ts index 59704585094..78439ff1152 100644 --- a/packages/studio/src/test/extract-zod-enums.test.ts +++ b/packages/studio/src/test/extract-zod-enums.test.ts @@ -43,9 +43,9 @@ test('Extract Zod enums #2', () => { ), tuples: z.tuple([z.enum(['a']), z.enum(['b'])]).optional(), abc: z - .record(z.enum(['a', 'b', 'c'])) + .record(z.enum(['a', 'b', 'c']), z.unknown()) .nullable() - .default({}), + .default(() => null), branded: z.object({a: z.enum(['a'])}).brand('branded'), }), zodRuntime: z, diff --git a/packages/studio/src/visual-controls/VisualControls.tsx b/packages/studio/src/visual-controls/VisualControls.tsx index 30a96ae7141..ef865fbcfab 100644 --- a/packages/studio/src/visual-controls/VisualControls.tsx +++ b/packages/studio/src/visual-controls/VisualControls.tsx @@ -9,14 +9,14 @@ import React, { useState, } from 'react'; import {useRemotionEnvironment} from 'remotion'; -import type {z, ZodTypeAny} from 'zod'; +// eslint-disable-next-line @typescript-eslint/no-explicit-any import {getZodSchemaFromPrimitive} from '../api/get-zod-schema-from-primitive'; import {useZodIfPossible} from '../components/get-zod-if-possible'; import {getVisualControlEditedValue} from './get-current-edited-value'; export type VisualControlValueWithoutUnsaved = { valueInCode: unknown; - schema: ZodTypeAny; + schema: any; stack: string; }; @@ -38,7 +38,7 @@ export const VisualControlsTabActivatedContext = export type SetVisualControlsContextType = { updateHandles: () => void; updateValue: (key: string, value: unknown) => void; - visualControl: (key: string, value: T, schema?: z.ZodTypeAny) => T; + visualControl: (key: string, value: T, schema?: any) => T; }; export const VisualControlsContext = createContext({ @@ -47,7 +47,7 @@ export const VisualControlsContext = createContext({ export type VisualControlRef = { // May not call it visualControl, because we rely on stacktrace names - globalVisualControl: (key: string, value: T, schema?: z.ZodTypeAny) => T; + globalVisualControl: (key: string, value: T, schema?: any) => T; }; export const visualControlRef = createRef(); @@ -116,7 +116,8 @@ export const VisualControlsProvider: React.FC<{ const visualControl = useCallback( // eslint-disable-next-line prefer-arrow-callback - function (key: string, value: T, schema?: z.ZodTypeAny): T { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + function (key: string, value: T, schema?: any): T { // eslint-disable-next-line no-constant-condition if (handles && false) { /** Intentional: State is managed imperatively */ From 51b7b0929c46764c54e1b7ebdad55758ffd2a13b Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Tue, 17 Feb 2026 13:17:45 +0100 Subject: [PATCH 07/49] Fix formatting Co-Authored-By: Claude Opus 4.6 --- packages/core/src/index.ts | 2 +- packages/example/src/Root.tsx | 2 +- packages/player/src/Player.tsx | 2 +- packages/player/src/Thumbnail.tsx | 8 +++- .../src/test/ZodV3SchemaTest.tsx | 4 +- .../studio/src/api/create-composition.tsx | 3 +- .../studio/src/api/helpers/calc-new-props.ts | 3 +- .../src/components/RenderModal/DataEditor.tsx | 15 ++++-- .../RenderModal/SchemaEditor/SchemaEditor.tsx | 2 +- .../SchemaEditor/SchemaSeparationLine.tsx | 2 +- .../SchemaEditor/ZodArrayEditor.tsx | 2 +- .../SchemaEditor/ZodDefaultEditor.tsx | 2 +- .../ZodDiscriminatedUnionEditor.tsx | 31 ++++--------- .../SchemaEditor/ZodEffectEditor.tsx | 2 +- .../SchemaEditor/ZodEnumEditor.tsx | 2 +- .../SchemaEditor/ZodErrorMessages.tsx | 46 ++++++++++--------- .../SchemaEditor/ZodFieldValidation.tsx | 20 ++++---- .../SchemaEditor/ZodMatrixEditor.tsx | 2 +- .../SchemaEditor/ZodNumberEditor.tsx | 10 ++-- .../SchemaEditor/ZodObjectEditor.tsx | 2 +- .../RenderModal/SchemaEditor/ZodSwitch.tsx | 5 +- .../SchemaEditor/ZodUnionEditor.tsx | 2 +- .../SchemaEditor/create-zod-values.ts | 12 ++--- packages/web-renderer/src/create-scaffold.tsx | 9 +++- .../web-renderer/src/props-if-has-props.ts | 3 +- .../web-renderer/src/render-media-on-web.tsx | 3 +- .../web-renderer/src/render-still-on-web.tsx | 2 +- 27 files changed, 95 insertions(+), 103 deletions(-) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 6d7a48fec07..680ac270998 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -123,6 +123,7 @@ export type BundleState = checkMultipleRemotionVersions(); export * from './AbsoluteFill.js'; export * from './animated-image/index.js'; +export type {AnyZodObject} from './any-zod-type.js'; export {Artifact} from './Artifact.js'; export {Audio, Html5Audio, RemotionAudioProps} from './audio/index.js'; export type {LoopVolumeCurveBehavior} from './audio/use-audio-frame.js'; @@ -172,7 +173,6 @@ export {Series} from './series/index.js'; export * from './spring/index.js'; export {staticFile} from './static-file.js'; export * from './Still.js'; -export type {AnyZodObject} from './any-zod-type.js'; export type {PlayableMediaTag} from './timeline-position-state.js'; export {useBufferState} from './use-buffer-state'; export {useCurrentFrame} from './use-current-frame.js'; diff --git a/packages/example/src/Root.tsx b/packages/example/src/Root.tsx index 6912bfe2728..3bb285aaf3b 100644 --- a/packages/example/src/Root.tsx +++ b/packages/example/src/Root.tsx @@ -66,7 +66,6 @@ import { schemaArrayTestSchema, schemaTestSchema, } from './SchemaTest'; -import {ZodV4SchemaTest, zodV4Schema} from './ZodV4SchemaTest'; import {Scripts} from './Scripts'; import {WidthHeightSequences} from './Sequence/WidthHeightSequences'; import CircleTest from './Shapes/CircleTest'; @@ -110,6 +109,7 @@ import {VideoTesting} from './VideoTesting'; import {WarpDemoOuter} from './WarpText'; import {WarpDemo2} from './WarpText/demo2'; import {WatchStaticDemo} from './watch-static'; +import {ZodV4SchemaTest, zodV4Schema} from './ZodV4SchemaTest'; if (alias !== 'alias') { throw new Error('should support TS aliases'); diff --git a/packages/player/src/Player.tsx b/packages/player/src/Player.tsx index 18c58faad7a..03bedf09d20 100644 --- a/packages/player/src/Player.tsx +++ b/packages/player/src/Player.tsx @@ -9,6 +9,7 @@ import React, { useState, } from 'react'; import type { + AnyZodObject, CompProps, LogLevel, PlayableMediaTag, @@ -16,7 +17,6 @@ import type { TimelineContextValue, } from 'remotion'; import {Composition, Internals} from 'remotion'; -import type {AnyZodObject} from 'remotion'; import {PlayerEmitterProvider} from './EmitterProvider.js'; import type {RenderMuteButton} from './MediaVolumeSlider.js'; import type { diff --git a/packages/player/src/Thumbnail.tsx b/packages/player/src/Thumbnail.tsx index 296cf9a2695..52f4b9e07e6 100644 --- a/packages/player/src/Thumbnail.tsx +++ b/packages/player/src/Thumbnail.tsx @@ -12,9 +12,13 @@ import { useRef, useState, } from 'react'; -import type {CompProps, LogLevel, TimelineContextValue} from 'remotion'; +import type { + AnyZodObject, + CompProps, + LogLevel, + TimelineContextValue, +} from 'remotion'; import {Internals, random} from 'remotion'; -import type {AnyZodObject} from 'remotion'; import {ThumbnailEmitterContext} from './emitter-context.js'; import {ThumbnailEmitter} from './event-emitter.js'; import type {ThumbnailMethods} from './player-methods.js'; diff --git a/packages/react18-tests/src/test/ZodV3SchemaTest.tsx b/packages/react18-tests/src/test/ZodV3SchemaTest.tsx index cf2c94f9fc4..3e2c7201174 100644 --- a/packages/react18-tests/src/test/ZodV3SchemaTest.tsx +++ b/packages/react18-tests/src/test/ZodV3SchemaTest.tsx @@ -38,9 +38,7 @@ export const ZodV3SchemaTest: React.FC> = ({
Count: {count} | Enabled: {String(enabled)} | Level: {level}
-
- Tags: {tags.join(', ')} -
+
Tags: {tags.join(', ')}
); }; diff --git a/packages/studio/src/api/create-composition.tsx b/packages/studio/src/api/create-composition.tsx index dec8c1db3a8..024c7e57d4f 100644 --- a/packages/studio/src/api/create-composition.tsx +++ b/packages/studio/src/api/create-composition.tsx @@ -1,6 +1,5 @@ -import type {CompositionProps, StillProps} from 'remotion'; +import type {AnyZodObject, CompositionProps, StillProps} from 'remotion'; import {Composition, Still} from 'remotion'; -import type {AnyZodObject} from 'remotion'; export const createComposition = >({ diff --git a/packages/studio/src/api/helpers/calc-new-props.ts b/packages/studio/src/api/helpers/calc-new-props.ts index f81611db019..88e12f7ad60 100644 --- a/packages/studio/src/api/helpers/calc-new-props.ts +++ b/packages/studio/src/api/helpers/calc-new-props.ts @@ -1,6 +1,5 @@ -import type {AnyComposition} from 'remotion'; +import type {AnyComposition, AnyZodObject} from 'remotion'; import {Internals, getRemotionEnvironment} from 'remotion'; -import type {AnyZodObject} from 'remotion'; export type UpdateDefaultPropsFunction = (currentValues: { schema: AnyZodObject | null; diff --git a/packages/studio/src/components/RenderModal/DataEditor.tsx b/packages/studio/src/components/RenderModal/DataEditor.tsx index 3b06ce1fbc8..688ef01ac5e 100644 --- a/packages/studio/src/components/RenderModal/DataEditor.tsx +++ b/packages/studio/src/components/RenderModal/DataEditor.tsx @@ -8,7 +8,6 @@ import React, { import type {_InternalTypes, SerializedJSONWithCustomFields} from 'remotion'; import {getInputProps, Internals} from 'remotion'; import {NoReactInternals} from 'remotion/no-react'; -import {getZodSchemaType} from './SchemaEditor/zod-schema-type'; import {FastRefreshContext} from '../../fast-refresh-context'; import {StudioServerConnectionCtx} from '../../helpers/client-id'; import {BACKGROUND, BORDER_COLOR, LIGHT_TEXT} from '../../helpers/colors'; @@ -30,6 +29,7 @@ import { ZodNotInstalled, } from './SchemaEditor/SchemaErrorMessages'; import {extractEnumJsonPaths} from './SchemaEditor/extract-enum-json-paths'; +import {getZodSchemaType} from './SchemaEditor/zod-schema-type'; import {WarningIndicatorButton} from './WarningIndicatorButton'; import type {TypeCanSaveState} from './get-render-modal-warnings'; import { @@ -49,7 +49,7 @@ export type State = value: Record; validJSON: true; // eslint-disable-next-line @typescript-eslint/no-explicit-any - zodValidation: {success: boolean; error?: any}; + zodValidation: {success: boolean; error?: any}; } | { str: string; @@ -174,7 +174,12 @@ export const DataEditor: React.FC<{ return 'no-schema' as const; } - if (!(typeof (unresolvedComposition.schema as {safeParse?: unknown}).safeParse === 'function')) { + if ( + !( + typeof (unresolvedComposition.schema as {safeParse?: unknown}) + .safeParse === 'function' + ) + ) { throw new Error( 'A value which is not a Zod schema was passed to `schema`', ); @@ -192,7 +197,9 @@ export const DataEditor: React.FC<{ return 'no-schema' as const; } - return (schema as {safeParse: (v: unknown) => {success: boolean; error?: unknown}}).safeParse(defaultProps); + return ( + schema as {safeParse: (v: unknown) => {success: boolean; error?: unknown}} + ).safeParse(defaultProps); }, [defaultProps, schema]); const setShowWarning: React.Dispatch> = diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/SchemaEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/SchemaEditor.tsx index 6abb1e93a0e..04f13a00b11 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/SchemaEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/SchemaEditor.tsx @@ -1,6 +1,5 @@ import React, {useCallback, useEffect, useMemo, useState} from 'react'; import {Internals} from 'remotion'; -import {getZodSchemaType} from './zod-schema-type'; import {setUnsavedProps} from '../../../helpers/document-title'; import {useKeybinding} from '../../../helpers/use-keybinding'; import {VERTICAL_SCROLLBAR_CLASSNAME} from '../../Menu/is-menu-item'; @@ -15,6 +14,7 @@ import {deepEqual} from './deep-equal'; import type {RevisionContextType} from './local-state'; import {RevisionContext} from './local-state'; import {defaultPropsEditorScrollableAreaRef} from './scroll-to-default-props-path'; +import {getZodSchemaType} from './zod-schema-type'; const scrollable: React.CSSProperties = { display: 'flex', diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/SchemaSeparationLine.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/SchemaSeparationLine.tsx index 16fbcf005d0..97122827be2 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/SchemaSeparationLine.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/SchemaSeparationLine.tsx @@ -1,5 +1,4 @@ import React, {useCallback, useMemo, useState} from 'react'; -import {getArrayElement} from './zod-schema-type'; import {BACKGROUND, LIGHT_TEXT, LINE_COLOR} from '../../../helpers/colors'; import {Plus} from '../../../icons/plus'; import { @@ -9,6 +8,7 @@ import { import {Spacing} from '../../layout'; import {fieldSetText} from '../layout'; import {createZodValues} from './create-zod-values'; +import {getArrayElement} from './zod-schema-type'; export const VERTICAL_GUIDE_HEIGHT = 24; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodArrayEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodArrayEditor.tsx index 6a18785a8b6..38225a23ee3 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodArrayEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodArrayEditor.tsx @@ -1,5 +1,4 @@ import React, {useMemo, useState} from 'react'; -import {getArrayElement} from './zod-schema-type'; import { useZodIfPossible, useZodTypesIfPossible, @@ -14,6 +13,7 @@ import type {UpdaterFunction} from './ZodSwitch'; import {createZodValues} from './create-zod-values'; import {deepEqual} from './deep-equal'; import {useLocalState} from './local-state'; +import {getArrayElement} from './zod-schema-type'; import type {JSONPath} from './zod-types'; // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodDefaultEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodDefaultEditor.tsx index 700335311ac..1bc893217cb 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodDefaultEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodDefaultEditor.tsx @@ -1,8 +1,8 @@ import React from 'react'; import {getInnerType} from './zod-schema-type'; +import type {JSONPath} from './zod-types'; import type {UpdaterFunction} from './ZodSwitch'; import {ZodSwitch} from './ZodSwitch'; -import type {JSONPath} from './zod-types'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodDefaultEditor: React.FC<{ diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.tsx index b42b2e947db..9c4b239c9ba 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.tsx @@ -13,12 +13,12 @@ import {ZodObjectEditor} from './ZodObjectEditor'; import type {UpdaterFunction} from './ZodSwitch'; import {createZodValues} from './create-zod-values'; import {useLocalState} from './local-state'; -import type {JSONPath} from './zod-types'; import { - getDiscriminator, - getDiscriminatedOptionKeys, getDiscriminatedOption, + getDiscriminatedOptionKeys, + getDiscriminator, } from './zod-schema-type'; +import type {JSONPath} from './zod-types'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodDiscriminatedUnionEditor: React.FC<{ @@ -77,15 +77,13 @@ export const ZodDiscriminatedUnionEditor: React.FC<{ label: option, id: option, keyHint: null, - leftItem: - option === value[discriminator] ? : null, + leftItem: option === value[discriminator] ? : null, onClick: () => { const optionSchema = getDiscriminatedOption(schema, option); - const val = createZodValues( - optionSchema, - z, - zodTypes, - ) as Record; + const val = createZodValues(optionSchema, z, zodTypes) as Record< + string, + unknown + >; setLocalValue(() => val, false, false); }, quickSwitcherLabel: null, @@ -93,15 +91,7 @@ export const ZodDiscriminatedUnionEditor: React.FC<{ type: 'item', }; }); - }, [ - options, - setLocalValue, - discriminator, - schema, - value, - z, - zodTypes, - ]); + }, [options, setLocalValue, discriminator, schema, value, z, zodTypes]); const save = useCallback(() => { onSave(() => value, false, false); @@ -116,8 +106,7 @@ export const ZodDiscriminatedUnionEditor: React.FC<{ - {zodValidationResult.error.errors.map((error: {path: (string | number)[]; message: string}) => { - return ( -
- - - {error.path.length === 0 ? 'Root' : error.path.join('.')}:{' '} - {error.message} -
- ); - })} + {zodValidationResult.error.errors.map( + (error: {path: (string | number)[]; message: string}) => { + return ( +
+ + + {error.path.length === 0 ? 'Root' : error.path.join('.')}:{' '} + {error.message} +
+ ); + }, + )}
); } return (
- {zodValidationResult.error.errors.map((error: {path: (string | number)[]; message: string}) => { - return ( -
- -{' '} - - {error.path.length === 0 ? 'Root' : error.path.join('.')} - - : {error.message} -
- ); - })} + {zodValidationResult.error.errors.map( + (error: {path: (string | number)[]; message: string}) => { + return ( +
+ -{' '} + + {error.path.length === 0 ? 'Root' : error.path.join('.')} + + : {error.message} +
+ ); + }, + )}
); }; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodFieldValidation.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodFieldValidation.tsx index 04ce1d848a7..218d72423e8 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodFieldValidation.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodFieldValidation.tsx @@ -37,15 +37,17 @@ export const ZodFieldValidation: React.FC<{
Zod Validation has failed:
- {localValue.zodValidation.error.errors.map((error: {code: string; message: string}, index: number) => ( - // eslint-disable-next-line react/no-array-index-key -
- Type: {error.code}
- Message: {error.message} -
- Path: {path.join('.')} -
- ))} + {localValue.zodValidation.error.errors.map( + (error: {code: string; message: string}, index: number) => ( + // eslint-disable-next-line react/no-array-index-key +
+ Type: {error.code}
+ Message: {error.message} +
+ Path: {path.join('.')} +
+ ), + )}
diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodMatrixEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodMatrixEditor.tsx index 31159e49a57..fb827e41cd9 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodMatrixEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodMatrixEditor.tsx @@ -3,7 +3,6 @@ import { useZodIfPossible, useZodTypesIfPossible, } from '../../get-zod-if-possible'; -import {getArrayElement} from './zod-schema-type'; import {Fieldset} from './Fieldset'; import {SchemaLabel} from './SchemaLabel'; import {SchemaArrayItemSeparationLine} from './SchemaSeparationLine'; @@ -14,6 +13,7 @@ import type {UpdaterFunction} from './ZodSwitch'; import {createZodValues} from './create-zod-values'; import {deepEqual} from './deep-equal'; import {useLocalState} from './local-state'; +import {getArrayElement} from './zod-schema-type'; import type {JSONPath} from './zod-types'; const rowStyle: React.CSSProperties = { diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodNumberEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodNumberEditor.tsx index 1ada57a043f..48ba438686a 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodNumberEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodNumberEditor.tsx @@ -5,8 +5,8 @@ import {SchemaLabel} from './SchemaLabel'; import {ZodFieldValidation} from './ZodFieldValidation'; import type {UpdaterFunction} from './ZodSwitch'; import {useLocalState} from './local-state'; -import type {JSONPath} from './zod-types'; import {isZodV3Schema} from './zod-schema-type'; +import type {JSONPath} from './zod-types'; const fullWidth: React.CSSProperties = { width: '100%', @@ -19,9 +19,7 @@ const getMinValue = (schema: any) => { if (isZodV3Schema(schema)) { // v3: {kind: "min", value: 0, inclusive: true} - const minCheck = checks.find( - (c: {kind: string}) => c.kind === 'min', - ); + const minCheck = checks.find((c: {kind: string}) => c.kind === 'min'); if (!minCheck || !minCheck.inclusive) return -Infinity; return minCheck.value; } @@ -44,9 +42,7 @@ const getMaxValue = (schema: any) => { if (isZodV3Schema(schema)) { // v3: {kind: "max", value: 100, inclusive: true} - const maxCheck = checks.find( - (c: {kind: string}) => c.kind === 'max', - ); + const maxCheck = checks.find((c: {kind: string}) => c.kind === 'max'); if (!maxCheck || !maxCheck.inclusive) return Infinity; return maxCheck.value; } diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodObjectEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodObjectEditor.tsx index d2771003e31..e1b38af015c 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodObjectEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodObjectEditor.tsx @@ -1,5 +1,4 @@ import React, {useMemo, useState} from 'react'; -import {isZodV3Schema, getZodSchemaType} from './zod-schema-type'; import {fieldsetLabel} from '../layout'; import {Fieldset} from './Fieldset'; import {SchemaLabel} from './SchemaLabel'; @@ -9,6 +8,7 @@ import type {UpdaterFunction} from './ZodSwitch'; import {ZodSwitch} from './ZodSwitch'; import {deepEqual} from './deep-equal'; import {useLocalState} from './local-state'; +import {getZodSchemaType, isZodV3Schema} from './zod-schema-type'; import type {JSONPath} from './zod-types'; export type ObjectDiscrimatedUnionReplacement = { diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodSwitch.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodSwitch.tsx index 7016be331c3..2055f27675e 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodSwitch.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodSwitch.tsx @@ -1,9 +1,6 @@ import React from 'react'; import {useZodTypesIfPossible} from '../../get-zod-if-possible'; -import { - getZodSchemaDescription, - getZodSchemaType, -} from './zod-schema-type'; +import {getZodSchemaDescription, getZodSchemaType} from './zod-schema-type'; import type {JSONPath} from './zod-types'; import {ZodArrayEditor} from './ZodArrayEditor'; import {ZodBooleanEditor} from './ZodBooleanEditor'; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodUnionEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodUnionEditor.tsx index 6b69ee10d9e..66914b2dc16 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodUnionEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodUnionEditor.tsx @@ -1,8 +1,8 @@ import {ZonNonEditableValue} from './ZodNonEditableValue'; import {ZodOrNullishEditor} from './ZodOrNullishEditor'; import type {UpdaterFunction} from './ZodSwitch'; -import type {JSONPath} from './zod-types'; import {getZodSchemaType} from './zod-schema-type'; +import type {JSONPath} from './zod-types'; // eslint-disable-next-line @typescript-eslint/no-explicit-any const findNull = (value: readonly any[]) => { diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/create-zod-values.ts b/packages/studio/src/components/RenderModal/SchemaEditor/create-zod-values.ts index 6a69d9fe9b0..012dd7791ad 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/create-zod-values.ts +++ b/packages/studio/src/components/RenderModal/SchemaEditor/create-zod-values.ts @@ -37,15 +37,13 @@ export const createZodValues = ( if (isZodV3Schema(schema)) { for (const check of checks) { if (check.kind === 'min') return check.value; - if (check.kind === 'max' && check.value < 0) - return check.value; + if (check.kind === 'max' && check.value < 0) return check.value; } } else { for (const check of checks) { const cd = check._zod?.def; if (cd?.check === 'greater_than') return cd.value; - if (cd?.check === 'less_than' && cd.value < 0) - return cd.value; + if (cd?.check === 'less_than' && cd.value < 0) return cd.value; } } } @@ -79,11 +77,7 @@ export const createZodValues = ( const keys = Object.keys(shape); const returnValue = keys.reduce( (existing, key) => { - existing[key] = createZodValues( - shape[key], - zodRuntime, - zodTypes, - ); + existing[key] = createZodValues(shape[key], zodRuntime, zodTypes); return existing; }, {} as Record, diff --git a/packages/web-renderer/src/create-scaffold.tsx b/packages/web-renderer/src/create-scaffold.tsx index a1320a5d22b..7fe063a1db6 100644 --- a/packages/web-renderer/src/create-scaffold.tsx +++ b/packages/web-renderer/src/create-scaffold.tsx @@ -1,9 +1,14 @@ import {createRef, type ComponentType} from 'react'; import {flushSync} from 'react-dom'; import ReactDOM from 'react-dom/client'; -import type {Codec, DelayRenderScope, LogLevel, TRenderAsset} from 'remotion'; +import type { + AnyZodObject, + Codec, + DelayRenderScope, + LogLevel, + TRenderAsset, +} from 'remotion'; import {Internals} from 'remotion'; -import type {AnyZodObject} from 'remotion'; import type {TimeUpdaterRef} from './update-time'; import {UpdateTime} from './update-time'; diff --git a/packages/web-renderer/src/props-if-has-props.ts b/packages/web-renderer/src/props-if-has-props.ts index bfca486bbcf..ca6b69edc9a 100644 --- a/packages/web-renderer/src/props-if-has-props.ts +++ b/packages/web-renderer/src/props-if-has-props.ts @@ -1,6 +1,5 @@ import type {ComponentType} from 'react'; -import type {CalculateMetadataFunction} from 'remotion'; -import type {AnyZodObject} from 'remotion'; +import type {AnyZodObject, CalculateMetadataFunction} from 'remotion'; export type InferProps< Schema extends AnyZodObject, diff --git a/packages/web-renderer/src/render-media-on-web.tsx b/packages/web-renderer/src/render-media-on-web.tsx index e139aa3286b..4f8bb2a985a 100644 --- a/packages/web-renderer/src/render-media-on-web.tsx +++ b/packages/web-renderer/src/render-media-on-web.tsx @@ -1,8 +1,7 @@ import {BufferTarget, StreamTarget} from 'mediabunny'; -import type {CalculateMetadataFunction} from 'remotion'; +import type {AnyZodObject, CalculateMetadataFunction} from 'remotion'; import {Internals, type LogLevel} from 'remotion'; import {VERSION} from 'remotion/version'; -import type {AnyZodObject} from 'remotion'; import {addAudioSample, addVideoSampleAndCloseFrame} from './add-sample'; import {handleArtifacts, type WebRendererOnArtifact} from './artifact'; import {onlyInlineAudio} from './audio'; diff --git a/packages/web-renderer/src/render-still-on-web.tsx b/packages/web-renderer/src/render-still-on-web.tsx index 413098a8138..fc287a08f0f 100644 --- a/packages/web-renderer/src/render-still-on-web.tsx +++ b/packages/web-renderer/src/render-still-on-web.tsx @@ -1,9 +1,9 @@ +import type {AnyZodObject} from 'remotion'; import { Internals, type CalculateMetadataFunction, type LogLevel, } from 'remotion'; -import type {AnyZodObject} from 'remotion'; import type {WebRendererOnArtifact} from './artifact'; import {handleArtifacts} from './artifact'; import {checkForError, createScaffold} from './create-scaffold'; From eea1a5a214b75e07e3328fa7c081d6b27f299dfe Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Tue, 17 Feb 2026 13:49:41 +0100 Subject: [PATCH 08/49] add lint --- .../RenderModal/SchemaEditor/create-zod-values.ts | 2 +- .../RenderModal/SchemaEditor/zod-schema-type.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/create-zod-values.ts b/packages/studio/src/components/RenderModal/SchemaEditor/create-zod-values.ts index 012dd7791ad..eb270bb0115 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/create-zod-values.ts +++ b/packages/studio/src/components/RenderModal/SchemaEditor/create-zod-values.ts @@ -32,7 +32,7 @@ export const createZodValues = ( case 'string': return ''; case 'number': { - const checks = def.checks; + const {checks} = def; if (checks) { if (isZodV3Schema(schema)) { for (const check of checks) { diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/zod-schema-type.ts b/packages/studio/src/components/RenderModal/SchemaEditor/zod-schema-type.ts index aa4cfe492c4..3cea7c59892 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/zod-schema-type.ts +++ b/packages/studio/src/components/RenderModal/SchemaEditor/zod-schema-type.ts @@ -86,12 +86,12 @@ export const isZodV3Schema = (schema: AnySchema): boolean => { */ export const getZodSchemaType = (schema: AnySchema): ZodSchemaType => { if (isZodV3Schema(schema)) { - const typeName: string = schema._def.typeName; + const {typeName} = schema._def; return v3TypeNameMap[typeName] ?? typeName; } // v4 schema: _def.type is a string like "string", "number", etc. - const type: string = schema._def.type; + const {type} = schema._def; // In v4, discriminatedUnion has _def.type === "union" with _def.discriminator if (type === 'union' && schema._def.discriminator !== undefined) { @@ -123,7 +123,7 @@ export const getZodSchemaDescription = ( * v4: _def.shape (plain object) */ export const getObjectShape = (schema: AnySchema): Record => { - const shape = schema._def.shape; + const {shape} = schema._def; return typeof shape === 'function' ? shape() : shape; }; @@ -175,7 +175,7 @@ export const getEnumValues = (schema: AnySchema): string[] => { return schema._def.values; } - const entries = schema._def.entries; + const {entries} = schema._def; return Object.values(entries); }; From 5373f2b203f4fd44ddce87964f04ac4659fa4f3f Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Tue, 17 Feb 2026 14:32:03 +0100 Subject: [PATCH 09/49] formatting --- .../ZodDiscriminatedUnionEditor.tsx | 7 +- .../SchemaEditor/create-zod-values.ts | 123 ++++++---- .../SchemaEditor/extract-enum-json-paths.ts | 68 +++--- .../SchemaEditor/zod-schema-type.ts | 214 ++++++++++++++---- .../studio/src/test/create-zod-values.test.ts | 6 +- 5 files changed, 294 insertions(+), 124 deletions(-) diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.tsx index 9c4b239c9ba..2e2c744d0da 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.tsx @@ -20,7 +20,6 @@ import { } from './zod-schema-type'; import type {JSONPath} from './zod-types'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodDiscriminatedUnionEditor: React.FC<{ schema: any; setValue: UpdaterFunction>; @@ -80,6 +79,12 @@ export const ZodDiscriminatedUnionEditor: React.FC<{ leftItem: option === value[discriminator] ? : null, onClick: () => { const optionSchema = getDiscriminatedOption(schema, option); + if (!optionSchema) { + throw new Error( + `No schema found for discriminator value: ${option}`, + ); + } + const val = createZodValues(optionSchema, z, zodTypes) as Record< string, unknown diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/create-zod-values.ts b/packages/studio/src/components/RenderModal/SchemaEditor/create-zod-values.ts index eb270bb0115..08d85c4e540 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/create-zod-values.ts +++ b/packages/studio/src/components/RenderModal/SchemaEditor/create-zod-values.ts @@ -1,23 +1,29 @@ import type {ZodTypesType} from '../../get-zod-if-possible'; import { + type AnyZodSchema, getArrayElement, + getBrandedInner, getDefaultValue, getEffectsInner, - getEnumValues, + getFirstEnumValue, getInnerType, + getIntersectionSchemas, getLiteralValue, getObjectShape, + getPipelineInput, + getPipelineOutput, + getRecordKeyType, + getRecordValueType, + getTupleItems, getUnionOptions, + getZodDef, getZodSchemaDescription, getZodSchemaType, isZodV3Schema, } from './zod-schema-type'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type AnySchema = any; - export const createZodValues = ( - schema: AnySchema, + schema: AnyZodSchema, zodRuntime: unknown, zodTypes: ZodTypesType | null, ): unknown => { @@ -25,14 +31,35 @@ export const createZodValues = ( throw new Error('Invalid zod schema'); } - const def = schema._def; + // In v4, .refine()/.describe() don't wrap in effects — the description + // lives directly on the schema. Check for branded descriptions early + // so they are detected regardless of the underlying type. + const description = getZodSchemaDescription(schema); + if (zodTypes) { + if (description === zodTypes.ZodZypesInternals.REMOTION_COLOR_BRAND) { + return '#ffffff'; + } + + if (description === zodTypes.ZodZypesInternals.REMOTION_TEXTAREA_BRAND) { + return ''; + } + + if (description === zodTypes.ZodZypesInternals.REMOTION_MATRIX_BRAND) { + return [ + [1, 0, 0], + [0, 1, 0], + [0, 0, 1], + ]; + } + } + const typeName = getZodSchemaType(schema); switch (typeName) { case 'string': return ''; case 'number': { - const {checks} = def; + const {checks} = getZodDef(schema); if (checks) { if (isZodV3Schema(schema)) { for (const check of checks) { @@ -67,6 +94,7 @@ export const createZodValues = ( case 'null': return null; case 'any': + case 'custom': throw new Error('Cannot create a value for type z.any()'); case 'unknown': throw new Error('Cannot create a value for type z.unknown()'); @@ -97,8 +125,8 @@ export const createZodValues = ( } case 'discriminatedUnion': { - const options = getUnionOptions(schema)[0]; - return createZodValues(options, zodRuntime, zodTypes); + const firstOption = getUnionOptions(schema)[0]; + return createZodValues(firstOption, zodRuntime, zodTypes); } case 'literal': { @@ -106,37 +134,11 @@ export const createZodValues = ( } case 'effects': { - const description = getZodSchemaDescription(schema); - if ( - zodTypes && - description === zodTypes.ZodZypesInternals.REMOTION_COLOR_BRAND - ) { - return '#ffffff'; - } - - if ( - zodTypes && - description === zodTypes.ZodZypesInternals.REMOTION_TEXTAREA_BRAND - ) { - return ''; - } - - if ( - zodTypes && - description === zodTypes.ZodZypesInternals.REMOTION_MATRIX_BRAND - ) { - return [ - [1, 0, 0], - [0, 1, 0], - [0, 0, 1], - ]; - } - return createZodValues(getEffectsInner(schema), zodRuntime, zodTypes); } case 'intersection': { - const {left, right} = def; + const {left, right} = getIntersectionSchemas(schema); const leftValue = createZodValues(left, zodRuntime, zodTypes); if (typeof leftValue !== 'object') { throw new Error( @@ -156,30 +158,45 @@ export const createZodValues = ( } case 'tuple': { - const items = def.items.map((item: AnySchema) => + return getTupleItems(schema).map((item) => createZodValues(item, zodRuntime, zodTypes), ); - return items; } case 'record': { - const values = createZodValues(def.valueType, zodRuntime, zodTypes); + const values = createZodValues( + getRecordValueType(schema), + zodRuntime, + zodTypes, + ); return {key: values}; } case 'map': { - const values = createZodValues(def.valueType, zodRuntime, zodTypes); - const key = createZodValues(def.keyType, zodRuntime, zodTypes); + const values = createZodValues( + getRecordValueType(schema), + zodRuntime, + zodTypes, + ); + const key = createZodValues( + getRecordKeyType(schema), + zodRuntime, + zodTypes, + ); return new Map([[key, values]]); } case 'lazy': { - const type = def.getter(); + const type = getZodDef(schema).getter(); return createZodValues(type, zodRuntime, zodTypes); } case 'set': { - const values = createZodValues(def.valueType, zodRuntime, zodTypes); + const values = createZodValues( + getZodDef(schema).valueType, + zodRuntime, + zodTypes, + ); return new Set([values]); } @@ -188,7 +205,7 @@ export const createZodValues = ( } case 'enum': { - return getEnumValues(schema)[0]; + return getFirstEnumValue(schema); } case 'nativeEnum': { @@ -206,6 +223,7 @@ export const createZodValues = ( } case 'promise': { + const def = getZodDef(schema); // v3: _def.type, v4: _def.innerType const inner = isZodV3Schema(schema) ? def.type : def.innerType; const value = createZodValues(inner, zodRuntime, zodTypes); @@ -213,14 +231,19 @@ export const createZodValues = ( } case 'branded': { - // v3: _def.type, v4: schema is the base type (branded doesn't wrap in v4) - const inner = isZodV3Schema(schema) ? def.type : schema; - return createZodValues(inner, zodRuntime, zodTypes); + return createZodValues(getBrandedInner(schema), zodRuntime, zodTypes); } - case 'pipeline': { - // v3: _def.out, v4: _def.out - return createZodValues(def.out, zodRuntime, zodTypes); + case 'pipeline': + case 'pipe': { + const out = getPipelineOutput(schema); + // In v4, .transform() creates pipe { in, out: transform }. + // Since we don't apply transforms, use the input side. + if (getZodSchemaType(out) === 'transform') { + return createZodValues(getPipelineInput(schema), zodRuntime, zodTypes); + } + + return createZodValues(out, zodRuntime, zodTypes); } default: diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/extract-enum-json-paths.ts b/packages/studio/src/components/RenderModal/SchemaEditor/extract-enum-json-paths.ts index 74999f6e766..817d183b1ae 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/extract-enum-json-paths.ts +++ b/packages/studio/src/components/RenderModal/SchemaEditor/extract-enum-json-paths.ts @@ -1,30 +1,43 @@ import type {ZodTypesType} from '../../get-zod-if-possible'; import { + type AnyZodSchema, getArrayElement, + getBrandedInner, getEffectsInner, getInnerType, + getIntersectionSchemas, getObjectShape, + getPipelineOutput, + getRecordKeyType, + getRecordValueType, + getTupleItems, getUnionOptions, getZodSchemaDescription, getZodSchemaType, - isZodV3Schema, } from './zod-schema-type'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type AnySchema = any; - export const extractEnumJsonPaths = ({ schema, zodRuntime, currentPath, zodTypes, }: { - schema: AnySchema; + schema: AnyZodSchema; zodRuntime: unknown; zodTypes: ZodTypesType | null; currentPath: (string | number)[]; }): (string | number)[][] => { - const def = schema._def; + // In v4, .refine()/.describe() don't wrap in effects — the description + // lives directly on the schema. Check for branded descriptions early + // so they are detected regardless of the underlying type. + const description = getZodSchemaDescription(schema); + if ( + zodTypes && + description === zodTypes.ZodZypesInternals.REMOTION_MATRIX_BRAND + ) { + return [currentPath]; + } + const typeName = getZodSchemaType(schema); switch (typeName) { @@ -54,7 +67,7 @@ export const extractEnumJsonPaths = ({ case 'union': { return getUnionOptions(schema) - .map((option: AnySchema) => { + .map((option) => { return extractEnumJsonPaths({ schema: option, zodRuntime, @@ -67,7 +80,7 @@ export const extractEnumJsonPaths = ({ case 'discriminatedUnion': { return getUnionOptions(schema) - .map((op: AnySchema) => { + .map((op) => { return extractEnumJsonPaths({ schema: op, zodRuntime, @@ -83,14 +96,6 @@ export const extractEnumJsonPaths = ({ } case 'effects': { - const description = getZodSchemaDescription(schema); - if ( - zodTypes && - description === zodTypes.ZodZypesInternals.REMOTION_MATRIX_BRAND - ) { - return [currentPath]; - } - return extractEnumJsonPaths({ schema: getEffectsInner(schema), zodRuntime, @@ -100,7 +105,7 @@ export const extractEnumJsonPaths = ({ } case 'intersection': { - const {left, right} = def; + const {left, right} = getIntersectionSchemas(schema); const leftValue = extractEnumJsonPaths({ schema: left, zodRuntime, @@ -119,8 +124,8 @@ export const extractEnumJsonPaths = ({ } case 'tuple': { - return def.items - .map((item: AnySchema, i: number) => + return getTupleItems(schema) + .map((item, i) => extractEnumJsonPaths({ schema: item, zodRuntime, @@ -132,12 +137,20 @@ export const extractEnumJsonPaths = ({ } case 'record': { - return extractEnumJsonPaths({ - schema: def.valueType, + const recordPath = [...currentPath, '{}']; + const keyResults = extractEnumJsonPaths({ + schema: getRecordKeyType(schema), + zodRuntime, + currentPath: recordPath, + zodTypes, + }); + const valueResults = extractEnumJsonPaths({ + schema: getRecordValueType(schema), zodRuntime, - currentPath: [...currentPath, '{}'], + currentPath: recordPath, zodTypes, }); + return [...keyResults, ...valueResults]; } case 'function': { @@ -177,18 +190,18 @@ export const extractEnumJsonPaths = ({ } case 'branded': { - const inner = isZodV3Schema(schema) ? def.type : schema; return extractEnumJsonPaths({ - schema: inner, + schema: getBrandedInner(schema), zodRuntime, currentPath, zodTypes, }); } - case 'pipeline': { + case 'pipeline': + case 'pipe': { return extractEnumJsonPaths({ - schema: def.out, + schema: getPipelineOutput(schema), zodRuntime, currentPath, zodTypes, @@ -210,7 +223,8 @@ export const extractEnumJsonPaths = ({ case 'void': case 'map': case 'lazy': - case 'set': { + case 'set': + case 'custom': { return []; } diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/zod-schema-type.ts b/packages/studio/src/components/RenderModal/SchemaEditor/zod-schema-type.ts index 3cea7c59892..e374482ae85 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/zod-schema-type.ts +++ b/packages/studio/src/components/RenderModal/SchemaEditor/zod-schema-type.ts @@ -8,8 +8,28 @@ * and accessor helpers that abstract v3/v4 `_def` property differences. */ +/** + * Structural type for any Zod schema (v3 or v4). + * + * v3 schemas have `_def` with `typeName` property. + * v4 classic schemas have `_def` with `type` property. + * v4 core schemas have `_zod.def` with `type` property. + * At runtime, all zod schemas have `_def` (classic layer adds it for v4). + */ +export interface AnyZodSchema { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly _def?: Record; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly _zod?: {def: Record; [key: string]: any}; + readonly description?: string; +} + // eslint-disable-next-line @typescript-eslint/no-explicit-any -type AnySchema = any; +export const getZodDef = (schema: AnyZodSchema): Record => { + if (schema._def) return schema._def; + if (schema._zod) return schema._zod.def; + throw new Error('Invalid zod schema: missing _def and _zod'); +}; export type ZodSchemaType = | 'string' @@ -74,8 +94,9 @@ const v3TypeNameMap: Record = { ZodPipeline: 'pipeline', }; -export const isZodV3Schema = (schema: AnySchema): boolean => { - return '_def' in schema && 'typeName' in schema._def; +export const isZodV3Schema = (schema: AnyZodSchema): boolean => { + const def = getZodDef(schema); + return 'typeName' in def; }; /** @@ -84,17 +105,19 @@ export const isZodV3Schema = (schema: AnySchema): boolean => { * In v4, discriminatedUnion is a union with a `discriminator` property on `_def`. * This function returns 'discriminatedUnion' for that case. */ -export const getZodSchemaType = (schema: AnySchema): ZodSchemaType => { - if (isZodV3Schema(schema)) { - const {typeName} = schema._def; +export const getZodSchemaType = (schema: AnyZodSchema): ZodSchemaType => { + const def = getZodDef(schema); + + if ('typeName' in def) { + const {typeName} = def; return v3TypeNameMap[typeName] ?? typeName; } - // v4 schema: _def.type is a string like "string", "number", etc. - const {type} = schema._def; + // v4 schema: def.type is a string like "string", "number", etc. + const {type} = def; - // In v4, discriminatedUnion has _def.type === "union" with _def.discriminator - if (type === 'union' && schema._def.discriminator !== undefined) { + // In v4, discriminatedUnion has def.type === "union" with def.discriminator + if (type === 'union' && def.discriminator !== undefined) { return 'discriminatedUnion'; } @@ -104,14 +127,14 @@ export const getZodSchemaType = (schema: AnySchema): ZodSchemaType => { /** * Get the description of a schema, handling v3 vs v4 differences. * - * v3: schema._def.description + * v3: _def.description * v4: schema.description */ export const getZodSchemaDescription = ( - schema: AnySchema, + schema: AnyZodSchema, ): string | undefined => { if (isZodV3Schema(schema)) { - return schema._def.description; + return getZodDef(schema).description; } return schema.description; @@ -122,8 +145,10 @@ export const getZodSchemaDescription = ( * v3: _def.shape() (function) * v4: _def.shape (plain object) */ -export const getObjectShape = (schema: AnySchema): Record => { - const {shape} = schema._def; +export const getObjectShape = ( + schema: AnyZodSchema, +): Record => { + const {shape} = getZodDef(schema); return typeof shape === 'function' ? shape() : shape; }; @@ -132,24 +157,25 @@ export const getObjectShape = (schema: AnySchema): Record => { * v3: _def.type * v4: _def.element */ -export const getArrayElement = (schema: AnySchema): AnySchema => { - return isZodV3Schema(schema) ? schema._def.type : schema._def.element; +export const getArrayElement = (schema: AnyZodSchema): AnyZodSchema => { + const def = getZodDef(schema); + return isZodV3Schema(schema) ? def.type : def.element; }; /** * Get the inner type for wrappers like optional, nullable, default, catch. * Both v3 and v4 use _def.innerType. */ -export const getInnerType = (schema: AnySchema): AnySchema => { - return schema._def.innerType; +export const getInnerType = (schema: AnyZodSchema): AnyZodSchema => { + return getZodDef(schema).innerType; }; /** * Get the inner schema for effects (v3 only - v4 doesn't wrap). * v3: _def.schema */ -export const getEffectsInner = (schema: AnySchema): AnySchema => { - return schema._def.schema; +export const getEffectsInner = (schema: AnyZodSchema): AnyZodSchema => { + return getZodDef(schema).schema; }; /** @@ -157,12 +183,13 @@ export const getEffectsInner = (schema: AnySchema): AnySchema => { * v3: _def.value (single value) * v4: _def.values (array of values) - take the first */ -export const getLiteralValue = (schema: AnySchema): unknown => { +export const getLiteralValue = (schema: AnyZodSchema): unknown => { + const def = getZodDef(schema); if (isZodV3Schema(schema)) { - return schema._def.value; + return def.value; } - return schema._def.values?.[0]; + return def.values?.[0]; }; /** @@ -170,21 +197,58 @@ export const getLiteralValue = (schema: AnySchema): unknown => { * v3: _def.values (string[]) * v4: _def.entries (Record) - convert to values array */ -export const getEnumValues = (schema: AnySchema): string[] => { +export const getEnumValues = (schema: AnyZodSchema): string[] => { + const def = getZodDef(schema); if (isZodV3Schema(schema)) { - return schema._def.values; + return def.values; } - const {entries} = schema._def; + const {entries} = def; return Object.values(entries); }; +/** + * Get the first valid value from an enum schema. + * Handles both regular enums and nativeEnums. + * + * In v4, nativeEnums are represented as regular enums with bidirectional + * entries (e.g. { Apple: 0, "0": "Apple" }). This function filters out + * the reverse mappings to return actual enum values. + */ +export const getFirstEnumValue = (schema: AnyZodSchema): unknown => { + const def = getZodDef(schema); + + if (isZodV3Schema(schema)) { + if (def.typeName === 'ZodNativeEnum') { + const vals = Object.values(def.values); + return vals[0]; + } + + return def.values[0]; + } + + const {entries} = def; + const pairs = Object.entries(entries); + + // Check for native enum with bidirectional mapping + const hasReverseMapping = pairs.some(([key, value]) => key !== String(value)); + if (hasReverseMapping) { + // For numeric native enums, filter out the numeric-key reverse mappings + const forwardPairs = pairs.filter(([key]) => Number.isNaN(Number(key))); + if (forwardPairs.length > 0) { + return forwardPairs[0][1]; + } + } + + return Object.values(entries)[0]; +}; + /** * Get the union/discriminatedUnion options array. * Both v3 and v4 use _def.options. */ -export const getUnionOptions = (schema: AnySchema): AnySchema[] => { - return schema._def.options; +export const getUnionOptions = (schema: AnyZodSchema): AnyZodSchema[] => { + return getZodDef(schema).options; }; /** @@ -192,8 +256,8 @@ export const getUnionOptions = (schema: AnySchema): AnySchema[] => { * v3: _def.defaultValue() (function) * v4: _def.defaultValue (plain value) */ -export const getDefaultValue = (schema: AnySchema): unknown => { - const dv = schema._def.defaultValue; +export const getDefaultValue = (schema: AnyZodSchema): unknown => { + const dv = getZodDef(schema).defaultValue; return typeof dv === 'function' ? dv() : dv; }; @@ -202,8 +266,8 @@ export const getDefaultValue = (schema: AnySchema): unknown => { * v3: _def.discriminator * v4: _def.discriminator */ -export const getDiscriminator = (schema: AnySchema): string => { - return schema._def.discriminator; +export const getDiscriminator = (schema: AnyZodSchema): string => { + return getZodDef(schema).discriminator; }; /** @@ -211,19 +275,20 @@ export const getDiscriminator = (schema: AnySchema): string => { * v3: [..._def.optionsMap.keys()] * v4: iterate options and extract literal values from discriminator field */ -export const getDiscriminatedOptionKeys = (schema: AnySchema): string[] => { +export const getDiscriminatedOptionKeys = (schema: AnyZodSchema): string[] => { + const def = getZodDef(schema); const discriminator = getDiscriminator(schema); // v3 has optionsMap - if (isZodV3Schema(schema) && schema._def.optionsMap) { - return [...schema._def.optionsMap.keys()]; + if (isZodV3Schema(schema) && def.optionsMap) { + return [...def.optionsMap.keys()]; } // v4: iterate options const options = getUnionOptions(schema); - return options.map((option: AnySchema) => { + return options.map((option) => { const shape = getObjectShape(option); - const discriminatorSchema = shape[discriminator] as AnySchema; + const discriminatorSchema = shape[discriminator]; return getLiteralValue(discriminatorSchema) as string; }); }; @@ -234,21 +299,82 @@ export const getDiscriminatedOptionKeys = (schema: AnySchema): string[] => { * v4: find matching option by inspecting literal values */ export const getDiscriminatedOption = ( - schema: AnySchema, + schema: AnyZodSchema, discriminatorValue: string, -): AnySchema => { +): AnyZodSchema | undefined => { + const def = getZodDef(schema); const discriminator = getDiscriminator(schema); // v3 has optionsMap - if (isZodV3Schema(schema) && schema._def.optionsMap) { - return schema._def.optionsMap.get(discriminatorValue); + if (isZodV3Schema(schema) && def.optionsMap) { + return def.optionsMap.get(discriminatorValue); } // v4: iterate options const options = getUnionOptions(schema); - return options.find((option: AnySchema) => { + return options.find((option) => { const shape = getObjectShape(option); - const discriminatorSchema = shape[discriminator] as AnySchema; + const discriminatorSchema = shape[discriminator]; return getLiteralValue(discriminatorSchema) === discriminatorValue; }); }; + +/** + * Get the left and right schemas from an intersection. + * Both v3 and v4 use _def.left and _def.right. + */ +export const getIntersectionSchemas = ( + schema: AnyZodSchema, +): {left: AnyZodSchema; right: AnyZodSchema} => { + const def = getZodDef(schema); + return {left: def.left, right: def.right}; +}; + +/** + * Get the items array from a tuple schema. + * Both v3 and v4 use _def.items. + */ +export const getTupleItems = (schema: AnyZodSchema): AnyZodSchema[] => { + return getZodDef(schema).items; +}; + +/** + * Get the value type schema from a record. + * Both v3 and v4 use _def.valueType. + */ +export const getRecordValueType = (schema: AnyZodSchema): AnyZodSchema => { + return getZodDef(schema).valueType; +}; + +/** + * Get the key type schema from a record. + * Both v3 and v4 use _def.keyType. + */ +export const getRecordKeyType = (schema: AnyZodSchema): AnyZodSchema => { + return getZodDef(schema).keyType; +}; + +/** + * Get the output schema from a pipeline/pipe. + * Both v3 and v4 use _def.out. + */ +export const getPipelineOutput = (schema: AnyZodSchema): AnyZodSchema => { + return getZodDef(schema).out; +}; + +/** + * Get the input schema from a pipeline/pipe. + * Both v3 and v4 use _def.in. + */ +export const getPipelineInput = (schema: AnyZodSchema): AnyZodSchema => { + return getZodDef(schema).in; +}; + +/** + * Get the inner schema from a branded type. + * v3: _def.type + * v4: branded is the schema itself (branding is type-level only) + */ +export const getBrandedInner = (schema: AnyZodSchema): AnyZodSchema => { + return isZodV3Schema(schema) ? getZodDef(schema).type : schema; +}; diff --git a/packages/studio/src/test/create-zod-values.test.ts b/packages/studio/src/test/create-zod-values.test.ts index b680cf78894..461c9a7f129 100644 --- a/packages/studio/src/test/create-zod-values.test.ts +++ b/packages/studio/src/test/create-zod-values.test.ts @@ -72,7 +72,8 @@ test('Should be able to create a union', async () => { expect(createZodValues(z.union([z.number(), z.string()]), z, zodTypes)).toBe( 0, ); - expect(createZodValues(z.union([]) as never, z, zodTypes)).toBe(undefined); + // In v4, z.union([]) throws during schema creation + expect(() => createZodValues(z.union([]) as never, z, zodTypes)).toThrow(); }); test('Zod literal', async () => { @@ -108,10 +109,11 @@ test('Should be able to create a discriminated union', async () => { ), ).toEqual({status: 'failed', error: 0}); + // In v4, z.discriminatedUnion('status', []) throws during schema creation expect(() => // @ts-expect-error invalid zod type createZodValues(z.discriminatedUnion('status', []), z, zodTypes), - ).toThrow(/Invalid zod schema/); + ).toThrow(); }); test('Zod instanceof', async () => { From 473eb0c3d4597a5730ef945f4f1a688020bc93af Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Tue, 17 Feb 2026 16:10:02 +0100 Subject: [PATCH 10/49] Fix InferProps to preserve schema type inference for v3 and v4 Use structural typing (InferZodInput) to extract input types from both zod v3 (_input) and v4 (_zod.input) schemas instead of losing type information with Record. Co-Authored-By: Claude Opus 4.6 --- packages/core/src/Composition.tsx | 5 +++-- packages/core/src/props-if-has-props.ts | 17 +++++++++++++++-- .../src/calculate-metadata/schema.ts | 2 +- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/core/src/Composition.tsx b/packages/core/src/Composition.tsx index 11bde1371d8..e04fc36d77b 100644 --- a/packages/core/src/Composition.tsx +++ b/packages/core/src/Composition.tsx @@ -8,6 +8,7 @@ import { CanUseRemotionHooksProvider, } from './CanUseRemotionHooks.js'; import type {Codec} from './codec.js'; +import type {TComposition} from './CompositionManager.js'; import {CompositionSetters} from './CompositionManagerContext.js'; import {FolderContext} from './Folder.js'; import {serializeThenDeserializeInStudio} from './input-props-serialization.js'; @@ -197,12 +198,12 @@ const InnerComposition = < component: lazy, defaultProps: serializeThenDeserializeInStudio( (defaultProps ?? {}) as z.output & Props, - ) as z.output & Props, + ) as InferProps, nonce, parentFolderName: parentName, schema: schema ?? null, calculateMetadata: compProps.calculateMetadata ?? null, - }); + } as TComposition); return () => { unregisterComposition(id); diff --git a/packages/core/src/props-if-has-props.ts b/packages/core/src/props-if-has-props.ts index 211a9e0fccc..2ff9fcc6cab 100644 --- a/packages/core/src/props-if-has-props.ts +++ b/packages/core/src/props-if-has-props.ts @@ -6,6 +6,19 @@ type And
= A extends true : false : false; +/** + * Infer the input type of a zod schema using structural typing. + * v3 schemas have `_input` phantom type. + * v4 schemas have `_zod.input` phantom type. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type InferZodInput = T extends {_zod: {input: any}} + ? T['_zod']['input'] + : // eslint-disable-next-line @typescript-eslint/no-explicit-any + T extends {_input: any} + ? T['_input'] + : Record; + export type PropsIfHasProps< Schema extends AnyZodObject, Props extends Record, @@ -34,6 +47,6 @@ export type InferProps< Props : {} extends Props ? // Only schema specified - Record + InferZodInput : // Props and schema specified - Record & Props; + InferZodInput & Props; diff --git a/packages/template-code-hike/src/calculate-metadata/schema.ts b/packages/template-code-hike/src/calculate-metadata/schema.ts index 99b2d8231f0..d1a374b3e80 100644 --- a/packages/template-code-hike/src/calculate-metadata/schema.ts +++ b/packages/template-code-hike/src/calculate-metadata/schema.ts @@ -7,7 +7,7 @@ export const width = z.discriminatedUnion("type", [ }), z.object({ type: z.literal("fixed"), - value: z.number().step(1), + value: z.number().multipleOf(1), }), ]); From 2465b873cae7e65de16c662069e63b1eb3cb7120 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Tue, 17 Feb 2026 16:42:27 +0100 Subject: [PATCH 11/49] Fix lint errors for zod v4 upgrade - Cast schema to `any` when passing to `zodToJsonSchema` in template-prompt-to-video since zod-to-json-schema types expect zod v3 - Use object destructuring in ZodNumberEditor to satisfy prefer-destructuring - Merge eslint-disable comments in VisualControls so prefer-arrow-callback suppression applies to the correct line Co-authored-by: Cursor --- .../components/RenderModal/SchemaEditor/ZodNumberEditor.tsx | 6 +++--- packages/studio/src/visual-controls/VisualControls.tsx | 3 +-- packages/template-prompt-to-video/cli/service.ts | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodNumberEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodNumberEditor.tsx index 48ba438686a..66c1c650a83 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodNumberEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodNumberEditor.tsx @@ -14,7 +14,7 @@ const fullWidth: React.CSSProperties = { // eslint-disable-next-line @typescript-eslint/no-explicit-any const getMinValue = (schema: any) => { - const checks = schema._def.checks; + const {checks} = schema._def; if (!checks) return -Infinity; if (isZodV3Schema(schema)) { @@ -37,7 +37,7 @@ const getMinValue = (schema: any) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const getMaxValue = (schema: any) => { - const checks = schema._def.checks; + const {checks} = schema._def; if (!checks) return Infinity; if (isZodV3Schema(schema)) { @@ -60,7 +60,7 @@ const getMaxValue = (schema: any) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const getStep = (schema: any): number | undefined => { - const checks = schema._def.checks; + const {checks} = schema._def; if (!checks) return undefined; if (isZodV3Schema(schema)) { diff --git a/packages/studio/src/visual-controls/VisualControls.tsx b/packages/studio/src/visual-controls/VisualControls.tsx index ef865fbcfab..519bdfd7079 100644 --- a/packages/studio/src/visual-controls/VisualControls.tsx +++ b/packages/studio/src/visual-controls/VisualControls.tsx @@ -115,8 +115,7 @@ export const VisualControlsProvider: React.FC<{ const env = useRemotionEnvironment(); const visualControl = useCallback( - // eslint-disable-next-line prefer-arrow-callback - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // eslint-disable-next-line prefer-arrow-callback, @typescript-eslint/no-explicit-any function (key: string, value: T, schema?: any): T { // eslint-disable-next-line no-constant-condition if (handles && false) { diff --git a/packages/template-prompt-to-video/cli/service.ts b/packages/template-prompt-to-video/cli/service.ts index 35fbfad337a..654630a1088 100644 --- a/packages/template-prompt-to-video/cli/service.ts +++ b/packages/template-prompt-to-video/cli/service.ts @@ -16,7 +16,7 @@ export const openaiStructuredCompletion = async ( schema: z.ZodType, ): Promise => { // eslint-disable-next-line @typescript-eslint/no-explicit-any - const jsonSchema = zodToJsonSchema(schema) as any; + const jsonSchema = zodToJsonSchema(schema as any) as any; const res = await fetch("https://api.openai.com/v1/chat/completions", { method: "POST", From 8eb3a62110f485abd8f6be6a44a2454ca06deb51 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Tue, 17 Feb 2026 17:04:27 +0100 Subject: [PATCH 12/49] Support standalone zod v3 (3.22.x) schemas in AnyZodObject Add StandaloneZodV3Object structural type to AnyZodObject union so schemas from standalone zod 3.22.x (which lack ~standard/~validate from the zod/v4 compat layer) are accepted by . Co-Authored-By: Claude Opus 4.6 --- bun.lock | 4 +++- packages/core/src/any-zod-type.ts | 12 +++++++++++- packages/example/src/Root.tsx | 9 ++++----- packages/example/src/ZodV4SchemaTest.tsx | 2 +- packages/react18-tests/package.json | 2 +- packages/react18-tests/src/test/ZodV3SchemaTest.tsx | 2 +- 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/bun.lock b/bun.lock index c7547deb941..ec3f0c6462a 100644 --- a/bun.lock +++ b/bun.lock @@ -1164,7 +1164,7 @@ "version": "4.0.423", "dependencies": { "remotion": "workspace:*", - "zod": "catalog:", + "zod": "3.22.3", }, "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", @@ -8892,6 +8892,8 @@ "@remotion/react18-tests/react-dom": ["react-dom@18.3.1", "", { "dependencies": { "loose-envify": "1.4.0", "scheduler": "0.23.2" }, "peerDependencies": { "react": "18.3.1" } }, "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw=="], + "@remotion/react18-tests/zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="], + "@remotion/renderer/source-map": ["source-map@0.8.0-beta.0", "", { "dependencies": { "whatwg-url": "7.1.0" } }, "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA=="], "@remotion/tailwind/tailwindcss": ["tailwindcss@3.4.13", "", { "dependencies": { "@alloc/quick-lru": "5.2.0", "arg": "5.0.2", "chokidar": "3.5.3", "didyoumean": "1.2.2", "dlv": "1.1.3", "fast-glob": "3.3.2", "glob-parent": "6.0.2", "is-glob": "4.0.3", "jiti": "1.21.6", "lilconfig": "2.1.0", "micromatch": "4.0.8", "normalize-path": "3.0.0", "object-hash": "3.0.0", "picocolors": "1.1.1", "postcss": "8.5.1", "postcss-import": "15.1.0", "postcss-js": "4.0.1", "postcss-load-config": "4.0.1", "postcss-nested": "6.0.1", "postcss-selector-parser": "6.1.1", "resolve": "1.22.8", "sucrase": "3.32.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw=="], diff --git a/packages/core/src/any-zod-type.ts b/packages/core/src/any-zod-type.ts index 978b721fbe5..89350e8a327 100644 --- a/packages/core/src/any-zod-type.ts +++ b/packages/core/src/any-zod-type.ts @@ -1,4 +1,14 @@ import type * as z3 from 'zod/v3'; import type * as z4 from 'zod/v4/core'; -export type AnyZodObject = z3.AnyZodObject | z4.$ZodObject; +/** + * Structural type for standalone zod v3 (e.g. 3.22.x) ZodObject, + * which predates Standard Schema and lacks ~standard/~validate. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type StandaloneZodV3Object = {_def: any; _input: any; [k: string]: any}; + +export type AnyZodObject = + | z3.AnyZodObject + | z4.$ZodObject + | StandaloneZodV3Object; diff --git a/packages/example/src/Root.tsx b/packages/example/src/Root.tsx index 3bb285aaf3b..0e4c3aaa3c2 100644 --- a/packages/example/src/Root.tsx +++ b/packages/example/src/Root.tsx @@ -1520,11 +1520,10 @@ export const Index: React.FC = () => { defaultProps={{ greeting: 'Hello from Zod v4!', count: 42, - enabled: true, - items: [{label: 'alpha', value: 1}], - mode: 'dark' as const, - optional: undefined, - nested: {a: 'hello', b: 99}, + enabled: false, + items: [{label: 'alpha!', value: 1}], + mode: 'light' as const, + nested: {a: 'asdfadsf', b: 99}, }} /> diff --git a/packages/example/src/ZodV4SchemaTest.tsx b/packages/example/src/ZodV4SchemaTest.tsx index 52e71561df3..d1df194b74a 100644 --- a/packages/example/src/ZodV4SchemaTest.tsx +++ b/packages/example/src/ZodV4SchemaTest.tsx @@ -4,7 +4,7 @@ */ import React from 'react'; import {AbsoluteFill} from 'remotion'; -import {z} from 'zod'; +import {z} from 'zod/v4'; export const zodV4Schema = z.object({ greeting: z.string().default('Hello from Zod v4!'), diff --git a/packages/react18-tests/package.json b/packages/react18-tests/package.json index c9f70112038..5f811e64c51 100644 --- a/packages/react18-tests/package.json +++ b/packages/react18-tests/package.json @@ -17,7 +17,7 @@ "license": "UNLICENSED", "dependencies": { "remotion": "workspace:*", - "zod": "catalog:" + "zod": "3.22.3" }, "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", diff --git a/packages/react18-tests/src/test/ZodV3SchemaTest.tsx b/packages/react18-tests/src/test/ZodV3SchemaTest.tsx index 3e2c7201174..f652ac4b2df 100644 --- a/packages/react18-tests/src/test/ZodV3SchemaTest.tsx +++ b/packages/react18-tests/src/test/ZodV3SchemaTest.tsx @@ -3,7 +3,7 @@ * Verifies that the studio schema editor works with zod v3 schemas. */ import React from 'react'; -import {z} from 'zod/v3'; +import {z} from 'zod'; export const zodV3Schema = z.object({ title: z.string(), From 3c148c4a90c36cf07c68b723831406bac732f2ec Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Tue, 17 Feb 2026 17:30:59 +0100 Subject: [PATCH 13/49] Fix array schema defaultProps in example after Zod upgrade Co-Authored-By: Claude Opus 4.6 --- packages/example/src/Root.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/example/src/Root.tsx b/packages/example/src/Root.tsx index 0e4c3aaa3c2..ec6d08a76bd 100644 --- a/packages/example/src/Root.tsx +++ b/packages/example/src/Root.tsx @@ -1505,9 +1505,8 @@ export const Index: React.FC = () => { height={630} fps={30} durationInFrames={150} - // @ts-expect-error Needs an object schema={schemaArrayTestSchema} - defaultProps={{}} + defaultProps={[]} /> Date: Tue, 17 Feb 2026 18:00:40 +0100 Subject: [PATCH 14/49] remove array schema, this is not supported --- packages/example/src/Root.tsx | 18 ++---------------- packages/example/src/SchemaTest/index.tsx | 14 -------------- 2 files changed, 2 insertions(+), 30 deletions(-) diff --git a/packages/example/src/Root.tsx b/packages/example/src/Root.tsx index ec6d08a76bd..e7aed679c31 100644 --- a/packages/example/src/Root.tsx +++ b/packages/example/src/Root.tsx @@ -60,12 +60,7 @@ import RemoteVideo from './RemoteVideo'; import {RetryDelayRender} from './RetryDelayRender'; import RiveVehicle from './Rive/RiveExample'; import {ScalePath} from './ScalePath'; -import { - ArrayTest, - SchemaTest, - schemaArrayTestSchema, - schemaTestSchema, -} from './SchemaTest'; +import {SchemaTest, schemaTestSchema} from './SchemaTest'; import {Scripts} from './Scripts'; import {WidthHeightSequences} from './Sequence/WidthHeightSequences'; import CircleTest from './Shapes/CircleTest'; @@ -1498,16 +1493,7 @@ export const Index: React.FC = () => { durationInFrames={150} schema={schemaTestSchema} /> - + { - return ( - - ); -}; - export const SchemaTest: React.FC> = ({ delay, title, From 44ee64d7fc746759c1ac6c7b366b3014dd1a9d1e Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Wed, 18 Feb 2026 10:36:08 +0100 Subject: [PATCH 15/49] v3 --- bun.lock | 23 ++++++++ packages/cli/src/list-of-remotion-packages.ts | 1 + .../src/list-of-remotion-packages.ts | 1 + packages/example/src/VisualControls/index.tsx | 2 +- packages/react18-tests/package.json | 4 +- packages/react18-tests/src/test/Root.tsx | 2 +- .../src/test/ZodV3SchemaTest.tsx | 3 +- packages/studio-shared/src/package-info.ts | 4 ++ .../RenderModal/SchemaEditor/ZodSwitch.tsx | 44 +++++++++++++++ .../src/visual-controls/VisualControls.tsx | 12 ++-- packages/zod-types-v3/.npmignore | 10 ++++ packages/zod-types-v3/README.md | 15 +++++ packages/zod-types-v3/bundle.ts | 32 +++++++++++ packages/zod-types-v3/eslint.config.mjs | 7 +++ packages/zod-types-v3/package.json | 55 +++++++++++++++++++ packages/zod-types-v3/src/index.ts | 3 + packages/zod-types-v3/src/z-color.ts | 20 +++++++ packages/zod-types-v3/src/z-matrix.ts | 17 ++++++ packages/zod-types-v3/src/z-textarea.ts | 6 ++ packages/zod-types-v3/tsconfig.json | 14 +++++ tsconfig.json | 3 + 21 files changed, 268 insertions(+), 10 deletions(-) create mode 100644 packages/zod-types-v3/.npmignore create mode 100644 packages/zod-types-v3/README.md create mode 100644 packages/zod-types-v3/bundle.ts create mode 100644 packages/zod-types-v3/eslint.config.mjs create mode 100644 packages/zod-types-v3/package.json create mode 100644 packages/zod-types-v3/src/index.ts create mode 100644 packages/zod-types-v3/src/z-color.ts create mode 100644 packages/zod-types-v3/src/z-matrix.ts create mode 100644 packages/zod-types-v3/src/z-textarea.ts create mode 100644 packages/zod-types-v3/tsconfig.json diff --git a/bun.lock b/bun.lock index ec3f0c6462a..4424cc23c89 100644 --- a/bun.lock +++ b/bun.lock @@ -1163,6 +1163,8 @@ "name": "@remotion/react18-tests", "version": "4.0.423", "dependencies": { + "@remotion/zod-types": "workspace:*", + "@remotion/zod-types-v3": "workspace:*", "remotion": "workspace:*", "zod": "3.22.3", }, @@ -2349,6 +2351,23 @@ "zod": "catalog:", }, }, + "packages/zod-types-v3": { + "name": "@remotion/zod-types-v3", + "version": "4.0.423", + "dependencies": { + "@remotion/zod-types": "workspace:*", + "remotion": "workspace:*", + }, + "devDependencies": { + "@remotion/eslint-config-internal": "workspace:*", + "@typescript/native-preview": "catalog:", + "eslint": "catalog:", + "zod": "3.22.3", + }, + "peerDependencies": { + "zod": ">=3.0.0 <4.0.0", + }, + }, }, "overrides": { "@rspack/core": "1.7.6", @@ -3752,6 +3771,8 @@ "@remotion/zod-types": ["@remotion/zod-types@workspace:packages/zod-types"], + "@remotion/zod-types-v3": ["@remotion/zod-types-v3@workspace:packages/zod-types-v3"], + "@rive-app/canvas-advanced": ["@rive-app/canvas-advanced@2.31.5", "", {}, "sha512-zwqLIc5wRF+zFKgDSTJn21+r4N4KWqAe6iVrjDGFzfxxeKDoESrwK7GQ9qVyS6UH2W4SsDRzO6q6jrlw33+yIg=="], "@rollup/pluginutils": ["@rollup/pluginutils@5.2.0", "", { "dependencies": { "@types/estree": "1.0.7", "estree-walker": "2.0.2", "picomatch": "4.0.2" } }, "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw=="], @@ -8906,6 +8927,8 @@ "@remotion/tailwind-v4/tailwindcss": ["tailwindcss@4.1.1", "", {}, "sha512-QNbdmeS979Efzim2g/bEvfuh+fTcIdp1y7gA+sb6OYSW74rt7Cr7M78AKdf6HqWT3d5AiTb7SwTT3sLQxr4/qw=="], + "@remotion/zod-types-v3/zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="], + "@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], "@shopify/react-native-skia/react": ["react@19.0.0", "", {}, "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ=="], diff --git a/packages/cli/src/list-of-remotion-packages.ts b/packages/cli/src/list-of-remotion-packages.ts index 2402bce3835..2320889e1cb 100644 --- a/packages/cli/src/list-of-remotion-packages.ts +++ b/packages/cli/src/list-of-remotion-packages.ts @@ -72,6 +72,7 @@ export const listOfRemotionPackages = [ '@remotion/transitions', '@remotion/media-parser', '@remotion/zod-types', + '@remotion/zod-types-v3', '@remotion/webcodecs', '@remotion/convert', '@remotion/captions', diff --git a/packages/create-video/src/list-of-remotion-packages.ts b/packages/create-video/src/list-of-remotion-packages.ts index 2402bce3835..2320889e1cb 100644 --- a/packages/create-video/src/list-of-remotion-packages.ts +++ b/packages/create-video/src/list-of-remotion-packages.ts @@ -72,6 +72,7 @@ export const listOfRemotionPackages = [ '@remotion/transitions', '@remotion/media-parser', '@remotion/zod-types', + '@remotion/zod-types-v3', '@remotion/webcodecs', '@remotion/convert', '@remotion/captions', diff --git a/packages/example/src/VisualControls/index.tsx b/packages/example/src/VisualControls/index.tsx index 0ea71d943a3..3f17a641303 100644 --- a/packages/example/src/VisualControls/index.tsx +++ b/packages/example/src/VisualControls/index.tsx @@ -6,7 +6,7 @@ import {AbsoluteFill} from 'remotion'; export const VisualControls = () => { const matrix = visualControl( 'my-matrix', - [9.63, 0.83, 1.3, 0, 0, 2.79, 0, 0, 1.26, 0.35, 1, 0, 0, 0, 0, 1] as const, + [11.77,1.49,1.3,0,0,2.79,0,0,1.26,0.35,1,0,0,0,0,1] as const, zMatrix(), ); diff --git a/packages/react18-tests/package.json b/packages/react18-tests/package.json index 5f811e64c51..34fe1fe1285 100644 --- a/packages/react18-tests/package.json +++ b/packages/react18-tests/package.json @@ -17,7 +17,9 @@ "license": "UNLICENSED", "dependencies": { "remotion": "workspace:*", - "zod": "3.22.3" + "zod": "3.22.3", + "@remotion/zod-types": "workspace:*", + "@remotion/zod-types-v3": "workspace:*" }, "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", diff --git a/packages/react18-tests/src/test/Root.tsx b/packages/react18-tests/src/test/Root.tsx index 3cc28e0964e..127b4ef7496 100644 --- a/packages/react18-tests/src/test/Root.tsx +++ b/packages/react18-tests/src/test/Root.tsx @@ -42,7 +42,7 @@ export const Root: React.FC = () => { defaultProps={{ title: 'Hello from Zod v3!', count: 10, - enabled: true, + enabled: [1, 0, 0, 1], tags: ['react18', 'zod-v3'], level: 'beginner' as const, }} diff --git a/packages/react18-tests/src/test/ZodV3SchemaTest.tsx b/packages/react18-tests/src/test/ZodV3SchemaTest.tsx index f652ac4b2df..18a627cb929 100644 --- a/packages/react18-tests/src/test/ZodV3SchemaTest.tsx +++ b/packages/react18-tests/src/test/ZodV3SchemaTest.tsx @@ -2,13 +2,14 @@ * Test composition using zod v3 schema (via zod/v3 import). * Verifies that the studio schema editor works with zod v3 schemas. */ +import {zMatrix} from '@remotion/zod-types-v3'; import React from 'react'; import {z} from 'zod'; export const zodV3Schema = z.object({ title: z.string(), count: z.number().min(0).max(100), - enabled: z.boolean(), + enabled: zMatrix(), tags: z.array(z.string()), level: z.enum(['beginner', 'intermediate', 'advanced']), }); diff --git a/packages/studio-shared/src/package-info.ts b/packages/studio-shared/src/package-info.ts index 3725ef5e349..7ce2637fc41 100644 --- a/packages/studio-shared/src/package-info.ts +++ b/packages/studio-shared/src/package-info.ts @@ -71,6 +71,7 @@ export const packages = [ 'transitions', 'media-parser', 'zod-types', + 'zod-types-v3', 'webcodecs', 'convert', 'captions', @@ -127,6 +128,7 @@ export const descriptions: {[key in Pkgs]: string | null} = { preload: 'Preloads assets for use in Remotion', shapes: 'Generate SVG shapes', 'zod-types': 'Zod types for Remotion', + 'zod-types-v3': 'Zod v3 types for Remotion', gif: 'Embed GIFs in a Remotion video', 'eslint-plugin': 'Rules for writing Remotion code', 'eslint-config': 'Default configuration for Remotion templates (ESLint <= 8)', @@ -266,6 +268,7 @@ export const installableMap: {[key in Pkgs]: boolean} = { transitions: true, 'media-parser': true, 'zod-types': true, + 'zod-types-v3': true, webcodecs: true, convert: false, captions: true, @@ -303,6 +306,7 @@ export const apiDocs: {[key in Pkgs]: string | null} = { preload: 'https://www.remotion.dev/docs/preload', shapes: 'https://www.remotion.dev/docs/shapes', 'zod-types': 'https://www.remotion.dev/docs/zod-types', + 'zod-types-v3': 'https://www.remotion.dev/docs/zod-types', gif: 'https://www.remotion.dev/docs/gif', 'eslint-plugin': 'https://www.remotion.dev/docs/brownfield#install-the-eslint-plugin', diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodSwitch.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodSwitch.tsx index 2055f27675e..b4f2ff03a82 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodSwitch.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodSwitch.tsx @@ -80,6 +80,28 @@ export const ZodSwitch: React.FC<{ } if (typeName === 'string') { + // In v4, .refine() doesn't wrap in ZodEffects, so check brand here too + if ( + zodTypes && + description === zodTypes.ZodZypesInternals.REMOTION_COLOR_BRAND + ) { + return ( + } + jsonPath={jsonPath} + schema={schema} + onSave={onSave as UpdaterFunction} + defaultValue={defaultValue as string} + showSaveButton={showSaveButton} + onRemove={onRemove} + saving={saving} + saveDisabledByParent={saveDisabledByParent} + mayPad={mayPad} + /> + ); + } + if ((value as string).startsWith(window.remotion_staticBase)) { return ( } + value={value as unknown[]} + jsonPath={jsonPath} + schema={schema} + defaultValue={defaultValue as unknown[]} + onSave={onSave as UpdaterFunction} + showSaveButton={showSaveButton} + onRemove={onRemove} + saving={saving} + saveDisabledByParent={saveDisabledByParent} + mayPad={mayPad} + /> + ); + } + return ( } diff --git a/packages/studio/src/visual-controls/VisualControls.tsx b/packages/studio/src/visual-controls/VisualControls.tsx index 519bdfd7079..6eb2f5ed85d 100644 --- a/packages/studio/src/visual-controls/VisualControls.tsx +++ b/packages/studio/src/visual-controls/VisualControls.tsx @@ -9,14 +9,14 @@ import React, { useState, } from 'react'; import {useRemotionEnvironment} from 'remotion'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any import {getZodSchemaFromPrimitive} from '../api/get-zod-schema-from-primitive'; import {useZodIfPossible} from '../components/get-zod-if-possible'; +import type {AnyZodSchema} from '../components/RenderModal/SchemaEditor/zod-schema-type'; import {getVisualControlEditedValue} from './get-current-edited-value'; export type VisualControlValueWithoutUnsaved = { valueInCode: unknown; - schema: any; + schema: AnyZodSchema; stack: string; }; @@ -38,7 +38,7 @@ export const VisualControlsTabActivatedContext = export type SetVisualControlsContextType = { updateHandles: () => void; updateValue: (key: string, value: unknown) => void; - visualControl: (key: string, value: T, schema?: any) => T; + visualControl: (key: string, value: T, schema?: AnyZodSchema) => T; }; export const VisualControlsContext = createContext({ @@ -47,7 +47,7 @@ export const VisualControlsContext = createContext({ export type VisualControlRef = { // May not call it visualControl, because we rely on stacktrace names - globalVisualControl: (key: string, value: T, schema?: any) => T; + globalVisualControl: (key: string, value: T, schema?: AnyZodSchema) => T; }; export const visualControlRef = createRef(); @@ -115,8 +115,8 @@ export const VisualControlsProvider: React.FC<{ const env = useRemotionEnvironment(); const visualControl = useCallback( - // eslint-disable-next-line prefer-arrow-callback, @typescript-eslint/no-explicit-any - function (key: string, value: T, schema?: any): T { + // eslint-disable-next-line prefer-arrow-callback + function (key: string, value: T, schema?: AnyZodSchema): T { // eslint-disable-next-line no-constant-condition if (handles && false) { /** Intentional: State is managed imperatively */ diff --git a/packages/zod-types-v3/.npmignore b/packages/zod-types-v3/.npmignore new file mode 100644 index 00000000000..71352c3fd9c --- /dev/null +++ b/packages/zod-types-v3/.npmignore @@ -0,0 +1,10 @@ +dist/test/** +src +eslint.config.mjs +tsconfig.tsbuildinfo +*.tgz +.turbo +tsconfig.json +.prettierrc.js +bundle.ts +dist/cjs/test \ No newline at end of file diff --git a/packages/zod-types-v3/README.md b/packages/zod-types-v3/README.md new file mode 100644 index 00000000000..d57ee50d914 --- /dev/null +++ b/packages/zod-types-v3/README.md @@ -0,0 +1,15 @@ +# @remotion/zod-types-v3 + +Zod v3 types for Remotion. Use this package if you are still using Zod v3 and need to compose Remotion schemas into a `z.object()`. + +If you are using Zod v4, use `@remotion/zod-types` instead. + +## Installation + +```bash +npm install @remotion/zod-types-v3 +``` + +## Documentation + +https://www.remotion.dev/docs/zod-types diff --git a/packages/zod-types-v3/bundle.ts b/packages/zod-types-v3/bundle.ts new file mode 100644 index 00000000000..1a9324d4af6 --- /dev/null +++ b/packages/zod-types-v3/bundle.ts @@ -0,0 +1,32 @@ +import {build} from 'bun'; +import path from 'path'; + +if (process.env.NODE_ENV !== 'production') { + throw new Error('This script must be run using NODE_ENV=production'); +} + +console.time('Generated.'); +const output = await build({ + entrypoints: ['src/index.ts'], + naming: '[name].mjs', + external: [ + 'remotion', + 'remotion/no-react', + '@remotion/zod-types', + 'zod', + ], +}); + +if (!output.success) { + console.log(output.logs.join('\n')); + process.exit(1); +} + +for (const file of output.outputs) { + const str = await file.text(); + const out = path.join('dist', 'esm', file.path); + + await Bun.write(out, str); +} + +console.timeEnd('Generated.'); diff --git a/packages/zod-types-v3/eslint.config.mjs b/packages/zod-types-v3/eslint.config.mjs new file mode 100644 index 00000000000..04fd4fac110 --- /dev/null +++ b/packages/zod-types-v3/eslint.config.mjs @@ -0,0 +1,7 @@ +import {remotionFlatConfig} from '@remotion/eslint-config-internal'; + +const config = remotionFlatConfig({react: false}); + +export default { + ...config, +}; diff --git a/packages/zod-types-v3/package.json b/packages/zod-types-v3/package.json new file mode 100644 index 00000000000..4c9a63b32af --- /dev/null +++ b/packages/zod-types-v3/package.json @@ -0,0 +1,55 @@ +{ + "name": "@remotion/zod-types-v3", + "version": "4.0.423", + "description": "Zod v3 types for Remotion", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "module": "dist/esm/index.mjs", + "repository": { + "url": "https://github.com/remotion-dev/remotion/tree/main/packages/zod-types-v3" + }, + "sideEffects": false, + "type": "module", + "scripts": { + "formatting": "prettier --experimental-cli src --check", + "lint": "eslint src", + "watch": "tsgo -w", + "make": "tsgo && bun --env-file=../.env.bundle bundle.ts" + }, + "author": "Jonny Burger ", + "contributors": [], + "license": "MIT", + "bugs": { + "url": "https://github.com/remotion-dev/remotion/issues" + }, + "dependencies": { + "remotion": "workspace:*", + "@remotion/zod-types": "workspace:*" + }, + "peerDependencies": { + "zod": ">=3.0.0 <4.0.0" + }, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "module": "./dist/esm/index.mjs", + "import": "./dist/esm/index.mjs" + }, + "./package.json": "./package.json" + }, + "devDependencies": { + "zod": "3.22.3", + "@remotion/eslint-config-internal": "workspace:*", + "eslint": "catalog:", + "@typescript/native-preview": "catalog:" + }, + "keywords": [ + "remotion", + "zod", + "zod-v3" + ], + "publishConfig": { + "access": "public" + }, + "homepage": "https://www.remotion.dev/docs/zod-types" +} diff --git a/packages/zod-types-v3/src/index.ts b/packages/zod-types-v3/src/index.ts new file mode 100644 index 00000000000..1857a7d3200 --- /dev/null +++ b/packages/zod-types-v3/src/index.ts @@ -0,0 +1,3 @@ +export {zColor} from './z-color.js'; +export {zMatrix} from './z-matrix.js'; +export {zTextarea} from './z-textarea.js'; diff --git a/packages/zod-types-v3/src/z-color.ts b/packages/zod-types-v3/src/z-color.ts new file mode 100644 index 00000000000..f982c95b1aa --- /dev/null +++ b/packages/zod-types-v3/src/z-color.ts @@ -0,0 +1,20 @@ +import {ZodZypesInternals} from '@remotion/zod-types'; +import {z} from 'zod'; + +const {parseColor, REMOTION_COLOR_BRAND} = ZodZypesInternals; + +export const zColor = () => + z + .string() + .refine( + (value) => { + try { + parseColor(value); + return true; + } catch { + return false; + } + }, + {message: 'Invalid color'}, + ) + .describe(REMOTION_COLOR_BRAND); diff --git a/packages/zod-types-v3/src/z-matrix.ts b/packages/zod-types-v3/src/z-matrix.ts new file mode 100644 index 00000000000..ce3befda314 --- /dev/null +++ b/packages/zod-types-v3/src/z-matrix.ts @@ -0,0 +1,17 @@ +import {ZodZypesInternals} from '@remotion/zod-types'; +import {z} from 'zod'; + +const {REMOTION_MATRIX_BRAND} = ZodZypesInternals; + +export const zMatrix = () => + z + .array(z.number().step(0.01)) + .refine( + (value) => { + const count = value.length; + const root = Math.sqrt(count); + return Number.isInteger(root) && root > 0; + }, + {message: 'Invalid matrix, must be a square matrix'}, + ) + .describe(REMOTION_MATRIX_BRAND); diff --git a/packages/zod-types-v3/src/z-textarea.ts b/packages/zod-types-v3/src/z-textarea.ts new file mode 100644 index 00000000000..d51b08ce7b9 --- /dev/null +++ b/packages/zod-types-v3/src/z-textarea.ts @@ -0,0 +1,6 @@ +import {ZodZypesInternals} from '@remotion/zod-types'; +import {z} from 'zod'; + +const {REMOTION_TEXTAREA_BRAND} = ZodZypesInternals; + +export const zTextarea = () => z.string().describe(REMOTION_TEXTAREA_BRAND); diff --git a/packages/zod-types-v3/tsconfig.json b/packages/zod-types-v3/tsconfig.json new file mode 100644 index 00000000000..e5c5f5163c6 --- /dev/null +++ b/packages/zod-types-v3/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../tsconfig.settings.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist", + "skipLibCheck": true, + "target": "ES2022", + "module": "es2020", + "moduleResolution": "bundler", + "declaration": true, + "emitDeclarationOnly": true + }, + "include": ["src"] +} diff --git a/tsconfig.json b/tsconfig.json index 5869c92a939..564700d35f5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -243,6 +243,9 @@ { "path": "./packages/zod-types" }, + { + "path": "./packages/zod-types-v3" + }, { "path": "./packages/media" }, From 074a58a170d7039c917ef7aa4c3cd9bf553b3473 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Wed, 18 Feb 2026 10:40:34 +0100 Subject: [PATCH 16/49] Add docs, example, and sidebar for @remotion/zod-types-v3 Co-Authored-By: Claude Opus 4.6 --- bun.lock | 2 ++ packages/docs/docs/zod-types/v3.mdx | 34 +++++++++++++++++++++++++++++ packages/docs/package.json | 1 + packages/docs/sidebars.ts | 1 + packages/example/package.json | 1 + packages/example/tsconfig.json | 1 + 6 files changed, 40 insertions(+) create mode 100644 packages/docs/docs/zod-types/v3.mdx diff --git a/bun.lock b/bun.lock index 4424cc23c89..5163c335d70 100644 --- a/bun.lock +++ b/bun.lock @@ -424,6 +424,7 @@ "@remotion/webcodecs": "workspace:*", "@remotion/whisper-web": "workspace:*", "@remotion/zod-types": "workspace:*", + "@remotion/zod-types-v3": "workspace:*", "@rive-app/canvas-advanced": "2.31.5", "@shopify/react-native-skia": "2.0.0", "@swc/core": "^1.3.80", @@ -624,6 +625,7 @@ "@remotion/webcodecs": "workspace:*", "@remotion/whisper-web": "workspace:*", "@remotion/zod-types": "workspace:*", + "@remotion/zod-types-v3": "workspace:*", "@shopify/react-native-skia": "2.0.0", "@types/express": "^4.17.11", "@types/hls.js": "^0.13.3", diff --git a/packages/docs/docs/zod-types/v3.mdx b/packages/docs/docs/zod-types/v3.mdx new file mode 100644 index 00000000000..8dabcf45cab --- /dev/null +++ b/packages/docs/docs/zod-types/v3.mdx @@ -0,0 +1,34 @@ +--- +image: /generated/articles-docs-zod-types-v3.png +sidebar_label: Zod v3 +title: '@remotion/zod-types-v3' +crumb: Schema +--- + +`@remotion/zod-types` creates schemas using Zod v4. If you are still using Zod v3 and need to compose Remotion schemas into a `z.object()`, use `@remotion/zod-types-v3` instead. + +## Installation + + + +## Usage + +```tsx title="Using @remotion/zod-types-v3 with Zod v3" +import {z} from 'zod'; +import {zColor} from '@remotion/zod-types-v3'; + +export const mySchema = z.object({ + color: zColor(), +}); +``` + +The package exports the same `zColor()`, `zTextarea()`, and `zMatrix()` functions as `@remotion/zod-types`, but they return Zod v3 schema types. + +## When to use + +- Use `@remotion/zod-types` (default) if you are using Zod v4. +- Use `@remotion/zod-types-v3` if you are still on Zod v3. + +## See also + +- [`@remotion/zod-types`](/docs/zod-types) diff --git a/packages/docs/package.json b/packages/docs/package.json index 99b4ece6e65..8170a25c6fd 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -80,6 +80,7 @@ "@remotion/webcodecs": "workspace:*", "@remotion/whisper-web": "workspace:*", "@remotion/zod-types": "workspace:*", + "@remotion/zod-types-v3": "workspace:*", "@rive-app/canvas-advanced": "2.31.5", "@shopify/react-native-skia": "2.0.0", "@swc/core": "^1.3.80", diff --git a/packages/docs/sidebars.ts b/packages/docs/sidebars.ts index da0ed817656..3b924af0a16 100644 --- a/packages/docs/sidebars.ts +++ b/packages/docs/sidebars.ts @@ -766,6 +766,7 @@ const sidebars: SidebarsConfig = { 'zod-types/z-color', 'zod-types/z-textarea', 'zod-types/z-matrix', + 'zod-types/v3', ], }, { diff --git a/packages/example/package.json b/packages/example/package.json index ede99ba8bc0..279a9ad22dc 100644 --- a/packages/example/package.json +++ b/packages/example/package.json @@ -70,6 +70,7 @@ "@remotion/media-parser": "workspace:*", "@remotion/whisper-web": "workspace:*", "@remotion/zod-types": "workspace:*", + "@remotion/zod-types-v3": "workspace:*", "@shopify/react-native-skia": "2.0.0", "@types/express": "^4.17.11", "@types/hls.js": "^0.13.3", diff --git a/packages/example/tsconfig.json b/packages/example/tsconfig.json index abf81d2eeb2..7be2fca483e 100644 --- a/packages/example/tsconfig.json +++ b/packages/example/tsconfig.json @@ -35,6 +35,7 @@ {"path": "../three"}, {"path": "../transitions"}, {"path": "../zod-types"}, + {"path": "../zod-types-v3"}, {"path": "../svg-3d-engine"}, {"path": "../media-parser"}, {"path": "../webcodecs"}, From 277952901b96e947074b2f15d7fd9fc40ede658d Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Wed, 18 Feb 2026 10:56:24 +0100 Subject: [PATCH 17/49] hmm --- packages/STATS.md | 1 + packages/example/src/VisualControls/index.tsx | 2 +- packages/lambda-php/composer.lock | 2 +- packages/promo-pages/.npmignore | 3 ++- packages/zod-types-v3/README.md | 25 +++++++++++-------- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/packages/STATS.md b/packages/STATS.md index 413c6392cda..118dc94d9e7 100644 --- a/packages/STATS.md +++ b/packages/STATS.md @@ -61,3 +61,4 @@ Monthly downloads of Remotion packages [![NPM Downloads](https://img.shields.io/npm/dm/@remotion/webcodecs.svg?style=flat&color=black&label=@remotion/webcodecs)](https://npmcharts.com/compare/@remotion/webcodecs?minimal=true) [![NPM Downloads](https://img.shields.io/npm/dm/@remotion/whisper-web.svg?style=flat&color=black&label=@remotion/whisper-web)](https://npmcharts.com/compare/@remotion/whisper-web?minimal=true) [![NPM Downloads](https://img.shields.io/npm/dm/@remotion/zod-types.svg?style=flat&color=black&label=@remotion/zod-types)](https://npmcharts.com/compare/@remotion/zod-types?minimal=true) +[![NPM Downloads](https://img.shields.io/npm/dm/@remotion/zod-types-v3.svg?style=flat&color=black&label=@remotion/zod-types-v3)](https://npmcharts.com/compare/@remotion/zod-types-v3?minimal=true) diff --git a/packages/example/src/VisualControls/index.tsx b/packages/example/src/VisualControls/index.tsx index 3f17a641303..6fadb3d4e96 100644 --- a/packages/example/src/VisualControls/index.tsx +++ b/packages/example/src/VisualControls/index.tsx @@ -6,7 +6,7 @@ import {AbsoluteFill} from 'remotion'; export const VisualControls = () => { const matrix = visualControl( 'my-matrix', - [11.77,1.49,1.3,0,0,2.79,0,0,1.26,0.35,1,0,0,0,0,1] as const, + [11.77, 1.49, 1.3, 0, 0, 2.79, 0, 0, 1.26, 0.35, 1, 0, 0, 0, 0, 1] as const, zMatrix(), ); diff --git a/packages/lambda-php/composer.lock b/packages/lambda-php/composer.lock index 082c04db2d9..477b81d4f03 100644 --- a/packages/lambda-php/composer.lock +++ b/packages/lambda-php/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "280ab9c7fda40490fd7afe90f75bda55", + "content-hash": "de2d3234d8b3ac7fce37dc7eace49d7c", "packages": [ { "name": "aws/aws-crt-php", diff --git a/packages/promo-pages/.npmignore b/packages/promo-pages/.npmignore index 64f89b690b1..9f7f8f5db60 100644 --- a/packages/promo-pages/.npmignore +++ b/packages/promo-pages/.npmignore @@ -4,4 +4,5 @@ eslint.config.mjs src server.ts vite.config.ts -tsconfig.json \ No newline at end of file +tsconfig.json +tsconfig.tsbuildinfo \ No newline at end of file diff --git a/packages/zod-types-v3/README.md b/packages/zod-types-v3/README.md index d57ee50d914..a0a0c5b5f12 100644 --- a/packages/zod-types-v3/README.md +++ b/packages/zod-types-v3/README.md @@ -1,15 +1,18 @@ # @remotion/zod-types-v3 - -Zod v3 types for Remotion. Use this package if you are still using Zod v3 and need to compose Remotion schemas into a `z.object()`. - -If you are using Zod v4, use `@remotion/zod-types` instead. - + +Zod v3 types for Remotion + +[![NPM Downloads](https://img.shields.io/npm/dm/@remotion/zod-types-v3.svg?style=flat&color=black&label=Downloads)](https://npmcharts.com/compare/@remotion/zod-types-v3?minimal=true) + ## Installation - + ```bash -npm install @remotion/zod-types-v3 +npm install @remotion/zod-types-v3 --save-exact ``` - -## Documentation - -https://www.remotion.dev/docs/zod-types + +When installing a Remotion package, make sure to align the version of all `remotion` and `@remotion/*` packages to the same version. +Remove the `^` character from the version number to use the exact version. + +## Usage + +See the [documentation](https://www.remotion.dev/docs/zod-types) for more information. From 6acffe0a3b246cbcf19e780d37c4a6990032af9a Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Wed, 18 Feb 2026 11:14:49 +0100 Subject: [PATCH 18/49] `@remotion/zod-types-v3`: Bump version to 4.0.424 to match other packages Co-Authored-By: Claude Opus 4.6 --- packages/zod-types-v3/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/zod-types-v3/package.json b/packages/zod-types-v3/package.json index 4c9a63b32af..366a362ff83 100644 --- a/packages/zod-types-v3/package.json +++ b/packages/zod-types-v3/package.json @@ -1,6 +1,6 @@ { "name": "@remotion/zod-types-v3", - "version": "4.0.423", + "version": "4.0.424", "description": "Zod v3 types for Remotion", "main": "dist/index.js", "types": "dist/index.d.ts", From 86d74c384f5e1c4f227aefebcc812c5f87a0b1a5 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Wed, 18 Feb 2026 11:40:34 +0100 Subject: [PATCH 19/49] Docs: Document Zod v4 support and @remotion/zod-types-v3 Co-Authored-By: Claude Opus 4.6 --- packages/docs/docs/zod-types-v3/index.mdx | 26 +++++++++++++++++++++++ packages/docs/docs/zod-types/index.mdx | 9 ++++++-- packages/docs/sidebars.ts | 9 ++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 packages/docs/docs/zod-types-v3/index.mdx diff --git a/packages/docs/docs/zod-types-v3/index.mdx b/packages/docs/docs/zod-types-v3/index.mdx new file mode 100644 index 00000000000..a6d9390d5c9 --- /dev/null +++ b/packages/docs/docs/zod-types-v3/index.mdx @@ -0,0 +1,26 @@ +--- +sidebar_label: Overview +title: '@remotion/zod-types-v3' +crumb: Schema +--- + +import {ZodTypesTableOfContents} from '../zod-types/TableOfContents'; + +This package provides the same utility types as [`@remotion/zod-types`](/docs/zod-types), but based on Zod 3.22.3 instead of Zod v4. + +Use this package if you are composing Remotion's Zod types with your own schemas that use Zod 3.22.3. +If you are using Zod v4, use [`@remotion/zod-types`](/docs/zod-types) instead. + + + +## Installation + + + +## API + + + +## License + +[Remotion License](https://remotion.dev/license) diff --git a/packages/docs/docs/zod-types/index.mdx b/packages/docs/docs/zod-types/index.mdx index aa5c8a9dfa5..8989e1abc31 100644 --- a/packages/docs/docs/zod-types/index.mdx +++ b/packages/docs/docs/zod-types/index.mdx @@ -9,8 +9,13 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import {ZodTypesTableOfContents} from './TableOfContents'; -Includes utility types and Remotion-specific types for [Zod](https://github.com/colinhacks/zod). -In the next major version of Remotion, the Zod version will be updated. +Since Remotion v4.0.425, `@remotion/zod-types` is based on Zod v4. +If you want to compose these types with your own Zod schemas, use Zod v4. + +If you are using Zod 3.22.3, use [`@remotion/zod-types-v3`](/docs/zod-types-v3) instead. +Other versions of Zod v3 might not compose well – we recommend staying on Zod 3.22.3 or upgrading to Zod v4. + +Includes utility types and Remotion-specific types for [Zod](https://github.com/colinhacks/zod). ## Installation diff --git a/packages/docs/sidebars.ts b/packages/docs/sidebars.ts index 3b924af0a16..af734d8068d 100644 --- a/packages/docs/sidebars.ts +++ b/packages/docs/sidebars.ts @@ -769,6 +769,15 @@ const sidebars: SidebarsConfig = { 'zod-types/v3', ], }, + { + type: 'category', + label: '@remotion/zod-types-v3', + link: { + type: 'doc', + id: 'zod-types-v3/index', + }, + items: [], + }, { type: 'html', value: From 98dd6f12a2d5e1a34a869a7c374aabf28bca0024 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Wed, 18 Feb 2026 13:03:58 +0100 Subject: [PATCH 20/49] Restore type-safe InferZodInput in player and web-renderer Co-Authored-By: Claude Opus 4.6 --- .../player/src/utils/props-if-has-props.ts | 14 +++++++++++--- .../web-renderer/src/props-if-has-props.ts | 18 +++++++++++++----- .../web-renderer/src/render-media-on-web.tsx | 2 +- .../web-renderer/src/render-still-on-web.tsx | 2 +- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/packages/player/src/utils/props-if-has-props.ts b/packages/player/src/utils/props-if-has-props.ts index 1fe5641cdb7..4523136e9e0 100644 --- a/packages/player/src/utils/props-if-has-props.ts +++ b/packages/player/src/utils/props-if-has-props.ts @@ -1,5 +1,13 @@ import type {AnyZodObject} from 'remotion'; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type InferZodInput = T extends {_zod: {input: any}} + ? T['_zod']['input'] + : // eslint-disable-next-line @typescript-eslint/no-explicit-any + T extends {_input: any} + ? T['_input'] + : Record; + export type PropsIfHasProps< Schema extends AnyZodObject, Props, @@ -7,7 +15,7 @@ export type PropsIfHasProps< ? {} extends Props ? { // Neither props nor schema specified - inputProps?: Record & Props; + inputProps?: InferZodInput & Props; } : { // Only props specified @@ -16,9 +24,9 @@ export type PropsIfHasProps< : {} extends Props ? { // Only schema specified - inputProps: Record; + inputProps: InferZodInput; } : { // Props and schema specified - inputProps: Record & Props; + inputProps: InferZodInput & Props; }; diff --git a/packages/web-renderer/src/props-if-has-props.ts b/packages/web-renderer/src/props-if-has-props.ts index ca6b69edc9a..fda246247d2 100644 --- a/packages/web-renderer/src/props-if-has-props.ts +++ b/packages/web-renderer/src/props-if-has-props.ts @@ -1,6 +1,14 @@ import type {ComponentType} from 'react'; import type {AnyZodObject, CalculateMetadataFunction} from 'remotion'; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type InferZodInput = T extends {_zod: {input: any}} + ? T['_zod']['input'] + : // eslint-disable-next-line @typescript-eslint/no-explicit-any + T extends {_input: any} + ? T['_input'] + : Record; + export type InferProps< Schema extends AnyZodObject, Props extends Record, @@ -12,9 +20,9 @@ export type InferProps< Props : {} extends Props ? // Only schema specified - Record + InferZodInput : // Props and schema specified - Record & Props; + InferZodInput & Props; export type DefaultPropsIfHasProps< Schema extends AnyZodObject, @@ -23,7 +31,7 @@ export type DefaultPropsIfHasProps< ? {} extends Props ? { // Neither props nor schema specified - defaultProps?: Record & Props; + defaultProps?: InferZodInput & Props; } : { // Only props specified @@ -32,11 +40,11 @@ export type DefaultPropsIfHasProps< : {} extends Props ? { // Only schema specified - defaultProps: Record; + defaultProps: InferZodInput; } : { // Props and schema specified - defaultProps: Record & Props; + defaultProps: InferZodInput & Props; }; type LooseComponentType = ComponentType | ((props: T) => React.ReactNode); diff --git a/packages/web-renderer/src/render-media-on-web.tsx b/packages/web-renderer/src/render-media-on-web.tsx index 4f8bb2a985a..b783429471b 100644 --- a/packages/web-renderer/src/render-media-on-web.tsx +++ b/packages/web-renderer/src/render-media-on-web.tsx @@ -225,7 +225,7 @@ const internalRenderMediaOnWeb = async < const resolved = await Internals.resolveVideoConfig({ calculateMetadata: - (composition.calculateMetadata as CalculateMetadataFunction< + (composition.calculateMetadata as unknown as CalculateMetadataFunction< InferProps> >) ?? null, signal: signal ?? new AbortController().signal, diff --git a/packages/web-renderer/src/render-still-on-web.tsx b/packages/web-renderer/src/render-still-on-web.tsx index fc287a08f0f..32c1110e1df 100644 --- a/packages/web-renderer/src/render-still-on-web.tsx +++ b/packages/web-renderer/src/render-still-on-web.tsx @@ -80,7 +80,7 @@ async function internalRenderStillOnWeb< const resolved = await Internals.resolveVideoConfig({ calculateMetadata: - (composition.calculateMetadata as CalculateMetadataFunction< + (composition.calculateMetadata as unknown as CalculateMetadataFunction< InferProps> >) ?? null, signal: signal ?? new AbortController().signal, From 38e97b21503fade55adac34b3ff918ad5ee27ee1 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Wed, 18 Feb 2026 16:43:21 +0100 Subject: [PATCH 21/49] Restore type safety in SchemaEditor by replacing `any` with `AnyZodSchema` Replace `schema: any` with `schema: AnyZodSchema` across 25+ editor components and `{success: boolean; error?: any}` with a proper `ZodSafeParseResult` discriminated union. Add `zodSafeParse()` helper and `ZodValidationError` type to zod-schema-type.ts. Use existing accessor helpers (getZodDef, getObjectShape, etc.) instead of raw `_def` access. Change `.errors` to `.issues` for v3/v4 compat. Co-Authored-By: Claude Opus 4.6 --- packages/studio/src/api/save-default-props.ts | 3 +- .../src/components/RenderModal/DataEditor.tsx | 15 +++--- .../RenderModalJSONPropsEditor.tsx | 12 ++--- .../RenderModal/SchemaEditor/SchemaEditor.tsx | 11 ++-- .../SchemaEditor/SchemaErrorMessages.tsx | 7 ++- .../SchemaEditor/SchemaSeparationLine.tsx | 4 +- .../SchemaEditor/ZodArrayEditor.tsx | 4 +- .../SchemaEditor/ZodArrayItemEditor.tsx | 4 +- .../SchemaEditor/ZodBooleanEditor.tsx | 4 +- .../SchemaEditor/ZodColorEditor.tsx | 4 +- .../SchemaEditor/ZodDateEditor.tsx | 4 +- .../SchemaEditor/ZodDefaultEditor.tsx | 4 +- .../ZodDiscriminatedUnionEditor.tsx | 7 ++- .../SchemaEditor/ZodEffectEditor.tsx | 4 +- .../SchemaEditor/ZodEnumEditor.tsx | 4 +- .../SchemaEditor/ZodErrorMessages.tsx | 50 +++++++++---------- .../SchemaEditor/ZodFieldValidation.tsx | 25 +++++----- .../SchemaEditor/ZodMatrixEditor.tsx | 4 +- .../SchemaEditor/ZodNullableEditor.tsx | 8 +-- .../SchemaEditor/ZodNumberEditor.tsx | 21 ++++---- .../SchemaEditor/ZodObjectEditor.tsx | 14 ++---- .../SchemaEditor/ZodOptionalEditor.tsx | 8 +-- .../SchemaEditor/ZodOrNullishEditor.tsx | 7 ++- .../SchemaEditor/ZodStaticFileEditor.tsx | 4 +- .../SchemaEditor/ZodStringEditor.tsx | 4 +- .../RenderModal/SchemaEditor/ZodSwitch.tsx | 14 +++--- .../SchemaEditor/ZodTextareaEditor.tsx | 4 +- .../SchemaEditor/ZodTupleEditor.tsx | 11 ++-- .../SchemaEditor/ZodTupleItemEditor.tsx | 8 +-- .../SchemaEditor/ZodUnionEditor.tsx | 11 ++-- .../RenderModal/SchemaEditor/local-state.tsx | 16 +++--- .../SchemaEditor/zod-schema-type.ts | 26 ++++++++++ .../src/visual-controls/VisualControls.tsx | 2 +- 33 files changed, 173 insertions(+), 155 deletions(-) diff --git a/packages/studio/src/api/save-default-props.ts b/packages/studio/src/api/save-default-props.ts index c0736bbf2e2..5f4e660283e 100644 --- a/packages/studio/src/api/save-default-props.ts +++ b/packages/studio/src/api/save-default-props.ts @@ -1,6 +1,7 @@ import {getRemotionEnvironment} from 'remotion'; import type {ZodTypesType} from '../components/get-zod-if-possible'; import {extractEnumJsonPaths} from '../components/RenderModal/SchemaEditor/extract-enum-json-paths'; +import type {AnyZodSchema} from '../components/RenderModal/SchemaEditor/zod-schema-type'; import {callUpdateDefaultPropsApi} from '../components/RenderQueue/actions'; import type {UpdateDefaultPropsFunction} from './helpers/calc-new-props'; import {calcNewProps} from './helpers/calc-new-props'; @@ -48,7 +49,7 @@ export const saveDefaultProps = async ({ generatedDefaultProps, composition.schema ? extractEnumJsonPaths({ - schema: composition.schema, + schema: composition.schema as AnyZodSchema, zodRuntime: z, currentPath: [], zodTypes, diff --git a/packages/studio/src/components/RenderModal/DataEditor.tsx b/packages/studio/src/components/RenderModal/DataEditor.tsx index 688ef01ac5e..57ccdad01e1 100644 --- a/packages/studio/src/components/RenderModal/DataEditor.tsx +++ b/packages/studio/src/components/RenderModal/DataEditor.tsx @@ -29,7 +29,11 @@ import { ZodNotInstalled, } from './SchemaEditor/SchemaErrorMessages'; import {extractEnumJsonPaths} from './SchemaEditor/extract-enum-json-paths'; -import {getZodSchemaType} from './SchemaEditor/zod-schema-type'; +import type { + AnyZodSchema, + ZodSafeParseResult, +} from './SchemaEditor/zod-schema-type'; +import {getZodSchemaType, zodSafeParse} from './SchemaEditor/zod-schema-type'; import {WarningIndicatorButton} from './WarningIndicatorButton'; import type {TypeCanSaveState} from './get-render-modal-warnings'; import { @@ -48,8 +52,7 @@ export type State = str: string; value: Record; validJSON: true; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - zodValidation: {success: boolean; error?: any}; + zodValidation: ZodSafeParseResult; } | { str: string; @@ -185,7 +188,7 @@ export const DataEditor: React.FC<{ ); } - return unresolvedComposition.schema; + return unresolvedComposition.schema as AnyZodSchema; }, [unresolvedComposition.schema, z]); const zodValidationResult = useMemo(() => { @@ -197,9 +200,7 @@ export const DataEditor: React.FC<{ return 'no-schema' as const; } - return ( - schema as {safeParse: (v: unknown) => {success: boolean; error?: unknown}} - ).safeParse(defaultProps); + return zodSafeParse(schema, defaultProps); }, [defaultProps, schema]); const setShowWarning: React.Dispatch> = diff --git a/packages/studio/src/components/RenderModal/RenderModalJSONPropsEditor.tsx b/packages/studio/src/components/RenderModal/RenderModalJSONPropsEditor.tsx index 06cc8bcdaea..90ed3e1e49b 100644 --- a/packages/studio/src/components/RenderModal/RenderModalJSONPropsEditor.tsx +++ b/packages/studio/src/components/RenderModal/RenderModalJSONPropsEditor.tsx @@ -11,6 +11,8 @@ import {Flex, Row, Spacing} from '../layout'; import type {State} from './DataEditor'; import {ZodErrorMessages} from './SchemaEditor/ZodErrorMessages'; import {deepEqual} from './SchemaEditor/deep-equal'; +import type {AnyZodSchema} from './SchemaEditor/zod-schema-type'; +import {zodSafeParse} from './SchemaEditor/zod-schema-type'; const style: React.CSSProperties = { fontFamily: 'monospace', @@ -24,11 +26,10 @@ const scrollable: React.CSSProperties = { flex: 1, }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const parseJSON = (str: string, schema: any): State => { +const parseJSON = (str: string, schema: AnyZodSchema): State => { try { const value = NoReactInternals.deserializeJSONWithSpecialTypes(str); - const zodValidation = schema.safeParse(value); + const zodValidation = zodSafeParse(schema, value); return {str, value, validJSON: true, zodValidation}; } catch (e) { return {str, validJSON: false, error: (e as Error).message}; @@ -44,8 +45,7 @@ export const RenderModalJSONPropsEditor: React.FC<{ readonly showSaveButton: boolean; readonly serializedJSON: SerializedJSONWithCustomFields | null; readonly defaultProps: Record; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - readonly schema: any; + readonly schema: AnyZodSchema; }> = ({ setValue, value, @@ -78,7 +78,7 @@ export const RenderModalJSONPropsEditor: React.FC<{ const parsed = parseJSON(e.target.value, schema); if (parsed.validJSON) { - const validationResult = schema.safeParse(parsed.value); + const validationResult = zodSafeParse(schema, parsed.value); setLocalValue({ str: e.target.value, value: parsed.value, diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/SchemaEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/SchemaEditor.tsx index 04f13a00b11..f079c4613ad 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/SchemaEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/SchemaEditor.tsx @@ -14,7 +14,8 @@ import {deepEqual} from './deep-equal'; import type {RevisionContextType} from './local-state'; import {RevisionContext} from './local-state'; import {defaultPropsEditorScrollableAreaRef} from './scroll-to-default-props-path'; -import {getZodSchemaType} from './zod-schema-type'; +import type {AnyZodSchema, ZodSafeParseResult} from './zod-schema-type'; +import {getZodSchemaType, zodSafeParse} from './zod-schema-type'; const scrollable: React.CSSProperties = { display: 'flex', @@ -22,15 +23,13 @@ const scrollable: React.CSSProperties = { overflowY: 'auto', }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const SchemaEditor: React.FC<{ - readonly schema: any; + readonly schema: AnyZodSchema; readonly unsavedDefaultProps: Record; readonly setValue: React.Dispatch< React.SetStateAction> >; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - readonly zodValidationResult: {success: boolean; error?: any}; + readonly zodValidationResult: ZodSafeParseResult; readonly savedDefaultProps: Record; readonly onSave: ( updater: (oldState: Record) => Record, @@ -117,7 +116,7 @@ export const SchemaEditor: React.FC<{ }, [savedDefaultProps, setValue]); if (!zodValidationResult.success) { - const defaultPropsValid = schema.safeParse(savedDefaultProps); + const defaultPropsValid = zodSafeParse(schema, savedDefaultProps); if (!defaultPropsValid.success) { return ; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/SchemaErrorMessages.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/SchemaErrorMessages.tsx index 0fee096d7de..e4073fc70cf 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/SchemaErrorMessages.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/SchemaErrorMessages.tsx @@ -4,6 +4,7 @@ import {Button} from '../../Button'; import {inlineCodeSnippet} from '../../Menu/styles'; import {Spacing} from '../../layout'; import {ZodErrorMessages} from './ZodErrorMessages'; +import type {ZodSafeParseResult} from './zod-schema-type'; const explainer: React.CSSProperties = { display: 'flex', @@ -86,8 +87,7 @@ export const NoDefaultProps = () => { }; export const InvalidDefaultProps: React.FC<{ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - zodValidationResult: {success: boolean; error?: any}; + zodValidationResult: ZodSafeParseResult; }> = ({zodValidationResult}) => { return (
@@ -112,8 +112,7 @@ export const InvalidDefaultProps: React.FC<{ }; export const InvalidSchema: React.FC<{ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - zodValidationResult: {success: boolean; error?: any}; + zodValidationResult: ZodSafeParseResult; reset: () => void; }> = ({zodValidationResult, reset}) => { return ( diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/SchemaSeparationLine.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/SchemaSeparationLine.tsx index 97122827be2..2cded5139ef 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/SchemaSeparationLine.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/SchemaSeparationLine.tsx @@ -8,6 +8,7 @@ import { import {Spacing} from '../../layout'; import {fieldSetText} from '../layout'; import {createZodValues} from './create-zod-values'; +import type {AnyZodSchema} from './zod-schema-type'; import {getArrayElement} from './zod-schema-type'; export const VERTICAL_GUIDE_HEIGHT = 24; @@ -35,8 +36,7 @@ export const SchemaArrayItemSeparationLine: React.FC<{ increment: boolean, ) => void; readonly index: number; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - readonly schema: any; + readonly schema: AnyZodSchema; readonly showAddButton: boolean; readonly isLast: boolean; }> = ({onChange, index, schema, isLast, showAddButton}) => { diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodArrayEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodArrayEditor.tsx index 38225a23ee3..e8a72ed50e6 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodArrayEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodArrayEditor.tsx @@ -13,12 +13,12 @@ import type {UpdaterFunction} from './ZodSwitch'; import {createZodValues} from './create-zod-values'; import {deepEqual} from './deep-equal'; import {useLocalState} from './local-state'; +import type {AnyZodSchema} from './zod-schema-type'; import {getArrayElement} from './zod-schema-type'; import type {JSONPath} from './zod-types'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodArrayEditor: React.FC<{ - readonly schema: any; + readonly schema: AnyZodSchema; readonly jsonPath: JSONPath; readonly value: unknown[]; readonly defaultValue: unknown[]; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodArrayItemEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodArrayItemEditor.tsx index b9e5679fafa..5a1dd5029ab 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodArrayItemEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodArrayItemEditor.tsx @@ -2,13 +2,13 @@ import {useCallback, useMemo} from 'react'; import {useZodIfPossible} from '../../get-zod-if-possible'; import type {UpdaterFunction} from './ZodSwitch'; import {ZodSwitch} from './ZodSwitch'; +import type {AnyZodSchema} from './zod-schema-type'; import type {JSONPath} from './zod-types'; export const ZodArrayItemEditor: React.FC<{ jsonPath: JSONPath; onChange: UpdaterFunction; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - elementSchema: any; + elementSchema: AnyZodSchema; index: number; value: unknown; defaultValue: unknown; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodBooleanEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodBooleanEditor.tsx index b516ff86bfb..6e34555c8f5 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodBooleanEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodBooleanEditor.tsx @@ -4,6 +4,7 @@ import {Fieldset} from './Fieldset'; import {SchemaLabel} from './SchemaLabel'; import type {UpdaterFunction} from './ZodSwitch'; import {useLocalState} from './local-state'; +import type {AnyZodSchema} from './zod-schema-type'; import type {JSONPath} from './zod-types'; const fullWidth: React.CSSProperties = { @@ -11,8 +12,7 @@ const fullWidth: React.CSSProperties = { }; export const ZodBooleanEditor: React.FC<{ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - readonly schema: any; + readonly schema: AnyZodSchema; readonly jsonPath: JSONPath; readonly value: boolean; readonly setValue: UpdaterFunction; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodColorEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodColorEditor.tsx index 402b6be4101..ec1c38af18c 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodColorEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodColorEditor.tsx @@ -13,6 +13,7 @@ import {SchemaLabel} from './SchemaLabel'; import {ZodFieldValidation} from './ZodFieldValidation'; import type {UpdaterFunction} from './ZodSwitch'; import {useLocalState} from './local-state'; +import type {AnyZodSchema} from './zod-schema-type'; import type {JSONPath} from './zod-types'; const fullWidth: React.CSSProperties = { @@ -20,8 +21,7 @@ const fullWidth: React.CSSProperties = { }; export const ZodColorEditor: React.FC<{ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - readonly schema: any; + readonly schema: AnyZodSchema; readonly jsonPath: JSONPath; readonly value: string; readonly defaultValue: string; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodDateEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodDateEditor.tsx index 511d4432e58..d287f683a6a 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodDateEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodDateEditor.tsx @@ -7,6 +7,7 @@ import {SchemaLabel} from './SchemaLabel'; import {ZodFieldValidation} from './ZodFieldValidation'; import type {UpdaterFunction} from './ZodSwitch'; import {useLocalState} from './local-state'; +import type {AnyZodSchema} from './zod-schema-type'; import type {JSONPath} from './zod-types'; const fullWidth: React.CSSProperties = { @@ -49,8 +50,7 @@ const formatDate = (date: Date) => { }; export const ZodDateEditor: React.FC<{ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - readonly schema: any; + readonly schema: AnyZodSchema; readonly jsonPath: JSONPath; readonly value: Date; readonly defaultValue: Date; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodDefaultEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodDefaultEditor.tsx index 1bc893217cb..5ae5ef2c86d 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodDefaultEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodDefaultEditor.tsx @@ -1,16 +1,16 @@ import React from 'react'; +import type {AnyZodSchema} from './zod-schema-type'; import {getInnerType} from './zod-schema-type'; import type {JSONPath} from './zod-types'; import type {UpdaterFunction} from './ZodSwitch'; import {ZodSwitch} from './ZodSwitch'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodDefaultEditor: React.FC<{ readonly showSaveButton: boolean; readonly jsonPath: JSONPath; readonly value: unknown; readonly defaultValue: unknown; - readonly schema: any; + readonly schema: AnyZodSchema; readonly setValue: UpdaterFunction; readonly onSave: UpdaterFunction; readonly onRemove: null | (() => void); diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.tsx index 2e2c744d0da..f6610fa8040 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.tsx @@ -13,6 +13,7 @@ import {ZodObjectEditor} from './ZodObjectEditor'; import type {UpdaterFunction} from './ZodSwitch'; import {createZodValues} from './create-zod-values'; import {useLocalState} from './local-state'; +import type {AnyZodSchema} from './zod-schema-type'; import { getDiscriminatedOption, getDiscriminatedOptionKeys, @@ -21,7 +22,7 @@ import { import type {JSONPath} from './zod-types'; export const ZodDiscriminatedUnionEditor: React.FC<{ - schema: any; + schema: AnyZodSchema; setValue: UpdaterFunction>; value: Record; defaultValue: Record; @@ -153,6 +154,10 @@ export const ZodDiscriminatedUnionEditor: React.FC<{ value[discriminator] as string, ); + if (!currentOptionSchema) { + throw new Error('No matching option found for discriminated union'); + } + return ( ; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodEnumEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodEnumEditor.tsx index eda8d859675..e830f53bbfb 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodEnumEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodEnumEditor.tsx @@ -7,6 +7,7 @@ import {SchemaLabel} from './SchemaLabel'; import {ZodFieldValidation} from './ZodFieldValidation'; import type {UpdaterFunction} from './ZodSwitch'; import {useLocalState} from './local-state'; +import type {AnyZodSchema} from './zod-schema-type'; import {getEnumValues} from './zod-schema-type'; import type {JSONPath} from './zod-types'; @@ -14,9 +15,8 @@ const container: React.CSSProperties = { width: '100%', }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodEnumEditor: React.FC<{ - readonly schema: any; + readonly schema: AnyZodSchema; readonly jsonPath: JSONPath; readonly value: string; readonly defaultValue: string; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodErrorMessages.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodErrorMessages.tsx index 920735158d9..016d5a7e341 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodErrorMessages.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodErrorMessages.tsx @@ -2,6 +2,7 @@ import React, {useMemo} from 'react'; import {FAIL_COLOR, LIGHT_TEXT} from '../../../helpers/colors'; import {WarningTriangle} from '../../NewComposition/ValidationMessage'; import {Spacing} from '../../layout'; +import type {ZodSafeParseResult} from './zod-schema-type'; const schemaLabel: React.CSSProperties = { fontSize: 14, @@ -24,8 +25,7 @@ const triangleStyle: React.CSSProperties = { }; export const ZodErrorMessages: React.FC<{ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - readonly zodValidationResult: {success: boolean; error?: any}; + readonly zodValidationResult: ZodSafeParseResult; readonly viewTab: 'schema' | 'json'; }> = ({zodValidationResult, viewTab}) => { if (zodValidationResult.success) { @@ -46,37 +46,33 @@ export const ZodErrorMessages: React.FC<{ if (viewTab === 'json') { return (
- {zodValidationResult.error.errors.map( - (error: {path: (string | number)[]; message: string}) => { - return ( -
- - - {error.path.length === 0 ? 'Root' : error.path.join('.')}:{' '} - {error.message} -
- ); - }, - )} + {zodValidationResult.error.issues.map((error) => { + return ( +
+ + + {error.path.length === 0 ? 'Root' : error.path.join('.')}:{' '} + {error.message} +
+ ); + })}
); } return (
- {zodValidationResult.error.errors.map( - (error: {path: (string | number)[]; message: string}) => { - return ( -
- -{' '} - - {error.path.length === 0 ? 'Root' : error.path.join('.')} - - : {error.message} -
- ); - }, - )} + {zodValidationResult.error.issues.map((error) => { + return ( +
+ -{' '} + + {error.path.length === 0 ? 'Root' : error.path.join('.')} + + : {error.message} +
+ ); + })}
); }; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodFieldValidation.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodFieldValidation.tsx index 218d72423e8..ad92d278524 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodFieldValidation.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodFieldValidation.tsx @@ -22,7 +22,8 @@ export const ZodFieldValidation: React.FC<{ localValue: LocalState; path: JSONPath; }> = ({localValue, path}) => { - if (localValue.zodValidation.success) { + const {zodValidation} = localValue; + if (zodValidation.success) { return null; } @@ -30,24 +31,22 @@ export const ZodFieldValidation: React.FC<{
Zod Validation has failed:
- {localValue.zodValidation.error.errors.map( - (error: {code: string; message: string}, index: number) => ( - // eslint-disable-next-line react/no-array-index-key -
- Type: {error.code}
- Message: {error.message} -
- Path: {path.join('.')} -
- ), - )} + {zodValidation.error.issues.map((error, index: number) => ( + // eslint-disable-next-line react/no-array-index-key +
+ Type: {error.code}
+ Message: {error.message} +
+ Path: {path.join('.')} +
+ ))}
diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodMatrixEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodMatrixEditor.tsx index fb827e41cd9..e69275c8d8d 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodMatrixEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodMatrixEditor.tsx @@ -13,6 +13,7 @@ import type {UpdaterFunction} from './ZodSwitch'; import {createZodValues} from './create-zod-values'; import {deepEqual} from './deep-equal'; import {useLocalState} from './local-state'; +import type {AnyZodSchema} from './zod-schema-type'; import {getArrayElement} from './zod-schema-type'; import type {JSONPath} from './zod-types'; @@ -22,9 +23,8 @@ const rowStyle: React.CSSProperties = { width: '100%', }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodMatrixEditor: React.FC<{ - readonly schema: any; + readonly schema: AnyZodSchema; readonly jsonPath: JSONPath; readonly value: unknown[]; readonly defaultValue: unknown[]; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodNullableEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodNullableEditor.tsx index 9b3259fcb56..f35d456aac9 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodNullableEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodNullableEditor.tsx @@ -1,14 +1,15 @@ import {ZodOrNullishEditor} from './ZodOrNullishEditor'; import type {UpdaterFunction} from './ZodSwitch'; +import type {AnyZodSchema} from './zod-schema-type'; +import {getInnerType} from './zod-schema-type'; import type {JSONPath} from './zod-types'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodNullableEditor: React.FC<{ showSaveButton: boolean; jsonPath: JSONPath; value: unknown; defaultValue: unknown; - schema: any; + schema: AnyZodSchema; setValue: UpdaterFunction; onSave: UpdaterFunction; onRemove: null | (() => void); @@ -28,8 +29,7 @@ export const ZodNullableEditor: React.FC<{ saveDisabledByParent, mayPad, }) => { - // Both v3 and v4 have _def.innerType - const {innerType} = schema._def; + const innerType = getInnerType(schema); return ( { - const {checks} = schema._def; +const getMinValue = (schema: AnyZodSchema) => { + const {checks} = getZodDef(schema); if (!checks) return -Infinity; if (isZodV3Schema(schema)) { @@ -35,9 +35,8 @@ const getMinValue = (schema: any) => { return -Infinity; }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const getMaxValue = (schema: any) => { - const {checks} = schema._def; +const getMaxValue = (schema: AnyZodSchema) => { + const {checks} = getZodDef(schema); if (!checks) return Infinity; if (isZodV3Schema(schema)) { @@ -58,9 +57,8 @@ const getMaxValue = (schema: any) => { return Infinity; }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const getStep = (schema: any): number | undefined => { - const {checks} = schema._def; +const getStep = (schema: AnyZodSchema): number | undefined => { + const {checks} = getZodDef(schema); if (!checks) return undefined; if (isZodV3Schema(schema)) { @@ -83,9 +81,8 @@ const getStep = (schema: any): number | undefined => { return undefined; }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodNumberEditor: React.FC<{ - readonly schema: any; + readonly schema: AnyZodSchema; readonly jsonPath: JSONPath; readonly value: number; readonly setValue: UpdaterFunction; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodObjectEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodObjectEditor.tsx index e1b38af015c..eddcdd4257c 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodObjectEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodObjectEditor.tsx @@ -8,7 +8,8 @@ import type {UpdaterFunction} from './ZodSwitch'; import {ZodSwitch} from './ZodSwitch'; import {deepEqual} from './deep-equal'; import {useLocalState} from './local-state'; -import {getZodSchemaType, isZodV3Schema} from './zod-schema-type'; +import type {AnyZodSchema} from './zod-schema-type'; +import {getObjectShape, getZodSchemaType} from './zod-schema-type'; import type {JSONPath} from './zod-types'; export type ObjectDiscrimatedUnionReplacement = { @@ -16,9 +17,8 @@ export type ObjectDiscrimatedUnionReplacement = { markup: React.ReactNode; }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodObjectEditor: React.FC<{ - readonly schema: any; + readonly schema: AnyZodSchema; readonly jsonPath: JSONPath; readonly unsavedValue: Record; readonly savedValue: Record; @@ -52,18 +52,12 @@ export const ZodObjectEditor: React.FC<{ savedValue, }); - const def = schema._def; - const typeName = getZodSchemaType(schema); if (typeName !== 'object') { throw new Error('expected object'); } - // v3: _def.shape() is a function, v4: _def.shape is an object - const shape = - isZodV3Schema(schema) && typeof def.shape === 'function' - ? def.shape() - : def.shape; + const shape = getObjectShape(schema); const keys = Object.keys(shape); const isRoot = jsonPath.length === 0; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodOptionalEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodOptionalEditor.tsx index 1d1ac4a3a91..92bbb1a78ae 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodOptionalEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodOptionalEditor.tsx @@ -1,14 +1,15 @@ import {ZodOrNullishEditor} from './ZodOrNullishEditor'; import type {UpdaterFunction} from './ZodSwitch'; +import type {AnyZodSchema} from './zod-schema-type'; +import {getInnerType} from './zod-schema-type'; import type {JSONPath} from './zod-types'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodOptionalEditor: React.FC<{ showSaveButton: boolean; jsonPath: JSONPath; value: unknown; defaultValue: unknown; - schema: any; + schema: AnyZodSchema; setValue: UpdaterFunction; onSave: UpdaterFunction; onRemove: null | (() => void); @@ -28,8 +29,7 @@ export const ZodOptionalEditor: React.FC<{ saveDisabledByParent, mayPad, }) => { - // Both v3 and v4 have _def.innerType - const {innerType} = schema._def; + const innerType = getInnerType(schema); return ( ; onSave: UpdaterFunction; onRemove: null | (() => void); diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodStaticFileEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodStaticFileEditor.tsx index 4ceffc6b23e..cbc2d15bc8b 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodStaticFileEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodStaticFileEditor.tsx @@ -8,15 +8,15 @@ import {SchemaLabel} from './SchemaLabel'; import {ZodFieldValidation} from './ZodFieldValidation'; import type {UpdaterFunction} from './ZodSwitch'; import {useLocalState} from './local-state'; +import type {AnyZodSchema} from './zod-schema-type'; import type {JSONPath} from './zod-types'; const container: React.CSSProperties = { width: '100%', }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodStaticFileEditor: React.FC<{ - readonly schema: any; + readonly schema: AnyZodSchema; readonly jsonPath: JSONPath; readonly value: string; readonly defaultValue: string; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodStringEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodStringEditor.tsx index a6eaa864921..0eff61d301d 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodStringEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodStringEditor.tsx @@ -6,6 +6,7 @@ import {SchemaLabel} from './SchemaLabel'; import {ZodFieldValidation} from './ZodFieldValidation'; import type {UpdaterFunction} from './ZodSwitch'; import {useLocalState} from './local-state'; +import type {AnyZodSchema} from './zod-schema-type'; import type {JSONPath} from './zod-types'; const fullWidth: React.CSSProperties = { @@ -13,8 +14,7 @@ const fullWidth: React.CSSProperties = { }; export const ZodStringEditor: React.FC<{ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - readonly schema: any; + readonly schema: AnyZodSchema; readonly jsonPath: JSONPath; readonly value: string; readonly defaultValue: string; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodSwitch.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodSwitch.tsx index b4f2ff03a82..e8f244cbfb2 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodSwitch.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodSwitch.tsx @@ -1,6 +1,11 @@ import React from 'react'; import {useZodTypesIfPossible} from '../../get-zod-if-possible'; -import {getZodSchemaDescription, getZodSchemaType} from './zod-schema-type'; +import type {AnyZodSchema} from './zod-schema-type'; +import { + getEffectsInner, + getZodSchemaDescription, + getZodSchemaType, +} from './zod-schema-type'; import type {JSONPath} from './zod-types'; import {ZodArrayEditor} from './ZodArrayEditor'; import {ZodBooleanEditor} from './ZodBooleanEditor'; @@ -28,11 +33,8 @@ export type UpdaterFunction = ( increment: boolean, ) => void; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type AnySchema = any; - export const ZodSwitch: React.FC<{ - readonly schema: AnySchema; + readonly schema: AnyZodSchema; readonly jsonPath: JSONPath; readonly value: unknown; readonly defaultValue: unknown; @@ -361,7 +363,7 @@ export const ZodSwitch: React.FC<{ setValue={setValue as UpdaterFunction} value={value as unknown[]} jsonPath={jsonPath} - schema={schema._def.schema} + schema={getEffectsInner(schema)} defaultValue={defaultValue as unknown[]} onSave={onSave as UpdaterFunction} showSaveButton={showSaveButton} diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodTextareaEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodTextareaEditor.tsx index 94d99552483..b84487ba7c0 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodTextareaEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodTextareaEditor.tsx @@ -9,6 +9,7 @@ import {SchemaLabel} from './SchemaLabel'; import {ZodFieldValidation} from './ZodFieldValidation'; import type {UpdaterFunction} from './ZodSwitch'; import {useLocalState} from './local-state'; +import type {AnyZodSchema} from './zod-schema-type'; import type {JSONPath} from './zod-types'; const fullWidth: React.CSSProperties = { @@ -21,8 +22,7 @@ const textareaStyle: React.CSSProperties = { }; export const ZodTextareaEditor: React.FC<{ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - readonly schema: any; + readonly schema: AnyZodSchema; readonly jsonPath: JSONPath; readonly value: string; readonly defaultValue: string; diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/ZodTupleEditor.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/ZodTupleEditor.tsx index 9891adffad0..bcb5935d492 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/ZodTupleEditor.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/ZodTupleEditor.tsx @@ -10,14 +10,15 @@ import {useLocalState} from './local-state'; import {SchemaLabel} from './SchemaLabel'; import {SchemaArrayItemSeparationLine} from './SchemaSeparationLine'; import {SchemaVerticalGuide} from './SchemaVerticalGuide'; +import type {AnyZodSchema} from './zod-schema-type'; +import {getTupleItems} from './zod-schema-type'; import type {JSONPath} from './zod-types'; import {ZodFieldValidation} from './ZodFieldValidation'; import type {UpdaterFunction} from './ZodSwitch'; import {ZodTupleItemEditor} from './ZodTupleItemEditor'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodTupleEditor: React.FC<{ - readonly schema: any; + readonly schema: AnyZodSchema; readonly jsonPath: JSONPath; readonly value: unknown[]; readonly defaultValue: unknown[]; @@ -49,7 +50,7 @@ export const ZodTupleEditor: React.FC<{ }); const [expanded, setExpanded] = useState(true); - const def = schema._def; + const tupleItems = getTupleItems(schema); const suffix = useMemo(() => { return expanded ? ' [' : ' [...] '; @@ -100,12 +101,12 @@ export const ZodTupleEditor: React.FC<{ ; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - def: any; + tupleItems: AnyZodSchema[]; index: number; value: unknown; defaultValue: unknown; @@ -18,7 +18,7 @@ export const ZodTupleItemEditor: React.FC<{ saveDisabledByParent: boolean; mayPad: boolean; }> = ({ - def, + tupleItems, onChange, jsonPath, index, @@ -71,7 +71,7 @@ export const ZodTupleItemEditor: React.FC<{
{ +const findNull = (value: readonly AnyZodSchema[]) => { const nullIndex = value.findIndex((v) => { const type = getZodSchemaType(v); return type === 'null' || type === 'undefined'; @@ -31,13 +31,12 @@ const findNull = (value: readonly any[]) => { }; }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const ZodUnionEditor: React.FC<{ showSaveButton: boolean; jsonPath: JSONPath; value: unknown; defaultValue: unknown; - schema: any; + schema: AnyZodSchema; setValue: UpdaterFunction; onSave: UpdaterFunction; onRemove: null | (() => void); @@ -57,7 +56,7 @@ export const ZodUnionEditor: React.FC<{ saveDisabledByParent, mayPad, }) => { - const {options} = schema._def; + const options = getUnionOptions(schema); if (options.length > 2) { return ( diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/local-state.tsx b/packages/studio/src/components/RenderModal/SchemaEditor/local-state.tsx index 02042cccaa5..9cf27d67ad8 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/local-state.tsx +++ b/packages/studio/src/components/RenderModal/SchemaEditor/local-state.tsx @@ -10,11 +10,12 @@ import React, { import {Internals} from 'remotion'; import type {UpdaterFunction} from './ZodSwitch'; import {deepEqual} from './deep-equal'; +import type {AnyZodSchema, ZodSafeParseResult} from './zod-schema-type'; +import {zodSafeParse} from './zod-schema-type'; export type LocalState = { value: T; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - zodValidation: {success: boolean; error?: any}; + zodValidation: ZodSafeParseResult; keyStabilityRevision: number; }; @@ -34,8 +35,7 @@ export const useLocalState = ({ savedValue, }: { unsavedValue: T; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - schema: any; + schema: AnyZodSchema; setValue: UpdaterFunction; savedValue: T; }) => { @@ -49,7 +49,7 @@ export const useLocalState = ({ [parentRevision]: { value: unsavedValue, keyStabilityRevision: 0, - zodValidation: schema.safeParse(unsavedValue), + zodValidation: zodSafeParse(schema, unsavedValue), }, }; }); @@ -59,7 +59,7 @@ export const useLocalState = ({ return { value: unsavedValue, keyStabilityRevision: 0, - zodValidation: schema.safeParse(unsavedValue), + zodValidation: zodSafeParse(schema, unsavedValue), }; } @@ -84,7 +84,7 @@ export const useLocalState = ({ localUnsavedValue ?? { value: savedValue, keyStabilityRevision: 0, - zodValidation: schema.safeParse(savedValue), + zodValidation: zodSafeParse(schema, savedValue), } ); }, [localUnsavedValue, savedValue, schema]); @@ -102,7 +102,7 @@ export const useLocalState = ({ return; } - const safeParse = schema.safeParse(newValue); + const safeParse = zodSafeParse(schema, newValue); if (safeParse.success || forceApply) { setValue(updater, forceApply, increment); diff --git a/packages/studio/src/components/RenderModal/SchemaEditor/zod-schema-type.ts b/packages/studio/src/components/RenderModal/SchemaEditor/zod-schema-type.ts index e374482ae85..5aff45065a3 100644 --- a/packages/studio/src/components/RenderModal/SchemaEditor/zod-schema-type.ts +++ b/packages/studio/src/components/RenderModal/SchemaEditor/zod-schema-type.ts @@ -16,6 +16,19 @@ * v4 core schemas have `_zod.def` with `type` property. * At runtime, all zod schemas have `_def` (classic layer adds it for v4). */ +export interface ZodValidationError { + format(): {_errors: string[]}; + issues: readonly { + code: string; + message: string; + path: readonly PropertyKey[]; + }[]; +} + +export type ZodSafeParseResult = + | {success: true; data: unknown} + | {success: false; error: ZodValidationError}; + export interface AnyZodSchema { // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly _def?: Record; @@ -24,6 +37,19 @@ export interface AnyZodSchema { readonly description?: string; } +/** + * Call safeParse on any Zod schema (v3 or v4). + * All Zod schemas have safeParse at runtime, but some v4 internal types + * (like $ZodObject) don't declare it in their type definition. + */ +export const zodSafeParse = ( + schema: AnyZodSchema, + data: unknown, +): ZodSafeParseResult => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return (schema as any).safeParse(data); +}; + // eslint-disable-next-line @typescript-eslint/no-explicit-any export const getZodDef = (schema: AnyZodSchema): Record => { if (schema._def) return schema._def; diff --git a/packages/studio/src/visual-controls/VisualControls.tsx b/packages/studio/src/visual-controls/VisualControls.tsx index 6eb2f5ed85d..90b0427b628 100644 --- a/packages/studio/src/visual-controls/VisualControls.tsx +++ b/packages/studio/src/visual-controls/VisualControls.tsx @@ -132,7 +132,7 @@ export const VisualControlsProvider: React.FC<{ const {changed, currentValue} = setControl(key, { valueInCode: value, - schema: schema ?? getZodSchemaFromPrimitive(value, z), + schema: (schema ?? getZodSchemaFromPrimitive(value, z)) as AnyZodSchema, stack: new Error().stack as string, }); From d811fc70e712b8ee799e6cd1c87995a9dc8d54ab Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Wed, 18 Feb 2026 17:37:10 +0100 Subject: [PATCH 22/49] Restore type-safe InferZodInput in web-renderer InputPropsIfHasProps Replace Record with InferZodInput in InputPropsIfHasProps to restore type-safe input prop inference for both Zod v3 and v4. Also simplify calculateMetadata cast targets and remove unused InferProps imports. Co-Authored-By: Claude Opus 4.6 --- packages/web-renderer/src/props-if-has-props.ts | 2 +- packages/web-renderer/src/render-media-on-web.tsx | 10 +++++----- packages/web-renderer/src/render-still-on-web.tsx | 7 ++----- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/web-renderer/src/props-if-has-props.ts b/packages/web-renderer/src/props-if-has-props.ts index fda246247d2..87fbe09429d 100644 --- a/packages/web-renderer/src/props-if-has-props.ts +++ b/packages/web-renderer/src/props-if-has-props.ts @@ -2,7 +2,7 @@ import type {ComponentType} from 'react'; import type {AnyZodObject, CalculateMetadataFunction} from 'remotion'; // eslint-disable-next-line @typescript-eslint/no-explicit-any -type InferZodInput = T extends {_zod: {input: any}} +export type InferZodInput = T extends {_zod: {input: any}} ? T['_zod']['input'] : // eslint-disable-next-line @typescript-eslint/no-explicit-any T extends {_input: any} diff --git a/packages/web-renderer/src/render-media-on-web.tsx b/packages/web-renderer/src/render-media-on-web.tsx index b783429471b..9d9e55b6f4e 100644 --- a/packages/web-renderer/src/render-media-on-web.tsx +++ b/packages/web-renderer/src/render-media-on-web.tsx @@ -33,7 +33,7 @@ import { import type {WebRendererOutputTarget} from './output-target'; import type { CompositionCalculateMetadataOrExplicit, - InferProps, + InferZodInput, } from './props-if-has-props'; import {onlyOneRenderAtATimeQueue} from './render-operations-queue'; import {resolveAudioCodec} from './resolve-audio-codec'; @@ -52,7 +52,7 @@ export type InputPropsIfHasProps< ? {} extends Props ? { // Neither props nor schema specified - inputProps?: Record & Props; + inputProps?: InferZodInput & Props; } : { // Only props specified @@ -61,11 +61,11 @@ export type InputPropsIfHasProps< : {} extends Props ? { // Only schema specified - inputProps: Record; + inputProps: InferZodInput; } : { // Props and schema specified - inputProps: Record & Props; + inputProps: InferZodInput & Props; }; type MandatoryRenderMediaOnWebOptions< @@ -226,7 +226,7 @@ const internalRenderMediaOnWeb = async < const resolved = await Internals.resolveVideoConfig({ calculateMetadata: (composition.calculateMetadata as unknown as CalculateMetadataFunction< - InferProps> + Record >) ?? null, signal: signal ?? new AbortController().signal, defaultProps: composition.defaultProps ?? {}, diff --git a/packages/web-renderer/src/render-still-on-web.tsx b/packages/web-renderer/src/render-still-on-web.tsx index 32c1110e1df..bce0cb6a444 100644 --- a/packages/web-renderer/src/render-still-on-web.tsx +++ b/packages/web-renderer/src/render-still-on-web.tsx @@ -9,10 +9,7 @@ import {handleArtifacts} from './artifact'; import {checkForError, createScaffold} from './create-scaffold'; import type {InternalState} from './internal-state'; import {makeInternalState} from './internal-state'; -import type { - CompositionCalculateMetadataOrExplicit, - InferProps, -} from './props-if-has-props'; +import type {CompositionCalculateMetadataOrExplicit} from './props-if-has-props'; import type {InputPropsIfHasProps} from './render-media-on-web'; import {onlyOneRenderAtATimeQueue} from './render-operations-queue'; import {sendUsageEvent} from './send-telemetry-event'; @@ -81,7 +78,7 @@ async function internalRenderStillOnWeb< const resolved = await Internals.resolveVideoConfig({ calculateMetadata: (composition.calculateMetadata as unknown as CalculateMetadataFunction< - InferProps> + Record >) ?? null, signal: signal ?? new AbortController().signal, defaultProps: composition.defaultProps ?? {}, From 3104ea7b2a04ba7f87642a7b686e17f338cb37c5 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Wed, 18 Feb 2026 18:53:34 +0100 Subject: [PATCH 23/49] Replace zod-to-json-schema with Zod v4 native z.toJSONSchema() zod-to-json-schema is deprecated as of Nov 2025. Zod v4 natively supports JSON schema generation via z.toJSONSchema(). This removes the as any cast that was needed for the third-party library. Co-Authored-By: Claude Opus 4.6 --- bun.lock | 11 ++++++----- packages/template-prompt-to-video/cli/service.ts | 4 +--- packages/template-prompt-to-video/package.json | 3 +-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/bun.lock b/bun.lock index c84f4ebd856..df4327780cf 100644 --- a/bun.lock +++ b/bun.lock @@ -1857,7 +1857,6 @@ "typescript": "5.9.3", "uuid": "^13.0.0", "yargs": "^18.0.0", - "zod-to-json-schema": "^3.24.6", }, }, "packages/template-react-router": { @@ -2358,7 +2357,7 @@ }, "packages/zod-types-v3": { "name": "@remotion/zod-types-v3", - "version": "4.0.423", + "version": "4.0.424", "dependencies": { "@remotion/zod-types": "workspace:*", "remotion": "workspace:*", @@ -7824,7 +7823,7 @@ "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], - "zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="], + "zod-to-json-schema": ["zod-to-json-schema@3.24.6", "", { "peerDependencies": { "zod": "3.25.76" } }, "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg=="], "zod-to-ts": ["zod-to-ts@1.2.0", "", { "peerDependencies": { "typescript": "5.8.2", "zod": "3.25.76" } }, "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA=="], @@ -8516,6 +8515,8 @@ "@modelcontextprotocol/sdk/zod": ["zod@4.1.13", "", {}, "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig=="], + "@modelcontextprotocol/sdk/zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="], + "@napi-rs/wasm-runtime/@emnapi/runtime": ["@emnapi/runtime@1.5.0", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="], "@next/eslint-plugin-next/fast-glob": ["fast-glob@3.3.1", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "@nodelib/fs.walk": "1.2.8", "glob-parent": "5.1.2", "merge2": "1.4.1", "micromatch": "4.0.8" } }, "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg=="], @@ -9480,8 +9481,6 @@ "astro/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "astro/zod-to-json-schema": ["zod-to-json-schema@3.24.6", "", { "peerDependencies": { "zod": "3.25.76" } }, "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg=="], - "async-disk-cache/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="], "async-disk-cache/mkdirp": ["mkdirp@0.5.6", "", { "dependencies": { "minimist": "1.2.6" }, "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw=="], @@ -10768,6 +10767,8 @@ "zip-stream/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "3.0.0", "buffer": "6.0.3", "events": "3.3.0", "process": "0.11.10", "string_decoder": "1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], + "zod-to-json-schema/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "zod-to-ts/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "zustand/react": ["react@19.0.0", "", {}, "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ=="], diff --git a/packages/template-prompt-to-video/cli/service.ts b/packages/template-prompt-to-video/cli/service.ts index 654630a1088..5987ddb7709 100644 --- a/packages/template-prompt-to-video/cli/service.ts +++ b/packages/template-prompt-to-video/cli/service.ts @@ -3,7 +3,6 @@ import * as fs from "fs"; import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js"; import { CharacterAlignmentResponseModel } from "@elevenlabs/elevenlabs-js/api"; import { IMAGE_HEIGHT, IMAGE_WIDTH } from "../src/lib/constants"; -import { zodToJsonSchema } from "zod-to-json-schema"; let apiKey: string | null = null; @@ -15,8 +14,7 @@ export const openaiStructuredCompletion = async ( prompt: string, schema: z.ZodType, ): Promise => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const jsonSchema = zodToJsonSchema(schema as any) as any; + const jsonSchema = z.toJSONSchema(schema); const res = await fetch("https://api.openai.com/v1/chat/completions", { method: "POST", diff --git a/packages/template-prompt-to-video/package.json b/packages/template-prompt-to-video/package.json index e6f568ae62f..faa49618485 100644 --- a/packages/template-prompt-to-video/package.json +++ b/packages/template-prompt-to-video/package.json @@ -40,8 +40,7 @@ "tsx": "^4.20.6", "typescript": "5.9.3", "uuid": "^13.0.0", - "yargs": "^18.0.0", - "zod-to-json-schema": "^3.24.6" + "yargs": "^18.0.0" }, "private": true } From 49eea29d5bcfe97e93a83930fe63dcb89f5d22af Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Thu, 19 Feb 2026 08:59:14 +0100 Subject: [PATCH 24/49] Docs: Update version references from 4.0.425 to 4.0.426 Co-Authored-By: Claude Opus 4.6 --- packages/docs/docs/zod-types-v3/index.mdx | 2 +- packages/docs/docs/zod-types/index.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/docs/docs/zod-types-v3/index.mdx b/packages/docs/docs/zod-types-v3/index.mdx index a6d9390d5c9..a70701e7f24 100644 --- a/packages/docs/docs/zod-types-v3/index.mdx +++ b/packages/docs/docs/zod-types-v3/index.mdx @@ -11,7 +11,7 @@ This package provides the same utility types as [`@remotion/zod-types`](/docs/zo Use this package if you are composing Remotion's Zod types with your own schemas that use Zod 3.22.3. If you are using Zod v4, use [`@remotion/zod-types`](/docs/zod-types) instead. - + ## Installation diff --git a/packages/docs/docs/zod-types/index.mdx b/packages/docs/docs/zod-types/index.mdx index 8989e1abc31..7713c187a37 100644 --- a/packages/docs/docs/zod-types/index.mdx +++ b/packages/docs/docs/zod-types/index.mdx @@ -9,7 +9,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import {ZodTypesTableOfContents} from './TableOfContents'; -Since Remotion v4.0.425, `@remotion/zod-types` is based on Zod v4. +Since Remotion v4.0.426, `@remotion/zod-types` is based on Zod v4. If you want to compose these types with your own Zod schemas, use Zod v4. If you are using Zod 3.22.3, use [`@remotion/zod-types-v3`](/docs/zod-types-v3) instead. From 524cdeb0543116b29bdb4ff233895c9f6a4d8125 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Thu, 19 Feb 2026 09:11:50 +0100 Subject: [PATCH 25/49] v4.0.425 --- bun.lock | 164 +++++++------- packages/animated-emoji/package.json | 2 +- packages/animation-utils/package.json | 2 +- packages/astro-example/package.json | 2 +- packages/babel-loader/package.json | 2 +- packages/bugs/package.json | 2 +- packages/bundler/package.json | 2 +- packages/captions/package.json | 2 +- packages/cli/package.json | 2 +- packages/cloudrun/container/package.json | 2 +- packages/cloudrun/package.json | 2 +- packages/compositor-darwin-arm64/package.json | 2 +- packages/compositor-darwin-x64/package.json | 2 +- .../compositor-linux-arm64-gnu/package.json | 2 +- .../compositor-linux-arm64-musl/package.json | 2 +- .../compositor-linux-x64-gnu/package.json | 2 +- .../compositor-linux-x64-musl/package.json | 2 +- .../compositor-win32-x64-msvc/package.json | 2 +- packages/compositor/package.json | 2 +- packages/convert/package.json | 2 +- packages/core/package.json | 2 +- packages/core/src/version.ts | 2 +- packages/create-video/package.json | 2 +- packages/design/package.json | 2 +- packages/discord-poster/package.json | 2 +- packages/docs/package.json | 2 +- packages/docusaurus-plugin/package.json | 2 +- packages/enable-scss/package.json | 2 +- packages/eslint-config-flat/package.json | 2 +- packages/eslint-config-internal/package.json | 2 +- packages/eslint-config/package.json | 2 +- packages/eslint-plugin/package.json | 2 +- packages/example-videos/package.json | 2 +- packages/example-without-zod/package.json | 2 +- packages/example/package.json | 2 +- packages/fonts/package.json | 2 +- packages/gif/package.json | 2 +- packages/google-fonts/package.json | 23 +- packages/google-fonts/scripts/google-fonts.ts | 206 +++++++++++++----- .../scripts/incompatible-fonts.ts | 94 ++++---- packages/google-fonts/src/BetaniaPatmos.ts | 46 ++++ packages/google-fonts/src/BetaniaPatmosGDL.ts | 46 ++++ packages/google-fonts/src/BetaniaPatmosIn.ts | 46 ++++ .../google-fonts/src/BetaniaPatmosInGDL.ts | 46 ++++ packages/google-fonts/src/GveretLevin.ts | 46 ++++ packages/google-fonts/src/Idiqlat.ts | 58 +++++ packages/google-fonts/src/MaShanZheng.ts | 186 ++++++++-------- packages/google-fonts/src/NotoColorEmoji.ts | 22 +- packages/google-fonts/src/Ramsina.ts | 46 ++++ packages/google-fonts/src/ZCOOLKuaiLe.ts | 190 ++++++++-------- packages/google-fonts/src/index.ts | 35 +++ packages/install-whisper-cpp/package.json | 2 +- packages/it-tests/package.json | 2 +- packages/lambda-client/package.json | 2 +- packages/lambda-go-example/package.json | 2 +- packages/lambda-go/package.json | 2 +- packages/lambda-go/version.go | 2 +- packages/lambda-php-example/composer.json | 2 +- packages/lambda-php/composer.json | 2 +- packages/lambda-php/package.json | 2 +- packages/lambda-php/src/Semantic.php | 2 +- packages/lambda-python/package.json | 2 +- .../lambda-python/remotion_lambda/version.py | 2 +- .../lib/remotion_lambda/version.rb | 2 +- packages/lambda-ruby/package.json | 2 +- packages/lambda-ruby/remotion_lambda.gemspec | 2 +- packages/lambda/package.json | 2 +- packages/layout-utils/package.json | 2 +- packages/licensing/package.json | 2 +- packages/light-leaks/package.json | 2 +- packages/lottie/package.json | 2 +- packages/mcp/package.json | 2 +- packages/media-parser/package.json | 2 +- packages/media-parser/src/version.ts | 2 +- packages/media-utils/package.json | 2 +- packages/media/package.json | 2 +- packages/motion-blur/package.json | 2 +- packages/noise/package.json | 2 +- packages/openai-whisper/package.json | 2 +- packages/paths/package.json | 2 +- packages/player-example/package.json | 2 +- packages/player/package.json | 2 +- packages/preload/package.json | 2 +- packages/promo-pages/package.json | 2 +- packages/react18-tests/package.json | 2 +- packages/renderer/package.json | 2 +- packages/rive/package.json | 2 +- packages/rounded-text-box/package.json | 2 +- packages/serverless-client/package.json | 2 +- packages/serverless/package.json | 2 +- packages/shapes/package.json | 2 +- packages/skia/package.json | 2 +- packages/skills/package.json | 2 +- packages/streaming/package.json | 2 +- packages/studio-server/package.json | 2 +- packages/studio-shared/package.json | 2 +- packages/studio/package.json | 2 +- packages/svg-3d-engine/package.json | 2 +- packages/tailwind-v4/package.json | 2 +- packages/tailwind/package.json | 2 +- packages/test-utils/package.json | 2 +- packages/three/package.json | 2 +- packages/transitions/package.json | 2 +- packages/web-renderer/package.json | 2 +- packages/webcodecs/package.json | 2 +- packages/whisper-web/package.json | 2 +- packages/zod-types/package.json | 2 +- 107 files changed, 967 insertions(+), 471 deletions(-) create mode 100644 packages/google-fonts/src/BetaniaPatmos.ts create mode 100644 packages/google-fonts/src/BetaniaPatmosGDL.ts create mode 100644 packages/google-fonts/src/BetaniaPatmosIn.ts create mode 100644 packages/google-fonts/src/BetaniaPatmosInGDL.ts create mode 100644 packages/google-fonts/src/GveretLevin.ts create mode 100644 packages/google-fonts/src/Idiqlat.ts create mode 100644 packages/google-fonts/src/Ramsina.ts diff --git a/bun.lock b/bun.lock index cf2a716f64e..8ee6b5db00a 100644 --- a/bun.lock +++ b/bun.lock @@ -21,7 +21,7 @@ }, "packages/animated-emoji": { "name": "@remotion/animated-emoji", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "remotion": "workspace:*", }, @@ -33,7 +33,7 @@ }, "packages/animation-utils": { "name": "@remotion/animation-utils", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "remotion": "workspace:*", }, @@ -49,7 +49,7 @@ }, "packages/astro-example": { "name": "@remotion/astro-example", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@astrojs/react": "4.0.0", "@remotion/gif": "workspace:*", @@ -68,7 +68,7 @@ }, "packages/babel-loader": { "name": "@remotion/babel-loader", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@babel/core": "7.23.2", "@babel/plugin-proposal-class-properties": "7.14.5", @@ -92,7 +92,7 @@ }, "packages/bundler": { "name": "@remotion/bundler", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@remotion/media-parser": "workspace:*", "@remotion/studio": "workspace:*", @@ -119,7 +119,7 @@ }, "packages/captions": { "name": "@remotion/captions", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", "@typescript/native-preview": "catalog:", @@ -128,7 +128,7 @@ }, "packages/cli": { "name": "@remotion/cli", - "version": "4.0.424", + "version": "4.0.425", "bin": { "remotion": "remotion-cli.js", "remotionb": "remotionb-cli.js", @@ -170,7 +170,7 @@ }, "packages/cloudrun": { "name": "@remotion/cloudrun", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@google-cloud/artifact-registry": "3.5.1", "@google-cloud/functions-framework": "3.4.6", @@ -196,39 +196,39 @@ }, "packages/compositor": { "name": "@remotion/compositor", - "version": "4.0.424", + "version": "4.0.425", }, "packages/compositor-darwin-arm64": { "name": "@remotion/compositor-darwin-arm64", - "version": "4.0.424", + "version": "4.0.425", }, "packages/compositor-darwin-x64": { "name": "@remotion/compositor-darwin-x64", - "version": "4.0.424", + "version": "4.0.425", }, "packages/compositor-linux-arm64-gnu": { "name": "@remotion/compositor-linux-arm64-gnu", - "version": "4.0.424", + "version": "4.0.425", }, "packages/compositor-linux-arm64-musl": { "name": "@remotion/compositor-linux-arm64-musl", - "version": "4.0.424", + "version": "4.0.425", }, "packages/compositor-linux-x64-gnu": { "name": "@remotion/compositor-linux-x64-gnu", - "version": "4.0.424", + "version": "4.0.425", }, "packages/compositor-linux-x64-musl": { "name": "@remotion/compositor-linux-x64-musl", - "version": "4.0.424", + "version": "4.0.425", }, "packages/compositor-win32-x64-msvc": { "name": "@remotion/compositor-win32-x64-msvc", - "version": "4.0.424", + "version": "4.0.425", }, "packages/convert": { "name": "@remotion/convert", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@mediabunny/mp3-encoder": "catalog:", "@mediafox/core": "^1.0.4", @@ -284,7 +284,7 @@ }, "packages/core": { "name": "remotion", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "@happy-dom/global-registrator": "14.5.1", "@remotion/eslint-config-internal": "workspace:*", @@ -306,7 +306,7 @@ }, "packages/create-video": { "name": "create-video", - "version": "4.0.424", + "version": "4.0.425", "bin": { "create-video": "bin.js", }, @@ -329,7 +329,7 @@ }, "packages/design": { "name": "@remotion/design", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@radix-ui/react-select": "2.1.1", "@radix-ui/react-tabs": "^1.1.0", @@ -358,11 +358,11 @@ }, "packages/discord-poster": { "name": "@remotion/discord-poster", - "version": "4.0.424", + "version": "4.0.425", }, "packages/docs": { "name": "docs", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@algora/sdk": "^0.1.2", "@aws-sdk/s3-request-presigner": "catalog:", @@ -475,7 +475,7 @@ }, "packages/docusaurus-plugin": { "name": "@remotion/docusaurus-plugin", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@docusaurus/types": "3.6.0", "@shikijs/twoslash": "3.22.0", @@ -494,7 +494,7 @@ }, "packages/enable-scss": { "name": "@remotion/enable-scss", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "css-loader": "5.2.7", "sass-loader": "14.2.1", @@ -512,7 +512,7 @@ }, "packages/eslint-config": { "name": "@remotion/eslint-config", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", "@remotion/eslint-plugin": "workspace:*", @@ -529,7 +529,7 @@ }, "packages/eslint-config-flat": { "name": "@remotion/eslint-config-flat", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "typescript-eslint": "8.21.0", }, @@ -548,7 +548,7 @@ }, "packages/eslint-config-internal": { "name": "@remotion/eslint-config-internal", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@eslint/compat": "1.2.2", "@eslint/eslintrc": "3.1.0", @@ -567,7 +567,7 @@ }, "packages/eslint-plugin": { "name": "@remotion/eslint-plugin", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@typescript-eslint/utils": "5.19.0", }, @@ -582,7 +582,7 @@ }, "packages/example": { "name": "@remotion/example", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@mdx-js/loader": "^2.3.0", "@mdx-js/react": "^2.3.0", @@ -666,7 +666,7 @@ }, "packages/example-videos": { "name": "@remotion/example-videos", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", "@typescript/native-preview": "catalog:", @@ -676,7 +676,7 @@ }, "packages/example-without-zod": { "name": "@remotion/example-without-zod", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@remotion/cli": "workspace:*", "react": "catalog:", @@ -686,7 +686,7 @@ }, "packages/fonts": { "name": "@remotion/fonts", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "remotion": "workspace:*", }, @@ -698,7 +698,7 @@ }, "packages/gif": { "name": "@remotion/gif", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "remotion": "workspace:*", }, @@ -718,7 +718,7 @@ }, "packages/google-fonts": { "name": "@remotion/google-fonts", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "remotion": "workspace:*", }, @@ -732,7 +732,7 @@ }, "packages/install-whisper-cpp": { "name": "@remotion/install-whisper-cpp", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@remotion/captions": "workspace:*", }, @@ -744,7 +744,7 @@ }, "packages/it-tests": { "name": "@remotion/it-tests", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "@remotion/bundler": "workspace:*", "@remotion/captions": "workspace:*", @@ -786,7 +786,7 @@ }, "packages/lambda": { "name": "@remotion/lambda", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@aws-sdk/client-cloudwatch-logs": "catalog:", "@aws-sdk/client-iam": "catalog:", @@ -829,7 +829,7 @@ }, "packages/lambda-client": { "name": "@remotion/lambda-client", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "@aws-sdk/client-cloudwatch-logs": "catalog:", "@aws-sdk/client-iam": "catalog:", @@ -853,25 +853,25 @@ }, "packages/lambda-go": { "name": "@remotion/lambda-go", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "remotion": "workspace:*", }, }, "packages/lambda-go-example": { "name": "@remotion/lambda-go-example", - "version": "4.0.424", + "version": "4.0.425", }, "packages/lambda-php": { "name": "@remotion/lambda-php", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "remotion": "workspace:*", }, }, "packages/lambda-python": { "name": "@remotion/lambda-python", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "dotenv": "17.3.1", }, @@ -881,14 +881,14 @@ }, "packages/lambda-ruby": { "name": "@remotion/lambda-ruby", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "remotion": "workspace:*", }, }, "packages/layout-utils": { "name": "@remotion/layout-utils", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", "@typescript/native-preview": "catalog:", @@ -897,7 +897,7 @@ }, "packages/licensing": { "name": "@remotion/licensing", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", "@typescript/native-preview": "catalog:", @@ -908,7 +908,7 @@ }, "packages/light-leaks": { "name": "@remotion/light-leaks", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "remotion": "workspace:*", }, @@ -926,7 +926,7 @@ }, "packages/lottie": { "name": "@remotion/lottie", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "remotion": "workspace:*", }, @@ -946,7 +946,7 @@ }, "packages/mcp": { "name": "@remotion/mcp", - "version": "4.0.424", + "version": "4.0.425", "bin": { "remotion-mcp": "./dist/esm/index.mjs", }, @@ -963,7 +963,7 @@ }, "packages/media": { "name": "@remotion/media", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@mediabunny/ac3": "catalog:", "mediabunny": "catalog:", @@ -986,7 +986,7 @@ }, "packages/media-parser": { "name": "@remotion/media-parser", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", "@remotion/example-videos": "workspace:*", @@ -999,7 +999,7 @@ }, "packages/media-utils": { "name": "@remotion/media-utils", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@remotion/media-parser": "workspace:*", "@remotion/webcodecs": "workspace:*", @@ -1018,7 +1018,7 @@ }, "packages/motion-blur": { "name": "@remotion/motion-blur", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "remotion": "workspace:*", }, @@ -1037,7 +1037,7 @@ }, "packages/noise": { "name": "@remotion/noise", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "remotion": "workspace:*", "simplex-noise": "4.0.1", @@ -1050,7 +1050,7 @@ }, "packages/openai-whisper": { "name": "@remotion/openai-whisper", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@remotion/captions": "workspace:*", }, @@ -1063,7 +1063,7 @@ }, "packages/paths": { "name": "@remotion/paths", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", "@typescript/native-preview": "catalog:", @@ -1072,7 +1072,7 @@ }, "packages/player": { "name": "@remotion/player", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "remotion": "workspace:*", }, @@ -1095,7 +1095,7 @@ }, "packages/player-example": { "name": "@remotion/player-example", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@remotion/bundler": "workspace:*", "@remotion/eslint-config-flat": "workspace:*", @@ -1116,7 +1116,7 @@ }, "packages/preload": { "name": "@remotion/preload", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", "@typescript/native-preview": "catalog:", @@ -1125,7 +1125,7 @@ }, "packages/promo-pages": { "name": "@remotion/promo-pages", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@mux/upchunk": "^3.5.0", "@remotion/animated-emoji": "workspace:*", @@ -1164,7 +1164,7 @@ }, "packages/react18-tests": { "name": "@remotion/react18-tests", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "remotion": "workspace:*", }, @@ -1191,7 +1191,7 @@ }, "packages/renderer": { "name": "@remotion/renderer", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@remotion/licensing": "workspace:*", "@remotion/streaming": "workspace:*", @@ -1230,7 +1230,7 @@ }, "packages/rive": { "name": "@remotion/rive", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@rive-app/canvas-advanced": "2.31.5", "remotion": "workspace:*", @@ -1249,7 +1249,7 @@ }, "packages/rounded-text-box": { "name": "@remotion/rounded-text-box", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@remotion/layout-utils": "workspace:*", "@remotion/paths": "workspace:*", @@ -1262,7 +1262,7 @@ }, "packages/serverless": { "name": "@remotion/serverless", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@remotion/bundler": "workspace:*", "@remotion/licensing": "workspace:*", @@ -1277,7 +1277,7 @@ }, "packages/serverless-client": { "name": "@remotion/serverless-client", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", "@remotion/renderer": "workspace:*", @@ -1289,7 +1289,7 @@ }, "packages/shapes": { "name": "@remotion/shapes", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@remotion/paths": "workspace:*", }, @@ -1309,7 +1309,7 @@ }, "packages/skia": { "name": "@remotion/skia", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "remotion": "workspace:*", }, @@ -1333,7 +1333,7 @@ }, "packages/skills": { "name": "@remotion/skills", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "@remotion/bundler": "workspace:*", "@remotion/cli": "workspace:*", @@ -1351,7 +1351,7 @@ }, "packages/streaming": { "name": "@remotion/streaming", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", "@typescript/native-preview": "catalog:", @@ -1360,7 +1360,7 @@ }, "packages/studio": { "name": "@remotion/studio", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@remotion/media-utils": "workspace:*", "@remotion/player": "workspace:*", @@ -1391,7 +1391,7 @@ }, "packages/studio-server": { "name": "@remotion/studio-server", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@babel/parser": "7.24.1", "@remotion/bundler": "workspace:*", @@ -1417,7 +1417,7 @@ }, "packages/studio-shared": { "name": "@remotion/studio-shared", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "remotion": "workspace:*", }, @@ -1430,7 +1430,7 @@ }, "packages/svg-3d-engine": { "name": "@remotion/svg-3d-engine", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@remotion/paths": "workspace:*", }, @@ -1442,7 +1442,7 @@ }, "packages/tailwind": { "name": "@remotion/tailwind", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "autoprefixer": "10.4.20", "css-loader": "5.2.7", @@ -1465,7 +1465,7 @@ }, "packages/tailwind-v4": { "name": "@remotion/tailwind-v4", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@tailwindcss/postcss": "4.1.1", "css-loader": "5.2.7", @@ -2213,7 +2213,7 @@ }, "packages/test-utils": { "name": "@remotion/test-utils", - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", "@typescript/native-preview": "catalog:", @@ -2225,7 +2225,7 @@ }, "packages/three": { "name": "@remotion/three", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "remotion": "workspace:*", }, @@ -2252,7 +2252,7 @@ }, "packages/transitions": { "name": "@remotion/transitions", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@remotion/paths": "workspace:*", "@remotion/shapes": "workspace:*", @@ -2276,7 +2276,7 @@ }, "packages/web-renderer": { "name": "@remotion/web-renderer", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@remotion/licensing": "workspace:*", "mediabunny": "catalog:", @@ -2308,7 +2308,7 @@ }, "packages/webcodecs": { "name": "@remotion/webcodecs", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@remotion/media-parser": "workspace:*", }, @@ -2325,7 +2325,7 @@ }, "packages/whisper-web": { "name": "@remotion/whisper-web", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "@remotion/captions": "workspace:*", }, @@ -2337,7 +2337,7 @@ }, "packages/zod-types": { "name": "@remotion/zod-types", - "version": "4.0.424", + "version": "4.0.425", "dependencies": { "remotion": "workspace:*", }, diff --git a/packages/animated-emoji/package.json b/packages/animated-emoji/package.json index 08f1b420e8d..b055e715da0 100644 --- a/packages/animated-emoji/package.json +++ b/packages/animated-emoji/package.json @@ -1,6 +1,6 @@ { "name": "@remotion/animated-emoji", - "version": "4.0.424", + "version": "4.0.425", "main": "dist/cjs/index.js", "types": "dist/cjs/index.d.ts", "module": "dist/esm/index.mjs", diff --git a/packages/animation-utils/package.json b/packages/animation-utils/package.json index 981c19e9cb2..de3e1411c97 100644 --- a/packages/animation-utils/package.json +++ b/packages/animation-utils/package.json @@ -7,7 +7,7 @@ "name": "Chetan Karwa", "email": "cbkarwa@gmail.com" }, - "version": "4.0.424", + "version": "4.0.425", "description": "Helpers for animating CSS properties", "main": "./dist/index.js", "module": "./dist/index.mjs", diff --git a/packages/astro-example/package.json b/packages/astro-example/package.json index f2405143ccb..906b11c4dd1 100644 --- a/packages/astro-example/package.json +++ b/packages/astro-example/package.json @@ -5,7 +5,7 @@ "name": "@remotion/astro-example", "private": true, "type": "module", - "version": "4.0.424", + "version": "4.0.425", "scripts": { "dev": "astro dev", "start": "astro dev", diff --git a/packages/babel-loader/package.json b/packages/babel-loader/package.json index 8d4a5b90c9f..29af56254aa 100644 --- a/packages/babel-loader/package.json +++ b/packages/babel-loader/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/babel-loader" }, "name": "@remotion/babel-loader", - "version": "4.0.424", + "version": "4.0.425", "description": "Babel loader for Remotion", "main": "dist/index.js", "scripts": { diff --git a/packages/bugs/package.json b/packages/bugs/package.json index d1256ac02bf..6715c36f9fb 100644 --- a/packages/bugs/package.json +++ b/packages/bugs/package.json @@ -4,5 +4,5 @@ }, "name": "bugs", "private": true, - "version": "4.0.424" + "version": "4.0.425" } diff --git a/packages/bundler/package.json b/packages/bundler/package.json index 40d5b3c3af5..36a501f5b2a 100644 --- a/packages/bundler/package.json +++ b/packages/bundler/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/bundler" }, "name": "@remotion/bundler", - "version": "4.0.424", + "version": "4.0.425", "description": "Bundle Remotion compositions using Webpack", "main": "dist/index.js", "sideEffects": false, diff --git a/packages/captions/package.json b/packages/captions/package.json index 22d5582e355..8dd1e4689c0 100644 --- a/packages/captions/package.json +++ b/packages/captions/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/captions" }, "name": "@remotion/captions", - "version": "4.0.424", + "version": "4.0.425", "description": "Primitives for dealing with captions", "main": "dist/index.js", "sideEffects": false, diff --git a/packages/cli/package.json b/packages/cli/package.json index 7ee83a7fc78..51b082e2dfc 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/cli" }, "name": "@remotion/cli", - "version": "4.0.424", + "version": "4.0.425", "description": "Control Remotion features using the `npx remotion` command", "main": "dist/index.js", "sideEffects": false, diff --git a/packages/cloudrun/container/package.json b/packages/cloudrun/container/package.json index 325e7aa875e..384b1d39d8b 100644 --- a/packages/cloudrun/container/package.json +++ b/packages/cloudrun/container/package.json @@ -1,6 +1,6 @@ { "name": "cloud-run-render", - "version": "4.0.424", + "version": "4.0.425", "description": "Render media and stills on GCP Cloud Run", "main": "dist/index.js", "scripts": { diff --git a/packages/cloudrun/package.json b/packages/cloudrun/package.json index 593d50a0791..8de554c1c51 100644 --- a/packages/cloudrun/package.json +++ b/packages/cloudrun/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/cloudrun" }, "name": "@remotion/cloudrun", - "version": "4.0.424", + "version": "4.0.425", "description": "Render Remotion videos on Google Cloud Run", "main": "dist/index.js", "sideEffects": false, diff --git a/packages/compositor-darwin-arm64/package.json b/packages/compositor-darwin-arm64/package.json index f548479c26a..2b1931dd015 100644 --- a/packages/compositor-darwin-arm64/package.json +++ b/packages/compositor-darwin-arm64/package.json @@ -2,7 +2,7 @@ "repository": { "url": "https://github.com/remotion-dev/remotion/tree/main/packages/compositor-darwin-arm64" }, - "version": "4.0.424", + "version": "4.0.425", "name": "@remotion/compositor-darwin-arm64", "os": [ "darwin" diff --git a/packages/compositor-darwin-x64/package.json b/packages/compositor-darwin-x64/package.json index 4f3b7142051..446d48e1ad1 100644 --- a/packages/compositor-darwin-x64/package.json +++ b/packages/compositor-darwin-x64/package.json @@ -2,7 +2,7 @@ "repository": { "url": "https://github.com/remotion-dev/remotion/tree/main/packages/compositor-darwin-x64" }, - "version": "4.0.424", + "version": "4.0.425", "name": "@remotion/compositor-darwin-x64", "os": [ "darwin" diff --git a/packages/compositor-linux-arm64-gnu/package.json b/packages/compositor-linux-arm64-gnu/package.json index 223ef2b73b7..983c3c32114 100644 --- a/packages/compositor-linux-arm64-gnu/package.json +++ b/packages/compositor-linux-arm64-gnu/package.json @@ -2,7 +2,7 @@ "repository": { "url": "https://github.com/remotion-dev/remotion/tree/main/packages/compositor-linux-arm64-gnu" }, - "version": "4.0.424", + "version": "4.0.425", "name": "@remotion/compositor-linux-arm64-gnu", "os": [ "linux" diff --git a/packages/compositor-linux-arm64-musl/package.json b/packages/compositor-linux-arm64-musl/package.json index a006b2d6b0c..94449cc0068 100644 --- a/packages/compositor-linux-arm64-musl/package.json +++ b/packages/compositor-linux-arm64-musl/package.json @@ -2,7 +2,7 @@ "repository": { "url": "https://github.com/remotion-dev/remotion/tree/main/packages/compositor-linux-arm64-musl" }, - "version": "4.0.424", + "version": "4.0.425", "name": "@remotion/compositor-linux-arm64-musl", "os": [ "linux" diff --git a/packages/compositor-linux-x64-gnu/package.json b/packages/compositor-linux-x64-gnu/package.json index 1e2f49cb6fb..37859e8fc86 100644 --- a/packages/compositor-linux-x64-gnu/package.json +++ b/packages/compositor-linux-x64-gnu/package.json @@ -2,7 +2,7 @@ "repository": { "url": "https://github.com/remotion-dev/remotion/tree/main/packages/compositor-linux-x64-gnu" }, - "version": "4.0.424", + "version": "4.0.425", "name": "@remotion/compositor-linux-x64-gnu", "os": [ "linux" diff --git a/packages/compositor-linux-x64-musl/package.json b/packages/compositor-linux-x64-musl/package.json index c104858d2bb..fee07a76da0 100644 --- a/packages/compositor-linux-x64-musl/package.json +++ b/packages/compositor-linux-x64-musl/package.json @@ -2,7 +2,7 @@ "repository": { "url": "https://github.com/remotion-dev/remotion/tree/main/packages/compositor-linux-x64-musl" }, - "version": "4.0.424", + "version": "4.0.425", "name": "@remotion/compositor-linux-x64-musl", "os": [ "linux" diff --git a/packages/compositor-win32-x64-msvc/package.json b/packages/compositor-win32-x64-msvc/package.json index c911106f965..50cd4bf858d 100644 --- a/packages/compositor-win32-x64-msvc/package.json +++ b/packages/compositor-win32-x64-msvc/package.json @@ -2,7 +2,7 @@ "repository": { "url": "https://github.com/remotion-dev/remotion/tree/main/packages/compositor-win32-x64-msvc" }, - "version": "4.0.424", + "version": "4.0.425", "name": "@remotion/compositor-win32-x64-msvc", "os": [ "win32" diff --git a/packages/compositor/package.json b/packages/compositor/package.json index a30e8432641..141658798f8 100644 --- a/packages/compositor/package.json +++ b/packages/compositor/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/compositor" }, "name": "@remotion/compositor", - "version": "4.0.424", + "version": "4.0.425", "description": "Rust binary for Remotion", "sideEffects": false, "scripts": { diff --git a/packages/convert/package.json b/packages/convert/package.json index b7299190817..ecc006f83a7 100644 --- a/packages/convert/package.json +++ b/packages/convert/package.json @@ -1,6 +1,6 @@ { "name": "@remotion/convert", - "version": "4.0.424", + "version": "4.0.425", "private": true, "sideEffects": false, "type": "module", diff --git a/packages/core/package.json b/packages/core/package.json index 8919b78e869..2f927016765 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/core" }, "name": "remotion", - "version": "4.0.424", + "version": "4.0.425", "description": "Make videos programmatically", "main": "dist/cjs/index.js", "types": "dist/cjs/index.d.ts", diff --git a/packages/core/src/version.ts b/packages/core/src/version.ts index 88dac71b7ef..adcf509616b 100644 --- a/packages/core/src/version.ts +++ b/packages/core/src/version.ts @@ -5,4 +5,4 @@ * @see [Documentation](https://remotion.dev/docs/version) * @returns {string} The current version of the remotion package */ -export const VERSION = '4.0.424'; +export const VERSION = '4.0.425'; diff --git a/packages/create-video/package.json b/packages/create-video/package.json index a6f1589af7c..56cb516b12f 100644 --- a/packages/create-video/package.json +++ b/packages/create-video/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/create-video" }, "name": "create-video", - "version": "4.0.424", + "version": "4.0.425", "description": "Create a new Remotion project", "main": "dist/index.js", "bin": { diff --git a/packages/design/package.json b/packages/design/package.json index 306679038dd..e282cf2ed0a 100644 --- a/packages/design/package.json +++ b/packages/design/package.json @@ -1,6 +1,6 @@ { "name": "@remotion/design", - "version": "4.0.424", + "version": "4.0.425", "main": "dist/index.js", "types": "dist/index.d.ts", "module": "dist/esm/index.mjs", diff --git a/packages/discord-poster/package.json b/packages/discord-poster/package.json index 07bd6fe5058..860f6c81541 100644 --- a/packages/discord-poster/package.json +++ b/packages/discord-poster/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/discord-poster" }, "name": "@remotion/discord-poster", - "version": "4.0.424", + "version": "4.0.425", "license": "SEE LICENSE IN LICENSE.md", "type": "module", "scripts": { diff --git a/packages/docs/package.json b/packages/docs/package.json index 0da9805daa7..ab5c9d9b2cc 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -4,7 +4,7 @@ }, "name": "docs", "private": true, - "version": "4.0.424", + "version": "4.0.425", "scripts": { "formatting": "prettier src --check", "docusaurus": "docusaurus", diff --git a/packages/docusaurus-plugin/package.json b/packages/docusaurus-plugin/package.json index b930c40ca65..5bf6790f073 100644 --- a/packages/docusaurus-plugin/package.json +++ b/packages/docusaurus-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@remotion/docusaurus-plugin", - "version": "4.0.424", + "version": "4.0.425", "main": "dist/index.js", "types": "dist/index.d.ts", "sideEffects": false, diff --git a/packages/enable-scss/package.json b/packages/enable-scss/package.json index 3e4aa0da594..f41e01f3302 100644 --- a/packages/enable-scss/package.json +++ b/packages/enable-scss/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/enable-scss" }, "name": "@remotion/enable-scss", - "version": "4.0.424", + "version": "4.0.425", "description": "Enable SCSS support in Remotion", "main": "dist/cjs/index.js", "types": "dist/cjs/index.d.ts", diff --git a/packages/eslint-config-flat/package.json b/packages/eslint-config-flat/package.json index 5fd19b631cf..895fccb12a7 100644 --- a/packages/eslint-config-flat/package.json +++ b/packages/eslint-config-flat/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/eslint-config-flat" }, "name": "@remotion/eslint-config-flat", - "version": "4.0.424", + "version": "4.0.425", "description": "Default configuration for Remotion templates (ESLint >= 9)", "main": "dist/esm/index.mjs", "type": "module", diff --git a/packages/eslint-config-internal/package.json b/packages/eslint-config-internal/package.json index 1fba753f471..b7d5e5996ff 100644 --- a/packages/eslint-config-internal/package.json +++ b/packages/eslint-config-internal/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/eslint-config-internal" }, "name": "@remotion/eslint-config-internal", - "version": "4.0.424", + "version": "4.0.425", "license": "SEE LICENSE IN LICENSE.md", "main": "dist/index.js", "scripts": { diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json index 90eda3ea608..ecce80713bf 100644 --- a/packages/eslint-config/package.json +++ b/packages/eslint-config/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/eslint-config" }, "name": "@remotion/eslint-config", - "version": "4.0.424", + "version": "4.0.425", "description": "Default configuration for Remotion templates (ESLint <= 8)", "main": "dist/index.js", "files": [ diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index a225cca0eb6..645e776c49d 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/eslint-plugin" }, "name": "@remotion/eslint-plugin", - "version": "4.0.424", + "version": "4.0.425", "description": "Rules for writing Remotion code", "scripts": { "test": "node src/tests/execute.mjs", diff --git a/packages/example-videos/package.json b/packages/example-videos/package.json index 92e8eba53ec..65268748ed7 100644 --- a/packages/example-videos/package.json +++ b/packages/example-videos/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/example-videos" }, "name": "@remotion/example-videos", - "version": "4.0.424", + "version": "4.0.425", "main": "dist/index.js", "types": "dist/index.d.ts", "sideEffects": false, diff --git a/packages/example-without-zod/package.json b/packages/example-without-zod/package.json index 82aa24d4acd..531c75399df 100644 --- a/packages/example-without-zod/package.json +++ b/packages/example-without-zod/package.json @@ -4,7 +4,7 @@ }, "name": "@remotion/example-without-zod", "private": true, - "version": "4.0.424", + "version": "4.0.425", "license": "SEE LICENSE IN LICENSE.md", "author": "Jonny Burger", "main": "dist/index.js", diff --git a/packages/example/package.json b/packages/example/package.json index c40ebdf976a..bbad4ee9ab5 100644 --- a/packages/example/package.json +++ b/packages/example/package.json @@ -4,7 +4,7 @@ }, "name": "@remotion/example", "private": true, - "version": "4.0.424", + "version": "4.0.425", "license": "SEE LICENSE IN LICENSE.md", "author": "Jonny Burger", "main": "dist/index.js", diff --git a/packages/fonts/package.json b/packages/fonts/package.json index 4fc60bcaf59..137c12f3c11 100644 --- a/packages/fonts/package.json +++ b/packages/fonts/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/fonts" }, "name": "@remotion/fonts", - "version": "4.0.424", + "version": "4.0.425", "description": "Helpers for loading local fonts into Remotion", "main": "dist/cjs/index.js", "types": "dist/cjs/index.d.ts", diff --git a/packages/gif/package.json b/packages/gif/package.json index ef78c646300..a9da6c32dc0 100644 --- a/packages/gif/package.json +++ b/packages/gif/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/gif" }, "name": "@remotion/gif", - "version": "4.0.424", + "version": "4.0.425", "description": "Embed GIFs in a Remotion video", "sideEffects": false, "bugs": { diff --git a/packages/google-fonts/package.json b/packages/google-fonts/package.json index 7794d5ca605..d1c281fe9ed 100644 --- a/packages/google-fonts/package.json +++ b/packages/google-fonts/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/google-fonts" }, "name": "@remotion/google-fonts", - "version": "4.0.424", + "version": "4.0.425", "description": "Use Google Fonts in Remotion", "main": "dist/cjs/index.js", "module": "dist/esm/index.mjs", @@ -620,6 +620,18 @@ "Besley": [ "dist/cjs/Besley.d.ts" ], + "BetaniaPatmos": [ + "dist/cjs/BetaniaPatmos.d.ts" + ], + "BetaniaPatmosGDL": [ + "dist/cjs/BetaniaPatmosGDL.d.ts" + ], + "BetaniaPatmosIn": [ + "dist/cjs/BetaniaPatmosIn.d.ts" + ], + "BetaniaPatmosInGDL": [ + "dist/cjs/BetaniaPatmosInGDL.d.ts" + ], "BethEllen": [ "dist/cjs/BethEllen.d.ts" ], @@ -1826,6 +1838,9 @@ "Gurajada": [ "dist/cjs/Gurajada.d.ts" ], + "GveretLevin": [ + "dist/cjs/GveretLevin.d.ts" + ], "Gwendolyn": [ "dist/cjs/Gwendolyn.d.ts" ], @@ -2015,6 +2030,9 @@ "Iceland": [ "dist/cjs/Iceland.d.ts" ], + "Idiqlat": [ + "dist/cjs/Idiqlat.d.ts" + ], "Imbue": [ "dist/cjs/Imbue.d.ts" ], @@ -4199,6 +4217,9 @@ "RampartOne": [ "dist/cjs/RampartOne.d.ts" ], + "Ramsina": [ + "dist/cjs/Ramsina.d.ts" + ], "Ranchers": [ "dist/cjs/Ranchers.d.ts" ], diff --git a/packages/google-fonts/scripts/google-fonts.ts b/packages/google-fonts/scripts/google-fonts.ts index d2483d78258..c1e3abca60c 100644 --- a/packages/google-fonts/scripts/google-fonts.ts +++ b/packages/google-fonts/scripts/google-fonts.ts @@ -4746,6 +4746,62 @@ export const googleFonts: Font[] = [ kind: 'webfonts#webfont', menu: 'https://fonts.gstatic.com/s/besley/v22/PlIhFlO1MaNwaNGWUC92IOH_mtG4fbbBedViFQ.woff2', }, + { + family: 'Betania Patmos', + variants: ['regular'], + subsets: ['latin', 'latin-ext'], + version: 'v2', + lastModified: '2026-02-17', + files: { + regular: + 'https://fonts.gstatic.com/s/betaniapatmos/v2/9oRXNYMTrDYnkuhOrHhyQracaunGNbEH8qpU.woff2', + }, + category: 'handwriting', + kind: 'webfonts#webfont', + menu: 'https://fonts.gstatic.com/s/betaniapatmos/v2/9oRXNYMTrDYnkuhOrHhyQracatnCP7A.woff2', + }, + { + family: 'Betania Patmos GDL', + variants: ['regular'], + subsets: ['latin', 'latin-ext'], + version: 'v2', + lastModified: '2026-02-17', + files: { + regular: + 'https://fonts.gstatic.com/s/betaniapatmosgdl/v2/-nFhOHE6_uoR4VYoynWSh_bKTCFIT7tx0vr352np3Q.woff2', + }, + category: 'handwriting', + kind: 'webfonts#webfont', + menu: 'https://fonts.gstatic.com/s/betaniapatmosgdl/v2/-nFhOHE6_uoR4VYoynWSh_bKTCFIT7tB1vD2.woff2', + }, + { + family: 'Betania Patmos In', + variants: ['regular'], + subsets: ['latin', 'latin-ext'], + version: 'v2', + lastModified: '2026-02-17', + files: { + regular: + 'https://fonts.gstatic.com/s/betaniapatmosin/v2/t5t6IQYdPp6dFAyhcz3W2MuHvhmmxLuDUBsTrn5P.woff2', + }, + category: 'handwriting', + kind: 'webfonts#webfont', + menu: 'https://fonts.gstatic.com/s/betaniapatmosin/v2/t5t6IQYdPp6dFAyhcz3W2MuHvhmmxIuHWho.woff2', + }, + { + family: 'Betania Patmos In GDL', + variants: ['regular'], + subsets: ['latin', 'latin-ext'], + version: 'v2', + lastModified: '2026-02-17', + files: { + regular: + 'https://fonts.gstatic.com/s/betaniapatmosingdl/v2/va9Y4lzJyMBdF8kOQbYe5MWhMhe2GnyJ0wb2GFPMgLIQTg.woff2', + }, + category: 'handwriting', + kind: 'webfonts#webfont', + menu: 'https://fonts.gstatic.com/s/betaniapatmosingdl/v2/va9Y4lzJyMBdF8kOQbYe5MWhMhe2GnyJ0wbGHFnN.woff2', + }, { family: 'Beth Ellen', variants: ['regular'], @@ -14127,6 +14183,20 @@ export const googleFonts: Font[] = [ kind: 'webfonts#webfont', menu: 'https://fonts.gstatic.com/s/gurajada/v22/FwZY7-Qx308m-l-0Ke6B6Mk.woff2', }, + { + family: 'Gveret Levin', + variants: ['regular'], + subsets: ['hebrew', 'latin'], + version: 'v4', + lastModified: '2026-02-17', + files: { + regular: + 'https://fonts.gstatic.com/s/gveretlevin/v4/0QInMXVI5YS9Rnn7ar449p-O9pbS8ANesw.woff2', + }, + category: 'handwriting', + kind: 'webfonts#webfont', + menu: 'https://fonts.gstatic.com/s/gveretlevin/v4/0QInMXVI5YS9Rnn7ar449p--8pzT.woff2', + }, { family: 'Gwendolyn', variants: ['regular', '700'], @@ -15643,6 +15713,24 @@ export const googleFonts: Font[] = [ kind: 'webfonts#webfont', menu: 'https://fonts.gstatic.com/s/iceland/v22/rax9HiuFsdMNOnWPaK1MAQ.woff2', }, + { + family: 'Idiqlat', + variants: ['200', '300', 'regular'], + subsets: ['latin', 'syriac'], + version: 'v2', + lastModified: '2026-02-17', + files: { + '200': + 'https://fonts.gstatic.com/s/idiqlat/v2/YA9Wr0ef50XNM6kiAOrKkiQqs7GtlvY.woff2', + '300': + 'https://fonts.gstatic.com/s/idiqlat/v2/YA9Wr0ef50XNM6kiAI7JkiQqs7GtlvY.woff2', + regular: + 'https://fonts.gstatic.com/s/idiqlat/v2/YA9Tr0ef50XNM6kiOCfhtikBr7g.woff2', + }, + category: 'serif', + kind: 'webfonts#webfont', + menu: 'https://fonts.gstatic.com/s/idiqlat/v2/YA9Tr0ef50XNM6kiCCPrtw.woff2', + }, { family: 'Imbue', variants: [ @@ -20569,15 +20657,15 @@ export const googleFonts: Font[] = [ family: 'Ma Shan Zheng', variants: ['regular'], subsets: ['chinese-simplified', 'latin'], - version: 'v14', - lastModified: '2025-09-08', + version: 'v17', + lastModified: '2026-02-17', files: { regular: - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMHsDIRSfr0.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMHsDIRSfr0.woff2', }, category: 'handwriting', kind: 'webfonts#webfont', - menu: 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXadMXmDQ.woff2', + menu: 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXadMXmDQ.woff2', }, { family: 'Macondo', @@ -21321,105 +21409,105 @@ export const googleFonts: Font[] = [ family: 'Material Symbols', variants: ['100', '200', '300', 'regular', '500', '600', '700'], subsets: ['latin'], - version: 'v42', - lastModified: '2026-02-10', + version: 'v43', + lastModified: '2026-02-17', files: { '100': - 'https://fonts.gstatic.com/s/materialsymbols/v42/d6kSkb-sS9m3-i1LgQNcsFOOuLQXvG559b5GLMxCWRtThFK5gn7xw7XblIl2peTfMb7ONaa2_wzcUHR1Ukiw2RYw2vadH3BFk0G4701x-cU0BaNVXEHuQLn3PT2vOA.woff2', + 'https://fonts.gstatic.com/s/materialsymbols/v43/d6kSkb-sS9m3-i1LgQNcsFOOuLQXvG559b5GLMxCWRtThFK5gn7xw7XblIl2peTfMb7ONaa2_wzcUHR1Ukiw2RYw2vadH3BFk0G4701x-cU0BaNVXEHuQLn3PT2vOA.woff2', '200': - 'https://fonts.gstatic.com/s/materialsymbols/v42/d6kSkb-sS9m3-i1LgQNcsFOOuLQXvG559b5GLMxCWRtThFK5gn7xw7XblIl2peTfMb7ONaa2_wzcUHR1Ukiw2RYw2vadH3BFk0G4701x-cU0BaNV3EDuQLn3PT2vOA.woff2', + 'https://fonts.gstatic.com/s/materialsymbols/v43/d6kSkb-sS9m3-i1LgQNcsFOOuLQXvG559b5GLMxCWRtThFK5gn7xw7XblIl2peTfMb7ONaa2_wzcUHR1Ukiw2RYw2vadH3BFk0G4701x-cU0BaNV3EDuQLn3PT2vOA.woff2', '300': - 'https://fonts.gstatic.com/s/materialsymbols/v42/d6kSkb-sS9m3-i1LgQNcsFOOuLQXvG559b5GLMxCWRtThFK5gn7xw7XblIl2peTfMb7ONaa2_wzcUHR1Ukiw2RYw2vadH3BFk0G4701x-cU0BaNVAkDuQLn3PT2vOA.woff2', + 'https://fonts.gstatic.com/s/materialsymbols/v43/d6kSkb-sS9m3-i1LgQNcsFOOuLQXvG559b5GLMxCWRtThFK5gn7xw7XblIl2peTfMb7ONaa2_wzcUHR1Ukiw2RYw2vadH3BFk0G4701x-cU0BaNVAkDuQLn3PT2vOA.woff2', '500': - 'https://fonts.gstatic.com/s/materialsymbols/v42/d6kSkb-sS9m3-i1LgQNcsFOOuLQXvG559b5GLMxCWRtThFK5gn7xw7XblIl2peTfMb7ONaa2_wzcUHR1Ukiw2RYw2vadH3BFk0G4701x-cU0BaNVbkDuQLn3PT2vOA.woff2', + 'https://fonts.gstatic.com/s/materialsymbols/v43/d6kSkb-sS9m3-i1LgQNcsFOOuLQXvG559b5GLMxCWRtThFK5gn7xw7XblIl2peTfMb7ONaa2_wzcUHR1Ukiw2RYw2vadH3BFk0G4701x-cU0BaNVbkDuQLn3PT2vOA.woff2', '600': - 'https://fonts.gstatic.com/s/materialsymbols/v42/d6kSkb-sS9m3-i1LgQNcsFOOuLQXvG559b5GLMxCWRtThFK5gn7xw7XblIl2peTfMb7ONaa2_wzcUHR1Ukiw2RYw2vadH3BFk0G4701x-cU0BaNVgkfuQLn3PT2vOA.woff2', + 'https://fonts.gstatic.com/s/materialsymbols/v43/d6kSkb-sS9m3-i1LgQNcsFOOuLQXvG559b5GLMxCWRtThFK5gn7xw7XblIl2peTfMb7ONaa2_wzcUHR1Ukiw2RYw2vadH3BFk0G4701x-cU0BaNVgkfuQLn3PT2vOA.woff2', '700': - 'https://fonts.gstatic.com/s/materialsymbols/v42/d6kSkb-sS9m3-i1LgQNcsFOOuLQXvG559b5GLMxCWRtThFK5gn7xw7XblIl2peTfMb7ONaa2_wzcUHR1Ukiw2RYw2vadH3BFk0G4701x-cU0BaNVu0fuQLn3PT2vOA.woff2', + 'https://fonts.gstatic.com/s/materialsymbols/v43/d6kSkb-sS9m3-i1LgQNcsFOOuLQXvG559b5GLMxCWRtThFK5gn7xw7XblIl2peTfMb7ONaa2_wzcUHR1Ukiw2RYw2vadH3BFk0G4701x-cU0BaNVu0fuQLn3PT2vOA.woff2', regular: - 'https://fonts.gstatic.com/s/materialsymbols/v42/d6kSkb-sS9m3-i1LgQNcsFOOuLQXvG559b5GLMxCWRtThFK5gn7xw7XblIl2peTfMb7ONaa2_wzcUHR1Ukiw2RYw2vadH3BFk0G4701x-cU0BaNVXEDuQLn3PT2vOA.woff2', + 'https://fonts.gstatic.com/s/materialsymbols/v43/d6kSkb-sS9m3-i1LgQNcsFOOuLQXvG559b5GLMxCWRtThFK5gn7xw7XblIl2peTfMb7ONaa2_wzcUHR1Ukiw2RYw2vadH3BFk0G4701x-cU0BaNVXEDuQLn3PT2vOA.woff2', }, category: 'monospace', kind: 'webfonts#webfont', - menu: 'https://fonts.gstatic.com/s/materialsymbols/v42/d6kSkb-sS9m3-i1LgQNcsFOOuLQXvG559b5GLMxCWRtThFK5gn7xw7XblIl2peTfMb7ONaa2_wzcUHR1Ukiw2RYw2vadH3BFk0G4701x-cU0BaNVXEDeRLP2.woff2', + menu: 'https://fonts.gstatic.com/s/materialsymbols/v43/d6kSkb-sS9m3-i1LgQNcsFOOuLQXvG559b5GLMxCWRtThFK5gn7xw7XblIl2peTfMb7ONaa2_wzcUHR1Ukiw2RYw2vadH3BFk0G4701x-cU0BaNVXEDeRLP2.woff2', }, { family: 'Material Symbols Outlined', variants: ['100', '200', '300', 'regular', '500', '600', '700'], subsets: ['latin'], - version: 'v314', - lastModified: '2026-02-10', + version: 'v315', + lastModified: '2026-02-17', files: { '100': - 'https://fonts.gstatic.com/s/materialsymbolsoutlined/v314/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHeejbd5zrTgt.woff2', + 'https://fonts.gstatic.com/s/materialsymbolsoutlined/v315/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHeejbd5zrTgt.woff2', '200': - 'https://fonts.gstatic.com/s/materialsymbolsoutlined/v314/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDAvHOejbd5zrTgt.woff2', + 'https://fonts.gstatic.com/s/materialsymbolsoutlined/v315/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDAvHOejbd5zrTgt.woff2', '300': - 'https://fonts.gstatic.com/s/materialsymbolsoutlined/v314/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDDxHOejbd5zrTgt.woff2', + 'https://fonts.gstatic.com/s/materialsymbolsoutlined/v315/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDDxHOejbd5zrTgt.woff2', '500': - 'https://fonts.gstatic.com/s/materialsymbolsoutlined/v314/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCdHOejbd5zrTgt.woff2', + 'https://fonts.gstatic.com/s/materialsymbolsoutlined/v315/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCdHOejbd5zrTgt.woff2', '600': - 'https://fonts.gstatic.com/s/materialsymbolsoutlined/v314/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDBxG-ejbd5zrTgt.woff2', + 'https://fonts.gstatic.com/s/materialsymbolsoutlined/v315/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDBxG-ejbd5zrTgt.woff2', '700': - 'https://fonts.gstatic.com/s/materialsymbolsoutlined/v314/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDBIG-ejbd5zrTgt.woff2', + 'https://fonts.gstatic.com/s/materialsymbolsoutlined/v315/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDBIG-ejbd5zrTgt.woff2', regular: - 'https://fonts.gstatic.com/s/materialsymbolsoutlined/v314/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOejbd5zrTgt.woff2', + 'https://fonts.gstatic.com/s/materialsymbolsoutlined/v315/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOejbd5zrTgt.woff2', }, category: 'monospace', kind: 'webfonts#webfont', - menu: 'https://fonts.gstatic.com/s/materialsymbolsoutlined/v314/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHNenZ98.woff2', + menu: 'https://fonts.gstatic.com/s/materialsymbolsoutlined/v315/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHNenZ98.woff2', }, { family: 'Material Symbols Rounded', variants: ['100', '200', '300', 'regular', '500', '600', '700'], subsets: ['latin'], - version: 'v316', - lastModified: '2026-02-10', + version: 'v317', + lastModified: '2026-02-17', files: { '100': - 'https://fonts.gstatic.com/s/materialsymbolsrounded/v316/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rIekXxeJKJBjAa8.woff2', + 'https://fonts.gstatic.com/s/materialsymbolsrounded/v317/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rIekXxeJKJBjAa8.woff2', '200': - 'https://fonts.gstatic.com/s/materialsymbolsrounded/v316/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rAelXxeJKJBjAa8.woff2', + 'https://fonts.gstatic.com/s/materialsymbolsrounded/v317/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rAelXxeJKJBjAa8.woff2', '300': - 'https://fonts.gstatic.com/s/materialsymbolsrounded/v316/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rNmlXxeJKJBjAa8.woff2', + 'https://fonts.gstatic.com/s/materialsymbolsrounded/v317/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rNmlXxeJKJBjAa8.woff2', '500': - 'https://fonts.gstatic.com/s/materialsymbolsrounded/v316/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rLWlXxeJKJBjAa8.woff2', + 'https://fonts.gstatic.com/s/materialsymbolsrounded/v317/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rLWlXxeJKJBjAa8.woff2', '600': - 'https://fonts.gstatic.com/s/materialsymbolsrounded/v316/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rFmiXxeJKJBjAa8.woff2', + 'https://fonts.gstatic.com/s/materialsymbolsrounded/v317/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rFmiXxeJKJBjAa8.woff2', '700': - 'https://fonts.gstatic.com/s/materialsymbolsrounded/v316/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rGCiXxeJKJBjAa8.woff2', + 'https://fonts.gstatic.com/s/materialsymbolsrounded/v317/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rGCiXxeJKJBjAa8.woff2', regular: - 'https://fonts.gstatic.com/s/materialsymbolsrounded/v316/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rIelXxeJKJBjAa8.woff2', + 'https://fonts.gstatic.com/s/materialsymbolsrounded/v317/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rIelXxeJKJBjAa8.woff2', }, category: 'monospace', kind: 'webfonts#webfont', - menu: 'https://fonts.gstatic.com/s/materialsymbolsrounded/v316/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rIelbxODKQ.woff2', + menu: 'https://fonts.gstatic.com/s/materialsymbolsrounded/v317/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rIelbxODKQ.woff2', }, { family: 'Material Symbols Sharp', variants: ['100', '200', '300', 'regular', '500', '600', '700'], subsets: ['latin'], - version: 'v311', - lastModified: '2026-02-10', + version: 'v312', + lastModified: '2026-02-17', files: { '100': - 'https://fonts.gstatic.com/s/materialsymbolssharp/v311/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxOLozCLJ1H7-knk.woff2', + 'https://fonts.gstatic.com/s/materialsymbolssharp/v312/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxOLozCLJ1H7-knk.woff2', '200': - 'https://fonts.gstatic.com/s/materialsymbolssharp/v311/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxMLojCLJ1H7-knk.woff2', + 'https://fonts.gstatic.com/s/materialsymbolssharp/v312/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxMLojCLJ1H7-knk.woff2', '300': - 'https://fonts.gstatic.com/s/materialsymbolssharp/v311/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxPVojCLJ1H7-knk.woff2', + 'https://fonts.gstatic.com/s/materialsymbolssharp/v312/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxPVojCLJ1H7-knk.woff2', '500': - 'https://fonts.gstatic.com/s/materialsymbolssharp/v311/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxO5ojCLJ1H7-knk.woff2', + 'https://fonts.gstatic.com/s/materialsymbolssharp/v312/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxO5ojCLJ1H7-knk.woff2', '600': - 'https://fonts.gstatic.com/s/materialsymbolssharp/v311/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxNVpTCLJ1H7-knk.woff2', + 'https://fonts.gstatic.com/s/materialsymbolssharp/v312/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxNVpTCLJ1H7-knk.woff2', '700': - 'https://fonts.gstatic.com/s/materialsymbolssharp/v311/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxNspTCLJ1H7-knk.woff2', + 'https://fonts.gstatic.com/s/materialsymbolssharp/v312/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxNspTCLJ1H7-knk.woff2', regular: - 'https://fonts.gstatic.com/s/materialsymbolssharp/v311/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxOLojCLJ1H7-knk.woff2', + 'https://fonts.gstatic.com/s/materialsymbolssharp/v312/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxOLojCLJ1H7-knk.woff2', }, category: 'monospace', kind: 'webfonts#webfont', - menu: 'https://fonts.gstatic.com/s/materialsymbolssharp/v311/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxOLogCPLVA.woff2', + menu: 'https://fonts.gstatic.com/s/materialsymbolssharp/v312/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxOLogCPLVA.woff2', }, { family: 'Maven Pro', @@ -23822,15 +23910,15 @@ export const googleFonts: Font[] = [ family: 'Noto Color Emoji', variants: ['regular'], subsets: ['emoji'], - version: 'v38', - lastModified: '2026-01-07', + version: 'v39', + lastModified: '2026-02-17', files: { regular: - 'https://fonts.gstatic.com/s/notocoloremoji/v38/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabts79iz64w.woff2', + 'https://fonts.gstatic.com/s/notocoloremoji/v39/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabts79iz64w.woff2', }, category: 'sans-serif', kind: 'webfonts#webfont', - menu: 'https://fonts.gstatic.com/s/notocoloremoji/v38/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFWb9m7g.woff2', + menu: 'https://fonts.gstatic.com/s/notocoloremoji/v39/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFWb9m7g.woff2', colorCapabilities: ['COLRv1', 'SVG'], }, { @@ -34177,6 +34265,20 @@ export const googleFonts: Font[] = [ kind: 'webfonts#webfont', menu: 'https://fonts.gstatic.com/s/rampartone/v13/K2F1fZFGl_JSR1tAWNG9R5qhJy8.woff2', }, + { + family: 'Ramsina', + variants: ['regular'], + subsets: ['latin', 'syriac'], + version: 'v2', + lastModified: '2026-02-17', + files: { + regular: + 'https://fonts.gstatic.com/s/ramsina/v2/daaYSTE-LGmCbhP9-Ls1Q4mMrSg.woff2', + }, + category: 'serif', + kind: 'webfonts#webfont', + menu: 'https://fonts.gstatic.com/s/ramsina/v2/daaYSTE-LGmCbhP9yL8_Qg.woff2', + }, { family: 'Ranchers', variants: ['regular'], @@ -43236,15 +43338,15 @@ export const googleFonts: Font[] = [ family: 'ZCOOL KuaiLe', variants: ['regular'], subsets: ['chinese-simplified', 'latin'], - version: 'v20', - lastModified: '2025-09-16', + version: 'v22', + lastModified: '2026-02-17', files: { regular: - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo4zzoXhC2g.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo4zzoXhC2g.woff2', }, category: 'sans-serif', kind: 'webfonts#webfont', - menu: 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2mp4by.woff2', + menu: 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2mp4by.woff2', }, { family: 'ZCOOL QingKe HuangYou', diff --git a/packages/google-fonts/scripts/incompatible-fonts.ts b/packages/google-fonts/scripts/incompatible-fonts.ts index 6bff67c45b9..9a957ff74d6 100644 --- a/packages/google-fonts/scripts/incompatible-fonts.ts +++ b/packages/google-fonts/scripts/incompatible-fonts.ts @@ -1,120 +1,120 @@ export const incompatibleFonts = [ - "Chiron GoRound TC", "Chiron Hei HK", "Chiron Sung HK", + "Chiron GoRound TC", "Linefont", - "Material Icons Sharp", + "Material Icons", "Material Icons Outlined", "Material Icons Round", - "Material Icons", + "Material Icons Sharp", "Material Icons Two Tone", "Material Symbols", "Material Symbols Rounded", - "Material Symbols Sharp", "Material Symbols Outlined", + "Material Symbols Sharp", "Playwrite AR", "Playwrite AR Guides", "Playwrite AT", "Playwrite AT Guides", - "Playwrite AU QLD Guides", "Playwrite AU NSW Guides", - "Playwrite AU SA", + "Playwrite AU QLD", "Playwrite AU NSW", + "Playwrite AU QLD Guides", + "Playwrite AU SA", "Playwrite AU SA Guides", - "Playwrite AU QLD", "Playwrite AU TAS", "Playwrite AU TAS Guides", - "Playwrite AU VIC", - "Playwrite BE VLG", "Playwrite AU VIC Guides", "Playwrite BE VLG Guides", + "Playwrite AU VIC", + "Playwrite BE WAL", "Playwrite BE WAL Guides", + "Playwrite BE VLG", "Playwrite BR", - "Playwrite BE WAL", - "Playwrite BR Guides", "Playwrite CA", - "Playwrite CL", + "Playwrite BR Guides", "Playwrite CA Guides", - "Playwrite CL Guides", - "Playwrite CU", + "Playwrite CL", "Playwrite CO Guides", + "Playwrite CO", + "Playwrite CU", "Playwrite CU Guides", + "Playwrite CZ Guides", "Playwrite CZ", "Playwrite DE Grund", - "Playwrite CZ Guides", + "Playwrite CL Guides", "Playwrite DE Grund Guides", - "Playwrite DE LA", - "Playwrite CO", "Playwrite DE LA Guides", "Playwrite DE SAS", + "Playwrite DE LA", + "Playwrite DE SAS Guides", "Playwrite DE VA", "Playwrite DE VA Guides", "Playwrite DK Loopet", - "Playwrite DK Loopet Guides", - "Playwrite DE SAS Guides", - "Playwrite DK Uloopet Guides", "Playwrite DK Uloopet", - "Playwrite ES", - "Playwrite ES Deco", - "Playwrite ES Deco Guides", - "Playwrite ES Guides", + "Playwrite DK Uloopet Guides", + "Playwrite DK Loopet Guides", "Playwrite FR Moderne", + "Playwrite ES", "Playwrite FR Moderne Guides", "Playwrite FR Trad", + "Playwrite ES Guides", "Playwrite FR Trad Guides", - "Playwrite GB J", "Playwrite GB J Guides", "Playwrite GB S", - "Playwrite HR", + "Playwrite GB J", "Playwrite GB S Guides", "Playwrite HR Guides", - "Playwrite HR Lijeva", + "Playwrite HR", "Playwrite HR Lijeva Guides", - "Playwrite HU", "Playwrite HU Guides", + "Playwrite HR Lijeva", + "Playwrite HU", + "Playwrite ID", "Playwrite ID Guides", "Playwrite IE", "Playwrite IE Guides", - "Playwrite IN", - "Playwrite ID", - "Playwrite IS Guides", "Playwrite IN Guides", "Playwrite IS", + "Playwrite IS Guides", "Playwrite IT Moderna", "Playwrite IT Moderna Guides", "Playwrite IT Trad", + "Playwrite ES Deco", + "Playwrite IN", + "Playwrite MX Guides", "Playwrite MX", - "Playwrite IT Trad Guides", + "Playwrite NG Modern", + "Playwrite NG Modern Guides", + "Playwrite NO", "Playwrite NL Guides", "Playwrite NL", - "Playwrite NO", "Playwrite NZ", "Playwrite NO Guides", - "Playwrite MX Guides", - "Playwrite NG Modern Guides", - "Playwrite NG Modern", - "Playwrite NZ Basic", - "Playwrite PL Guides", "Playwrite NZ Guides", + "Playwrite PE", "Playwrite PE Guides", "Playwrite NZ Basic Guides", - "Playwrite PE", + "Playwrite NZ Basic", "Playwrite PL", - "Playwrite PT", + "Playwrite PL Guides", "Playwrite PT Guides", - "Playwrite TZ", - "Playwrite SK Guides", - "Playwrite RO Guides", + "Playwrite PT", + "Playwrite RO", "Playwrite SK", - "Playwrite TZ Guides", + "Playwrite RO Guides", + "Playwrite SK Guides", + "Playwrite TZ", "Playwrite US Modern", - "Playwrite US Trad", - "Playwrite RO", "Playwrite US Modern Guides", + "Playwrite ES Deco Guides", + "Playwrite US Trad", + "Playwrite IT Trad Guides", "Playwrite US Trad Guides", "Playwrite VN", + "Playwrite TZ Guides", "Playwrite VN Guides", - "Playwrite ZA Guides", "Playwrite ZA", + "Playwrite ZA Guides", "Wavefont" ]; \ No newline at end of file diff --git a/packages/google-fonts/src/BetaniaPatmos.ts b/packages/google-fonts/src/BetaniaPatmos.ts new file mode 100644 index 00000000000..036da85a0f0 --- /dev/null +++ b/packages/google-fonts/src/BetaniaPatmos.ts @@ -0,0 +1,46 @@ +import {loadFonts} from './base'; + +export const getInfo = () => ({ + fontFamily: 'Betania Patmos', + importName: 'BetaniaPatmos', + version: 'v2', + url: 'https://fonts.googleapis.com/css2?family=Betania+Patmos:ital,wght@0,400', + unicodeRanges: { + 'latin-ext': + 'U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF', + latin: + 'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD', + }, + fonts: { + normal: { + '400': { + 'latin-ext': + 'https://fonts.gstatic.com/s/betaniapatmos/v2/9oRXNYMTrDYnkuhOrHhyQracatnKP7A38g.woff2', + latin: + 'https://fonts.gstatic.com/s/betaniapatmos/v2/9oRXNYMTrDYnkuhOrHhyQracatnEP7A.woff2', + }, + }, + }, + subsets: ['latin', 'latin-ext'], +}); + +export const fontFamily = 'Betania Patmos' as const; + +type Variants = { + normal: { + weights: '400'; + subsets: 'latin' | 'latin-ext'; + }; +}; + +export const loadFont = ( + style?: T, + options?: { + weights?: Variants[T]['weights'][]; + subsets?: Variants[T]['subsets'][]; + document?: Document; + ignoreTooManyRequestsWarning?: boolean; + }, +) => { + return loadFonts(getInfo(), style, options); +}; diff --git a/packages/google-fonts/src/BetaniaPatmosGDL.ts b/packages/google-fonts/src/BetaniaPatmosGDL.ts new file mode 100644 index 00000000000..9b0f6ab05a2 --- /dev/null +++ b/packages/google-fonts/src/BetaniaPatmosGDL.ts @@ -0,0 +1,46 @@ +import {loadFonts} from './base'; + +export const getInfo = () => ({ + fontFamily: 'Betania Patmos GDL', + importName: 'BetaniaPatmosGDL', + version: 'v2', + url: 'https://fonts.googleapis.com/css2?family=Betania+Patmos+GDL:ital,wght@0,400', + unicodeRanges: { + 'latin-ext': + 'U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF', + latin: + 'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD', + }, + fonts: { + normal: { + '400': { + 'latin-ext': + 'https://fonts.gstatic.com/s/betaniapatmosgdl/v2/-nFhOHE6_uoR4VYoynWSh_bKTCFIT7tB3vD212k.woff2', + latin: + 'https://fonts.gstatic.com/s/betaniapatmosgdl/v2/-nFhOHE6_uoR4VYoynWSh_bKTCFIT7tB0PD2.woff2', + }, + }, + }, + subsets: ['latin', 'latin-ext'], +}); + +export const fontFamily = 'Betania Patmos GDL' as const; + +type Variants = { + normal: { + weights: '400'; + subsets: 'latin' | 'latin-ext'; + }; +}; + +export const loadFont = ( + style?: T, + options?: { + weights?: Variants[T]['weights'][]; + subsets?: Variants[T]['subsets'][]; + document?: Document; + ignoreTooManyRequestsWarning?: boolean; + }, +) => { + return loadFonts(getInfo(), style, options); +}; diff --git a/packages/google-fonts/src/BetaniaPatmosIn.ts b/packages/google-fonts/src/BetaniaPatmosIn.ts new file mode 100644 index 00000000000..eb7d7ea6d7d --- /dev/null +++ b/packages/google-fonts/src/BetaniaPatmosIn.ts @@ -0,0 +1,46 @@ +import {loadFonts} from './base'; + +export const getInfo = () => ({ + fontFamily: 'Betania Patmos In', + importName: 'BetaniaPatmosIn', + version: 'v2', + url: 'https://fonts.googleapis.com/css2?family=Betania+Patmos+In:ital,wght@0,400', + unicodeRanges: { + 'latin-ext': + 'U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF', + latin: + 'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD', + }, + fonts: { + normal: { + '400': { + 'latin-ext': + 'https://fonts.gstatic.com/s/betaniapatmosin/v2/t5t6IQYdPp6dFAyhcz3W2MuHvhmmxIuPWhojrg.woff2', + latin: + 'https://fonts.gstatic.com/s/betaniapatmosin/v2/t5t6IQYdPp6dFAyhcz3W2MuHvhmmxIuBWho.woff2', + }, + }, + }, + subsets: ['latin', 'latin-ext'], +}); + +export const fontFamily = 'Betania Patmos In' as const; + +type Variants = { + normal: { + weights: '400'; + subsets: 'latin' | 'latin-ext'; + }; +}; + +export const loadFont = ( + style?: T, + options?: { + weights?: Variants[T]['weights'][]; + subsets?: Variants[T]['subsets'][]; + document?: Document; + ignoreTooManyRequestsWarning?: boolean; + }, +) => { + return loadFonts(getInfo(), style, options); +}; diff --git a/packages/google-fonts/src/BetaniaPatmosInGDL.ts b/packages/google-fonts/src/BetaniaPatmosInGDL.ts new file mode 100644 index 00000000000..75de49e1b1c --- /dev/null +++ b/packages/google-fonts/src/BetaniaPatmosInGDL.ts @@ -0,0 +1,46 @@ +import {loadFonts} from './base'; + +export const getInfo = () => ({ + fontFamily: 'Betania Patmos In GDL', + importName: 'BetaniaPatmosInGDL', + version: 'v2', + url: 'https://fonts.googleapis.com/css2?family=Betania+Patmos+In+GDL:ital,wght@0,400', + unicodeRanges: { + 'latin-ext': + 'U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF', + latin: + 'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD', + }, + fonts: { + normal: { + '400': { + 'latin-ext': + 'https://fonts.gstatic.com/s/betaniapatmosingdl/v2/va9Y4lzJyMBdF8kOQbYe5MWhMhe2GnyJ0wbGFFnNsLI.woff2', + latin: + 'https://fonts.gstatic.com/s/betaniapatmosingdl/v2/va9Y4lzJyMBdF8kOQbYe5MWhMhe2GnyJ0wbGGlnN.woff2', + }, + }, + }, + subsets: ['latin', 'latin-ext'], +}); + +export const fontFamily = 'Betania Patmos In GDL' as const; + +type Variants = { + normal: { + weights: '400'; + subsets: 'latin' | 'latin-ext'; + }; +}; + +export const loadFont = ( + style?: T, + options?: { + weights?: Variants[T]['weights'][]; + subsets?: Variants[T]['subsets'][]; + document?: Document; + ignoreTooManyRequestsWarning?: boolean; + }, +) => { + return loadFonts(getInfo(), style, options); +}; diff --git a/packages/google-fonts/src/GveretLevin.ts b/packages/google-fonts/src/GveretLevin.ts new file mode 100644 index 00000000000..5414450e3b7 --- /dev/null +++ b/packages/google-fonts/src/GveretLevin.ts @@ -0,0 +1,46 @@ +import {loadFonts} from './base'; + +export const getInfo = () => ({ + fontFamily: 'Gveret Levin', + importName: 'GveretLevin', + version: 'v4', + url: 'https://fonts.googleapis.com/css2?family=Gveret+Levin:ital,wght@0,400', + unicodeRanges: { + hebrew: + 'U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F', + latin: + 'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD', + }, + fonts: { + normal: { + '400': { + hebrew: + 'https://fonts.gstatic.com/s/gveretlevin/v4/0QInMXVI5YS9Rnn7ar449p--9pzTwAM.woff2', + latin: + 'https://fonts.gstatic.com/s/gveretlevin/v4/0QInMXVI5YS9Rnn7ar449p--9JzT.woff2', + }, + }, + }, + subsets: ['hebrew', 'latin'], +}); + +export const fontFamily = 'Gveret Levin' as const; + +type Variants = { + normal: { + weights: '400'; + subsets: 'hebrew' | 'latin'; + }; +}; + +export const loadFont = ( + style?: T, + options?: { + weights?: Variants[T]['weights'][]; + subsets?: Variants[T]['subsets'][]; + document?: Document; + ignoreTooManyRequestsWarning?: boolean; + }, +) => { + return loadFonts(getInfo(), style, options); +}; diff --git a/packages/google-fonts/src/Idiqlat.ts b/packages/google-fonts/src/Idiqlat.ts new file mode 100644 index 00000000000..32b9c51c866 --- /dev/null +++ b/packages/google-fonts/src/Idiqlat.ts @@ -0,0 +1,58 @@ +import {loadFonts} from './base'; + +export const getInfo = () => ({ + fontFamily: 'Idiqlat', + importName: 'Idiqlat', + version: 'v2', + url: 'https://fonts.googleapis.com/css2?family=Idiqlat:ital,wght@0,200;0,300;0,400', + unicodeRanges: { + syriac: + 'U+0303-0304, U+0307-0308, U+030A, U+0320, U+0323-0325, U+032D-032E, U+0330-0331, U+060C, U+061B-061C, U+061F, U+0621, U+0640, U+064B-0655, U+0660-066C, U+0670, U+0700-074F, U+0860-086A, U+1DF8, U+1DFA, U+200C-200F, U+25CC, U+2670-2671', + latin: + 'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD', + }, + fonts: { + normal: { + '200': { + syriac: + 'https://fonts.gstatic.com/s/idiqlat/v2/YA9Wr0ef50XNM6kiAOrKolUgsoGt.woff2', + latin: + 'https://fonts.gstatic.com/s/idiqlat/v2/YA9Wr0ef50XNM6kiAOrKoiYgsg.woff2', + }, + '300': { + syriac: + 'https://fonts.gstatic.com/s/idiqlat/v2/YA9Wr0ef50XNM6kiAI7JolUgsoGt.woff2', + latin: + 'https://fonts.gstatic.com/s/idiqlat/v2/YA9Wr0ef50XNM6kiAI7JoiYgsg.woff2', + }, + '400': { + syriac: + 'https://fonts.gstatic.com/s/idiqlat/v2/YA9Tr0ef50XNM6kiCFbrtxkB.woff2', + latin: + 'https://fonts.gstatic.com/s/idiqlat/v2/YA9Tr0ef50XNM6kiCCXrtw.woff2', + }, + }, + }, + subsets: ['latin', 'syriac'], +}); + +export const fontFamily = 'Idiqlat' as const; + +type Variants = { + normal: { + weights: '200' | '300' | '400'; + subsets: 'latin' | 'syriac'; + }; +}; + +export const loadFont = ( + style?: T, + options?: { + weights?: Variants[T]['weights'][]; + subsets?: Variants[T]['subsets'][]; + document?: Document; + ignoreTooManyRequestsWarning?: boolean; + }, +) => { + return loadFonts(getInfo(), style, options); +}; diff --git a/packages/google-fonts/src/MaShanZheng.ts b/packages/google-fonts/src/MaShanZheng.ts index c26f06570a2..98127197530 100644 --- a/packages/google-fonts/src/MaShanZheng.ts +++ b/packages/google-fonts/src/MaShanZheng.ts @@ -3,7 +3,7 @@ import {loadFonts} from './base'; export const getInfo = () => ({ fontFamily: 'Ma Shan Zheng', importName: 'MaShanZheng', - version: 'v14', + version: 'v17', url: 'https://fonts.googleapis.com/css2?family=Ma+Shan+Zheng:ital,wght@0,400', unicodeRanges: { '[5]': @@ -195,189 +195,189 @@ export const getInfo = () => ({ normal: { '400': { '[5]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.5.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.5.woff2', '[6]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.6.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.6.woff2', '[21]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.21.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.21.woff2', '[22]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.22.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.22.woff2', '[23]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.23.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.23.woff2', '[24]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.24.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.24.woff2', '[25]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.25.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.25.woff2', '[26]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.26.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.26.woff2', '[27]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.27.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.27.woff2', '[28]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.28.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.28.woff2', '[29]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.29.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.29.woff2', '[30]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.30.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.30.woff2', '[31]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.31.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.31.woff2', '[32]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.32.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.32.woff2', '[33]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.33.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.33.woff2', '[34]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.34.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.34.woff2', '[35]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.35.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.35.woff2', '[36]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.36.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.36.woff2', '[37]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.37.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.37.woff2', '[38]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.38.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.38.woff2', '[39]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.39.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.39.woff2', '[40]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.40.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.40.woff2', '[41]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.41.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.41.woff2', '[42]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.42.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.42.woff2', '[43]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.43.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.43.woff2', '[44]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.44.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.44.woff2', '[45]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.45.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.45.woff2', '[46]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.46.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.46.woff2', '[47]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.47.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.47.woff2', '[48]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.48.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.48.woff2', '[49]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.49.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.49.woff2', '[50]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.50.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.50.woff2', '[51]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.51.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.51.woff2', '[52]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.52.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.52.woff2', '[53]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.53.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.53.woff2', '[54]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.54.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.54.woff2', '[55]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.55.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.55.woff2', '[56]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.56.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.56.woff2', '[57]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.57.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.57.woff2', '[58]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.58.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.58.woff2', '[59]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.59.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.59.woff2', '[60]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.60.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.60.woff2', '[61]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.61.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.61.woff2', '[62]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.62.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.62.woff2', '[63]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.63.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.63.woff2', '[64]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.64.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.64.woff2', '[65]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.65.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.65.woff2', '[66]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.66.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.66.woff2', '[67]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.67.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.67.woff2', '[68]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.68.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.68.woff2', '[69]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.69.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.69.woff2', '[70]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.70.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.70.woff2', '[71]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.71.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.71.woff2', '[72]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.72.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.72.woff2', '[73]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.73.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.73.woff2', '[74]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.74.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.74.woff2', '[75]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.75.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.75.woff2', '[76]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.76.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.76.woff2', '[77]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.77.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.77.woff2', '[78]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.78.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.78.woff2', '[79]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.79.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.79.woff2', '[80]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.80.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.80.woff2', '[81]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.81.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.81.woff2', '[82]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.82.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.82.woff2', '[83]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.83.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.83.woff2', '[84]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.84.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.84.woff2', '[85]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.85.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.85.woff2', '[90]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.90.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.90.woff2', '[91]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.91.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.91.woff2', '[97]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.97.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.97.woff2', '[99]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.99.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.99.woff2', '[100]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.100.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.100.woff2', '[101]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.101.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.101.woff2', '[102]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.102.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.102.woff2', '[103]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.103.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.103.woff2', '[104]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.104.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.104.woff2', '[105]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.105.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.105.woff2', '[106]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.106.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.106.woff2', '[107]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.107.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.107.woff2', '[108]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.108.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.108.woff2', '[109]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.109.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.109.woff2', '[110]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.110.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.110.woff2', '[111]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.111.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.111.woff2', '[112]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.112.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.112.woff2', '[113]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.113.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.113.woff2', '[114]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.114.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.114.woff2', '[115]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.115.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.115.woff2', '[116]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.116.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.116.woff2', '[117]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.117.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.117.woff2', '[118]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.118.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.118.woff2', '[119]': - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.119.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXaRMGEFoZJFdX0wQ5Xo5Hr21L9zCcRFhbSe5Nk0pIMuUkHEA.119.woff2', latin: - 'https://fonts.gstatic.com/s/mashanzheng/v14/NaPecZTRCLxvwo41b4gvzkXadMPmDQ.woff2', + 'https://fonts.gstatic.com/s/mashanzheng/v17/NaPecZTRCLxvwo41b4gvzkXadMPmDQ.woff2', }, }, }, diff --git a/packages/google-fonts/src/NotoColorEmoji.ts b/packages/google-fonts/src/NotoColorEmoji.ts index 8537e2494cc..6104136572a 100644 --- a/packages/google-fonts/src/NotoColorEmoji.ts +++ b/packages/google-fonts/src/NotoColorEmoji.ts @@ -3,7 +3,7 @@ import {loadFonts} from './base'; export const getInfo = () => ({ fontFamily: 'Noto Color Emoji', importName: 'NotoColorEmoji', - version: 'v38', + version: 'v39', url: 'https://fonts.googleapis.com/css2?family=Noto+Color+Emoji:ital,wght@0,400', unicodeRanges: { '[0]': 'U+1f1e6-1f1ff', @@ -30,25 +30,25 @@ export const getInfo = () => ({ normal: { '400': { '[0]': - 'https://fonts.gstatic.com/s/notocoloremoji/v38/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.0.woff2', + 'https://fonts.gstatic.com/s/notocoloremoji/v39/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.0.woff2', '[1]': - 'https://fonts.gstatic.com/s/notocoloremoji/v38/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.1.woff2', + 'https://fonts.gstatic.com/s/notocoloremoji/v39/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.1.woff2', '[2]': - 'https://fonts.gstatic.com/s/notocoloremoji/v38/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.2.woff2', + 'https://fonts.gstatic.com/s/notocoloremoji/v39/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.2.woff2', '[3]': - 'https://fonts.gstatic.com/s/notocoloremoji/v38/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.3.woff2', + 'https://fonts.gstatic.com/s/notocoloremoji/v39/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.3.woff2', '[4]': - 'https://fonts.gstatic.com/s/notocoloremoji/v38/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.4.woff2', + 'https://fonts.gstatic.com/s/notocoloremoji/v39/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.4.woff2', '[5]': - 'https://fonts.gstatic.com/s/notocoloremoji/v38/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.5.woff2', + 'https://fonts.gstatic.com/s/notocoloremoji/v39/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.5.woff2', '[6]': - 'https://fonts.gstatic.com/s/notocoloremoji/v38/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.6.woff2', + 'https://fonts.gstatic.com/s/notocoloremoji/v39/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.6.woff2', '[7]': - 'https://fonts.gstatic.com/s/notocoloremoji/v38/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.7.woff2', + 'https://fonts.gstatic.com/s/notocoloremoji/v39/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.7.woff2', '[8]': - 'https://fonts.gstatic.com/s/notocoloremoji/v38/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.8.woff2', + 'https://fonts.gstatic.com/s/notocoloremoji/v39/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.8.woff2', '[9]': - 'https://fonts.gstatic.com/s/notocoloremoji/v38/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.9.woff2', + 'https://fonts.gstatic.com/s/notocoloremoji/v39/Yq6P-KqIXTD0t4D9z1ESnKM3-HpFabsE4tq3luCC7p-aXxcn.9.woff2', }, }, }, diff --git a/packages/google-fonts/src/Ramsina.ts b/packages/google-fonts/src/Ramsina.ts new file mode 100644 index 00000000000..7d48453b756 --- /dev/null +++ b/packages/google-fonts/src/Ramsina.ts @@ -0,0 +1,46 @@ +import {loadFonts} from './base'; + +export const getInfo = () => ({ + fontFamily: 'Ramsina', + importName: 'Ramsina', + version: 'v2', + url: 'https://fonts.googleapis.com/css2?family=Ramsina:ital,wght@0,400', + unicodeRanges: { + syriac: + 'U+0303-0304, U+0307-0308, U+030A, U+0320, U+0323-0325, U+032D-032E, U+0330-0331, U+060C, U+061B-061C, U+061F, U+0621, U+0640, U+064B-0655, U+0660-066C, U+0670, U+0700-074F, U+0860-086A, U+1DF8, U+1DFA, U+200C-200F, U+25CC, U+2670-2671', + latin: + 'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD', + }, + fonts: { + normal: { + '400': { + syriac: + 'https://fonts.gstatic.com/s/ramsina/v2/daaYSTE-LGmCbhP9yMo_QrmM.woff2', + latin: + 'https://fonts.gstatic.com/s/ramsina/v2/daaYSTE-LGmCbhP9yLk_Qg.woff2', + }, + }, + }, + subsets: ['latin', 'syriac'], +}); + +export const fontFamily = 'Ramsina' as const; + +type Variants = { + normal: { + weights: '400'; + subsets: 'latin' | 'syriac'; + }; +}; + +export const loadFont = ( + style?: T, + options?: { + weights?: Variants[T]['weights'][]; + subsets?: Variants[T]['subsets'][]; + document?: Document; + ignoreTooManyRequestsWarning?: boolean; + }, +) => { + return loadFonts(getInfo(), style, options); +}; diff --git a/packages/google-fonts/src/ZCOOLKuaiLe.ts b/packages/google-fonts/src/ZCOOLKuaiLe.ts index 042fb421275..58997717f15 100644 --- a/packages/google-fonts/src/ZCOOLKuaiLe.ts +++ b/packages/google-fonts/src/ZCOOLKuaiLe.ts @@ -3,7 +3,7 @@ import {loadFonts} from './base'; export const getInfo = () => ({ fontFamily: 'ZCOOL KuaiLe', importName: 'ZCOOLKuaiLe', - version: 'v20', + version: 'v22', url: 'https://fonts.googleapis.com/css2?family=ZCOOL+KuaiLe:ital,wght@0,400', unicodeRanges: { '[5]': @@ -140,6 +140,8 @@ export const getInfo = () => ({ 'U+4ea3, U+4ea5, U+4eb0-4eb1, U+4eb3-4eb6, U+4eb8-4eb9, U+4ebb-4ebe, U+4ec2-4ec4, U+4ec8-4ec9, U+4ecc, U+4ecf-4ed0, U+4ed2, U+4eda-4edb, U+4edd-4ee1, U+4ee6-4ee9, U+4eeb, U+4eee-4eef, U+4ef3-4ef5, U+4ef8-4efa, U+4efc, U+4f00, U+4f03-4f05, U+4f08-4f09, U+4f0b, U+4f0e, U+4f12-4f13, U+4f15, U+4f1b, U+4f1d, U+4f21-4f22, U+4f25, U+4f27-4f29, U+4f2b-4f2e, U+4f31-4f33, U+4f36-4f37, U+4f39, U+4f3e, U+4f40-4f41, U+4f43, U+4f47-4f49, U+4f54, U+4f57-4f58, U+4f5d-4f5e, U+4f61-4f62, U+4f64-4f65, U+4f67, U+4f6a, U+4f6e-4f6f, U+4f72, U+4f74-4f7e, U+4f80-4f82, U+4f84, U+4f89-4f8a, U+4f8e-4f98, U+4f9e, U+4fa1, U+4fa5, U+4fa9-4faa, U+4fac, U+4fb3, U+4fb6-4fb8, U+4fbd, U+4fc2, U+4fc5-4fc6, U+4fcd-4fce, U+4fd0', '[85]': 'U+3129, U+3131, U+3134, U+3137, U+3139, U+3141-3142, U+3145, U+3147-3148, U+314b, U+314d-314e, U+315c, U+3160-3161, U+3163-3164, U+3186, U+318d, U+3192, U+3196-3198, U+319e-319f, U+3220-3229, U+3231, U+3268, U+3297, U+3299, U+32a3, U+338e-338f, U+3395, U+339c-339e, U+33c4, U+33d1-33d2, U+33d5, U+3434, U+34dc, U+34ee, U+353e, U+355d, U+3566, U+3575, U+3592, U+35a0-35a1, U+35ad, U+35ce, U+36a2, U+36ab, U+38a8, U+3dab, U+3de7, U+3deb, U+3e1a, U+3f1b, U+3f6d, U+4495, U+4723, U+48fa, U+4ca3, U+4db6-4dbf, U+4e02, U+4e04-4e06, U+4e0c, U+4e0f, U+4e15, U+4e17, U+4e1f-4e21, U+4e26, U+4e29, U+4e2c, U+4e2f, U+4e31, U+4e35, U+4e37, U+4e3c, U+4e3f-4e42, U+4e44, U+4e46-4e47, U+4e57, U+4e5a-4e5c, U+4e64-4e65, U+4e67, U+4e69, U+4e6d, U+4e78, U+4e7f-4e82, U+4e85, U+4e87, U+4e8a, U+4e8d, U+4e93, U+4e96, U+4e98-4e99, U+4e9c, U+4e9e-4ea0, U+4ea2', + '[86]': + 'U+279f-27a2, U+27a4-27a5, U+27a8, U+27b0, U+27b2-27b3, U+27b9, U+27e8-27e9, U+27f6, U+2800, U+28ec, U+2913, U+2921-2922, U+2934-2935, U+2a2f, U+2b05-2b07, U+2b50, U+2b55, U+2bc5-2bc6, U+2e1c-2e1d, U+2ebb, U+2f00, U+2f08, U+2f24, U+2f2d, U+2f2f-2f30, U+2f3c, U+2f45, U+2f63-2f64, U+2f74, U+2f83, U+2f8f, U+2fbc, U+3003, U+3005-3007, U+3012-3013, U+301c-301e, U+3021, U+3023-3024, U+3030, U+3034-3035, U+3041, U+3043, U+3045, U+3047, U+3049, U+3056, U+3058, U+305c, U+305e, U+3062, U+306c, U+3074, U+3077, U+307a, U+307c-307d, U+3080, U+308e, U+3090-3091, U+3099-309b, U+309d-309e, U+30a5, U+30bc, U+30be, U+30c2, U+30c5, U+30cc, U+30d8, U+30e2, U+30e8, U+30ee, U+30f0-30f2, U+30f4-30f6, U+30fd-30fe, U+3105-3126, U+3128', '[90]': 'U+207c-2083, U+208c-208e, U+2092, U+20a6, U+20a8-20ad, U+20af, U+20b1, U+20b4-20b5, U+20b8-20ba, U+20bd, U+20db, U+20dd, U+20e0, U+20e3, U+2105, U+2109, U+2113, U+2116-2117, U+2120-2121, U+2126, U+212b, U+2133, U+2139, U+2194, U+2196-2199, U+21a0, U+21a9-21aa, U+21af, U+21b3, U+21b5, U+21ba-21bb, U+21c4, U+21ca, U+21cc, U+21d0-21d4, U+21e1, U+21e6-21e9, U+2200, U+2202, U+2205-2208, U+220f, U+2211-2212, U+2215, U+2217-2219, U+221d-2220, U+2223, U+2225, U+2227-222b, U+222e, U+2234-2237, U+223c-223d, U+2248, U+224c, U+2252, U+2256, U+2260-2261, U+2266-2267, U+226a-226b, U+226e-226f, U+2282-2283, U+2295, U+2297, U+2299, U+22a5, U+22b0-22b1, U+22b9, U+22bf, U+22c5-22c6, U+22ef, U+2304, U+2307, U+230b, U+2312-2314, U+2318, U+231a-231b, U+2323, U+239b, U+239d-239e, U+23a0, U+23e9', '[91]': @@ -195,189 +197,191 @@ export const getInfo = () => ({ normal: { '400': { '[5]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.5.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.5.woff2', '[6]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.6.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.6.woff2', '[21]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.21.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.21.woff2', '[22]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.22.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.22.woff2', '[23]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.23.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.23.woff2', '[24]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.24.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.24.woff2', '[25]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.25.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.25.woff2', '[26]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.26.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.26.woff2', '[27]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.27.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.27.woff2', '[28]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.28.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.28.woff2', '[29]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.29.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.29.woff2', '[30]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.30.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.30.woff2', '[31]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.31.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.31.woff2', '[32]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.32.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.32.woff2', '[33]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.33.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.33.woff2', '[34]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.34.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.34.woff2', '[35]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.35.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.35.woff2', '[36]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.36.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.36.woff2', '[37]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.37.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.37.woff2', '[38]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.38.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.38.woff2', '[39]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.39.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.39.woff2', '[40]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.40.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.40.woff2', '[41]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.41.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.41.woff2', '[42]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.42.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.42.woff2', '[43]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.43.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.43.woff2', '[44]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.44.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.44.woff2', '[45]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.45.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.45.woff2', '[46]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.46.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.46.woff2', '[47]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.47.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.47.woff2', '[48]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.48.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.48.woff2', '[49]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.49.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.49.woff2', '[50]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.50.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.50.woff2', '[51]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.51.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.51.woff2', '[52]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.52.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.52.woff2', '[53]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.53.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.53.woff2', '[54]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.54.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.54.woff2', '[55]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.55.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.55.woff2', '[56]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.56.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.56.woff2', '[57]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.57.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.57.woff2', '[58]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.58.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.58.woff2', '[59]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.59.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.59.woff2', '[60]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.60.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.60.woff2', '[61]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.61.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.61.woff2', '[62]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.62.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.62.woff2', '[63]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.63.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.63.woff2', '[64]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.64.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.64.woff2', '[65]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.65.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.65.woff2', '[66]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.66.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.66.woff2', '[67]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.67.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.67.woff2', '[68]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.68.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.68.woff2', '[69]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.69.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.69.woff2', '[70]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.70.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.70.woff2', '[71]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.71.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.71.woff2', '[72]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.72.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.72.woff2', '[73]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.73.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.73.woff2', '[74]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.74.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.74.woff2', '[75]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.75.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.75.woff2', '[76]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.76.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.76.woff2', '[77]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.77.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.77.woff2', '[78]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.78.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.78.woff2', '[79]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.79.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.79.woff2', '[80]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.80.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.80.woff2', '[81]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.81.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.81.woff2', '[82]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.82.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.82.woff2', '[83]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.83.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.83.woff2', '[84]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.84.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.84.woff2', '[85]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.85.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.85.woff2', + '[86]': + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.86.woff2', '[90]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.90.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.90.woff2', '[91]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.91.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.91.woff2', '[97]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.97.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.97.woff2', '[99]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.99.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.99.woff2', '[100]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.100.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.100.woff2', '[101]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.101.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.101.woff2', '[102]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.102.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.102.woff2', '[103]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.103.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.103.woff2', '[104]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.104.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.104.woff2', '[105]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.105.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.105.woff2', '[106]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.106.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.106.woff2', '[107]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.107.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.107.woff2', '[108]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.108.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.108.woff2', '[109]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.109.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.109.woff2', '[110]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.110.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.110.woff2', '[111]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.111.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.111.woff2', '[112]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.112.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.112.woff2', '[113]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.113.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.113.woff2', '[114]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.114.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.114.woff2', '[115]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.115.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.115.woff2', '[116]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.116.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.116.woff2', '[117]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.117.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.117.woff2', '[118]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.118.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.118.woff2', '[119]': - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.119.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2Wo-Tpo2MpsrpYU3EJjXfOiTrBdUtGm0PGsPHkbHZzpr3G.119.woff2', latin: - 'https://fonts.gstatic.com/s/zcoolkuaile/v20/tssqApdaRQokwFjFJjvM6h2moYby.woff2', + 'https://fonts.gstatic.com/s/zcoolkuaile/v22/tssqApdaRQokwFjFJjvM6h2moYby.woff2', }, }, }, diff --git a/packages/google-fonts/src/index.ts b/packages/google-fonts/src/index.ts index 23b41fd998d..575492f2022 100644 --- a/packages/google-fonts/src/index.ts +++ b/packages/google-fonts/src/index.ts @@ -1030,6 +1030,26 @@ export const getAvailableFonts = () => [ importName: 'Besley', load: () => import('./Besley') as Promise, }, + { + fontFamily: 'Betania Patmos', + importName: 'BetaniaPatmos', + load: () => import('./BetaniaPatmos') as Promise, + }, + { + fontFamily: 'Betania Patmos GDL', + importName: 'BetaniaPatmosGDL', + load: () => import('./BetaniaPatmosGDL') as Promise, + }, + { + fontFamily: 'Betania Patmos In', + importName: 'BetaniaPatmosIn', + load: () => import('./BetaniaPatmosIn') as Promise, + }, + { + fontFamily: 'Betania Patmos In GDL', + importName: 'BetaniaPatmosInGDL', + load: () => import('./BetaniaPatmosInGDL') as Promise, + }, { fontFamily: 'Beth Ellen', importName: 'BethEllen', @@ -3040,6 +3060,11 @@ export const getAvailableFonts = () => [ importName: 'Gurajada', load: () => import('./Gurajada') as Promise, }, + { + fontFamily: 'Gveret Levin', + importName: 'GveretLevin', + load: () => import('./GveretLevin') as Promise, + }, { fontFamily: 'Gwendolyn', importName: 'Gwendolyn', @@ -3355,6 +3380,11 @@ export const getAvailableFonts = () => [ importName: 'Iceland', load: () => import('./Iceland') as Promise, }, + { + fontFamily: 'Idiqlat', + importName: 'Idiqlat', + load: () => import('./Idiqlat') as Promise, + }, { fontFamily: 'Imbue', importName: 'Imbue', @@ -6996,6 +7026,11 @@ export const getAvailableFonts = () => [ importName: 'RampartOne', load: () => import('./RampartOne') as Promise, }, + { + fontFamily: 'Ramsina', + importName: 'Ramsina', + load: () => import('./Ramsina') as Promise, + }, { fontFamily: 'Ranchers', importName: 'Ranchers', diff --git a/packages/install-whisper-cpp/package.json b/packages/install-whisper-cpp/package.json index 9b73ee8f7d7..cfb96deb666 100644 --- a/packages/install-whisper-cpp/package.json +++ b/packages/install-whisper-cpp/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/install-whisper-cpp" }, "name": "@remotion/install-whisper-cpp", - "version": "4.0.424", + "version": "4.0.425", "description": "Helpers for installing and using Whisper.cpp", "main": "dist/index.js", "sideEffects": false, diff --git a/packages/it-tests/package.json b/packages/it-tests/package.json index 48ff83f4db3..3687e7629ee 100644 --- a/packages/it-tests/package.json +++ b/packages/it-tests/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/it-tests" }, "name": "@remotion/it-tests", - "version": "4.0.424", + "version": "4.0.425", "license": "SEE LICENSE IN LICENSE.md", "scripts": { "test": " node --test src/node-version/media-parser.mjs && bun test src/rendering --run", diff --git a/packages/lambda-client/package.json b/packages/lambda-client/package.json index ea3addee4cc..e66af820311 100644 --- a/packages/lambda-client/package.json +++ b/packages/lambda-client/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/lambda-client" }, "name": "@remotion/lambda-client", - "version": "4.0.424", + "version": "4.0.425", "main": "dist/cjs/index.js", "sideEffects": false, "scripts": { diff --git a/packages/lambda-go-example/package.json b/packages/lambda-go-example/package.json index 1472e4e1e5a..95d4aa29a8d 100644 --- a/packages/lambda-go-example/package.json +++ b/packages/lambda-go-example/package.json @@ -4,6 +4,6 @@ }, "name": "@remotion/lambda-go-example", "private": true, - "version": "4.0.424", + "version": "4.0.425", "scripts": {} } diff --git a/packages/lambda-go/package.json b/packages/lambda-go/package.json index 6fa9dbedbf8..857061162c8 100644 --- a/packages/lambda-go/package.json +++ b/packages/lambda-go/package.json @@ -4,7 +4,7 @@ }, "name": "@remotion/lambda-go", "private": true, - "version": "4.0.424", + "version": "4.0.425", "scripts": { "lint": "node build.mjs", "publishprivate": "node publish.mjs" diff --git a/packages/lambda-go/version.go b/packages/lambda-go/version.go index d64a2fb0879..6e70e257f88 100644 --- a/packages/lambda-go/version.go +++ b/packages/lambda-go/version.go @@ -1,3 +1,3 @@ package lambda_go_sdk; -const VERSION = "4.0.424" \ No newline at end of file +const VERSION = "4.0.425" \ No newline at end of file diff --git a/packages/lambda-php-example/composer.json b/packages/lambda-php-example/composer.json index 88c131a5811..8b009b88344 100644 --- a/packages/lambda-php-example/composer.json +++ b/packages/lambda-php-example/composer.json @@ -19,6 +19,6 @@ ], "require": { "vlucas/phpdotenv": "^5.5", - "remotion/lambda": "4.0.424" + "remotion/lambda": "4.0.425" } } diff --git a/packages/lambda-php/composer.json b/packages/lambda-php/composer.json index 0a1cc61b974..8aa339ee7d2 100644 --- a/packages/lambda-php/composer.json +++ b/packages/lambda-php/composer.json @@ -1,7 +1,7 @@ { "name": "remotion/lambda", "type": "library", - "version": "4.0.424", + "version": "4.0.425", "description": "A PHP library for working with Remotion Lambda", "license": "proprietary", "autoload": { diff --git a/packages/lambda-php/package.json b/packages/lambda-php/package.json index 206fde5571b..c5a46d58c8d 100644 --- a/packages/lambda-php/package.json +++ b/packages/lambda-php/package.json @@ -4,7 +4,7 @@ }, "name": "@remotion/lambda-php", "private": true, - "version": "4.0.424", + "version": "4.0.425", "scripts": { "lint": "node build.mjs", "publishprivate": "node publish.mjs" diff --git a/packages/lambda-php/src/Semantic.php b/packages/lambda-php/src/Semantic.php index b768135029e..60db25e7236 100644 --- a/packages/lambda-php/src/Semantic.php +++ b/packages/lambda-php/src/Semantic.php @@ -4,5 +4,5 @@ class Semantic { - public const VERSION = "4.0.424"; + public const VERSION = "4.0.425"; } \ No newline at end of file diff --git a/packages/lambda-python/package.json b/packages/lambda-python/package.json index 0c24fcb1464..a0bd4f23ba1 100644 --- a/packages/lambda-python/package.json +++ b/packages/lambda-python/package.json @@ -4,7 +4,7 @@ }, "name": "@remotion/lambda-python", "private": true, - "version": "4.0.424", + "version": "4.0.425", "scripts": { "publishprivate": "node publish.mjs" }, diff --git a/packages/lambda-python/remotion_lambda/version.py b/packages/lambda-python/remotion_lambda/version.py index 16fe619fd91..6e972127a85 100644 --- a/packages/lambda-python/remotion_lambda/version.py +++ b/packages/lambda-python/remotion_lambda/version.py @@ -1,2 +1,2 @@ # pylint: disable=missing-module-docstring, missing-final-newline -VERSION = "4.0.424" \ No newline at end of file +VERSION = "4.0.425" \ No newline at end of file diff --git a/packages/lambda-ruby/lib/remotion_lambda/version.rb b/packages/lambda-ruby/lib/remotion_lambda/version.rb index 2082105a73f..6ceaaac09d4 100644 --- a/packages/lambda-ruby/lib/remotion_lambda/version.rb +++ b/packages/lambda-ruby/lib/remotion_lambda/version.rb @@ -1 +1 @@ -VERSION = "4.0.424" \ No newline at end of file +VERSION = "4.0.425" \ No newline at end of file diff --git a/packages/lambda-ruby/package.json b/packages/lambda-ruby/package.json index 53ff4b1fc2d..1c94de50776 100644 --- a/packages/lambda-ruby/package.json +++ b/packages/lambda-ruby/package.json @@ -4,7 +4,7 @@ }, "name": "@remotion/lambda-ruby", "private": true, - "version": "4.0.424", + "version": "4.0.425", "scripts": { "publishprivate": "bun publish.ts" }, diff --git a/packages/lambda-ruby/remotion_lambda.gemspec b/packages/lambda-ruby/remotion_lambda.gemspec index ceda4996bc8..0c88e0e3fad 100644 --- a/packages/lambda-ruby/remotion_lambda.gemspec +++ b/packages/lambda-ruby/remotion_lambda.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = "remotion_lambda" - s.version = "4.0.424" + s.version = "4.0.425" s.summary = "Remotion Lambda SDK" s.description = "A Ruby SDK for Remotion Lambda" s.authors = ["Jonny Burger"] diff --git a/packages/lambda/package.json b/packages/lambda/package.json index 7f57f76a8bd..6df7a3edff7 100644 --- a/packages/lambda/package.json +++ b/packages/lambda/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/lambda" }, "name": "@remotion/lambda", - "version": "4.0.424", + "version": "4.0.425", "description": "Render Remotion videos on AWS Lambda", "main": "dist/index.js", "sideEffects": false, diff --git a/packages/layout-utils/package.json b/packages/layout-utils/package.json index 8f29f5c32d1..86a157cc6c2 100644 --- a/packages/layout-utils/package.json +++ b/packages/layout-utils/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/layout-utils" }, "name": "@remotion/layout-utils", - "version": "4.0.424", + "version": "4.0.425", "description": "Utilities for working with layouts", "main": "dist/cjs/index.js", "types": "dist/cjs/index.d.ts", diff --git a/packages/licensing/package.json b/packages/licensing/package.json index 6723cca0d82..c8dccb159c1 100644 --- a/packages/licensing/package.json +++ b/packages/licensing/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/licensing" }, "name": "@remotion/licensing", - "version": "4.0.424", + "version": "4.0.425", "description": "Manage your Remotion.pro license", "main": "dist", "sideEffects": false, diff --git a/packages/light-leaks/package.json b/packages/light-leaks/package.json index 5f269810bbc..cc0cdddf103 100644 --- a/packages/light-leaks/package.json +++ b/packages/light-leaks/package.json @@ -1,6 +1,6 @@ { "name": "@remotion/light-leaks", - "version": "4.0.424", + "version": "4.0.425", "description": "Light leak effects for Remotion", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/lottie/package.json b/packages/lottie/package.json index ddc2eaca585..938a4c4b763 100644 --- a/packages/lottie/package.json +++ b/packages/lottie/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/lottie" }, "name": "@remotion/lottie", - "version": "4.0.424", + "version": "4.0.425", "description": "Include Lottie animations in Remotion", "main": "dist/cjs/index.js", "types": "dist/cjs/index.d.ts", diff --git a/packages/mcp/package.json b/packages/mcp/package.json index c64b374629b..9022bf5be54 100644 --- a/packages/mcp/package.json +++ b/packages/mcp/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/mcp" }, "name": "@remotion/mcp", - "version": "4.0.424", + "version": "4.0.425", "description": "Remotion's Model Context Protocol", "main": "dist/esm/index.mjs", "sideEffects": false, diff --git a/packages/media-parser/package.json b/packages/media-parser/package.json index 7651e52ee8a..9c506dd4a07 100644 --- a/packages/media-parser/package.json +++ b/packages/media-parser/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/media-parser" }, "name": "@remotion/media-parser", - "version": "4.0.424", + "version": "4.0.425", "main": "dist/index.js", "sideEffects": false, "scripts": { diff --git a/packages/media-parser/src/version.ts b/packages/media-parser/src/version.ts index 00e70c3a84d..d12a573d3a5 100644 --- a/packages/media-parser/src/version.ts +++ b/packages/media-parser/src/version.ts @@ -1,2 +1,2 @@ // Automatically generated on publish -export const VERSION = '4.0.424'; +export const VERSION = '4.0.425'; diff --git a/packages/media-utils/package.json b/packages/media-utils/package.json index 45f8ed25eac..dc3ac11c3f1 100644 --- a/packages/media-utils/package.json +++ b/packages/media-utils/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/media-utils" }, "name": "@remotion/media-utils", - "version": "4.0.424", + "version": "4.0.425", "description": "Utilities for working with media files", "main": "dist/index.js", "sideEffects": false, diff --git a/packages/media/package.json b/packages/media/package.json index 3b2b83a6bfe..eb968ae7d0d 100644 --- a/packages/media/package.json +++ b/packages/media/package.json @@ -1,6 +1,6 @@ { "name": "@remotion/media", - "version": "4.0.424", + "version": "4.0.425", "main": "dist/index.js", "types": "dist/index.d.ts", "module": "dist/esm/index.mjs", diff --git a/packages/motion-blur/package.json b/packages/motion-blur/package.json index 861f36a388b..d646fafffb7 100644 --- a/packages/motion-blur/package.json +++ b/packages/motion-blur/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/motion-blur" }, "name": "@remotion/motion-blur", - "version": "4.0.424", + "version": "4.0.425", "description": "Motion blur effect for Remotion", "main": "dist/cjs/index.js", "types": "dist/cjs/index.d.ts", diff --git a/packages/noise/package.json b/packages/noise/package.json index a385059f68f..0739bdbea0c 100644 --- a/packages/noise/package.json +++ b/packages/noise/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/noise" }, "name": "@remotion/noise", - "version": "4.0.424", + "version": "4.0.425", "description": "Noise generation functions", "main": "dist/cjs/index.js", "types": "dist/cjs/index.d.ts", diff --git a/packages/openai-whisper/package.json b/packages/openai-whisper/package.json index bfee3ec6943..031c9323bed 100644 --- a/packages/openai-whisper/package.json +++ b/packages/openai-whisper/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/openai-whisper" }, "name": "@remotion/openai-whisper", - "version": "4.0.424", + "version": "4.0.425", "description": "Work with the output of the OpenAI Whisper API", "main": "dist/index.js", "sideEffects": false, diff --git a/packages/paths/package.json b/packages/paths/package.json index 4cdf22949aa..3124e8b4bb8 100644 --- a/packages/paths/package.json +++ b/packages/paths/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/paths" }, "name": "@remotion/paths", - "version": "4.0.424", + "version": "4.0.425", "description": "Utilities for working with SVG paths", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/player-example/package.json b/packages/player-example/package.json index 9d20f69ab8a..b62e3f59052 100644 --- a/packages/player-example/package.json +++ b/packages/player-example/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/player-example" }, "name": "@remotion/player-example", - "version": "4.0.424", + "version": "4.0.425", "private": true, "author": "Jonny Burger ", "maintainers": [ diff --git a/packages/player/package.json b/packages/player/package.json index 2fc917014dc..0c82c79920a 100644 --- a/packages/player/package.json +++ b/packages/player/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/player" }, "name": "@remotion/player", - "version": "4.0.424", + "version": "4.0.425", "description": "React component for embedding a Remotion preview into your app", "main": "dist/cjs/index.js", "types": "dist/cjs/index.d.ts", diff --git a/packages/preload/package.json b/packages/preload/package.json index c152026c079..2cf4389463c 100644 --- a/packages/preload/package.json +++ b/packages/preload/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/preload" }, "name": "@remotion/preload", - "version": "4.0.424", + "version": "4.0.425", "description": "Preloads assets for use in Remotion", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/promo-pages/package.json b/packages/promo-pages/package.json index f9153e1f16d..8812b0d72f1 100644 --- a/packages/promo-pages/package.json +++ b/packages/promo-pages/package.json @@ -1,6 +1,6 @@ { "name": "@remotion/promo-pages", - "version": "4.0.424", + "version": "4.0.425", "publishConfig": { "access": "public" }, diff --git a/packages/react18-tests/package.json b/packages/react18-tests/package.json index c70491dc18b..69de90e00de 100644 --- a/packages/react18-tests/package.json +++ b/packages/react18-tests/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/react18-tests" }, "name": "@remotion/react18-tests", - "version": "4.0.424", + "version": "4.0.425", "main": "dist/index.js", "sideEffects": false, "scripts": { diff --git a/packages/renderer/package.json b/packages/renderer/package.json index 714dc1af61f..7739bd151ad 100644 --- a/packages/renderer/package.json +++ b/packages/renderer/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/renderer" }, "name": "@remotion/renderer", - "version": "4.0.424", + "version": "4.0.425", "description": "Render Remotion videos using Node.js or Bun", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/rive/package.json b/packages/rive/package.json index 7f8f4dfbe93..23ac0de146c 100644 --- a/packages/rive/package.json +++ b/packages/rive/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/rive" }, "name": "@remotion/rive", - "version": "4.0.424", + "version": "4.0.425", "description": "Embed Rive animations in a Remotion video", "main": "dist/cjs/index.js", "types": "dist/cjs/index.d.ts", diff --git a/packages/rounded-text-box/package.json b/packages/rounded-text-box/package.json index de532bf49aa..58b75753d43 100644 --- a/packages/rounded-text-box/package.json +++ b/packages/rounded-text-box/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/rounded-text-box" }, "name": "@remotion/rounded-text-box", - "version": "4.0.424", + "version": "4.0.425", "description": "Create a TikTok-like multiline text box SVG path with rounded corners", "main": "dist/cjs/index.js", "types": "dist/cjs/index.d.ts", diff --git a/packages/serverless-client/package.json b/packages/serverless-client/package.json index be274f1f40f..db19ad5ed98 100644 --- a/packages/serverless-client/package.json +++ b/packages/serverless-client/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/serverless-client" }, "name": "@remotion/serverless-client", - "version": "4.0.424", + "version": "4.0.425", "main": "dist", "sideEffects": false, "scripts": { diff --git a/packages/serverless/package.json b/packages/serverless/package.json index 481ac7014bb..980c07bf666 100644 --- a/packages/serverless/package.json +++ b/packages/serverless/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/serverless" }, "name": "@remotion/serverless", - "version": "4.0.424", + "version": "4.0.425", "description": "A runtime for distributed rendering", "main": "dist", "sideEffects": false, diff --git a/packages/shapes/package.json b/packages/shapes/package.json index b355bf28ba5..5300eb4b666 100644 --- a/packages/shapes/package.json +++ b/packages/shapes/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/shapes" }, "name": "@remotion/shapes", - "version": "4.0.424", + "version": "4.0.425", "description": "Generate SVG shapes", "main": "dist/index.js", "sideEffects": false, diff --git a/packages/skia/package.json b/packages/skia/package.json index 5a9f8da2941..43a792a4b88 100644 --- a/packages/skia/package.json +++ b/packages/skia/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/skia" }, "name": "@remotion/skia", - "version": "4.0.424", + "version": "4.0.425", "description": "Include React Native Skia components in a Remotion video", "main": "dist/cjs/index.js", "types": "dist/cjs/index.d.ts", diff --git a/packages/skills/package.json b/packages/skills/package.json index 19b74d213de..7d871e621ee 100644 --- a/packages/skills/package.json +++ b/packages/skills/package.json @@ -7,7 +7,7 @@ }, "name": "@remotion/skills", "private": true, - "version": "4.0.424", + "version": "4.0.425", "devDependencies": { "@remotion/eslint-config-internal": "workspace:*", "eslint": "catalog:", diff --git a/packages/streaming/package.json b/packages/streaming/package.json index ca18807a392..d862d38d216 100644 --- a/packages/streaming/package.json +++ b/packages/streaming/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/streaming" }, "name": "@remotion/streaming", - "version": "4.0.424", + "version": "4.0.425", "description": "Utilities for streaming data between programs", "main": "dist", "sideEffects": false, diff --git a/packages/studio-server/package.json b/packages/studio-server/package.json index 5c165481125..edc7b617d41 100644 --- a/packages/studio-server/package.json +++ b/packages/studio-server/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/studio-server" }, "name": "@remotion/studio-server", - "version": "4.0.424", + "version": "4.0.425", "description": "Run a Remotion Studio with a server backend", "main": "dist", "sideEffects": false, diff --git a/packages/studio-shared/package.json b/packages/studio-shared/package.json index 5779c5b9352..52e09824ea6 100644 --- a/packages/studio-shared/package.json +++ b/packages/studio-shared/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/studio-shared" }, "name": "@remotion/studio-shared", - "version": "4.0.424", + "version": "4.0.425", "description": "Internal package for shared objects between the Studio backend and frontend", "main": "dist", "sideEffects": false, diff --git a/packages/studio/package.json b/packages/studio/package.json index b159c72fe7e..60047f2e274 100644 --- a/packages/studio/package.json +++ b/packages/studio/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/studio" }, "name": "@remotion/studio", - "version": "4.0.424", + "version": "4.0.425", "description": "APIs for interacting with the Remotion Studio", "main": "dist", "sideEffects": false, diff --git a/packages/svg-3d-engine/package.json b/packages/svg-3d-engine/package.json index 962ec98c417..b4149aec72a 100644 --- a/packages/svg-3d-engine/package.json +++ b/packages/svg-3d-engine/package.json @@ -24,7 +24,7 @@ "require": "./dist/cjs/index.js" } }, - "version": "4.0.424", + "version": "4.0.425", "repository": { "url": "https://github.com/remotion-dev/remotion/tree/main/packages/svg-3d-engine" }, diff --git a/packages/tailwind-v4/package.json b/packages/tailwind-v4/package.json index a8e00ab9094..5e0a23da65d 100644 --- a/packages/tailwind-v4/package.json +++ b/packages/tailwind-v4/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/tailwind-v4" }, "name": "@remotion/tailwind-v4", - "version": "4.0.424", + "version": "4.0.425", "description": "Enable TailwindCSS support in Remotion (TailwindCSS v4)", "main": "dist/cjs/index.js", "types": "dist/cjs/index.d.ts", diff --git a/packages/tailwind/package.json b/packages/tailwind/package.json index 7ff74f24a0b..95f076a3f24 100644 --- a/packages/tailwind/package.json +++ b/packages/tailwind/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/tailwind" }, "name": "@remotion/tailwind", - "version": "4.0.424", + "version": "4.0.425", "description": "Enable TailwindCSS support in Remotion (TailwindCSS v3)", "main": "dist/cjs/index.js", "types": "dist/cjs/index.d.ts", diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index e74ebaea04c..96107377299 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/test-utils" }, "name": "@remotion/test-utils", - "version": "4.0.424", + "version": "4.0.425", "main": "dist", "sideEffects": false, "scripts": { diff --git a/packages/three/package.json b/packages/three/package.json index 5c91387830a..7bd9a3e7111 100644 --- a/packages/three/package.json +++ b/packages/three/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/three" }, "name": "@remotion/three", - "version": "4.0.424", + "version": "4.0.425", "description": "Include React Three Fiber components in a Remotion video", "main": "dist/cjs/index.js", "types": "dist/cjs/index.d.ts", diff --git a/packages/transitions/package.json b/packages/transitions/package.json index db9a86b22d4..1f9184b4803 100644 --- a/packages/transitions/package.json +++ b/packages/transitions/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/transitions" }, "name": "@remotion/transitions", - "version": "4.0.424", + "version": "4.0.425", "description": "Library for creating transitions in Remotion", "sideEffects": false, "main": "dist/esm/index.mjs", diff --git a/packages/web-renderer/package.json b/packages/web-renderer/package.json index da410f20b58..edd3b13cc99 100644 --- a/packages/web-renderer/package.json +++ b/packages/web-renderer/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/web-renderer" }, "name": "@remotion/web-renderer", - "version": "4.0.424", + "version": "4.0.425", "main": "dist/index.js", "type": "module", "scripts": { diff --git a/packages/webcodecs/package.json b/packages/webcodecs/package.json index d2c9508d5e4..40a92cd781f 100644 --- a/packages/webcodecs/package.json +++ b/packages/webcodecs/package.json @@ -1,6 +1,6 @@ { "name": "@remotion/webcodecs", - "version": "4.0.424", + "version": "4.0.425", "main": "dist/index.js", "types": "dist/index.d.ts", "module": "dist/esm/index.mjs", diff --git a/packages/whisper-web/package.json b/packages/whisper-web/package.json index 4a6abbf74b9..fa113a966f1 100644 --- a/packages/whisper-web/package.json +++ b/packages/whisper-web/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/whisper-web" }, "name": "@remotion/whisper-web", - "version": "4.0.424", + "version": "4.0.425", "main": "dist/index.js", "sideEffects": false, "scripts": { diff --git a/packages/zod-types/package.json b/packages/zod-types/package.json index 21db4a7e95d..8dbf3498ee5 100644 --- a/packages/zod-types/package.json +++ b/packages/zod-types/package.json @@ -3,7 +3,7 @@ "url": "https://github.com/remotion-dev/remotion/tree/main/packages/zod-types" }, "name": "@remotion/zod-types", - "version": "4.0.424", + "version": "4.0.425", "description": "Zod types for Remotion", "main": "dist/cjs/index.js", "types": "dist/cjs/index.d.ts", From 49228d2ec027db78b0541ec035a1a6f084a99ee6 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Thu, 19 Feb 2026 09:16:58 +0100 Subject: [PATCH 26/49] Fix release command: add 1Password account flag and use npm CLI for version check - Add --account remotiondev.1password.com to all op commands (fixes failure when multiple 1Password accounts exist) - Use echo pipe instead of <<< for password input (more reliable) - Use npm view remotion version instead of fetching npmjs.com (which returns 403) Co-Authored-By: Claude Opus 4.6 --- .claude/commands/release.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.claude/commands/release.md b/.claude/commands/release.md index 5857fe996ee..3ac9363d426 100644 --- a/.claude/commands/release.md +++ b/.claude/commands/release.md @@ -1,11 +1,11 @@ - Kill any `turbo` processes that might be running with SIGKILL - Run `npm login` (I will manually do 2FA in the browser) -- Use `op item get "Npmjs" --fields password --reveal` to get the password for NPM. -- Use `op item get "Npmjs" --otp` to get a one-time password for 2FA. -- Run `npm token create --name="PublishRemotionXXXXXX" --packages "remotion" --packages "create-video" --packages-and-scopes-permission read-write --bypass-2fa --scopes "@remotion" --otp=`. Replace XXXXXX with a random string so we have a unique name. Use `op item get "Npmjs" --otp` to get the OTP and pass it via `--otp=`. It will ask for a password, pipe in the password using `<<<`. The NPM token will be printed. +- Use `op item get "Npmjs" --fields password --reveal --account remotiondev.1password.com` to get the password for NPM. +- Use `op item get "Npmjs" --otp --account remotiondev.1password.com` to get a one-time password for 2FA. +- Run `npm token create --name="PublishRemotionXXXXXX" --packages "remotion" --packages "create-video" --packages-and-scopes-permission read-write --bypass-2fa --scopes "@remotion" --otp=`. Replace XXXXXX with a random string so we have a unique name. Use `op item get "Npmjs" --otp --account remotiondev.1password.com` to get the OTP and pass it via `--otp=`. It will ask for a password, pipe in the password using `echo "$PASSWORD" |`. - Run `bun i` - Run `bun run build` -- Check `https://www.npmjs.com/package/remotion` to get the current version number +- Run `npm view remotion version` to get the current version number - Run `bun set-version.ts `, where is the current version plus 1 - Run `NPM_CONFIG_TOKEN= bun run release` where is the NPM token we just created - Generate a changelog in markdown and save it to `/tmp/release-.md`: From 5d6df78ac419767ecbfa287cb73b84d9e2abd61c Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Thu, 19 Feb 2026 09:21:10 +0100 Subject: [PATCH 27/49] Update changelog generation guidelines in release command - Group "What's Changed" items by package with subheadings - Strip redundant prefixes (e.g. "Docs:" in Docs section) - Add separate "Templates" section - Remove "New Contributors" section (unreliable from version range) Co-Authored-By: Claude Opus 4.6 --- .claude/commands/release.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.claude/commands/release.md b/.claude/commands/release.md index 3ac9363d426..401e71e57d6 100644 --- a/.claude/commands/release.md +++ b/.claude/commands/release.md @@ -12,7 +12,10 @@ - Run `git log v..v --oneline` to get all commits - Extract PR numbers from merge commits - For each PR, run `gh pr view --json title,author,number,url --jq '"* \(.title) by @\(.author.login) in \(.url)"'` - - Categorize PRs into sections: "What's Changed" (features, fixes, improvements), "Internal" (dependency upgrades, tooling, infra), "Docs" (documentation changes), "Templates" (template changes) - - Check for new contributors by comparing authors against known contributors + - Categorize PRs into sections: "What's Changed", "Templates", "Docs", "Internal" + - In "What's Changed", group items by package using `### \`package-name\`` subheadings + - Strip redundant prefixes from PR titles (e.g. remove "Docs:" from items in the Docs section, remove package names from items already grouped under that package) + - "Templates" is a separate section for any template-* changes + - Do NOT add a "New Contributors" section - contributors may appear new in a version range but not actually be first-time contributors - Add `**Full Changelog**: https://github.com/remotion-dev/remotion/compare/v...v` at the bottom - Use the same format as previous GitHub releases (check with `gh release view v`) From aa79186d197461d98c5c7afa751355747b3143cc Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Thu, 19 Feb 2026 09:23:15 +0100 Subject: [PATCH 28/49] Fix changelog grouping: sort by package, no subheadings Co-Authored-By: Claude Opus 4.6 --- .claude/commands/release.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.claude/commands/release.md b/.claude/commands/release.md index 401e71e57d6..a5a039f4a08 100644 --- a/.claude/commands/release.md +++ b/.claude/commands/release.md @@ -13,8 +13,8 @@ - Extract PR numbers from merge commits - For each PR, run `gh pr view --json title,author,number,url --jq '"* \(.title) by @\(.author.login) in \(.url)"'` - Categorize PRs into sections: "What's Changed", "Templates", "Docs", "Internal" - - In "What's Changed", group items by package using `### \`package-name\`` subheadings - - Strip redundant prefixes from PR titles (e.g. remove "Docs:" from items in the Docs section, remove package names from items already grouped under that package) + - In "What's Changed", sort items so that entries for the same package are adjacent (no subheadings, just sorted order) + - Strip redundant prefixes from PR titles (e.g. remove "Docs:" from items in the Docs section) - "Templates" is a separate section for any template-* changes - Do NOT add a "New Contributors" section - contributors may appear new in a version range but not actually be first-time contributors - Add `**Full Changelog**: https://github.com/remotion-dev/remotion/compare/v...v` at the bottom From 159b45dae2978d86782875518c315ec0b9b96b0e Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Thu, 19 Feb 2026 09:25:53 +0100 Subject: [PATCH 29/49] Check full contributor list for New Contributors section Use gh API to check against all repo contributors instead of just the previous release, so only truly first-time contributors are listed. Co-Authored-By: Claude Opus 4.6 --- .claude/commands/release.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.claude/commands/release.md b/.claude/commands/release.md index a5a039f4a08..0ea15b0b758 100644 --- a/.claude/commands/release.md +++ b/.claude/commands/release.md @@ -15,7 +15,7 @@ - Categorize PRs into sections: "What's Changed", "Templates", "Docs", "Internal" - In "What's Changed", sort items so that entries for the same package are adjacent (no subheadings, just sorted order) - Strip redundant prefixes from PR titles (e.g. remove "Docs:" from items in the Docs section) - - "Templates" is a separate section for any template-* changes - - Do NOT add a "New Contributors" section - contributors may appear new in a version range but not actually be first-time contributors + - "Templates" is a separate section for any template-\* changes + - Check for genuinely new contributors by running `gh api repos/remotion-dev/remotion/contributors --paginate --jq '.[].login'` and comparing against PR authors. Only add a "New Contributors" section for authors not in that list - Add `**Full Changelog**: https://github.com/remotion-dev/remotion/compare/v...v` at the bottom - Use the same format as previous GitHub releases (check with `gh release view v`) From f01fd916f2582f1d3b7221b5c2787ffd32460580 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Thu, 19 Feb 2026 09:33:42 +0100 Subject: [PATCH 30/49] Prioritize remotion core package at top of changelog Co-Authored-By: Claude Opus 4.6 --- .claude/commands/release.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/commands/release.md b/.claude/commands/release.md index 0ea15b0b758..84d0dd4ecfc 100644 --- a/.claude/commands/release.md +++ b/.claude/commands/release.md @@ -13,7 +13,7 @@ - Extract PR numbers from merge commits - For each PR, run `gh pr view --json title,author,number,url --jq '"* \(.title) by @\(.author.login) in \(.url)"'` - Categorize PRs into sections: "What's Changed", "Templates", "Docs", "Internal" - - In "What's Changed", sort items so that entries for the same package are adjacent (no subheadings, just sorted order) + - In "What's Changed", sort items so that entries for the same package are adjacent (no subheadings, just sorted order). Changes to the `remotion` core package should appear first - Strip redundant prefixes from PR titles (e.g. remove "Docs:" from items in the Docs section) - "Templates" is a separate section for any template-\* changes - Check for genuinely new contributors by running `gh api repos/remotion-dev/remotion/contributors --paginate --jq '.[].login'` and comparing against PR authors. Only add a "New Contributors" section for authors not in that list From 0be7801fd86e9c3aa1082dd783d30a6c3b1ed5b3 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Thu, 19 Feb 2026 09:33:51 +0100 Subject: [PATCH 31/49] Simplify web-renderer to only support Zod v4 Remove custom InferZodInput type and use z.input from Zod v4 directly. Replace AnyZodObject (v3/v4 union) with $ZodObject from zod/v4/core as the schema constraint. Co-Authored-By: Claude Opus 4.6 --- packages/web-renderer/src/create-scaffold.tsx | 11 ++---- .../web-renderer/src/props-if-has-props.ts | 36 ++++++++----------- .../web-renderer/src/render-media-on-web.tsx | 31 ++++++++-------- .../web-renderer/src/render-still-on-web.tsx | 14 ++++---- 4 files changed, 40 insertions(+), 52 deletions(-) diff --git a/packages/web-renderer/src/create-scaffold.tsx b/packages/web-renderer/src/create-scaffold.tsx index 7fe063a1db6..02d7237a063 100644 --- a/packages/web-renderer/src/create-scaffold.tsx +++ b/packages/web-renderer/src/create-scaffold.tsx @@ -1,14 +1,9 @@ import {createRef, type ComponentType} from 'react'; import {flushSync} from 'react-dom'; import ReactDOM from 'react-dom/client'; -import type { - AnyZodObject, - Codec, - DelayRenderScope, - LogLevel, - TRenderAsset, -} from 'remotion'; +import type {Codec, DelayRenderScope, LogLevel, TRenderAsset} from 'remotion'; import {Internals} from 'remotion'; +import type {$ZodObject} from 'zod/v4/core'; import type {TimeUpdaterRef} from './update-time'; import {UpdateTime} from './update-time'; @@ -50,7 +45,7 @@ export function createScaffold>({ initialFrame: number; durationInFrames: number; fps: number; - schema: AnyZodObject | null; + schema: $ZodObject | null; Component: ComponentType; audioEnabled: boolean; videoEnabled: boolean; diff --git a/packages/web-renderer/src/props-if-has-props.ts b/packages/web-renderer/src/props-if-has-props.ts index 87fbe09429d..3e9564ac209 100644 --- a/packages/web-renderer/src/props-if-has-props.ts +++ b/packages/web-renderer/src/props-if-has-props.ts @@ -1,18 +1,12 @@ import type {ComponentType} from 'react'; -import type {AnyZodObject, CalculateMetadataFunction} from 'remotion'; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export type InferZodInput = T extends {_zod: {input: any}} - ? T['_zod']['input'] - : // eslint-disable-next-line @typescript-eslint/no-explicit-any - T extends {_input: any} - ? T['_input'] - : Record; +import type {CalculateMetadataFunction} from 'remotion'; +import type {z} from 'zod'; +import type {$ZodObject} from 'zod/v4/core'; export type InferProps< - Schema extends AnyZodObject, + Schema extends $ZodObject, Props extends Record, -> = AnyZodObject extends Schema +> = $ZodObject extends Schema ? {} extends Props ? // Neither props nor schema specified Record @@ -20,18 +14,18 @@ export type InferProps< Props : {} extends Props ? // Only schema specified - InferZodInput + z.input : // Props and schema specified - InferZodInput & Props; + z.input & Props; export type DefaultPropsIfHasProps< - Schema extends AnyZodObject, + Schema extends $ZodObject, Props, -> = AnyZodObject extends Schema +> = $ZodObject extends Schema ? {} extends Props ? { // Neither props nor schema specified - defaultProps?: InferZodInput & Props; + defaultProps?: z.input & Props; } : { // Only props specified @@ -40,17 +34,17 @@ export type DefaultPropsIfHasProps< : {} extends Props ? { // Only schema specified - defaultProps: InferZodInput; + defaultProps: z.input; } : { // Props and schema specified - defaultProps: InferZodInput & Props; + defaultProps: z.input & Props; }; type LooseComponentType = ComponentType | ((props: T) => React.ReactNode); type OptionalDimensions< - Schema extends AnyZodObject, + Schema extends $ZodObject, Props extends Record, > = { component: LooseComponentType; @@ -61,7 +55,7 @@ type OptionalDimensions< }; type MandatoryDimensions< - Schema extends AnyZodObject, + Schema extends $ZodObject, Props extends Record, > = { component: LooseComponentType; @@ -74,7 +68,7 @@ type MandatoryDimensions< }; export type CompositionCalculateMetadataOrExplicit< - Schema extends AnyZodObject, + Schema extends $ZodObject, Props extends Record, > = ( | (OptionalDimensions & { diff --git a/packages/web-renderer/src/render-media-on-web.tsx b/packages/web-renderer/src/render-media-on-web.tsx index 9d9e55b6f4e..74c455495e7 100644 --- a/packages/web-renderer/src/render-media-on-web.tsx +++ b/packages/web-renderer/src/render-media-on-web.tsx @@ -1,7 +1,9 @@ import {BufferTarget, StreamTarget} from 'mediabunny'; -import type {AnyZodObject, CalculateMetadataFunction} from 'remotion'; +import type {CalculateMetadataFunction} from 'remotion'; import {Internals, type LogLevel} from 'remotion'; import {VERSION} from 'remotion/version'; +import type {z} from 'zod'; +import type {$ZodObject} from 'zod/v4/core'; import {addAudioSample, addVideoSampleAndCloseFrame} from './add-sample'; import {handleArtifacts, type WebRendererOnArtifact} from './artifact'; import {onlyInlineAudio} from './audio'; @@ -31,10 +33,7 @@ import { type WebRendererVideoCodec, } from './mediabunny-mappings'; import type {WebRendererOutputTarget} from './output-target'; -import type { - CompositionCalculateMetadataOrExplicit, - InferZodInput, -} from './props-if-has-props'; +import type {CompositionCalculateMetadataOrExplicit} from './props-if-has-props'; import {onlyOneRenderAtATimeQueue} from './render-operations-queue'; import {resolveAudioCodec} from './resolve-audio-codec'; import {sendUsageEvent} from './send-telemetry-event'; @@ -46,13 +45,13 @@ import {waitForReady} from './wait-for-ready'; import {cleanupStaleOpfsFiles, createWebFsTarget} from './web-fs-target'; export type InputPropsIfHasProps< - Schema extends AnyZodObject, + Schema extends $ZodObject, Props, -> = AnyZodObject extends Schema +> = $ZodObject extends Schema ? {} extends Props ? { // Neither props nor schema specified - inputProps?: InferZodInput & Props; + inputProps?: z.input & Props; } : { // Only props specified @@ -61,15 +60,15 @@ export type InputPropsIfHasProps< : {} extends Props ? { // Only schema specified - inputProps: InferZodInput; + inputProps: z.input; } : { // Props and schema specified - inputProps: InferZodInput & Props; + inputProps: z.input & Props; }; type MandatoryRenderMediaOnWebOptions< - Schema extends AnyZodObject, + Schema extends $ZodObject, Props extends Record, > = { composition: CompositionCalculateMetadataOrExplicit; @@ -95,7 +94,7 @@ export type WebRendererHardwareAcceleration = | 'prefer-hardware' | 'prefer-software'; -type OptionalRenderMediaOnWebOptions = { +type OptionalRenderMediaOnWebOptions = { delayRenderTimeoutInMilliseconds: number; logLevel: LogLevel; schema: Schema | undefined; @@ -121,14 +120,14 @@ type OptionalRenderMediaOnWebOptions = { }; export type RenderMediaOnWebOptions< - Schema extends AnyZodObject, + Schema extends $ZodObject, Props extends Record, > = MandatoryRenderMediaOnWebOptions & Partial> & InputPropsIfHasProps; type InternalRenderMediaOnWebOptions< - Schema extends AnyZodObject, + Schema extends $ZodObject, Props extends Record, > = MandatoryRenderMediaOnWebOptions & OptionalRenderMediaOnWebOptions & @@ -139,7 +138,7 @@ type InternalRenderMediaOnWebOptions< // TODO: Apply defaultCodec const internalRenderMediaOnWeb = async < - Schema extends AnyZodObject, + Schema extends $ZodObject, Props extends Record, >({ composition, @@ -534,7 +533,7 @@ const internalRenderMediaOnWeb = async < }; export const renderMediaOnWeb = < - Schema extends AnyZodObject, + Schema extends $ZodObject, Props extends Record, >( options: RenderMediaOnWebOptions, diff --git a/packages/web-renderer/src/render-still-on-web.tsx b/packages/web-renderer/src/render-still-on-web.tsx index bce0cb6a444..ce28d2125ad 100644 --- a/packages/web-renderer/src/render-still-on-web.tsx +++ b/packages/web-renderer/src/render-still-on-web.tsx @@ -1,9 +1,9 @@ -import type {AnyZodObject} from 'remotion'; import { Internals, type CalculateMetadataFunction, type LogLevel, } from 'remotion'; +import type {$ZodObject} from 'zod/v4/core'; import type {WebRendererOnArtifact} from './artifact'; import {handleArtifacts} from './artifact'; import {checkForError, createScaffold} from './create-scaffold'; @@ -20,7 +20,7 @@ import {waitForReady} from './wait-for-ready'; export type RenderStillOnWebImageFormat = 'png' | 'jpeg' | 'webp'; type MandatoryRenderStillOnWebOptions< - Schema extends AnyZodObject, + Schema extends $ZodObject, Props extends Record, > = { frame: number; @@ -29,7 +29,7 @@ type MandatoryRenderStillOnWebOptions< composition: CompositionCalculateMetadataOrExplicit; }; -type OptionalRenderStillOnWebOptions = { +type OptionalRenderStillOnWebOptions = { delayRenderTimeoutInMilliseconds: number; logLevel: LogLevel; schema: Schema | undefined; @@ -42,21 +42,21 @@ type OptionalRenderStillOnWebOptions = { }; type InternalRenderStillOnWebOptions< - Schema extends AnyZodObject, + Schema extends $ZodObject, Props extends Record, > = MandatoryRenderStillOnWebOptions & OptionalRenderStillOnWebOptions & InputPropsIfHasProps; export type RenderStillOnWebOptions< - Schema extends AnyZodObject, + Schema extends $ZodObject, Props extends Record, > = MandatoryRenderStillOnWebOptions & Partial> & InputPropsIfHasProps; async function internalRenderStillOnWeb< - Schema extends AnyZodObject, + Schema extends $ZodObject, Props extends Record, >({ frame, @@ -187,7 +187,7 @@ async function internalRenderStillOnWeb< } export const renderStillOnWeb = < - Schema extends AnyZodObject, + Schema extends $ZodObject, Props extends Record, >( options: RenderStillOnWebOptions, From a19eefa0a736c21b28bf6703aa8c48571eecd31e Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Thu, 19 Feb 2026 09:44:04 +0100 Subject: [PATCH 32/49] Update GitHub stars from 36k to 37k Co-Authored-By: Claude Opus 4.6 --- .../promo-pages/src/components/homepage/CommunityStatsItems.tsx | 2 +- packages/promo-pages/src/components/homepage/GitHubButton.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/promo-pages/src/components/homepage/CommunityStatsItems.tsx b/packages/promo-pages/src/components/homepage/CommunityStatsItems.tsx index b8e29bb163b..b8cac935ccf 100644 --- a/packages/promo-pages/src/components/homepage/CommunityStatsItems.tsx +++ b/packages/promo-pages/src/components/homepage/CommunityStatsItems.tsx @@ -177,7 +177,7 @@ export const GitHubStars: React.FC = () => { width="45px" /> {
GitHub{' '}
- {'36k'} + {'37k'}
); From 83f8f02e134f34eba975756d820cc3bf78008873 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Thu, 19 Feb 2026 09:56:44 +0100 Subject: [PATCH 33/49] better docs --- packages/docs/docs/zod-types-v3/index.mdx | 3 +- packages/docs/docs/zod-types/index.mdx | 4 +- packages/docs/docs/zod-types/v3.mdx | 48 +++++++++++++++++++---- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/packages/docs/docs/zod-types-v3/index.mdx b/packages/docs/docs/zod-types-v3/index.mdx index a70701e7f24..1a6f6c57e64 100644 --- a/packages/docs/docs/zod-types-v3/index.mdx +++ b/packages/docs/docs/zod-types-v3/index.mdx @@ -9,7 +9,8 @@ import {ZodTypesTableOfContents} from '../zod-types/TableOfContents'; This package provides the same utility types as [`@remotion/zod-types`](/docs/zod-types), but based on Zod 3.22.3 instead of Zod v4. Use this package if you are composing Remotion's Zod types with your own schemas that use Zod 3.22.3. -If you are using Zod v4, use [`@remotion/zod-types`](/docs/zod-types) instead. +If you are using Zod v4, use [`@remotion/zod-types`](/docs/zod-types) instead. +Other versions of Zod v3 might not compose well – we recommend staying on Zod 3.22.3 or upgrading to Zod v4. diff --git a/packages/docs/docs/zod-types/index.mdx b/packages/docs/docs/zod-types/index.mdx index 7713c187a37..976a911ac89 100644 --- a/packages/docs/docs/zod-types/index.mdx +++ b/packages/docs/docs/zod-types/index.mdx @@ -10,9 +10,9 @@ import TabItem from '@theme/TabItem'; import {ZodTypesTableOfContents} from './TableOfContents'; Since Remotion v4.0.426, `@remotion/zod-types` is based on Zod v4. -If you want to compose these types with your own Zod schemas, use Zod v4. +If you want, you can now upgrade to Zod v4. -If you are using Zod 3.22.3, use [`@remotion/zod-types-v3`](/docs/zod-types-v3) instead. +If you want to stay on Zod 3.22.3 as previously required by Remotion, use [`@remotion/zod-types-v3`](/docs/zod-types-v3) instead of [`@remotion/zod-types`](/docs/zod-types). Other versions of Zod v3 might not compose well – we recommend staying on Zod 3.22.3 or upgrading to Zod v4. Includes utility types and Remotion-specific types for [Zod](https://github.com/colinhacks/zod). diff --git a/packages/docs/docs/zod-types/v3.mdx b/packages/docs/docs/zod-types/v3.mdx index 8dabcf45cab..94df07c252a 100644 --- a/packages/docs/docs/zod-types/v3.mdx +++ b/packages/docs/docs/zod-types/v3.mdx @@ -1,11 +1,15 @@ --- image: /generated/articles-docs-zod-types-v3.png -sidebar_label: Zod v3 +sidebar_label: Zod 3 vs. Zod 4 title: '@remotion/zod-types-v3' crumb: Schema --- -`@remotion/zod-types` creates schemas using Zod v4. If you are still using Zod v3 and need to compose Remotion schemas into a `z.object()`, use `@remotion/zod-types-v3` instead. +# @remotion/zod-types-v3 + +[`@remotion/zod-types`](/docs/zod-types) creates schemas using Zod v4 since Remotion v4.0.426. + +This package is for if you are using Zod v3.22.3 and want to compose functions like [`zColor()`] with Zod v3.22.3 schemas. ## Installation @@ -13,8 +17,8 @@ crumb: Schema ## Usage -```tsx title="Using @remotion/zod-types-v3 with Zod v3" -import {z} from 'zod'; +```tsx twoslash title="Using @remotion/zod-types-v3 with Zod v3" +import {z} from 'zod'; // zod = 3.22.3 import {zColor} from '@remotion/zod-types-v3'; export const mySchema = z.object({ @@ -22,12 +26,42 @@ export const mySchema = z.object({ }); ``` -The package exports the same `zColor()`, `zTextarea()`, and `zMatrix()` functions as `@remotion/zod-types`, but they return Zod v3 schema types. +The package exports the same [`zColor()`](/docs/zod-types/z-color), [`zTextarea()`](/docs/zod-types/z-textarea), and [`zMatrix()`](/docs/zod-types/z-matrix) functions as [`@remotion/zod-types`](/docs/zod-types), but they return Zod v3.22.3 schema types. ## When to use -- Use `@remotion/zod-types` (default) if you are using Zod v4. -- Use `@remotion/zod-types-v3` if you are still on Zod v3. +Use [`@remotion/zod-types`](/docs/zod-types) with Zod v4: + +```tsx twoslash +import {z} from 'zod'; // zod = 4.x.x +import {zColor} from '@remotion/zod-types'; + +export const mySchema = z.object({ + color: zColor(), +}); +``` + +Use [`@remotion/zod-types`](/docs/zod-types) if you are not nesting schemas: + +```tsx twoslash +import {zColor} from '@remotion/zod-types'; +import {visualControl} from '@remotion/studio'; + +export const myVisualControl = visualControl('my-color', '#fff', zColor()); +``` + +Use [`@remotion/zod-types-v3`](/docs/zod-types-v3) with Zod v3.22.3: + +```tsx twoslash +import {z} from 'zod'; // zod = 3.22.3 +import {zColor} from '@remotion/zod-types-v3'; + +export const mySchema = z.object({ + color: zColor(), +}); +``` + +Other Zod 3.x.x versions are not officially supported. ## See also From 048cd15b43e8ab792a42823bdb038e35ad39aa38 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Thu, 19 Feb 2026 09:58:59 +0100 Subject: [PATCH 34/49] one page too many --- packages/docs/docs/zod-types-v3/index.mdx | 27 ----------------------- packages/docs/sidebars.ts | 9 -------- 2 files changed, 36 deletions(-) delete mode 100644 packages/docs/docs/zod-types-v3/index.mdx diff --git a/packages/docs/docs/zod-types-v3/index.mdx b/packages/docs/docs/zod-types-v3/index.mdx deleted file mode 100644 index 1a6f6c57e64..00000000000 --- a/packages/docs/docs/zod-types-v3/index.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -sidebar_label: Overview -title: '@remotion/zod-types-v3' -crumb: Schema ---- - -import {ZodTypesTableOfContents} from '../zod-types/TableOfContents'; - -This package provides the same utility types as [`@remotion/zod-types`](/docs/zod-types), but based on Zod 3.22.3 instead of Zod v4. - -Use this package if you are composing Remotion's Zod types with your own schemas that use Zod 3.22.3. -If you are using Zod v4, use [`@remotion/zod-types`](/docs/zod-types) instead. -Other versions of Zod v3 might not compose well – we recommend staying on Zod 3.22.3 or upgrading to Zod v4. - - - -## Installation - - - -## API - - - -## License - -[Remotion License](https://remotion.dev/license) diff --git a/packages/docs/sidebars.ts b/packages/docs/sidebars.ts index af734d8068d..3b924af0a16 100644 --- a/packages/docs/sidebars.ts +++ b/packages/docs/sidebars.ts @@ -769,15 +769,6 @@ const sidebars: SidebarsConfig = { 'zod-types/v3', ], }, - { - type: 'category', - label: '@remotion/zod-types-v3', - link: { - type: 'doc', - id: 'zod-types-v3/index', - }, - items: [], - }, { type: 'html', value: From 78d5b6dda059e37f2386a466d04eb79b1fcc97f2 Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Thu, 19 Feb 2026 10:03:19 +0100 Subject: [PATCH 35/49] `@remotion/docusaurus-plugin`: Fix title fence not rendering in code blocks Co-Authored-By: Claude Opus 4.6 --- packages/docusaurus-plugin/src/shiki.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/docusaurus-plugin/src/shiki.ts b/packages/docusaurus-plugin/src/shiki.ts index b467c3fbc36..f0c6fba12b6 100644 --- a/packages/docusaurus-plugin/src/shiki.ts +++ b/packages/docusaurus-plugin/src/shiki.ts @@ -186,8 +186,7 @@ const remarkVisitor = md: 'markdown', txt: 'plaintext', }; - const resolvedLang = - langAliases[fence.lang] || fence.lang || 'plaintext'; + const resolvedLang = langAliases[fence.lang] || fence.lang || 'plaintext'; try { shikiHTML = highlighter.codeToHtml(node.value, { @@ -209,6 +208,19 @@ const remarkVisitor = ); } + // Inject title bar if fence has a title attribute + if (fence.meta.title && typeof fence.meta.title === 'string') { + const title = fence.meta.title; + shikiHTML = shikiHTML.replace( + '
]*>)/,
+				`$1
${title}
`, + ); + } + // @ts-expect-error node.type = 'mdxJsxFlowElement'; node.name = 'div'; From cec3bf0f4c03c02a5260e92084f3e8473d02e83c Mon Sep 17 00:00:00 2001 From: Jonny Burger Date: Thu, 19 Feb 2026 10:06:58 +0100 Subject: [PATCH 36/49] Update shiki.ts --- packages/docusaurus-plugin/src/shiki.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus-plugin/src/shiki.ts b/packages/docusaurus-plugin/src/shiki.ts index f0c6fba12b6..28039fb581d 100644 --- a/packages/docusaurus-plugin/src/shiki.ts +++ b/packages/docusaurus-plugin/src/shiki.ts @@ -210,7 +210,7 @@ const remarkVisitor = // Inject title bar if fence has a title attribute if (fence.meta.title && typeof fence.meta.title === 'string') { - const title = fence.meta.title; + const {title} = fence.meta; shikiHTML = shikiHTML.replace( '
Date: Thu, 19 Feb 2026 10:08:57 +0100
Subject: [PATCH 37/49] update docs

---
 .../docs/web-renderer/render-media-on-web.mdx   |   8 ++++----
 .../docs/web-renderer/render-still-on-web.mdx   |   8 ++++----
 packages/docs/docs/zod-types/index.mdx          |  12 ++++++------
 packages/docs/docs/zod-types/v3.mdx             |   4 ++--
 packages/docs/src/data/articles.ts              |   9 +++++++++
 .../generated/articles-docs-zod-types-v3.png    | Bin 0 -> 49602 bytes
 6 files changed, 25 insertions(+), 16 deletions(-)
 create mode 100644 packages/docs/static/generated/articles-docs-zod-types-v3.png

diff --git a/packages/docs/docs/web-renderer/render-media-on-web.mdx b/packages/docs/docs/web-renderer/render-media-on-web.mdx
index 25b22c2eb8e..f4ea4686d77 100644
--- a/packages/docs/docs/web-renderer/render-media-on-web.mdx
+++ b/packages/docs/docs/web-renderer/render-media-on-web.mdx
@@ -5,6 +5,8 @@ title: renderMediaOnWeb()
 crumb: '@remotion/web-renderer'
 ---
 
+# renderMediaOnWeb()
+
 :::warning
 Very experimental feature - expect bugs and breaking changes at any time.  
 [Track progress on GitHub](https://github.com/remotion-dev/remotion/issues/5913) and discuss in the [`#web-renderer`](https://remotion.dev/discord) channel on Discord.
@@ -12,8 +14,6 @@ Very experimental feature - expect bugs and breaking changes at any time.
 
 _Part of the `@remotion/web-renderer` package._
 
-
-
 Renders a video or audio in the browser.  
 If you want to render a single frame to an image, use [`renderStillOnWeb()`](/docs/web-renderer/render-still-on-web).
 
@@ -271,9 +271,9 @@ By default, Remotion will automatically choose `"web-fs"` if available, otherwis
 
 ### `schema?`
 
-_Zod schema_ 
+_Zod v4 schema_ 
 
-A Zod schema to validate the input props.  
+A Zod v4 schema to validate the input props.
 See [Schemas](/docs/schemas) for more information.
 
 ### `licenseKey?`
diff --git a/packages/docs/docs/web-renderer/render-still-on-web.mdx b/packages/docs/docs/web-renderer/render-still-on-web.mdx
index 5a269c150b6..df7a24fbab4 100644
--- a/packages/docs/docs/web-renderer/render-still-on-web.mdx
+++ b/packages/docs/docs/web-renderer/render-still-on-web.mdx
@@ -5,6 +5,8 @@ title: renderStillOnWeb()
 crumb: '@remotion/web-renderer'
 ---
 
+# renderStillOnWeb()
+
 :::warning
 Very experimental feature - expect bugs and breaking changes at any time.  
 [Track progress on GitHub](https://github.com/remotion-dev/remotion/issues/5913) and discuss in the [`#web-renderer`](https://remotion.dev/discord) channel on Discord.
@@ -12,8 +14,6 @@ Very experimental feature - expect bugs and breaking changes at any time.
 
 _Part of the `@remotion/web-renderer` package._
 
-
-
 Renders a single frame to an image in the browser.  
 If you want to render a video instead, use [`renderMediaOnWeb()`](/docs/web-renderer/render-media-on-web).
 
@@ -149,9 +149,9 @@ _function_
 
 ### `schema?`
 
-_Zod schema_ 
+_Zod v4 schema_ 
 
-A Zod schema to validate the input props.  
+A Zod v4 schema to validate the input props.
 See [Schemas](/docs/schemas) for more information.
 
 ### `licenseKey?`
diff --git a/packages/docs/docs/zod-types/index.mdx b/packages/docs/docs/zod-types/index.mdx
index 976a911ac89..7c00981c258 100644
--- a/packages/docs/docs/zod-types/index.mdx
+++ b/packages/docs/docs/zod-types/index.mdx
@@ -9,14 +9,14 @@ import Tabs from '@theme/Tabs';
 import TabItem from '@theme/TabItem';
 import {ZodTypesTableOfContents} from './TableOfContents';
 
-Since Remotion v4.0.426, `@remotion/zod-types` is based on Zod v4.
-If you want, you can now upgrade to Zod v4.
-
-If you want to stay on Zod 3.22.3 as previously required by Remotion, use [`@remotion/zod-types-v3`](/docs/zod-types-v3) instead of [`@remotion/zod-types`](/docs/zod-types).
-Other versions of Zod v3 might not compose well – we recommend staying on Zod 3.22.3 or upgrading to Zod v4.
-
 Includes utility types and Remotion-specific types for [Zod](https://github.com/colinhacks/zod).
 
+:::note
+Since Remotion v4.0.426, `@remotion/zod-types` is based on Zod v4.
+If you want, you can now upgrade to Zod v4.  
+If you want to stay on Zod 3.22.3 as previously required by Remotion, use [`@remotion/zod-types-v3`](/docs/zod-types/v3) instead of [`@remotion/zod-types`](/docs/zod-types).
+:::
+
 ## Installation
 
 
diff --git a/packages/docs/docs/zod-types/v3.mdx b/packages/docs/docs/zod-types/v3.mdx
index 94df07c252a..afbfe500302 100644
--- a/packages/docs/docs/zod-types/v3.mdx
+++ b/packages/docs/docs/zod-types/v3.mdx
@@ -2,14 +2,14 @@
 image: /generated/articles-docs-zod-types-v3.png
 sidebar_label: Zod 3 vs. Zod 4
 title: '@remotion/zod-types-v3'
-crumb: Schema
+crumb: '@remotion/zod-types'
 ---
 
 # @remotion/zod-types-v3
 
 [`@remotion/zod-types`](/docs/zod-types) creates schemas using Zod v4 since Remotion v4.0.426.
 
-This package is for if you are using Zod v3.22.3 and want to compose functions like [`zColor()`] with Zod v3.22.3 schemas.
+This package is for if you are using Zod v3.22.3 and want to compose functions like [`zColor()`](/docs/zod-types/z-color) with Zod v3.22.3 schemas.
 
 ## Installation
 
diff --git a/packages/docs/src/data/articles.ts b/packages/docs/src/data/articles.ts
index 12cc0c068ea..4c017c8e851 100644
--- a/packages/docs/src/data/articles.ts
+++ b/packages/docs/src/data/articles.ts
@@ -7087,6 +7087,15 @@ export const articles = [
 		noAi: false,
 		slug: 'zod-types/index',
 	},
+	{
+		id: 'zod-types/v3',
+		title: '@remotion/zod-types-v3',
+		relativePath: 'docs/zod-types/v3.mdx',
+		compId: 'articles-docs-zod-types-v3',
+		crumb: '@remotion/zod-types',
+		noAi: false,
+		slug: 'zod-types/v3',
+	},
 	{
 		id: 'zod-types/z-color',
 		title: 'zColor()',
diff --git a/packages/docs/static/generated/articles-docs-zod-types-v3.png b/packages/docs/static/generated/articles-docs-zod-types-v3.png
new file mode 100644
index 0000000000000000000000000000000000000000..29d307f461132ce97565d13c82da3191ec429b8b
GIT binary patch
literal 49602
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

literal 0
HcmV?d00001


From e0e0bb07f7fab00ad4eacaa8e6bfb956cbadf304 Mon Sep 17 00:00:00 2001
From: Jonny Burger 
Date: Thu, 19 Feb 2026 10:14:01 +0100
Subject: [PATCH 38/49] Update package-info.ts

---
 packages/studio-shared/src/package-info.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/studio-shared/src/package-info.ts b/packages/studio-shared/src/package-info.ts
index 7ce2637fc41..00e1cc83d4c 100644
--- a/packages/studio-shared/src/package-info.ts
+++ b/packages/studio-shared/src/package-info.ts
@@ -128,7 +128,7 @@ export const descriptions: {[key in Pkgs]: string | null} = {
 	preload: 'Preloads assets for use in Remotion',
 	shapes: 'Generate SVG shapes',
 	'zod-types': 'Zod types for Remotion',
-	'zod-types-v3': 'Zod v3 types for Remotion',
+	'zod-types-v3': 'Zod 3.22.3 types for Remotion',
 	gif: 'Embed GIFs in a Remotion video',
 	'eslint-plugin': 'Rules for writing Remotion code',
 	'eslint-config': 'Default configuration for Remotion templates (ESLint <= 8)',

From e364b8a3fafe4211adfd8b326a9cfa756b58a1db Mon Sep 17 00:00:00 2001
From: Jonny Burger 
Date: Thu, 19 Feb 2026 10:14:05 +0100
Subject: [PATCH 39/49] aha, simplify

---
 packages/studio/src/api/save-default-props.ts | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/packages/studio/src/api/save-default-props.ts b/packages/studio/src/api/save-default-props.ts
index 5f4e660283e..c0736bbf2e2 100644
--- a/packages/studio/src/api/save-default-props.ts
+++ b/packages/studio/src/api/save-default-props.ts
@@ -1,7 +1,6 @@
 import {getRemotionEnvironment} from 'remotion';
 import type {ZodTypesType} from '../components/get-zod-if-possible';
 import {extractEnumJsonPaths} from '../components/RenderModal/SchemaEditor/extract-enum-json-paths';
-import type {AnyZodSchema} from '../components/RenderModal/SchemaEditor/zod-schema-type';
 import {callUpdateDefaultPropsApi} from '../components/RenderQueue/actions';
 import type {UpdateDefaultPropsFunction} from './helpers/calc-new-props';
 import {calcNewProps} from './helpers/calc-new-props';
@@ -49,7 +48,7 @@ export const saveDefaultProps = async ({
 		generatedDefaultProps,
 		composition.schema
 			? extractEnumJsonPaths({
-					schema: composition.schema as AnyZodSchema,
+					schema: composition.schema,
 					zodRuntime: z,
 					currentPath: [],
 					zodTypes,

From 81b8b4687d07c5bd52f742abe876fbec190cac66 Mon Sep 17 00:00:00 2001
From: Jonny Burger 
Date: Thu, 19 Feb 2026 10:14:49 +0100
Subject: [PATCH 40/49] Update package-info.ts

---
 packages/studio-shared/src/package-info.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/studio-shared/src/package-info.ts b/packages/studio-shared/src/package-info.ts
index 00e1cc83d4c..c3676a2e1ee 100644
--- a/packages/studio-shared/src/package-info.ts
+++ b/packages/studio-shared/src/package-info.ts
@@ -306,7 +306,7 @@ export const apiDocs: {[key in Pkgs]: string | null} = {
 	preload: 'https://www.remotion.dev/docs/preload',
 	shapes: 'https://www.remotion.dev/docs/shapes',
 	'zod-types': 'https://www.remotion.dev/docs/zod-types',
-	'zod-types-v3': 'https://www.remotion.dev/docs/zod-types',
+	'zod-types-v3': 'https://www.remotion.dev/docs/zod-types/v3',
 	gif: 'https://www.remotion.dev/docs/gif',
 	'eslint-plugin':
 		'https://www.remotion.dev/docs/brownfield#install-the-eslint-plugin',

From 70b8070b6a43c769643ff1573dc923ee1ee136e2 Mon Sep 17 00:00:00 2001
From: Jonny Burger 
Date: Thu, 19 Feb 2026 10:21:06 +0100
Subject: [PATCH 41/49] new recommended package

---
 packages/cli/src/extra-packages.ts         | 2 ++
 packages/studio-shared/src/package-info.ts | 6 ++++++
 2 files changed, 8 insertions(+)

diff --git a/packages/cli/src/extra-packages.ts b/packages/cli/src/extra-packages.ts
index bb5f65ca15e..2ea64760ad8 100644
--- a/packages/cli/src/extra-packages.ts
+++ b/packages/cli/src/extra-packages.ts
@@ -1,7 +1,9 @@
 export const EXTRA_PACKAGES: Record = {
 	mediabunny: '1.34.4',
+	zod: '4.3.6',
 };
 
 export const EXTRA_PACKAGES_DOCS: Record = {
 	mediabunny: 'https://www.remotion.dev/docs/mediabunny/version',
+	zod: 'https://zod.dev',
 };
diff --git a/packages/studio-shared/src/package-info.ts b/packages/studio-shared/src/package-info.ts
index c3676a2e1ee..3a1d6c4fa6f 100644
--- a/packages/studio-shared/src/package-info.ts
+++ b/packages/studio-shared/src/package-info.ts
@@ -101,6 +101,12 @@ export const extraPackages: ExtraPackage[] = [
 		description: 'Multimedia library used by Remotion',
 		docsUrl: 'https://www.remotion.dev/docs/mediabunny/version',
 	},
+	{
+		name: 'zod',
+		version: '4.3.6',
+		description: 'TypeScript-first schema validation',
+		docsUrl: 'https://zod.dev',
+	},
 ];
 
 export const descriptions: {[key in Pkgs]: string | null} = {

From dadd43c9a59554fbee7c3efa4d3e4a5aaf664cfe Mon Sep 17 00:00:00 2001
From: Jonny Burger 
Date: Thu, 19 Feb 2026 10:23:15 +0100
Subject: [PATCH 42/49] Update v3.mdx

---
 packages/docs/docs/zod-types/v3.mdx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/docs/docs/zod-types/v3.mdx b/packages/docs/docs/zod-types/v3.mdx
index afbfe500302..5d5c8553a06 100644
--- a/packages/docs/docs/zod-types/v3.mdx
+++ b/packages/docs/docs/zod-types/v3.mdx
@@ -50,7 +50,7 @@ import {visualControl} from '@remotion/studio';
 export const myVisualControl = visualControl('my-color', '#fff', zColor());
 ```
 
-Use [`@remotion/zod-types-v3`](/docs/zod-types-v3) with Zod v3.22.3:
+Use `@remotion/zod-types-v3` with Zod v3.22.3:
 
 ```tsx twoslash
 import {z} from 'zod'; // zod = 3.22.3

From de152234d9e90c43126c5b74d73dcbed999e6eac Mon Sep 17 00:00:00 2001
From: Mehmet <86873911+MehmetAdemi@users.noreply.github.com>
Date: Thu, 19 Feb 2026 10:24:42 +0100
Subject: [PATCH 43/49] Update investors page

---
 packages/docs/docs/investors.mdx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/docs/docs/investors.mdx b/packages/docs/docs/investors.mdx
index 812298346b9..60270f108ad 100644
--- a/packages/docs/docs/investors.mdx
+++ b/packages/docs/docs/investors.mdx
@@ -42,7 +42,7 @@ See also: [Why we are not building Lovable for Motion Graphics](/docs/lovable-fo
 
 ## Customers
 
-Remotion has over 150 active customers, making us very diversified.  
+Remotion has over 200 active customers, making us very diversified.  
 Our goal is to make Remotion a framework that works for everyone, not favoring any specific customer.
 
 ## Shark Tank appearance

From 09e8bf279351b48912b7a9419504a28f52820955 Mon Sep 17 00:00:00 2001
From: Jonny Burger 
Date: Thu, 19 Feb 2026 10:31:08 +0100
Subject: [PATCH 44/49] be more precise

---
 packages/zod-types-v3/README.md    | 4 ++--
 packages/zod-types-v3/package.json | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/packages/zod-types-v3/README.md b/packages/zod-types-v3/README.md
index a0a0c5b5f12..7e6f5fdd650 100644
--- a/packages/zod-types-v3/README.md
+++ b/packages/zod-types-v3/README.md
@@ -1,6 +1,6 @@
 # @remotion/zod-types-v3
  
-Zod v3 types for Remotion
+Zod 3.22.3 types for Remotion
  
 [![NPM Downloads](https://img.shields.io/npm/dm/@remotion/zod-types-v3.svg?style=flat&color=black&label=Downloads)](https://npmcharts.com/compare/@remotion/zod-types-v3?minimal=true)
  
@@ -15,4 +15,4 @@ Remove the `^` character from the version number to use the exact version.
  
 ## Usage
  
-See the [documentation](https://www.remotion.dev/docs/zod-types) for more information.
+See the [documentation](https://www.remotion.dev/docs/zod-types/v3) for more information.
diff --git a/packages/zod-types-v3/package.json b/packages/zod-types-v3/package.json
index 366a362ff83..6dcf705f0b1 100644
--- a/packages/zod-types-v3/package.json
+++ b/packages/zod-types-v3/package.json
@@ -1,7 +1,7 @@
 {
 	"name": "@remotion/zod-types-v3",
 	"version": "4.0.424",
-	"description": "Zod v3 types for Remotion",
+	"description": "Zod 3.22.3 types for Remotion",
 	"main": "dist/index.js",
 	"types": "dist/index.d.ts",
 	"module": "dist/esm/index.mjs",
@@ -51,5 +51,5 @@
 	"publishConfig": {
 		"access": "public"
 	},
-	"homepage": "https://www.remotion.dev/docs/zod-types"
+	"homepage": "https://www.remotion.dev/docs/zod-types/v3"
 }

From 69c8bebc9c86b386d4ec9b95514cd1983cef2ccf Mon Sep 17 00:00:00 2001
From: Jonny Burger 
Date: Thu, 19 Feb 2026 10:31:33 +0100
Subject: [PATCH 45/49] update v

---
 bun.lock                           | 2 +-
 packages/zod-types-v3/package.json | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/bun.lock b/bun.lock
index ca95c0dde3b..b1c4837e7ea 100644
--- a/bun.lock
+++ b/bun.lock
@@ -2357,7 +2357,7 @@
     },
     "packages/zod-types-v3": {
       "name": "@remotion/zod-types-v3",
-      "version": "4.0.424",
+      "version": "4.0.425",
       "dependencies": {
         "@remotion/zod-types": "workspace:*",
         "remotion": "workspace:*",
diff --git a/packages/zod-types-v3/package.json b/packages/zod-types-v3/package.json
index 6dcf705f0b1..e8d069734f4 100644
--- a/packages/zod-types-v3/package.json
+++ b/packages/zod-types-v3/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "@remotion/zod-types-v3",
-	"version": "4.0.424",
+	"version": "4.0.425",
 	"description": "Zod 3.22.3 types for Remotion",
 	"main": "dist/index.js",
 	"types": "dist/index.d.ts",

From 68daeaddfcf0076a5a6dd8e13bfe753adafdd85c Mon Sep 17 00:00:00 2001
From: Jonny Burger 
Date: Thu, 19 Feb 2026 11:05:35 +0100
Subject: [PATCH 46/49] less flaky tests

---
 packages/it-tests/package.json                |  2 +-
 .../src/rendering/frame-accuracy.test.ts      | 56 ++++++-------------
 2 files changed, 17 insertions(+), 41 deletions(-)

diff --git a/packages/it-tests/package.json b/packages/it-tests/package.json
index 3687e7629ee..100f464cef3 100644
--- a/packages/it-tests/package.json
+++ b/packages/it-tests/package.json
@@ -6,7 +6,7 @@
 	"version": "4.0.425",
 	"license": "SEE LICENSE IN LICENSE.md",
 	"scripts": {
-		"test": " node --test src/node-version/media-parser.mjs && bun test src/rendering --run",
+		"test": " node --test src/node-version/media-parser.mjs && bun test src/rendering --run --timeout 60000",
 		"testssr": "bun test src/ssr src/bundle src/webcodecs src/templates src/monorepo --timeout 40000",
 		"testlambda": "exit 0",
 		"lint": "tsc -d",
diff --git a/packages/it-tests/src/rendering/frame-accuracy.test.ts b/packages/it-tests/src/rendering/frame-accuracy.test.ts
index 4f1675e6e57..b287a9610d7 100644
--- a/packages/it-tests/src/rendering/frame-accuracy.test.ts
+++ b/packages/it-tests/src/rendering/frame-accuracy.test.ts
@@ -1,46 +1,22 @@
 import {expect, test} from 'bun:test';
 import {getMissedFramesforCodec} from './test-utils';
 
-test(
-	'should render correct frames from embedded videos - WebM onthread',
-	async () => {
-		const missedFrames = await getMissedFramesforCodec('webm', 'normal');
-		expect(missedFrames).toBeLessThanOrEqual(8);
-	},
-	{
-		timeout: 60000,
-	},
-);
+test('should render correct frames from embedded videos - WebM onthread', async () => {
+	const missedFrames = await getMissedFramesforCodec('webm', 'normal');
+	expect(missedFrames).toBeLessThanOrEqual(8);
+});
 
-test(
-	'should render correct frames from embedded videos - WebM offthread',
-	async () => {
-		const missedFrames = await getMissedFramesforCodec('webm', 'offthread');
-		expect(missedFrames).toBe(0);
-	},
-	{
-		timeout: 60000,
-	},
-);
+test('should render correct frames from embedded videos - WebM offthread', async () => {
+	const missedFrames = await getMissedFramesforCodec('webm', 'offthread');
+	expect(missedFrames).toBe(0);
+});
 
-test(
-	'should render correct frames from embedded videos - MP4 onthread',
-	async () => {
-		const missedFrames = await getMissedFramesforCodec('mp4', 'normal');
-		expect(missedFrames).toBeLessThanOrEqual(8);
-	},
-	{
-		timeout: 60000,
-	},
-);
+test('should render correct frames from embedded videos - MP4 onthread', async () => {
+	const missedFrames = await getMissedFramesforCodec('mp4', 'normal');
+	expect(missedFrames).toBeLessThanOrEqual(8);
+});
 
-test(
-	'should render correct frames from embedded videos - MP4 offthread',
-	async () => {
-		const missedFrames = await getMissedFramesforCodec('mp4', 'offthread');
-		expect(missedFrames).toBe(0);
-	},
-	{
-		timeout: 60000,
-	},
-);
+test('should render correct frames from embedded videos - MP4 offthread', async () => {
+	const missedFrames = await getMissedFramesforCodec('mp4', 'offthread');
+	expect(missedFrames).toBe(0);
+});

From ffc16d2c21a7f48755c042b53fbafa24743501dc Mon Sep 17 00:00:00 2001
From: Jonny Burger 
Date: Thu, 19 Feb 2026 11:34:32 +0100
Subject: [PATCH 47/49] `remotion-monorepo`: Upgrade turbo from 2.8.6 to 2.8.10

Co-Authored-By: Claude Opus 4.6 
---
 bun.lock     | 30 ++++++++++++++++++++++--------
 package.json |  2 +-
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/bun.lock b/bun.lock
index b1c4837e7ea..4f3e227714e 100644
--- a/bun.lock
+++ b/bun.lock
@@ -6,7 +6,7 @@
       "name": "remotion-monorepo",
       "dependencies": {
         "p-limit": "7.2.0",
-        "turbo": "2.8.6",
+        "turbo": "2.8.10",
         "typescript": "5.9.3",
       },
       "devDependencies": {
@@ -7513,21 +7513,21 @@
 
     "tunnel-rat": ["tunnel-rat@0.1.2", "", { "dependencies": { "zustand": "4.5.5" } }, "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ=="],
 
-    "turbo": ["turbo@2.8.6", "", { "optionalDependencies": { "turbo-darwin-64": "2.8.6", "turbo-darwin-arm64": "2.8.6", "turbo-linux-64": "2.8.6", "turbo-linux-arm64": "2.8.6", "turbo-windows-64": "2.8.6", "turbo-windows-arm64": "2.8.6" }, "bin": { "turbo": "bin/turbo" } }, "sha512-QMj1SQwUYehc+xJ9SxXn56UO43hfKN64/NFetVW1BwzysRqn+q0FSgrmk+IbJ+djfd8j8zXGKGeqsnUcXwQSUQ=="],
+    "turbo": ["turbo@2.8.10", "", { "optionalDependencies": { "turbo-darwin-64": "2.8.10", "turbo-darwin-arm64": "2.8.10", "turbo-linux-64": "2.8.10", "turbo-linux-arm64": "2.8.10", "turbo-windows-64": "2.8.10", "turbo-windows-arm64": "2.8.10" }, "bin": { "turbo": "bin/turbo" } }, "sha512-OxbzDES66+x7nnKGg2MwBA1ypVsZoDTLHpeaP4giyiHSixbsiTaMyeJqbEyvBdp5Cm28fc+8GG6RdQtic0ijwQ=="],
 
-    "turbo-darwin-64": ["turbo-darwin-64@2.8.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-6QeZ/aLZizekiI6tKZN0IGP1a1WYZ9c/qDKPa0rSmj2X0O0Iw/ES4rKZV40S5n8SUJdiU01EFLygHJ2oWaYKXg=="],
+    "turbo-darwin-64": ["turbo-darwin-64@2.8.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-A03fXh+B7S8mL3PbdhTd+0UsaGrhfyPkODvzBDpKRY7bbeac4MDFpJ7I+Slf2oSkCEeSvHKR7Z4U71uKRUfX7g=="],
 
-    "turbo-darwin-arm64": ["turbo-darwin-arm64@2.8.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RS4Z902vB93cQD3PJS/1IMmS0HefrB5ZXuw4ECOrxhOGz5jJVmYFJ6weDzedjoTDeYHHXGo1NoiCSHg69ngWKA=="],
+    "turbo-darwin-arm64": ["turbo-darwin-arm64@2.8.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-sidzowgWL3s5xCHLeqwC9M3s9M0i16W1nuQF3Mc7fPHpZ+YPohvcbVFBB2uoRRHYZg6yBnwD4gyUHKTeXfwtXA=="],
 
-    "turbo-linux-64": ["turbo-linux-64@2.8.6", "", { "os": "linux", "cpu": "x64" }, "sha512-hCWDnDepYbrSJdByuryKFoHAGFkvgBYXr6qdaGsYhX1Wgq8isqXCQBKOo99Y/9tXDwKGEeQ7xnkdFvSL7AQ4iQ=="],
+    "turbo-linux-64": ["turbo-linux-64@2.8.10", "", { "os": "linux", "cpu": "x64" }, "sha512-YK9vcpL3TVtqonB021XwgaQhY9hJJbKKUhLv16osxV0HkcQASQWUqR56yMge7puh6nxU67rQlTq1b7ksR1T3KA=="],
 
-    "turbo-linux-arm64": ["turbo-linux-arm64@2.8.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-oS15aCYEpynG/l69xs/ZnQ0dnz0pHhfHg70Zf5J+j5Cam0/RA0MpcryjneN/9G0PmP8a/6ZxnL5nZahX+wOBPA=="],
+    "turbo-linux-arm64": ["turbo-linux-arm64@2.8.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-3+j2tL0sG95iBJTm+6J8/45JsETQABPqtFyYjVjBbi6eVGdtNTiBmHNKrbvXRlQ3ZbUG75bKLaSSDHSEEN+btQ=="],
 
     "turbo-stream": ["turbo-stream@2.4.0", "", {}, "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g=="],
 
-    "turbo-windows-64": ["turbo-windows-64@2.8.6", "", { "os": "win32", "cpu": "x64" }, "sha512-eqBxqJD7H/uk9V0QO10VgwY9J2BUXejsGuzChln72Yl+o8GZwsvhOekndRxccR90J8ZO+LKO24+3VzHFh4Cu/g=="],
+    "turbo-windows-64": ["turbo-windows-64@2.8.10", "", { "os": "win32", "cpu": "x64" }, "sha512-hdeF5qmVY/NFgiucf8FW0CWJWtyT2QPm5mIsX0W1DXAVzqKVXGq+Zf+dg4EUngAFKjDzoBeN6ec2Fhajwfztkw=="],
 
-    "turbo-windows-arm64": ["turbo-windows-arm64@2.8.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-I3VEQyxIlNZ6XTg4fLKAkuhcwzIs/GD7Vs1yhelH2aUTjf08wprjBWknDqP7mjAHMpsosRrq4DtfSZEQm83Hxg=="],
+    "turbo-windows-arm64": ["turbo-windows-arm64@2.8.10", "", { "os": "win32", "cpu": "arm64" }, "sha512-QGdr/Q8LWmj+ITMkSvfiz2glf0d7JG0oXVzGL3jxkGqiBI1zXFj20oqVY0qWi+112LO9SVrYdpHS0E/oGFrMbQ=="],
 
     "tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="],
 
@@ -10583,6 +10583,8 @@
 
     "template-vercel/tailwindcss": ["tailwindcss@4.0.3", "", {}, "sha512-ImmZF0Lon5RrQpsEAKGxRvHwCvMgSC4XVlFRqmbzTEDb/3wvin9zfEZrMwgsa3yqBbPqahYcVI6lulM2S7IZAA=="],
 
+    "template-vercel/turbo": ["turbo@2.8.6", "", { "optionalDependencies": { "turbo-darwin-64": "2.8.6", "turbo-darwin-arm64": "2.8.6", "turbo-linux-64": "2.8.6", "turbo-linux-arm64": "2.8.6", "turbo-windows-64": "2.8.6", "turbo-windows-arm64": "2.8.6" }, "bin": { "turbo": "bin/turbo" } }, "sha512-QMj1SQwUYehc+xJ9SxXn56UO43hfKN64/NFetVW1BwzysRqn+q0FSgrmk+IbJ+djfd8j8zXGKGeqsnUcXwQSUQ=="],
+
     "template-vercel/typescript-eslint": ["typescript-eslint@8.46.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.46.0", "@typescript-eslint/parser": "8.46.0", "@typescript-eslint/typescript-estree": "8.46.0", "@typescript-eslint/utils": "8.46.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-6+ZrB6y2bT2DX3K+Qd9vn7OFOJR+xSLDj+Aw/N3zBwUt27uTw2sw2TE2+UcY1RiyBZkaGbTkVg9SSdPNUG6aUw=="],
 
     "terser/acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="],
@@ -13733,6 +13735,18 @@
 
     "template-vercel/@typescript-eslint/parser/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
 
+    "template-vercel/turbo/turbo-darwin-64": ["turbo-darwin-64@2.8.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-6QeZ/aLZizekiI6tKZN0IGP1a1WYZ9c/qDKPa0rSmj2X0O0Iw/ES4rKZV40S5n8SUJdiU01EFLygHJ2oWaYKXg=="],
+
+    "template-vercel/turbo/turbo-darwin-arm64": ["turbo-darwin-arm64@2.8.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RS4Z902vB93cQD3PJS/1IMmS0HefrB5ZXuw4ECOrxhOGz5jJVmYFJ6weDzedjoTDeYHHXGo1NoiCSHg69ngWKA=="],
+
+    "template-vercel/turbo/turbo-linux-64": ["turbo-linux-64@2.8.6", "", { "os": "linux", "cpu": "x64" }, "sha512-hCWDnDepYbrSJdByuryKFoHAGFkvgBYXr6qdaGsYhX1Wgq8isqXCQBKOo99Y/9tXDwKGEeQ7xnkdFvSL7AQ4iQ=="],
+
+    "template-vercel/turbo/turbo-linux-arm64": ["turbo-linux-arm64@2.8.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-oS15aCYEpynG/l69xs/ZnQ0dnz0pHhfHg70Zf5J+j5Cam0/RA0MpcryjneN/9G0PmP8a/6ZxnL5nZahX+wOBPA=="],
+
+    "template-vercel/turbo/turbo-windows-64": ["turbo-windows-64@2.8.6", "", { "os": "win32", "cpu": "x64" }, "sha512-eqBxqJD7H/uk9V0QO10VgwY9J2BUXejsGuzChln72Yl+o8GZwsvhOekndRxccR90J8ZO+LKO24+3VzHFh4Cu/g=="],
+
+    "template-vercel/turbo/turbo-windows-arm64": ["turbo-windows-arm64@2.8.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-I3VEQyxIlNZ6XTg4fLKAkuhcwzIs/GD7Vs1yhelH2aUTjf08wprjBWknDqP7mjAHMpsosRrq4DtfSZEQm83Hxg=="],
+
     "template-vercel/typescript-eslint/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.46.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.46.0", "@typescript-eslint/tsconfig-utils": "8.46.0", "@typescript-eslint/types": "8.46.0", "@typescript-eslint/visitor-keys": "8.46.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg=="],
 
     "template-vercel/typescript-eslint/@typescript-eslint/utils": ["@typescript-eslint/utils@8.46.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.46.0", "@typescript-eslint/types": "8.46.0", "@typescript-eslint/typescript-estree": "8.46.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g=="],
diff --git a/package.json b/package.json
index b3c036985e6..37de5b51a3a 100644
--- a/package.json
+++ b/package.json
@@ -57,7 +57,7 @@
 	"dependencies": {
 		"p-limit": "7.2.0",
 		"typescript": "5.9.3",
-		"turbo": "2.8.6"
+		"turbo": "2.8.10"
 	},
 	"packageManager": "bun@1.3.3",
 	"overrides": {

From a1983138bcb40be050870458c1fcffd03959c239 Mon Sep 17 00:00:00 2001
From: Jonny Burger 
Date: Thu, 19 Feb 2026 11:36:52 +0100
Subject: [PATCH 48/49] `remotion-monorepo`: Fix Vercel deployment warnings

- Move `paths` and `types` inside `compilerOptions` in packages/docs/tsconfig.json
- Add `build` task to turbo.json

Co-Authored-By: Claude Opus 4.6 
---
 packages/docs/tsconfig.json | 18 +++++++++---------
 turbo.json                  |  5 +++++
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/packages/docs/tsconfig.json b/packages/docs/tsconfig.json
index eb94dcf5155..87a40321e83 100644
--- a/packages/docs/tsconfig.json
+++ b/packages/docs/tsconfig.json
@@ -11,16 +11,16 @@
 		"noImplicitAny": false,
 		"strictNullChecks": true,
 		"strict": false,
-		"noEmit": true
+		"noEmit": true,
+		"paths": {
+			"@site/*": ["./*"]
+		},
+		"types": [
+			"node",
+			"@docusaurus/module-type-aliases",
+			"@docusaurus/theme-classic"
+		]
 	},
-	"paths": {
-		"@site/*": ["./*"]
-	},
-	"types": [
-		"node",
-		"@docusaurus/module-type-aliases",
-		"@docusaurus/theme-classic"
-	],
 
 	"references": [
 		{"path": "../player"},
diff --git a/turbo.json b/turbo.json
index caf4c01dd5a..8b26ad65357 100644
--- a/turbo.json
+++ b/turbo.json
@@ -24,6 +24,11 @@
 		"testwebrenderer": {
 			"dependsOn": ["@remotion/web-renderer#make"]
 		},
+		"build": {
+			"dependsOn": ["^make"],
+			"outputs": ["dist"],
+			"outputLogs": "new-only"
+		},
 		"make": {
 			"dependsOn": ["^make"],
 			"outputs": ["dist"],

From 2eb837795aba2ea178bba0f2df4c95c150810ea7 Mon Sep 17 00:00:00 2001
From: Jonny Burger 
Date: Thu, 19 Feb 2026 11:52:42 +0100
Subject: [PATCH 49/49] Update package.json

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index b3c036985e6..b5324a9550c 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,7 @@
 		"ts-build": "tsc -b --verbose --watch",
 		"stylecheck": "turbo run lint formatting --no-update-notifier",
 		"build": "turbo run make --no-update-notifier",
-		"build-docs": "turbo run build-docs --no-update-notifier",
+		"build-docs": "TURBO_TELEMETRY_DISABLED=1 turbo run build-docs --no-update-notifier",
 		"testssr": "turbo run testssr --no-update-notifier",
 		"testwebcodecs": "turbo run testwebcodecs --no-update-notifier",
 		"testwebrenderer": "turbo run testwebrenderer --concurrency=1 --no-update-notifier",