From 6862a5315208a15550d235467c59c13937f0a651 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Mon, 10 Jun 2024 13:23:50 +0000 Subject: [PATCH 01/60] v15.0.0-canary.23 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 12 ++++++------ packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 14 +++++++------- 17 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lerna.json b/lerna.json index 0d8e13d3fc933..94a4e3ec3aa34 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "15.0.0-canary.22" + "version": "15.0.0-canary.23" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index b7bd758027509..ce007372145a1 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "15.0.0-canary.22", + "version": "15.0.0-canary.23", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 9c749cb721812..c9a7df2503da0 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "15.0.0-canary.22", + "version": "15.0.0-canary.23", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "15.0.0-canary.22", + "@next/eslint-plugin-next": "15.0.0-canary.23", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 6fba251782c69..50ade39c4c856 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "15.0.0-canary.22", + "version": "15.0.0-canary.23", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 96fba7c3a1a25..091c04d1b88c5 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "15.0.0-canary.22", + "version": "15.0.0-canary.23", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index b1222791ec8ae..7a0b841555df6 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "15.0.0-canary.22", + "version": "15.0.0-canary.23", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index c6103c8378600..173c683fc8938 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "15.0.0-canary.22", + "version": "15.0.0-canary.23", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 15a7a147d7a90..fa1cc5d6b097d 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "15.0.0-canary.22", + "version": "15.0.0-canary.23", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index e11228fcc5e6d..e2a86a3798385 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "15.0.0-canary.22", + "version": "15.0.0-canary.23", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 5a681b41664b6..126d047effba2 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "15.0.0-canary.22", + "version": "15.0.0-canary.23", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 61452ba1ba9ce..0c37743b7b2dd 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "15.0.0-canary.22", + "version": "15.0.0-canary.23", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 7ce2f97ee75c9..747a7d76861d8 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "15.0.0-canary.22", + "version": "15.0.0-canary.23", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index e27ccbdf355ef..c01106d87150b 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "15.0.0-canary.22", + "version": "15.0.0-canary.23", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index a4dd2c7e17bc8..0293509e348d2 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "15.0.0-canary.22", + "version": "15.0.0-canary.23", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -93,7 +93,7 @@ ] }, "dependencies": { - "@next/env": "15.0.0-canary.22", + "@next/env": "15.0.0-canary.23", "@swc/helpers": "0.5.11", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -157,10 +157,10 @@ "@jest/types": "29.5.0", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/polyfill-module": "15.0.0-canary.22", - "@next/polyfill-nomodule": "15.0.0-canary.22", - "@next/react-refresh-utils": "15.0.0-canary.22", - "@next/swc": "15.0.0-canary.22", + "@next/polyfill-module": "15.0.0-canary.23", + "@next/polyfill-nomodule": "15.0.0-canary.23", + "@next/react-refresh-utils": "15.0.0-canary.23", + "@next/swc": "15.0.0-canary.23", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.41.2", "@swc/core": "1.5.7", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index dd6110978113b..76a39bfffdc7f 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "15.0.0-canary.22", + "version": "15.0.0-canary.23", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 19a834ac99d9e..25cf5bdeaca50 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "15.0.0-canary.22", + "version": "15.0.0-canary.23", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -26,7 +26,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "15.0.0-canary.22", + "next": "15.0.0-canary.23", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9c35a3f85736b..f9a16e1f0b72b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -753,7 +753,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 15.0.0-canary.22 + specifier: 15.0.0-canary.23 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -815,7 +815,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 15.0.0-canary.22 + specifier: 15.0.0-canary.23 version: link:../next-env '@swc/helpers': specifier: 0.5.11 @@ -943,16 +943,16 @@ importers: specifier: 1.2.0 version: 1.2.0 '@next/polyfill-module': - specifier: 15.0.0-canary.22 + specifier: 15.0.0-canary.23 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 15.0.0-canary.22 + specifier: 15.0.0-canary.23 version: link:../next-polyfill-nomodule '@next/react-refresh-utils': - specifier: 15.0.0-canary.22 + specifier: 15.0.0-canary.23 version: link:../react-refresh-utils '@next/swc': - specifier: 15.0.0-canary.22 + specifier: 15.0.0-canary.23 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1576,7 +1576,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 15.0.0-canary.22 + specifier: 15.0.0-canary.23 version: link:../next outdent: specifier: 0.8.0 From d7d5117777485fd3777f3429901369f4f244eb76 Mon Sep 17 00:00:00 2001 From: mratlamwala Date: Mon, 10 Jun 2024 18:57:19 +0530 Subject: [PATCH 02/60] Update 08-lazy-loading.mdx (#66705) wording changes. --------- Co-authored-by: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com> --- .../05-optimizing/08-lazy-loading.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/03-pages/01-building-your-application/05-optimizing/08-lazy-loading.mdx b/docs/03-pages/01-building-your-application/05-optimizing/08-lazy-loading.mdx index bcbd1dea35f3d..f78374e9db239 100644 --- a/docs/03-pages/01-building-your-application/05-optimizing/08-lazy-loading.mdx +++ b/docs/03-pages/01-building-your-application/05-optimizing/08-lazy-loading.mdx @@ -1,6 +1,6 @@ --- title: Lazy Loading -description: Lazy load imported libraries and React Components to improve your application's loading performance. +description: Lazy load imported libraries and React Components to improve your application's overall loading performance. source: app/building-your-application/optimizing/lazy-loading --- From 1cb3a0b73dcba37d0e274de9be593ddcfea4c914 Mon Sep 17 00:00:00 2001 From: hrmny <8845940+ForsakenHarmony@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:23:03 +0200 Subject: [PATCH 03/60] fix(turbopack): remove tailwindcss from default external packages (#66706) ### Why? Importing `tailwind/tailwind.css` is not possible right now with turbopack, and there's no reason it needs to be marked as external. ### How? Closes PACK-3013 Fixes #64837 --- .../serverExternalPackages.mdx | 1 - .../serverExternalPackages.mdx | 1 - .../src/lib/server-external-packages.json | 1 - test/e2e/app-dir/tailwind-css/app/layout.tsx | 10 +++ test/e2e/app-dir/tailwind-css/app/page.tsx | 63 +++++++++++++++++++ test/e2e/app-dir/tailwind-css/next.config.js | 6 ++ .../app-dir/tailwind-css/postcss.config.js | 6 ++ .../app-dir/tailwind-css/tailwind-css.test.ts | 26 ++++++++ .../app-dir/tailwind-css/tailwind.config.js | 8 +++ test/e2e/postcss-config-cjs/index.test.ts | 36 +++-------- 10 files changed, 128 insertions(+), 30 deletions(-) create mode 100644 test/e2e/app-dir/tailwind-css/app/layout.tsx create mode 100644 test/e2e/app-dir/tailwind-css/app/page.tsx create mode 100644 test/e2e/app-dir/tailwind-css/next.config.js create mode 100644 test/e2e/app-dir/tailwind-css/postcss.config.js create mode 100644 test/e2e/app-dir/tailwind-css/tailwind-css.test.ts create mode 100644 test/e2e/app-dir/tailwind-css/tailwind.config.js diff --git a/docs/02-app/02-api-reference/05-next-config-js/serverExternalPackages.mdx b/docs/02-app/02-api-reference/05-next-config-js/serverExternalPackages.mdx index 981fb9b87dfea..e353b91685e94 100644 --- a/docs/02-app/02-api-reference/05-next-config-js/serverExternalPackages.mdx +++ b/docs/02-app/02-api-reference/05-next-config-js/serverExternalPackages.mdx @@ -68,7 +68,6 @@ Next.js includes a [short list of popular packages](https://github.com/vercel/ne - `sharp` - `shiki` - `sqlite3` -- `tailwindcss` - `ts-node` - `typescript` - `vscode-oniguruma` diff --git a/docs/03-pages/02-api-reference/03-next-config-js/serverExternalPackages.mdx b/docs/03-pages/02-api-reference/03-next-config-js/serverExternalPackages.mdx index 5d6c608c0c58d..0750d548e0030 100644 --- a/docs/03-pages/02-api-reference/03-next-config-js/serverExternalPackages.mdx +++ b/docs/03-pages/02-api-reference/03-next-config-js/serverExternalPackages.mdx @@ -68,7 +68,6 @@ Next.js includes a [short list of popular packages](https://github.com/vercel/ne - `sharp` - `shiki` - `sqlite3` -- `tailwindcss` - `ts-node` - `typescript` - `vscode-oniguruma` diff --git a/packages/next/src/lib/server-external-packages.json b/packages/next/src/lib/server-external-packages.json index 610c13c4d2436..96612bc45f67d 100644 --- a/packages/next/src/lib/server-external-packages.json +++ b/packages/next/src/lib/server-external-packages.json @@ -49,7 +49,6 @@ "sharp", "shiki", "sqlite3", - "tailwindcss", "ts-node", "typescript", "vscode-oniguruma", diff --git a/test/e2e/app-dir/tailwind-css/app/layout.tsx b/test/e2e/app-dir/tailwind-css/app/layout.tsx new file mode 100644 index 0000000000000..c939c5c1f3882 --- /dev/null +++ b/test/e2e/app-dir/tailwind-css/app/layout.tsx @@ -0,0 +1,10 @@ +import 'tailwindcss/tailwind.css' +import { ReactNode } from 'react' + +export default function Root({ children }: { children: ReactNode }) { + return ( + + {children} + + ) +} diff --git a/test/e2e/app-dir/tailwind-css/app/page.tsx b/test/e2e/app-dir/tailwind-css/app/page.tsx new file mode 100644 index 0000000000000..53704f91b6689 --- /dev/null +++ b/test/e2e/app-dir/tailwind-css/app/page.tsx @@ -0,0 +1,63 @@ +export default function HomePage() { + return ( +
+
+

+ Welcome to{' '} + + Next.js! + +

+ +

+ Get started by editing{' '} + + pages/index.js + +

+ +
+ +

Documentation →

+

+ Find in-depth information about Next.js features and API. +

+
+ + +

Learn →

+

+ Learn about Next.js in an interactive course with quizzes! +

+
+ + +

Examples →

+

+ Discover and deploy boilerplate example Next.js projects. +

+
+ + +

Deploy →

+

+ Instantly deploy your Next.js site to a public URL with Vercel. +

+
+
+
+
+ ) +} diff --git a/test/e2e/app-dir/tailwind-css/next.config.js b/test/e2e/app-dir/tailwind-css/next.config.js new file mode 100644 index 0000000000000..807126e4cf0bf --- /dev/null +++ b/test/e2e/app-dir/tailwind-css/next.config.js @@ -0,0 +1,6 @@ +/** + * @type {import('next').NextConfig} + */ +const nextConfig = {} + +module.exports = nextConfig diff --git a/test/e2e/app-dir/tailwind-css/postcss.config.js b/test/e2e/app-dir/tailwind-css/postcss.config.js new file mode 100644 index 0000000000000..33ad091d26d8a --- /dev/null +++ b/test/e2e/app-dir/tailwind-css/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/test/e2e/app-dir/tailwind-css/tailwind-css.test.ts b/test/e2e/app-dir/tailwind-css/tailwind-css.test.ts new file mode 100644 index 0000000000000..3e8589b3b4f32 --- /dev/null +++ b/test/e2e/app-dir/tailwind-css/tailwind-css.test.ts @@ -0,0 +1,26 @@ +import { nextTestSetup } from 'e2e-utils' + +describe('tailwind-css', () => { + const { next } = nextTestSetup({ + files: __dirname, + dependencies: { + autoprefixer: '10.4.19', + postcss: '8.4.38', + tailwindcss: '3.4.4', + }, + }) + + it('works when importing tailwind/tailwind.css', async () => { + const browser = await next.browser('/') + try { + const text = await browser.elementByCss('.text-6xl').text() + expect(text).toMatch(/Welcome to/) + const cssBlue = await browser + .elementByCss('#test-link') + .getComputedCss('color') + expect(cssBlue).toBe('rgb(37, 99, 235)') + } finally { + await browser.close() + } + }) +}) diff --git a/test/e2e/app-dir/tailwind-css/tailwind.config.js b/test/e2e/app-dir/tailwind-css/tailwind.config.js new file mode 100644 index 0000000000000..b297e210951b2 --- /dev/null +++ b/test/e2e/app-dir/tailwind-css/tailwind.config.js @@ -0,0 +1,8 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ['./app/**/*.{js,ts,jsx,tsx}'], + theme: { + extend: {}, + }, + plugins: [], +} diff --git a/test/e2e/postcss-config-cjs/index.test.ts b/test/e2e/postcss-config-cjs/index.test.ts index 5cbbb4a3b50b9..8438f1275fcc9 100644 --- a/test/e2e/postcss-config-cjs/index.test.ts +++ b/test/e2e/postcss-config-cjs/index.test.ts @@ -1,34 +1,18 @@ -import { createNext, FileRef } from 'e2e-utils' +import { FileRef, nextTestSetup } from 'e2e-utils' import { join } from 'path' -import { NextInstance } from 'e2e-utils' -import webdriver from 'next-webdriver' describe('postcss-config-cjs', () => { - let next: NextInstance - - beforeAll(async () => { - next = await createNext({ - files: { - 'postcss.config.cjs': new FileRef( - join(__dirname, 'app/postcss.config.cjs') - ), - 'tailwind.config.cjs': new FileRef( - join(__dirname, 'app/tailwind.config.cjs') - ), - pages: new FileRef(join(__dirname, 'app/pages')), - }, - dependencies: { - tailwindcss: '2.2.19', - postcss: '8.3.5', - }, - }) + const { next } = nextTestSetup({ + files: new FileRef(join(__dirname, 'app')), + dependencies: { + tailwindcss: '2.2.19', + postcss: '8.3.5', + }, }) - afterAll(() => next.destroy()) it('works with postcss.config.cjs files', async () => { - let browser + let browser = await next.browser('/') try { - browser = await webdriver(next.url, '/') const text = await browser.elementByCss('.text-6xl').text() expect(text).toMatch(/Welcome to/) const cssBlue = await browser @@ -36,9 +20,7 @@ describe('postcss-config-cjs', () => { .getComputedCss('color') expect(cssBlue).toBe('rgb(37, 99, 235)') } finally { - if (browser) { - await browser.close() - } + await browser.close() } }) }) From 544fc0acdfe4d47e8b7df20321b7aa8faebd3d66 Mon Sep 17 00:00:00 2001 From: Mayank Date: Mon, 10 Jun 2024 20:10:26 +0530 Subject: [PATCH 04/60] fix: Update docker base images to node:20 (#66702) --- .devcontainer/Dockerfile | 2 +- .devcontainer/base.Dockerfile | 2 +- .devcontainer/devcontainer.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 2a85a75b11a71..2976914683621 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster -ARG VARIANT=16-bullseye +ARG VARIANT=20-bullseye FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT} # [Optional] Uncomment this section to install additional OS packages. diff --git a/.devcontainer/base.Dockerfile b/.devcontainer/base.Dockerfile index 7b4c41b2ead31..c0b841eebe671 100644 --- a/.devcontainer/base.Dockerfile +++ b/.devcontainer/base.Dockerfile @@ -1,5 +1,5 @@ # [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster -ARG VARIANT=16-bullseye +ARG VARIANT=20-bullseye FROM node:${VARIANT} # [Option] Install zsh diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 0d8b4901dfda7..02cd7988f1d9d 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,7 +8,7 @@ // Append -bullseye or -buster to pin to an OS version. // Use -bullseye variants on local arm64/Apple Silicon. "args": { - "VARIANT": "16-bullseye" + "VARIANT": "20-bullseye" } }, // Configure tool-specific properties. From f893c1852837122842557d5033f22b0ffa49f97f Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Mon, 10 Jun 2024 17:34:06 +0200 Subject: [PATCH 05/60] Append sitemap extension and optimize imafe metadata static generation (#66477) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### What Optimizing the static generation for dynamic metadata routes If you're not using `generateSitemaps()` or `generateSitemaps()`, you don't need to change any file conventions. If you're using multi sitemap routes, make sure the returned `id` properties from `generateSitemaps()` don't need to contain `.xml`, since we'll always append one for you. Analyzing the exports of metadata routes and determine if we need to make them as dynamic routes. ### Why Previously, users are struggling with the multi routes of sitemap or images. For sitemap, the `.xml` extension in url doesn't get appended consistently to the multi sitemap route between dev and prod. For image routes, the generated image routes are always dynamic routes which cannot get static optimized. The reason is that we need to always generate a catch-all route (such as `/icon/[[...id]]` to handle both single route case (e.g. without `generateImageMetadata`, representing url `/icon`) or multi route (e.g. with `generateImageMetadata`, representing url `/icon/[id]`), only catch-all routes can do it. This approach fail the static optimization and make mapping url pretty difficult as parsing the file to check the module exports has to be done before it. #### Benifits For image routes urls, this approach could help on static generation such as single `/opengraph-image` route can be treated as static, and then it can get static optimized if possible. **Before**: `/opengraph-image/[[...id]]` cannot be optimized **After**: single route `/opengraph-image` and multi-route `/opengraph-image/[id]` are both possible to be statically optimized For sitemap, since we removed appending `.xml` for dynamic routes, it’s hard for users to have `/sitemap.xml` url with dynamic route convention `sitemap.js` . But users desire smooth migration and flexibility. **Before**: In v15 rc we removed the `.xml` appending that `sitemap.js` will generate url `/sitemap` makes users hard to migrate, as users need to re-submit the new sitemap url. **After**: Now we'll consistently generate the `.xml`. Single route will become `/sitemap.xml`, and multi route will become `/sitemap/[id].xml`. It's still better than v15 as the urls generation is consistent, no difference between dev and prod. Here's the url generation comparsion #### Before All the routes are dynamic which cannot be optimized, we only had a hacky optimization for prodution build multi-routes sitemap routes | | only default export | `export generateImageMetadata()` | `export generateSitemaps()` | | -- | -- | -- | -- | | opengraph-image.js | /opengraph-image/[[...id]] | /opengraph-image[[...id]]/ | /opengraph-image/[[...id]] | | sitemap.js | /sitemap/[[...id]] | /sitemap/[[...id]] | dev: `/sitemap/[[...id]]` prod: `/sitemap/[id]` | #### After Most of the single route will are to get statically optimized now, and the multi-routes sitemap are able to get SSG now | | only default export | `export generateImageMetadata()` | `export generateSitemaps()` | | -- | -- | -- | -- | | opengraph-image.js | /opengraph-image | /opengraph-image/[id] | - | | sitemap.js | /sitemap.xml | - | /sitemap/[id].xml | Next.js will have less overhead of mapping urls, we can easily multiply the urls generation simply based on file conventions. x-ref: feedback from #65507 Closes #66232 --- .../01-metadata/sitemap.mdx | 6 +- .../next-core/src/app_segment_config.rs | 44 ++++++-- .../next-core/src/next_app/metadata/mod.rs | 16 +-- .../next-core/src/next_app/metadata/route.rs | 102 +++++++++++------- .../build/analysis/get-page-static-info.ts | 28 ++--- packages/next/src/build/entries.ts | 87 +++++++++------ packages/next/src/build/index.ts | 65 +++-------- packages/next/src/build/output/store.ts | 10 +- .../webpack/loaders/metadata/discover.ts | 11 +- .../build/webpack/loaders/next-app-loader.ts | 10 +- .../loaders/next-metadata-route-loader.ts | 92 ++++++++-------- packages/next/src/export/routes/app-route.ts | 9 +- .../src/lib/metadata/get-metadata-route.ts | 35 ++++-- .../lib/metadata/is-metadata-route.test.ts | 45 ++++++++ .../src/lib/metadata/is-metadata-route.ts | 45 +++++--- .../src/server/dev/hot-reloader-turbopack.ts | 9 +- .../src/server/dev/hot-reloader-webpack.ts | 5 +- .../next/src/server/dev/turbopack-utils.ts | 30 +++++- .../lib/router-utils/setup-dev-bundler.ts | 33 +++++- .../dev-app-route-route-matcher-provider.ts | 75 +++++++++++-- .../dynamic-metadata-error.test.ts | 2 +- .../dynamic-in-generate-params/index.test.ts | 8 +- .../e2e/app-dir/logging/fetch-logging.test.ts | 2 +- .../metadata-dynamic-routes/app/gsp/icon.tsx | 37 +++++++ .../metadata-dynamic-routes/index.test.ts | 45 +++++--- test/e2e/app-dir/metadata/metadata.test.ts | 2 +- .../metadata-static/metadata-static.test.ts | 2 +- test/turbopack-build-tests-manifest.json | 3 +- 28 files changed, 563 insertions(+), 295 deletions(-) create mode 100644 packages/next/src/lib/metadata/is-metadata-route.test.ts create mode 100644 test/e2e/app-dir/metadata-dynamic-routes/app/gsp/icon.tsx diff --git a/docs/02-app/02-api-reference/02-file-conventions/01-metadata/sitemap.mdx b/docs/02-app/02-api-reference/02-file-conventions/01-metadata/sitemap.mdx index 75fa2686bda13..4aa94f9c022fb 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/01-metadata/sitemap.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/01-metadata/sitemap.mdx @@ -97,7 +97,7 @@ export default function sitemap() { Output: -```xml filename="acme.com/sitemap" +```xml filename="acme.com/sitemap.xml" https://acme.com @@ -163,7 +163,7 @@ export default function sitemap(): MetadataRoute.Sitemap { Output: -```xml filename="acme.com/sitemap" +```xml filename="acme.com/sitemap.xml" https://acme.com @@ -264,7 +264,7 @@ export default async function sitemap({ id }) { } ``` -Your generated sitemaps will be available at `/.../sitemap/[id]`. For example, `/product/sitemap/1`. +Your generated sitemaps will be available at `/.../sitemap/[id]`. For example, `/product/sitemap/1.xml`. See the [`generateSitemaps` API reference](/docs/app/api-reference/functions/generate-sitemaps) for more information. diff --git a/packages/next-swc/crates/next-core/src/app_segment_config.rs b/packages/next-swc/crates/next-core/src/app_segment_config.rs index a4a76ede1533b..9b815d44f8d2c 100644 --- a/packages/next-swc/crates/next-core/src/app_segment_config.rs +++ b/packages/next-swc/crates/next-core/src/app_segment_config.rs @@ -8,7 +8,7 @@ use turbo_tasks_fs::FileSystemPath; use turbopack_binding::{ swc::core::{ common::{source_map::Pos, Span, Spanned, GLOBALS}, - ecma::ast::{Expr, Ident, Program}, + ecma::ast::{Decl, Expr, FnExpr, Ident, Program}, }, turbopack::{ core::{ @@ -73,6 +73,9 @@ pub struct NextSegmentConfig { pub runtime: Option, pub preferred_region: Option>, pub experimental_ppr: Option, + /// Wether these metadata exports are defined in the source file. + pub generate_image_metadata: bool, + pub generate_sitemaps: bool, } #[turbo_tasks::value_impl] @@ -95,6 +98,7 @@ impl NextSegmentConfig { runtime, preferred_region, experimental_ppr, + .. } = self; *dynamic = dynamic.or(parent.dynamic); *dynamic_params = dynamic_params.or(parent.dynamic_params); @@ -137,6 +141,7 @@ impl NextSegmentConfig { runtime, preferred_region, experimental_ppr, + .. } = self; merge_parallel(dynamic, ¶llel_config.dynamic, "dynamic")?; merge_parallel( @@ -272,22 +277,35 @@ pub async fn parse_segment_config_from_source( let mut config = NextSegmentConfig::default(); for item in &module_ast.body { - let Some(decl) = item + let Some(export_decl) = item .as_module_decl() .and_then(|mod_decl| mod_decl.as_export_decl()) - .and_then(|export_decl| export_decl.decl.as_var()) else { continue; }; - for decl in &decl.decls { - let Some(ident) = decl.name.as_ident().map(|ident| ident.deref()) else { - continue; - }; + match &export_decl.decl { + Decl::Var(var_decl) => { + for decl in &var_decl.decls { + let Some(ident) = decl.name.as_ident().map(|ident| ident.deref()) else { + continue; + }; - if let Some(init) = decl.init.as_ref() { - parse_config_value(source, &mut config, ident, init, eval_context); + if let Some(init) = decl.init.as_ref() { + parse_config_value(source, &mut config, ident, init, eval_context); + } + } + } + Decl::Fn(fn_decl) => { + let ident = &fn_decl.ident; + // create an empty expression of {}, we don't need init for function + let init = Expr::Fn(FnExpr { + ident: None, + function: fn_decl.function.clone(), + }); + parse_config_value(source, &mut config, ident, &init, eval_context); } + _ => {} } } config @@ -431,6 +449,14 @@ fn parse_config_value( config.preferred_region = Some(preferred_region); } + // Match exported generateImageMetadata function and generateSitemaps function, and pass + // them to config. + "generateImageMetadata" => { + config.generate_image_metadata = true; + } + "generateSitemaps" => { + config.generate_sitemaps = true; + } "experimental_ppr" => { let value = eval_context.eval(init); let Some(val) = value.as_bool() else { diff --git a/packages/next-swc/crates/next-core/src/next_app/metadata/mod.rs b/packages/next-swc/crates/next-core/src/next_app/metadata/mod.rs index ac35312e3a235..08af0f5908a72 100644 --- a/packages/next-swc/crates/next-core/src/next_app/metadata/mod.rs +++ b/packages/next-swc/crates/next-core/src/next_app/metadata/mod.rs @@ -306,8 +306,7 @@ pub fn normalize_metadata_route(mut page: AppPage) -> Result { route += ".txt" } else if route == "/manifest" { route += ".webmanifest" - // Do not append the suffix for the sitemap route - } else if !route.ends_with("/sitemap") { + } else { // Remove the file extension, e.g. /route-path/robots.txt -> /route-path let pathname_prefix = split_directory(&route).0.unwrap_or_default(); suffix = get_metadata_route_suffix(pathname_prefix); @@ -317,13 +316,8 @@ pub fn normalize_metadata_route(mut page: AppPage) -> Result { // //route.ts. If it's a metadata file route, we need to // append /[id]/route to the page. if !route.ends_with("/route") { - let is_static_metadata_file = is_static_metadata_route_file(&page.to_string()); let (base_name, ext) = split_extension(&route); - let is_static_route = route.starts_with("/robots") - || route.starts_with("/manifest") - || is_static_metadata_file; - page.0.pop(); page.push(PageSegment::Static( @@ -338,10 +332,6 @@ pub fn normalize_metadata_route(mut page: AppPage) -> Result { .into(), ))?; - if !is_static_route { - page.push(PageSegment::OptionalCatchAll("__metadata_id__".into()))?; - } - page.push(PageSegment::PageType(PageType::Route))?; } @@ -358,11 +348,11 @@ mod test { let cases = vec![ [ "/client/(meme)/more-route/twitter-image", - "/client/(meme)/more-route/twitter-image-769mad/[[...__metadata_id__]]/route", + "/client/(meme)/more-route/twitter-image-769mad/route", ], [ "/client/(meme)/more-route/twitter-image2", - "/client/(meme)/more-route/twitter-image2-769mad/[[...__metadata_id__]]/route", + "/client/(meme)/more-route/twitter-image2-769mad/route", ], ["/robots.txt", "/robots.txt/route"], ["/manifest.webmanifest", "/manifest.webmanifest/route"], diff --git a/packages/next-swc/crates/next-core/src/next_app/metadata/route.rs b/packages/next-swc/crates/next-core/src/next_app/metadata/route.rs index 7227f34bdce9d..d978de8369d3f 100644 --- a/packages/next-swc/crates/next-core/src/next_app/metadata/route.rs +++ b/packages/next-swc/crates/next-core/src/next_app/metadata/route.rs @@ -2,7 +2,7 @@ //! //! See `next/src/build/webpack/loaders/next-metadata-route-loader` -use anyhow::{bail, Result}; +use anyhow::{bail, Ok, Result}; use base64::{display::Base64Display, engine::general_purpose::STANDARD}; use indoc::{formatdoc, indoc}; use turbo_tasks::{ValueToString, Vc}; @@ -22,7 +22,9 @@ use super::get_content_type; use crate::{ app_structure::MetadataItem, mode::NextMode, - next_app::{app_entry::AppEntry, app_route_entry::get_app_route_entry, AppPage, PageSegment}, + next_app::{ + app_entry::AppEntry, app_route_entry::get_app_route_entry, AppPage, PageSegment, PageType, + }, next_config::NextConfig, parse_segment_config_from_source, }; @@ -30,9 +32,9 @@ use crate::{ /// Computes the route source for a Next.js metadata file. #[turbo_tasks::function] pub async fn get_app_metadata_route_source( - page: AppPage, mode: NextMode, metadata: MetadataItem, + is_multi_dynamic: bool, ) -> Result>> { Ok(match metadata { MetadataItem::Static { path } => static_route_source(mode, path), @@ -43,7 +45,7 @@ pub async fn get_app_metadata_route_source( if stem == "robots" || stem == "manifest" { dynamic_text_route_source(path) } else if stem == "sitemap" { - dynamic_site_map_route_source(mode, path, page) + dynamic_site_map_route_source(mode, path, is_multi_dynamic) } else { dynamic_image_route_source(path) } @@ -52,11 +54,11 @@ pub async fn get_app_metadata_route_source( } #[turbo_tasks::function] -pub fn get_app_metadata_route_entry( +pub async fn get_app_metadata_route_entry( nodejs_context: Vc, edge_context: Vc, project_root: Vc, - page: AppPage, + mut page: AppPage, mode: NextMode, metadata: MetadataItem, next_config: Vc, @@ -69,11 +71,43 @@ pub fn get_app_metadata_route_entry( let source = Vc::upcast(FileSource::new(original_path)); let segment_config = parse_segment_config_from_source(source); + let is_dynamic_metadata = matches!(metadata, MetadataItem::Dynamic { .. }); + let is_multi_dynamic: bool = if Some(segment_config).is_some() { + // is_multi_dynamic is true when config.generateSitemaps or + // config.generateImageMetadata is defined in dynamic routes + let config = segment_config.await.unwrap(); + config.generate_sitemaps || config.generate_image_metadata + } else { + false + }; + + // Map dynamic sitemap and image routes based on the exports. + // if there's generator export: add /[__metadata_id__] to the route; + // otherwise keep the original route. + // For sitemap, if the last segment is sitemap, appending .xml suffix. + if is_dynamic_metadata { + // remove the last /route segment of page + page.0.pop(); + + let _ = if is_multi_dynamic { + page.push(PageSegment::Dynamic("__metadata_id__".into())) + } else { + // if page last segment is sitemap, change to sitemap.xml + if page.last() == Some(&PageSegment::Static("sitemap".into())) { + page.0.pop(); + page.push(PageSegment::Static("sitemap.xml".into())) + } else { + Ok(()) + } + }; + // Push /route back + let _ = page.push(PageSegment::PageType(PageType::Route)); + }; get_app_route_entry( nodejs_context, edge_context, - get_app_metadata_route_source(page.clone(), mode, metadata), + get_app_metadata_route_source(mode, metadata, is_multi_dynamic), page, project_root, Some(segment_config), @@ -208,26 +242,24 @@ async fn dynamic_text_route_source(path: Vc) -> Result, - page: AppPage, + is_multi_dynamic: bool, ) -> Result>> { let stem = path.file_stem().await?; let stem = stem.as_deref().unwrap_or_default(); let ext = &*path.extension().await?; - let content_type = get_content_type(path).await?; - let mut static_generation_code = ""; - if mode.is_production() && page.contains(&PageSegment::Dynamic("[__metadata_id__]".into())) { + if mode.is_production() && is_multi_dynamic { static_generation_code = indoc! { r#" export async function generateStaticParams() { const sitemaps = await generateSitemaps() const params = [] - for (const item of sitemaps) { - params.push({ __metadata_id__: item.id.toString() }) - } + for (const item of sitemaps) {{ + params.push({ __metadata_id__: item.id.toString() + '.xml' }) + }} return params } "#, @@ -252,29 +284,25 @@ async fn dynamic_site_map_route_source( }} export async function GET(_, ctx) {{ - const {{ __metadata_id__ = [], ...params }} = ctx.params || {{}} - const targetId = __metadata_id__[0] - let id = undefined - const sitemaps = generateSitemaps ? await generateSitemaps() : null + const {{ __metadata_id__: id, ...params }} = ctx.params || {{}} + const hasXmlExtension = id ? id.endsWith('.xml') : false + if (id && !hasXmlExtension) {{ + return new NextResponse('Not Found', {{ + status: 404, + }}) + }} - if (sitemaps) {{ - id = sitemaps.find((item) => {{ - if (process.env.NODE_ENV !== 'production') {{ - if (item?.id == null) {{ - throw new Error('id property is required for every item returned from generateSitemaps') - }} + if (process.env.NODE_ENV !== 'production' && sitemapModule.generateSitemaps) {{ + const sitemaps = await sitemapModule.generateSitemaps() + for (const item of sitemaps) {{ + if (item?.id == null) {{ + throw new Error('id property is required for every item returned from generateSitemaps') }} - return item.id.toString() === targetId - }})?.id - - if (id == null) {{ - return new NextResponse('Not Found', {{ - status: 404, - }}) }} }} - - const data = await handler({{ id }}) + + const targetId = id && hasXmlExtension ? id.slice(0, -4) : undefined + const data = await handler({{ id: targetId }}) const content = resolveRouteData(data, fileType) return new NextResponse(content, {{ @@ -324,12 +352,12 @@ async fn dynamic_image_route_source(path: Vc) -> Result {{ if (process.env.NODE_ENV !== 'production') {{ if (item?.id == null) {{ diff --git a/packages/next/src/build/analysis/get-page-static-info.ts b/packages/next/src/build/analysis/get-page-static-info.ts index 97dd5b2f69455..d77c236e10d53 100644 --- a/packages/next/src/build/analysis/get-page-static-info.ts +++ b/packages/next/src/build/analysis/get-page-static-info.ts @@ -59,6 +59,8 @@ export interface PageStaticInfo { ssr?: boolean rsc?: RSCModuleType generateStaticParams?: boolean + generateSitemaps?: boolean + generateImageMetadata?: boolean middleware?: MiddlewareConfigParsed amp?: boolean | 'hybrid' extraConfig?: Record @@ -141,8 +143,8 @@ function checkExports( ssg: boolean runtime?: string preferredRegion?: string | string[] - generateImageMetadata?: boolean - generateSitemaps?: boolean + generateImageMetadata: boolean + generateSitemaps: boolean generateStaticParams: boolean extraProperties?: Set directives?: Set @@ -467,20 +469,6 @@ function warnAboutUnsupportedValue( warnedUnsupportedValueMap.set(pageFilePath, true) } -// Detect if metadata routes is a dynamic route, which containing -// generateImageMetadata or generateSitemaps as export -export async function isDynamicMetadataRoute( - pageFilePath: string -): Promise { - const fileContent = (await tryToReadFile(pageFilePath, true)) || '' - if (/generateImageMetadata|generateSitemaps/.test(fileContent)) { - const swcAST = await parseModule(pageFilePath, fileContent) - const exportsInfo = checkExports(swcAST, pageFilePath) - return !!(exportsInfo.generateImageMetadata || exportsInfo.generateSitemaps) - } - return false -} - /** * For a given pageFilePath and nextConfig, if the config supports it, this * function will read the file and return the runtime that should be used. @@ -499,7 +487,7 @@ export async function getPageStaticInfo(params: { const fileContent = (await tryToReadFile(pageFilePath, !isDev)) || '' if ( - /(? { const isAppRoute = pagesType === 'app' - const pages = pagePaths.reduce<{ [key: string]: string }>( - (result, pagePath) => { - // Do not process .d.ts files as routes - if (pagePath.endsWith('.d.ts') && pageExtensions.includes('ts')) { - return result - } + const pages: MappedPages = {} + const promises = pagePaths.map>(async (pagePath) => { + // Do not process .d.ts files as routes + if (pagePath.endsWith('.d.ts') && pageExtensions.includes('ts')) { + return + } - let pageKey = getPageFromPath(pagePath, pageExtensions) - if (isAppRoute) { - pageKey = pageKey.replace(/%5F/g, '_') - if (pageKey === '/not-found') { - pageKey = UNDERSCORE_NOT_FOUND_ROUTE_ENTRY - } + let pageKey = getPageFromPath(pagePath, pageExtensions) + if (isAppRoute) { + pageKey = pageKey.replace(/%5F/g, '_') + if (pageKey === '/not-found') { + pageKey = UNDERSCORE_NOT_FOUND_ROUTE_ENTRY } + } - const normalizedPath = normalizePathSep( - join( - pagesType === 'pages' - ? PAGES_DIR_ALIAS - : pagesType === 'app' - ? APP_DIR_ALIAS - : ROOT_DIR_ALIAS, - pagePath - ) + const normalizedPath = normalizePathSep( + join( + pagesType === 'pages' + ? PAGES_DIR_ALIAS + : pagesType === 'app' + ? APP_DIR_ALIAS + : ROOT_DIR_ALIAS, + pagePath ) + ) - const route = - pagesType === 'app' ? normalizeMetadataRoute(pageKey) : pageKey - result[route] = normalizedPath - return result - }, - {} - ) + let route = pagesType === 'app' ? normalizeMetadataRoute(pageKey) : pageKey + + if (isMetadataRoute(route) && pagesType === 'app') { + const filePath = join(appDir!, pagePath) + const staticInfo = await getPageStaticInfo({ + nextConfig: {}, + pageFilePath: filePath, + isDev, + page: pageKey, + pageType: pagesType, + }) + + route = normalizeMetadataPageToRoute( + route, + !!(staticInfo.generateImageMetadata || staticInfo.generateSitemaps) + ) + } + + pages[route] = normalizedPath + }) + + await Promise.all(promises) switch (pagesType) { case PAGE_TYPES.ROOT: { diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts index 5e2d15e62d2aa..6729c182a510e 100644 --- a/packages/next/src/build/index.ts +++ b/packages/next/src/build/index.ts @@ -100,11 +100,8 @@ import { } from '../telemetry/events' import type { EventBuildFeatureUsage } from '../telemetry/events' import { Telemetry } from '../telemetry/storage' -import { - isDynamicMetadataRoute, - getPageStaticInfo, -} from './analysis/get-page-static-info' -import { createPagesMapping, getPageFilePath, sortByPageExts } from './entries' +import { getPageStaticInfo } from './analysis/get-page-static-info' +import { createPagesMapping, sortByPageExts } from './entries' import { PAGE_TYPES } from '../lib/page-types' import { generateBuildId } from './generate-build-id' import { isWriteable } from './is-writeable' @@ -912,15 +909,16 @@ export default async function build( } NextBuildContext.previewProps = previewProps - const mappedPages = nextBuildSpan + const mappedPages = await nextBuildSpan .traceChild('create-pages-mapping') - .traceFn(() => + .traceAsyncFn(() => createPagesMapping({ isDev: false, pageExtensions: config.pageExtensions, pagesType: PAGE_TYPES.PAGES, pagePaths: pagesPaths, pagesDir, + appDir, }) ) NextBuildContext.mappedPages = mappedPages @@ -942,60 +940,29 @@ export default async function build( }) ) - mappedAppPages = nextBuildSpan + mappedAppPages = await nextBuildSpan .traceChild('create-app-mapping') - .traceFn(() => + .traceAsyncFn(() => createPagesMapping({ pagePaths: appPaths, isDev: false, pagesType: PAGE_TYPES.APP, pageExtensions: config.pageExtensions, - pagesDir: pagesDir, - }) - ) - - // If the metadata route doesn't contain generating dynamic exports, - // we can replace the dynamic catch-all route and use the static route instead. - for (const [pageKey, pagePath] of Object.entries(mappedAppPages)) { - if (pageKey.includes('[[...__metadata_id__]]')) { - const pageFilePath = getPageFilePath({ - absolutePagePath: pagePath, pagesDir, appDir, - rootDir, }) - - const isDynamic = await isDynamicMetadataRoute(pageFilePath) - if (!isDynamic) { - delete mappedAppPages[pageKey] - mappedAppPages[pageKey.replace('[[...__metadata_id__]]/', '')] = - pagePath - } - - if ( - pageKey.includes('sitemap/[[...__metadata_id__]]') && - isDynamic - ) { - delete mappedAppPages[pageKey] - mappedAppPages[ - pageKey.replace( - 'sitemap/[[...__metadata_id__]]', - 'sitemap/[__metadata_id__]' - ) - ] = pagePath - } - } - } + ) NextBuildContext.mappedAppPages = mappedAppPages } - const mappedRootPaths = createPagesMapping({ + const mappedRootPaths = await createPagesMapping({ isDev: false, pageExtensions: config.pageExtensions, pagePaths: rootPaths, pagesType: PAGE_TYPES.ROOT, pagesDir: pagesDir, + appDir, }) NextBuildContext.mappedRootPaths = mappedRootPaths @@ -1223,11 +1190,6 @@ export default async function build( '{"type": "commonjs"}' ) - // We need to write the manifest with rewrites before build - await nextBuildSpan - .traceChild('write-routes-manifest') - .traceAsyncFn(() => writeManifest(routesManifestPath, routesManifest)) - await writeEdgePartialPrerenderManifest(distDir, {}) const outputFileTracingRoot = @@ -2338,9 +2300,14 @@ export default async function build( return buildDataRoute(page, buildId) }) - await writeManifest(routesManifestPath, routesManifest) + // await writeManifest(routesManifestPath, routesManifest) } + // We need to write the manifest with rewrites before build + await nextBuildSpan + .traceChild('write-routes-manifest') + .traceAsyncFn(() => writeManifest(routesManifestPath, routesManifest)) + // Since custom _app.js can wrap the 404 page we have to opt-out of static optimization if it has getInitialProps // Only export the static 404 when there is no /_error present const useStaticPages404 = diff --git a/packages/next/src/build/output/store.ts b/packages/next/src/build/output/store.ts index b77ebd8f8545c..f761ba6055075 100644 --- a/packages/next/src/build/output/store.ts +++ b/packages/next/src/build/output/store.ts @@ -24,13 +24,13 @@ export type OutputState = } )) -const internalSegments = ['[[...__metadata_id__]]', '[__metadata_id__]'] export function formatTrigger(trigger: string) { - for (const segment of internalSegments) { - if (trigger.includes(segment)) { - trigger = trigger.replace(segment, '') - } + // Format dynamic sitemap routes to simpler file path + // e.g., /sitemap.xml[] -> /sitemap.xml + if (trigger.includes('[__metadata_id__]')) { + trigger = trigger.replace('/[__metadata_id__]', '/[id]') } + if (trigger.length > 1 && trigger.endsWith('/')) { trigger = trigger.slice(0, -1) } diff --git a/packages/next/src/build/webpack/loaders/metadata/discover.ts b/packages/next/src/build/webpack/loaders/metadata/discover.ts index c0264c4e50d61..74d0403ed6d2d 100644 --- a/packages/next/src/build/webpack/loaders/metadata/discover.ts +++ b/packages/next/src/build/webpack/loaders/metadata/discover.ts @@ -10,6 +10,7 @@ import type { MetadataResolver } from '../next-app-loader' import type { PageExtensions } from '../../../page-extensions-type' const METADATA_TYPE = 'metadata' +const NUMERIC_SUFFIX_ARRAY = Array(10).fill(0) // Produce all compositions with filename (icon, apple-icon, etc.) with extensions (png, jpg, etc.) async function enumMetadataFiles( @@ -27,11 +28,10 @@ async function enumMetadataFiles( ): Promise { const collectedFiles: string[] = [] + // Collect ., []. const possibleFileNames = [filename].concat( numericSuffix - ? Array(10) - .fill(0) - .map((_, index) => filename + index) + ? NUMERIC_SUFFIX_ARRAY.map((_, index) => filename + index) : [] ) for (const name of possibleFileNames) { @@ -91,14 +91,15 @@ export async function createStaticMetadataFromRoute( return } + const isFavicon = type === 'favicon' const resolvedMetadataFiles = await enumMetadataFiles( resolvedDir, STATIC_METADATA_IMAGES[type].filename, [ ...STATIC_METADATA_IMAGES[type].extensions, - ...(type === 'favicon' ? [] : pageExtensions), + ...(isFavicon ? [] : pageExtensions), ], - { metadataResolver, numericSuffix: true } + { metadataResolver, numericSuffix: !isFavicon } ) resolvedMetadataFiles .sort((a, b) => a.localeCompare(b)) diff --git a/packages/next/src/build/webpack/loaders/next-app-loader.ts b/packages/next/src/build/webpack/loaders/next-app-loader.ts index 6c781d76e7feb..728cc5f8427ee 100644 --- a/packages/next/src/build/webpack/loaders/next-app-loader.ts +++ b/packages/next/src/build/webpack/loaders/next-app-loader.ts @@ -121,15 +121,15 @@ async function createAppRouteCode({ // If this is a metadata route, then we need to use the metadata loader for // the route to ensure that the route is generated. - const filename = path.parse(resolvedPagePath).name - if (isMetadataRoute(name) && filename !== 'route') { + const fileBaseName = path.parse(resolvedPagePath).name + if (isMetadataRoute(name) && fileBaseName !== 'route') { const { ext } = getFilenameAndExtension(resolvedPagePath) - const isDynamic = pageExtensions.includes(ext) + const isDynamicRouteExtension = pageExtensions.includes(ext) resolvedPagePath = `next-metadata-route-loader?${stringify({ page, filePath: resolvedPagePath, - isDynamic: isDynamic ? '1' : '0', + isDynamicRouteExtension: isDynamicRouteExtension ? '1' : '0', })}!?${WEBPACK_RESOURCE_QUERIES.metadataRoute}` } @@ -142,7 +142,7 @@ async function createAppRouteCode({ VAR_USERLAND: resolvedPagePath, VAR_DEFINITION_PAGE: page, VAR_DEFINITION_PATHNAME: pathname, - VAR_DEFINITION_FILENAME: filename, + VAR_DEFINITION_FILENAME: fileBaseName, VAR_DEFINITION_BUNDLE_PATH: bundlePath, VAR_RESOLVED_PAGE_PATH: resolvedPagePath, VAR_ORIGINAL_PATHNAME: page, diff --git a/packages/next/src/build/webpack/loaders/next-metadata-route-loader.ts b/packages/next/src/build/webpack/loaders/next-metadata-route-loader.ts index 5adb640f7ce33..b0cee835f9d40 100644 --- a/packages/next/src/build/webpack/loaders/next-metadata-route-loader.ts +++ b/packages/next/src/build/webpack/loaders/next-metadata-route-loader.ts @@ -23,13 +23,17 @@ const cacheHeader = { type MetadataRouteLoaderOptions = { page: string filePath: string - isDynamic: '1' | '0' + isDynamicRouteExtension: '1' | '0' + isDynamicMultiRoute: '1' | '0' } export function getFilenameAndExtension(resourcePath: string) { const filename = path.basename(resourcePath) const [name, ext] = filename.split('.', 2) - return { name, ext } + return { + name, + ext, + } } function getContentType(resourcePath: string) { @@ -123,11 +127,11 @@ ${errorOnBadHandler(resourcePath)} export async function GET(_, ctx) { const { __metadata_id__, ...params } = ctx.params || {} - const targetId = __metadata_id__?.[0] + const targetId = __metadata_id__ let id = undefined - const imageMetadata = generateImageMetadata ? await generateImageMetadata({ params }) : null - - if (imageMetadata) { + + if (generateImageMetadata) { + const imageMetadata = await generateImageMetadata({ params }) id = imageMetadata.find((item) => { if (process.env.NODE_ENV !== 'production') { if (item?.id == null) { @@ -142,14 +146,14 @@ export async function GET(_, ctx) { }) } } + return handler({ params: ctx.params ? params : undefined, id }) } ` } -async function getDynamicSiteMapRouteCode( +async function getDynamicSitemapRouteCode( resourcePath: string, - page: string, loaderContext: webpack.LoaderContext ) { let staticGenerationCode = '' @@ -163,23 +167,20 @@ async function getDynamicSiteMapRouteCode( (name) => name !== 'default' && name !== 'generateSitemaps' ) - const hasGenerateSiteMaps = exportNames.includes('generateSitemaps') - if ( - process.env.NODE_ENV === 'production' && - hasGenerateSiteMaps && - page.includes('[__metadata_id__]') - ) { + const hasGenerateSitemaps = exportNames.includes('generateSitemaps') + + if (process.env.NODE_ENV === 'production' && hasGenerateSitemaps) { staticGenerationCode = `\ -/* dynamic sitemap route */ -export async function generateStaticParams() { - const sitemaps = generateSitemaps ? await generateSitemaps() : [] - const params = [] + /* dynamic sitemap route */ + export async function generateStaticParams() { + const sitemaps = await sitemapModule.generateSitemaps() + const params = [] - for (const item of sitemaps) { - params.push({ __metadata_id__: item.id.toString() }) - } - return params -} + for (const item of sitemaps) { + params.push({ __metadata_id__: item.id.toString() + '.xml' }) + } + return params + } ` } @@ -190,7 +191,6 @@ import { resolveRouteData } from 'next/dist/build/webpack/loaders/metadata/resol const sitemapModule = { ...userland } const handler = sitemapModule.default -const generateSitemaps = sitemapModule.generateSitemaps const contentType = ${JSON.stringify(getContentType(resourcePath))} const fileType = ${JSON.stringify(getFilenameAndExtension(resourcePath).name)} @@ -206,35 +206,27 @@ ${ } export async function GET(_, ctx) { - const { __metadata_id__, ...params } = ctx.params || {} - ${ - '' /* sitemap will be optimized to [__metadata_id__] from [[..._metadata_id__]] in production */ - } - const targetId = process.env.NODE_ENV !== 'production' - ? __metadata_id__?.[0] - : __metadata_id__ + const { __metadata_id__: id, ...params } = ctx.params || {} + const hasXmlExtension = id ? id.endsWith('.xml') : false - let id = undefined - const sitemaps = generateSitemaps ? await generateSitemaps() : null + if (id && !hasXmlExtension) { + return new NextResponse('Not Found', { + status: 404, + }) + } - if (sitemaps) { - id = sitemaps.find((item) => { - if (process.env.NODE_ENV !== 'production') { - if (item?.id == null) { - throw new Error('id property is required for every item returned from generateSitemaps') - } + if (process.env.NODE_ENV !== 'production' && sitemapModule.generateSitemaps) { + const sitemaps = await sitemapModule.generateSitemaps() + for (const item of sitemaps) { + if (item?.id == null) { + throw new Error('id property is required for every item returned from generateSitemaps') } - let itemID = item.id.toString() - return itemID === targetId - })?.id - if (id == null) { - return new NextResponse('Not Found', { - status: 404, - }) } } - const data = await handler({ id }) + const targetId = id && hasXmlExtension ? id.slice(0, -4) : undefined + + const data = await handler({ id: targetId }) const content = resolveRouteData(data, fileType) return new NextResponse(content, { @@ -254,15 +246,15 @@ ${staticGenerationCode} // TODO-METADATA: improve the cache control strategy const nextMetadataRouterLoader: webpack.LoaderDefinitionFunction = async function () { - const { page, isDynamic, filePath } = this.getOptions() + const { isDynamicRouteExtension, filePath } = this.getOptions() const { name: fileBaseName } = getFilenameAndExtension(filePath) let code = '' - if (isDynamic === '1') { + if (isDynamicRouteExtension === '1') { if (fileBaseName === 'robots' || fileBaseName === 'manifest') { code = getDynamicTextRouteCode(filePath) } else if (fileBaseName === 'sitemap') { - code = await getDynamicSiteMapRouteCode(filePath, page, this) + code = await getDynamicSitemapRouteCode(filePath, this) } else { code = getDynamicImageRouteCode(filePath) } diff --git a/packages/next/src/export/routes/app-route.ts b/packages/next/src/export/routes/app-route.ts index 7c5218bb9df13..66db13b36347a 100644 --- a/packages/next/src/export/routes/app-route.ts +++ b/packages/next/src/export/routes/app-route.ts @@ -25,10 +25,7 @@ import { SERVER_DIRECTORY } from '../../shared/lib/constants' import { hasNextSupport } from '../../telemetry/ci-info' import { isStaticGenEnabled } from '../../server/route-modules/app-route/helpers/is-static-gen-enabled' import type { ExperimentalConfig } from '../../server/config-shared' -import { - isMetadataRouteFile, - isStaticMetadataRoute, -} from '../../lib/metadata/is-metadata-route' +import { isMetadataRouteFile } from '../../lib/metadata/is-metadata-route' import { normalizeAppPath } from '../../shared/lib/router/utils/app-paths' export const enum ExportedAppRouteFiles { @@ -97,9 +94,7 @@ export async function exportAppRoute( // we don't bail from the static optimization for // metadata routes const normalizedPage = normalizeAppPath(page) - const isMetadataRoute = - isStaticMetadataRoute(normalizedPage) || - isMetadataRouteFile(`${normalizedPage}.ts`, ['ts'], true) + const isMetadataRoute = isMetadataRouteFile(normalizedPage, [], false) if (!isStaticGenEnabled(userland) && !isMetadataRoute) { return { revalidate: 0 } diff --git a/packages/next/src/lib/metadata/get-metadata-route.ts b/packages/next/src/lib/metadata/get-metadata-route.ts index 8bccf25b42647..dff0ae500c8ac 100644 --- a/packages/next/src/lib/metadata/get-metadata-route.ts +++ b/packages/next/src/lib/metadata/get-metadata-route.ts @@ -1,4 +1,4 @@ -import { isMetadataRoute, isStaticMetadataRoute } from './is-metadata-route' +import { isMetadataRoute } from './is-metadata-route' import path from '../../shared/lib/isomorphic/path' import { interpolateDynamicPath } from '../../server/server-utils' import { getNamedRouteRegex } from '../../shared/lib/router/utils/route-regex' @@ -11,8 +11,8 @@ import { normalizePathSep } from '../../shared/lib/page-path/normalize-path-sep' * Give it a unique hash suffix to avoid conflicts * * e.g. - * /app/open-graph.tsx -> /open-graph/route - * /app/(post)/open-graph.tsx -> /open-graph/route-[0-9a-z]{6} + * /app/opengraph-image.tsx -> /opengraph-image + * /app/(post)/opengraph-image.tsx -> /opengraph-image-[0-9a-z]{6} */ function getMetadataRouteSuffix(page: string) { let suffix = '' @@ -65,10 +65,10 @@ export function normalizeMetadataRoute(page: string) { route += '.txt' } else if (page === '/manifest') { route += '.webmanifest' - } - // For sitemap, we don't automatically add the route suffix since it can have sub-routes - else if (!page.endsWith('/sitemap')) { - // Remove the file extension, e.g. /route-path/robots.txt -> /route-path + } else { + // Remove the file extension, + // e.g. /path/robots.txt -> /route-path + // e.g. /path/opengraph-image.tsx -> /path/opengraph-image const pathnamePrefix = page.slice(0, -(path.basename(page).length + 1)) suffix = getMetadataRouteSuffix(pathnamePrefix) } @@ -76,15 +76,30 @@ export function normalizeMetadataRoute(page: string) { // If it's a metadata file route, we need to append /[id]/route to the page. if (!route.endsWith('/route')) { const { dir, name: baseName, ext } = path.parse(route) - const isStaticRoute = isStaticMetadataRoute(page) - route = path.posix.join( dir, `${baseName}${suffix ? `-${suffix}` : ''}${ext}`, - isStaticRoute ? '' : '[[...__metadata_id__]]', 'route' ) } return route } + +// Normalize metadata route page to either a single route or a dynamic route. +// e.g. Input: /sitemap/route +// when isDynamic is false, single route -> /sitemap.xml/route +// when isDynamic is false, dynamic route -> /sitemap/[__metadata_id__]/route +// also works for pathname such as /sitemap -> /sitemap.xml, but will not append /route suffix +export function normalizeMetadataPageToRoute(page: string, isDynamic: boolean) { + const isRoute = page.endsWith('/route') + const routePagePath = isRoute ? page.slice(0, -'/route'.length) : page + const metadataRouteExtension = routePagePath.endsWith('/sitemap') + ? '.xml' + : '' + const mapped = isDynamic + ? `${routePagePath}/[__metadata_id__]` + : `${routePagePath}${metadataRouteExtension}` + + return mapped + (isRoute ? '/route' : '') +} diff --git a/packages/next/src/lib/metadata/is-metadata-route.test.ts b/packages/next/src/lib/metadata/is-metadata-route.test.ts new file mode 100644 index 0000000000000..99c520fd94b7a --- /dev/null +++ b/packages/next/src/lib/metadata/is-metadata-route.test.ts @@ -0,0 +1,45 @@ +import { getExtensionRegexString } from './is-metadata-route' + +describe('getExtensionRegexString', () => { + function createExtensionMatchRegex( + ...args: Parameters + ) { + return new RegExp(`^${getExtensionRegexString(...args)}$`) + } + + describe('with dynamic extensions', () => { + it('should return the correct regex', () => { + const regex = createExtensionMatchRegex(['png', 'jpg'], ['tsx', 'ts']) + expect(regex.test('.png')).toBe(true) + expect(regex.test('.jpg')).toBe(true) + expect(regex.test('.webp')).toBe(false) + + expect(regex.test('.tsx')).toBe(true) + expect(regex.test('.ts')).toBe(true) + expect(regex.test('.js')).toBe(false) + }) + + it('should match dynamic multi-routes with dynamic extensions', () => { + const regex = createExtensionMatchRegex(['png'], ['ts']) + expect(regex.test('.png')).toBe(true) + expect(regex.test('[].png')).toBe(false) + + expect(regex.test('.ts')).toBe(true) + expect(regex.test('[].ts')).toBe(true) + expect(regex.test('.tsx')).toBe(false) + expect(regex.test('[].tsx')).toBe(false) + }) + }) + + describe('without dynamic extensions', () => { + it('should return the correct regex', () => { + const regex = createExtensionMatchRegex(['png', 'jpg'], null) + expect(regex.test('.png')).toBe(true) + expect(regex.test('.jpg')).toBe(true) + expect(regex.test('.webp')).toBe(false) + + expect(regex.test('.tsx')).toBe(false) + expect(regex.test('.js')).toBe(false) + }) + }) +}) diff --git a/packages/next/src/lib/metadata/is-metadata-route.ts b/packages/next/src/lib/metadata/is-metadata-route.ts index 0cc542d6cc12f..ac1e68e456e6c 100644 --- a/packages/next/src/lib/metadata/is-metadata-route.ts +++ b/packages/next/src/lib/metadata/is-metadata-route.ts @@ -28,8 +28,19 @@ export const STATIC_METADATA_IMAGES = { // TODO-METADATA: support more metadata routes with more extensions const defaultExtensions = ['js', 'jsx', 'ts', 'tsx'] -const getExtensionRegexString = (extensions: readonly string[]) => - `(?:${extensions.join('|')})` +// Match the file extension with the dynamic multi-routes extensions +// e.g. ([xml, js], null) -> can match `/sitemap.xml/route`, `sitemap.js/route` +// e.g. ([png], [ts]) -> can match `/opengrapg-image.png/route`, `/opengraph-image.ts[]/route` +export const getExtensionRegexString = ( + staticExtensions: readonly string[], + dynamicExtensions: readonly string[] | null +) => { + // If there's no possible multi dynamic routes, will not match any []. files + if (!dynamicExtensions) { + return `\\.(?:${staticExtensions.join('|')})` + } + return `(?:\\.(${staticExtensions.join('|')})|((\\[\\])?\\.(${dynamicExtensions.join('|')})))` +} // When you only pass the file extension as `[]`, it will only match the static convention files // e.g. /robots.txt, /sitemap.xml, /favicon.ico, /manifest.json @@ -46,15 +57,16 @@ export function isMetadataRouteFile( new RegExp( `^[\\\\/]robots${ withExtension - ? `\\.${getExtensionRegexString(pageExtensions.concat('txt'))}$` + ? `${getExtensionRegexString(pageExtensions.concat('txt'), null)}$` : '' }` ), new RegExp( `^[\\\\/]manifest${ withExtension - ? `\\.${getExtensionRegexString( - pageExtensions.concat('webmanifest', 'json') + ? `${getExtensionRegexString( + pageExtensions.concat('webmanifest', 'json'), + null )}$` : '' }` @@ -63,15 +75,16 @@ export function isMetadataRouteFile( new RegExp( `[\\\\/]sitemap${ withExtension - ? `\\.${getExtensionRegexString(pageExtensions.concat('xml'))}$` + ? `${getExtensionRegexString(['xml'], pageExtensions)}$` : '' }` ), new RegExp( `[\\\\/]${STATIC_METADATA_IMAGES.icon.filename}\\d?${ withExtension - ? `\\.${getExtensionRegexString( - pageExtensions.concat(STATIC_METADATA_IMAGES.icon.extensions) + ? `${getExtensionRegexString( + STATIC_METADATA_IMAGES.icon.extensions, + pageExtensions )}$` : '' }` @@ -79,8 +92,9 @@ export function isMetadataRouteFile( new RegExp( `[\\\\/]${STATIC_METADATA_IMAGES.apple.filename}\\d?${ withExtension - ? `\\.${getExtensionRegexString( - pageExtensions.concat(STATIC_METADATA_IMAGES.apple.extensions) + ? `${getExtensionRegexString( + STATIC_METADATA_IMAGES.apple.extensions, + pageExtensions )}$` : '' }` @@ -88,8 +102,9 @@ export function isMetadataRouteFile( new RegExp( `[\\\\/]${STATIC_METADATA_IMAGES.openGraph.filename}\\d?${ withExtension - ? `\\.${getExtensionRegexString( - pageExtensions.concat(STATIC_METADATA_IMAGES.openGraph.extensions) + ? `${getExtensionRegexString( + STATIC_METADATA_IMAGES.openGraph.extensions, + pageExtensions )}$` : '' }` @@ -97,8 +112,9 @@ export function isMetadataRouteFile( new RegExp( `[\\\\/]${STATIC_METADATA_IMAGES.twitter.filename}\\d?${ withExtension - ? `\\.${getExtensionRegexString( - pageExtensions.concat(STATIC_METADATA_IMAGES.twitter.extensions) + ? `${getExtensionRegexString( + STATIC_METADATA_IMAGES.twitter.extensions, + pageExtensions )}$` : '' }` @@ -115,6 +131,7 @@ export function isStaticMetadataRouteFile(appDirRelativePath: string) { return isMetadataRouteFile(appDirRelativePath, [], true) } +// @deprecated export function isStaticMetadataRoute(page: string) { return ( page === '/robots' || diff --git a/packages/next/src/server/dev/hot-reloader-turbopack.ts b/packages/next/src/server/dev/hot-reloader-turbopack.ts index 9619bf2c28e4f..c09e7be9ea984 100644 --- a/packages/next/src/server/dev/hot-reloader-turbopack.ts +++ b/packages/next/src/server/dev/hot-reloader-turbopack.ts @@ -1,6 +1,6 @@ import type { Socket } from 'net' import { mkdir, writeFile } from 'fs/promises' -import { join } from 'path' +import { join, extname } from 'path' import ws from 'next/dist/compiled/ws' @@ -63,6 +63,7 @@ import { type TopLevelIssuesMap, isWellKnownError, printNonFatalIssue, + normalizeAppMetadataRoutePage, } from './turbopack-utils' import { propagateServerField, @@ -807,9 +808,13 @@ export async function createHotReloaderTurbopack( await currentEntriesHandling const isInsideAppDir = routeDef.bundlePath.startsWith('app/') + const normalizedAppPage = normalizeAppMetadataRoutePage( + page, + extname(routeDef.filename) + ) const route = isInsideAppDir - ? currentEntrypoints.app.get(page) + ? currentEntrypoints.app.get(normalizedAppPage) : currentEntrypoints.page.get(page) if (!route) { diff --git a/packages/next/src/server/dev/hot-reloader-webpack.ts b/packages/next/src/server/dev/hot-reloader-webpack.ts index f55a9f5ece216..d6e5130c7948f 100644 --- a/packages/next/src/server/dev/hot-reloader-webpack.ts +++ b/packages/next/src/server/dev/hot-reloader-webpack.ts @@ -583,9 +583,9 @@ export default class HotReloaderWebpack implements NextJsHotReloaderInterface { ]) ) - this.pagesMapping = webpackConfigSpan + this.pagesMapping = await webpackConfigSpan .traceChild('create-pages-mapping') - .traceFn(() => + .traceAsyncFn(() => createPagesMapping({ isDev: true, pageExtensions: this.config.pageExtensions, @@ -594,6 +594,7 @@ export default class HotReloaderWebpack implements NextJsHotReloaderInterface { (i: string | null): i is string => typeof i === 'string' ), pagesDir: this.pagesDir, + appDir: this.appDir, }) ) diff --git a/packages/next/src/server/dev/turbopack-utils.ts b/packages/next/src/server/dev/turbopack-utils.ts index 7167fedcbcf87..564eea33c8e59 100644 --- a/packages/next/src/server/dev/turbopack-utils.ts +++ b/packages/next/src/server/dev/turbopack-utils.ts @@ -33,6 +33,7 @@ import { } from './turbopack/entry-key' import type ws from 'next/dist/compiled/ws' import isInternal from '../../shared/lib/is-internal' +import { isMetadataRoute } from '../../lib/metadata/is-metadata-route' export async function getTurbopackJsConfig( dir: string, @@ -519,7 +520,10 @@ export async function handleRouteType({ const type = writtenEndpoint?.type - await manifestLoader.loadAppPathsManifest(page) + await manifestLoader.loadAppPathsManifest( + normalizeAppMetadataRoutePage(page, false) + ) + if (type === 'edge') { await manifestLoader.loadMiddlewareManifest(page, 'app') } else { @@ -995,3 +999,27 @@ export async function handlePagesErrorRoute({ pageEntrypoints: entrypoints.page, }) } + +export function normalizeAppMetadataRoutePage( + route: string, + ext: string | false +): string { + let entrypointKey = route + if (isMetadataRoute(entrypointKey)) { + entrypointKey = entrypointKey.endsWith('/route') + ? entrypointKey.slice(0, -'/route'.length) + : entrypointKey + + if (ext) { + if (entrypointKey.endsWith('/[__metadata_id__]')) { + entrypointKey = entrypointKey.slice(0, -'/[__metadata_id__]'.length) + } + if (entrypointKey.endsWith('/sitemap.xml') && ext !== '.xml') { + // For dynamic sitemap route, remove the extension + entrypointKey = entrypointKey.slice(0, -'.xml'.length) + } + } + entrypointKey = entrypointKey + '/route' + } + return entrypointKey +} diff --git a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts index 79fbba8c00c41..ad1ac8fa5457e 100644 --- a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts +++ b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts @@ -1,7 +1,10 @@ import type { NextConfigComplete } from '../../config-shared' import type { FilesystemDynamicRoute } from './filesystem' import type { UnwrapPromise } from '../../../lib/coalesced-function' -import type { MiddlewareMatcher } from '../../../build/analysis/get-page-static-info' +import { + getPageStaticInfo, + type MiddlewareMatcher, +} from '../../../build/analysis/get-page-static-info' import type { MiddlewareRouteMatch } from '../../../shared/lib/router/utils/middleware-route-matcher' import type { PropagateToWorkersField } from './types' import type { NextJsHotReloaderInterface } from '../../dev/hot-reloader-types' @@ -77,6 +80,8 @@ import { getErrorSource } from '../../../shared/lib/error-source' import type { StackFrame } from 'next/dist/compiled/stacktrace-parser' import { generateEncryptionKeyBase64 } from '../../app-render/encryption-utils' import { ModuleBuildError } from '../../dev/turbopack-utils' +import { isMetadataRoute } from '../../../lib/metadata/is-metadata-route' +import { normalizeMetadataPageToRoute } from '../../../lib/metadata/get-metadata-route' export type SetupOpts = { renderServer: LazyRenderServerInstance @@ -397,6 +402,32 @@ async function startWatcher(opts: SetupOpts) { pagesType: isAppPath ? PAGE_TYPES.APP : PAGE_TYPES.PAGES, }) + if (isAppPath && isMetadataRoute(pageName)) { + const staticInfo = await getPageStaticInfo({ + pageFilePath: fileName, + nextConfig: {}, + page: pageName, + isDev: true, + pageType: PAGE_TYPES.APP, + }) + + pageName = normalizeMetadataPageToRoute( + pageName, + !!(staticInfo.generateSitemaps || staticInfo.generateImageMetadata) + ) + + // pageName = pageName.slice(0, -'/route'.length) + // if (pageName.endsWith('/sitemap')) { + + // if (staticInfo.generateSitemaps) { + // pageName = `${pageName}/[__metadata_id__]` + // } else { + // pageName = `${pageName}.xml` + // } + // } + // pageName = `${pageName}/route` + } + if ( !isAppPath && pageName.startsWith('/api/') && diff --git a/packages/next/src/server/route-matcher-providers/dev/dev-app-route-route-matcher-provider.ts b/packages/next/src/server/route-matcher-providers/dev/dev-app-route-route-matcher-provider.ts index bd681c7ab378f..1a236aa8406a7 100644 --- a/packages/next/src/server/route-matcher-providers/dev/dev-app-route-route-matcher-provider.ts +++ b/packages/next/src/server/route-matcher-providers/dev/dev-app-route-route-matcher-provider.ts @@ -5,6 +5,11 @@ import { RouteKind } from '../../route-kind' import { FileCacheRouteMatcherProvider } from './file-cache-route-matcher-provider' import { isAppRouteRoute } from '../../../lib/is-app-route-route' import { DevAppNormalizers } from '../../normalizers/built/app' +import { + isMetadataRoute, + isStaticMetadataRoute, +} from '../../../lib/metadata/is-metadata-route' +import { normalizeMetadataPageToRoute } from '../../../lib/metadata/get-metadata-route' export class DevAppRouteRouteMatcherProvider extends FileCacheRouteMatcherProvider { private readonly normalizers: { @@ -39,15 +44,67 @@ export class DevAppRouteRouteMatcherProvider extends FileCacheRouteMatcherProvid const pathname = this.normalizers.pathname.normalize(filename) const bundlePath = this.normalizers.bundlePath.normalize(filename) - matchers.push( - new AppRouteRouteMatcher({ - kind: RouteKind.APP_ROUTE, - pathname, - page, - bundlePath, - filename, - }) - ) + if (isMetadataRoute(page) && !isStaticMetadataRoute(page)) { + // Matching dynamic metadata routes. + // Add 2 possibilities for both single and multiple routes: + { + // single: + // /sitemap.ts -> /sitemap.xml/route + // /icon.ts -> /icon/route + // We'll map the filename before normalization: + // sitemap.ts -> sitemap.xml/route.ts + // icon.ts -> icon/route.ts + const metadataPage = normalizeMetadataPageToRoute(page, false) // this.normalizers.page.normalize(dummyFilename) + const metadataPathname = normalizeMetadataPageToRoute(pathname, false) // this.normalizers.pathname.normalize(dummyFilename) + const metadataBundlePath = normalizeMetadataPageToRoute( + bundlePath, + false + ) // this.normalizers.bundlePath.normalize(dummyFilename) + + const matcher = new AppRouteRouteMatcher({ + kind: RouteKind.APP_ROUTE, + page: metadataPage, + pathname: metadataPathname, + bundlePath: metadataBundlePath, + filename, + }) + matchers.push(matcher) + } + { + // multiple: + // /sitemap.ts -> /sitemap/[__metadata_id__]/route + // /icon.ts -> /icon/[__metadata_id__]/route + // We'll map the filename before normalization: + // sitemap.ts -> sitemap.xml/[__metadata_id__].ts + // icon.ts -> icon/[__metadata_id__].ts + const metadataPage = normalizeMetadataPageToRoute(page, true) + const metadataPathname = normalizeMetadataPageToRoute(pathname, true) + const metadataBundlePath = normalizeMetadataPageToRoute( + bundlePath, + true + ) + + const matcher = new AppRouteRouteMatcher({ + kind: RouteKind.APP_ROUTE, + page: metadataPage, + pathname: metadataPathname, + bundlePath: metadataBundlePath, + filename, + }) + matchers.push(matcher) + } + } else { + // Normal app routes and static metadata routes. + matchers.push( + new AppRouteRouteMatcher({ + kind: RouteKind.APP_ROUTE, + page, + pathname, + bundlePath, + filename, + }) + ) + } } return matchers diff --git a/test/development/acceptance-app/dynamic-metadata-error.test.ts b/test/development/acceptance-app/dynamic-metadata-error.test.ts index 4c478d31d442b..abbaad9051dba 100644 --- a/test/development/acceptance-app/dynamic-metadata-error.test.ts +++ b/test/development/acceptance-app/dynamic-metadata-error.test.ts @@ -71,7 +71,7 @@ describe('dynamic metadata error', () => { const { cleanup } = await sandbox( next, new Map([[sitemapFilePath, contentMissingIdProperty]]), - '/metadata-base/unset/sitemap/100' + '/metadata-base/unset/sitemap/100.xml' ) await retry(async () => { diff --git a/test/e2e/app-dir/dynamic-in-generate-params/index.test.ts b/test/e2e/app-dir/dynamic-in-generate-params/index.test.ts index d43ffdf9fad4b..14f2d55395da1 100644 --- a/test/e2e/app-dir/dynamic-in-generate-params/index.test.ts +++ b/test/e2e/app-dir/dynamic-in-generate-params/index.test.ts @@ -18,15 +18,15 @@ describe('app-dir - dynamic in generate params', () => { }) it('should render sitemap with generateSitemaps in force-dynamic config dynamically', async () => { - const firstTime = await getLastModifiedTime(next, 'sitemap/0') - const secondTime = await getLastModifiedTime(next, 'sitemap/0') + const firstTime = await getLastModifiedTime(next, 'sitemap/0.xml') + const secondTime = await getLastModifiedTime(next, 'sitemap/0.xml') expect(firstTime).not.toEqual(secondTime) }) it('should be able to call while generating multiple dynamic sitemaps', async () => { - const res0 = await next.fetch('sitemap/0') - const res1 = await next.fetch('sitemap/1') + const res0 = await next.fetch('sitemap/0.xml') + const res1 = await next.fetch('sitemap/1.xml') assertSitemapResponse(res0) assertSitemapResponse(res1) }) diff --git a/test/e2e/app-dir/logging/fetch-logging.test.ts b/test/e2e/app-dir/logging/fetch-logging.test.ts index 05076470055f8..04df20d2699dd 100644 --- a/test/e2e/app-dir/logging/fetch-logging.test.ts +++ b/test/e2e/app-dir/logging/fetch-logging.test.ts @@ -225,7 +225,7 @@ describe('app-dir - logging', () => { const output = stripAnsi(next.cliOutput.slice(logLength)) expect(output).toContain('/dynamic/[slug]/icon') expect(output).not.toContain('/(group)') - expect(output).not.toContain('[[...__metadata_id__]]') + expect(output).not.toContain('[__metadata_id__]') expect(output).not.toContain('/route') }) }) diff --git a/test/e2e/app-dir/metadata-dynamic-routes/app/gsp/icon.tsx b/test/e2e/app-dir/metadata-dynamic-routes/app/gsp/icon.tsx new file mode 100644 index 0000000000000..11c40f86bc1f0 --- /dev/null +++ b/test/e2e/app-dir/metadata-dynamic-routes/app/gsp/icon.tsx @@ -0,0 +1,37 @@ +import { ImageResponse } from 'next/og' + +export async function generateImageMetadata({ params }) { + return [ + { + contentType: 'image/png', + size: { width: 48, height: 48 }, + id: 'small', + }, + { + contentType: 'image/png', + size: { width: 72, height: 72 }, + id: 'medium', + }, + ] +} + +export default function icon({ params, id }) { + return new ImageResponse( + ( +
+ Icon {params.size} {id} +
+ ) + ) +} diff --git a/test/e2e/app-dir/metadata-dynamic-routes/index.test.ts b/test/e2e/app-dir/metadata-dynamic-routes/index.test.ts index 9e66abed21d09..2dca3ba618dbc 100644 --- a/test/e2e/app-dir/metadata-dynamic-routes/index.test.ts +++ b/test/e2e/app-dir/metadata-dynamic-routes/index.test.ts @@ -44,7 +44,7 @@ describe('app dir - metadata dynamic routes', () => { describe('sitemap', () => { it('should handle sitemap.[ext] dynamic routes', async () => { - const res = await next.fetch('/sitemap') + const res = await next.fetch('/sitemap.xml') const text = await res.text() expect(res.headers.get('content-type')).toBe('application/xml') @@ -70,23 +70,30 @@ describe('app dir - metadata dynamic routes', () => { it('should support generate multi sitemaps with generateSitemaps', async () => { const ids = ['child0', 'child1', 'child2', 'child3'] - function fetchSitemap(id) { - return next.fetch(`/gsp/sitemap/${id}`).then((res) => res.text()) + function fetchSitemap(id, withExtension) { + return next.fetch(`/gsp/sitemap/${id}${withExtension ? `.xml` : ''}`) } + // Required to have .xml extension for dynamic sitemap for (const id of ids) { - const text = await fetchSitemap(id) + const text = await fetchSitemap(id, true).then((res) => res.text()) expect(text).toContain(`https://example.com/dynamic/${id}`) } + + // Should 404 when missing .xml extension + for (const id of ids) { + const { status } = await fetchSitemap(id, false) + expect(status).toBe(404) + } }) it('should not throw if client components are imported but not used in sitemap', async () => { - const { status } = await next.fetch('/client-ref-dependency/sitemap') + const { status } = await next.fetch('/client-ref-dependency/sitemap.xml') expect(status).toBe(200) }) it('should support alternate.languages in sitemap', async () => { - const xml = await (await next.fetch('/lang/sitemap')).text() + const xml = await (await next.fetch('/lang/sitemap.xml')).text() expect(xml).toContain('xmlns:xhtml="http://www.w3.org/1999/xhtml') expect(xml).toContain( @@ -105,19 +112,19 @@ describe('app dir - metadata dynamic routes', () => { expect(appPathsManifest).toMatchObject({ // static routes '/twitter-image/route': 'app/twitter-image/route.js', - '/sitemap/route': 'app/sitemap/route.js', + '/sitemap.xml/route': 'app/sitemap.xml/route.js', // dynamic '/gsp/sitemap/[__metadata_id__]/route': 'app/gsp/sitemap/[__metadata_id__]/route.js', - '/(group)/dynamic/[size]/apple-icon-ahg52g/[[...__metadata_id__]]/route': - 'app/(group)/dynamic/[size]/apple-icon-ahg52g/[[...__metadata_id__]]/route.js', + '/(group)/dynamic/[size]/apple-icon-ahg52g/[__metadata_id__]/route': + 'app/(group)/dynamic/[size]/apple-icon-ahg52g/[__metadata_id__]/route.js', }) }) it('should generate static paths of dynamic sitemap in production', async () => { const sitemapPaths = ['child0', 'child1', 'child2', 'child3'].map( - (id) => `.next/server/app/gsp/sitemap/${id}.meta` + (id) => `.next/server/app/gsp/sitemap/${id}.xml.meta` ) const promises = sitemapPaths.map(async (filePath) => { expect(await next.hasFile(filePath)).toBe(true) @@ -183,9 +190,7 @@ describe('app dir - metadata dynamic routes', () => { const entryKeys = Object.keys(appPathsManifest) // Only has one route for twitter-image with catch-all routes in dev expect(entryKeys).not.toContain('/twitter-image') - expect(entryKeys).toContain( - '/twitter-image/[[...__metadata_id__]]/route' - ) + expect(entryKeys).toContain('/twitter-image/route') } // edge runtime @@ -316,7 +321,7 @@ describe('app dir - metadata dynamic routes', () => { if (isNextStart) { describe('route segment config', () => { it('should generate dynamic route if dynamic config is force-dynamic', async () => { - const dynamicRoute = '/route-config/sitemap' + const dynamicRoute = '/route-config/sitemap.xml' expect( await next.hasFile(`.next/server/app${dynamicRoute}/route.js`) @@ -453,7 +458,7 @@ describe('app dir - metadata dynamic routes', () => { it('should include default og font files in file trace', async () => { const fileTrace = JSON.parse( await next.readFile( - '.next/server/app/metadata-base/unset/opengraph-image2/[[...__metadata_id__]]/route.js.nft.json' + '.next/server/app/metadata-base/unset/opengraph-image2/[__metadata_id__]/route.js.nft.json' ) ) @@ -463,5 +468,15 @@ describe('app dir - metadata dynamic routes', () => { ) expect(isTraced).toBe(true) }) + + it('should statically optimized single image route', async () => { + const prerenderManifest = JSON.parse( + await next.readFile('.next/prerender-manifest.json') + ) + const dynamicRoutes = Object.keys(prerenderManifest.routes) + expect(dynamicRoutes).toContain('/opengraph-image') + expect(dynamicRoutes).toContain('/opengraph-image-1ow20b') + expect(dynamicRoutes).toContain('/apple-icon') + }) } }) diff --git a/test/e2e/app-dir/metadata/metadata.test.ts b/test/e2e/app-dir/metadata/metadata.test.ts index f03f72937d385..8b63a5f15da04 100644 --- a/test/e2e/app-dir/metadata/metadata.test.ts +++ b/test/e2e/app-dir/metadata/metadata.test.ts @@ -958,7 +958,7 @@ describe('app dir - metadata', () => { ).toBe(true) expect( await next.hasFile( - '.next/server/app/opengraph/static/opengraph-image.png/[[...__metadata_id__]]/route.js' + '.next/server/app/opengraph/static/opengraph-image.png/[__metadata_id__]/route.js' ) ).toBe(false) }) diff --git a/test/production/app-dir/metadata-static/metadata-static.test.ts b/test/production/app-dir/metadata-static/metadata-static.test.ts index bd1cf476f2aa7..104160a21ce9d 100644 --- a/test/production/app-dir/metadata-static/metadata-static.test.ts +++ b/test/production/app-dir/metadata-static/metadata-static.test.ts @@ -12,7 +12,7 @@ describe('app dir - metadata', () => { for (const key of [ '/robots.txt', - '/sitemap', + '/sitemap.xml', '/opengraph-image', '/manifest.webmanifest', ]) { diff --git a/test/turbopack-build-tests-manifest.json b/test/turbopack-build-tests-manifest.json index a104fee5b7388..a004ecf5807c3 100644 --- a/test/turbopack-build-tests-manifest.json +++ b/test/turbopack-build-tests-manifest.json @@ -1924,7 +1924,8 @@ "app dir - metadata dynamic routes social image routes should render og image with opengraph-image dynamic routes", "app dir - metadata dynamic routes social image routes should render og image with twitter-image dynamic routes", "app dir - metadata dynamic routes social image routes should support generate multi images with generateImageMetadata", - "app dir - metadata dynamic routes social image routes should support params as argument in dynamic routes" + "app dir - metadata dynamic routes social image routes should support params as argument in dynamic routes", + "app dir - metadata dynamic routes should statically optimized single image route" ], "pending": [], "flakey": [], From 6c1d700afc812352c56690defad0056f185b127f Mon Sep 17 00:00:00 2001 From: hrmny <8845940+ForsakenHarmony@users.noreply.github.com> Date: Mon, 10 Jun 2024 17:39:40 +0200 Subject: [PATCH 06/60] feat(turbopack-ecmascript): cache external modules with wrapper (#63337) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### What? This is a fix for a bundle potentially referring to two different external modules (e.g. `react` because it gets invalided from the require cache) See https://github.com/vercel/turbo/pull/7988 ### Turbopack Updates * https://github.com/vercel/turbo/pull/8376 * https://github.com/vercel/turbo/pull/8371 * https://github.com/vercel/turbo/pull/8370 * https://github.com/vercel/turbo/pull/7988 Closes PACK-2622 --- Cargo.lock | 100 +++++++----------- Cargo.toml | 6 +- packages/next/package.json | 2 +- .../internal/helpers/parseStack.ts | 16 +++ pnpm-lock.yaml | 8 +- .../middleware-errors/index.test.ts | 8 +- ...-good-stack-traces-in-edge-runtime.test.ts | 18 +--- .../test/externals.test.js | 2 +- .../externals-pages-bundle/test/index.test.js | 8 +- test/turbopack-build-tests-manifest.json | 5 +- test/turbopack-dev-tests-manifest.json | 5 +- 11 files changed, 84 insertions(+), 94 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 982b635219835..593060f5cc206 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -321,7 +321,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "serde", "smallvec", @@ -1138,7 +1138,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.10.1", + "phf 0.11.2", "serde", "smallvec", ] @@ -3092,7 +3092,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "serde", @@ -3568,9 +3568,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" dependencies = [ - "phf_macros 0.10.0", "phf_shared 0.10.0", - "proc-macro-hack", ] [[package]] @@ -3579,7 +3577,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_macros 0.11.2", + "phf_macros", "phf_shared 0.11.2", ] @@ -3613,20 +3611,6 @@ dependencies = [ "rand", ] -[[package]] -name = "phf_macros" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" -dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "phf_macros" version = "0.11.2" @@ -3821,12 +3805,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - [[package]] name = "proc-macro2" version = "1.0.79" @@ -6969,12 +6947,12 @@ dependencies = [ [[package]] name = "turbo-prehash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "async-trait", @@ -7006,7 +6984,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "cargo-lock", @@ -7018,7 +6996,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "bytes", @@ -7032,7 +7010,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "dotenvs", @@ -7046,7 +7024,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "lazy_static", @@ -7062,7 +7040,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "auto-hash-map", @@ -7094,7 +7072,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "md4", "turbo-tasks-macros", @@ -7104,7 +7082,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "proc-macro-error", @@ -7118,7 +7096,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "proc-macro2", "quote", @@ -7128,7 +7106,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "mimalloc", ] @@ -7136,7 +7114,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "auto-hash-map", @@ -7163,7 +7141,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "async-recursion", @@ -7193,7 +7171,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "auto-hash-map", "mdxjs", @@ -7234,7 +7212,7 @@ dependencies = [ [[package]] name = "turbopack-browser" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7257,7 +7235,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "clap", @@ -7274,7 +7252,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "async-recursion", @@ -7303,7 +7281,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7330,7 +7308,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "async-compression", @@ -7366,7 +7344,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "async-trait", @@ -7401,7 +7379,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "serde", "serde_json", @@ -7412,7 +7390,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "async-trait", @@ -7437,7 +7415,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "indoc", @@ -7453,7 +7431,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7469,7 +7447,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "base64 0.21.4", @@ -7488,7 +7466,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "serde", @@ -7503,7 +7481,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "mdxjs", @@ -7518,7 +7496,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "async-stream", @@ -7552,7 +7530,7 @@ dependencies = [ [[package]] name = "turbopack-nodejs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7572,7 +7550,7 @@ dependencies = [ [[package]] name = "turbopack-resolve" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7590,7 +7568,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "serde", @@ -7606,7 +7584,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "swc_core", "turbo-tasks", @@ -7617,7 +7595,7 @@ dependencies = [ [[package]] name = "turbopack-trace-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "either", @@ -7637,7 +7615,7 @@ dependencies = [ [[package]] name = "turbopack-trace-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "crossbeam-channel", @@ -7653,7 +7631,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240607.3#c2fb13e3101ae2a6331453a3e925d832e52ced91" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index 48b55d8bee122..16ffbc9d43e30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,11 +37,11 @@ swc_core = { version = "0.92.5", features = [ testing = { version = "0.35.25" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240607.3" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240610.2" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240607.3" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240610.2" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240607.3" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240610.2" } # General Deps diff --git a/packages/next/package.json b/packages/next/package.json index 0293509e348d2..c0f8f273e554b 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -206,7 +206,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.27.1", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240607.3", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240610.2", "acorn": "8.11.3", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/parseStack.ts b/packages/next/src/client/components/react-dev-overlay/internal/helpers/parseStack.ts index 693b53d7bdcdf..a7af46b00c933 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/parseStack.ts +++ b/packages/next/src/client/components/react-dev-overlay/internal/helpers/parseStack.ts @@ -16,6 +16,22 @@ export function parseStack(stack: string): StackFrame[] { } } + // throw away eval information that stacktrace-parser doesn't support + // adapted from https://github.com/stacktracejs/error-stack-parser/blob/9f33c224b5d7b607755eb277f9d51fcdb7287e24/error-stack-parser.js#L59C33-L59C62 + stack = stack + .split('\n') + .map((line) => { + if (line.includes('(eval ')) { + line = line + .replace(/eval code/g, 'eval') + .replace(/\(eval at [^()]* \(/, '(file://') + .replace(/\),.*$/g, ')') + } + + return line + }) + .join('\n') + const frames = parse(stack) return frames.map((frame) => { try { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f9a16e1f0b72b..e9a9b538751d0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1090,8 +1090,8 @@ importers: specifier: 0.27.1 version: 0.27.1 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240607.3 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240607.3' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240610.2 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240610.2' acorn: specifier: 8.11.3 version: 8.11.3 @@ -25890,8 +25890,8 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240607.3': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240607.3} + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240610.2': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240610.2} name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: diff --git a/test/development/middleware-errors/index.test.ts b/test/development/middleware-errors/index.test.ts index feb4c824f2bc5..ae37479743dd6 100644 --- a/test/development/middleware-errors/index.test.ts +++ b/test/development/middleware-errors/index.test.ts @@ -107,7 +107,7 @@ describe('middleware - development errors', () => { it('logs the error correctly', async () => { await next.fetch('/') - const output = stripAnsi(next.cliOutput) + // const output = stripAnsi(next.cliOutput) await check(() => { expect(stripAnsi(next.cliOutput)).toMatch( /middleware.js \(\d+:\d+\) @ eval/ @@ -115,9 +115,9 @@ describe('middleware - development errors', () => { expect(stripAnsi(next.cliOutput)).toMatch(/test is not defined/) return 'success' }, 'success') - expect(output).not.toContain( - 'webpack-internal:///(middleware)/./middleware.js' - ) + // expect(output).not.toContain( + // 'webpack-internal:///(middleware)/./middleware.js' + // ) }) it('renders the error correctly and recovers', async () => { diff --git a/test/e2e/fetch-failures-have-good-stack-traces-in-edge-runtime/fetch-failures-have-good-stack-traces-in-edge-runtime.test.ts b/test/e2e/fetch-failures-have-good-stack-traces-in-edge-runtime/fetch-failures-have-good-stack-traces-in-edge-runtime.test.ts index b37af4f53343d..22aa7dad2cb82 100644 --- a/test/e2e/fetch-failures-have-good-stack-traces-in-edge-runtime/fetch-failures-have-good-stack-traces-in-edge-runtime.test.ts +++ b/test/e2e/fetch-failures-have-good-stack-traces-in-edge-runtime/fetch-failures-have-good-stack-traces-in-edge-runtime.test.ts @@ -41,18 +41,10 @@ describe('fetch failures have good stack traces in edge runtime', () => { it('when returning `fetch` using an unknown domain, stack traces are preserved', async () => { await webdriver(next.url, '/api/unknown-domain-no-await') - if (process.env.TURBOPACK) { - // pages_api_unknown-domain-no-await_d8c7f5.js:14:5 - await check( - () => stripAnsi(next.cliOutput), - /pages_api_unknown-domain-no-await_.*?\.js/ - ) - } else { - // webpack-internal:///(middleware)/./pages/api/unknown-domain-no-await.js:10:5 - await check( - () => stripAnsi(next.cliOutput), - /at.+\/pages\/api\/unknown-domain-no-await.js/ - ) - } + // TODO: turbopack needs to have its source maps picked up by node.js + await check( + () => stripAnsi(next.cliOutput), + /at.+\/pages\/api\/unknown-domain-no-await.js/ + ) }) }) diff --git a/test/integration/externals-pages-bundle/test/externals.test.js b/test/integration/externals-pages-bundle/test/externals.test.js index 2b698534e4166..0fc7b89cd865e 100644 --- a/test/integration/externals-pages-bundle/test/externals.test.js +++ b/test/integration/externals-pages-bundle/test/externals.test.js @@ -32,7 +32,7 @@ describe('default', () => { allBundles += output } expect(allBundles).toContain( - '__turbopack_external_require__("external-package", true)' + '__turbopack_external_require__("external-package")' ) } else { const output = await fs.readFile( diff --git a/test/integration/externals-pages-bundle/test/index.test.js b/test/integration/externals-pages-bundle/test/index.test.js index cd0ee2f1c4eec..b7f1e75e9ddac 100644 --- a/test/integration/externals-pages-bundle/test/index.test.js +++ b/test/integration/externals-pages-bundle/test/index.test.js @@ -28,7 +28,9 @@ describe('bundle pages externals with config.bundlePagesRouterDependencies', () } // we don't know the name of the minified `__turbopack_external_require__`, so we just check the arguments. - expect(allBundles).not.toContain('("external-package",!0)') + expect(allBundles).not.toContain( + '"[externals]/ [external] (external-package, cjs)"' + ) } else { const output = await fs.readFile( join(appDir, '.next/server/pages/index.js'), @@ -52,7 +54,9 @@ describe('bundle pages externals with config.bundlePagesRouterDependencies', () } // we don't know the name of the minified `__turbopack_external_require__`, so we just check the arguments. - expect(allBundles).toContain('("opted-out-external-package",!0)') + expect(allBundles).toContain( + '"[externals]/ [external] (opted-out-external-package, cjs)"' + ) } else { const output = await fs.readFile( join(appDir, '.next/server/pages/index.js'), diff --git a/test/turbopack-build-tests-manifest.json b/test/turbopack-build-tests-manifest.json index a004ecf5807c3..edc3c0dac2500 100644 --- a/test/turbopack-build-tests-manifest.json +++ b/test/turbopack-build-tests-manifest.json @@ -4041,10 +4041,9 @@ "runtimeError": false }, "test/e2e/fetch-failures-have-good-stack-traces-in-edge-runtime/fetch-failures-have-good-stack-traces-in-edge-runtime.test.ts": { - "passed": [ - "fetch failures have good stack traces in edge runtime when returning `fetch` using an unknown domain, stack traces are preserved" - ], + "passed": [], "failed": [ + "fetch failures have good stack traces in edge runtime when returning `fetch` using an unknown domain, stack traces are preserved", "fetch failures have good stack traces in edge runtime when awaiting `fetch` using an unknown domain, stack traces are preserved" ], "pending": [], diff --git a/test/turbopack-dev-tests-manifest.json b/test/turbopack-dev-tests-manifest.json index 76abe5752caa4..c358e0141a355 100644 --- a/test/turbopack-dev-tests-manifest.json +++ b/test/turbopack-dev-tests-manifest.json @@ -6134,10 +6134,11 @@ }, "test/e2e/fetch-failures-have-good-stack-traces-in-edge-runtime/fetch-failures-have-good-stack-traces-in-edge-runtime.test.ts": { "passed": [ - "fetch failures have good stack traces in edge runtime when awaiting `fetch` using an unknown domain, stack traces are preserved", + "fetch failures have good stack traces in edge runtime when awaiting `fetch` using an unknown domain, stack traces are preserved" + ], + "failed": [ "fetch failures have good stack traces in edge runtime when returning `fetch` using an unknown domain, stack traces are preserved" ], - "failed": [], "pending": [], "flakey": [], "runtimeError": false From 5be04cf8fdf22e4c874386b19c51b8e1b42da6b1 Mon Sep 17 00:00:00 2001 From: Karl Keefer Date: Mon, 10 Jun 2024 16:48:54 +0100 Subject: [PATCH 07/60] Incremental Static Regeneration - docs update explaining surprising behavior (#66151) The _requirement_ to export a `generateStaticParams` to get static cache behavior _after_ build time was _really_ surprising behavior for me, and I think others: * https://github.com/vercel/next.js/issues/62195#issuecomment-1952091312 * https://github.com/vercel/next.js/discussions/57961#discussioncomment-8491488 Potentially this is a bug, and not something that should be fixed with documentation? I don't understand next.js caching enough to make that determination, so instead I'm proposing these changes to docs which might be encountered by folks who are surprised by this cache behavior. One point in favor of this being a bug: The CLI reports that a route is `SSG` enabled in the build output, but doesn't actually cache post-build page renders if this export is missing. @awinogrodzki made a demo repo showing this behavior, as described [here](https://github.com/vercel/next.js/discussions/57961#discussioncomment-7468144). --------- Co-authored-by: Delba de Oliveira Co-authored-by: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com> Co-authored-by: samcx --- .../04-caching/index.mdx | 37 +++++++- .../route-segment-config.mdx | 1 + .../04-functions/generate-static-params.mdx | 86 ++++++++++++++----- 3 files changed, 102 insertions(+), 22 deletions(-) diff --git a/docs/02-app/01-building-your-application/04-caching/index.mdx b/docs/02-app/01-building-your-application/04-caching/index.mdx index 625097480c24b..8e482a7918f4a 100644 --- a/docs/02-app/01-building-your-application/04-caching/index.mdx +++ b/docs/02-app/01-building-your-application/04-caching/index.mdx @@ -536,9 +536,42 @@ See the [Route Segment Config](/docs/app/api-reference/file-conventions/route-se For [dynamic segments](/docs/app/building-your-application/routing/dynamic-routes) (e.g. `app/blog/[slug]/page.js`), paths provided by `generateStaticParams` are cached in the Full Route Cache at build time. At request time, Next.js will also cache paths that weren't known at build time the first time they're visited. -You can disable caching at request time by using `export const dynamicParams = false` option in a route segment. When this config option is used, only paths provided by `generateStaticParams` will be served, and other routes will 404 or match (in the case of [catch-all routes](/docs/app/building-your-application/routing/dynamic-routes#catch-all-segments)). +To statically render all paths at build time, supply the full list of paths to `generateStaticParams`: -See the [`generateStaticParams` API reference](/docs/app/api-reference/functions/generate-static-params). +```tsx filename="app/blog/[slug]/page.tsx" switcher +export async function generateStaticParams() { + const posts = await fetch('https://.../posts').then((res) => res.json()) + + return posts.map((post) => ({ + slug: post.slug, + })) +} +``` + +To statically render a subset of paths at build time, and the rest the first time they're visited at runtime, return a partial list of paths: + +```tsx filename="app/blog/[slug]/page.tsx" switcher +export async function generateStaticParams() { + const posts = await fetch('https://.../posts').then((res) => res.json()) + + // Render the first 10 posts at build time + return posts.slice(0, 10).map((post) => ({ + slug: post.slug, + })) +} +``` + +To statically render all paths the first time they're visited, return an empty array (no paths will be rendered at build time): + +```tsx filename="app/blog/[slug]/page.tsx" switcher +export async function generateStaticParams() { + return [] +} +``` + +> **Good to know:** You must always return an array from `generateStaticParams`, even if it's empty. Otherwise, the route will be dynamically rendered. + +To disable caching at request time, add the `export const dynamicParams = false` option in a route segment. When this config option is used, only paths provided by `generateStaticParams` will be served, and other routes will 404 or match (in the case of [catch-all routes](/docs/app/building-your-application/routing/dynamic-routes#catch-all-segments)). ### React `cache` function diff --git a/docs/02-app/02-api-reference/02-file-conventions/route-segment-config.mdx b/docs/02-app/02-api-reference/02-file-conventions/route-segment-config.mdx index 0c00300a97663..95c0b34be0f12 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/route-segment-config.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/route-segment-config.mdx @@ -84,6 +84,7 @@ export const dynamicParams = true // true | false, > **Good to know**: > > - This option replaces the `fallback: true | false | blocking` option of `getStaticPaths` in the `pages` directory. +> - To statically render all paths the first time they're visited, you'll need to return an empty array in `generateStaticParams`. > - When `dynamicParams = true`, the segment uses [Streaming Server Rendering](/docs/app/building-your-application/routing/loading-ui-and-streaming#streaming-with-suspense). > - If the `dynamic = 'error'` and `dynamic = 'force-static'` are used, it'll change the default of `dynamicParams` to `false`. diff --git a/docs/02-app/02-api-reference/04-functions/generate-static-params.mdx b/docs/02-app/02-api-reference/04-functions/generate-static-params.mdx index 34aa34733df33..ea0eb37964c11 100644 --- a/docs/02-app/02-api-reference/04-functions/generate-static-params.mdx +++ b/docs/02-app/02-api-reference/04-functions/generate-static-params.mdx @@ -26,6 +26,7 @@ export default function Page({ params }) { > **Good to know** > > - You can use the [`dynamicParams`](/docs/app/api-reference/file-conventions/route-segment-config#dynamicparams) segment config option to control what happens when a dynamic segment is visited that was not generated with `generateStaticParams`. +> - You must always return [an array from `generateStaticParams`](#all-paths-at-build-time), even if it's empty. > - During `next dev`, `generateStaticParams` will be called when you navigate to a route. > - During `next build`, `generateStaticParams` runs before the corresponding Layouts or Pages are generated. > - During revalidation (ISR), `generateStaticParams` will not be called again. @@ -168,6 +169,69 @@ export default function Page({ params }) { ## Examples +### Static Rendering + +#### All paths at build time + +To statically render all paths at build time, supply the full list of paths to `generateStaticParams`: + +```tsx filename="app/blog/[slug]/page.tsx" switcher +export async function generateStaticParams() { + const posts = await fetch('https://.../posts').then((res) => res.json()) + + return posts.map((post) => ({ + slug: post.slug, + })) +} +``` + +#### Subset of paths at build time + +To statically render a subset of paths at build time, and the rest the first time they're visited at runtime, return a partial list of paths: + +```tsx filename="app/blog/[slug]/page.tsx" switcher +export async function generateStaticParams() { + const posts = await fetch('https://.../posts').then((res) => res.json()) + + // Render the first 10 posts at build time + return posts.slice(0, 10).map((post) => ({ + slug: post.slug, + })) +} +``` + +Then, by using the [`dynamicParams`](/docs/app/api-reference/file-conventions/route-segment-config#dynamicparams) segment config option, you can control what happens when a dynamic segment is visited that was not generated with `generateStaticParams`. + +```jsx filename="app/blog/[slug]/page.js" +// All posts besides the top 10 will be a 404 +export const dynamicParams = false + +export async function generateStaticParams() { + const posts = await fetch('https://.../posts').then((res) => res.json()) + const topPosts = posts.slice(0, 10) + + return topPosts.map((post) => ({ + slug: post.slug, + })) +} +``` + +#### All paths at runtime + +To statically render all paths the first time they're visited, return an empty array (no paths will be rendered at build time): + +```tsx filename="app/blog/[slug]/page.tsx" switcher +export async function generateStaticParams() { + return [] +} +``` + +> **Good to know:** You must always return an array from `generateStaticParams`, even if it's empty. Otherwise, the route will be dynamically rendered. + +### Disable rendering for unspecified paths + +To prevent unspecified paths from being statically rendered at runtime, add the `export const dynamicParams = false` option in a route segment. When this config option is used, only paths provided by `generateStaticParams` will be served, and unspecified routes will 404 or match (in the case of [catch-all routes](/docs/app/building-your-application/routing/dynamic-routes#catch-all-segments)). + ### Multiple Dynamic Segments in a Route You can generate params for dynamic segments above the current layout or page, but **not below**. For example, given the `app/products/[category]/[product]` route: @@ -177,7 +241,7 @@ You can generate params for dynamic segments above the current layout or page, b There are two approaches to generating params for a route with multiple dynamic segments: -### Generate params from the bottom up +#### Generate params from the bottom up Generate multiple dynamic segments from the child route segment. @@ -217,7 +281,7 @@ export default function Page({ params }) { } ``` -### Generate params from the top down +#### Generate params from the top down Generate the parent segments first and use the result to generate the child segments. @@ -301,24 +365,6 @@ export default function Page({ params }) { > **Good to know**: `fetch` requests are automatically [memoized](/docs/app/building-your-application/caching#request-memoization) for the same data across all `generate`-prefixed functions, Layouts, Pages, and Server Components. React [`cache` can be used](/docs/app/building-your-application/caching#react-cache-function) if `fetch` is unavailable. -### Generate only a subset of params - -You can generate a subset of params for a route by returning an array of objects with only the dynamic segments you want to generate. Then, by using the [`dynamicParams`](/docs/app/api-reference/file-conventions/route-segment-config#dynamicparams) segment config option, you can control what happens when a dynamic segment is visited that was not generated with `generateStaticParams`. - -```jsx filename="app/blog/[slug]/page.js" -// All posts besides the top 10 will be a 404 -export const dynamicParams = false - -export async function generateStaticParams() { - const posts = await fetch('https://.../posts').then((res) => res.json()) - const topPosts = posts.slice(0, 10) - - return topPosts.map((post) => ({ - slug: post.slug, - })) -} -``` - ## Version History | Version | Changes | From e7694b3f3d5b4c8e8e4c48fc0dd2963d27ccdb63 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Mon, 10 Jun 2024 09:42:32 -0700 Subject: [PATCH 08/60] [ppr] Enable static shell debugging in other environments (#65483) To assist with the development and testing of the new partial prerendering (PPR) paradigm, this introduces a stop-gap solution to let us verify issues with pages in preview and production environments if enabled. When a Next.js app is built and ran with the `__NEXT_EXPERIMENTAL_STATIC_SHELL_DEBUGGING=1` environment variable, pages that have PPR enabled in production and preview environments can have only their static shell served when accessed with a `?__nextppronly=1` query parameter. If your project is not using PPR, it will not change anything. If a page is accessed in production or development with the query parameter but PPR is not enabled, it will not change anything. Tests have been added to validate that going forward. --- .../next/src/server/app-render/app-render.tsx | 2 +- .../server/app-render/dynamic-rendering.ts | 10 ++- packages/next/src/server/app-render/types.ts | 13 ++- ...static-generation-async-storage-wrapper.ts | 4 +- packages/next/src/server/base-server.ts | 85 +++++++++++++------ test/e2e/app-dir/app/index.test.ts | 50 ++++------- .../static-shell-debugging/app/layout.jsx | 7 ++ .../static-shell-debugging/app/page.jsx | 17 ++++ .../static-shell-debugging.test.ts | 40 +++++++++ 9 files changed, 160 insertions(+), 68 deletions(-) create mode 100644 test/e2e/app-dir/static-shell-debugging/app/layout.jsx create mode 100644 test/e2e/app-dir/static-shell-debugging/app/page.jsx create mode 100644 test/e2e/app-dir/static-shell-debugging/static-shell-debugging.test.ts diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx index 1e56d4e2497c4..f8b94d47fb9c4 100644 --- a/packages/next/src/server/app-render/app-render.tsx +++ b/packages/next/src/server/app-render/app-render.tsx @@ -1433,7 +1433,7 @@ async function renderToHTMLOrFlightImpl( if ( staticGenerationStore.prerenderState && usedDynamicAPIs(staticGenerationStore.prerenderState) && - staticGenerationStore.prerenderState?.isDebugSkeleton + staticGenerationStore.prerenderState?.isDebugDynamicAccesses ) { warn('The following dynamic usage was detected:') for (const access of formatDynamicAPIAccesses( diff --git a/packages/next/src/server/app-render/dynamic-rendering.ts b/packages/next/src/server/app-render/dynamic-rendering.ts index f661334ab0890..24b0fb2473edc 100644 --- a/packages/next/src/server/app-render/dynamic-rendering.ts +++ b/packages/next/src/server/app-render/dynamic-rendering.ts @@ -49,7 +49,7 @@ export type PrerenderState = { /** * When true, stack information will also be tracked during dynamic access. */ - readonly isDebugSkeleton: boolean | undefined + readonly isDebugDynamicAccesses: boolean | undefined /** * The dynamic accesses that occurred during the render. @@ -58,10 +58,10 @@ export type PrerenderState = { } export function createPrerenderState( - isDebugSkeleton: boolean | undefined + isDebugDynamicAccesses: boolean | undefined ): PrerenderState { return { - isDebugSkeleton, + isDebugDynamicAccesses, dynamicAccesses: [], } } @@ -194,7 +194,9 @@ function postponeWithTracking( prerenderState.dynamicAccesses.push({ // When we aren't debugging, we don't need to create another error for the // stack trace. - stack: prerenderState.isDebugSkeleton ? new Error().stack : undefined, + stack: prerenderState.isDebugDynamicAccesses + ? new Error().stack + : undefined, expression, }) diff --git a/packages/next/src/server/app-render/types.ts b/packages/next/src/server/app-render/types.ts index 4f073cb4fa415..47ea6ff38ccf7 100644 --- a/packages/next/src/server/app-render/types.ts +++ b/packages/next/src/server/app-render/types.ts @@ -172,10 +172,17 @@ export interface RenderOptsPartial { } postponed?: string /** - * When true, only the skeleton of the PPR page will be rendered. This will - * also enable other debugging features such as logging. + * When true, only the static shell of the page will be rendered. This will + * also enable other debugging features such as logging in development. */ - isDebugPPRSkeleton?: boolean + isDebugStaticShell?: boolean + + /** + * When true, the page will be rendered using the static rendering to detect + * any dynamic API's that would have stopped the page from being fully + * statically generated. + */ + isDebugDynamicAccesses?: boolean isStaticGeneration?: boolean } diff --git a/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts b/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts index e7b71e377d54c..956cf140437f2 100644 --- a/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts +++ b/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts @@ -45,7 +45,7 @@ export type StaticGenerationContext = { | 'isRevalidate' | 'nextExport' | 'isDraftMode' - | 'isDebugPPRSkeleton' + | 'isDebugDynamicAccesses' > & Partial } @@ -83,7 +83,7 @@ export const StaticGenerationAsyncStorageWrapper: AsyncStorageWrapper< const prerenderState: StaticGenerationStore['prerenderState'] = isStaticGeneration && renderOpts.experimental?.isRoutePPREnabled - ? createPrerenderState(renderOpts.isDebugPPRSkeleton) + ? createPrerenderState(renderOpts.isDebugDynamicAccesses) : null const store: StaticGenerationStore = { diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index 7dbd10d9fece5..96e25f3ff8ebd 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -2016,29 +2016,38 @@ export default abstract class Server< typeof routeModule !== 'undefined' && isAppPageRouteModule(routeModule) - // If this is a request that's rendering an app page that support's PPR, - // then if we're in development mode (or using the experimental test - // proxy) and the query parameter is set, then we should render the - // skeleton. We assume that if the page _could_ support it, we should - // show the skeleton in development. Ideally we would check the appConfig - // to see if this page has it enabled or not, but that would require - // plumbing the appConfig through to the server during development. - const isDebugPPRSkeleton = - query.__nextppronly && - couldSupportPPR && - (this.renderOpts.dev || this.experimentalTestProxy) - ? true - : false + // When enabled, this will allow the use of the `?__nextppronly` query to + // enable debugging of the static shell. + const hasDebugStaticShellQuery = + process.env.__NEXT_EXPERIMENTAL_STATIC_SHELL_DEBUGGING === '1' && + typeof query.__nextppronly !== 'undefined' && + couldSupportPPR // This page supports PPR if it has `experimentalPPR` set to `true` in the // prerender manifest and this is an app page. const isRoutePPREnabled: boolean = couldSupportPPR && + // In production, we'd expect to see the `experimentalPPR` flag set in the + // prerender manifest. (( prerenderManifest.routes[pathname] ?? prerenderManifest.dynamicRoutes[pathname] )?.experimentalPPR === true || - isDebugPPRSkeleton) + // Ideally we'd want to check the appConfig to see if this page has PPR + // enabled or not, but that would require plumbing the appConfig through + // to the server during development. We assume that the page supports it + // but only during development. + (hasDebugStaticShellQuery && + (this.renderOpts.dev === true || + this.experimentalTestProxy === true))) + + const isDebugStaticShell: boolean = + hasDebugStaticShellQuery && isRoutePPREnabled + + // We should enable debugging dynamic accesses when the static shell + // debugging has been enabled and we're also in development mode. + const isDebugDynamicAccesses = + isDebugStaticShell && this.renderOpts.dev === true // If we're in minimal mode, then try to get the postponed information from // the request metadata. If available, use it for resuming the postponed @@ -2276,13 +2285,16 @@ export default abstract class Server< // TODO: investigate, this is not safe across multiple concurrent requests incrementalCache?.resetRequestCache() - type Renderer = (context: { + type RendererContext = { /** * The postponed data for this render. This is only provided when resuming * a render that has been postponed. */ postponed: string | undefined - }) => Promise + } + type Renderer = ( + context: RendererContext + ) => Promise const doRender: Renderer = async ({ postponed }) => { // In development, we always want to generate dynamic HTML. @@ -2362,13 +2374,14 @@ export default abstract class Server< onClose: res.onClose.bind(res), } - if (isDebugPPRSkeleton) { + if (isDebugStaticShell || isDebugDynamicAccesses) { supportsDynamicResponse = false renderOpts.nextExport = true renderOpts.supportsDynamicResponse = false renderOpts.isStaticGeneration = true renderOpts.isRevalidate = true - renderOpts.isDebugPPRSkeleton = true + renderOpts.isDebugStaticShell = isDebugStaticShell + renderOpts.isDebugDynamicAccesses = isDebugDynamicAccesses } // Legacy render methods will return a render result that needs to be @@ -2758,18 +2771,38 @@ export default abstract class Server< } } - const result = await doRender({ + const context: RendererContext = { // Only requests that aren't revalidating can be resumed. If we have the // minimal postponed data, then we should resume the render with it. postponed: !isOnDemandRevalidate && !isRevalidating && minimalPostponed ? minimalPostponed : undefined, - }) - if (!result) { - return null } + // When we're in minimal mode, if we're trying to debug the static shell, + // we should just return nothing instead of resuming the dynamic render. + if ( + (isDebugStaticShell || isDebugDynamicAccesses) && + typeof context.postponed !== 'undefined' + ) { + return { + revalidate: 1, + value: { + kind: 'PAGE', + html: RenderResult.fromStatic(''), + pageData: {}, + postponed: undefined, + headers: undefined, + status: undefined, + }, + } + } + + // Perform the render. + const result = await doRender(context) + if (!result) return null + return { ...result, revalidate: @@ -3083,9 +3116,11 @@ export default abstract class Server< } } - // If we're debugging the skeleton, we should just serve the HTML without - // resuming the render. The returned HTML will be the static shell. - if (isDebugPPRSkeleton) { + // If we're debugging the static shell or the dynamic API accesses, we + // should just serve the HTML without resuming the render. The returned + // HTML will be the static shell so all the Dynamic API's will be used + // during static generation. + if (isDebugStaticShell || isDebugDynamicAccesses) { return { type: 'html', body, revalidate: 0 } } diff --git a/test/e2e/app-dir/app/index.test.ts b/test/e2e/app-dir/app/index.test.ts index 40e0796506f2d..e1a9aa85701f0 100644 --- a/test/e2e/app-dir/app/index.test.ts +++ b/test/e2e/app-dir/app/index.test.ts @@ -9,32 +9,16 @@ import stripAnsi from 'strip-ansi' const isPPREnabledByDefault = process.env.__NEXT_EXPERIMENTAL_PPR === 'true' describe('app dir - basic', () => { - const { - next, - isNextDev: isDev, - isNextStart, - isNextDeploy, - isTurbopack, - } = nextTestSetup({ - files: __dirname, - buildCommand: process.env.NEXT_EXPERIMENTAL_COMPILE - ? `pnpm next build --experimental-build-mode=compile` - : undefined, - dependencies: { - nanoid: '4.0.1', - }, - }) - - if (isDev && isPPREnabledByDefault) { - it('should allow returning just skeleton in dev with query', async () => { - const res = await next.fetch('/skeleton?__nextppronly=1') - expect(res.status).toBe(200) - - const html = await res.text() - expect(html).toContain('Skeleton') - expect(html).not.toContain('suspended content') + const { next, isNextDev, isNextStart, isNextDeploy, isTurbopack } = + nextTestSetup({ + files: __dirname, + buildCommand: process.env.NEXT_EXPERIMENTAL_COMPILE + ? `pnpm next build --experimental-build-mode=compile` + : undefined, + dependencies: { + nanoid: '4.0.1', + }, }) - } if (process.env.NEXT_EXPERIMENTAL_COMPILE) { it('should provide query for getStaticProps page correctly', async () => { @@ -142,7 +126,7 @@ describe('app dir - basic', () => { }) }) - if (!isDev) { + if (!isNextDev) { it('should successfully detect app route during prefetch', async () => { const browser = await next.browser('/') @@ -229,7 +213,7 @@ describe('app dir - basic', () => { expect(await browser.eval('window.beforeNav')).toBe(1) }) - if (isDev) { + if (isNextDev) { it('should not have duplicate config warnings', async () => { await next.fetch('/') expect( @@ -573,7 +557,7 @@ describe('app dir - basic', () => { }) // TODO-APP: Enable in development - ;(isDev || + ;(isNextDev || // When PPR is enabled, the shared layouts re-render because we prefetch // from the root. This will be addressed before GA. isPPREnabledByDefault @@ -1148,7 +1132,7 @@ describe('app dir - basic', () => { }) }) - if (isDev) { + if (isNextDev) { describe('HMR', () => { it('should HMR correctly for server component', async () => { const filePath = 'app/dashboard/index/page.js' @@ -1368,7 +1352,7 @@ describe('app dir - basic', () => { }) // TODO-APP: disable failing test and investigate later - ;(isDev || + ;(isNextDev || // When PPR is enabled, the shared layouts re-render because we prefetch // from the root. This will be addressed before GA. isPPREnabledByDefault @@ -1508,7 +1492,7 @@ describe('app dir - basic', () => { const val2 = await browser.elementByCss('#value-2').text() // TODO: enable when fetch cache is enabled in dev - if (!isDev) { + if (!isNextDev) { expect(val1).toBe(val2) } }) @@ -1701,7 +1685,7 @@ describe('app dir - basic', () => { expect(element.attribs.nonce).toBeTruthy() }) - if (!isDev) { + if (!isNextDev) { const browser = await next.browser('/script-nonce') await retry(async () => { @@ -1744,7 +1728,7 @@ describe('app dir - basic', () => { }) // Turbopack doesn't use eval by default, so we can check strict CSP. - if (!isDev || isTurbopack) { + if (!isNextDev || isTurbopack) { // This test is here to ensure that we don't accidentally turn CSP off // for the prod version. it('should successfully bootstrap even when using CSP', async () => { diff --git a/test/e2e/app-dir/static-shell-debugging/app/layout.jsx b/test/e2e/app-dir/static-shell-debugging/app/layout.jsx new file mode 100644 index 0000000000000..750eb927b1980 --- /dev/null +++ b/test/e2e/app-dir/static-shell-debugging/app/layout.jsx @@ -0,0 +1,7 @@ +export default function Layout({ children }) { + return ( + + {children} + + ) +} diff --git a/test/e2e/app-dir/static-shell-debugging/app/page.jsx b/test/e2e/app-dir/static-shell-debugging/app/page.jsx new file mode 100644 index 0000000000000..f7efe39b6fd9c --- /dev/null +++ b/test/e2e/app-dir/static-shell-debugging/app/page.jsx @@ -0,0 +1,17 @@ +import { unstable_noStore } from 'next/cache' +import { Suspense } from 'react' + +function Dynamic() { + unstable_noStore() + return
Dynamic
+} + +export default function Page() { + return ( +
+ Fallback
}> + + + + ) +} diff --git a/test/e2e/app-dir/static-shell-debugging/static-shell-debugging.test.ts b/test/e2e/app-dir/static-shell-debugging/static-shell-debugging.test.ts new file mode 100644 index 0000000000000..438f371a53777 --- /dev/null +++ b/test/e2e/app-dir/static-shell-debugging/static-shell-debugging.test.ts @@ -0,0 +1,40 @@ +import { nextTestSetup } from 'e2e-utils' + +describe('static-shell-debugging', () => { + describe.each([ + { ppr: true, debugging: true }, + { ppr: false, debugging: true }, + { ppr: true, debugging: false }, + { ppr: false, debugging: false }, + ])('ppr = $ppr, debugging = $debugging', (context) => { + const { next } = nextTestSetup({ + files: __dirname, + env: { + __NEXT_EXPERIMENTAL_STATIC_SHELL_DEBUGGING: context.debugging + ? '1' + : undefined, + }, + nextConfig: { experimental: { ppr: context.ppr } }, + }) + + if (context.debugging && context.ppr) { + it('should only render the static shell', async () => { + const res = await next.fetch('/?__nextppronly=1') + expect(res.status).toBe(200) + + const html = await res.text() + expect(html).toContain('Fallback') + expect(html).not.toContain('Dynamic') + }) + } else { + it('should render the full page', async () => { + const res = await next.fetch('/?__nextppronly=1') + expect(res.status).toBe(200) + + const html = await res.text() + expect(html).toContain('Fallback') + expect(html).toContain('Dynamic') + }) + } + }) +}) From eb9f49b07e880965ca3cb0c7e091da8eabb76fd5 Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Mon, 10 Jun 2024 19:03:13 +0200 Subject: [PATCH 09/60] Run Pages Router test with same version as Next.js peer dependency (#66712) --- run-tests.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/run-tests.js b/run-tests.js index 32f532d4cdfdf..98dd35e5de120 100644 --- a/run-tests.js +++ b/run-tests.js @@ -405,8 +405,7 @@ ${ENDGROUP}`) // a starter Next.js install to re-use to speed up tests // to avoid having to run yarn each time console.log(`${GROUP}Creating Next.js install for isolated tests`) - const reactVersion = - process.env.NEXT_TEST_REACT_VERSION || '19.0.0-rc-f994737d14-20240522' + const reactVersion = process.env.NEXT_TEST_REACT_VERSION || '19.0.0-rc.0' const { installDir, pkgPaths, tmpRepoDir } = await createNextInstall({ parentSpan: mockTrace(), dependencies: { From 755c9e445bf88f05c8893579ce838161ff13be6c Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 10 Jun 2024 11:34:36 -0700 Subject: [PATCH 10/60] Add timeout/retry handling for fetch cache (#66652) As discussed this adds handling to timeout at a max of 500ms for fetch cache request and retries a max of 3 times due to network instability. This also adds cache service tests and fixes a case we've been trying to track down where we were seeing `undefined` cache URL values which made debugging fetches tricky. --- packages/next/src/server/base-server.ts | 1 - .../lib/incremental-cache/fetch-cache.ts | 72 ++++-- .../web/spec-extension/unstable-cache.ts | 10 +- test/ppr-tests-manifest.json | 11 + .../fetch-cache/app/api/revalidate/route.ts | 9 + .../app-dir/fetch-cache/app/layout.tsx | 8 + .../app-dir/fetch-cache/app/page.tsx | 32 +++ .../app-dir/fetch-cache/fetch-cache.test.ts | 240 ++++++++++++++++++ test/turbopack-build-tests-manifest.json | 11 + 9 files changed, 371 insertions(+), 23 deletions(-) create mode 100644 test/production/app-dir/fetch-cache/app/api/revalidate/route.ts create mode 100644 test/production/app-dir/fetch-cache/app/layout.tsx create mode 100644 test/production/app-dir/fetch-cache/app/page.tsx create mode 100644 test/production/app-dir/fetch-cache/fetch-cache.test.ts diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index 96e25f3ff8ebd..714b27837f5d3 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -2792,7 +2792,6 @@ export default abstract class Server< kind: 'PAGE', html: RenderResult.fromStatic(''), pageData: {}, - postponed: undefined, headers: undefined, status: undefined, }, diff --git a/packages/next/src/server/lib/incremental-cache/fetch-cache.ts b/packages/next/src/server/lib/incremental-cache/fetch-cache.ts index ee0431a4f218d..909a3ad955a1a 100644 --- a/packages/next/src/server/lib/incremental-cache/fetch-cache.ts +++ b/packages/next/src/server/lib/incremental-cache/fetch-cache.ts @@ -24,10 +24,40 @@ const CACHE_REVALIDATE_HEADER = 'x-vercel-revalidate' as const const CACHE_FETCH_URL_HEADER = 'x-vercel-cache-item-name' as const const CACHE_CONTROL_VALUE_HEADER = 'x-vercel-cache-control' as const +const DEBUG = Boolean(process.env.NEXT_PRIVATE_DEBUG_CACHE) + +async function fetchRetryWithTimeout( + url: Parameters[0], + init: Parameters[1], + retryIndex = 0 +): Promise { + const controller = new AbortController() + const timeout = setTimeout(() => { + controller.abort() + }, 500) + + return fetch(url, { + ...(init || {}), + signal: controller.signal, + }) + .catch((err) => { + if (retryIndex === 3) { + throw err + } else { + if (DEBUG) { + console.log(`Fetch failed for ${url} retry ${retryIndex}`) + } + return fetchRetryWithTimeout(url, init, retryIndex + 1) + } + }) + .finally(() => { + clearTimeout(timeout) + }) +} + export default class FetchCache implements CacheHandler { private headers: Record private cacheEndpoint?: string - private debug: boolean private hasMatchingTags(arr1: string[], arr2: string[]) { if (arr1.length !== arr2.length) return false @@ -53,7 +83,6 @@ export default class FetchCache implements CacheHandler { } constructor(ctx: CacheHandlerContext) { - this.debug = !!process.env.NEXT_PRIVATE_DEBUG_CACHE this.headers = {} this.headers['Content-Type'] = 'application/json' @@ -79,17 +108,18 @@ export default class FetchCache implements CacheHandler { } if (scHost) { - this.cacheEndpoint = `https://${scHost}${scBasePath || ''}` - if (this.debug) { + const scProto = process.env.SUSPENSE_CACHE_PROTO || 'https' + this.cacheEndpoint = `${scProto}://${scHost}${scBasePath || ''}` + if (DEBUG) { console.log('using cache endpoint', this.cacheEndpoint) } - } else if (this.debug) { + } else if (DEBUG) { console.log('no cache endpoint available') } if (ctx.maxMemoryCacheSize) { if (!memoryCache) { - if (this.debug) { + if (DEBUG) { console.log('using memory store for fetch cache') } @@ -118,7 +148,7 @@ export default class FetchCache implements CacheHandler { }) } } else { - if (this.debug) { + if (DEBUG) { console.log('not using memory store for fetch cache') } } @@ -133,21 +163,21 @@ export default class FetchCache implements CacheHandler { ) { let [tags] = args tags = typeof tags === 'string' ? [tags] : tags - if (this.debug) { + if (DEBUG) { console.log('revalidateTag', tags) } if (!tags.length) return if (Date.now() < rateLimitedUntil) { - if (this.debug) { + if (DEBUG) { console.log('rate limited ', rateLimitedUntil) } return } try { - const res = await fetch( + const res = await fetchRetryWithTimeout( `${this.cacheEndpoint}/v1/suspense-cache/revalidate?tags=${tags .map((tag) => encodeURIComponent(tag)) .join(',')}`, @@ -181,7 +211,7 @@ export default class FetchCache implements CacheHandler { } if (Date.now() < rateLimitedUntil) { - if (this.debug) { + if (DEBUG) { console.log('rate limited') } return null @@ -227,7 +257,7 @@ export default class FetchCache implements CacheHandler { } if (res.status === 404) { - if (this.debug) { + if (DEBUG) { console.log( `no fetch cache entry for ${key}, duration: ${ Date.now() - start @@ -245,7 +275,7 @@ export default class FetchCache implements CacheHandler { const cached: IncrementalCacheValue = await res.json() if (!cached || cached.kind !== 'FETCH') { - this.debug && console.log({ cached }) + DEBUG && console.log({ cached }) throw new Error('invalid cache value') } @@ -272,7 +302,7 @@ export default class FetchCache implements CacheHandler { : Date.now() - parseInt(age || '0', 10) * 1000, } - if (this.debug) { + if (DEBUG) { console.log( `got fetch cache entry for ${key}, duration: ${ Date.now() - start @@ -289,7 +319,7 @@ export default class FetchCache implements CacheHandler { } } catch (err) { // unable to get data from fetch-cache - if (this.debug) { + if (DEBUG) { console.error(`Failed to get from fetch-cache`, err) } } @@ -314,7 +344,7 @@ export default class FetchCache implements CacheHandler { JSON.stringify((newValue as Record)[field]) ) ) { - if (this.debug) { + if (DEBUG) { console.log(`skipping cache set for ${key} as not modified`) } return @@ -324,7 +354,7 @@ export default class FetchCache implements CacheHandler { if (!fetchCache) return if (Date.now() < rateLimitedUntil) { - if (this.debug) { + if (DEBUG) { console.log('rate limited') } return @@ -356,7 +386,7 @@ export default class FetchCache implements CacheHandler { tags: undefined, }) - if (this.debug) { + if (DEBUG) { console.log('set cache', key) } const fetchParams: NextFetchCacheParams = { @@ -385,11 +415,11 @@ export default class FetchCache implements CacheHandler { } if (!res.ok) { - this.debug && console.log(await res.text()) + DEBUG && console.log(await res.text()) throw new Error(`invalid response ${res.status}`) } - if (this.debug) { + if (DEBUG) { console.log( `successfully set to fetch-cache for ${key}, duration: ${ Date.now() - start @@ -398,7 +428,7 @@ export default class FetchCache implements CacheHandler { } } catch (err) { // unable to set to fetch-cache - if (this.debug) { + if (DEBUG) { console.error(`Failed to update fetch cache`, err) } } diff --git a/packages/next/src/server/web/spec-extension/unstable-cache.ts b/packages/next/src/server/web/spec-extension/unstable-cache.ts index 56e0801492f18..e132279e0a94e 100644 --- a/packages/next/src/server/web/spec-extension/unstable-cache.ts +++ b/packages/next/src/server/web/spec-extension/unstable-cache.ts @@ -113,7 +113,7 @@ export function unstable_cache( return a.localeCompare(b) }) const sortedSearch = sortedSearchKeys - .map((key) => searchParams.get(key)) + .map((key) => `${key}=${searchParams.get(key)}`) .join('&') // Construct the complete cache key for this function invocation @@ -180,6 +180,7 @@ export function unstable_cache( tags, softTags: implicitTags, fetchIdx, + fetchUrl, }) if (cacheEntry && cacheEntry.value) { @@ -276,10 +277,17 @@ export function unstable_cache( if (!incrementalCache.isOnDemandRevalidate) { // We aren't doing an on demand revalidation so we check use the cache if valid + // @TODO check on this API. addImplicitTags mutates the store and returns the implicit tags. The naming + // of this function is potentially a little confusing + const implicitTags = store && addImplicitTags(store) + const cacheEntry = await incrementalCache.get(cacheKey, { kindHint: 'fetch', revalidate: options.revalidate, tags, + fetchIdx, + fetchUrl, + softTags: implicitTags, }) if (cacheEntry && cacheEntry.value) { diff --git a/test/ppr-tests-manifest.json b/test/ppr-tests-manifest.json index d3f170e5f5ea3..19db3c4177518 100644 --- a/test/ppr-tests-manifest.json +++ b/test/ppr-tests-manifest.json @@ -1,6 +1,17 @@ { "version": 2, "suites": { + "test/production/app-dir/fetch-cache/fetch-cache.test.ts": { + "passed": [], + "failed": [ + "fetch-cache should have correct fetchUrl field for fetches and unstable_cache", + "fetch-cache should retry 3 times when revalidate times out", + "fetch-cache should not retry for failed fetch-cache GET" + ], + "pending": [], + "flakey": [], + "runtimeError": false + }, "test/e2e/app-dir/app-static/app-static.test.ts": { "failed": [ "app-dir static/dynamic handling usePathname should have values from canonical url on rewrite", diff --git a/test/production/app-dir/fetch-cache/app/api/revalidate/route.ts b/test/production/app-dir/fetch-cache/app/api/revalidate/route.ts new file mode 100644 index 0000000000000..3f8985e20754e --- /dev/null +++ b/test/production/app-dir/fetch-cache/app/api/revalidate/route.ts @@ -0,0 +1,9 @@ +import { revalidateTag } from 'next/cache' +import { NextRequest, NextResponse } from 'next/server' + +export const dynamic = 'force-dynamic' + +export function GET(req: NextRequest) { + revalidateTag('thankyounext') + return NextResponse.json({ done: true }) +} diff --git a/test/production/app-dir/fetch-cache/app/layout.tsx b/test/production/app-dir/fetch-cache/app/layout.tsx new file mode 100644 index 0000000000000..888614deda3ba --- /dev/null +++ b/test/production/app-dir/fetch-cache/app/layout.tsx @@ -0,0 +1,8 @@ +import { ReactNode } from 'react' +export default function Root({ children }: { children: ReactNode }) { + return ( + + {children} + + ) +} diff --git a/test/production/app-dir/fetch-cache/app/page.tsx b/test/production/app-dir/fetch-cache/app/page.tsx new file mode 100644 index 0000000000000..40db1a33422ff --- /dev/null +++ b/test/production/app-dir/fetch-cache/app/page.tsx @@ -0,0 +1,32 @@ +import { unstable_cache } from 'next/cache' + +export const dynamic = 'force-dynamic' +export const fetchCache = 'default-cache' + +const getCachedRandom = unstable_cache( + async () => { + return Math.random() + }, + [], + { + revalidate: 3, + tags: ['thankyounext'], + } +) + +export default async function Page() { + const data = await fetch( + 'https://next-data-api-endpoint.vercel.app/api/random?a=b', + { next: { tags: ['thankyounext'], revalidate: 3 } } + ).then((res) => res.text()) + + const cachedRandom = getCachedRandom() + + return ( + <> +

hello world

+

{data}

+

{cachedRandom}

+ + ) +} diff --git a/test/production/app-dir/fetch-cache/fetch-cache.test.ts b/test/production/app-dir/fetch-cache/fetch-cache.test.ts new file mode 100644 index 0000000000000..972e8ef280076 --- /dev/null +++ b/test/production/app-dir/fetch-cache/fetch-cache.test.ts @@ -0,0 +1,240 @@ +import glob from 'glob' +import http from 'http' +import fs from 'fs-extra' +import { join } from 'path' +import { FileRef, NextInstance, createNext } from 'e2e-utils' +import { + retry, + killApp, + findPort, + fetchViaHTTP, + initNextServerScript, +} from 'next-test-utils' + +describe('fetch-cache', () => { + let next: NextInstance + let appPort: any + let cliOuptut = '' + let nextInstance: any + let fetchGetReqIndex = 0 + let revalidateReqIndex = 0 + let fetchGetShouldError = false + let fetchCacheServer: http.Server + let fetchCacheRequests: Array<{ + url: string + method: string + headers: Record + }> = [] + let fetchCacheEnv: Record = { + SUSPENSE_CACHE_PROTO: 'http', + } + + const setupNext = async ({ + nextEnv, + minimalMode, + }: { + nextEnv?: boolean + minimalMode?: boolean + }) => { + // test build against environment with next support + process.env.NOW_BUILDER = nextEnv ? '1' : '' + + next = await createNext({ + files: { + app: new FileRef(join(__dirname, 'app')), + }, + nextConfig: { + eslint: { + ignoreDuringBuilds: true, + }, + output: 'standalone', + }, + }) + await next.stop() + + await fs.move( + join(next.testDir, '.next/standalone'), + join(next.testDir, 'standalone') + ) + for (const file of await fs.readdir(next.testDir)) { + if (file !== 'standalone') { + await fs.remove(join(next.testDir, file)) + console.log('removed', file) + } + } + const files = glob.sync('**/*', { + cwd: join(next.testDir, 'standalone/.next/server/pages'), + dot: true, + }) + + for (const file of files) { + if (file.endsWith('.json') || file.endsWith('.html')) { + await fs.remove(join(next.testDir, '.next/server', file)) + } + } + + const testServer = join(next.testDir, 'standalone/server.js') + await fs.writeFile( + testServer, + (await fs.readFile(testServer, 'utf8')).replace( + 'port:', + `minimalMode: ${minimalMode},port:` + ) + ) + appPort = await findPort() + nextInstance = await initNextServerScript( + testServer, + /- Local:/, + { + ...process.env, + ...fetchCacheEnv, + PORT: appPort, + }, + undefined, + { + cwd: next.testDir, + onStderr(data) { + cliOuptut += data + }, + onStdout(data) { + cliOuptut += data + }, + } + ) + } + + beforeAll(async () => { + fetchGetReqIndex = 0 + revalidateReqIndex = 0 + fetchCacheRequests = [] + fetchGetShouldError = false + fetchCacheServer = http.createServer((req, res) => { + console.log(`fetch cache request ${req.url} ${req.method}`, req.headers) + const parsedUrl = new URL(req.url || '/', 'http://n') + + fetchCacheRequests.push({ + url: req.url, + method: req.method?.toLowerCase(), + headers: req.headers, + }) + + if (parsedUrl.pathname === '/v1/suspense-cache/revalidate') { + revalidateReqIndex += 1 + // timeout unless it's 3rd retry + const shouldTimeout = revalidateReqIndex % 3 !== 0 + + if (shouldTimeout) { + console.log('not responding for', req.url, { revalidateReqIndex }) + return + } + res.statusCode = 200 + res.end(`revalidated ${parsedUrl.searchParams.get('tags')}`) + return + } + const keyMatches = parsedUrl.pathname.match( + /\/v1\/suspense-cache\/(.*?)\/?$/ + ) + const key = keyMatches?.[0] + + if (key) { + const type = req.method?.toLowerCase() + console.log(`got ${type} for ${key}`) + + if (type === 'get') { + fetchGetReqIndex += 1 + + if (fetchGetShouldError) { + res.statusCode = 500 + res.end('internal server error') + return + } + } + res.statusCode = type === 'post' ? 200 : 404 + res.end(`${type} for ${key}`) + return + } + res.statusCode = 404 + res.end('not found') + }) + await new Promise(async (resolve) => { + let fetchCachePort = await findPort() + fetchCacheServer.listen(fetchCachePort, () => { + fetchCacheEnv['SUSPENSE_CACHE_URL'] = `[::]:${fetchCachePort}` + console.log( + `Started fetch cache server at http://${fetchCacheEnv['SUSPENSE_CACHE_URL']}` + ) + resolve() + }) + }) + await setupNext({ nextEnv: true, minimalMode: true }) + }) + afterAll(async () => { + await next.destroy() + if (fetchCacheServer) fetchCacheServer.close() + if (nextInstance) await killApp(nextInstance) + }) + + it('should have correct fetchUrl field for fetches and unstable_cache', async () => { + const res = await fetchViaHTTP(appPort, '/?myKey=myValue') + const html = await res.text() + + expect(res.status).toBe(200) + expect(html).toContain('hello world') + + const fetchUrlHeader = 'x-vercel-cache-item-name' + const fetchTagsHeader = 'x-vercel-cache-tags' + const fetchSoftTagsHeader = 'x-next-cache-soft-tags' + const unstableCacheSet = fetchCacheRequests.find((item) => { + return ( + item.method === 'get' && + item.headers[fetchUrlHeader]?.includes('unstable_cache') + ) + }) + const fetchSet = fetchCacheRequests.find((item) => { + return ( + item.method === 'get' && + item.headers[fetchUrlHeader]?.includes('next-data-api-endpoint') + ) + }) + + expect(unstableCacheSet.headers[fetchUrlHeader]).toMatch( + /unstable_cache \/\?myKey=myValue .*?/ + ) + expect(unstableCacheSet.headers[fetchTagsHeader]).toBe('thankyounext') + expect(unstableCacheSet.headers[fetchSoftTagsHeader]).toBe( + '_N_T_/layout,_N_T_/page,_N_T_/' + ) + expect(fetchSet.headers[fetchUrlHeader]).toBe( + 'https://next-data-api-endpoint.vercel.app/api/random?a=b' + ) + expect(fetchSet.headers[fetchSoftTagsHeader]).toBe( + '_N_T_/layout,_N_T_/page,_N_T_/' + ) + expect(fetchSet.headers[fetchTagsHeader]).toBe('thankyounext') + }) + + it('should retry 3 times when revalidate times out', async () => { + await fetchViaHTTP(appPort, '/api/revalidate') + + await retry(() => { + expect(revalidateReqIndex).toBe(3) + }) + expect(cliOuptut).not.toContain('Failed to revalidate') + expect(cliOuptut).not.toContain('Error') + }) + + it('should not retry for failed fetch-cache GET', async () => { + fetchGetShouldError = true + const fetchGetReqIndexStart = fetchGetReqIndex + + try { + await fetchViaHTTP(appPort, '/api/revalidate') + const res = await fetchViaHTTP(appPort, '/') + expect(res.status).toBe(200) + expect(await res.text()).toContain('hello world') + expect(fetchGetReqIndex).toBe(fetchGetReqIndexStart + 2) + } finally { + fetchGetShouldError = false + } + }) +}) diff --git a/test/turbopack-build-tests-manifest.json b/test/turbopack-build-tests-manifest.json index edc3c0dac2500..6ff821b17121a 100644 --- a/test/turbopack-build-tests-manifest.json +++ b/test/turbopack-build-tests-manifest.json @@ -1,6 +1,17 @@ { "version": 2, "suites": { + "test/production/app-dir/fetch-cache/fetch-cache.test.ts": { + "passed": [], + "failed": [ + "fetch-cache should have correct fetchUrl field for fetches and unstable_cache", + "fetch-cache should retry 3 times when revalidate times out", + "fetch-cache should not retry for failed fetch-cache GET" + ], + "pending": [], + "flakey": [], + "runtimeError": false + }, "test/e2e/404-page-router/index.test.ts": { "passed": [ "404-page-router 404-page-router with basePath of false and i18n of false and middleware false for /error should have the correct router parameters after it is ready", From 16caf419955980c98dced610449f90ceb94bc171 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 10 Jun 2024 12:13:05 -0700 Subject: [PATCH 11/60] Fix inconsistency with 404 getStaticProps cache-control (#66674) While investigating unexpected stale responses when leveraging `getStaticProps` on the 404 page noticed we have an inconsistency between local and deployed due to `Cache-Control` being set to `no-store, must-revalidate` even though a revalidate period is provided. The inconsistency also differs between the HTML response and the data response `_next/data` which causes even more unexpected behavior. To avoid this behavior, this replaces the handling to ensure we honor the originally provided revalidate period during `notFound: true` for the `Cache-Control` header. Validated against provided reproduction here https://github.com/fusdev0/next-notfound-revalidate Deployment: https://vercel.live/link/next-notfound-revalidate-govzskknf-vtest314-ijjk-testing.vercel.app/fallback-blocking/fasdf Prior PR for prior context that introduced this https://github.com/vercel/next.js/pull/19165 x-ref: [slack thread](https://vercel.slack.com/archives/C0676QZBWKS/p1717492459342109) --- packages/next/src/server/base-server.ts | 24 +++++++++++++++---- packages/next/src/server/request-meta.ts | 5 ++++ .../not-found-revalidate/pages/404.js | 2 +- .../not-found-revalidate/test/index.test.js | 12 ++++++---- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index 714b27837f5d3..d5ca7ebf50195 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -2892,9 +2892,8 @@ export default abstract class Server< typeof cacheEntry.revalidate !== 'undefined' && (!this.renderOpts.dev || (hasServerProps && !isNextDataRequest)) ) { - // If this is a preview mode request, we shouldn't cache it. We also don't - // cache 404 pages. - if (isPreviewMode || (is404Page && !isNextDataRequest)) { + // If this is a preview mode request, we shouldn't cache it + if (isPreviewMode) { revalidate = 0 } @@ -2906,6 +2905,18 @@ export default abstract class Server< } } + // If we are rendering the 404 page we derive the cache-control + // revalidate period from the value that trigged the not found + // to be rendered. So if `getStaticProps` returns + // { notFound: true, revalidate 60 } the revalidate period should + // be 60 but if a static asset 404s directly it should have a revalidate + // period of 0 so that it doesn't get cached unexpectedly by a CDN + else if (is404Page) { + const notFoundRevalidate = getRequestMeta(req, 'notFoundRevalidate') + revalidate = + typeof notFoundRevalidate === 'undefined' ? 0 : notFoundRevalidate + } + // If the cache entry has a revalidate value that's a number, use it. else if (typeof cacheEntry.revalidate === 'number') { if (cacheEntry.revalidate < 1) { @@ -2953,6 +2964,12 @@ export default abstract class Server< } if (!cachedData) { + // add revalidate metadata before rendering 404 page + // so that we can use this as source of truth for the + // cache-control header instead of what the 404 page returns + // for the revalidate value + addRequestMeta(req, 'notFoundRevalidate', cacheEntry.revalidate) + if (cacheEntry.revalidate) { res.setHeader( 'Cache-Control', @@ -2971,7 +2988,6 @@ export default abstract class Server< if (this.renderOpts.dev) { query.__nextNotFoundSrcPage = pathname } - await this.render404(req, res, { pathname, query }, false) return null } else if (cachedData.kind === 'REDIRECT') { diff --git a/packages/next/src/server/request-meta.ts b/packages/next/src/server/request-meta.ts index f45c2afe252c8..772447aa6d043 100644 --- a/packages/next/src/server/request-meta.ts +++ b/packages/next/src/server/request-meta.ts @@ -94,6 +94,11 @@ export interface RequestMeta { cacheEntry: any, requestMeta: any ) => Promise | boolean | void + + /** + * The previous revalidate before rendering 404 page for notFound: true + */ + notFoundRevalidate?: number | false } /** diff --git a/test/integration/not-found-revalidate/pages/404.js b/test/integration/not-found-revalidate/pages/404.js index cb670e86b596c..6c4da3942ca80 100644 --- a/test/integration/not-found-revalidate/pages/404.js +++ b/test/integration/not-found-revalidate/pages/404.js @@ -14,6 +14,6 @@ export const getStaticProps = () => { notFound: true, random: Math.random(), }, - revalidate: 1, + revalidate: 6000, } } diff --git a/test/integration/not-found-revalidate/test/index.test.js b/test/integration/not-found-revalidate/test/index.test.js index 2f2928961429b..98ff9ea8be548 100644 --- a/test/integration/not-found-revalidate/test/index.test.js +++ b/test/integration/not-found-revalidate/test/index.test.js @@ -81,9 +81,9 @@ const runTests = () => { let res = await fetchViaHTTP(appPort, '/fallback-blocking/hello') let $ = cheerio.load(await res.text()) - const privateCache = - 'private, no-cache, no-store, max-age=0, must-revalidate' - expect(res.headers.get('cache-control')).toBe(privateCache) + expect(res.headers.get('cache-control')).toBe( + `s-maxage=1, stale-while-revalidate` + ) expect(res.status).toBe(404) expect(JSON.parse($('#props').text()).notFound).toBe(true) @@ -91,7 +91,9 @@ const runTests = () => { res = await fetchViaHTTP(appPort, '/fallback-blocking/hello') $ = cheerio.load(await res.text()) - expect(res.headers.get('cache-control')).toBe(privateCache) + expect(res.headers.get('cache-control')).toBe( + `s-maxage=1, stale-while-revalidate` + ) expect(res.status).toBe(404) expect(JSON.parse($('#props').text()).notFound).toBe(true) @@ -146,7 +148,7 @@ const runTests = () => { let $ = cheerio.load(await res.text()) expect(res.headers.get('cache-control')).toBe( - 'private, no-cache, no-store, max-age=0, must-revalidate' + `s-maxage=1, stale-while-revalidate` ) expect(res.status).toBe(404) expect(JSON.parse($('#props').text()).notFound).toBe(true) From 996a290afd7f8e37a93f23281276a7b5f4b8cd29 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Mon, 10 Jun 2024 12:57:46 -0700 Subject: [PATCH 12/60] [lint] Allow lint warnings to pass in CI (#66140) To allow us to incrementally adopt more comprehensive linting rules, this pull request disables the previous behaviour of failing CI when any warnings were discovered. Instead, this modifies the previous warnings to be errors which will preserve the previous linting behaviour. As we enable new lint rules, they can be added as warnings which will gently nudge us towards fixing in related pull requests. --- .eslintrc.json | 182 ++++++++++++++++---------------- lint-staged.config.js | 2 +- package.json | 4 +- packages/next-env/package.json | 2 +- packages/next-env/tsconfig.json | 4 +- 5 files changed, 98 insertions(+), 96 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 0081edc950129..4151575356c85 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -93,7 +93,7 @@ ], "no-unused-vars": "off", "@typescript-eslint/no-unused-vars": [ - "warn", + "error", { "args": "none", "ignoreRestSiblings": true @@ -102,7 +102,7 @@ "no-use-before-define": "off", "no-useless-constructor": "off", "@typescript-eslint/no-use-before-define": "off", - "@typescript-eslint/no-useless-constructor": "warn", + "@typescript-eslint/no-useless-constructor": "error", "@typescript-eslint/prefer-literal-enum-member": "error" } }, @@ -150,7 +150,7 @@ "packages/next/webpack.config.js" ], "rules": { - "no-shadow": ["warn", { "builtinGlobals": false }], + "no-shadow": ["error", { "builtinGlobals": false }], "import/no-extraneous-dependencies": [ "error", { "devDependencies": false } @@ -162,9 +162,9 @@ "rules": { // Note: you must disable the base rule as it can report incorrect errors "no-shadow": "off", - "@typescript-eslint/no-shadow": ["warn", { "builtinGlobals": false }], + "@typescript-eslint/no-shadow": ["error", { "builtinGlobals": false }], "@typescript-eslint/no-unused-vars": [ - "warn", + "error", { "args": "all", "argsIgnorePattern": "^_", @@ -211,39 +211,39 @@ } ], "rules": { - "array-callback-return": "warn", - "default-case": ["warn", { "commentPattern": "^no default$" }], - "dot-location": ["warn", "property"], - "eqeqeq": ["warn", "smart"], - "new-parens": "warn", - "no-array-constructor": "warn", - "no-caller": "warn", - "no-cond-assign": ["warn", "except-parens"], - "no-const-assign": "warn", - "no-control-regex": "warn", - "no-delete-var": "warn", - "no-dupe-args": "warn", - "no-dupe-class-members": "warn", - "no-dupe-keys": "warn", - "no-duplicate-case": "warn", - "no-empty-character-class": "warn", - "no-empty-pattern": "warn", - "no-eval": "warn", - "no-ex-assign": "warn", - "no-extend-native": "warn", - "no-extra-bind": "warn", - "no-extra-label": "warn", - "no-fallthrough": "warn", - "no-func-assign": "warn", - "no-implied-eval": "warn", - "no-invalid-regexp": "warn", - "no-iterator": "warn", - "no-label-var": "warn", - "no-labels": ["warn", { "allowLoop": true, "allowSwitch": false }], - "no-lone-blocks": "warn", - "no-loop-func": "warn", + "array-callback-return": "error", + "default-case": ["error", { "commentPattern": "^no default$" }], + "dot-location": ["error", "property"], + "eqeqeq": ["error", "smart"], + "new-parens": "error", + "no-array-constructor": "error", + "no-caller": "error", + "no-cond-assign": ["error", "except-parens"], + "no-const-assign": "error", + "no-control-regex": "error", + "no-delete-var": "error", + "no-dupe-args": "error", + "no-dupe-class-members": "error", + "no-dupe-keys": "error", + "no-duplicate-case": "error", + "no-empty-character-class": "error", + "no-empty-pattern": "error", + "no-eval": "error", + "no-ex-assign": "error", + "no-extend-native": "error", + "no-extra-bind": "error", + "no-extra-label": "error", + "no-fallthrough": "error", + "no-func-assign": "error", + "no-implied-eval": "error", + "no-invalid-regexp": "error", + "no-iterator": "error", + "no-label-var": "error", + "no-labels": ["error", { "allowLoop": true, "allowSwitch": false }], + "no-lone-blocks": "error", + "no-loop-func": "error", "no-mixed-operators": [ - "warn", + "error", { "groups": [ ["&", "|", "^", "~", "<<", ">>", ">>>"], @@ -254,37 +254,37 @@ "allowSamePrecedence": false } ], - "no-multi-str": "warn", - "no-native-reassign": "warn", - "no-negated-in-lhs": "warn", - "no-new-func": "warn", - "no-new-object": "warn", - "no-new-symbol": "warn", - "no-new-wrappers": "warn", - "no-obj-calls": "warn", - "no-octal": "warn", - "no-octal-escape": "warn", - "no-regex-spaces": "warn", + "no-multi-str": "error", + "no-native-reassign": "error", + "no-negated-in-lhs": "error", + "no-new-func": "error", + "no-new-object": "error", + "no-new-symbol": "error", + "no-new-wrappers": "error", + "no-obj-calls": "error", + "no-octal": "error", + "no-octal-escape": "error", + "no-regex-spaces": "error", "no-restricted-syntax": [ - "warn", + "error", "WithStatement", { "message": "substr() is deprecated, use slice() or substring() instead", "selector": "MemberExpression > Identifier[name='substr']" } ], - "no-script-url": "warn", - "no-self-assign": "warn", - "no-self-compare": "warn", - "no-sequences": "warn", - "no-shadow-restricted-names": "warn", - "no-sparse-arrays": "warn", + "no-script-url": "error", + "no-self-assign": "error", + "no-self-compare": "error", + "no-sequences": "error", + "no-shadow-restricted-names": "error", + "no-sparse-arrays": "error", "no-template-curly-in-string": "error", - "no-this-before-super": "warn", - "no-throw-literal": "warn", + "no-this-before-super": "error", + "no-throw-literal": "error", "no-undef": "error", - "no-unexpected-multiline": "warn", - "no-unreachable": "warn", + "no-unexpected-multiline": "error", + "no-unreachable": "error", "no-unused-expressions": [ "error", { @@ -293,64 +293,64 @@ "allowTaggedTemplates": true } ], - "no-unused-labels": "warn", + "no-unused-labels": "error", "no-unused-vars": [ - "warn", + "error", { "args": "none", "ignoreRestSiblings": true } ], "no-use-before-define": "off", - "no-useless-computed-key": "warn", - "no-useless-concat": "warn", - "no-useless-constructor": "warn", - "no-useless-escape": "warn", + "no-useless-computed-key": "error", + "no-useless-concat": "error", + "no-useless-constructor": "error", + "no-useless-escape": "error", "no-useless-rename": [ - "warn", + "error", { "ignoreDestructuring": false, "ignoreImport": false, "ignoreExport": false } ], - "no-with": "warn", - "no-whitespace-before-property": "warn", - "react-hooks/exhaustive-deps": "warn", - "require-yield": "warn", - "rest-spread-spacing": ["warn", "never"], - "strict": ["warn", "never"], - "unicode-bom": ["warn", "never"], - "use-isnan": "warn", - "valid-typeof": "warn", - "getter-return": "warn", - "react/forbid-foreign-prop-types": ["warn", { "allowInPropTypes": true }], - "react/jsx-no-comment-textnodes": "warn", - "react/jsx-no-duplicate-props": "warn", - "react/jsx-no-target-blank": "warn", + "no-with": "error", + "no-whitespace-before-property": "error", + "react-hooks/exhaustive-deps": "error", + "require-yield": "error", + "rest-spread-spacing": ["error", "never"], + "strict": ["error", "never"], + "unicode-bom": ["error", "never"], + "use-isnan": "error", + "valid-typeof": "error", + "getter-return": "error", + "react/forbid-foreign-prop-types": ["error", { "allowInPropTypes": true }], + "react/jsx-no-comment-textnodes": "error", + "react/jsx-no-duplicate-props": "error", + "react/jsx-no-target-blank": "error", "react/jsx-no-undef": "error", "react/jsx-pascal-case": [ - "warn", + "error", { "allowAllCaps": true, "ignore": [] } ], - "react/jsx-uses-react": "warn", - "react/jsx-uses-vars": "warn", - "react/no-danger-with-children": "warn", - "react/no-deprecated": "warn", - "react/no-direct-mutation-state": "warn", - "react/no-is-mounted": "warn", + "react/jsx-uses-react": "error", + "react/jsx-uses-vars": "error", + "react/no-danger-with-children": "error", + "react/no-deprecated": "error", + "react/no-direct-mutation-state": "error", + "react/no-is-mounted": "error", "react/no-typos": "error", "react/react-in-jsx-scope": "off", "react/require-render-return": "error", - "react/style-prop-object": "warn", + "react/style-prop-object": "error", "react-hooks/rules-of-hooks": "error", - // "@typescript-eslint/non-nullable-type-assertion-style": "warn", - "@typescript-eslint/prefer-as-const": "warn", + // "@typescript-eslint/non-nullable-type-assertion-style": "error", + "@typescript-eslint/prefer-as-const": "error", "@typescript-eslint/no-redeclare": [ - "warn", + "error", { "builtinGlobals": false, "ignoreDeclarationMerge": true } ] } diff --git a/lint-staged.config.js b/lint-staged.config.js index 9397860c6c07e..9cdc3d318c0d3 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -30,7 +30,7 @@ module.exports = { return [ `prettier --with-node-modules --ignore-path .prettierignore --write ${escapedFileNames}`, - `eslint --no-ignore --max-warnings=0 --fix ${eslintFileNames + `eslint --no-ignore --fix ${eslintFileNames .filter((filename) => filename !== null) .map((filename) => { return `"${filename}"` diff --git a/package.json b/package.json index d7add869c8697..4ebdbf04f7c66 100644 --- a/package.json +++ b/package.json @@ -33,12 +33,12 @@ "git-clean": "git clean -d -x -e node_modules -e packages -f", "typescript": "tsc --noEmit", "lint-typescript": "turbo run typescript", - "lint-eslint": "eslint . --ext js,jsx,ts,tsx --max-warnings=0 --config .eslintrc.json --no-eslintrc", + "lint-eslint": "eslint . --ext js,jsx,ts,tsx --config .eslintrc.json --no-eslintrc", "lint-no-typescript": "run-p prettier-check lint-eslint lint-language", "types-and-precompiled": "run-p lint-typescript check-precompiled validate-externals-doc", "validate-externals-doc": "node ./scripts/validate-externals-doc.js", "lint": "run-p test-types lint-typescript prettier-check lint-eslint lint-language", - "lint-fix": "pnpm prettier-fix && eslint . --ext js,jsx,ts,tsx --fix --max-warnings=0 --config .eslintrc.json --no-eslintrc", + "lint-fix": "pnpm prettier-fix && eslint . --ext js,jsx,ts,tsx --fix --config .eslintrc.json --no-eslintrc", "lint-language": "alex .", "prettier-check": "prettier --check .", "check-examples": "./scripts/check-examples.sh", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index fa1cc5d6b097d..689c30978422e 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -23,7 +23,7 @@ "scripts": { "dev": "ncc build ./index.ts -w -o dist/", "prerelease": "node ../../scripts/rm.mjs dist", - "types": "tsc index.ts --declaration --emitDeclarationOnly --declarationDir dist --esModuleInterop", + "types": "tsc --declaration --emitDeclarationOnly --declarationDir dist", "release": "ncc build ./index.ts -o ./dist/ --minify --no-cache --no-source-map-register", "build": "pnpm release && pnpm types", "prepublishOnly": "cd ../../ && turbo run build" diff --git a/packages/next-env/tsconfig.json b/packages/next-env/tsconfig.json index d0e9e223e6a05..bf4c959b79202 100644 --- a/packages/next-env/tsconfig.json +++ b/packages/next-env/tsconfig.json @@ -6,5 +6,7 @@ "resolveJsonModule": true, "esModuleInterop": true, "skipLibCheck": false - } + }, + "include": ["**/*.ts"], + "exclude": ["node_modules", "dist"] } From edf8cc52fc79151f0b57809c09ef5d32cb37c72d Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Mon, 10 Jun 2024 13:31:05 -0700 Subject: [PATCH 13/60] tests: fixed some test types and fixed darwin support (#65722) This fixes some tests so that they can run on macOS that previously had some issues with IPv6 during testing as well as updated some of the tests to use `retry` over `check`. --- .../required-server-files-ppr.test.ts | 7 ++- .../required-server-files.test.ts | 59 +++++++++---------- 2 files changed, 31 insertions(+), 35 deletions(-) diff --git a/test/production/standalone-mode/required-server-files/required-server-files-ppr.test.ts b/test/production/standalone-mode/required-server-files/required-server-files-ppr.test.ts index f7501015d73e0..69e6ab764fb2f 100644 --- a/test/production/standalone-mode/required-server-files/required-server-files-ppr.test.ts +++ b/test/production/standalone-mode/required-server-files/required-server-files-ppr.test.ts @@ -10,11 +10,12 @@ import { initNextServerScript, killApp, } from 'next-test-utils' +import { ChildProcess } from 'child_process' describe('required server files app router', () => { let next: NextInstance - let server - let appPort + let server: ChildProcess + let appPort: number | string let delayedPostpone let rewritePostpone @@ -93,7 +94,7 @@ describe('required server files app router', () => { /- Local:/, { ...process.env, - PORT: appPort, + PORT: `${appPort}`, }, undefined, { diff --git a/test/production/standalone-mode/required-server-files/required-server-files.test.ts b/test/production/standalone-mode/required-server-files/required-server-files.test.ts index 7d5d33a3bb079..934ad318baf82 100644 --- a/test/production/standalone-mode/required-server-files/required-server-files.test.ts +++ b/test/production/standalone-mode/required-server-files/required-server-files.test.ts @@ -12,6 +12,7 @@ import { initNextServerScript, killApp, renderViaHTTP, + retry, waitFor, } from 'next-test-utils' @@ -134,11 +135,21 @@ describe('required server files', () => { }, } ) + + if (process.platform === 'darwin') { + appPort = `http://127.0.0.1:${appPort}` + } } beforeAll(async () => { await setupNext({ nextEnv: true, minimalMode: true }) }) + + beforeEach(() => { + errors = [] + stderr = '' + }) + afterAll(async () => { await next.destroy() if (server) await killApp(server) @@ -958,60 +969,43 @@ describe('required server files', () => { }) it('should bubble error correctly for gip page', async () => { - errors = [] const res = await fetchViaHTTP(appPort, '/errors/gip', { crash: '1' }) expect(res.status).toBe(500) expect(await res.text()).toBe('Internal Server Error') - await check( - () => - errors.join('\n').includes('gip hit an oops') - ? 'success' - : errors.join('\n'), - 'success' - ) + await retry(() => { + expect(errors.join('\n')).toInclude('gip hit an oops') + }) }) it('should bubble error correctly for gssp page', async () => { - errors = [] const res = await fetchViaHTTP(appPort, '/errors/gssp', { crash: '1' }) expect(res.status).toBe(500) expect(await res.text()).toBe('Internal Server Error') - await check( - () => - errors.join('\n').includes('gssp hit an oops') - ? 'success' - : errors.join('\n'), - 'success' - ) + + await retry(() => { + expect(errors.join('\n')).toInclude('gssp hit an oops') + }) }) it('should bubble error correctly for gsp page', async () => { - errors = [] const res = await fetchViaHTTP(appPort, '/errors/gsp/crash') expect(res.status).toBe(500) expect(await res.text()).toBe('Internal Server Error') - await check( - () => - errors.join('\n').includes('gsp hit an oops') - ? 'success' - : errors.join('\n'), - 'success' - ) + + await retry(() => { + expect(errors.join('\n')).toInclude('gsp hit an oops') + }) }) it('should bubble error correctly for API page', async () => { - errors = [] const res = await fetchViaHTTP(appPort, '/api/error') expect(res.status).toBe(500) expect(await res.text()).toBe('Internal Server Error') - await check( - () => - errors.join('\n').includes('some error from /api/error') - ? 'success' - : errors.join('\n'), - 'success' - ) + + await retry(() => { + expect(errors.join('\n')).toInclude('some error from /api/error') + }) }) it('should normalize optional values correctly for SSP page', async () => { @@ -1284,6 +1278,7 @@ describe('required server files', () => { expect(envVariables.envFromHost).toBe('FOOBAR') }) + // FIXME: update to not mutate the global state it('should run middleware correctly (without minimalMode, with wasm)', async () => { const standaloneDir = join(next.testDir, 'standalone') From 78505fcb785f9601c6e5218834479d84237d819f Mon Sep 17 00:00:00 2001 From: Sam Ko Date: Mon, 10 Jun 2024 14:54:56 -0700 Subject: [PATCH 14/60] chore(test): add types to tests (#66724) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Why? Adding types to test—building on this [PR](https://github.com/vercel/next.js/pull/65722). --- .../required-server-files-app.test.ts | 12 ++++++++---- .../required-server-files-i18n.test.ts | 12 +++++++++--- .../required-server-files-ppr.test.ts | 5 ++++- .../required-server-files.test.ts | 9 +++++---- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/test/production/standalone-mode/required-server-files/required-server-files-app.test.ts b/test/production/standalone-mode/required-server-files/required-server-files-app.test.ts index 410fa183b3f1b..e2f45d7a2a70b 100644 --- a/test/production/standalone-mode/required-server-files/required-server-files-app.test.ts +++ b/test/production/standalone-mode/required-server-files/required-server-files-app.test.ts @@ -10,11 +10,12 @@ import { initNextServerScript, killApp, } from 'next-test-utils' +import { ChildProcess } from 'child_process' describe('required server files app router', () => { let next: NextInstance - let server - let appPort + let server: ChildProcess + let appPort: number | string const setupNext = async ({ nextEnv, @@ -83,14 +84,17 @@ describe('required server files app router', () => { /- Local:/, { ...process.env, - PORT: appPort, + PORT: `${appPort}`, }, undefined, { cwd: next.testDir, } ) - appPort = `http://127.0.0.1:${appPort}` + + if (process.platform === 'darwin') { + appPort = `http://127.0.0.1:${appPort}` + } } beforeAll(async () => { diff --git a/test/production/standalone-mode/required-server-files/required-server-files-i18n.test.ts b/test/production/standalone-mode/required-server-files/required-server-files-i18n.test.ts index 12da3649353d7..941bd06e3bcb2 100644 --- a/test/production/standalone-mode/required-server-files/required-server-files-i18n.test.ts +++ b/test/production/standalone-mode/required-server-files/required-server-files-i18n.test.ts @@ -14,11 +14,12 @@ import { waitFor, } from 'next-test-utils' import nodeFetch from 'node-fetch' +import { ChildProcess } from 'child_process' describe('required server files i18n', () => { let next: NextInstance - let server - let appPort + let server: ChildProcess + let appPort: number | string let errors = [] let requiredFilesManifest @@ -117,7 +118,7 @@ describe('required server files i18n', () => { /- Local:/, { ...process.env, - PORT: appPort, + PORT: `${appPort}`, }, undefined, { @@ -127,7 +128,12 @@ describe('required server files i18n', () => { }, } ) + + if (process.platform === 'darwin') { + appPort = `http://127.0.0.1:${appPort}` + } }) + afterAll(async () => { await next.destroy() if (server) await killApp(server) diff --git a/test/production/standalone-mode/required-server-files/required-server-files-ppr.test.ts b/test/production/standalone-mode/required-server-files/required-server-files-ppr.test.ts index 69e6ab764fb2f..06142d7e9a8fe 100644 --- a/test/production/standalone-mode/required-server-files/required-server-files-ppr.test.ts +++ b/test/production/standalone-mode/required-server-files/required-server-files-ppr.test.ts @@ -101,7 +101,10 @@ describe('required server files app router', () => { cwd: next.testDir, } ) - appPort = `http://127.0.0.1:${appPort}` + + if (process.platform === 'darwin') { + appPort = `http://127.0.0.1:${appPort}` + } } beforeAll(async () => { diff --git a/test/production/standalone-mode/required-server-files/required-server-files.test.ts b/test/production/standalone-mode/required-server-files/required-server-files.test.ts index 934ad318baf82..7f457ce3c8593 100644 --- a/test/production/standalone-mode/required-server-files/required-server-files.test.ts +++ b/test/production/standalone-mode/required-server-files/required-server-files.test.ts @@ -15,11 +15,12 @@ import { retry, waitFor, } from 'next-test-utils' +import { ChildProcess } from 'child_process' describe('required server files', () => { let next: NextInstance - let server - let appPort + let server: ChildProcess + let appPort: number | string let errors = [] let stderr = '' let requiredFilesManifest @@ -124,7 +125,7 @@ describe('required server files', () => { { ...process.env, ENV_FROM_HOST: 'FOOBAR', - PORT: appPort, + PORT: `${appPort}`, }, undefined, { @@ -1296,7 +1297,7 @@ describe('required server files', () => { /- Local:/, { ...process.env, - PORT: appPort, + PORT: `${appPort}`, }, undefined, { From 14ec3a288e8c1f30da3eb434855615aba5b0821c Mon Sep 17 00:00:00 2001 From: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com> Date: Mon, 10 Jun 2024 23:45:00 +0100 Subject: [PATCH 15/60] Docs: Update `unstable_after` based on community questions (#66716) --- .../04-functions/unstable_after.mdx | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/docs/02-app/02-api-reference/04-functions/unstable_after.mdx b/docs/02-app/02-api-reference/04-functions/unstable_after.mdx index b1f243f541f25..6d33ddc4ad185 100644 --- a/docs/02-app/02-api-reference/04-functions/unstable_after.mdx +++ b/docs/02-app/02-api-reference/04-functions/unstable_after.mdx @@ -20,6 +20,8 @@ const nextConfig = { module.exports = nextConfig ``` +The function accepts a callback that will be executed after the response is finished: + ```tsx filename="app/layout.tsx switcher import { unstable_after as after } from 'next/server' import { log } from '@/app/utils' @@ -52,11 +54,25 @@ export default function Layout({ children }) { > - `unstable_after()` is a [dynamic function](/docs/app/building-your-application/rendering/server-components#dynamic-functions) that will opt a route into dynamic rendering. This behavior can be overridden with the [`export dynamic = "force-static"`](/docs/app/api-reference/file-conventions/route-segment-config#dynamic) segment config. > - You can use React `cache` to deduplicate functions called inside `unstable_after()`. > - [`cookies()`](/docs/app/api-reference/functions/cookies) cannot be set inside `unstable_after()` since the response has already been sent. +> - `unstable_after()` can be nested inside other `unstable_after()` calls. -### Parameters +## Parameters -- A function that will be executed after the response is finished. +- A callback function which will be executed after the response is finished. -### Returns +## Returns - `unstable_after()` does not return a value. + +## Alternatives + +The use case for `unstable_after()` is to process secondary tasks without blocking the primary response. It's similar to using the platform's [`waitUntil()`](https://vercel.com/docs/functions/functions-api-reference) or removing `await` from a promise, but with the following differences: + +- **[`waitUntil()`]**: accepts promise and enqueues a task to be executed during the lifecycle of the request, whereas `unstable_after()` accepts a callback that will be executed **after** the response is finished. +- **Removing `await`**: starts executing during the response, which uses resources. It's also not reliable in serverless environments as the function stops computation immediately after the response is sent, potentially interrupting the task. + +We recommend using `unstable_after()` as it has been designed to consider other Next.js APIs and contexts. + +## Serverless function duration + +`unstable_after()` will run for the platform's default or configured max duration of a serverless function. If your platform supports it, you can configure the timeout limit using the [`maxDuration`](/docs/app/api-reference/file-conventions/route-segment-config#maxduration) route segment config. From fc03faedfba08df952a21f25d3777ffb6761fa18 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Mon, 10 Jun 2024 23:23:08 +0000 Subject: [PATCH 16/60] v15.0.0-canary.24 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 12 ++++++------ packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 14 +++++++------- 17 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lerna.json b/lerna.json index 94a4e3ec3aa34..ec450eea586cb 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "15.0.0-canary.23" + "version": "15.0.0-canary.24" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index ce007372145a1..77b05e9694d53 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "15.0.0-canary.23", + "version": "15.0.0-canary.24", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index c9a7df2503da0..124ad6b3dff5e 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "15.0.0-canary.23", + "version": "15.0.0-canary.24", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "15.0.0-canary.23", + "@next/eslint-plugin-next": "15.0.0-canary.24", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 50ade39c4c856..73b40f6ad9ae1 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "15.0.0-canary.23", + "version": "15.0.0-canary.24", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 091c04d1b88c5..5541ca4f3b5fc 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "15.0.0-canary.23", + "version": "15.0.0-canary.24", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 7a0b841555df6..3783a84156724 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "15.0.0-canary.23", + "version": "15.0.0-canary.24", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 173c683fc8938..a37de0b5cadbe 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "15.0.0-canary.23", + "version": "15.0.0-canary.24", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 689c30978422e..02439a126ac1e 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "15.0.0-canary.23", + "version": "15.0.0-canary.24", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index e2a86a3798385..1e92ab8d9bc31 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "15.0.0-canary.23", + "version": "15.0.0-canary.24", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 126d047effba2..89b32ab422baf 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "15.0.0-canary.23", + "version": "15.0.0-canary.24", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 0c37743b7b2dd..28c7975ba703c 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "15.0.0-canary.23", + "version": "15.0.0-canary.24", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 747a7d76861d8..44df70682e50b 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "15.0.0-canary.23", + "version": "15.0.0-canary.24", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index c01106d87150b..dbe984313bc31 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "15.0.0-canary.23", + "version": "15.0.0-canary.24", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index c0f8f273e554b..e3801961535e8 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "15.0.0-canary.23", + "version": "15.0.0-canary.24", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -93,7 +93,7 @@ ] }, "dependencies": { - "@next/env": "15.0.0-canary.23", + "@next/env": "15.0.0-canary.24", "@swc/helpers": "0.5.11", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -157,10 +157,10 @@ "@jest/types": "29.5.0", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/polyfill-module": "15.0.0-canary.23", - "@next/polyfill-nomodule": "15.0.0-canary.23", - "@next/react-refresh-utils": "15.0.0-canary.23", - "@next/swc": "15.0.0-canary.23", + "@next/polyfill-module": "15.0.0-canary.24", + "@next/polyfill-nomodule": "15.0.0-canary.24", + "@next/react-refresh-utils": "15.0.0-canary.24", + "@next/swc": "15.0.0-canary.24", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.41.2", "@swc/core": "1.5.7", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 76a39bfffdc7f..6cbe8f4321e28 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "15.0.0-canary.23", + "version": "15.0.0-canary.24", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 25cf5bdeaca50..61578a8281c5a 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "15.0.0-canary.23", + "version": "15.0.0-canary.24", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -26,7 +26,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "15.0.0-canary.23", + "next": "15.0.0-canary.24", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e9a9b538751d0..e9ba53e490b40 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -753,7 +753,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 15.0.0-canary.23 + specifier: 15.0.0-canary.24 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -815,7 +815,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 15.0.0-canary.23 + specifier: 15.0.0-canary.24 version: link:../next-env '@swc/helpers': specifier: 0.5.11 @@ -943,16 +943,16 @@ importers: specifier: 1.2.0 version: 1.2.0 '@next/polyfill-module': - specifier: 15.0.0-canary.23 + specifier: 15.0.0-canary.24 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 15.0.0-canary.23 + specifier: 15.0.0-canary.24 version: link:../next-polyfill-nomodule '@next/react-refresh-utils': - specifier: 15.0.0-canary.23 + specifier: 15.0.0-canary.24 version: link:../react-refresh-utils '@next/swc': - specifier: 15.0.0-canary.23 + specifier: 15.0.0-canary.24 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1576,7 +1576,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 15.0.0-canary.23 + specifier: 15.0.0-canary.24 version: link:../next outdent: specifier: 0.8.0 From fa05f115532c3fc6b5cdb4b14d08e037ee303edb Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:29:49 -0700 Subject: [PATCH 17/60] tweak flaky module-imports test (#66728) This test flakes a _lot_ ([ref](https://github.com/vercel/next.js/actions/runs/9456072960/job/26048162244), [ref](https://github.com/vercel/next.js/actions/runs/9456072960/attempts/2), [ref](https://github.com/vercel/next.js/actions/runs/9456076941/job/26048598801)) likely due to all of the `context` mutation and sharing between tests. This updates the test that fails the most with locally scoped context to flakes introduced by other tests. --- .../test/module-imports.test.js | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/test/integration/edge-runtime-module-errors/test/module-imports.test.js b/test/integration/edge-runtime-module-errors/test/module-imports.test.js index ec253989ccf1e..136cf33fd629e 100644 --- a/test/integration/edge-runtime-module-errors/test/module-imports.test.js +++ b/test/integration/edge-runtime-module-errors/test/module-imports.test.js @@ -21,6 +21,7 @@ import { expectUnsupportedModuleDevError, expectUnsupportedModuleProdError, getUnsupportedModuleWarning, + getModuleNotFound, } from './utils' jest.setTimeout(1000 * 60 * 2) @@ -296,14 +297,29 @@ describe('Edge runtime code with imports', () => { stderr: true, }) expect(stderr).toContain(getUnsupportedModuleWarning(moduleName)) - context.app = await nextStart( - context.appDir, - context.appPort, - appOption - ) - const res = await fetchViaHTTP(context.appPort, url) + + let logs = { stdout: '', stderr: '' } + const port = await findPort() + + const options = { + onStdout(msg) { + logs.output += msg + logs.stdout += msg + }, + onStderr(msg) { + logs.output += msg + logs.stderr += msg + }, + } + + await nextStart(context.appDir, port, options) + const res = await fetchViaHTTP(port, url) expect(res.status).toBe(200) - expectNoError(moduleName) + + expect(logs.output).not.toContain( + getUnsupportedModuleWarning(moduleName) + ) + expect(logs.output).not.toContain(getModuleNotFound(moduleName)) }) } ) From 0e582a9b59ad3a30031fd9d1b8148eabbeacbc19 Mon Sep 17 00:00:00 2001 From: Ivan Torres <40922354+torresgol10@users.noreply.github.com> Date: Tue, 11 Jun 2024 01:45:06 +0200 Subject: [PATCH 18/60] Update devdependecy @types/node (#66725) Update DevDependecy to the last version: @types/node@20.14.2 Co-authored-by: torresgol10.itd --- packages/create-next-app/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 77b05e9694d53..1953229936705 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -32,7 +32,7 @@ "@types/async-retry": "1.4.2", "@types/ci-info": "2.0.0", "@types/cross-spawn": "6.0.0", - "@types/node": "^20.12.3", + "@types/node": "20.14.2", "@types/prompts": "2.4.2", "@types/tar": "6.1.13", "@types/validate-npm-package-name": "4.0.2", From 7b97f30c40bff16e2e4ec5f81fbe1b839548b090 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Mon, 10 Jun 2024 17:04:33 -0700 Subject: [PATCH 19/60] Revert "Fix esm property def in flight loader" (#66727) This is causing unexpected errors. Reverts vercel/next.js#66286 --- .../webpack/loaders/next-flight-loader/index.ts | 17 +++++++---------- .../src/shared/lib/lazy-dynamic/loadable.tsx | 2 +- .../app-routes-client-component.test.ts | 10 ++++++---- .../dynamic/app/dynamic/named-export/page.js | 2 +- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/next/src/build/webpack/loaders/next-flight-loader/index.ts b/packages/next/src/build/webpack/loaders/next-flight-loader/index.ts index 46d6b0ede8142..79a0ae48ef6ea 100644 --- a/packages/next/src/build/webpack/loaders/next-flight-loader/index.ts +++ b/packages/next/src/build/webpack/loaders/next-flight-loader/index.ts @@ -97,24 +97,21 @@ export default function transformSource( return } - // `proxy` is the module proxy that we treat the module as a client boundary. - // For ESM, we access the property of the module proxy directly for each export. - // This is bit hacky that treating using a CJS like module proxy for ESM's exports, - // but this will avoid creating nested proxies for each export. It will be improved in the future. let esmSource = `\ import { createProxy } from "${MODULE_PROXY_PATH}" - -const proxy = createProxy(String.raw\`${resourceKey}\`) ` let cnt = 0 for (const ref of clientRefs) { if (ref === '') { - esmSource += `exports[''] = proxy['']\n` + esmSource += `\nexports[''] = createProxy(String.raw\`${resourceKey}#\`);` } else if (ref === 'default') { - esmSource += `export default createProxy(String.raw\`${resourceKey}#default\`);\n` + esmSource += `\ +export default createProxy(String.raw\`${resourceKey}#default\`); +` } else { - esmSource += `const e${cnt} = proxy["${ref}"];\n` - esmSource += `export { e${cnt++} as ${ref} };\n` + esmSource += ` +const e${cnt} = createProxy(String.raw\`${resourceKey}#${ref}\`); +export { e${cnt++} as ${ref} };` } } diff --git a/packages/next/src/shared/lib/lazy-dynamic/loadable.tsx b/packages/next/src/shared/lib/lazy-dynamic/loadable.tsx index 5950b1d82ce2f..31b6e459e93d8 100644 --- a/packages/next/src/shared/lib/lazy-dynamic/loadable.tsx +++ b/packages/next/src/shared/lib/lazy-dynamic/loadable.tsx @@ -15,7 +15,7 @@ function convertModule

( // Cases: // mod: { default: Component } // mod: Component - // mod: { default: proxy(Component) } + // mod: { $$typeof, default: proxy(Component) } // mod: proxy(Component) const hasDefault = mod && 'default' in mod return { diff --git a/test/e2e/app-dir/app-routes-client-component/app-routes-client-component.test.ts b/test/e2e/app-dir/app-routes-client-component/app-routes-client-component.test.ts index b0a5079ac0a64..a98b19ff6eb37 100644 --- a/test/e2e/app-dir/app-routes-client-component/app-routes-client-component.test.ts +++ b/test/e2e/app-dir/app-routes-client-component/app-routes-client-component.test.ts @@ -1,14 +1,16 @@ -import { nextTestSetup } from 'e2e-utils' +import { FileRef, nextTestSetup } from 'e2e-utils' +import path from 'path' describe('referencing a client component in an app route', () => { const { next } = nextTestSetup({ - files: __dirname, + files: new FileRef(path.join(__dirname)), }) it('responds without error', async () => { expect(JSON.parse(await next.render('/runtime'))).toEqual({ - clientComponent: 'function', - myModuleClientComponent: 'function', + // Turbopack's proxy components are functions + clientComponent: process.env.TURBOPACK ? 'function' : 'object', + myModuleClientComponent: process.env.TURBOPACK ? 'function' : 'object', }) }) }) diff --git a/test/e2e/app-dir/dynamic/app/dynamic/named-export/page.js b/test/e2e/app-dir/dynamic/app/dynamic/named-export/page.js index 3285b72c5f559..b767273ab6077 100644 --- a/test/e2e/app-dir/dynamic/app/dynamic/named-export/page.js +++ b/test/e2e/app-dir/dynamic/app/dynamic/named-export/page.js @@ -2,7 +2,7 @@ import dynamic from 'next/dynamic' const Button = dynamic(() => import('./client').then((mod) => { - return { default: mod.Button } + return mod.Button }) ) From e01d52abe6c53fda450366665e30c7bc4dfcf1c2 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Mon, 10 Jun 2024 17:06:12 -0700 Subject: [PATCH 20/60] Update React from `1df34bdf62` to `6230622a1a` (#66726)

React upstream changes - https://github.com/facebook/react/pull/29835
--- package.json | 32 +- .../cjs/react-dom-client.development.js | 64 ++-- .../cjs/react-dom-client.production.js | 105 +++--- .../cjs/react-dom-profiling.development.js | 64 ++-- .../cjs/react-dom-profiling.profiling.js | 105 +++--- ...t-dom-server-legacy.browser.development.js | 4 +- ...ct-dom-server-legacy.browser.production.js | 6 +- ...eact-dom-server-legacy.node.development.js | 4 +- ...react-dom-server-legacy.node.production.js | 6 +- .../react-dom-server.browser.development.js | 4 +- .../react-dom-server.browser.production.js | 10 +- .../cjs/react-dom-server.bun.production.js | 10 +- .../cjs/react-dom-server.edge.development.js | 4 +- .../cjs/react-dom-server.edge.production.js | 10 +- .../cjs/react-dom-server.node.development.js | 4 +- .../cjs/react-dom-server.node.production.js | 10 +- .../react-dom-unstable_testing.development.js | 64 ++-- .../react-dom-unstable_testing.production.js | 105 +++--- .../cjs/react-dom.development.js | 2 +- .../cjs/react-dom.production.js | 2 +- .../cjs/react-dom.react-server.development.js | 2 +- .../cjs/react-dom.react-server.production.js | 2 +- .../react-dom-experimental/package.json | 4 +- .../cjs/react-dom-client.development.js | 64 ++-- .../cjs/react-dom-client.production.js | 105 +++--- .../cjs/react-dom-profiling.development.js | 64 ++-- .../cjs/react-dom-profiling.profiling.js | 105 +++--- ...t-dom-server-legacy.browser.development.js | 4 +- ...ct-dom-server-legacy.browser.production.js | 6 +- ...eact-dom-server-legacy.node.development.js | 4 +- ...react-dom-server-legacy.node.production.js | 6 +- .../react-dom-server.browser.development.js | 4 +- .../react-dom-server.browser.production.js | 10 +- .../cjs/react-dom-server.bun.production.js | 10 +- .../cjs/react-dom-server.edge.development.js | 4 +- .../cjs/react-dom-server.edge.production.js | 10 +- .../cjs/react-dom-server.node.development.js | 4 +- .../cjs/react-dom-server.node.production.js | 10 +- .../react-dom/cjs/react-dom.development.js | 2 +- .../react-dom/cjs/react-dom.production.js | 2 +- .../cjs/react-dom.react-server.development.js | 2 +- .../cjs/react-dom.react-server.production.js | 2 +- .../next/src/compiled/react-dom/package.json | 4 +- .../cjs/react.development.js | 2 +- .../cjs/react.production.js | 2 +- .../cjs/react.react-server.development.js | 2 +- .../cjs/react.react-server.production.js | 2 +- .../next/src/compiled/react-is/package.json | 2 +- .../package.json | 4 +- .../react-server-dom-turbopack/package.json | 4 +- .../package.json | 4 +- .../react-server-dom-webpack/package.json | 4 +- .../compiled/react/cjs/react.development.js | 2 +- .../compiled/react/cjs/react.production.js | 2 +- .../cjs/react.react-server.development.js | 2 +- .../cjs/react.react-server.production.js | 2 +- .../next/src/compiled/unistore/unistore.js | 2 +- pnpm-lock.yaml | 308 +++++++++--------- test/.stats-app/package.json | 6 +- 59 files changed, 740 insertions(+), 655 deletions(-) diff --git a/package.json b/package.json index 4ebdbf04f7c66..07c9d84f46acd 100644 --- a/package.json +++ b/package.json @@ -197,18 +197,18 @@ "pretty-bytes": "5.3.0", "pretty-ms": "7.0.0", "random-seed": "0.3.0", - "react": "19.0.0-rc-1df34bdf62-20240605", + "react": "19.0.0-rc-6230622a1a-20240610", "react-17": "npm:react@17.0.2", - "react-builtin": "npm:react@19.0.0-rc-1df34bdf62-20240605", - "react-dom": "19.0.0-rc-1df34bdf62-20240605", + "react-builtin": "npm:react@19.0.0-rc-6230622a1a-20240610", + "react-dom": "19.0.0-rc-6230622a1a-20240610", "react-dom-17": "npm:react-dom@17.0.2", - "react-dom-builtin": "npm:react-dom@19.0.0-rc-1df34bdf62-20240605", - "react-dom-experimental-builtin": "npm:react-dom@0.0.0-experimental-1df34bdf62-20240605", - "react-experimental-builtin": "npm:react@0.0.0-experimental-1df34bdf62-20240605", - "react-server-dom-turbopack": "19.0.0-rc-1df34bdf62-20240605", - "react-server-dom-turbopack-experimental": "npm:react-server-dom-turbopack@0.0.0-experimental-1df34bdf62-20240605", - "react-server-dom-webpack": "19.0.0-rc-1df34bdf62-20240605", - "react-server-dom-webpack-experimental": "npm:react-server-dom-webpack@0.0.0-experimental-1df34bdf62-20240605", + "react-dom-builtin": "npm:react-dom@19.0.0-rc-6230622a1a-20240610", + "react-dom-experimental-builtin": "npm:react-dom@0.0.0-experimental-6230622a1a-20240610", + "react-experimental-builtin": "npm:react@0.0.0-experimental-6230622a1a-20240610", + "react-server-dom-turbopack": "19.0.0-rc-6230622a1a-20240610", + "react-server-dom-turbopack-experimental": "npm:react-server-dom-turbopack@0.0.0-experimental-6230622a1a-20240610", + "react-server-dom-webpack": "19.0.0-rc-6230622a1a-20240610", + "react-server-dom-webpack-experimental": "npm:react-server-dom-webpack@0.0.0-experimental-6230622a1a-20240610", "react-ssr-prepass": "1.0.8", "react-virtualized": "9.22.3", "relay-compiler": "13.0.2", @@ -218,8 +218,8 @@ "resolve-from": "5.0.0", "sass": "1.54.0", "satori": "0.10.9", - "scheduler-builtin": "npm:scheduler@0.25.0-rc-1df34bdf62-20240605", - "scheduler-experimental-builtin": "npm:scheduler@0.0.0-experimental-1df34bdf62-20240605", + "scheduler-builtin": "npm:scheduler@0.25.0-rc-6230622a1a-20240610", + "scheduler-experimental-builtin": "npm:scheduler@0.0.0-experimental-6230622a1a-20240610", "seedrandom": "3.0.5", "semver": "7.3.7", "shell-quote": "1.7.3", @@ -253,10 +253,10 @@ "@babel/traverse": "7.22.5", "@types/react": "npm:types-react@19.0.0-rc.0", "@types/react-dom": "npm:types-react-dom@19.0.0-rc.0", - "react": "19.0.0-rc-1df34bdf62-20240605", - "react-dom": "19.0.0-rc-1df34bdf62-20240605", - "react-is": "19.0.0-rc-1df34bdf62-20240605", - "scheduler": "0.25.0-rc-1df34bdf62-20240605" + "react": "19.0.0-rc-6230622a1a-20240610", + "react-dom": "19.0.0-rc-6230622a1a-20240610", + "react-is": "19.0.0-rc-6230622a1a-20240610", + "scheduler": "0.25.0-rc-6230622a1a-20240610" }, "engines": { "node": ">=18.17.0", diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.development.js index 878f0bf3d1eb2..b1262973216c8 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.development.js @@ -35848,8 +35848,25 @@ function getResource(type, currentProps, pendingProps, currentResource) { _styles.set(_key, _resource); + var instance = ownerDocument.querySelector(getStylesheetSelectorFromKey(_key)); + + if (instance) { + var loadingState = instance._p; + + if (loadingState) ; else { + // This instance is already loaded + _resource.instance = instance; + _resource.state.loading = Loaded | Inserted; + } + } + if (!preloadPropsMap.has(_key)) { - preloadStylesheet(ownerDocument, _key, preloadPropsFromStylesheet(qualifiedProps), _resource.state); + var preloadProps = preloadPropsFromStylesheet(qualifiedProps); + preloadPropsMap.set(_key, preloadProps); + + if (!instance) { + preloadStylesheet(ownerDocument, _key, preloadProps, _resource.state); + } } } @@ -35996,31 +36013,24 @@ function stylesheetPropsFromRawProps(rawProps) { } function preloadStylesheet(ownerDocument, key, preloadProps, state) { - preloadPropsMap.set(key, preloadProps); - - if (!ownerDocument.querySelector(getStylesheetSelectorFromKey(key))) { - // There is no matching stylesheet instance in the Document. - // We will insert a preload now to kick off loading because - // we expect this stylesheet to commit - var preloadEl = ownerDocument.querySelector(getPreloadStylesheetSelectorFromKey(key)); - - if (preloadEl) { - // If we find a preload already it was SSR'd and we won't have an actual - // loading state to track. For now we will just assume it is loaded - state.loading = Loaded; - } else { - var instance = ownerDocument.createElement('link'); - state.preload = instance; - instance.addEventListener('load', function () { - return state.loading |= Loaded; - }); - instance.addEventListener('error', function () { - return state.loading |= Errored; - }); - setInitialProperties(instance, 'link', preloadProps); - markNodeAsHoistable(instance); - ownerDocument.head.appendChild(instance); - } + var preloadEl = ownerDocument.querySelector(getPreloadStylesheetSelectorFromKey(key)); + + if (preloadEl) { + // If we find a preload already it was SSR'd and we won't have an actual + // loading state to track. For now we will just assume it is loaded + state.loading = Loaded; + } else { + var instance = ownerDocument.createElement('link'); + state.preload = instance; + instance.addEventListener('load', function () { + return state.loading |= Loaded; + }); + instance.addEventListener('error', function () { + return state.loading |= Errored; + }); + setInitialProperties(instance, 'link', preloadProps); + markNodeAsHoistable(instance); + ownerDocument.head.appendChild(instance); } } @@ -36888,7 +36898,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-experimental-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; // Might add PROFILE later. diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.production.js index ca9c12e9cc76d..2543bedce9385 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.production.js @@ -13569,20 +13569,20 @@ function getResource(type, currentProps, pendingProps, currentResource) { case "style": return "string" === typeof pendingProps.precedence && "string" === typeof pendingProps.href - ? ((pendingProps = getStyleKey(pendingProps.href)), - (JSCompiler_inline_result = getResourcesFromRoot( + ? ((currentProps = getStyleKey(pendingProps.href)), + (pendingProps = getResourcesFromRoot( JSCompiler_inline_result ).hoistableStyles), - (currentProps = JSCompiler_inline_result.get(pendingProps)), - currentProps || - ((currentProps = { + (currentResource = pendingProps.get(currentProps)), + currentResource || + ((currentResource = { type: "style", instance: null, count: 0, state: null }), - JSCompiler_inline_result.set(pendingProps, currentProps)), - currentProps) + pendingProps.set(currentProps, currentResource)), + currentResource) : { type: "void", instance: null, count: 0, state: null }; case "link": if ( @@ -13605,22 +13605,31 @@ function getResource(type, currentProps, pendingProps, currentResource) { state: { loading: 0, preload: null } }), styles$231.set(type, resource$232), + (styles$231 = JSCompiler_inline_result.querySelector( + getStylesheetSelectorFromKey(type) + )) && + !styles$231._p && + ((resource$232.instance = styles$231), + (resource$232.state.loading = 5)), preloadPropsMap.has(type) || - preloadStylesheet( - JSCompiler_inline_result, - type, - { - rel: "preload", - as: "style", - href: pendingProps.href, - crossOrigin: pendingProps.crossOrigin, - integrity: pendingProps.integrity, - media: pendingProps.media, - hrefLang: pendingProps.hrefLang, - referrerPolicy: pendingProps.referrerPolicy - }, - resource$232.state - )); + ((pendingProps = { + rel: "preload", + as: "style", + href: pendingProps.href, + crossOrigin: pendingProps.crossOrigin, + integrity: pendingProps.integrity, + media: pendingProps.media, + hrefLang: pendingProps.hrefLang, + referrerPolicy: pendingProps.referrerPolicy + }), + preloadPropsMap.set(type, pendingProps), + styles$231 || + preloadStylesheet( + JSCompiler_inline_result, + type, + pendingProps, + resource$232.state + ))); if (currentProps && null === currentResource) throw Error(formatProdErrorMessage(528, "")); return resource$232; @@ -13636,20 +13645,20 @@ function getResource(type, currentProps, pendingProps, currentResource) { currentProps && "function" !== typeof currentProps && "symbol" !== typeof currentProps - ? ((pendingProps = getScriptKey(pendingProps)), - (JSCompiler_inline_result = getResourcesFromRoot( + ? ((currentProps = getScriptKey(pendingProps)), + (pendingProps = getResourcesFromRoot( JSCompiler_inline_result ).hoistableScripts), - (currentProps = JSCompiler_inline_result.get(pendingProps)), - currentProps || - ((currentProps = { + (currentResource = pendingProps.get(currentProps)), + currentResource || + ((currentResource = { type: "script", instance: null, count: 0, state: null }), - JSCompiler_inline_result.set(pendingProps, currentProps)), - currentProps) + pendingProps.set(currentProps, currentResource)), + currentResource) : { type: "void", instance: null, count: 0, state: null } ); default: @@ -13669,21 +13678,19 @@ function stylesheetPropsFromRawProps(rawProps) { }); } function preloadStylesheet(ownerDocument, key, preloadProps, state) { - preloadPropsMap.set(key, preloadProps); - ownerDocument.querySelector(getStylesheetSelectorFromKey(key)) || - (ownerDocument.querySelector('link[rel="preload"][as="style"][' + key + "]") - ? (state.loading = 1) - : ((key = ownerDocument.createElement("link")), - (state.preload = key), - key.addEventListener("load", function () { - return (state.loading |= 1); - }), - key.addEventListener("error", function () { - return (state.loading |= 2); - }), - setInitialProperties(key, "link", preloadProps), - markNodeAsHoistable(key), - ownerDocument.head.appendChild(key))); + ownerDocument.querySelector('link[rel="preload"][as="style"][' + key + "]") + ? (state.loading = 1) + : ((key = ownerDocument.createElement("link")), + (state.preload = key), + key.addEventListener("load", function () { + return (state.loading |= 1); + }), + key.addEventListener("error", function () { + return (state.loading |= 2); + }), + setInitialProperties(key, "link", preloadProps), + markNodeAsHoistable(key), + ownerDocument.head.appendChild(key)); } function getScriptKey(src) { return '[src="' + escapeSelectorAttributeValueInsideDoubleQuotes(src) + '"]'; @@ -14782,14 +14789,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) { }; var isomorphicReactPackageVersion$jscomp$inline_1631 = React.version; if ( - "19.0.0-experimental-1df34bdf62-20240605" !== + "19.0.0-experimental-6230622a1a-20240610" !== isomorphicReactPackageVersion$jscomp$inline_1631 ) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion$jscomp$inline_1631, - "19.0.0-experimental-1df34bdf62-20240605" + "19.0.0-experimental-6230622a1a-20240610" ) ); ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { @@ -14808,7 +14815,7 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { var devToolsConfig$jscomp$inline_1638 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "19.0.0-experimental-1df34bdf62-20240605", + version: "19.0.0-experimental-6230622a1a-20240610", rendererPackageName: "react-dom" }; var internals$jscomp$inline_2016 = { @@ -14838,7 +14845,7 @@ var internals$jscomp$inline_2016 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-experimental-1df34bdf62-20240605" + reconcilerVersion: "19.0.0-experimental-6230622a1a-20240610" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_2017 = __REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -14944,4 +14951,4 @@ exports.hydrateRoot = function (container, initialChildren, options) { listenToAllSupportedEvents(container); return new ReactDOMHydrationRoot(initialChildren); }; -exports.version = "19.0.0-experimental-1df34bdf62-20240605"; +exports.version = "19.0.0-experimental-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.development.js index a95facdb76834..574227c795ee7 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.development.js @@ -35896,8 +35896,25 @@ function getResource(type, currentProps, pendingProps, currentResource) { _styles.set(_key, _resource); + var instance = ownerDocument.querySelector(getStylesheetSelectorFromKey(_key)); + + if (instance) { + var loadingState = instance._p; + + if (loadingState) ; else { + // This instance is already loaded + _resource.instance = instance; + _resource.state.loading = Loaded | Inserted; + } + } + if (!preloadPropsMap.has(_key)) { - preloadStylesheet(ownerDocument, _key, preloadPropsFromStylesheet(qualifiedProps), _resource.state); + var preloadProps = preloadPropsFromStylesheet(qualifiedProps); + preloadPropsMap.set(_key, preloadProps); + + if (!instance) { + preloadStylesheet(ownerDocument, _key, preloadProps, _resource.state); + } } } @@ -36044,31 +36061,24 @@ function stylesheetPropsFromRawProps(rawProps) { } function preloadStylesheet(ownerDocument, key, preloadProps, state) { - preloadPropsMap.set(key, preloadProps); - - if (!ownerDocument.querySelector(getStylesheetSelectorFromKey(key))) { - // There is no matching stylesheet instance in the Document. - // We will insert a preload now to kick off loading because - // we expect this stylesheet to commit - var preloadEl = ownerDocument.querySelector(getPreloadStylesheetSelectorFromKey(key)); - - if (preloadEl) { - // If we find a preload already it was SSR'd and we won't have an actual - // loading state to track. For now we will just assume it is loaded - state.loading = Loaded; - } else { - var instance = ownerDocument.createElement('link'); - state.preload = instance; - instance.addEventListener('load', function () { - return state.loading |= Loaded; - }); - instance.addEventListener('error', function () { - return state.loading |= Errored; - }); - setInitialProperties(instance, 'link', preloadProps); - markNodeAsHoistable(instance); - ownerDocument.head.appendChild(instance); - } + var preloadEl = ownerDocument.querySelector(getPreloadStylesheetSelectorFromKey(key)); + + if (preloadEl) { + // If we find a preload already it was SSR'd and we won't have an actual + // loading state to track. For now we will just assume it is loaded + state.loading = Loaded; + } else { + var instance = ownerDocument.createElement('link'); + state.preload = instance; + instance.addEventListener('load', function () { + return state.loading |= Loaded; + }); + instance.addEventListener('error', function () { + return state.loading |= Errored; + }); + setInitialProperties(instance, 'link', preloadProps); + markNodeAsHoistable(instance); + ownerDocument.head.appendChild(instance); } } @@ -36936,7 +36946,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-experimental-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; function createPortal$1(children, containerInfo, // TODO: figure out the API for cross-renderer implementation. implementation) { diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.profiling.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.profiling.js index 40806315323ea..869e063e75513 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.profiling.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.profiling.js @@ -14260,20 +14260,20 @@ function getResource(type, currentProps, pendingProps, currentResource) { case "style": return "string" === typeof pendingProps.precedence && "string" === typeof pendingProps.href - ? ((pendingProps = getStyleKey(pendingProps.href)), - (JSCompiler_inline_result = getResourcesFromRoot( + ? ((currentProps = getStyleKey(pendingProps.href)), + (pendingProps = getResourcesFromRoot( JSCompiler_inline_result ).hoistableStyles), - (currentProps = JSCompiler_inline_result.get(pendingProps)), - currentProps || - ((currentProps = { + (currentResource = pendingProps.get(currentProps)), + currentResource || + ((currentResource = { type: "style", instance: null, count: 0, state: null }), - JSCompiler_inline_result.set(pendingProps, currentProps)), - currentProps) + pendingProps.set(currentProps, currentResource)), + currentResource) : { type: "void", instance: null, count: 0, state: null }; case "link": if ( @@ -14296,22 +14296,31 @@ function getResource(type, currentProps, pendingProps, currentResource) { state: { loading: 0, preload: null } }), styles$251.set(type, resource$252), + (styles$251 = JSCompiler_inline_result.querySelector( + getStylesheetSelectorFromKey(type) + )) && + !styles$251._p && + ((resource$252.instance = styles$251), + (resource$252.state.loading = 5)), preloadPropsMap.has(type) || - preloadStylesheet( - JSCompiler_inline_result, - type, - { - rel: "preload", - as: "style", - href: pendingProps.href, - crossOrigin: pendingProps.crossOrigin, - integrity: pendingProps.integrity, - media: pendingProps.media, - hrefLang: pendingProps.hrefLang, - referrerPolicy: pendingProps.referrerPolicy - }, - resource$252.state - )); + ((pendingProps = { + rel: "preload", + as: "style", + href: pendingProps.href, + crossOrigin: pendingProps.crossOrigin, + integrity: pendingProps.integrity, + media: pendingProps.media, + hrefLang: pendingProps.hrefLang, + referrerPolicy: pendingProps.referrerPolicy + }), + preloadPropsMap.set(type, pendingProps), + styles$251 || + preloadStylesheet( + JSCompiler_inline_result, + type, + pendingProps, + resource$252.state + ))); if (currentProps && null === currentResource) throw Error(formatProdErrorMessage(528, "")); return resource$252; @@ -14327,20 +14336,20 @@ function getResource(type, currentProps, pendingProps, currentResource) { currentProps && "function" !== typeof currentProps && "symbol" !== typeof currentProps - ? ((pendingProps = getScriptKey(pendingProps)), - (JSCompiler_inline_result = getResourcesFromRoot( + ? ((currentProps = getScriptKey(pendingProps)), + (pendingProps = getResourcesFromRoot( JSCompiler_inline_result ).hoistableScripts), - (currentProps = JSCompiler_inline_result.get(pendingProps)), - currentProps || - ((currentProps = { + (currentResource = pendingProps.get(currentProps)), + currentResource || + ((currentResource = { type: "script", instance: null, count: 0, state: null }), - JSCompiler_inline_result.set(pendingProps, currentProps)), - currentProps) + pendingProps.set(currentProps, currentResource)), + currentResource) : { type: "void", instance: null, count: 0, state: null } ); default: @@ -14360,21 +14369,19 @@ function stylesheetPropsFromRawProps(rawProps) { }); } function preloadStylesheet(ownerDocument, key, preloadProps, state) { - preloadPropsMap.set(key, preloadProps); - ownerDocument.querySelector(getStylesheetSelectorFromKey(key)) || - (ownerDocument.querySelector('link[rel="preload"][as="style"][' + key + "]") - ? (state.loading = 1) - : ((key = ownerDocument.createElement("link")), - (state.preload = key), - key.addEventListener("load", function () { - return (state.loading |= 1); - }), - key.addEventListener("error", function () { - return (state.loading |= 2); - }), - setInitialProperties(key, "link", preloadProps), - markNodeAsHoistable(key), - ownerDocument.head.appendChild(key))); + ownerDocument.querySelector('link[rel="preload"][as="style"][' + key + "]") + ? (state.loading = 1) + : ((key = ownerDocument.createElement("link")), + (state.preload = key), + key.addEventListener("load", function () { + return (state.loading |= 1); + }), + key.addEventListener("error", function () { + return (state.loading |= 2); + }), + setInitialProperties(key, "link", preloadProps), + markNodeAsHoistable(key), + ownerDocument.head.appendChild(key)); } function getScriptKey(src) { return '[src="' + escapeSelectorAttributeValueInsideDoubleQuotes(src) + '"]'; @@ -15492,14 +15499,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) { }; var isomorphicReactPackageVersion$jscomp$inline_1719 = React.version; if ( - "19.0.0-experimental-1df34bdf62-20240605" !== + "19.0.0-experimental-6230622a1a-20240610" !== isomorphicReactPackageVersion$jscomp$inline_1719 ) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion$jscomp$inline_1719, - "19.0.0-experimental-1df34bdf62-20240605" + "19.0.0-experimental-6230622a1a-20240610" ) ); ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { @@ -15518,7 +15525,7 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { var devToolsConfig$jscomp$inline_1726 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "19.0.0-experimental-1df34bdf62-20240605", + version: "19.0.0-experimental-6230622a1a-20240610", rendererPackageName: "react-dom" }; (function (internals) { @@ -15561,7 +15568,7 @@ var devToolsConfig$jscomp$inline_1726 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-experimental-1df34bdf62-20240605" + reconcilerVersion: "19.0.0-experimental-6230622a1a-20240610" }); function noop() {} function getCrossOriginStringAs(as, input) { @@ -15815,7 +15822,7 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactSharedInternals.H.useHostTransitionStatus(); }; -exports.version = "19.0.0-experimental-1df34bdf62-20240605"; +exports.version = "19.0.0-experimental-6230622a1a-20240610"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.development.js index bff1234e7c701..50f3351789139 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.development.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react-experimental"); var ReactDOM = require('react-dom'); -var ReactVersion = '19.0.0-experimental-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; @@ -1941,7 +1941,7 @@ function sanitizeURL(url) { // Run `yarn generate-inline-fizz-runtime` to generate. var clientRenderBoundary = '$RX=function(b,c,d,e,f){var a=document.getElementById(b);a&&(b=a.previousSibling,b.data="$!",a=a.dataset,c&&(a.dgst=c),d&&(a.msg=d),e&&(a.stck=e),f&&(a.cstck=f),b._reactRetry&&b._reactRetry())};'; var completeBoundary = '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};'; -var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};'; +var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};'; var completeSegment = '$RS=function(a,b){a=document.getElementById(a);b=document.getElementById(b);for(a.parentNode.removeChild(a);a.firstChild;)b.parentNode.insertBefore(a.firstChild,b);b.parentNode.removeChild(b)};'; var formReplaying = 'addEventListener("submit",function(a){if(!a.defaultPrevented){var c=a.target,d=a.submitter,e=c.action,b=d;if(d){var f=d.getAttribute("formAction");null!=f&&(e=f,b=null)}"javascript:throw new Error(\'React form unexpectedly submitted.\')"===e&&(a.preventDefault(),b?(a=document.createElement("input"),a.name=b.name,a.value=b.value,b.parentNode.insertBefore(a,b),b=new FormData(c),a.parentNode.removeChild(a)):b=new FormData(c),a=c.ownerDocument||c,(a.$$reactFormReplay=a.$$reactFormReplay||[]).push(c,d,b))}});'; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.production.js index 8b5a9ae0fe69a..23065ec2d9ee9 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.production.js @@ -5442,12 +5442,12 @@ function flushCompletedBoundary(request, destination, boundary) { ? 0 === (completedSegments.instructions & 2) ? ((completedSegments.instructions |= 10), destination.push( - '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' )) : 0 === (completedSegments.instructions & 8) ? ((completedSegments.instructions |= 8), destination.push( - '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' )) : destination.push('$RR("') : 0 === (completedSegments.instructions & 2) @@ -5863,4 +5863,4 @@ exports.renderToString = function (children, options) { 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server' ); }; -exports.version = "19.0.0-experimental-1df34bdf62-20240605"; +exports.version = "19.0.0-experimental-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.development.js index 64ba8d9c55e1e..1b311e7bace6d 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.development.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react-experimental"); var ReactDOM = require('react-dom'); -var ReactVersion = '19.0.0-experimental-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; @@ -1941,7 +1941,7 @@ function sanitizeURL(url) { // Run `yarn generate-inline-fizz-runtime` to generate. var clientRenderBoundary = '$RX=function(b,c,d,e,f){var a=document.getElementById(b);a&&(b=a.previousSibling,b.data="$!",a=a.dataset,c&&(a.dgst=c),d&&(a.msg=d),e&&(a.stck=e),f&&(a.cstck=f),b._reactRetry&&b._reactRetry())};'; var completeBoundary = '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};'; -var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};'; +var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};'; var completeSegment = '$RS=function(a,b){a=document.getElementById(a);b=document.getElementById(b);for(a.parentNode.removeChild(a);a.firstChild;)b.parentNode.insertBefore(a.firstChild,b);b.parentNode.removeChild(b)};'; var formReplaying = 'addEventListener("submit",function(a){if(!a.defaultPrevented){var c=a.target,d=a.submitter,e=c.action,b=d;if(d){var f=d.getAttribute("formAction");null!=f&&(e=f,b=null)}"javascript:throw new Error(\'React form unexpectedly submitted.\')"===e&&(a.preventDefault(),b?(a=document.createElement("input"),a.name=b.name,a.value=b.value,b.parentNode.insertBefore(a,b),b=new FormData(c),a.parentNode.removeChild(a)):b=new FormData(c),a=c.ownerDocument||c,(a.$$reactFormReplay=a.$$reactFormReplay||[]).push(c,d,b))}});'; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.production.js index 73b225d2a0035..080b75226badb 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.production.js @@ -5531,12 +5531,12 @@ function flushCompletedBoundary(request, destination, boundary) { ? 0 === (completedSegments.instructions & 2) ? ((completedSegments.instructions |= 10), destination.push( - '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' )) : 0 === (completedSegments.instructions & 8) ? ((completedSegments.instructions |= 8), destination.push( - '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' )) : destination.push('$RR("') : 0 === (completedSegments.instructions & 2) @@ -5959,4 +5959,4 @@ exports.renderToString = function (children, options) { 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToPipeableStream" which supports Suspense on the server' ); }; -exports.version = "19.0.0-experimental-1df34bdf62-20240605"; +exports.version = "19.0.0-experimental-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.development.js index 73e35cb9878fb..47ac3fa761a15 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.development.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react-experimental"); var ReactDOM = require('react-dom'); -var reactDOMPackageVersion = '19.0.0-experimental-1df34bdf62-20240605'; +var reactDOMPackageVersion = '19.0.0-experimental-6230622a1a-20240610'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; @@ -2016,7 +2016,7 @@ function sanitizeURL(url) { // Run `yarn generate-inline-fizz-runtime` to generate. var clientRenderBoundary = '$RX=function(b,c,d,e,f){var a=document.getElementById(b);a&&(b=a.previousSibling,b.data="$!",a=a.dataset,c&&(a.dgst=c),d&&(a.msg=d),e&&(a.stck=e),f&&(a.cstck=f),b._reactRetry&&b._reactRetry())};'; var completeBoundary = '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};'; -var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};'; +var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};'; var completeSegment = '$RS=function(a,b){a=document.getElementById(a);b=document.getElementById(b);for(a.parentNode.removeChild(a);a.firstChild;)b.parentNode.insertBefore(a.firstChild,b);b.parentNode.removeChild(b)};'; var formReplaying = 'addEventListener("submit",function(a){if(!a.defaultPrevented){var c=a.target,d=a.submitter,e=c.action,b=d;if(d){var f=d.getAttribute("formAction");null!=f&&(e=f,b=null)}"javascript:throw new Error(\'React form unexpectedly submitted.\')"===e&&(a.preventDefault(),b?(a=document.createElement("input"),a.name=b.name,a.value=b.value,b.parentNode.insertBefore(a,b),b=new FormData(c),a.parentNode.removeChild(a)):b=new FormData(c),a=c.ownerDocument||c,(a.$$reactFormReplay=a.$$reactFormReplay||[]).push(c,d,b))}});'; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.production.js index 27b6b0307d0c5..725e15419d634 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.production.js @@ -2332,10 +2332,10 @@ var completeSegmentScript1Full = stringToPrecomputedChunk( ), completeBoundaryScript1Partial = stringToPrecomputedChunk('$RC("'), completeBoundaryWithStylesScript1FullBoth = stringToPrecomputedChunk( - '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' ), completeBoundaryWithStylesScript1FullPartial = stringToPrecomputedChunk( - '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' ), completeBoundaryWithStylesScript1Partial = stringToPrecomputedChunk('$RR("'), completeBoundaryScript2 = stringToPrecomputedChunk('","'), @@ -6345,12 +6345,12 @@ function getPostponedState(request) { } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-experimental-1df34bdf62-20240605" !== isomorphicReactPackageVersion) + if ("19.0.0-experimental-6230622a1a-20240610" !== isomorphicReactPackageVersion) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion, - "19.0.0-experimental-1df34bdf62-20240605" + "19.0.0-experimental-6230622a1a-20240610" ) ); } @@ -6555,4 +6555,4 @@ exports.resume = function (children, postponedState, options) { startWork(request); }); }; -exports.version = "19.0.0-experimental-1df34bdf62-20240605"; +exports.version = "19.0.0-experimental-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.bun.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.bun.production.js index e4cc5bc173b5f..84cc171c78b82 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.bun.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.bun.production.js @@ -5504,13 +5504,13 @@ function flushCompletedBoundary(request, destination, boundary) { ? ((completedSegments.instructions |= 10), writeChunk( destination, - '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' )) : 0 === (completedSegments.instructions & 8) ? ((completedSegments.instructions |= 8), writeChunk( destination, - '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' )) : writeChunk(destination, '$RR("') : 0 === (completedSegments.instructions & 2) @@ -5864,13 +5864,13 @@ function addToReplayParent(node, parentKeyPath, trackedPostpones) { } var isomorphicReactPackageVersion$jscomp$inline_800 = React.version; if ( - "19.0.0-experimental-1df34bdf62-20240605" !== + "19.0.0-experimental-6230622a1a-20240610" !== isomorphicReactPackageVersion$jscomp$inline_800 ) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion$jscomp$inline_800 + - "\n - react-dom: 19.0.0-experimental-1df34bdf62-20240605\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-experimental-6230622a1a-20240610\nLearn more: https://react.dev/warnings/version-mismatch") ); exports.renderToReadableStream = function (children, options) { return new Promise(function (resolve, reject) { @@ -5961,4 +5961,4 @@ exports.renderToReadableStream = function (children, options) { safelyEmitEarlyPreloads(request, 0 === request.pendingRootTasks); }); }; -exports.version = "19.0.0-experimental-1df34bdf62-20240605"; +exports.version = "19.0.0-experimental-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js index 74fcbcf35e596..0cb90ebfd3c7b 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react-experimental"); var ReactDOM = require('react-dom'); -var reactDOMPackageVersion = '19.0.0-experimental-1df34bdf62-20240605'; +var reactDOMPackageVersion = '19.0.0-experimental-6230622a1a-20240610'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; @@ -2016,7 +2016,7 @@ function sanitizeURL(url) { // Run `yarn generate-inline-fizz-runtime` to generate. var clientRenderBoundary = '$RX=function(b,c,d,e,f){var a=document.getElementById(b);a&&(b=a.previousSibling,b.data="$!",a=a.dataset,c&&(a.dgst=c),d&&(a.msg=d),e&&(a.stck=e),f&&(a.cstck=f),b._reactRetry&&b._reactRetry())};'; var completeBoundary = '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};'; -var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};'; +var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};'; var completeSegment = '$RS=function(a,b){a=document.getElementById(a);b=document.getElementById(b);for(a.parentNode.removeChild(a);a.firstChild;)b.parentNode.insertBefore(a.firstChild,b);b.parentNode.removeChild(b)};'; var formReplaying = 'addEventListener("submit",function(a){if(!a.defaultPrevented){var c=a.target,d=a.submitter,e=c.action,b=d;if(d){var f=d.getAttribute("formAction");null!=f&&(e=f,b=null)}"javascript:throw new Error(\'React form unexpectedly submitted.\')"===e&&(a.preventDefault(),b?(a=document.createElement("input"),a.name=b.name,a.value=b.value,b.parentNode.insertBefore(a,b),b=new FormData(c),a.parentNode.removeChild(a)):b=new FormData(c),a=c.ownerDocument||c,(a.$$reactFormReplay=a.$$reactFormReplay||[]).push(c,d,b))}});'; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js index d2a7dfea4aefe..3b96678ec3d29 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js @@ -2349,10 +2349,10 @@ var completeSegmentScript1Full = stringToPrecomputedChunk( ), completeBoundaryScript1Partial = stringToPrecomputedChunk('$RC("'), completeBoundaryWithStylesScript1FullBoth = stringToPrecomputedChunk( - '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' ), completeBoundaryWithStylesScript1FullPartial = stringToPrecomputedChunk( - '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' ), completeBoundaryWithStylesScript1Partial = stringToPrecomputedChunk('$RR("'), completeBoundaryScript2 = stringToPrecomputedChunk('","'), @@ -6468,11 +6468,11 @@ function getPostponedState(request) { } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-experimental-1df34bdf62-20240605" !== isomorphicReactPackageVersion) + if ("19.0.0-experimental-6230622a1a-20240610" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-experimental-1df34bdf62-20240605\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-experimental-6230622a1a-20240610\nLearn more: https://react.dev/warnings/version-mismatch") ); } ensureCorrectIsomorphicReactVersion(); @@ -6676,4 +6676,4 @@ exports.resume = function (children, postponedState, options) { startWork(request); }); }; -exports.version = "19.0.0-experimental-1df34bdf62-20240605"; +exports.version = "19.0.0-experimental-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.development.js index a53aad340966d..18c0609458ce4 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.development.js @@ -21,7 +21,7 @@ var async_hooks = require('async_hooks'); var ReactDOM = require('react-dom'); var stream = require('stream'); -var reactDOMPackageVersion = '19.0.0-experimental-1df34bdf62-20240605'; +var reactDOMPackageVersion = '19.0.0-experimental-6230622a1a-20240610'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; @@ -1997,7 +1997,7 @@ function sanitizeURL(url) { // Run `yarn generate-inline-fizz-runtime` to generate. var clientRenderBoundary = '$RX=function(b,c,d,e,f){var a=document.getElementById(b);a&&(b=a.previousSibling,b.data="$!",a=a.dataset,c&&(a.dgst=c),d&&(a.msg=d),e&&(a.stck=e),f&&(a.cstck=f),b._reactRetry&&b._reactRetry())};'; var completeBoundary = '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};'; -var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};'; +var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};'; var completeSegment = '$RS=function(a,b){a=document.getElementById(a);b=document.getElementById(b);for(a.parentNode.removeChild(a);a.firstChild;)b.parentNode.insertBefore(a.firstChild,b);b.parentNode.removeChild(b)};'; var formReplaying = 'addEventListener("submit",function(a){if(!a.defaultPrevented){var c=a.target,d=a.submitter,e=c.action,b=d;if(d){var f=d.getAttribute("formAction");null!=f&&(e=f,b=null)}"javascript:throw new Error(\'React form unexpectedly submitted.\')"===e&&(a.preventDefault(),b?(a=document.createElement("input"),a.name=b.name,a.value=b.value,b.parentNode.insertBefore(a,b),b=new FormData(c),a.parentNode.removeChild(a)):b=new FormData(c),a=c.ownerDocument||c,(a.$$reactFormReplay=a.$$reactFormReplay||[]).push(c,d,b))}});'; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.production.js index 4e95e7baaeb87..4d1d54adaed25 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.production.js @@ -2271,10 +2271,10 @@ var completeSegmentScript1Full = stringToPrecomputedChunk( ), completeBoundaryScript1Partial = stringToPrecomputedChunk('$RC("'), completeBoundaryWithStylesScript1FullBoth = stringToPrecomputedChunk( - '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' ), completeBoundaryWithStylesScript1FullPartial = stringToPrecomputedChunk( - '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' ), completeBoundaryWithStylesScript1Partial = stringToPrecomputedChunk('$RR("'), completeBoundaryScript2 = stringToPrecomputedChunk('","'), @@ -6263,11 +6263,11 @@ function getPostponedState(request) { } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-experimental-1df34bdf62-20240605" !== isomorphicReactPackageVersion) + if ("19.0.0-experimental-6230622a1a-20240610" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-experimental-1df34bdf62-20240605\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-experimental-6230622a1a-20240610\nLearn more: https://react.dev/warnings/version-mismatch") ); } ensureCorrectIsomorphicReactVersion(); @@ -6548,4 +6548,4 @@ exports.resumeToPipeableStream = function (children, postponedState, options) { } }; }; -exports.version = "19.0.0-experimental-1df34bdf62-20240605"; +exports.version = "19.0.0-experimental-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.development.js index e9be6fa003c53..0613fd5ed9ec5 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.development.js @@ -36549,8 +36549,25 @@ function getResource(type, currentProps, pendingProps, currentResource) { _styles.set(_key, _resource); + var instance = ownerDocument.querySelector(getStylesheetSelectorFromKey(_key)); + + if (instance) { + var loadingState = instance._p; + + if (loadingState) ; else { + // This instance is already loaded + _resource.instance = instance; + _resource.state.loading = Loaded | Inserted; + } + } + if (!preloadPropsMap.has(_key)) { - preloadStylesheet(ownerDocument, _key, preloadPropsFromStylesheet(qualifiedProps), _resource.state); + var preloadProps = preloadPropsFromStylesheet(qualifiedProps); + preloadPropsMap.set(_key, preloadProps); + + if (!instance) { + preloadStylesheet(ownerDocument, _key, preloadProps, _resource.state); + } } } @@ -36697,31 +36714,24 @@ function stylesheetPropsFromRawProps(rawProps) { } function preloadStylesheet(ownerDocument, key, preloadProps, state) { - preloadPropsMap.set(key, preloadProps); - - if (!ownerDocument.querySelector(getStylesheetSelectorFromKey(key))) { - // There is no matching stylesheet instance in the Document. - // We will insert a preload now to kick off loading because - // we expect this stylesheet to commit - var preloadEl = ownerDocument.querySelector(getPreloadStylesheetSelectorFromKey(key)); - - if (preloadEl) { - // If we find a preload already it was SSR'd and we won't have an actual - // loading state to track. For now we will just assume it is loaded - state.loading = Loaded; - } else { - var instance = ownerDocument.createElement('link'); - state.preload = instance; - instance.addEventListener('load', function () { - return state.loading |= Loaded; - }); - instance.addEventListener('error', function () { - return state.loading |= Errored; - }); - setInitialProperties(instance, 'link', preloadProps); - markNodeAsHoistable(instance); - ownerDocument.head.appendChild(instance); - } + var preloadEl = ownerDocument.querySelector(getPreloadStylesheetSelectorFromKey(key)); + + if (preloadEl) { + // If we find a preload already it was SSR'd and we won't have an actual + // loading state to track. For now we will just assume it is loaded + state.loading = Loaded; + } else { + var instance = ownerDocument.createElement('link'); + state.preload = instance; + instance.addEventListener('load', function () { + return state.loading |= Loaded; + }); + instance.addEventListener('error', function () { + return state.loading |= Errored; + }); + setInitialProperties(instance, 'link', preloadProps); + markNodeAsHoistable(instance); + ownerDocument.head.appendChild(instance); } } @@ -37589,7 +37599,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-experimental-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; // Might add PROFILE later. diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.production.js index e426db9f52f4b..9d61431c8aea1 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.production.js @@ -13948,20 +13948,20 @@ function getResource(type, currentProps, pendingProps, currentResource) { case "style": return "string" === typeof pendingProps.precedence && "string" === typeof pendingProps.href - ? ((pendingProps = getStyleKey(pendingProps.href)), - (JSCompiler_inline_result = getResourcesFromRoot( + ? ((currentProps = getStyleKey(pendingProps.href)), + (pendingProps = getResourcesFromRoot( JSCompiler_inline_result ).hoistableStyles), - (currentProps = JSCompiler_inline_result.get(pendingProps)), - currentProps || - ((currentProps = { + (currentResource = pendingProps.get(currentProps)), + currentResource || + ((currentResource = { type: "style", instance: null, count: 0, state: null }), - JSCompiler_inline_result.set(pendingProps, currentProps)), - currentProps) + pendingProps.set(currentProps, currentResource)), + currentResource) : { type: "void", instance: null, count: 0, state: null }; case "link": if ( @@ -13984,22 +13984,31 @@ function getResource(type, currentProps, pendingProps, currentResource) { state: { loading: 0, preload: null } }), styles$232.set(type, resource$233), + (styles$232 = JSCompiler_inline_result.querySelector( + getStylesheetSelectorFromKey(type) + )) && + !styles$232._p && + ((resource$233.instance = styles$232), + (resource$233.state.loading = 5)), preloadPropsMap.has(type) || - preloadStylesheet( - JSCompiler_inline_result, - type, - { - rel: "preload", - as: "style", - href: pendingProps.href, - crossOrigin: pendingProps.crossOrigin, - integrity: pendingProps.integrity, - media: pendingProps.media, - hrefLang: pendingProps.hrefLang, - referrerPolicy: pendingProps.referrerPolicy - }, - resource$233.state - )); + ((pendingProps = { + rel: "preload", + as: "style", + href: pendingProps.href, + crossOrigin: pendingProps.crossOrigin, + integrity: pendingProps.integrity, + media: pendingProps.media, + hrefLang: pendingProps.hrefLang, + referrerPolicy: pendingProps.referrerPolicy + }), + preloadPropsMap.set(type, pendingProps), + styles$232 || + preloadStylesheet( + JSCompiler_inline_result, + type, + pendingProps, + resource$233.state + ))); if (currentProps && null === currentResource) throw Error(formatProdErrorMessage(528, "")); return resource$233; @@ -14015,20 +14024,20 @@ function getResource(type, currentProps, pendingProps, currentResource) { currentProps && "function" !== typeof currentProps && "symbol" !== typeof currentProps - ? ((pendingProps = getScriptKey(pendingProps)), - (JSCompiler_inline_result = getResourcesFromRoot( + ? ((currentProps = getScriptKey(pendingProps)), + (pendingProps = getResourcesFromRoot( JSCompiler_inline_result ).hoistableScripts), - (currentProps = JSCompiler_inline_result.get(pendingProps)), - currentProps || - ((currentProps = { + (currentResource = pendingProps.get(currentProps)), + currentResource || + ((currentResource = { type: "script", instance: null, count: 0, state: null }), - JSCompiler_inline_result.set(pendingProps, currentProps)), - currentProps) + pendingProps.set(currentProps, currentResource)), + currentResource) : { type: "void", instance: null, count: 0, state: null } ); default: @@ -14048,21 +14057,19 @@ function stylesheetPropsFromRawProps(rawProps) { }); } function preloadStylesheet(ownerDocument, key, preloadProps, state) { - preloadPropsMap.set(key, preloadProps); - ownerDocument.querySelector(getStylesheetSelectorFromKey(key)) || - (ownerDocument.querySelector('link[rel="preload"][as="style"][' + key + "]") - ? (state.loading = 1) - : ((key = ownerDocument.createElement("link")), - (state.preload = key), - key.addEventListener("load", function () { - return (state.loading |= 1); - }), - key.addEventListener("error", function () { - return (state.loading |= 2); - }), - setInitialProperties(key, "link", preloadProps), - markNodeAsHoistable(key), - ownerDocument.head.appendChild(key))); + ownerDocument.querySelector('link[rel="preload"][as="style"][' + key + "]") + ? (state.loading = 1) + : ((key = ownerDocument.createElement("link")), + (state.preload = key), + key.addEventListener("load", function () { + return (state.loading |= 1); + }), + key.addEventListener("error", function () { + return (state.loading |= 2); + }), + setInitialProperties(key, "link", preloadProps), + markNodeAsHoistable(key), + ownerDocument.head.appendChild(key)); } function getScriptKey(src) { return '[src="' + escapeSelectorAttributeValueInsideDoubleQuotes(src) + '"]'; @@ -15161,14 +15168,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) { }; var isomorphicReactPackageVersion$jscomp$inline_1660 = React.version; if ( - "19.0.0-experimental-1df34bdf62-20240605" !== + "19.0.0-experimental-6230622a1a-20240610" !== isomorphicReactPackageVersion$jscomp$inline_1660 ) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion$jscomp$inline_1660, - "19.0.0-experimental-1df34bdf62-20240605" + "19.0.0-experimental-6230622a1a-20240610" ) ); ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { @@ -15187,7 +15194,7 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { var devToolsConfig$jscomp$inline_1667 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "19.0.0-experimental-1df34bdf62-20240605", + version: "19.0.0-experimental-6230622a1a-20240610", rendererPackageName: "react-dom" }; var internals$jscomp$inline_2050 = { @@ -15217,7 +15224,7 @@ var internals$jscomp$inline_2050 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-experimental-1df34bdf62-20240605" + reconcilerVersion: "19.0.0-experimental-6230622a1a-20240610" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_2051 = __REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -15474,4 +15481,4 @@ exports.observeVisibleRects = function ( } }; }; -exports.version = "19.0.0-experimental-1df34bdf62-20240605"; +exports.version = "19.0.0-experimental-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.development.js index 8eb39f3787470..197c5b33a7c0c 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.development.js @@ -144,7 +144,7 @@ var Internals = { findDOMNode: null }; -var ReactVersion = '19.0.0-experimental-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; /** * HTML nodeType values that represent the type of the node diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.production.js index 129540b8c827b..9e324072ab49c 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.production.js @@ -206,4 +206,4 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactSharedInternals.H.useHostTransitionStatus(); }; -exports.version = "19.0.0-experimental-1df34bdf62-20240605"; +exports.version = "19.0.0-experimental-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.development.js index 15aeabc7fdaec..1a32afc1da3c1 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.development.js @@ -16,7 +16,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react-experimental"); -var ReactVersion = '19.0.0-experimental-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; var ReactSharedInternalsServer = // $FlowFixMe: It's defined in the one we resolve to. React.__SERVER_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.production.js index 726abeedb5d63..456b1c2aa9462 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.production.js @@ -151,4 +151,4 @@ exports.preloadModule = function (href, options) { }); } else Internals.d.m(href); }; -exports.version = "19.0.0-experimental-1df34bdf62-20240605"; +exports.version = "19.0.0-experimental-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom-experimental/package.json b/packages/next/src/compiled/react-dom-experimental/package.json index b339bdd6a3d96..0cc406b2d32b9 100644 --- a/packages/next/src/compiled/react-dom-experimental/package.json +++ b/packages/next/src/compiled/react-dom-experimental/package.json @@ -72,10 +72,10 @@ "./package.json": "./package.json" }, "dependencies": { - "scheduler": "0.0.0-experimental-1df34bdf62-20240605" + "scheduler": "0.0.0-experimental-6230622a1a-20240610" }, "peerDependencies": { - "react": "0.0.0-experimental-1df34bdf62-20240605" + "react": "0.0.0-experimental-6230622a1a-20240610" }, "browser": { "./server.js": "./server.browser.js", diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-client.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-client.development.js index 6db71eaa50edf..4cc92bdf21d53 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-client.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-client.development.js @@ -35384,8 +35384,25 @@ function getResource(type, currentProps, pendingProps, currentResource) { _styles.set(_key, _resource); + var instance = ownerDocument.querySelector(getStylesheetSelectorFromKey(_key)); + + if (instance) { + var loadingState = instance._p; + + if (loadingState) ; else { + // This instance is already loaded + _resource.instance = instance; + _resource.state.loading = Loaded | Inserted; + } + } + if (!preloadPropsMap.has(_key)) { - preloadStylesheet(ownerDocument, _key, preloadPropsFromStylesheet(qualifiedProps), _resource.state); + var preloadProps = preloadPropsFromStylesheet(qualifiedProps); + preloadPropsMap.set(_key, preloadProps); + + if (!instance) { + preloadStylesheet(ownerDocument, _key, preloadProps, _resource.state); + } } } @@ -35532,31 +35549,24 @@ function stylesheetPropsFromRawProps(rawProps) { } function preloadStylesheet(ownerDocument, key, preloadProps, state) { - preloadPropsMap.set(key, preloadProps); - - if (!ownerDocument.querySelector(getStylesheetSelectorFromKey(key))) { - // There is no matching stylesheet instance in the Document. - // We will insert a preload now to kick off loading because - // we expect this stylesheet to commit - var preloadEl = ownerDocument.querySelector(getPreloadStylesheetSelectorFromKey(key)); - - if (preloadEl) { - // If we find a preload already it was SSR'd and we won't have an actual - // loading state to track. For now we will just assume it is loaded - state.loading = Loaded; - } else { - var instance = ownerDocument.createElement('link'); - state.preload = instance; - instance.addEventListener('load', function () { - return state.loading |= Loaded; - }); - instance.addEventListener('error', function () { - return state.loading |= Errored; - }); - setInitialProperties(instance, 'link', preloadProps); - markNodeAsHoistable(instance); - ownerDocument.head.appendChild(instance); - } + var preloadEl = ownerDocument.querySelector(getPreloadStylesheetSelectorFromKey(key)); + + if (preloadEl) { + // If we find a preload already it was SSR'd and we won't have an actual + // loading state to track. For now we will just assume it is loaded + state.loading = Loaded; + } else { + var instance = ownerDocument.createElement('link'); + state.preload = instance; + instance.addEventListener('load', function () { + return state.loading |= Loaded; + }); + instance.addEventListener('error', function () { + return state.loading |= Errored; + }); + setInitialProperties(instance, 'link', preloadProps); + markNodeAsHoistable(instance); + ownerDocument.head.appendChild(instance); } } @@ -36424,7 +36434,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-rc-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-rc-6230622a1a-20240610'; // Might add PROFILE later. diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-client.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-client.production.js index a047fba31ec29..52d5e3c749149 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-client.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-client.production.js @@ -13413,20 +13413,20 @@ function getResource(type, currentProps, pendingProps, currentResource) { case "style": return "string" === typeof pendingProps.precedence && "string" === typeof pendingProps.href - ? ((pendingProps = getStyleKey(pendingProps.href)), - (JSCompiler_inline_result = getResourcesFromRoot( + ? ((currentProps = getStyleKey(pendingProps.href)), + (pendingProps = getResourcesFromRoot( JSCompiler_inline_result ).hoistableStyles), - (currentProps = JSCompiler_inline_result.get(pendingProps)), - currentProps || - ((currentProps = { + (currentResource = pendingProps.get(currentProps)), + currentResource || + ((currentResource = { type: "style", instance: null, count: 0, state: null }), - JSCompiler_inline_result.set(pendingProps, currentProps)), - currentProps) + pendingProps.set(currentProps, currentResource)), + currentResource) : { type: "void", instance: null, count: 0, state: null }; case "link": if ( @@ -13449,22 +13449,31 @@ function getResource(type, currentProps, pendingProps, currentResource) { state: { loading: 0, preload: null } }), styles$229.set(type, resource$230), + (styles$229 = JSCompiler_inline_result.querySelector( + getStylesheetSelectorFromKey(type) + )) && + !styles$229._p && + ((resource$230.instance = styles$229), + (resource$230.state.loading = 5)), preloadPropsMap.has(type) || - preloadStylesheet( - JSCompiler_inline_result, - type, - { - rel: "preload", - as: "style", - href: pendingProps.href, - crossOrigin: pendingProps.crossOrigin, - integrity: pendingProps.integrity, - media: pendingProps.media, - hrefLang: pendingProps.hrefLang, - referrerPolicy: pendingProps.referrerPolicy - }, - resource$230.state - )); + ((pendingProps = { + rel: "preload", + as: "style", + href: pendingProps.href, + crossOrigin: pendingProps.crossOrigin, + integrity: pendingProps.integrity, + media: pendingProps.media, + hrefLang: pendingProps.hrefLang, + referrerPolicy: pendingProps.referrerPolicy + }), + preloadPropsMap.set(type, pendingProps), + styles$229 || + preloadStylesheet( + JSCompiler_inline_result, + type, + pendingProps, + resource$230.state + ))); if (currentProps && null === currentResource) throw Error(formatProdErrorMessage(528, "")); return resource$230; @@ -13480,20 +13489,20 @@ function getResource(type, currentProps, pendingProps, currentResource) { currentProps && "function" !== typeof currentProps && "symbol" !== typeof currentProps - ? ((pendingProps = getScriptKey(pendingProps)), - (JSCompiler_inline_result = getResourcesFromRoot( + ? ((currentProps = getScriptKey(pendingProps)), + (pendingProps = getResourcesFromRoot( JSCompiler_inline_result ).hoistableScripts), - (currentProps = JSCompiler_inline_result.get(pendingProps)), - currentProps || - ((currentProps = { + (currentResource = pendingProps.get(currentProps)), + currentResource || + ((currentResource = { type: "script", instance: null, count: 0, state: null }), - JSCompiler_inline_result.set(pendingProps, currentProps)), - currentProps) + pendingProps.set(currentProps, currentResource)), + currentResource) : { type: "void", instance: null, count: 0, state: null } ); default: @@ -13513,21 +13522,19 @@ function stylesheetPropsFromRawProps(rawProps) { }); } function preloadStylesheet(ownerDocument, key, preloadProps, state) { - preloadPropsMap.set(key, preloadProps); - ownerDocument.querySelector(getStylesheetSelectorFromKey(key)) || - (ownerDocument.querySelector('link[rel="preload"][as="style"][' + key + "]") - ? (state.loading = 1) - : ((key = ownerDocument.createElement("link")), - (state.preload = key), - key.addEventListener("load", function () { - return (state.loading |= 1); - }), - key.addEventListener("error", function () { - return (state.loading |= 2); - }), - setInitialProperties(key, "link", preloadProps), - markNodeAsHoistable(key), - ownerDocument.head.appendChild(key))); + ownerDocument.querySelector('link[rel="preload"][as="style"][' + key + "]") + ? (state.loading = 1) + : ((key = ownerDocument.createElement("link")), + (state.preload = key), + key.addEventListener("load", function () { + return (state.loading |= 1); + }), + key.addEventListener("error", function () { + return (state.loading |= 2); + }), + setInitialProperties(key, "link", preloadProps), + markNodeAsHoistable(key), + ownerDocument.head.appendChild(key)); } function getScriptKey(src) { return '[src="' + escapeSelectorAttributeValueInsideDoubleQuotes(src) + '"]'; @@ -14626,14 +14633,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) { }; var isomorphicReactPackageVersion$jscomp$inline_1651 = React.version; if ( - "19.0.0-rc-1df34bdf62-20240605" !== + "19.0.0-rc-6230622a1a-20240610" !== isomorphicReactPackageVersion$jscomp$inline_1651 ) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion$jscomp$inline_1651, - "19.0.0-rc-1df34bdf62-20240605" + "19.0.0-rc-6230622a1a-20240610" ) ); ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { @@ -14652,7 +14659,7 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { var devToolsConfig$jscomp$inline_1658 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "19.0.0-rc-1df34bdf62-20240605", + version: "19.0.0-rc-6230622a1a-20240610", rendererPackageName: "react-dom" }; var internals$jscomp$inline_2036 = { @@ -14682,7 +14689,7 @@ var internals$jscomp$inline_2036 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-1df34bdf62-20240605" + reconcilerVersion: "19.0.0-rc-6230622a1a-20240610" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_2037 = __REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -14788,4 +14795,4 @@ exports.hydrateRoot = function (container, initialChildren, options) { listenToAllSupportedEvents(container); return new ReactDOMHydrationRoot(initialChildren); }; -exports.version = "19.0.0-rc-1df34bdf62-20240605"; +exports.version = "19.0.0-rc-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.development.js index 57fa6f402ca9d..d70e6d3421157 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.development.js @@ -35432,8 +35432,25 @@ function getResource(type, currentProps, pendingProps, currentResource) { _styles.set(_key, _resource); + var instance = ownerDocument.querySelector(getStylesheetSelectorFromKey(_key)); + + if (instance) { + var loadingState = instance._p; + + if (loadingState) ; else { + // This instance is already loaded + _resource.instance = instance; + _resource.state.loading = Loaded | Inserted; + } + } + if (!preloadPropsMap.has(_key)) { - preloadStylesheet(ownerDocument, _key, preloadPropsFromStylesheet(qualifiedProps), _resource.state); + var preloadProps = preloadPropsFromStylesheet(qualifiedProps); + preloadPropsMap.set(_key, preloadProps); + + if (!instance) { + preloadStylesheet(ownerDocument, _key, preloadProps, _resource.state); + } } } @@ -35580,31 +35597,24 @@ function stylesheetPropsFromRawProps(rawProps) { } function preloadStylesheet(ownerDocument, key, preloadProps, state) { - preloadPropsMap.set(key, preloadProps); - - if (!ownerDocument.querySelector(getStylesheetSelectorFromKey(key))) { - // There is no matching stylesheet instance in the Document. - // We will insert a preload now to kick off loading because - // we expect this stylesheet to commit - var preloadEl = ownerDocument.querySelector(getPreloadStylesheetSelectorFromKey(key)); - - if (preloadEl) { - // If we find a preload already it was SSR'd and we won't have an actual - // loading state to track. For now we will just assume it is loaded - state.loading = Loaded; - } else { - var instance = ownerDocument.createElement('link'); - state.preload = instance; - instance.addEventListener('load', function () { - return state.loading |= Loaded; - }); - instance.addEventListener('error', function () { - return state.loading |= Errored; - }); - setInitialProperties(instance, 'link', preloadProps); - markNodeAsHoistable(instance); - ownerDocument.head.appendChild(instance); - } + var preloadEl = ownerDocument.querySelector(getPreloadStylesheetSelectorFromKey(key)); + + if (preloadEl) { + // If we find a preload already it was SSR'd and we won't have an actual + // loading state to track. For now we will just assume it is loaded + state.loading = Loaded; + } else { + var instance = ownerDocument.createElement('link'); + state.preload = instance; + instance.addEventListener('load', function () { + return state.loading |= Loaded; + }); + instance.addEventListener('error', function () { + return state.loading |= Errored; + }); + setInitialProperties(instance, 'link', preloadProps); + markNodeAsHoistable(instance); + ownerDocument.head.appendChild(instance); } } @@ -36472,7 +36482,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-rc-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-rc-6230622a1a-20240610'; function createPortal$1(children, containerInfo, // TODO: figure out the API for cross-renderer implementation. implementation) { diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.profiling.js b/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.profiling.js index fcab6f04d28eb..494d4a867b0ed 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.profiling.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.profiling.js @@ -14104,20 +14104,20 @@ function getResource(type, currentProps, pendingProps, currentResource) { case "style": return "string" === typeof pendingProps.precedence && "string" === typeof pendingProps.href - ? ((pendingProps = getStyleKey(pendingProps.href)), - (JSCompiler_inline_result = getResourcesFromRoot( + ? ((currentProps = getStyleKey(pendingProps.href)), + (pendingProps = getResourcesFromRoot( JSCompiler_inline_result ).hoistableStyles), - (currentProps = JSCompiler_inline_result.get(pendingProps)), - currentProps || - ((currentProps = { + (currentResource = pendingProps.get(currentProps)), + currentResource || + ((currentResource = { type: "style", instance: null, count: 0, state: null }), - JSCompiler_inline_result.set(pendingProps, currentProps)), - currentProps) + pendingProps.set(currentProps, currentResource)), + currentResource) : { type: "void", instance: null, count: 0, state: null }; case "link": if ( @@ -14140,22 +14140,31 @@ function getResource(type, currentProps, pendingProps, currentResource) { state: { loading: 0, preload: null } }), styles$249.set(type, resource$250), + (styles$249 = JSCompiler_inline_result.querySelector( + getStylesheetSelectorFromKey(type) + )) && + !styles$249._p && + ((resource$250.instance = styles$249), + (resource$250.state.loading = 5)), preloadPropsMap.has(type) || - preloadStylesheet( - JSCompiler_inline_result, - type, - { - rel: "preload", - as: "style", - href: pendingProps.href, - crossOrigin: pendingProps.crossOrigin, - integrity: pendingProps.integrity, - media: pendingProps.media, - hrefLang: pendingProps.hrefLang, - referrerPolicy: pendingProps.referrerPolicy - }, - resource$250.state - )); + ((pendingProps = { + rel: "preload", + as: "style", + href: pendingProps.href, + crossOrigin: pendingProps.crossOrigin, + integrity: pendingProps.integrity, + media: pendingProps.media, + hrefLang: pendingProps.hrefLang, + referrerPolicy: pendingProps.referrerPolicy + }), + preloadPropsMap.set(type, pendingProps), + styles$249 || + preloadStylesheet( + JSCompiler_inline_result, + type, + pendingProps, + resource$250.state + ))); if (currentProps && null === currentResource) throw Error(formatProdErrorMessage(528, "")); return resource$250; @@ -14171,20 +14180,20 @@ function getResource(type, currentProps, pendingProps, currentResource) { currentProps && "function" !== typeof currentProps && "symbol" !== typeof currentProps - ? ((pendingProps = getScriptKey(pendingProps)), - (JSCompiler_inline_result = getResourcesFromRoot( + ? ((currentProps = getScriptKey(pendingProps)), + (pendingProps = getResourcesFromRoot( JSCompiler_inline_result ).hoistableScripts), - (currentProps = JSCompiler_inline_result.get(pendingProps)), - currentProps || - ((currentProps = { + (currentResource = pendingProps.get(currentProps)), + currentResource || + ((currentResource = { type: "script", instance: null, count: 0, state: null }), - JSCompiler_inline_result.set(pendingProps, currentProps)), - currentProps) + pendingProps.set(currentProps, currentResource)), + currentResource) : { type: "void", instance: null, count: 0, state: null } ); default: @@ -14204,21 +14213,19 @@ function stylesheetPropsFromRawProps(rawProps) { }); } function preloadStylesheet(ownerDocument, key, preloadProps, state) { - preloadPropsMap.set(key, preloadProps); - ownerDocument.querySelector(getStylesheetSelectorFromKey(key)) || - (ownerDocument.querySelector('link[rel="preload"][as="style"][' + key + "]") - ? (state.loading = 1) - : ((key = ownerDocument.createElement("link")), - (state.preload = key), - key.addEventListener("load", function () { - return (state.loading |= 1); - }), - key.addEventListener("error", function () { - return (state.loading |= 2); - }), - setInitialProperties(key, "link", preloadProps), - markNodeAsHoistable(key), - ownerDocument.head.appendChild(key))); + ownerDocument.querySelector('link[rel="preload"][as="style"][' + key + "]") + ? (state.loading = 1) + : ((key = ownerDocument.createElement("link")), + (state.preload = key), + key.addEventListener("load", function () { + return (state.loading |= 1); + }), + key.addEventListener("error", function () { + return (state.loading |= 2); + }), + setInitialProperties(key, "link", preloadProps), + markNodeAsHoistable(key), + ownerDocument.head.appendChild(key)); } function getScriptKey(src) { return '[src="' + escapeSelectorAttributeValueInsideDoubleQuotes(src) + '"]'; @@ -15336,14 +15343,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) { }; var isomorphicReactPackageVersion$jscomp$inline_1739 = React.version; if ( - "19.0.0-rc-1df34bdf62-20240605" !== + "19.0.0-rc-6230622a1a-20240610" !== isomorphicReactPackageVersion$jscomp$inline_1739 ) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion$jscomp$inline_1739, - "19.0.0-rc-1df34bdf62-20240605" + "19.0.0-rc-6230622a1a-20240610" ) ); ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { @@ -15362,7 +15369,7 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { var devToolsConfig$jscomp$inline_1746 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "19.0.0-rc-1df34bdf62-20240605", + version: "19.0.0-rc-6230622a1a-20240610", rendererPackageName: "react-dom" }; (function (internals) { @@ -15405,7 +15412,7 @@ var devToolsConfig$jscomp$inline_1746 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-1df34bdf62-20240605" + reconcilerVersion: "19.0.0-rc-6230622a1a-20240610" }); function noop() {} function getCrossOriginStringAs(as, input) { @@ -15659,7 +15666,7 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactSharedInternals.H.useHostTransitionStatus(); }; -exports.version = "19.0.0-rc-1df34bdf62-20240605"; +exports.version = "19.0.0-rc-6230622a1a-20240610"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.development.js index 0a5c814c7c5a5..fae26ddcab7bc 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.development.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react"); var ReactDOM = require('react-dom'); -var ReactVersion = '19.0.0-rc-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-rc-6230622a1a-20240610'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; @@ -1941,7 +1941,7 @@ function sanitizeURL(url) { // Run `yarn generate-inline-fizz-runtime` to generate. var clientRenderBoundary = '$RX=function(b,c,d,e,f){var a=document.getElementById(b);a&&(b=a.previousSibling,b.data="$!",a=a.dataset,c&&(a.dgst=c),d&&(a.msg=d),e&&(a.stck=e),f&&(a.cstck=f),b._reactRetry&&b._reactRetry())};'; var completeBoundary = '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};'; -var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};'; +var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};'; var completeSegment = '$RS=function(a,b){a=document.getElementById(a);b=document.getElementById(b);for(a.parentNode.removeChild(a);a.firstChild;)b.parentNode.insertBefore(a.firstChild,b);b.parentNode.removeChild(b)};'; var formReplaying = 'addEventListener("submit",function(a){if(!a.defaultPrevented){var c=a.target,d=a.submitter,e=c.action,b=d;if(d){var f=d.getAttribute("formAction");null!=f&&(e=f,b=null)}"javascript:throw new Error(\'React form unexpectedly submitted.\')"===e&&(a.preventDefault(),b?(a=document.createElement("input"),a.name=b.name,a.value=b.value,b.parentNode.insertBefore(a,b),b=new FormData(c),a.parentNode.removeChild(a)):b=new FormData(c),a=c.ownerDocument||c,(a.$$reactFormReplay=a.$$reactFormReplay||[]).push(c,d,b))}});'; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.production.js index 7324f2d312c3d..3a49cf59b7cd5 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.production.js @@ -5098,12 +5098,12 @@ function flushCompletedBoundary(request, destination, boundary) { ? 0 === (completedSegments.instructions & 2) ? ((completedSegments.instructions |= 10), destination.push( - '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' )) : 0 === (completedSegments.instructions & 8) ? ((completedSegments.instructions |= 8), destination.push( - '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' )) : destination.push('$RR("') : 0 === (completedSegments.instructions & 2) @@ -5469,4 +5469,4 @@ exports.renderToString = function (children, options) { 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server' ); }; -exports.version = "19.0.0-rc-1df34bdf62-20240605"; +exports.version = "19.0.0-rc-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.development.js index 95be43805dcde..946c5e4474556 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.development.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react"); var ReactDOM = require('react-dom'); -var ReactVersion = '19.0.0-rc-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-rc-6230622a1a-20240610'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; @@ -1941,7 +1941,7 @@ function sanitizeURL(url) { // Run `yarn generate-inline-fizz-runtime` to generate. var clientRenderBoundary = '$RX=function(b,c,d,e,f){var a=document.getElementById(b);a&&(b=a.previousSibling,b.data="$!",a=a.dataset,c&&(a.dgst=c),d&&(a.msg=d),e&&(a.stck=e),f&&(a.cstck=f),b._reactRetry&&b._reactRetry())};'; var completeBoundary = '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};'; -var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};'; +var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};'; var completeSegment = '$RS=function(a,b){a=document.getElementById(a);b=document.getElementById(b);for(a.parentNode.removeChild(a);a.firstChild;)b.parentNode.insertBefore(a.firstChild,b);b.parentNode.removeChild(b)};'; var formReplaying = 'addEventListener("submit",function(a){if(!a.defaultPrevented){var c=a.target,d=a.submitter,e=c.action,b=d;if(d){var f=d.getAttribute("formAction");null!=f&&(e=f,b=null)}"javascript:throw new Error(\'React form unexpectedly submitted.\')"===e&&(a.preventDefault(),b?(a=document.createElement("input"),a.name=b.name,a.value=b.value,b.parentNode.insertBefore(a,b),b=new FormData(c),a.parentNode.removeChild(a)):b=new FormData(c),a=c.ownerDocument||c,(a.$$reactFormReplay=a.$$reactFormReplay||[]).push(c,d,b))}});'; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.production.js index f01739c24a855..3211d1bf49077 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.production.js @@ -5173,12 +5173,12 @@ function flushCompletedBoundary(request, destination, boundary) { ? 0 === (completedSegments.instructions & 2) ? ((completedSegments.instructions |= 10), destination.push( - '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' )) : 0 === (completedSegments.instructions & 8) ? ((completedSegments.instructions |= 8), destination.push( - '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' )) : destination.push('$RR("') : 0 === (completedSegments.instructions & 2) @@ -5551,4 +5551,4 @@ exports.renderToString = function (children, options) { 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToPipeableStream" which supports Suspense on the server' ); }; -exports.version = "19.0.0-rc-1df34bdf62-20240605"; +exports.version = "19.0.0-rc-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.development.js index 9a3cd2ea388f6..dd5f57932f795 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.development.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react"); var ReactDOM = require('react-dom'); -var reactDOMPackageVersion = '19.0.0-rc-1df34bdf62-20240605'; +var reactDOMPackageVersion = '19.0.0-rc-6230622a1a-20240610'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; @@ -2016,7 +2016,7 @@ function sanitizeURL(url) { // Run `yarn generate-inline-fizz-runtime` to generate. var clientRenderBoundary = '$RX=function(b,c,d,e,f){var a=document.getElementById(b);a&&(b=a.previousSibling,b.data="$!",a=a.dataset,c&&(a.dgst=c),d&&(a.msg=d),e&&(a.stck=e),f&&(a.cstck=f),b._reactRetry&&b._reactRetry())};'; var completeBoundary = '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};'; -var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};'; +var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};'; var completeSegment = '$RS=function(a,b){a=document.getElementById(a);b=document.getElementById(b);for(a.parentNode.removeChild(a);a.firstChild;)b.parentNode.insertBefore(a.firstChild,b);b.parentNode.removeChild(b)};'; var formReplaying = 'addEventListener("submit",function(a){if(!a.defaultPrevented){var c=a.target,d=a.submitter,e=c.action,b=d;if(d){var f=d.getAttribute("formAction");null!=f&&(e=f,b=null)}"javascript:throw new Error(\'React form unexpectedly submitted.\')"===e&&(a.preventDefault(),b?(a=document.createElement("input"),a.name=b.name,a.value=b.value,b.parentNode.insertBefore(a,b),b=new FormData(c),a.parentNode.removeChild(a)):b=new FormData(c),a=c.ownerDocument||c,(a.$$reactFormReplay=a.$$reactFormReplay||[]).push(c,d,b))}});'; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.production.js index 3b5c5d02fab70..9e3e2f70509d0 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.production.js @@ -2300,10 +2300,10 @@ var completeBoundaryScript1Full = stringToPrecomputedChunk( ), completeBoundaryScript1Partial = stringToPrecomputedChunk('$RC("'), completeBoundaryWithStylesScript1FullBoth = stringToPrecomputedChunk( - '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' ), completeBoundaryWithStylesScript1FullPartial = stringToPrecomputedChunk( - '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' ), completeBoundaryWithStylesScript1Partial = stringToPrecomputedChunk('$RR("'), completeBoundaryScript2 = stringToPrecomputedChunk('","'), @@ -5717,14 +5717,14 @@ function abort(request, reason) { } var isomorphicReactPackageVersion$jscomp$inline_728 = React.version; if ( - "19.0.0-rc-1df34bdf62-20240605" !== + "19.0.0-rc-6230622a1a-20240610" !== isomorphicReactPackageVersion$jscomp$inline_728 ) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion$jscomp$inline_728, - "19.0.0-rc-1df34bdf62-20240605" + "19.0.0-rc-6230622a1a-20240610" ) ); exports.renderToReadableStream = function (children, options) { @@ -5816,4 +5816,4 @@ exports.renderToReadableStream = function (children, options) { safelyEmitEarlyPreloads(request, 0 === request.pendingRootTasks); }); }; -exports.version = "19.0.0-rc-1df34bdf62-20240605"; +exports.version = "19.0.0-rc-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.bun.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.bun.production.js index ef38d94e159f7..132f8e49ea8a3 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.bun.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.bun.production.js @@ -5125,13 +5125,13 @@ function flushCompletedBoundary(request, destination, boundary) { ? ((completedSegments.instructions |= 10), writeChunk( destination, - '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' )) : 0 === (completedSegments.instructions & 8) ? ((completedSegments.instructions |= 8), writeChunk( destination, - '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' )) : writeChunk(destination, '$RR("') : 0 === (completedSegments.instructions & 2) @@ -5430,13 +5430,13 @@ function abort(request, reason) { } var isomorphicReactPackageVersion$jscomp$inline_724 = React.version; if ( - "19.0.0-rc-1df34bdf62-20240605" !== + "19.0.0-rc-6230622a1a-20240610" !== isomorphicReactPackageVersion$jscomp$inline_724 ) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion$jscomp$inline_724 + - "\n - react-dom: 19.0.0-rc-1df34bdf62-20240605\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-rc-6230622a1a-20240610\nLearn more: https://react.dev/warnings/version-mismatch") ); exports.renderToReadableStream = function (children, options) { return new Promise(function (resolve, reject) { @@ -5527,4 +5527,4 @@ exports.renderToReadableStream = function (children, options) { safelyEmitEarlyPreloads(request, 0 === request.pendingRootTasks); }); }; -exports.version = "19.0.0-rc-1df34bdf62-20240605"; +exports.version = "19.0.0-rc-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js index c6541ef83ea08..04c3f42c748d2 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react"); var ReactDOM = require('react-dom'); -var reactDOMPackageVersion = '19.0.0-rc-1df34bdf62-20240605'; +var reactDOMPackageVersion = '19.0.0-rc-6230622a1a-20240610'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; @@ -2016,7 +2016,7 @@ function sanitizeURL(url) { // Run `yarn generate-inline-fizz-runtime` to generate. var clientRenderBoundary = '$RX=function(b,c,d,e,f){var a=document.getElementById(b);a&&(b=a.previousSibling,b.data="$!",a=a.dataset,c&&(a.dgst=c),d&&(a.msg=d),e&&(a.stck=e),f&&(a.cstck=f),b._reactRetry&&b._reactRetry())};'; var completeBoundary = '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};'; -var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};'; +var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};'; var completeSegment = '$RS=function(a,b){a=document.getElementById(a);b=document.getElementById(b);for(a.parentNode.removeChild(a);a.firstChild;)b.parentNode.insertBefore(a.firstChild,b);b.parentNode.removeChild(b)};'; var formReplaying = 'addEventListener("submit",function(a){if(!a.defaultPrevented){var c=a.target,d=a.submitter,e=c.action,b=d;if(d){var f=d.getAttribute("formAction");null!=f&&(e=f,b=null)}"javascript:throw new Error(\'React form unexpectedly submitted.\')"===e&&(a.preventDefault(),b?(a=document.createElement("input"),a.name=b.name,a.value=b.value,b.parentNode.insertBefore(a,b),b=new FormData(c),a.parentNode.removeChild(a)):b=new FormData(c),a=c.ownerDocument||c,(a.$$reactFormReplay=a.$$reactFormReplay||[]).push(c,d,b))}});'; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js index 76c0c5bd61300..b565ba3c56f43 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js @@ -2317,10 +2317,10 @@ var completeBoundaryScript1Full = stringToPrecomputedChunk( ), completeBoundaryScript1Partial = stringToPrecomputedChunk('$RC("'), completeBoundaryWithStylesScript1FullBoth = stringToPrecomputedChunk( - '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' ), completeBoundaryWithStylesScript1FullPartial = stringToPrecomputedChunk( - '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' ), completeBoundaryWithStylesScript1Partial = stringToPrecomputedChunk('$RR("'), completeBoundaryScript2 = stringToPrecomputedChunk('","'), @@ -5832,13 +5832,13 @@ function abort(request, reason) { } var isomorphicReactPackageVersion$jscomp$inline_728 = React.version; if ( - "19.0.0-rc-1df34bdf62-20240605" !== + "19.0.0-rc-6230622a1a-20240610" !== isomorphicReactPackageVersion$jscomp$inline_728 ) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion$jscomp$inline_728 + - "\n - react-dom: 19.0.0-rc-1df34bdf62-20240605\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-rc-6230622a1a-20240610\nLearn more: https://react.dev/warnings/version-mismatch") ); exports.renderToReadableStream = function (children, options) { return new Promise(function (resolve, reject) { @@ -5926,4 +5926,4 @@ exports.renderToReadableStream = function (children, options) { startWork(request); }); }; -exports.version = "19.0.0-rc-1df34bdf62-20240605"; +exports.version = "19.0.0-rc-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.development.js index 2dce5823bab10..e81ff0454735b 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.development.js @@ -20,7 +20,7 @@ var crypto = require('crypto'); var async_hooks = require('async_hooks'); var ReactDOM = require('react-dom'); -var reactDOMPackageVersion = '19.0.0-rc-1df34bdf62-20240605'; +var reactDOMPackageVersion = '19.0.0-rc-6230622a1a-20240610'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; @@ -1996,7 +1996,7 @@ function sanitizeURL(url) { // Run `yarn generate-inline-fizz-runtime` to generate. var clientRenderBoundary = '$RX=function(b,c,d,e,f){var a=document.getElementById(b);a&&(b=a.previousSibling,b.data="$!",a=a.dataset,c&&(a.dgst=c),d&&(a.msg=d),e&&(a.stck=e),f&&(a.cstck=f),b._reactRetry&&b._reactRetry())};'; var completeBoundary = '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};'; -var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};'; +var completeBoundaryWithStyles = '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};'; var completeSegment = '$RS=function(a,b){a=document.getElementById(a);b=document.getElementById(b);for(a.parentNode.removeChild(a);a.firstChild;)b.parentNode.insertBefore(a.firstChild,b);b.parentNode.removeChild(b)};'; var formReplaying = 'addEventListener("submit",function(a){if(!a.defaultPrevented){var c=a.target,d=a.submitter,e=c.action,b=d;if(d){var f=d.getAttribute("formAction");null!=f&&(e=f,b=null)}"javascript:throw new Error(\'React form unexpectedly submitted.\')"===e&&(a.preventDefault(),b?(a=document.createElement("input"),a.name=b.name,a.value=b.value,b.parentNode.insertBefore(a,b),b=new FormData(c),a.parentNode.removeChild(a)):b=new FormData(c),a=c.ownerDocument||c,(a.$$reactFormReplay=a.$$reactFormReplay||[]).push(c,d,b))}});'; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.production.js index 7fc02ad079096..88b32e2e4cc19 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.production.js @@ -2024,10 +2024,10 @@ var completeBoundaryScript1Full = stringToPrecomputedChunk( ), completeBoundaryScript1Partial = stringToPrecomputedChunk('$RC("'), completeBoundaryWithStylesScript1FullBoth = stringToPrecomputedChunk( - '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RC=function(b,c,e){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(e)b.data="$!",a.setAttribute("data-dgst",e);else{e=b.parentNode;a=b.nextSibling;var f=0;do{if(a&&8===a.nodeType){var d=a.data;if("/$"===d)if(0===f)break;else f--;else"$"!==d&&"$?"!==d&&"$!"!==d||f++}d=a.nextSibling;e.removeChild(a);a=d}while(a);for(;c.firstChild;)e.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}};$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' ), completeBoundaryWithStylesScript1FullPartial = stringToPrecomputedChunk( - '$RM=new Map;\n$RR=function(r,t,w){for(var u=$RC,n=$RM,p=new Map,q=document,g,b,h=q.querySelectorAll("link[data-precedence],style[data-precedence]"),v=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?v.push(b):("LINK"===b.tagName&&n.set(b.getAttribute("href"),b),p.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var f=w[b++];if(!f){k=!1;b=0;continue}var c=!1,m=0;var d=f[m++];if(a=n.get(d)){var e=a._p;c=!0}else{a=q.createElement("link");a.href=d;a.rel="stylesheet";for(a.dataset.precedence=\nl=f[m++];e=f[m++];)a.setAttribute(e,f[m++]);e=a._p=new Promise(function(x,y){a.onload=x;a.onerror=y});n.set(d,a)}d=a.getAttribute("media");!e||"l"===e.s||d&&!matchMedia(d).matches||h.push(e);if(c)continue}else{a=v[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=p.get(l)||g;c===g&&(g=a);p.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=q.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(u.bind(null,r,t,""),u.bind(null,r,t,"Resource failed to load"))};$RR("' + '$RM=new Map;\n$RR=function(t,u,y){function v(n){this._p=null;n()}for(var w=$RC,p=$RM,q=new Map,r=document,g,b,h=r.querySelectorAll("link[data-precedence],style[data-precedence]"),x=[],k=0;b=h[k++];)"not all"===b.getAttribute("media")?x.push(b):("LINK"===b.tagName&&p.set(b.getAttribute("href"),b),q.set(b.dataset.precedence,g=b));b=0;h=[];var l,a;for(k=!0;;){if(k){var e=y[b++];if(!e){k=!1;b=0;continue}var c=!1,m=0;var d=e[m++];if(a=p.get(d)){var f=a._p;c=!0}else{a=r.createElement("link");a.href=\nd;a.rel="stylesheet";for(a.dataset.precedence=l=e[m++];f=e[m++];)a.setAttribute(f,e[m++]);f=a._p=new Promise(function(n,z){a.onload=v.bind(a,n);a.onerror=v.bind(a,z)});p.set(d,a)}d=a.getAttribute("media");!f||d&&!matchMedia(d).matches||h.push(f);if(c)continue}else{a=x[b++];if(!a)break;l=a.getAttribute("data-precedence");a.removeAttribute("media")}c=q.get(l)||g;c===g&&(g=a);q.set(l,a);c?c.parentNode.insertBefore(a,c.nextSibling):(c=r.head,c.insertBefore(a,c.firstChild))}Promise.all(h).then(w.bind(null,\nt,u,""),w.bind(null,t,u,"Resource failed to load"))};$RR("' ), completeBoundaryWithStylesScript1Partial = stringToPrecomputedChunk('$RR("'), completeBoundaryScript2 = stringToPrecomputedChunk('","'), @@ -5456,13 +5456,13 @@ function abort(request, reason) { } var isomorphicReactPackageVersion$jscomp$inline_751 = React.version; if ( - "19.0.0-rc-1df34bdf62-20240605" !== + "19.0.0-rc-6230622a1a-20240610" !== isomorphicReactPackageVersion$jscomp$inline_751 ) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion$jscomp$inline_751 + - "\n - react-dom: 19.0.0-rc-1df34bdf62-20240605\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-rc-6230622a1a-20240610\nLearn more: https://react.dev/warnings/version-mismatch") ); function createDrainHandler(destination, request) { return function () { @@ -5789,4 +5789,4 @@ exports.renderToPipeableStream = function (children, options) { } }; }; -exports.version = "19.0.0-rc-1df34bdf62-20240605"; +exports.version = "19.0.0-rc-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom.development.js index 50b7518ba7c2b..8db01a385167a 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom.development.js @@ -142,7 +142,7 @@ var Internals = { findDOMNode: null }; -var ReactVersion = '19.0.0-rc-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-rc-6230622a1a-20240610'; /** * HTML nodeType values that represent the type of the node diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom.production.js index 5bbb4129c89ae..09e9499d29d65 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom.production.js @@ -206,4 +206,4 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactSharedInternals.H.useHostTransitionStatus(); }; -exports.version = "19.0.0-rc-1df34bdf62-20240605"; +exports.version = "19.0.0-rc-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.development.js index dfa6df9e6d0b6..ebba208d3dbab 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.development.js @@ -16,7 +16,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react"); -var ReactVersion = '19.0.0-rc-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-rc-6230622a1a-20240610'; var ReactSharedInternalsServer = // $FlowFixMe: It's defined in the one we resolve to. React.__SERVER_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.production.js index 8921335acc127..2550b1a382478 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.production.js @@ -151,4 +151,4 @@ exports.preloadModule = function (href, options) { }); } else Internals.d.m(href); }; -exports.version = "19.0.0-rc-1df34bdf62-20240605"; +exports.version = "19.0.0-rc-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-dom/package.json b/packages/next/src/compiled/react-dom/package.json index 085fbfe4f5de1..7cae0f6a1a0ac 100644 --- a/packages/next/src/compiled/react-dom/package.json +++ b/packages/next/src/compiled/react-dom/package.json @@ -67,10 +67,10 @@ "./package.json": "./package.json" }, "dependencies": { - "scheduler": "0.25.0-rc-1df34bdf62-20240605" + "scheduler": "0.25.0-rc-6230622a1a-20240610" }, "peerDependencies": { - "react": "19.0.0-rc-1df34bdf62-20240605" + "react": "19.0.0-rc-6230622a1a-20240610" }, "browser": { "./server.js": "./server.browser.js", diff --git a/packages/next/src/compiled/react-experimental/cjs/react.development.js b/packages/next/src/compiled/react-experimental/cjs/react.development.js index d1bcf740ce7e3..2d96aa48ef62b 100644 --- a/packages/next/src/compiled/react-experimental/cjs/react.development.js +++ b/packages/next/src/compiled/react-experimental/cjs/react.development.js @@ -129,7 +129,7 @@ function printWarning(level, format, args, currentStack) { } } -var ReactVersion = '19.0.0-experimental-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; var REACT_ELEMENT_TYPE = Symbol.for('react.transitional.element') ; var REACT_PORTAL_TYPE = Symbol.for('react.portal'); diff --git a/packages/next/src/compiled/react-experimental/cjs/react.production.js b/packages/next/src/compiled/react-experimental/cjs/react.production.js index be77c72100288..b052713a3bcb3 100644 --- a/packages/next/src/compiled/react-experimental/cjs/react.production.js +++ b/packages/next/src/compiled/react-experimental/cjs/react.production.js @@ -559,4 +559,4 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactSharedInternals.H.useTransition(); }; -exports.version = "19.0.0-experimental-1df34bdf62-20240605"; +exports.version = "19.0.0-experimental-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-experimental/cjs/react.react-server.development.js b/packages/next/src/compiled/react-experimental/cjs/react.react-server.development.js index 806199e5d1c6c..77efc5682d9e2 100644 --- a/packages/next/src/compiled/react-experimental/cjs/react.react-server.development.js +++ b/packages/next/src/compiled/react-experimental/cjs/react.react-server.development.js @@ -1683,7 +1683,7 @@ function postpone(reason) { throw postponeInstance; } -var ReactVersion = '19.0.0-experimental-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; var getPrototypeOf = Object.getPrototypeOf; diff --git a/packages/next/src/compiled/react-experimental/cjs/react.react-server.production.js b/packages/next/src/compiled/react-experimental/cjs/react.react-server.production.js index bfc3d825831e5..39f2350364782 100644 --- a/packages/next/src/compiled/react-experimental/cjs/react.react-server.production.js +++ b/packages/next/src/compiled/react-experimental/cjs/react.react-server.production.js @@ -564,4 +564,4 @@ exports.useId = function () { exports.useMemo = function (create, deps) { return ReactSharedInternals.H.useMemo(create, deps); }; -exports.version = "19.0.0-experimental-1df34bdf62-20240605"; +exports.version = "19.0.0-experimental-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react-is/package.json b/packages/next/src/compiled/react-is/package.json index c01cf973535c5..4425e958fd1d0 100644 --- a/packages/next/src/compiled/react-is/package.json +++ b/packages/next/src/compiled/react-is/package.json @@ -1,6 +1,6 @@ { "name": "react-is", - "version": "19.0.0-rc-1df34bdf62-20240605", + "version": "19.0.0-rc-6230622a1a-20240610", "description": "Brand checking of React Elements.", "main": "index.js", "sideEffects": false, diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/package.json b/packages/next/src/compiled/react-server-dom-turbopack-experimental/package.json index 068bf0c3b18a3..753a9380a4924 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/package.json +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/package.json @@ -47,7 +47,7 @@ "neo-async": "^2.6.1" }, "peerDependencies": { - "react": "0.0.0-experimental-1df34bdf62-20240605", - "react-dom": "0.0.0-experimental-1df34bdf62-20240605" + "react": "0.0.0-experimental-6230622a1a-20240610", + "react-dom": "0.0.0-experimental-6230622a1a-20240610" } } \ No newline at end of file diff --git a/packages/next/src/compiled/react-server-dom-turbopack/package.json b/packages/next/src/compiled/react-server-dom-turbopack/package.json index 813a65ae6a557..a3195b088c38f 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/package.json +++ b/packages/next/src/compiled/react-server-dom-turbopack/package.json @@ -47,7 +47,7 @@ "neo-async": "^2.6.1" }, "peerDependencies": { - "react": "19.0.0-rc-1df34bdf62-20240605", - "react-dom": "19.0.0-rc-1df34bdf62-20240605" + "react": "19.0.0-rc-6230622a1a-20240610", + "react-dom": "19.0.0-rc-6230622a1a-20240610" } } \ No newline at end of file diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/package.json b/packages/next/src/compiled/react-server-dom-webpack-experimental/package.json index 4ee3b210276b5..2a519e5cd49ee 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/package.json +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/package.json @@ -46,8 +46,8 @@ "neo-async": "^2.6.1" }, "peerDependencies": { - "react": "0.0.0-experimental-1df34bdf62-20240605", - "react-dom": "0.0.0-experimental-1df34bdf62-20240605", + "react": "0.0.0-experimental-6230622a1a-20240610", + "react-dom": "0.0.0-experimental-6230622a1a-20240610", "webpack": "^5.59.0" } } \ No newline at end of file diff --git a/packages/next/src/compiled/react-server-dom-webpack/package.json b/packages/next/src/compiled/react-server-dom-webpack/package.json index c1114708c0a88..71bd27598a5b4 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/package.json +++ b/packages/next/src/compiled/react-server-dom-webpack/package.json @@ -46,8 +46,8 @@ "neo-async": "^2.6.1" }, "peerDependencies": { - "react": "19.0.0-rc-1df34bdf62-20240605", - "react-dom": "19.0.0-rc-1df34bdf62-20240605", + "react": "19.0.0-rc-6230622a1a-20240610", + "react-dom": "19.0.0-rc-6230622a1a-20240610", "webpack": "^5.59.0" } } \ No newline at end of file diff --git a/packages/next/src/compiled/react/cjs/react.development.js b/packages/next/src/compiled/react/cjs/react.development.js index 040cea6a7bffd..2b5e6c323f65f 100644 --- a/packages/next/src/compiled/react/cjs/react.development.js +++ b/packages/next/src/compiled/react/cjs/react.development.js @@ -20,7 +20,7 @@ if ( ) { __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error()); } -var ReactVersion = '19.0.0-rc-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-rc-6230622a1a-20240610'; // ----------------------------------------------------------------------------- diff --git a/packages/next/src/compiled/react/cjs/react.production.js b/packages/next/src/compiled/react/cjs/react.production.js index d316eb009852b..94a3f59a62593 100644 --- a/packages/next/src/compiled/react/cjs/react.production.js +++ b/packages/next/src/compiled/react/cjs/react.production.js @@ -536,4 +536,4 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactSharedInternals.H.useTransition(); }; -exports.version = "19.0.0-rc-1df34bdf62-20240605"; +exports.version = "19.0.0-rc-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/react/cjs/react.react-server.development.js b/packages/next/src/compiled/react/cjs/react.react-server.development.js index 98dba1d42cb0c..17c2f381a7cfa 100644 --- a/packages/next/src/compiled/react/cjs/react.react-server.development.js +++ b/packages/next/src/compiled/react/cjs/react.react-server.development.js @@ -2068,7 +2068,7 @@ function cache(fn) { }; } -var ReactVersion = '19.0.0-rc-1df34bdf62-20240605'; +var ReactVersion = '19.0.0-rc-6230622a1a-20240610'; var Children = { map: mapChildren, diff --git a/packages/next/src/compiled/react/cjs/react.react-server.production.js b/packages/next/src/compiled/react/cjs/react.react-server.production.js index 6ce229eced05b..1e80bd7250e14 100644 --- a/packages/next/src/compiled/react/cjs/react.react-server.production.js +++ b/packages/next/src/compiled/react/cjs/react.react-server.production.js @@ -424,4 +424,4 @@ exports.useId = function () { exports.useMemo = function (create, deps) { return ReactSharedInternals.H.useMemo(create, deps); }; -exports.version = "19.0.0-rc-1df34bdf62-20240605"; +exports.version = "19.0.0-rc-6230622a1a-20240610"; diff --git a/packages/next/src/compiled/unistore/unistore.js b/packages/next/src/compiled/unistore/unistore.js index 1ae669a40e336..91850c3f0d708 100644 --- a/packages/next/src/compiled/unistore/unistore.js +++ b/packages/next/src/compiled/unistore/unistore.js @@ -1 +1 @@ -(()=>{var t={59:t=>{function n(t,i){for(var _ in i)t[_]=i[_];return t}t.exports=function(t){var i=[];function u(t){for(var _=[],a=0;a{var t={448:t=>{function n(t,i){for(var _ in i)t[_]=i[_];return t}t.exports=function(t){var i=[];function u(t){for(var _=[],a=0;a=0.15.0' - version: 2.2.1(react@19.0.0-rc-1df34bdf62-20240605) + version: 2.2.1(react@19.0.0-rc-6230622a1a-20240610) source-map: specifier: ^0.7.0 version: 0.7.3 @@ -1569,8 +1569,8 @@ importers: packages/third-parties: dependencies: react: - specifier: 19.0.0-rc-1df34bdf62-20240605 - version: 19.0.0-rc-1df34bdf62-20240605 + specifier: 19.0.0-rc-6230622a1a-20240610 + version: 19.0.0-rc-6230622a1a-20240610 third-party-capital: specifier: 1.0.20 version: 1.0.20 @@ -3662,11 +3662,11 @@ packages: resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} dev: true - /@emotion/react@11.11.1(react@19.0.0-rc-1df34bdf62-20240605)(types-react@19.0.0-rc.0): + /@emotion/react@11.11.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): resolution: {integrity: sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==} peerDependencies: '@types/react': '*' - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 peerDependenciesMeta: '@types/react': optional: true @@ -3675,12 +3675,12 @@ packages: '@emotion/babel-plugin': 11.11.0 '@emotion/cache': 11.11.0 '@emotion/serialize': 1.1.2 - '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@19.0.0-rc-1df34bdf62-20240605) + '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@19.0.0-rc-6230622a1a-20240610) '@emotion/utils': 1.2.1 '@emotion/weak-memoize': 0.3.1 '@types/react': /types-react@19.0.0-rc.0 hoist-non-react-statics: 3.3.2 - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 dev: true /@emotion/serialize@1.1.2: @@ -3701,12 +3701,12 @@ packages: resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} dev: true - /@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@19.0.0-rc-1df34bdf62-20240605): + /@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@19.0.0-rc-6230622a1a-20240610): resolution: {integrity: sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==} peerDependencies: - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 dependencies: - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 dev: true /@emotion/utils@1.2.1: @@ -5593,14 +5593,14 @@ packages: transitivePeerDependencies: - supports-color - /@mdx-js/react@2.2.1(react@19.0.0-rc-1df34bdf62-20240605): + /@mdx-js/react@2.2.1(react@19.0.0-rc-6230622a1a-20240610): resolution: {integrity: sha512-YdXcMcEnqZhzql98RNrqYo9cEhTTesBiCclEtoiQUbJwx87q9453GTapYU6kJ8ZZ2ek1Vp25SiAXEFy5O/eAPw==} peerDependencies: - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 dependencies: '@types/mdx': 2.0.3 '@types/react': /types-react@19.0.0-rc.0 - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 /@mswjs/cookies@1.1.0: resolution: {integrity: sha512-0ZcCVQxifZmhwNBoQIrystCb+2sWBY2Zw8lpfJBPCHGCA/HWqehITeCRVIv4VMy8MPlaHo2w2pTHFV2pFfqKPw==} @@ -6944,13 +6944,13 @@ packages: redent: 3.0.0 dev: true - /@testing-library/react@15.0.7(react-dom@19.0.0-rc-1df34bdf62-20240605)(react@19.0.0-rc-1df34bdf62-20240605)(types-react@19.0.0-rc.0): + /@testing-library/react@15.0.7(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): resolution: {integrity: sha512-cg0RvEdD1TIhhkm1IeYMQxrzy0MtUNfa3minv4MjbgcYzJAZ7yD0i0lwoPOTPr+INtiXFezt2o8xMSnyHhEn2Q==} engines: {node: '>=18'} peerDependencies: '@types/react': npm:types-react@19.0.0-rc.0 - react: 19.0.0-rc-1df34bdf62-20240605 - react-dom: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610 peerDependenciesMeta: '@types/react': optional: true @@ -6959,8 +6959,8 @@ packages: '@testing-library/dom': 10.1.0 '@types/react': /types-react@19.0.0-rc.0 '@types/react-dom': /types-react-dom@19.0.0-rc.0 - react: 19.0.0-rc-1df34bdf62-20240605 - react-dom: 19.0.0-rc-1df34bdf62-20240605(react@19.0.0-rc-1df34bdf62-20240605) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) dev: true /@tootallnate/once@1.1.2: @@ -14143,7 +14143,7 @@ packages: /hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} dependencies: - react-is: 19.0.0-rc-1df34bdf62-20240605 + react-is: 19.0.0-rc-6230622a1a-20240610 dev: true /homedir-polyfill@1.0.3: @@ -18299,15 +18299,15 @@ packages: resolution: {integrity: sha1-yobR/ogoFpsBICCOPchCS524NCw=} dev: true - /next@14.3.0-canary.15(@babel/core@7.22.5)(@opentelemetry/api@1.4.1)(@playwright/test@1.19.2)(react-dom@19.0.0-rc-1df34bdf62-20240605)(react@19.0.0-rc-1df34bdf62-20240605)(sass@1.54.0): + /next@14.3.0-canary.15(@babel/core@7.22.5)(@opentelemetry/api@1.4.1)(@playwright/test@1.19.2)(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610)(sass@1.54.0): resolution: {integrity: sha512-vQ376NxcS/zYLJKIZRRfyis9nK+Y23KUqD8Hg93kbrgVWhJW0fZIcKf14ATm8AZg2uxDt4/vj7gVOt1QrWtMIQ==} engines: {node: '>=18.17.0'} hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 '@playwright/test': ^1.41.2 - react: 19.0.0-rc-1df34bdf62-20240605 - react-dom: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610 sass: ^1.3.0 peerDependenciesMeta: '@opentelemetry/api': @@ -18325,10 +18325,10 @@ packages: caniuse-lite: 1.0.30001579 graceful-fs: 4.2.11 postcss: 8.4.31 - react: 19.0.0-rc-1df34bdf62-20240605 - react-dom: 19.0.0-rc-1df34bdf62-20240605(react@19.0.0-rc-1df34bdf62-20240605) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) sass: 1.54.0 - styled-jsx: 5.1.1(@babel/core@7.22.5)(react@19.0.0-rc-1df34bdf62-20240605) + styled-jsx: 5.1.1(@babel/core@7.22.5)(react@19.0.0-rc-6230622a1a-20240610) optionalDependencies: '@next/swc-darwin-arm64': 14.3.0-canary.15 '@next/swc-darwin-x64': 14.3.0-canary.15 @@ -20957,7 +20957,7 @@ packages: '@jest/types': 24.9.0 ansi-regex: 4.1.0 ansi-styles: 3.2.1 - react-is: 19.0.0-rc-1df34bdf62-20240605 + react-is: 19.0.0-rc-6230622a1a-20240610 /pretty-format@27.5.1: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} @@ -20965,7 +20965,7 @@ packages: dependencies: ansi-regex: 5.0.1 ansi-styles: 5.2.0 - react-is: 19.0.0-rc-1df34bdf62-20240605 + react-is: 19.0.0-rc-6230622a1a-20240610 /pretty-format@29.5.0: resolution: {integrity: sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==} @@ -20973,7 +20973,7 @@ packages: dependencies: '@jest/schemas': 29.4.3 ansi-styles: 5.2.0 - react-is: 19.0.0-rc-1df34bdf62-20240605 + react-is: 19.0.0-rc-6230622a1a-20240610 dev: true /pretty-format@29.7.0: @@ -20982,7 +20982,7 @@ packages: dependencies: '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 - react-is: 19.0.0-rc-1df34bdf62-20240605 + react-is: 19.0.0-rc-6230622a1a-20240610 dev: true /pretty-ms@7.0.0: @@ -21084,7 +21084,7 @@ packages: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 - react-is: 19.0.0-rc-1df34bdf62-20240605 + react-is: 19.0.0-rc-6230622a1a-20240610 /proper-lockfile@4.1.2: resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} @@ -21364,36 +21364,36 @@ packages: strip-json-comments: 2.0.1 dev: true - /react-dom@0.0.0-experimental-1df34bdf62-20240605(react@19.0.0-rc-1df34bdf62-20240605): - resolution: {integrity: sha512-GOjWoRwx7tiDkrGAa0Qc6kNUuNJOi5q+OgYDR14X9mCZZz8aicl7/rNakKZ+aYU74PkJbAf3b9VKP8an6DCuhg==} + /react-dom@0.0.0-experimental-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610): + resolution: {integrity: sha512-rkLgUvHRh4Spb22M7fVs0AKEqdwiw9TMyVQmZw6pj+FJpgn0Hgqb+evnWsT0B656bwplrp/mltS727Xkw4c0uw==} peerDependencies: - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 dependencies: - react: 19.0.0-rc-1df34bdf62-20240605 - scheduler: 0.25.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 + scheduler: 0.25.0-rc-6230622a1a-20240610 dev: true - /react-dom@17.0.2(react@19.0.0-rc-1df34bdf62-20240605): + /react-dom@17.0.2(react@19.0.0-rc-6230622a1a-20240610): resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==} peerDependencies: - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 - react: 19.0.0-rc-1df34bdf62-20240605 - scheduler: 0.25.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 + scheduler: 0.25.0-rc-6230622a1a-20240610 dev: true - /react-dom@19.0.0-rc-1df34bdf62-20240605(react@19.0.0-rc-1df34bdf62-20240605): - resolution: {integrity: sha512-rhPZXaFc9lDagraujwbFFRoV84om75D0VpP1EVcfoclsNdcj7aD+dFgjY6nATQ6n0jNr+OPyH+kagRzfQeuGNQ==} + /react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610): + resolution: {integrity: sha512-56G4Pum5E7FeGL1rwHX5IxidSJxQnXP4yORRo0pVeOJuu5DQJvNKpUwmJoftMP/ez0AiglYTY77L2Gs8iyt1Hg==} peerDependencies: - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 dependencies: - react: 19.0.0-rc-1df34bdf62-20240605 - scheduler: 0.25.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 + scheduler: 0.25.0-rc-6230622a1a-20240610 - /react-is@19.0.0-rc-1df34bdf62-20240605: - resolution: {integrity: sha512-StF0rCxn2SXQQOHpTWJCsCpUSajQech83s6XZeQzdiGAviBIaoPFVxna8tkxb8+b0adHqHPq7Jv7ckNAPlCLhQ==} + /react-is@19.0.0-rc-6230622a1a-20240610: + resolution: {integrity: sha512-6BH4F/xpoTJ+BTcb2AmZAzWXInEPUNKgL4u4C1BssZmFkGsvUpZmllLgCEVa105omvex85ZWwKHCy22KftGwDw==} /react-lifecycles-compat@3.0.4: resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} @@ -21404,91 +21404,91 @@ packages: engines: {node: '>=0.10.0'} dev: true - /react-server-dom-turbopack@0.0.0-experimental-1df34bdf62-20240605(react-dom@19.0.0-rc-1df34bdf62-20240605)(react@19.0.0-rc-1df34bdf62-20240605): - resolution: {integrity: sha512-Cw3GcTAEkiPhzppdSdgb8iC5PxK1dhjNgVhFrfijbXQSExPCS/fMohaUymqZ+QhYss0PBuothqjBV3HvtPZQSw==} + /react-server-dom-turbopack@0.0.0-experimental-6230622a1a-20240610(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610): + resolution: {integrity: sha512-U/7v8k6XS+EPSn46S8/7igwIkNdlfLRjWOCYNxXRs1/nC/BQa/gYUti4bGrMJ7b/2h7WWIHQOdGZRxOvUKIBHg==} engines: {node: '>=0.10.0'} peerDependencies: - react: 19.0.0-rc-1df34bdf62-20240605 - react-dom: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610 dependencies: acorn-loose: 8.3.0 neo-async: 2.6.1 - react: 19.0.0-rc-1df34bdf62-20240605 - react-dom: 19.0.0-rc-1df34bdf62-20240605(react@19.0.0-rc-1df34bdf62-20240605) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) dev: true - /react-server-dom-turbopack@19.0.0-rc-1df34bdf62-20240605(react-dom@19.0.0-rc-1df34bdf62-20240605)(react@19.0.0-rc-1df34bdf62-20240605): - resolution: {integrity: sha512-lhVtmo5Eo5KCxGefWpcdsbjjadsIZXn8bl9kBrrYxmp34UShuCGoydNAO5Eg9jmQchKvcuzomKaSIQpOjzpQiA==} + /react-server-dom-turbopack@19.0.0-rc-6230622a1a-20240610(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610): + resolution: {integrity: sha512-nhNFHBAB48CMxRZWRo1yrNAbqLrOnDtE6FiSCZuMCkkyiQYtVnWWVIS06O/unlZlY72A97XQyZX9K8RYb8K3iQ==} engines: {node: '>=0.10.0'} peerDependencies: - react: 19.0.0-rc-1df34bdf62-20240605 - react-dom: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610 dependencies: acorn-loose: 8.3.0 neo-async: 2.6.1 - react: 19.0.0-rc-1df34bdf62-20240605 - react-dom: 19.0.0-rc-1df34bdf62-20240605(react@19.0.0-rc-1df34bdf62-20240605) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) dev: true - /react-server-dom-webpack@0.0.0-experimental-1df34bdf62-20240605(react-dom@19.0.0-rc-1df34bdf62-20240605)(react@19.0.0-rc-1df34bdf62-20240605)(webpack@5.90.0): - resolution: {integrity: sha512-ALhLfh1eVQcElQb3DpgF/n9CqR7ldo5QUq3i4JEgyeYKXUgpnUS2SzSRoDTXSL0E4OvublQF3tFSGnVqnOTWgw==} + /react-server-dom-webpack@0.0.0-experimental-6230622a1a-20240610(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610)(webpack@5.90.0): + resolution: {integrity: sha512-HunYxzgNQJ3QCB+wt/X1S0/jalfRWujzHZK5nn5lM72T14M+XEg0mspF55Rmm2+RDE++eFbVqiVLlwFOZ8ln3w==} engines: {node: '>=0.10.0'} peerDependencies: - react: 19.0.0-rc-1df34bdf62-20240605 - react-dom: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610 webpack: 5.90.0 dependencies: acorn-loose: 8.3.0 neo-async: 2.6.1 - react: 19.0.0-rc-1df34bdf62-20240605 - react-dom: 19.0.0-rc-1df34bdf62-20240605(react@19.0.0-rc-1df34bdf62-20240605) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) webpack: 5.90.0(@swc/core@1.5.7) dev: true - /react-server-dom-webpack@19.0.0-rc-1df34bdf62-20240605(react-dom@19.0.0-rc-1df34bdf62-20240605)(react@19.0.0-rc-1df34bdf62-20240605)(webpack@5.90.0): - resolution: {integrity: sha512-SHiKb0QVH/sCVHU1MYI0M6WsS5QqLfMXIaVYyDjptnES3JT18O5nM7LCRNqykqS7xgk2eP+IKUWNHf/Qq7AZDw==} + /react-server-dom-webpack@19.0.0-rc-6230622a1a-20240610(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610)(webpack@5.90.0): + resolution: {integrity: sha512-nr+IsOVD07QdeCr4BLvR5TALfLaZLi9AIaoa6vXymBc051iDPWedJujYYrjRJy5+9jp9oCx3G8Tt/Bs//TckJw==} engines: {node: '>=0.10.0'} peerDependencies: - react: 19.0.0-rc-1df34bdf62-20240605 - react-dom: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610 webpack: 5.90.0 dependencies: acorn-loose: 8.3.0 neo-async: 2.6.1 - react: 19.0.0-rc-1df34bdf62-20240605 - react-dom: 19.0.0-rc-1df34bdf62-20240605(react@19.0.0-rc-1df34bdf62-20240605) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) webpack: 5.90.0(@swc/core@1.5.7) dev: true - /react-ssr-prepass@1.0.8(react-is@19.0.0-rc-1df34bdf62-20240605)(react@19.0.0-rc-1df34bdf62-20240605): + /react-ssr-prepass@1.0.8(react-is@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610): resolution: {integrity: sha512-O0gfRA1SaK+9ITKxqfnXsej2jF+OHGP/+GxD4unROQaM/0/UczGF9fuF+wTboxaQoKdIf4FvS3h/OigWh704VA==} peerDependencies: - react: 19.0.0-rc-1df34bdf62-20240605 - react-is: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 + react-is: 19.0.0-rc-6230622a1a-20240610 dependencies: object-is: 1.0.2 - react: 19.0.0-rc-1df34bdf62-20240605 - react-is: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 + react-is: 19.0.0-rc-6230622a1a-20240610 dev: true - /react-virtualized@9.22.3(react-dom@19.0.0-rc-1df34bdf62-20240605)(react@19.0.0-rc-1df34bdf62-20240605): + /react-virtualized@9.22.3(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610): resolution: {integrity: sha512-MKovKMxWTcwPSxE1kK1HcheQTWfuCxAuBoSTf2gwyMM21NdX/PXUhnoP8Uc5dRKd+nKm8v41R36OellhdCpkrw==} peerDependencies: - react: 19.0.0-rc-1df34bdf62-20240605 - react-dom: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610 dependencies: '@babel/runtime': 7.22.5 clsx: 1.1.1 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 19.0.0-rc-1df34bdf62-20240605 - react-dom: 19.0.0-rc-1df34bdf62-20240605(react@19.0.0-rc-1df34bdf62-20240605) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) react-lifecycles-compat: 3.0.4 dev: true - /react@0.0.0-experimental-1df34bdf62-20240605: - resolution: {integrity: sha512-87pB4CziP34PuDHa7jAIDTW7CpKNDmXn85XNRJGVJf1dHCBbSRuQYKOdNGwfX55Nr5GQIwS16Ux8VsGaXmqBww==} + /react@0.0.0-experimental-6230622a1a-20240610: + resolution: {integrity: sha512-A6J2Uj5Jzgz8pLOj9qyyTEQ0v5SwyT6JASC56XxjAwbi9ckb3UwwG6lTjF+rltg4poT3fjPcPyRjd2Q4cWZy/Q==} engines: {node: '>=0.10.0'} dev: true @@ -21500,8 +21500,8 @@ packages: object-assign: 4.1.1 dev: true - /react@19.0.0-rc-1df34bdf62-20240605: - resolution: {integrity: sha512-FDsCKRtf4Ee3JzBVu2eZRHSWIV2HBFO8jcnEzhH9l2SG1ouA7pdnAxS3s/vA6EqvNOs0gPXqzqFkMJ5sbwQjIQ==} + /react@19.0.0-rc-6230622a1a-20240610: + resolution: {integrity: sha512-SMgWGY//7nO7F3HMuBfmC15Cr4vTe2tlpSCATfnz/wymSftDOKUqc+0smjRhcUeCFCc1zhOAWJ+N//U5CrmOzQ==} engines: {node: '>=0.10.0'} /read-cache@1.0.0: @@ -22505,12 +22505,12 @@ packages: xmlchars: 2.2.0 dev: true - /scheduler@0.0.0-experimental-1df34bdf62-20240605: - resolution: {integrity: sha512-j7dyetNE5KhnJkgnKY1pub6Ad9qpIaF8caYHCo6O0Y2Mu/eOMBtJIHpWe0PlH22b48G8merIec2MPpSlZ+6hZw==} + /scheduler@0.0.0-experimental-6230622a1a-20240610: + resolution: {integrity: sha512-jJZKVNvX9z+p8keIDncyZldGXNZVTBvHrBVWyJ6X9UYxZCtWgbRS0HGLXY9Doqz63wwg1SRIUX7cbgmwF30xKg==} dev: true - /scheduler@0.25.0-rc-1df34bdf62-20240605: - resolution: {integrity: sha512-MDeym3H4Wj0p9M9/68P3lr+vTiVTtBY7hy5pX0bTRvf5B6pmF2lYEBs7MrwbAJEF9NsDdjGFQViW2jv7Y8DZaQ==} + /scheduler@0.25.0-rc-6230622a1a-20240610: + resolution: {integrity: sha512-GTIQdJXthps5mgkIFo7yAq03M0QQYTfN8z+GrnMC/SCKFSuyFP5tk2BMaaWUsVy4u4r+dTLdiXH8JEivVls0Bw==} /schema-utils@2.7.1: resolution: {integrity: sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==} @@ -23532,13 +23532,13 @@ packages: dependencies: inline-style-parser: 0.1.1 - /styled-components@6.0.0-rc.3(react-dom@19.0.0-rc-1df34bdf62-20240605)(react@19.0.0-rc-1df34bdf62-20240605): + /styled-components@6.0.0-rc.3(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610): resolution: {integrity: sha512-5FbCTxynopck99GRwM5Ey0+VRp8pkQq69TwGOJJeYtR7gPvwGjNx8yBPLN7/dfxwwvn9ymOZYB19eQkv2k70wQ==} engines: {node: '>= 16'} peerDependencies: babel-plugin-styled-components: '>= 2' - react: 19.0.0-rc-1df34bdf62-20240605 - react-dom: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610 peerDependenciesMeta: babel-plugin-styled-components: optional: true @@ -23556,8 +23556,8 @@ packages: '@emotion/unitless': 0.8.1 css-to-react-native: 3.2.0 postcss: 8.4.31 - react: 19.0.0-rc-1df34bdf62-20240605 - react-dom: 19.0.0-rc-1df34bdf62-20240605(react@19.0.0-rc-1df34bdf62-20240605) + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) shallowequal: 1.1.0 stylis: 4.2.0 tslib: 2.5.3 @@ -23572,13 +23572,13 @@ packages: postcss-load-plugins: 2.3.0 dev: true - /styled-jsx@5.1.1(@babel/core@7.22.5)(react@19.0.0-rc-1df34bdf62-20240605): + /styled-jsx@5.1.1(@babel/core@7.22.5)(react@19.0.0-rc-6230622a1a-20240610): resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} engines: {node: '>= 12.0.0'} peerDependencies: '@babel/core': '*' babel-plugin-macros: '*' - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 peerDependenciesMeta: '@babel/core': optional: true @@ -23587,16 +23587,16 @@ packages: dependencies: '@babel/core': 7.22.5 client-only: 0.0.1 - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 dev: false - /styled-jsx@5.1.6(@babel/core@7.22.5)(react@19.0.0-rc-1df34bdf62-20240605): + /styled-jsx@5.1.6(@babel/core@7.22.5)(react@19.0.0-rc-6230622a1a-20240610): resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} engines: {node: '>= 12.0.0'} peerDependencies: '@babel/core': '*' babel-plugin-macros: '*' - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 peerDependenciesMeta: '@babel/core': optional: true @@ -23605,7 +23605,7 @@ packages: dependencies: '@babel/core': 7.22.5 client-only: 0.0.1 - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 /stylehacks@4.0.3: resolution: {integrity: sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==} @@ -23739,14 +23739,14 @@ packages: stable: 0.1.8 dev: true - /swr@2.2.4(react@19.0.0-rc-1df34bdf62-20240605): + /swr@2.2.4(react@19.0.0-rc-6230622a1a-20240610): resolution: {integrity: sha512-njiZ/4RiIhoOlAaLYDqwz5qH/KZXVilRLvomrx83HjzCWTfa+InyfAjv05PSFxnmLzZkNO9ZfvgoqzAaEI4sGQ==} peerDependencies: - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 dependencies: client-only: 0.0.1 - react: 19.0.0-rc-1df34bdf62-20240605 - use-sync-external-store: 1.2.0(react@19.0.0-rc-1df34bdf62-20240605) + react: 19.0.0-rc-6230622a1a-20240610 + use-sync-external-store: 1.2.0(react@19.0.0-rc-6230622a1a-20240610) dev: true /symbol-observable@1.0.1: @@ -24842,7 +24842,7 @@ packages: unist-util-is: 5.2.0 unist-util-visit-parents: 5.1.3 - /unistore@3.4.1(react@19.0.0-rc-1df34bdf62-20240605): + /unistore@3.4.1(react@19.0.0-rc-6230622a1a-20240610): resolution: {integrity: sha512-p2Ej8qqrqcD10Ah0ZUKUU/mhRB8pM4q6gzjxq9kZpgxa8dks7oHT8jDP4CqLhoRof3RXOZLKB9EBV1DTzHiJRw==} peerDependencies: preact: '*' @@ -24853,7 +24853,7 @@ packages: react: optional: true dependencies: - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 dev: true /universal-github-app-jwt@1.1.1: @@ -25008,12 +25008,12 @@ packages: engines: {node: '>= 4'} dev: true - /use-sync-external-store@1.2.0(react@19.0.0-rc-1df34bdf62-20240605): + /use-sync-external-store@1.2.0(react@19.0.0-rc-6230622a1a-20240610): resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} peerDependencies: - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 dependencies: - react: 19.0.0-rc-1df34bdf62-20240605 + react: 19.0.0-rc-6230622a1a-20240610 dev: true /use@3.1.1: diff --git a/test/.stats-app/package.json b/test/.stats-app/package.json index e85c3567f8205..12142589b0134 100644 --- a/test/.stats-app/package.json +++ b/test/.stats-app/package.json @@ -3,9 +3,9 @@ "private": true, "license": "MIT", "dependencies": { - "next": "19.0.0-rc-1df34bdf62-20240605", - "react": "19.0.0-rc-1df34bdf62-20240605", - "react-dom": "19.0.0-rc-1df34bdf62-20240605" + "next": "19.0.0-rc-6230622a1a-20240610", + "react": "19.0.0-rc-6230622a1a-20240610", + "react-dom": "19.0.0-rc-6230622a1a-20240610" }, "engines": { "node": ">=18.17.0", From 8bac76a5b3073319cf8d4449fc8a26e7c8dc6104 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Tue, 11 Jun 2024 00:13:55 +0000 Subject: [PATCH 21/60] v15.0.0-canary.25 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 12 ++++++------ packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 14 +++++++------- 17 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lerna.json b/lerna.json index ec450eea586cb..c3bdab6d1098d 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "15.0.0-canary.24" + "version": "15.0.0-canary.25" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 1953229936705..c0220da4eea19 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "15.0.0-canary.24", + "version": "15.0.0-canary.25", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 124ad6b3dff5e..af8a52fad51a2 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "15.0.0-canary.24", + "version": "15.0.0-canary.25", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "15.0.0-canary.24", + "@next/eslint-plugin-next": "15.0.0-canary.25", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 73b40f6ad9ae1..1655ba6ad37eb 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "15.0.0-canary.24", + "version": "15.0.0-canary.25", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 5541ca4f3b5fc..21816345b5c39 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "15.0.0-canary.24", + "version": "15.0.0-canary.25", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 3783a84156724..75806b74ac495 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "15.0.0-canary.24", + "version": "15.0.0-canary.25", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index a37de0b5cadbe..2587dbe02118a 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "15.0.0-canary.24", + "version": "15.0.0-canary.25", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 02439a126ac1e..47211a3f5667b 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "15.0.0-canary.24", + "version": "15.0.0-canary.25", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 1e92ab8d9bc31..c8b38de241f7c 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "15.0.0-canary.24", + "version": "15.0.0-canary.25", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 89b32ab422baf..5ff3cf7f0fd7f 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "15.0.0-canary.24", + "version": "15.0.0-canary.25", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 28c7975ba703c..8a5c49bba3472 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "15.0.0-canary.24", + "version": "15.0.0-canary.25", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 44df70682e50b..5ba0187a703c4 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "15.0.0-canary.24", + "version": "15.0.0-canary.25", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index dbe984313bc31..78cd19bdeb97c 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "15.0.0-canary.24", + "version": "15.0.0-canary.25", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index e3801961535e8..6bcdf71ce10e1 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "15.0.0-canary.24", + "version": "15.0.0-canary.25", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -93,7 +93,7 @@ ] }, "dependencies": { - "@next/env": "15.0.0-canary.24", + "@next/env": "15.0.0-canary.25", "@swc/helpers": "0.5.11", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -157,10 +157,10 @@ "@jest/types": "29.5.0", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/polyfill-module": "15.0.0-canary.24", - "@next/polyfill-nomodule": "15.0.0-canary.24", - "@next/react-refresh-utils": "15.0.0-canary.24", - "@next/swc": "15.0.0-canary.24", + "@next/polyfill-module": "15.0.0-canary.25", + "@next/polyfill-nomodule": "15.0.0-canary.25", + "@next/react-refresh-utils": "15.0.0-canary.25", + "@next/swc": "15.0.0-canary.25", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.41.2", "@swc/core": "1.5.7", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 6cbe8f4321e28..f0ad59412e96d 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "15.0.0-canary.24", + "version": "15.0.0-canary.25", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 61578a8281c5a..8ccf3857b714e 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "15.0.0-canary.24", + "version": "15.0.0-canary.25", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -26,7 +26,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "15.0.0-canary.24", + "next": "15.0.0-canary.25", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 12178429cf39e..88142bd78392c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -753,7 +753,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 15.0.0-canary.24 + specifier: 15.0.0-canary.25 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -815,7 +815,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 15.0.0-canary.24 + specifier: 15.0.0-canary.25 version: link:../next-env '@swc/helpers': specifier: 0.5.11 @@ -943,16 +943,16 @@ importers: specifier: 1.2.0 version: 1.2.0 '@next/polyfill-module': - specifier: 15.0.0-canary.24 + specifier: 15.0.0-canary.25 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 15.0.0-canary.24 + specifier: 15.0.0-canary.25 version: link:../next-polyfill-nomodule '@next/react-refresh-utils': - specifier: 15.0.0-canary.24 + specifier: 15.0.0-canary.25 version: link:../react-refresh-utils '@next/swc': - specifier: 15.0.0-canary.24 + specifier: 15.0.0-canary.25 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1576,7 +1576,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 15.0.0-canary.24 + specifier: 15.0.0-canary.25 version: link:../next outdent: specifier: 0.8.0 From db9170c2b89c5cdebe40f83256ccbe58fd69fa06 Mon Sep 17 00:00:00 2001 From: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com> Date: Tue, 11 Jun 2024 14:30:42 +0100 Subject: [PATCH 22/60] Docs: Fix typo (#66749) Fix typo in `unstable_cache` API page. re: https://github.com/vercel/next.js/pull/66716 --- docs/02-app/02-api-reference/04-functions/unstable_after.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/02-app/02-api-reference/04-functions/unstable_after.mdx b/docs/02-app/02-api-reference/04-functions/unstable_after.mdx index 6d33ddc4ad185..21efe30979431 100644 --- a/docs/02-app/02-api-reference/04-functions/unstable_after.mdx +++ b/docs/02-app/02-api-reference/04-functions/unstable_after.mdx @@ -68,7 +68,7 @@ export default function Layout({ children }) { The use case for `unstable_after()` is to process secondary tasks without blocking the primary response. It's similar to using the platform's [`waitUntil()`](https://vercel.com/docs/functions/functions-api-reference) or removing `await` from a promise, but with the following differences: -- **[`waitUntil()`]**: accepts promise and enqueues a task to be executed during the lifecycle of the request, whereas `unstable_after()` accepts a callback that will be executed **after** the response is finished. +- **`waitUntil()`**: accepts a promise and enqueues a task to be executed during the lifecycle of the request, whereas `unstable_after()` accepts a callback that will be executed **after** the response is finished. - **Removing `await`**: starts executing during the response, which uses resources. It's also not reliable in serverless environments as the function stops computation immediately after the response is sent, potentially interrupting the task. We recommend using `unstable_after()` as it has been designed to consider other Next.js APIs and contexts. From 12190afcd3c38497641f022008c5e43008858134 Mon Sep 17 00:00:00 2001 From: Karim Shehadeh Date: Tue, 11 Jun 2024 10:29:02 -0400 Subject: [PATCH 23/60] Prevent append of trailing slash in cases where path ends with a file extension (#66636) ### What Skip adding trailing slash for file pattern like same origin urls ### Why Fixes #66635 Next.js will not append trailing slash for file like pattern urls when `trailingSlash` is enabled. This PR aligns the behavior of the metadata trailing slash appending with next-server route handling. --------- Co-authored-by: Jiachi Liu --- .../metadata/resolvers/resolve-url.test.ts | 11 ++++++++++ .../src/lib/metadata/resolvers/resolve-url.ts | 20 +++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/packages/next/src/lib/metadata/resolvers/resolve-url.test.ts b/packages/next/src/lib/metadata/resolvers/resolve-url.test.ts index b9e1caf796aa5..d70c7bc5dc81a 100644 --- a/packages/next/src/lib/metadata/resolvers/resolve-url.test.ts +++ b/packages/next/src/lib/metadata/resolvers/resolve-url.test.ts @@ -110,6 +110,17 @@ describe('resolveAbsoluteUrlWithPathname', () => { 'https://example.com/foo?bar' ) }) + + it('should not add trailing slash to relative url that matches file pattern', () => { + expect(resolver('/foo.html')).toBe('https://example.com/foo.html') + expect(resolver('/foo.html?q=v')).toBe('https://example.com/foo.html?q=v') + expect(resolver(new URL('/.well-known/bar.jpg', metadataBase))).toBe( + 'https://example.com/.well-known/bar.jpg/' + ) + expect(resolver(new URL('/foo.html', metadataBase))).toBe( + 'https://example.com/foo.html' + ) + }) }) }) diff --git a/packages/next/src/lib/metadata/resolvers/resolve-url.ts b/packages/next/src/lib/metadata/resolvers/resolve-url.ts index 89edce00fa6db..6b4a25bebf3e9 100644 --- a/packages/next/src/lib/metadata/resolvers/resolve-url.ts +++ b/packages/next/src/lib/metadata/resolvers/resolve-url.ts @@ -86,6 +86,13 @@ function resolveRelativeUrl(url: string | URL, pathname: string): string | URL { return url } +// The regex is matching logic from packages/next/src/lib/load-custom-routes.ts +const FILE_REGEX = + /^(?:\/((?!\.well-known(?:\/.*)?)(?:[^/]+\/)*[^/]+\.\w+))(\/?|$)/i +function isFilePattern(pathname: string): boolean { + return FILE_REGEX.test(pathname) +} + // Resolve `pathname` if `url` is a relative path the compose with `metadataBase`. function resolveAbsoluteUrlWithPathname( url: string | URL, @@ -110,18 +117,27 @@ function resolveAbsoluteUrlWithPathname( // - Doesn't have query if (trailingSlash && !resolvedUrl.endsWith('/')) { let isRelative = resolvedUrl.startsWith('/') - let isExternal = false let hasQuery = resolvedUrl.includes('?') + let isExternal = false + let isFileUrl = false + if (!isRelative) { try { const parsedUrl = new URL(resolvedUrl) isExternal = metadataBase != null && parsedUrl.origin !== metadataBase.origin + isFileUrl = isFilePattern(parsedUrl.pathname) } catch { // If it's not a valid URL, treat it as external isExternal = true } - if (!isExternal && !hasQuery) return `${resolvedUrl}/` + if ( + // Do not apply trailing slash for file like urls, aligning with the behavior with `trailingSlash` + !isFileUrl && + !isExternal && + !hasQuery + ) + return `${resolvedUrl}/` } } From f6bdd11c5bdcc7f115e696b67946cdcd57705b23 Mon Sep 17 00:00:00 2001 From: Vercel Release Bot <88769842+vercel-release-bot@users.noreply.github.com> Date: Tue, 11 Jun 2024 11:01:47 -0400 Subject: [PATCH 24/60] Update font data (#66730) This auto-generated PR updates font data with latest available --- packages/font/src/google/font-data.json | 26 +++++++++++++++++----- packages/font/src/google/index.ts | 29 +++++++++++++++++++------ 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/packages/font/src/google/font-data.json b/packages/font/src/google/font-data.json index c4a78a18f81f0..29e18ae7d101a 100644 --- a/packages/font/src/google/font-data.json +++ b/packages/font/src/google/font-data.json @@ -496,9 +496,17 @@ "subsets": ["devanagari", "latin", "latin-ext"] }, "Anaheim": { - "weights": ["400"], + "weights": ["400", "500", "600", "700", "800", "variable"], "styles": ["normal"], - "subsets": ["latin", "latin-ext"] + "axes": [ + { + "tag": "wght", + "min": 400, + "max": 800, + "defaultValue": 400 + } + ], + "subsets": ["latin", "latin-ext", "vietnamese"] }, "Andada Pro": { "weights": ["400", "500", "600", "700", "800", "variable"], @@ -4771,7 +4779,7 @@ "Holtwood One SC": { "weights": ["400"], "styles": ["normal"], - "subsets": ["latin"] + "subsets": ["latin", "latin-ext"] }, "Homemade Apple": { "weights": ["400"], @@ -7096,8 +7104,16 @@ "subsets": ["latin", "latin-ext"] }, "Monda": { - "weights": ["400", "700"], + "weights": ["400", "500", "600", "700", "variable"], "styles": ["normal"], + "axes": [ + { + "tag": "wght", + "min": 400, + "max": 700, + "defaultValue": 400 + } + ], "subsets": ["latin", "latin-ext", "vietnamese"] }, "Monofett": { @@ -8292,7 +8308,7 @@ "defaultValue": 400 } ], - "subsets": ["hebrew", "latin", "latin-ext"] + "subsets": ["cyrillic-ext", "greek-ext", "hebrew", "latin", "latin-ext"] }, "Noto Sans Imperial Aramaic": { "weights": ["400"], diff --git a/packages/font/src/google/index.ts b/packages/font/src/google/index.ts index 0b764d7bb19ad..dd161be8a5fa6 100644 --- a/packages/font/src/google/index.ts +++ b/packages/font/src/google/index.ts @@ -926,15 +926,22 @@ export declare function Amita< }): T extends undefined ? NextFont : NextFontWithVariable export declare function Anaheim< T extends CssVariable | undefined = undefined, ->(options: { - weight: '400' | Array<'400'> +>(options?: { + weight?: + | '400' + | '500' + | '600' + | '700' + | '800' + | 'variable' + | Array<'400' | '500' | '600' | '700' | '800'> style?: 'normal' | Array<'normal'> display?: Display variable?: T preload?: boolean fallback?: string[] adjustFontFallback?: boolean - subsets?: Array<'latin' | 'latin-ext'> + subsets?: Array<'latin' | 'latin-ext' | 'vietnamese'> }): T extends undefined ? NextFont : NextFontWithVariable export declare function Andada_Pro< T extends CssVariable | undefined = undefined, @@ -8419,7 +8426,7 @@ export declare function Holtwood_One_SC< preload?: boolean fallback?: string[] adjustFontFallback?: boolean - subsets?: Array<'latin'> + subsets?: Array<'latin' | 'latin-ext'> }): T extends undefined ? NextFont : NextFontWithVariable export declare function Homemade_Apple< T extends CssVariable | undefined = undefined, @@ -12815,8 +12822,14 @@ export declare function Molle< }): T extends undefined ? NextFont : NextFontWithVariable export declare function Monda< T extends CssVariable | undefined = undefined, ->(options: { - weight: '400' | '700' | Array<'400' | '700'> +>(options?: { + weight?: + | '400' + | '500' + | '600' + | '700' + | 'variable' + | Array<'400' | '500' | '600' | '700'> style?: 'normal' | Array<'normal'> display?: Display variable?: T @@ -14680,7 +14693,9 @@ export declare function Noto_Sans_Hebrew< preload?: boolean fallback?: string[] adjustFontFallback?: boolean - subsets?: Array<'hebrew' | 'latin' | 'latin-ext'> + subsets?: Array< + 'cyrillic-ext' | 'greek-ext' | 'hebrew' | 'latin' | 'latin-ext' + > axes?: 'wdth'[] }): T extends undefined ? NextFont : NextFontWithVariable export declare function Noto_Sans_Imperial_Aramaic< From 73e4895dfaeb5ac2f8efba90171140272f527b14 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Tue, 11 Jun 2024 17:19:23 +0200 Subject: [PATCH 25/60] Use addDependency to track metadata route file changes (#66714) ### What Use `addDependency` to track the file path passed to `next-metadata-route-loader` NOTE: We cannot apply the `next-metadata-route-loader` directly to the metatda convention source files, since the json file could be processed by json loader (Related previous fix #62615) ### Why Previously when we passed down the file path as argument to the loader, which sort of breaking the caching of webpack as the actual resource path is string, it's not tracked as a dependency. This change fixed the bad caching issue of static metadata routes. Based on the above reason we use `addDependency` here to track the dependency change Closes NEXT-3521 Closes #65755 --- .../build/webpack/loaders/next-app-loader.ts | 1 - .../loaders/next-metadata-route-loader.ts | 5 +- .../app/favicon.ico | Bin 0 -> 1406 bytes .../app/favicon.ico.new | Bin 0 -> 5430 bytes .../app/opengraph-image.png | Bin 0 -> 1545 bytes .../app/opengraph-image.png.new | Bin 0 -> 46715 bytes .../metadata-static-route-cache.test.ts | 52 ++++++++++++++++++ test/turbopack-build-tests-manifest.json | 9 +++ 8 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 test/production/app-dir/metadata-static-route-cache/app/favicon.ico create mode 100644 test/production/app-dir/metadata-static-route-cache/app/favicon.ico.new create mode 100644 test/production/app-dir/metadata-static-route-cache/app/opengraph-image.png create mode 100644 test/production/app-dir/metadata-static-route-cache/app/opengraph-image.png.new create mode 100644 test/production/app-dir/metadata-static-route-cache/metadata-static-route-cache.test.ts diff --git a/packages/next/src/build/webpack/loaders/next-app-loader.ts b/packages/next/src/build/webpack/loaders/next-app-loader.ts index 728cc5f8427ee..5d49a3a3e3fad 100644 --- a/packages/next/src/build/webpack/loaders/next-app-loader.ts +++ b/packages/next/src/build/webpack/loaders/next-app-loader.ts @@ -127,7 +127,6 @@ async function createAppRouteCode({ const isDynamicRouteExtension = pageExtensions.includes(ext) resolvedPagePath = `next-metadata-route-loader?${stringify({ - page, filePath: resolvedPagePath, isDynamicRouteExtension: isDynamicRouteExtension ? '1' : '0', })}!?${WEBPACK_RESOURCE_QUERIES.metadataRoute}` diff --git a/packages/next/src/build/webpack/loaders/next-metadata-route-loader.ts b/packages/next/src/build/webpack/loaders/next-metadata-route-loader.ts index b0cee835f9d40..e49475b52fb4c 100644 --- a/packages/next/src/build/webpack/loaders/next-metadata-route-loader.ts +++ b/packages/next/src/build/webpack/loaders/next-metadata-route-loader.ts @@ -21,10 +21,10 @@ const cacheHeader = { } type MetadataRouteLoaderOptions = { - page: string + // Using separate argument to avoid json being parsed and hit error + // x-ref: https://github.com/vercel/next.js/pull/62615 filePath: string isDynamicRouteExtension: '1' | '0' - isDynamicMultiRoute: '1' | '0' } export function getFilenameAndExtension(resourcePath: string) { @@ -248,6 +248,7 @@ const nextMetadataRouterLoader: webpack.LoaderDefinitionFunction|C8fRCQc@{1W|Z_W(=?f8@|Y&WRE)<= zW3ootQJF+GWsPBI*gPk(Ye_r1@%wFeSE@h!)Bnz$bIy0Zx!*l=&jIx4v9N&7B8>nm zitMOsDO>7#FriTg#_~V7q3Ale&w8QnsszKZP!ION+^HU-@-kFqcfgic0^_Lf2)NS; z52*@nscpF3!JsfR1EcIH80su_g^GdSH3>d9yhEN!g|E4rL$#8ny;wA) zzl4!vC)Kg2jL%1~S2g;QK47T%1qPbb5J&W(LiiCfnGB|`gXj@u!MJ4vm7(ouyIF^b zxORL=9;A8=k{#j^oybRAO)0X|`oQa35q^15D>C{>v6)dnnFmBE3MBF;_gG1Y{%GTZH%>< zO_m*?U61HEgUEw~7|-&Z7ISRF8Ooek$m01bKNt)!z!*8OfZuFqJ9B8MpOa- literal 0 HcmV?d00001 diff --git a/test/production/app-dir/metadata-static-route-cache/app/favicon.ico.new b/test/production/app-dir/metadata-static-route-cache/app/favicon.ico.new new file mode 100644 index 0000000000000000000000000000000000000000..82339b3b1dbbcf4550b737faf99c7774196fb8cb GIT binary patch literal 5430 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 literal 0 HcmV?d00001 diff --git a/test/production/app-dir/metadata-static-route-cache/app/opengraph-image.png.new b/test/production/app-dir/metadata-static-route-cache/app/opengraph-image.png.new new file mode 100644 index 0000000000000000000000000000000000000000..b7bb4dc1497bac8e6f4c339b760dcecbc67de692 GIT binary patch literal 46715 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 Sp zOVd&fKiPEUh{fCxHkoy8=)A-CtH)I3Yjrg%8!S} zSFCh)i?o;Sb1Q7@D&|z^Mi&XET{9A~t=zT1c}nqU8BeD+qhx7!>(*x-iP@<(NoKCf zS&3Cb{KzFh(Mx)8+J&3by}!B7eJ`S( zw*K@OWFw>NKstq?i^$lpqE_#_4=x&d7;X{7<-BkHy8GtJ^=Edal?`rq9i?_4)2c1? zh(M;8dR%HsS7xGy-bRb0k5y z@0m$Oc}{cmlFQPjB_&~oA|6NIiapQF!SAHC?%26ZK2yd-F(xU?4wqFf?px4tB&&Ks zNy&w_;1YR>rr<2$I?rN}Ye~^vM+Q=(*SC$ain8fTO|h5$buA&odc)sHw_wRZ&7xbjahcT?_gg zkColKyl%&A`KQq-Zr_7qQ{24lkC=Jy<$s>~)in8>V^fAkTdLEg0lB|Qc$c)bso~m9 zZbq?It!{Brrh6~!^$zLiD{Ased~4O@5$Dl#x5QQK!gX`ErY@O%>!W<^Gt;oQ<0tHY zEX{xLH}qE_ib-7$4>~IKU6q^K@u%0AW4<)MBBqU~SOd}m2JLABn;VAy%0okjF28bT zRn=46%#oR?y-RIsQ=*`Yt4MNYTQgQ}Oh-<0igb~1>^6rsB~$*6)aFjlI77UoihWa8 zbg{54iCgfYJfro+W42WtP-|;_e7*eh=}A7fH#S#nz3~0*^XEfGu{Oi6QEi;|+^wRs z&V1-ZuJ@3IjY)aC`G&NP)Y&OMPpT3ZSYOQ4d>7yuW?1|sjxm!rzL1DUMo_&AxG|SN;O-8gU}{K)Lt z#s!fNR!n+srrIQ*q}XX?e7@>yc5-LU*K9uzqPAUz)A8Y&v5B@up(Z9h-r#ZtYVEDMFxY+%F{y*+N zbjZK))~fjB47-MAi~AQa!U0K0((2@_zsXZpQK7A&`i~TkbU0O8Ngh zvMh-a)i-j<-~as%lrQ>t%O}t8xC|G6|NSyc$bbJSx&HSrsNDhgi6iSe{$axZd4K{W z`jHDKF5|Yx{&&*;Z({y$V*YQ({NIlGe+3fcLjM=a{(pYP{2m%9DzV^5<>jY}Bk(_U N6|GG%8+M=ie*nVr4@Lk0 literal 0 HcmV?d00001 diff --git a/test/production/app-dir/metadata-static-route-cache/metadata-static-route-cache.test.ts b/test/production/app-dir/metadata-static-route-cache/metadata-static-route-cache.test.ts new file mode 100644 index 0000000000000..9bc2dd31abddf --- /dev/null +++ b/test/production/app-dir/metadata-static-route-cache/metadata-static-route-cache.test.ts @@ -0,0 +1,52 @@ +import { nextTestSetup } from 'e2e-utils' +import crypto from 'crypto' + +function generateMD5(text: string) { + const hash = crypto.createHash('md5') + hash.update(text) + return hash.digest('hex') +} + +describe('app dir - metadata static routes cache', () => { + const { next } = nextTestSetup({ + files: __dirname, + skipStart: true, + }) + + it('should generate different content after replace the static metadata file', async () => { + await next.build() + + const faviconBuildContent = await next.readFile( + '.next/server/app/favicon.ico.body' + ) + const opengrpahImageBuildContent = await next.readFile( + '.next/server/app/opengraph-image.png.body' + ) + + const faviconMd5 = generateMD5(faviconBuildContent) + const opengraphImageMd5 = generateMD5(opengrpahImageBuildContent) + + // Update favicon and opengraph image + const newFaviconContent = await next.readFile('app/favicon.ico.new') + await next.patchFile('app/favicon.ico', newFaviconContent) + + const newOpengraphImageContent = await next.readFile( + 'app/opengraph-image.png.new' + ) + await next.patchFile('app/opengraph-image.png', newOpengraphImageContent) + + await next.build() + const faviconBuildContentNew = await next.readFile( + '.next/server/app/favicon.ico.body' + ) + const opengrpahImageBuildContentNew = await next.readFile( + '.next/server/app/opengraph-image.png.body' + ) + + const faviconMd5New = generateMD5(faviconBuildContentNew) + const opengraphImageMd5New = generateMD5(opengrpahImageBuildContentNew) + + expect(faviconMd5).not.toBe(faviconMd5New) + expect(opengraphImageMd5).not.toBe(opengraphImageMd5New) + }) +}) diff --git a/test/turbopack-build-tests-manifest.json b/test/turbopack-build-tests-manifest.json index 6ff821b17121a..c6ba6a53e9fd6 100644 --- a/test/turbopack-build-tests-manifest.json +++ b/test/turbopack-build-tests-manifest.json @@ -15735,6 +15735,15 @@ "pending": [], "flakey": [], "runtimeError": false + }, + "test/production/app-dir/metadata-static-route-cache/metadata-static-route-cache.test.ts": { + "passed": [], + "failed": [ + "app dir - metadata static routes cache should generate different content after replace the static metadata file" + ], + "pending": [], + "flakey": [], + "runtimeError": false } }, "rules": { From 6606630af2c8272409d9e86423313b8fa67b8378 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Tue, 11 Jun 2024 08:51:53 -0700 Subject: [PATCH 26/60] refactor: simplified lint-staged config (#66720) This restores the changes that were reverted in #66554. This corrects the issue that triggered the revert by removing the `--no-ignore` flag which allows ESLint to handle the ignored files correctly. --- lint-staged.config.js | 44 ++++--------------------------------------- 1 file changed, 4 insertions(+), 40 deletions(-) diff --git a/lint-staged.config.js b/lint-staged.config.js index 9cdc3d318c0d3..167eaaaa0fa0d 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -1,44 +1,8 @@ -const { quote } = require('shell-quote') -const { ESLint } = require('eslint') - -const eslint = new ESLint() - -/** - * Escape filenames to ensure that spaces and such aren't interpreted as - * separators. - * - * @param {string[]} filenames - * @returns {string[]} - */ -function escape(filenames) { - if (process.platform === 'win32') { - return filenames - } - - return filenames.map((filename) => quote([filename]).replace(/\\@/g, '@')) -} - module.exports = { - '*.{js,jsx,mjs,ts,tsx,mts}': async (filenames) => { - const escapedFileNames = escape(filenames).join(' ') - const eslintFileNames = await Promise.all( - filenames.map(async (filename) => { - const ignored = await eslint.isPathIgnored(filename) - return ignored ? null : filename - }) - ) - - return [ - `prettier --with-node-modules --ignore-path .prettierignore --write ${escapedFileNames}`, - `eslint --no-ignore --fix ${eslintFileNames - .filter((filename) => filename !== null) - .map((filename) => { - return `"${filename}"` - }) - .join(' ')}`, - `git add ${escapedFileNames}`, - ] - }, + '*.{js,jsx,mjs,ts,tsx,mts}': [ + 'prettier --with-node-modules --ignore-path .prettierignore --write', + 'eslint --fix', + ], '*.{json,md,mdx,css,html,yml,yaml,scss}': [ 'prettier --with-node-modules --ignore-path .prettierignore --write', ], From fbcc21ab00c61b64150ea0d7c384c92d2dea2ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=9E=E3=83=AB=E3=82=B3=E3=83=A1?= Date: Wed, 12 Jun 2024 01:16:09 +0900 Subject: [PATCH 27/60] docs(create-next-app): update Geist font reference (#66737) ### What? Add [Geist font](https://vercel.com/font) reference instead of [Google Inter font](https://fonts.google.com/specimen/Inter). ### Why? `create-next-app@canary` doesn't use Google Inter font anymore at #65803. Co-authored-by: JJ Kasper --- packages/create-next-app/templates/app-tw/js/README-template.md | 2 +- packages/create-next-app/templates/app-tw/ts/README-template.md | 2 +- packages/create-next-app/templates/app/js/README-template.md | 2 +- packages/create-next-app/templates/app/ts/README-template.md | 2 +- .../create-next-app/templates/default-tw/js/README-template.md | 2 +- .../create-next-app/templates/default-tw/ts/README-template.md | 2 +- .../create-next-app/templates/default/js/README-template.md | 2 +- .../create-next-app/templates/default/ts/README-template.md | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/create-next-app/templates/app-tw/js/README-template.md b/packages/create-next-app/templates/app-tw/js/README-template.md index 4745a63eda105..66bb426ffe6ec 100644 --- a/packages/create-next-app/templates/app-tw/js/README-template.md +++ b/packages/create-next-app/templates/app-tw/js/README-template.md @@ -18,7 +18,7 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file. -This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load Inter, a custom Google Font. +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. ## Learn More diff --git a/packages/create-next-app/templates/app-tw/ts/README-template.md b/packages/create-next-app/templates/app-tw/ts/README-template.md index a98bfa8140e14..234c6d154f643 100644 --- a/packages/create-next-app/templates/app-tw/ts/README-template.md +++ b/packages/create-next-app/templates/app-tw/ts/README-template.md @@ -18,7 +18,7 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. -This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load Inter, a custom Google Font. +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. ## Learn More diff --git a/packages/create-next-app/templates/app/js/README-template.md b/packages/create-next-app/templates/app/js/README-template.md index c3ff7774f638d..6410399e647f8 100644 --- a/packages/create-next-app/templates/app/js/README-template.md +++ b/packages/create-next-app/templates/app/js/README-template.md @@ -18,7 +18,7 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file. -This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load Inter, a custom Google Font. +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. ## Learn More diff --git a/packages/create-next-app/templates/app/ts/README-template.md b/packages/create-next-app/templates/app/ts/README-template.md index a98bfa8140e14..234c6d154f643 100644 --- a/packages/create-next-app/templates/app/ts/README-template.md +++ b/packages/create-next-app/templates/app/ts/README-template.md @@ -18,7 +18,7 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. -This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load Inter, a custom Google Font. +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. ## Learn More diff --git a/packages/create-next-app/templates/default-tw/js/README-template.md b/packages/create-next-app/templates/default-tw/js/README-template.md index c828f80be635d..eb8aec4611422 100644 --- a/packages/create-next-app/templates/default-tw/js/README-template.md +++ b/packages/create-next-app/templates/default-tw/js/README-template.md @@ -22,7 +22,7 @@ You can start editing the page by modifying `pages/index.js`. The page auto-upda The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/pages/building-your-application/routing/api-routes) instead of React pages. -This project uses [`next/font`](https://nextjs.org/docs/pages/building-your-application/optimizing/fonts) to automatically optimize and load Inter, a custom Google Font. +This project uses [`next/font`](https://nextjs.org/docs/pages/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. ## Learn More diff --git a/packages/create-next-app/templates/default-tw/ts/README-template.md b/packages/create-next-app/templates/default-tw/ts/README-template.md index 90708d2e75099..ef0e47e31fa3d 100644 --- a/packages/create-next-app/templates/default-tw/ts/README-template.md +++ b/packages/create-next-app/templates/default-tw/ts/README-template.md @@ -22,7 +22,7 @@ You can start editing the page by modifying `pages/index.tsx`. The page auto-upd The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/pages/building-your-application/routing/api-routes) instead of React pages. -This project uses [`next/font`](https://nextjs.org/docs/pages/building-your-application/optimizing/fonts) to automatically optimize and load Inter, a custom Google Font. +This project uses [`next/font`](https://nextjs.org/docs/pages/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. ## Learn More diff --git a/packages/create-next-app/templates/default/js/README-template.md b/packages/create-next-app/templates/default/js/README-template.md index c828f80be635d..eb8aec4611422 100644 --- a/packages/create-next-app/templates/default/js/README-template.md +++ b/packages/create-next-app/templates/default/js/README-template.md @@ -22,7 +22,7 @@ You can start editing the page by modifying `pages/index.js`. The page auto-upda The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/pages/building-your-application/routing/api-routes) instead of React pages. -This project uses [`next/font`](https://nextjs.org/docs/pages/building-your-application/optimizing/fonts) to automatically optimize and load Inter, a custom Google Font. +This project uses [`next/font`](https://nextjs.org/docs/pages/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. ## Learn More diff --git a/packages/create-next-app/templates/default/ts/README-template.md b/packages/create-next-app/templates/default/ts/README-template.md index 90708d2e75099..ef0e47e31fa3d 100644 --- a/packages/create-next-app/templates/default/ts/README-template.md +++ b/packages/create-next-app/templates/default/ts/README-template.md @@ -22,7 +22,7 @@ You can start editing the page by modifying `pages/index.tsx`. The page auto-upd The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/pages/building-your-application/routing/api-routes) instead of React pages. -This project uses [`next/font`](https://nextjs.org/docs/pages/building-your-application/optimizing/fonts) to automatically optimize and load Inter, a custom Google Font. +This project uses [`next/font`](https://nextjs.org/docs/pages/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. ## Learn More From 801e891c7e20eac65c8b7c6e8764f5546df7127f Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Tue, 11 Jun 2024 10:18:58 -0700 Subject: [PATCH 28/60] remove related e2e workflow (#66758) I'm working on fixing our deploy tests workflow. See: - #66721 This particular workflow runs on each PR but it uses the canary version. It also wipes the deploy test project which will cause conflicts with the main e2e one. Removing this for now since it's not working as intended, and will reland it with fixes. --- .github/workflows/test_e2e_deploy_related.yml | 81 ------------------- 1 file changed, 81 deletions(-) delete mode 100644 .github/workflows/test_e2e_deploy_related.yml diff --git a/.github/workflows/test_e2e_deploy_related.yml b/.github/workflows/test_e2e_deploy_related.yml deleted file mode 100644 index acda4db3332c7..0000000000000 --- a/.github/workflows/test_e2e_deploy_related.yml +++ /dev/null @@ -1,81 +0,0 @@ -name: Test E2E (Vercel Deploy), related - -on: - pull_request: - types: [opened, synchronize] - -jobs: - test: - if: '!github.event.pull_request.head.repo.fork' - runs-on: ubuntu-latest - - env: - CARGO_PROFILE_RELEASE_LTO: 'true' - DATADOG_API_KEY: ${{ secrets.DATA_DOG_API_KEY }} - DD_ENV: 'ci' - NAPI_CLI_VERSION: 2.16.2 - NEXT_JUNIT_TEST_REPORT: 'true' - NEXT_TELEMETRY_DISABLED: 1 - NEXT_TEST_JOB: 1 - NEXT_TEST_MODE: 'deploy' - NODE_LTS_VERSION: 20 - TEST_TIMINGS_TOKEN: ${{ secrets.TEST_TIMINGS_TOKEN }} - TURBO_REMOTE_ONLY: 'true' - TURBO_TEAM: 'vercel' - TURBO_VERSION: 1.13.3-canary.2 - VERCEL_TEST_TEAM: vtest314-next-e2e-tests - VERCEL_TEST_TOKEN: ${{ secrets.VERCEL_TEST_TOKEN }} - - strategy: - fail-fast: false - - steps: - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_LTS_VERSION }} - check-latest: true - - - name: Setup pnpm - run: corepack enable - - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 25 - - - name: Setup tests - run: | - pnpm install - pnpm run build - npm i -g vercel@latest - node scripts/run-e2e-test-project-reset.mjs - - - name: Run tests - run: | - docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.41.2-jammy /bin/bash -c "cd /work && \ - NODE_VERSION=${{ env.NODE_LTS_VERSION }} ./scripts/setup-node.sh && \ - corepack enable > /dev/null && \ - NEXT_JUNIT_TEST_REPORT=${{ env.NEXT_JUNIT_TEST_REPORT }} \ - DATADOG_API_KEY=${{ env.DATADOG_API_KEY }} \ - DD_ENV=${{ env.DD_ENV }} \ - VERCEL_TEST_TOKEN=${{ env.VERCEL_TEST_TOKEN }} \ - VERCEL_TEST_TEAM=${{ env.VERCEL_TEST_TEAM }} \ - NEXT_TEST_JOB=${{ env.NEXT_TEST_JOB }} \ - NEXT_TEST_MODE=${{ env.NEXT_TEST_MODE }} \ - TEST_TIMINGS_TOKEN=${{ env.TEST_TIMINGS_TOKEN }} \ - xvfb-run node run-tests.js --related --timings -c 1 >> /proc/1/fd/1" - - - name: Save test report as artifacts - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-reports - if-no-files-found: ignore - retention-days: 2 - path: test/test-junit-report - - - name: Upload test report to Datadog - continue-on-error: true - run: | - pnpx @datadog/datadog-ci@2.23.1 junit upload --tags test.type:nextjs_deploy_e2e --service nextjs ./test/test-junit-report From 46d3066c98d9971b5eec708c5999a6227a8eabb3 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Tue, 11 Jun 2024 10:30:56 -0700 Subject: [PATCH 29/60] Log stdio for pull-turbo-cache script (#66759) Gives us more context when this fails as it is here https://github.com/vercel/next.js/actions/runs/9469195858/job/26087290365#step:15:23 --- scripts/pull-turbo-cache.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/pull-turbo-cache.js b/scripts/pull-turbo-cache.js index fa7e9a06e6f28..9a49d845956c6 100644 --- a/scripts/pull-turbo-cache.js +++ b/scripts/pull-turbo-cache.js @@ -17,7 +17,12 @@ const { spawn } = require('child_process') } ) + child.stderr.on('data', (data) => { + process.stderr.write(data) + }) + child.stdout.on('data', (data) => { + process.stdout.write(data) turboResult += data.toString() }) From b5d0a67912b1ea40a1840873e99e5145f48da6fd Mon Sep 17 00:00:00 2001 From: Ivan Torres <40922354+torresgol10@users.noreply.github.com> Date: Tue, 11 Jun 2024 20:12:55 +0200 Subject: [PATCH 30/60] Update devDependecy prettier-plugin-tailwindcss (#66713) Upgrade devDependecy prettier-plugin-tailwindcss to the latest version Co-authored-by: torresgol10.itd Co-authored-by: Sam Ko --- packages/create-next-app/package.json | 2 +- pnpm-lock.yaml | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index c0220da4eea19..acc47eb880e53 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -44,7 +44,7 @@ "cross-spawn": "7.0.3", "fast-glob": "3.3.1", "picocolors": "1.0.0", - "prettier-plugin-tailwindcss": "0.3.0", + "prettier-plugin-tailwindcss": "0.6.2", "prompts": "2.4.2", "tar": "7.2.0", "update-check": "1.5.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 88142bd78392c..2b5fe5bd0adc3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -735,8 +735,8 @@ importers: specifier: 1.0.0 version: 1.0.0 prettier-plugin-tailwindcss: - specifier: 0.3.0 - version: 0.3.0(prettier@3.2.5) + specifier: 0.6.2 + version: 0.6.2(prettier@3.2.5) prompts: specifier: 2.4.2 version: 2.4.2 @@ -20861,16 +20861,16 @@ packages: engines: {node: '>=4'} dev: true - /prettier-plugin-tailwindcss@0.3.0(prettier@3.2.5): - resolution: {integrity: sha512-009/Xqdy7UmkcTBpwlq7jsViDqXAYSOMLDrHAdTMlVZOrKfM2o9Ci7EMWTMZ7SkKBFTG04UM9F9iM2+4i6boDA==} - engines: {node: '>=12.17.0'} + /prettier-plugin-tailwindcss@0.6.2(prettier@3.2.5): + resolution: {integrity: sha512-eFefm4cg+1c2B57+H274Qm//CTWBdtQN9ansl0YTP/8TC8x3bugCTQSS/e4FC5Ctl9djhTzsbcMrZ7x2/abIow==} + engines: {node: '>=14.21.3'} peerDependencies: '@ianvs/prettier-plugin-sort-imports': '*' '@prettier/plugin-pug': '*' '@shopify/prettier-plugin-liquid': '*' - '@shufo/prettier-plugin-blade': '*' '@trivago/prettier-plugin-sort-imports': '*' - prettier: '>=2.2.0' + '@zackad/prettier-plugin-twig-melody': '*' + prettier: ^3.0 prettier-plugin-astro: '*' prettier-plugin-css-order: '*' prettier-plugin-import-sort: '*' @@ -20878,9 +20878,9 @@ packages: prettier-plugin-marko: '*' prettier-plugin-organize-attributes: '*' prettier-plugin-organize-imports: '*' + prettier-plugin-sort-imports: '*' prettier-plugin-style-order: '*' prettier-plugin-svelte: '*' - prettier-plugin-twig-melody: '*' peerDependenciesMeta: '@ianvs/prettier-plugin-sort-imports': optional: true @@ -20888,10 +20888,10 @@ packages: optional: true '@shopify/prettier-plugin-liquid': optional: true - '@shufo/prettier-plugin-blade': - optional: true '@trivago/prettier-plugin-sort-imports': optional: true + '@zackad/prettier-plugin-twig-melody': + optional: true prettier-plugin-astro: optional: true prettier-plugin-css-order: @@ -20906,12 +20906,12 @@ packages: optional: true prettier-plugin-organize-imports: optional: true + prettier-plugin-sort-imports: + optional: true prettier-plugin-style-order: optional: true prettier-plugin-svelte: optional: true - prettier-plugin-twig-melody: - optional: true dependencies: prettier: 3.2.5 dev: true From 62e8c9dd453839a40627a98803ecf1f0e401eacd Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Tue, 11 Jun 2024 20:42:10 +0200 Subject: [PATCH 31/60] test: add name re-export from client components as page case (#66760) ### What Add new test case where a named export from client component is being exported as page ### Why We found this case while investigating the errors triggered introduced by #66286 , adding this test to avoid future regression --- .../app-dir/app-routes-client-component/app/layout.js | 7 +++++++ .../e2e/app-dir/rsc-basic/app/reexport-named/client.js | 9 +++++++++ test/e2e/app-dir/rsc-basic/app/reexport-named/page.js | 3 +++ .../client-index.js | 0 .../{reexport-client => reexport-namespace}/client.js | 2 +- .../{reexport-client => reexport-namespace}/page.js | 0 test/e2e/app-dir/rsc-basic/rsc-basic.test.ts | 10 ++++++++++ 7 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 test/e2e/app-dir/app-routes-client-component/app/layout.js create mode 100644 test/e2e/app-dir/rsc-basic/app/reexport-named/client.js create mode 100644 test/e2e/app-dir/rsc-basic/app/reexport-named/page.js rename test/e2e/app-dir/rsc-basic/app/{reexport-client => reexport-namespace}/client-index.js (100%) rename test/e2e/app-dir/rsc-basic/app/{reexport-client => reexport-namespace}/client.js (54%) rename test/e2e/app-dir/rsc-basic/app/{reexport-client => reexport-namespace}/page.js (100%) diff --git a/test/e2e/app-dir/app-routes-client-component/app/layout.js b/test/e2e/app-dir/app-routes-client-component/app/layout.js new file mode 100644 index 0000000000000..803f17d863c8a --- /dev/null +++ b/test/e2e/app-dir/app-routes-client-component/app/layout.js @@ -0,0 +1,7 @@ +export default function RootLayout({ children }) { + return ( + + {children} + + ) +} diff --git a/test/e2e/app-dir/rsc-basic/app/reexport-named/client.js b/test/e2e/app-dir/rsc-basic/app/reexport-named/client.js new file mode 100644 index 0000000000000..44131eed1e9a9 --- /dev/null +++ b/test/e2e/app-dir/rsc-basic/app/reexport-named/client.js @@ -0,0 +1,9 @@ +'use client' + +export function PageComponent() { + return ( +
+

Client Title

+
+ ) +} diff --git a/test/e2e/app-dir/rsc-basic/app/reexport-named/page.js b/test/e2e/app-dir/rsc-basic/app/reexport-named/page.js new file mode 100644 index 0000000000000..e86f8465b6d91 --- /dev/null +++ b/test/e2e/app-dir/rsc-basic/app/reexport-named/page.js @@ -0,0 +1,3 @@ +import { PageComponent } from './client' + +export default PageComponent diff --git a/test/e2e/app-dir/rsc-basic/app/reexport-client/client-index.js b/test/e2e/app-dir/rsc-basic/app/reexport-namespace/client-index.js similarity index 100% rename from test/e2e/app-dir/rsc-basic/app/reexport-client/client-index.js rename to test/e2e/app-dir/rsc-basic/app/reexport-namespace/client-index.js diff --git a/test/e2e/app-dir/rsc-basic/app/reexport-client/client.js b/test/e2e/app-dir/rsc-basic/app/reexport-namespace/client.js similarity index 54% rename from test/e2e/app-dir/rsc-basic/app/reexport-client/client.js rename to test/e2e/app-dir/rsc-basic/app/reexport-namespace/client.js index a31f2e420a749..a65202a7ca51a 100644 --- a/test/e2e/app-dir/rsc-basic/app/reexport-client/client.js +++ b/test/e2e/app-dir/rsc-basic/app/reexport-namespace/client.js @@ -1,5 +1,5 @@ 'use client' export function Foo() { - return
Foo
+ return
Foo
} diff --git a/test/e2e/app-dir/rsc-basic/app/reexport-client/page.js b/test/e2e/app-dir/rsc-basic/app/reexport-namespace/page.js similarity index 100% rename from test/e2e/app-dir/rsc-basic/app/reexport-client/page.js rename to test/e2e/app-dir/rsc-basic/app/reexport-namespace/page.js diff --git a/test/e2e/app-dir/rsc-basic/rsc-basic.test.ts b/test/e2e/app-dir/rsc-basic/rsc-basic.test.ts index db618770ae3b0..8cf289f7f7b5b 100644 --- a/test/e2e/app-dir/rsc-basic/rsc-basic.test.ts +++ b/test/e2e/app-dir/rsc-basic/rsc-basic.test.ts @@ -109,6 +109,16 @@ describe('app dir - rsc basics', () => { expect($('#return-undefined-layout').html()).toBeEmpty() }) + it('should handle named client components imported as page', async () => { + const $ = await next.render$('/reexport-named') + expect($('#client-title').text()).toBe('Client Title') + }) + + it('should handle client components imported as namespace', async () => { + const $ = await next.render$('/reexport-namespace') + expect($('#foo').text()).toBe('Foo') + }) + it('should render server components correctly', async () => { const homeHTML = await next.render('/', null, { headers: { From 0fee50ed6e18c35d8a6c40b9bb2dd5c0bed523f8 Mon Sep 17 00:00:00 2001 From: Janka Uryga Date: Tue, 11 Jun 2024 21:36:27 +0200 Subject: [PATCH 32/60] fix: app-router prefetch crash when an invalid URL is passed to Link (#66755) Closes [#66650](https://github.com/vercel/next.js/issues/66650) Closes NEXT-3520 ### What? - Make Link not throw during prefetch if it received an invalid `href` (see [#66650](https://github.com/vercel/next.js/issues/66650)) - Throw in dev mode if an invalid link was passed to `router.prefetch` -- this matches current prod behavior - (previously, we'd immediately exit out of `router.prefetch`, so the user would see no indication that this'd fail in prod) ### Why? If an invalid URL was passed to ``, the whole app would crash and show "A client-side exception occurred". A failed prefetch should not bring down the whole app. Note that This preserves the current behavior of explicit `router.prefetch(url)` throwing an error if `url` is invalid. We may want to adjust this in the future, but that could be considered a breaking change, so I'm leaving it out for now. This only affects `Link`, which was intended to catch any errors thrown from `router.prefetch`, but that bit was accidentally broken. --- .../next/src/client/components/app-router.tsx | 20 ++++++++++++++----- packages/next/src/client/link.tsx | 14 +++++++++---- .../app-prefetch/app/invalid-url/delay.js | 15 ++++++++++++++ .../app-prefetch/app/invalid-url/error.js | 4 ++++ .../app/invalid-url/from-link/page.js | 16 +++++++++++++++ .../invalid-url/from-router-prefetch/page.js | 20 +++++++++++++++++++ .../app/invalid-url/invalid-url.js | 8 ++++++++ .../app-dir/app-prefetch/prefetching.test.ts | 18 +++++++++++++++++ 8 files changed, 106 insertions(+), 9 deletions(-) create mode 100644 test/e2e/app-dir/app-prefetch/app/invalid-url/delay.js create mode 100644 test/e2e/app-dir/app-prefetch/app/invalid-url/error.js create mode 100644 test/e2e/app-dir/app-prefetch/app/invalid-url/from-link/page.js create mode 100644 test/e2e/app-dir/app-prefetch/app/invalid-url/from-router-prefetch/page.js create mode 100644 test/e2e/app-dir/app-prefetch/app/invalid-url/invalid-url.js diff --git a/packages/next/src/client/components/app-router.tsx b/packages/next/src/client/components/app-router.tsx index 0a8493ac219f2..73bbd87adb8f2 100644 --- a/packages/next/src/client/components/app-router.tsx +++ b/packages/next/src/client/components/app-router.tsx @@ -362,14 +362,24 @@ function Router({ forward: () => window.history.forward(), prefetch: (href, options) => { // Don't prefetch for bots as they don't navigate. + if (isBot(window.navigator.userAgent)) { + return + } + + let url: URL + try { + url = new URL(addBasePath(href), window.location.href) + } catch (_) { + throw new Error( + `Cannot prefetch '${href}' because it cannot be converted to a URL.` + ) + } + // Don't prefetch during development (improves compilation performance) - if ( - isBot(window.navigator.userAgent) || - process.env.NODE_ENV === 'development' - ) { + if (process.env.NODE_ENV === 'development') { return } - const url = new URL(addBasePath(href), window.location.href) + // External urls can't be prefetched in the same way. if (isExternalURL(url)) { return diff --git a/packages/next/src/client/link.tsx b/packages/next/src/client/link.tsx index d8e9318f2ac2d..1c3b149d8b615 100644 --- a/packages/next/src/client/link.tsx +++ b/packages/next/src/client/link.tsx @@ -161,15 +161,21 @@ function prefetch( prefetched.add(prefetchedKey) } - const prefetchPromise = isAppRouter - ? (router as AppRouterInstance).prefetch(href, appOptions) - : (router as NextRouter).prefetch(href, as, options) + const doPrefetch = async () => { + if (isAppRouter) { + // note that `appRouter.prefetch()` is currently sync, + // so we have to wrap this call in an async function to be able to catch() errors below. + return (router as AppRouterInstance).prefetch(href, appOptions) + } else { + return (router as NextRouter).prefetch(href, as, options) + } + } // Prefetch the JSON page if asked (only in the client) // We need to handle a prefetch error here since we may be // loading with priority which can reject but we don't // want to force navigation since this is only a prefetch - Promise.resolve(prefetchPromise).catch((err) => { + doPrefetch().catch((err) => { if (process.env.NODE_ENV !== 'production') { // rethrow to show invalid URL errors throw err diff --git a/test/e2e/app-dir/app-prefetch/app/invalid-url/delay.js b/test/e2e/app-dir/app-prefetch/app/invalid-url/delay.js new file mode 100644 index 0000000000000..0f6f762a51bbc --- /dev/null +++ b/test/e2e/app-dir/app-prefetch/app/invalid-url/delay.js @@ -0,0 +1,15 @@ +'use client' + +import { useEffect } from 'react' +import { useState } from 'react' + +export function Delay({ duration = 500, children }) { + const [isVisible, setIsVisible] = useState(false) + useEffect(() => { + const timeout = setTimeout(() => setIsVisible(true), duration) + return () => clearTimeout(timeout) + }, [duration]) + + if (!isVisible) return null + return <>{children} +} diff --git a/test/e2e/app-dir/app-prefetch/app/invalid-url/error.js b/test/e2e/app-dir/app-prefetch/app/invalid-url/error.js new file mode 100644 index 0000000000000..365d656d68601 --- /dev/null +++ b/test/e2e/app-dir/app-prefetch/app/invalid-url/error.js @@ -0,0 +1,4 @@ +'use client' +export default function Error() { + return

A prefetch threw an error

+} diff --git a/test/e2e/app-dir/app-prefetch/app/invalid-url/from-link/page.js b/test/e2e/app-dir/app-prefetch/app/invalid-url/from-link/page.js new file mode 100644 index 0000000000000..cdb564620683e --- /dev/null +++ b/test/e2e/app-dir/app-prefetch/app/invalid-url/from-link/page.js @@ -0,0 +1,16 @@ +import Link from 'next/link' +import { INVALID_URL } from '../invalid-url' +import { Delay } from '../delay' + +export const dynamic = 'force-dynamic' + +export default function Page() { + return ( + <> + invalid link + +

Hello, world!

+
+ + ) +} diff --git a/test/e2e/app-dir/app-prefetch/app/invalid-url/from-router-prefetch/page.js b/test/e2e/app-dir/app-prefetch/app/invalid-url/from-router-prefetch/page.js new file mode 100644 index 0000000000000..a5a61aa3624da --- /dev/null +++ b/test/e2e/app-dir/app-prefetch/app/invalid-url/from-router-prefetch/page.js @@ -0,0 +1,20 @@ +'use client' +import { useEffect } from 'react' +import { INVALID_URL } from '../invalid-url' +import { Delay } from '../delay' +import { useRouter } from 'next/navigation' + +export const dynamic = 'force-dynamic' + +export default function Page() { + const router = useRouter() + useEffect(() => { + router.prefetch(INVALID_URL) + }, [router]) + + return ( + +

Hello, world!

+
+ ) +} diff --git a/test/e2e/app-dir/app-prefetch/app/invalid-url/invalid-url.js b/test/e2e/app-dir/app-prefetch/app/invalid-url/invalid-url.js new file mode 100644 index 0000000000000..a0415625a2753 --- /dev/null +++ b/test/e2e/app-dir/app-prefetch/app/invalid-url/invalid-url.js @@ -0,0 +1,8 @@ +// We need a URL that reliably fails `new URL(url, window.location) +// This only fails if `window.location` starts with `https://`: +// +// const invalidUrl = 'http:' +// +// because `new URL('http:', 'http://localhost:3000')` works fine. +// So better to pick something that's always invalid +export const INVALID_URL = '///' diff --git a/test/e2e/app-dir/app-prefetch/prefetching.test.ts b/test/e2e/app-dir/app-prefetch/prefetching.test.ts index 002836bc969f4..06d1cf0c0eb7d 100644 --- a/test/e2e/app-dir/app-prefetch/prefetching.test.ts +++ b/test/e2e/app-dir/app-prefetch/prefetching.test.ts @@ -329,4 +329,22 @@ describe('app dir - prefetching', () => { }) }) }) + + describe('invalid URLs', () => { + it('should not throw when an invalid URL is passed to Link', async () => { + const browser = await next.browser('/invalid-url/from-link') + + await check(() => browser.hasElementByCssSelector('h1'), true) + expect(await browser.elementByCss('h1').text()).toEqual('Hello, world!') + }) + + it('should throw when an invalid URL is passed to router.prefetch', async () => { + const browser = await next.browser('/invalid-url/from-router-prefetch') + + await check(() => browser.hasElementByCssSelector('h1'), true) + expect(await browser.elementByCss('h1').text()).toEqual( + 'A prefetch threw an error' + ) + }) + }) }) From f0e4298f674c1cd031ad1e8046f479f7425ffc3b Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Tue, 11 Jun 2024 12:49:07 -0700 Subject: [PATCH 33/60] Ensure urlPathname is always a pathname (#63846) ### What? This modifies the static generation store to instead store a `url` object with the `pathname` and `search` properties. This corrects the previous behaviour which used the variable `urlPathname` which had ambiguous meanings as it technically contained the search string as well, not just the pathname. In cases during the app render, this still grabs the contents of `url.pathname + url.search` (where `url.search` always has a leading `?` if it has any query parameters, [see the docs](https://developer.mozilla.org/en-US/docs/Web/API/URL/search)) so that it emulates the current behaviour. This allows more specific access though, where now additional parsing can be eliminated which had to strip the query string off of the `urlPathname` in a few places, and more worrisome, still accidentally contained the search string causing errors. ### How? This requires an upstream fix (#64088) which corrected a bug with the store access which had caused some previous test failures (accessing `store.url.pathname` was throwing as `store.url` was undefined on the wrong return, check the upstream PR for more details on that). This also changes out usage of `pagePath` with `route`, and lets it be the fallback (for debugging and error messaging). During static generation, we will provide a value for the page being rendered that's correlated to the particular file on the filesystem that the route is based on: ``` // rendering app/users/[userID]/page.tsx page: /users/[userID] pathname: /users/1, /users/2, etc ``` The `route` is used only for debugging, such as when `generateStaticParams` incorrectly calls `headers()`. This also moves the pathname from the `staticGenerationStore` into the `requestStore`, as it's tied to a given request. Closes NEXT-2965 --- .../next-core/src/next_app/app_page_entry.rs | 1 - .../next-core/src/next_app/app_route_entry.rs | 3 +- packages/next/src/build/templates/app-page.ts | 1 - .../next/src/build/templates/app-route.ts | 5 +- packages/next/src/build/utils.ts | 3 +- .../build/webpack/loaders/next-app-loader.ts | 2 - .../request-async-storage.external.ts | 17 +++++ ...tatic-generation-async-storage.external.ts | 14 +++- packages/next/src/export/routes/app-route.ts | 3 +- packages/next/src/export/worker.ts | 1 - packages/next/src/lib/metadata/metadata.tsx | 4 +- packages/next/src/lib/url.ts | 10 +-- .../src/server/after/after-context.test.ts | 5 +- .../next/src/server/after/after-context.ts | 1 + packages/next/src/server/after/after.ts | 4 +- .../next/src/server/app-render/app-render.tsx | 31 ++++---- .../app-render/create-component-tree.tsx | 7 +- .../server/app-render/dynamic-rendering.ts | 28 +++---- .../next/src/server/app-render/entry-base.ts | 2 +- packages/next/src/server/app-render/types.ts | 1 - .../src/server/app-render/validate-url.tsx | 18 ----- .../request-async-storage-wrapper.ts | 41 +++++++--- ...static-generation-async-storage-wrapper.ts | 15 ++-- packages/next/src/server/base-server.ts | 2 - packages/next/src/server/lib/patch-fetch.ts | 75 +++++++++---------- packages/next/src/server/load-components.ts | 2 +- .../server/load-default-error-components.ts | 2 +- .../server/route-modules/app-route/module.ts | 23 +++--- packages/next/src/server/web/adapter.ts | 14 ++-- .../server/web/spec-extension/revalidate.ts | 5 +- .../web/spec-extension/unstable-cache.ts | 71 +++++++++++------- .../router/utils/parse-relative-url.test.ts | 20 +++++ .../lib/router/utils/parse-relative-url.ts | 21 +++++- .../lib/router/utils/resolve-rewrites.ts | 4 +- test/unit/validate-url.test.ts | 13 ---- 35 files changed, 250 insertions(+), 219 deletions(-) delete mode 100644 packages/next/src/server/app-render/validate-url.tsx create mode 100644 packages/next/src/shared/lib/router/utils/parse-relative-url.test.ts delete mode 100644 test/unit/validate-url.test.ts diff --git a/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs b/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs index 1305d4346ca58..9beb79635d156 100644 --- a/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs +++ b/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs @@ -81,7 +81,6 @@ pub async fn get_app_page_entry( indexmap! { "VAR_DEFINITION_PAGE" => page.to_string().into(), "VAR_DEFINITION_PATHNAME" => pathname.clone(), - "VAR_ORIGINAL_PATHNAME" => original_name.clone(), // TODO(alexkirsz) Support custom global error. "VAR_MODULE_GLOBAL_ERROR" => "next/dist/client/components/error-boundary".into(), }, diff --git a/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs b/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs index 1114043a4bed1..06aa3e74392c4 100644 --- a/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs +++ b/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs @@ -84,8 +84,7 @@ pub async fn get_app_route_entry( "VAR_DEFINITION_PATHNAME" => pathname.clone(), "VAR_DEFINITION_FILENAME" => path.file_stem().await?.as_ref().unwrap().as_str().into(), // TODO(alexkirsz) Is this necessary? - "VAR_DEFINITION_BUNDLE_PATH" => "".into(), - "VAR_ORIGINAL_PATHNAME" => original_name.clone(), + "VAR_DEFINITION_BUNDLE_PATH" => "".to_string().into(), "VAR_RESOLVED_PAGE_PATH" => path.to_string().await?.clone_value(), "VAR_USERLAND" => INNER.into(), }, diff --git a/packages/next/src/build/templates/app-page.ts b/packages/next/src/build/templates/app-page.ts index a3594095494c7..0fb72182245ed 100644 --- a/packages/next/src/build/templates/app-page.ts +++ b/packages/next/src/build/templates/app-page.ts @@ -27,7 +27,6 @@ declare const __next_app_load_chunk__: any // INJECT:__next_app_require__ // INJECT:__next_app_load_chunk__ -export const originalPathname = 'VAR_ORIGINAL_PATHNAME' export const __next_app__ = { require: __next_app_require__, loadChunk: __next_app_load_chunk__, diff --git a/packages/next/src/build/templates/app-route.ts b/packages/next/src/build/templates/app-route.ts index b65276d0c84f2..81217489f2d98 100644 --- a/packages/next/src/build/templates/app-route.ts +++ b/packages/next/src/build/templates/app-route.ts @@ -35,10 +35,8 @@ const routeModule = new AppRouteRouteModule({ const { requestAsyncStorage, staticGenerationAsyncStorage, serverHooks } = routeModule -const originalPathname = 'VAR_ORIGINAL_PATHNAME' - function patchFetch() { - return _patchFetch({ staticGenerationAsyncStorage }) + return _patchFetch({ staticGenerationAsyncStorage, requestAsyncStorage }) } export { @@ -46,6 +44,5 @@ export { requestAsyncStorage, staticGenerationAsyncStorage, serverHooks, - originalPathname, patchFetch, } diff --git a/packages/next/src/build/utils.ts b/packages/next/src/build/utils.ts index 8c1e9d3305fd7..666f84e71572a 100644 --- a/packages/next/src/build/utils.ts +++ b/packages/next/src/build/utils.ts @@ -1384,9 +1384,8 @@ export async function buildAppStaticPaths({ return StaticGenerationAsyncStorageWrapper.wrap( ComponentMod.staticGenerationAsyncStorage, { - urlPathname: page, + page, renderOpts: { - originalPathname: page, incrementalCache, supportsDynamicResponse: true, isRevalidate: false, diff --git a/packages/next/src/build/webpack/loaders/next-app-loader.ts b/packages/next/src/build/webpack/loaders/next-app-loader.ts index 5d49a3a3e3fad..f90b349b3ca17 100644 --- a/packages/next/src/build/webpack/loaders/next-app-loader.ts +++ b/packages/next/src/build/webpack/loaders/next-app-loader.ts @@ -144,7 +144,6 @@ async function createAppRouteCode({ VAR_DEFINITION_FILENAME: fileBaseName, VAR_DEFINITION_BUNDLE_PATH: bundlePath, VAR_RESOLVED_PAGE_PATH: resolvedPagePath, - VAR_ORIGINAL_PATHNAME: page, }, { nextConfigOutput: JSON.stringify(nextConfigOutput), @@ -772,7 +771,6 @@ const nextAppLoader: AppLoader = async function nextAppLoader() { VAR_DEFINITION_PAGE: page, VAR_DEFINITION_PATHNAME: pathname, VAR_MODULE_GLOBAL_ERROR: treeCodeResult.globalError, - VAR_ORIGINAL_PATHNAME: page, }, { tree: treeCodeResult.treeCode, diff --git a/packages/next/src/client/components/request-async-storage.external.ts b/packages/next/src/client/components/request-async-storage.external.ts index e2c696bed2319..c15dfac24491e 100644 --- a/packages/next/src/client/components/request-async-storage.external.ts +++ b/packages/next/src/client/components/request-async-storage.external.ts @@ -10,6 +10,23 @@ import type { DeepReadonly } from '../../shared/lib/deep-readonly' import type { AfterContext } from '../../server/after/after-context' export interface RequestStore { + /** + * The URL of the request. This only specifies the pathname and the search + * part of the URL. + */ + readonly url: { + /** + * The pathname of the requested URL. + */ + readonly pathname: string + + /** + * The search part of the requested URL. If the request did not provide a + * search part, this will be an empty string. + */ + readonly search: string + } + readonly headers: ReadonlyHeaders readonly cookies: ReadonlyRequestCookies readonly mutableCookies: ResponseCookies diff --git a/packages/next/src/client/components/static-generation-async-storage.external.ts b/packages/next/src/client/components/static-generation-async-storage.external.ts index fc6ac8a4ad3d6..7cb6c83c9876e 100644 --- a/packages/next/src/client/components/static-generation-async-storage.external.ts +++ b/packages/next/src/client/components/static-generation-async-storage.external.ts @@ -10,8 +10,18 @@ import { staticGenerationAsyncStorage } from './static-generation-async-storage- export interface StaticGenerationStore { readonly isStaticGeneration: boolean - readonly pagePath?: string - readonly urlPathname: string + + /** + * The page that is being rendered. This relates to the path to the page file. + */ + readonly page: string + + /** + * The route that is being rendered. This is the page property without the + * trailing `/page` or `/route` suffix. + */ + readonly route: string + readonly incrementalCache?: IncrementalCache readonly isOnDemandRevalidate?: boolean readonly isPrerendering?: boolean diff --git a/packages/next/src/export/routes/app-route.ts b/packages/next/src/export/routes/app-route.ts index 66db13b36347a..6ac3155a69db9 100644 --- a/packages/next/src/export/routes/app-route.ts +++ b/packages/next/src/export/routes/app-route.ts @@ -69,8 +69,7 @@ export async function exportAppRoute( notFoundRoutes: [], }, renderOpts: { - experimental: experimental, - originalPathname: page, + experimental, nextExport: true, supportsDynamicResponse: false, incrementalCache, diff --git a/packages/next/src/export/worker.ts b/packages/next/src/export/worker.ts index c727420307b51..ce567ccb7a14a 100644 --- a/packages/next/src/export/worker.ts +++ b/packages/next/src/export/worker.ts @@ -269,7 +269,6 @@ async function exportPageImpl( fontManifest: optimizeFonts ? requireFontManifest(distDir) : undefined, locale, supportsDynamicResponse: false, - originalPathname: page, experimental: { ...input.renderOpts.experimental, isRoutePPREnabled, diff --git a/packages/next/src/lib/metadata/metadata.tsx b/packages/next/src/lib/metadata/metadata.tsx index 3808f9843e23d..6cdf5eb8c63c0 100644 --- a/packages/next/src/lib/metadata/metadata.tsx +++ b/packages/next/src/lib/metadata/metadata.tsx @@ -35,11 +35,11 @@ import { isNotFoundError } from '../../client/components/not-found' import type { MetadataContext } from './types/resolvers' export function createMetadataContext( - urlPathname: string, + pathname: string, renderOpts: AppRenderContext['renderOpts'] ): MetadataContext { return { - pathname: urlPathname.split('?')[0], + pathname, trailingSlash: renderOpts.trailingSlash, isStandaloneMode: renderOpts.nextConfigOutput === 'standalone', } diff --git a/packages/next/src/lib/url.ts b/packages/next/src/lib/url.ts index 7daf240b00f49..f5969c1019449 100644 --- a/packages/next/src/lib/url.ts +++ b/packages/next/src/lib/url.ts @@ -1,14 +1,6 @@ import { NEXT_RSC_UNION_QUERY } from '../client/components/app-router-headers' -export const DUMMY_ORIGIN = 'http://n' - -function getUrlWithoutHost(url: string) { - return new URL(url, DUMMY_ORIGIN) -} - -export function getPathname(url: string) { - return getUrlWithoutHost(url).pathname -} +const DUMMY_ORIGIN = 'http://n' export function isFullStringUrl(url: string) { return /https?:\/\//.test(url) diff --git a/packages/next/src/server/after/after-context.test.ts b/packages/next/src/server/after/after-context.test.ts index 8ca2e25ea13ad..c171b307701b0 100644 --- a/packages/next/src/server/after/after-context.test.ts +++ b/packages/next/src/server/after/after-context.test.ts @@ -463,13 +463,14 @@ describe('createAfterContext', () => { const createMockRequestStore = (afterContext: AfterContext): RequestStore => { const partialStore: Partial = { + url: { pathname: '/', search: '' }, afterContext: afterContext, assetPrefix: '', reactLoadableManifest: {}, draftMode: undefined, } - return new Proxy(partialStore, { + return new Proxy(partialStore as RequestStore, { get(target, key) { if (key in target) { return target[key as keyof typeof target] @@ -478,5 +479,5 @@ const createMockRequestStore = (afterContext: AfterContext): RequestStore => { `RequestStore property not mocked: '${typeof key === 'symbol' ? key.toString() : key}'` ) }, - }) as RequestStore + }) } diff --git a/packages/next/src/server/after/after-context.ts b/packages/next/src/server/after/after-context.ts index 874390a07097e..2d75d280ce2c6 100644 --- a/packages/next/src/server/after/after-context.ts +++ b/packages/next/src/server/after/after-context.ts @@ -143,6 +143,7 @@ function wrapRequestStoreForAfterCallbacks( requestStore: RequestStore ): RequestStore { return { + url: requestStore.url, get headers() { return requestStore.headers }, diff --git a/packages/next/src/server/after/after.ts b/packages/next/src/server/after/after.ts index d9863a9048ad2..9b891262cc6fa 100644 --- a/packages/next/src/server/after/after.ts +++ b/packages/next/src/server/after/after.ts @@ -1,7 +1,6 @@ import { getExpectedRequestStore } from '../../client/components/request-async-storage.external' import { staticGenerationAsyncStorage } from '../../client/components/static-generation-async-storage.external' import { StaticGenBailoutError } from '../../client/components/static-generation-bailout' -import { getPathname } from '../../lib/url' import { markCurrentScopeAsDynamic } from '../app-render/dynamic-rendering' @@ -27,9 +26,8 @@ export function unstable_after(task: AfterTask) { if (staticGenerationStore) { if (staticGenerationStore.forceStatic) { - const pathname = getPathname(staticGenerationStore.urlPathname) throw new StaticGenBailoutError( - `Route ${pathname} with \`dynamic = "force-static"\` couldn't be rendered statically because it used \`${callingExpression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering` + `Route ${staticGenerationStore.route} with \`dynamic = "force-static"\` couldn't be rendered statically because it used \`${callingExpression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering` ) } else { markCurrentScopeAsDynamic(staticGenerationStore, callingExpression) diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx index f8b94d47fb9c4..a10b2d50e25bf 100644 --- a/packages/next/src/server/app-render/app-render.tsx +++ b/packages/next/src/server/app-render/app-render.tsx @@ -70,7 +70,6 @@ import { import { getSegmentParam } from './get-segment-param' import { getScriptNonceFromHeader } from './get-script-nonce-from-header' import { parseAndValidateFlightRouterState } from './parse-and-validate-flight-router-state' -import { validateURL } from './validate-url' import { createFlightRouterStateFromLoaderTree } from './create-flight-router-state-from-loader-tree' import { handleAction } from './action-handler' import { isBailoutToCSRError } from '../../shared/lib/lazy-dynamic/bailout-to-csr' @@ -116,6 +115,7 @@ import { import { createServerModuleMap } from './action-utils' import { isNodeNextRequest } from '../base-http/helpers' import { parseParameter } from '../../shared/lib/router/utils/route-regex' +import { parseRelativeUrl } from '../../shared/lib/router/utils/parse-relative-url' export type GetDynamicParamFromSegment = ( // [slug] / [[slug]] / [...slug] @@ -319,7 +319,7 @@ async function generateFlight( }, getDynamicParamFromSegment, appUsingSizeAdjustment, - staticGenerationStore: { urlPathname }, + requestStore: { url }, query, requestId, flightRouterState, @@ -329,7 +329,7 @@ async function generateFlight( const [MetadataTree, MetadataOutlet] = createMetadataComponents({ tree: loaderTree, query, - metadataContext: createMetadataContext(urlPathname, ctx.renderOpts), + metadataContext: createMetadataContext(url.pathname, ctx.renderOpts), getDynamicParamFromSegment, appUsingSizeAdjustment, createDynamicallyTrackedSearchParams, @@ -441,7 +441,7 @@ async function ReactServerApp({ tree, ctx, asNotFound }: ReactServerAppProps) { GlobalError, createDynamicallyTrackedSearchParams, }, - staticGenerationStore: { urlPathname }, + requestStore: { url }, } = ctx const initialTree = createFlightRouterStateFromLoaderTree( tree, @@ -453,7 +453,7 @@ async function ReactServerApp({ tree, ctx, asNotFound }: ReactServerAppProps) { tree, errorType: asNotFound ? 'not-found' : undefined, query, - metadataContext: createMetadataContext(urlPathname, ctx.renderOpts), + metadataContext: createMetadataContext(url.pathname, ctx.renderOpts), getDynamicParamFromSegment: getDynamicParamFromSegment, appUsingSizeAdjustment: appUsingSizeAdjustment, createDynamicallyTrackedSearchParams, @@ -485,7 +485,7 @@ async function ReactServerApp({ tree, ctx, asNotFound }: ReactServerAppProps) { { - // TODO: this includes query string, should it? - const pathname = validateURL(req.url) + if (!req.url) { + throw new Error('Invalid URL') + } + + const url = parseRelativeUrl(req.url, undefined, false) return RequestAsyncStorageWrapper.wrap( renderOpts.ComponentMod.requestAsyncStorage, - { req, res, renderOpts }, + { req, url, res, renderOpts }, (requestStore) => StaticGenerationAsyncStorageWrapper.wrap( renderOpts.ComponentMod.staticGenerationAsyncStorage, { - urlPathname: pathname, + page: renderOpts.routeModule.definition.page, renderOpts, requestEndedState: { ended: false }, }, diff --git a/packages/next/src/server/app-render/create-component-tree.tsx b/packages/next/src/server/app-render/create-component-tree.tsx index acee5b460119a..1081f78c4b9bd 100644 --- a/packages/next/src/server/app-render/create-component-tree.tsx +++ b/packages/next/src/server/app-render/create-component-tree.tsx @@ -227,10 +227,7 @@ async function createComponentTreeInternal({ } if (typeof layoutOrPageMod?.revalidate !== 'undefined') { - validateRevalidate( - layoutOrPageMod?.revalidate, - staticGenerationStore.urlPathname - ) + validateRevalidate(layoutOrPageMod?.revalidate, staticGenerationStore.route) } if (typeof layoutOrPageMod?.revalidate === 'number') { @@ -537,7 +534,7 @@ async function createComponentTreeInternal({ , loadingData, ], diff --git a/packages/next/src/server/app-render/dynamic-rendering.ts b/packages/next/src/server/app-render/dynamic-rendering.ts index 24b0fb2473edc..d67024f9bacd4 100644 --- a/packages/next/src/server/app-render/dynamic-rendering.ts +++ b/packages/next/src/server/app-render/dynamic-rendering.ts @@ -26,7 +26,6 @@ import React from 'react' import type { StaticGenerationStore } from '../../client/components/static-generation-async-storage.external' import { DynamicServerError } from '../../client/components/hooks-server-context' import { StaticGenBailoutError } from '../../client/components/static-generation-bailout' -import { getPathname } from '../../lib/url' const hasPostpone = typeof React.unstable_postpone === 'function' @@ -86,11 +85,9 @@ export function markCurrentScopeAsDynamic( // or it's static and it should not throw or postpone here. if (store.forceDynamic || store.forceStatic) return - const pathname = getPathname(store.urlPathname) - if (store.dynamicShouldError) { throw new StaticGenBailoutError( - `Route ${pathname} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering` + `Route ${store.route} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering` ) } @@ -101,7 +98,7 @@ export function markCurrentScopeAsDynamic( // We track that we had a dynamic scope that postponed. // This will be used by the renderer to decide whether // the prerender requires a resume - postponeWithTracking(store.prerenderState, expression, pathname) + postponeWithTracking(store.prerenderState, expression, store.route) } store.revalidate = 0 @@ -109,7 +106,7 @@ export function markCurrentScopeAsDynamic( if (store.isStaticGeneration) { // We aren't prerendering but we are generating a static page. We need to bail out of static generation const err = new DynamicServerError( - `Route ${pathname} couldn't be rendered statically because it used ${expression}. See more info here: https://nextjs.org/docs/messages/dynamic-server-error` + `Route ${store.route} couldn't be rendered statically because it used ${expression}. See more info here: https://nextjs.org/docs/messages/dynamic-server-error` ) store.dynamicUsageDescription = expression store.dynamicUsageStack = err.stack @@ -131,14 +128,13 @@ export function trackDynamicDataAccessed( store: StaticGenerationStore, expression: string ): void { - const pathname = getPathname(store.urlPathname) if (store.isUnstableCacheCallback) { throw new Error( - `Route ${pathname} used "${expression}" inside a function cached with "unstable_cache(...)". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "${expression}" outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/app/api-reference/functions/unstable_cache` + `Route ${store.route} used "${expression}" inside a function cached with "unstable_cache(...)". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "${expression}" outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/app/api-reference/functions/unstable_cache` ) } else if (store.dynamicShouldError) { throw new StaticGenBailoutError( - `Route ${pathname} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering` + `Route ${store.route} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering` ) } else if ( // We are in a prerender (PPR enabled, during build) @@ -147,14 +143,14 @@ export function trackDynamicDataAccessed( // We track that we had a dynamic scope that postponed. // This will be used by the renderer to decide whether // the prerender requires a resume - postponeWithTracking(store.prerenderState, expression, pathname) + postponeWithTracking(store.prerenderState, expression, store.route) } else { store.revalidate = 0 if (store.isStaticGeneration) { // We aren't prerendering but we are generating a static page. We need to bail out of static generation const err = new DynamicServerError( - `Route ${pathname} couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error` + `Route ${store.route} couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error` ) store.dynamicUsageDescription = expression store.dynamicUsageStack = err.stack @@ -170,24 +166,24 @@ export function trackDynamicDataAccessed( type PostponeProps = { reason: string prerenderState: PrerenderState - pathname: string + route: string } export function Postpone({ reason, prerenderState, - pathname, + route, }: PostponeProps): never { - postponeWithTracking(prerenderState, reason, pathname) + postponeWithTracking(prerenderState, reason, route) } function postponeWithTracking( prerenderState: PrerenderState, expression: string, - pathname: string + route: string ): never { assertPostpone() const reason = - `Route ${pathname} needs to bail out of prerendering at this point because it used ${expression}. ` + + `Route ${route} needs to bail out of prerendering at this point because it used ${expression}. ` + `React throws this special object to indicate where. It should not be caught by ` + `your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-caught-error` diff --git a/packages/next/src/server/app-render/entry-base.ts b/packages/next/src/server/app-render/entry-base.ts index 9a5ec61699cfe..e7160c2a7f221 100644 --- a/packages/next/src/server/app-render/entry-base.ts +++ b/packages/next/src/server/app-render/entry-base.ts @@ -44,7 +44,7 @@ function patchCacheScopeSupportIntoReact() { // patchFetch makes use of APIs such as `React.unstable_postpone` which are only available // in the experimental channel of React, so export it from here so that it comes from the bundled runtime function patchFetch() { - return _patchFetch({ staticGenerationAsyncStorage }) + return _patchFetch({ staticGenerationAsyncStorage, requestAsyncStorage }) } export { diff --git a/packages/next/src/server/app-render/types.ts b/packages/next/src/server/app-render/types.ts index 47ea6ff38ccf7..d9fded143cd13 100644 --- a/packages/next/src/server/app-render/types.ts +++ b/packages/next/src/server/app-render/types.ts @@ -143,7 +143,6 @@ export interface RenderOptsPartial { nextExport?: boolean nextConfigOutput?: 'standalone' | 'export' appDirDevErrorLogger?: (err: any) => Promise - originalPathname?: string isDraftMode?: boolean deploymentId?: string onUpdateCookies?: (cookies: string[]) => void diff --git a/packages/next/src/server/app-render/validate-url.tsx b/packages/next/src/server/app-render/validate-url.tsx deleted file mode 100644 index f43b1061b4398..0000000000000 --- a/packages/next/src/server/app-render/validate-url.tsx +++ /dev/null @@ -1,18 +0,0 @@ -const DUMMY_ORIGIN = 'http://n' -const INVALID_URL_MESSAGE = 'Invalid request URL' - -export function validateURL(url: string | undefined): string { - if (!url) { - throw new Error(INVALID_URL_MESSAGE) - } - try { - const parsed = new URL(url, DUMMY_ORIGIN) - // Avoid origin change by extra slashes in pathname - if (parsed.origin !== DUMMY_ORIGIN) { - throw new Error(INVALID_URL_MESSAGE) - } - return url - } catch { - throw new Error(INVALID_URL_MESSAGE) - } -} diff --git a/packages/next/src/server/async-storage/request-async-storage-wrapper.ts b/packages/next/src/server/async-storage/request-async-storage-wrapper.ts index f597987da07d5..1740a16c21712 100644 --- a/packages/next/src/server/async-storage/request-async-storage-wrapper.ts +++ b/packages/next/src/server/async-storage/request-async-storage-wrapper.ts @@ -40,19 +40,39 @@ function getMutableCookies( return MutableRequestCookiesAdapter.wrap(cookies, onUpdateCookies) } -export type WrapperRenderOpts = Omit & - RequestLifecycleOpts & +export type WrapperRenderOpts = RequestLifecycleOpts & Partial< Pick< RenderOpts, - 'ComponentMod' // can be undefined in a route handler + | 'ComponentMod' + | 'onUpdateCookies' + | 'assetPrefix' + | 'reactLoadableManifest' > > & { experimental: Pick + previewProps?: __ApiPreviewProps } export type RequestContext = { req: IncomingMessage | BaseNextRequest | NextRequest + /** + * The URL of the request. This only specifies the pathname and the search + * part of the URL. This is only undefined when generating static paths (ie, + * there is no request in progress, nor do we know one). + */ + url: { + /** + * The pathname of the requested URL. + */ + pathname: string + + /** + * The search part of the requested URL. If the request did not provide a + * search part, this will be an empty string. + */ + search?: string + } res?: ServerResponse | BaseNextResponse renderOpts?: WrapperRenderOpts } @@ -72,16 +92,9 @@ export const RequestAsyncStorageWrapper: AsyncStorageWrapper< */ wrap( storage: AsyncLocalStorage, - { req, res, renderOpts }: RequestContext, + { req, url, res, renderOpts }: RequestContext, callback: (store: RequestStore) => Result ): Result { - let previewProps: __ApiPreviewProps | undefined = undefined - - if (renderOpts && 'previewProps' in renderOpts) { - // TODO: investigate why previewProps isn't on RenderOpts - previewProps = (renderOpts as any).previewProps - } - const [wrapWithAfter, afterContext] = createAfterWrapper(renderOpts) function defaultOnUpdateCookies(cookies: string[]) { @@ -98,6 +111,10 @@ export const RequestAsyncStorageWrapper: AsyncStorageWrapper< } = {} const store: RequestStore = { + // Rather than just using the whole `url` here, we pull the parts we want + // to ensure we don't use parts of the URL that we shouldn't. This also + // lets us avoid requiring an empty string for `search` in the type. + url: { pathname: url.pathname, search: url.search ?? '' }, get headers() { if (!cache.headers) { // Seal the headers object that'll freeze out any methods that could @@ -154,7 +171,7 @@ export const RequestAsyncStorageWrapper: AsyncStorageWrapper< get draftMode() { if (!cache.draftMode) { cache.draftMode = new DraftModeProvider( - previewProps, + renderOpts?.previewProps, req, this.cookies, this.mutableCookies diff --git a/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts b/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts index 956cf140437f2..7a4d125a18151 100644 --- a/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts +++ b/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts @@ -4,12 +4,16 @@ import type { AsyncLocalStorage } from 'async_hooks' import type { IncrementalCache } from '../lib/incremental-cache' import type { RenderOptsPartial } from '../app-render/types' -import { createPrerenderState } from '../../server/app-render/dynamic-rendering' +import { createPrerenderState } from '../app-render/dynamic-rendering' import type { FetchMetric } from '../base-http' import type { RequestLifecycleOpts } from '../base-server' +import { normalizeAppPath } from '../../shared/lib/router/utils/app-paths' export type StaticGenerationContext = { - urlPathname: string + /** + * The page that is being rendered. This relates to the path to the page file. + */ + page: string requestEndedState?: { ended?: boolean } renderOpts: { incrementalCache?: IncrementalCache @@ -40,7 +44,6 @@ export type StaticGenerationContext = { // Pull some properties from RenderOptsPartial so that the docs are also // mirrored. RenderOptsPartial, - | 'originalPathname' | 'supportsDynamicResponse' | 'isRevalidate' | 'nextExport' @@ -56,7 +59,7 @@ export const StaticGenerationAsyncStorageWrapper: AsyncStorageWrapper< > = { wrap( storage: AsyncLocalStorage, - { urlPathname, renderOpts, requestEndedState }: StaticGenerationContext, + { page, renderOpts, requestEndedState }: StaticGenerationContext, callback: (store: StaticGenerationStore) => Result ): Result { /** @@ -88,8 +91,8 @@ export const StaticGenerationAsyncStorageWrapper: AsyncStorageWrapper< const store: StaticGenerationStore = { isStaticGeneration, - urlPathname, - pagePath: renderOpts.originalPathname, + page, + route: normalizeAppPath(page), incrementalCache: // we fallback to a global incremental cache for edge-runtime locally // so that it can access the fs cache without mocks diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index d5ca7ebf50195..f948f311ce8e6 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -2340,7 +2340,6 @@ export default abstract class Server< // it is not a dynamic RSC request then it is a revalidation // request. isRevalidate: isSSG && !postponed && !isDynamicRSCRequest, - originalPathname: components.ComponentMod.originalPathname, serverActions: this.nextConfig.experimental.serverActions, } : {}), @@ -2409,7 +2408,6 @@ export default abstract class Server< experimental: { after: renderOpts.experimental.after, }, - originalPathname: components.ComponentMod.originalPathname, supportsDynamicResponse, incrementalCache, isRevalidate: isSSG, diff --git a/packages/next/src/server/lib/patch-fetch.ts b/packages/next/src/server/lib/patch-fetch.ts index fe312aa0f62b1..8bded58694445 100644 --- a/packages/next/src/server/lib/patch-fetch.ts +++ b/packages/next/src/server/lib/patch-fetch.ts @@ -15,6 +15,10 @@ import * as Log from '../../build/output/log' import { markCurrentScopeAsDynamic } from '../app-render/dynamic-rendering' import type { FetchMetric } from '../base-http' import { createDedupeFetch } from './dedupe-fetch' +import type { + RequestAsyncStorage, + RequestStore, +} from '../../client/components/request-async-storage.external' const isEdgeRuntime = process.env.NEXT_RUNTIME === 'edge' @@ -34,7 +38,7 @@ function isPatchedFetch( export function validateRevalidate( revalidateVal: unknown, - pathname: string + route: string ): undefined | number | false { try { let normalizedRevalidate: false | number | undefined = undefined @@ -49,7 +53,7 @@ export function validateRevalidate( normalizedRevalidate = revalidateVal } else if (typeof revalidateVal !== 'undefined') { throw new Error( - `Invalid revalidate value "${revalidateVal}" on "${pathname}", must be a non-negative number or "false"` + `Invalid revalidate value "${revalidateVal}" on "${route}", must be a non-negative number or "false"` ) } return normalizedRevalidate @@ -127,35 +131,35 @@ const getDerivedTags = (pathname: string): string[] => { return derivedTags } -export function addImplicitTags(staticGenerationStore: StaticGenerationStore) { +export function addImplicitTags( + staticGenerationStore: StaticGenerationStore, + requestStore: RequestStore | undefined +) { const newTags: string[] = [] - const { pagePath, urlPathname } = staticGenerationStore + const { page } = staticGenerationStore - if (!Array.isArray(staticGenerationStore.tags)) { - staticGenerationStore.tags = [] - } - - if (pagePath) { - const derivedTags = getDerivedTags(pagePath) + // Ini the tags array if it doesn't exist. + staticGenerationStore.tags ??= [] - for (let tag of derivedTags) { - tag = `${NEXT_CACHE_IMPLICIT_TAG_ID}${tag}` - if (!staticGenerationStore.tags?.includes(tag)) { - staticGenerationStore.tags.push(tag) - } - newTags.push(tag) + // Add the derived tags from the page. + const derivedTags = getDerivedTags(page) + for (let tag of derivedTags) { + tag = `${NEXT_CACHE_IMPLICIT_TAG_ID}${tag}` + if (!staticGenerationStore.tags?.includes(tag)) { + staticGenerationStore.tags.push(tag) } + newTags.push(tag) } - if (urlPathname) { - const parsedPathname = new URL(urlPathname, 'http://n').pathname - - const tag = `${NEXT_CACHE_IMPLICIT_TAG_ID}${parsedPathname}` + // Add the tags from the pathname. + if (requestStore?.url.pathname) { + const tag = `${NEXT_CACHE_IMPLICIT_TAG_ID}${requestStore.url.pathname}` if (!staticGenerationStore.tags?.includes(tag)) { staticGenerationStore.tags.push(tag) } newTags.push(tag) } + return newTags } @@ -210,11 +214,12 @@ function trackFetchMetric( interface PatchableModule { staticGenerationAsyncStorage: StaticGenerationAsyncStorage + requestAsyncStorage: RequestAsyncStorage } function createPatchedFetcher( originFetch: Fetcher, - { staticGenerationAsyncStorage }: PatchableModule + { staticGenerationAsyncStorage, requestAsyncStorage }: PatchableModule ): PatchedFetcher { // Create the patched fetch function. We don't set the type here, as it's // verified as the return value of this function. @@ -260,6 +265,7 @@ function createPatchedFetcher( } const staticGenerationStore = staticGenerationAsyncStorage.getStore() + const requestStore = requestAsyncStorage.getStore() // If the staticGenerationStore is not available, we can't do any // special treatment of fetch, therefore fallback to the original @@ -311,7 +317,10 @@ function createPatchedFetcher( } } } - const implicitTags = addImplicitTags(staticGenerationStore) + const implicitTags = addImplicitTags( + staticGenerationStore, + requestStore + ) const pageFetchCacheMode = staticGenerationStore.fetchCache const isUsingNoStore = !!staticGenerationStore.isUnstableNoStore @@ -327,7 +336,7 @@ function createPatchedFetcher( // we only want to warn if the user is explicitly setting a cache value if (!(isRequestInput && currentFetchCacheConfig === 'default')) { Log.warn( - `fetch for ${fetchUrl} on ${staticGenerationStore.urlPathname} specified "cache: ${currentFetchCacheConfig}" and "revalidate: ${currentFetchRevalidate}", only one should be specified.` + `fetch for ${fetchUrl} on ${staticGenerationStore.route} specified "cache: ${currentFetchCacheConfig}" and "revalidate: ${currentFetchRevalidate}", only one should be specified.` ) } currentFetchCacheConfig = undefined @@ -359,7 +368,7 @@ function createPatchedFetcher( finalRevalidate = validateRevalidate( currentFetchRevalidate, - staticGenerationStore.urlPathname + staticGenerationStore.route ) const _headers = getRequestMeta('headers') @@ -484,11 +493,7 @@ function createPatchedFetcher( if (finalRevalidate === 0) { markCurrentScopeAsDynamic( staticGenerationStore, - `revalidate: 0 fetch ${input}${ - staticGenerationStore.urlPathname - ? ` ${staticGenerationStore.urlPathname}` - : '' - }` + `revalidate: 0 fetch ${input} ${staticGenerationStore.route}` ) } @@ -711,11 +716,7 @@ function createPatchedFetcher( // If enabled, we should bail out of static generation. markCurrentScopeAsDynamic( staticGenerationStore, - `no-store fetch ${input}${ - staticGenerationStore.urlPathname - ? ` ${staticGenerationStore.urlPathname}` - : '' - }` + `no-store fetch ${input} ${staticGenerationStore.route}` ) } @@ -731,11 +732,7 @@ function createPatchedFetcher( // If enabled, we should bail out of static generation. markCurrentScopeAsDynamic( staticGenerationStore, - `revalidate: 0 fetch ${input}${ - staticGenerationStore.urlPathname - ? ` ${staticGenerationStore.urlPathname}` - : '' - }` + `revalidate: 0 fetch ${input} ${staticGenerationStore.route}` ) } diff --git a/packages/next/src/server/load-components.ts b/packages/next/src/server/load-components.ts index 0d01343a5d7e8..5e9fc519c2fc6 100644 --- a/packages/next/src/server/load-components.ts +++ b/packages/next/src/server/load-components.ts @@ -64,7 +64,7 @@ export type LoadComponentsReturnType = { getStaticPaths?: GetStaticPaths getServerSideProps?: GetServerSideProps ComponentMod: NextModule - routeModule?: RouteModule + routeModule: RouteModule isAppPath?: boolean page: string } diff --git a/packages/next/src/server/load-default-error-components.ts b/packages/next/src/server/load-default-error-components.ts index b1b0f669d3791..8e35f2469404b 100644 --- a/packages/next/src/server/load-default-error-components.ts +++ b/packages/next/src/server/load-default-error-components.ts @@ -40,7 +40,7 @@ export type LoadComponentsReturnType = { getStaticPaths?: GetStaticPaths getServerSideProps?: GetServerSideProps ComponentMod: any - routeModule?: RouteModule + routeModule: RouteModule isAppPath?: boolean page: string } diff --git a/packages/next/src/server/route-modules/app-route/module.ts b/packages/next/src/server/route-modules/app-route/module.ts index 63e76265104bf..0b76b07a7eae1 100644 --- a/packages/next/src/server/route-modules/app-route/module.ts +++ b/packages/next/src/server/route-modules/app-route/module.ts @@ -257,19 +257,18 @@ export class AppRouteRouteModule extends RouteModule< // Get the context for the request. const requestContext: RequestContext = { req: rawRequest, - } - - requestContext.renderOpts = { - // @ts-expect-error TODO: types for renderOpts should include previewProps - previewProps: context.prerenderManifest.preview, - waitUntil: context.renderOpts.waitUntil, - onClose: context.renderOpts.onClose, - experimental: context.renderOpts.experimental, + url: rawRequest.nextUrl, + renderOpts: { + previewProps: context.prerenderManifest.preview, + waitUntil: context.renderOpts.waitUntil, + onClose: context.renderOpts.onClose, + experimental: context.renderOpts.experimental, + }, } // Get the context for the static generation. const staticGenerationContext: StaticGenerationContext = { - urlPathname: rawRequest.nextUrl.pathname, + page: this.definition.page, renderOpts: context.renderOpts, } @@ -288,7 +287,7 @@ export class AppRouteRouteModule extends RouteModule< RequestAsyncStorageWrapper.wrap( this.requestAsyncStorage, requestContext, - () => + (requestStore) => StaticGenerationAsyncStorageWrapper.wrap( this.staticGenerationAsyncStorage, staticGenerationContext, @@ -375,6 +374,7 @@ export class AppRouteRouteModule extends RouteModule< patchFetch({ staticGenerationAsyncStorage: this.staticGenerationAsyncStorage, + requestAsyncStorage: this.requestAsyncStorage, }) const res = await handler(request, { params: context.params @@ -398,14 +398,13 @@ export class AppRouteRouteModule extends RouteModule< ), ]) - addImplicitTags(staticGenerationStore) + addImplicitTags(staticGenerationStore, requestStore) ;(context.renderOpts as any).fetchTags = staticGenerationStore.tags?.join(',') // It's possible cookies were set in the handler, so we need // to merge the modified cookies and the returned response // here. - const requestStore = this.requestAsyncStorage.getStore() if (requestStore && requestStore.mutableCookies) { const headers = new Headers(res.headers) if ( diff --git a/packages/next/src/server/web/adapter.ts b/packages/next/src/server/web/adapter.ts index 42100a08b78ff..701c0c1a27217 100644 --- a/packages/next/src/server/web/adapter.ts +++ b/packages/next/src/server/web/adapter.ts @@ -240,20 +240,22 @@ export async function adapter( }, async () => { try { + const previewProps = prerenderManifest?.preview || { + previewModeId: 'development-id', + previewModeEncryptionKey: '', + previewModeSigningKey: '', + } + return await RequestAsyncStorageWrapper.wrap( requestAsyncStorage, { req: request, + url: request.nextUrl, renderOpts: { onUpdateCookies: (cookies) => { cookiesFromResponse = cookies }, - // @ts-expect-error TODO: investigate why previewProps isn't on RenderOpts - previewProps: prerenderManifest?.preview || { - previewModeId: 'development-id', - previewModeEncryptionKey: '', - previewModeSigningKey: '', - }, + previewProps, waitUntil, onClose: closeController ? closeController.onClose.bind(closeController) diff --git a/packages/next/src/server/web/spec-extension/revalidate.ts b/packages/next/src/server/web/spec-extension/revalidate.ts index 00996c7d188f2..015a1701a0d36 100644 --- a/packages/next/src/server/web/spec-extension/revalidate.ts +++ b/packages/next/src/server/web/spec-extension/revalidate.ts @@ -4,7 +4,6 @@ import { NEXT_CACHE_IMPLICIT_TAG_ID, NEXT_CACHE_SOFT_TAG_MAX_LENGTH, } from '../../../lib/constants' -import { getPathname } from '../../../lib/url' import { staticGenerationAsyncStorage } from '../../../client/components/static-generation-async-storage.external' /** @@ -51,9 +50,7 @@ function revalidate(tag: string, expression: string) { if (store.isUnstableCacheCallback) { throw new Error( - `Route ${getPathname( - store.urlPathname - )} used "${expression}" inside a function cached with "unstable_cache(...)" which is unsupported. To ensure revalidation is performed consistently it must always happen outside of renders and cached functions. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering` + `Route ${store.route} used "${expression}" inside a function cached with "unstable_cache(...)" which is unsupported. To ensure revalidation is performed consistently it must always happen outside of renders and cached functions. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering` ) } diff --git a/packages/next/src/server/web/spec-extension/unstable-cache.ts b/packages/next/src/server/web/spec-extension/unstable-cache.ts index e132279e0a94e..7e213105becd4 100644 --- a/packages/next/src/server/web/spec-extension/unstable-cache.ts +++ b/packages/next/src/server/web/spec-extension/unstable-cache.ts @@ -7,6 +7,7 @@ import { validateTags, } from '../../lib/patch-fetch' import { staticGenerationAsyncStorage } from '../../../client/components/static-generation-async-storage.external' +import { requestAsyncStorage } from '../../../client/components/request-async-storage.external' type Callback = (...args: any[]) => Promise @@ -90,13 +91,15 @@ export function unstable_cache( }` const cachedCb = async (...args: any[]) => { - const store = staticGenerationAsyncStorage.getStore() + const staticGenerationStore = staticGenerationAsyncStorage.getStore() + const requestStore = requestAsyncStorage.getStore() // We must be able to find the incremental cache otherwise we throw const maybeIncrementalCache: | import('../../lib/incremental-cache').IncrementalCache | undefined = - store?.incrementalCache || (globalThis as any).__incrementalCache + staticGenerationStore?.incrementalCache || + (globalThis as any).__incrementalCache if (!maybeIncrementalCache) { throw new Error( @@ -105,10 +108,14 @@ export function unstable_cache( } const incrementalCache = maybeIncrementalCache - const { pathname, searchParams } = new URL( - store?.urlPathname || '/', - 'http://n' - ) + // If there's no request store, we aren't in a request (or we're not in app + // router) and if there's no static generation store, we aren't in app + // router. Default to an empty pathname and search params when there's no + // request store or static generation store available. + const pathname = + requestStore?.url.pathname ?? staticGenerationStore?.route ?? '' + const searchParams = new URLSearchParams(requestStore?.url.search ?? '') + const sortedSearchKeys = [...searchParams.keys()].sort((a, b) => { return a.localeCompare(b) }) @@ -123,10 +130,13 @@ export function unstable_cache( const cacheKey = await incrementalCache.fetchCacheKey(invocationKey) // $urlWithPath,$sortedQueryStringKeys,$hashOfEveryThingElse const fetchUrl = `unstable_cache ${pathname}${sortedSearch.length ? '?' : ''}${sortedSearch} ${cb.name ? ` ${cb.name}` : cacheKey}` - const fetchIdx = (store ? store.nextFetchId : noStoreFetchIdx) ?? 1 + const fetchIdx = + (staticGenerationStore + ? staticGenerationStore.nextFetchId + : noStoreFetchIdx) ?? 1 - if (store) { - store.nextFetchId = fetchIdx + 1 + if (staticGenerationStore) { + staticGenerationStore.nextFetchId = fetchIdx + 1 // We are in an App Router context. We try to return the cached entry if it exists and is valid // If the entry is fresh we return it. If the entry is stale we return it but revalidate the entry in @@ -135,43 +145,43 @@ export function unstable_cache( // We update the store's revalidate property if the option.revalidate is a higher precedence if (typeof options.revalidate === 'number') { if ( - typeof store.revalidate === 'number' && - store.revalidate < options.revalidate + typeof staticGenerationStore.revalidate === 'number' && + staticGenerationStore.revalidate < options.revalidate ) { // The store is already revalidating on a shorter time interval, leave it alone } else { - store.revalidate = options.revalidate + staticGenerationStore.revalidate = options.revalidate } } else if ( options.revalidate === false && - typeof store.revalidate === 'undefined' + typeof staticGenerationStore.revalidate === 'undefined' ) { // The store has not defined revalidate type so we can use the false option - store.revalidate = options.revalidate + staticGenerationStore.revalidate = options.revalidate } // We need to accumulate the tags for this invocation within the store - if (!store.tags) { - store.tags = tags.slice() + if (!staticGenerationStore.tags) { + staticGenerationStore.tags = tags.slice() } else { for (const tag of tags) { // @TODO refactor tags to be a set to avoid this O(n) lookup - if (!store.tags.includes(tag)) { - store.tags.push(tag) + if (!staticGenerationStore.tags.includes(tag)) { + staticGenerationStore.tags.push(tag) } } } // @TODO check on this API. addImplicitTags mutates the store and returns the implicit tags. The naming // of this function is potentially a little confusing - const implicitTags = addImplicitTags(store) + const implicitTags = addImplicitTags(staticGenerationStore, requestStore) if ( // when we are nested inside of other unstable_cache's // we should bypass cache similar to fetches - store.fetchCache !== 'force-no-store' && - !store.isOnDemandRevalidate && + staticGenerationStore.fetchCache !== 'force-no-store' && + !staticGenerationStore.isOnDemandRevalidate && !incrementalCache.isOnDemandRevalidate && - !store.isDraftMode + !staticGenerationStore.isDraftMode ) { // We attempt to get the current cache entry from the incremental cache. const cacheEntry = await incrementalCache.get(cacheKey, { @@ -203,15 +213,15 @@ export function unstable_cache( : undefined if (cacheEntry.isStale) { // In App Router we return the stale result and revalidate in the background - if (!store.pendingRevalidates) { - store.pendingRevalidates = {} + if (!staticGenerationStore.pendingRevalidates) { + staticGenerationStore.pendingRevalidates = {} } // We run the cache function asynchronously and save the result when it completes - store.pendingRevalidates[invocationKey] = + staticGenerationStore.pendingRevalidates[invocationKey] = staticGenerationAsyncStorage .run( { - ...store, + ...staticGenerationStore, // force any nested fetches to bypass cache so they revalidate // when the unstable_cache call is revalidated fetchCache: 'force-no-store', @@ -248,7 +258,7 @@ export function unstable_cache( // If we got this far then we had an invalid cache entry and need to generate a new one const result = await staticGenerationAsyncStorage.run( { - ...store, + ...staticGenerationStore, // force any nested fetches to bypass cache so they revalidate // when the unstable_cache call is revalidated fetchCache: 'force-no-store', @@ -279,7 +289,9 @@ export function unstable_cache( // @TODO check on this API. addImplicitTags mutates the store and returns the implicit tags. The naming // of this function is potentially a little confusing - const implicitTags = store && addImplicitTags(store) + const implicitTags = + staticGenerationStore && + addImplicitTags(staticGenerationStore, requestStore) const cacheEntry = await incrementalCache.get(cacheKey, { kindHint: 'fetch', @@ -325,7 +337,8 @@ export function unstable_cache( // when the unstable_cache call is revalidated fetchCache: 'force-no-store', isUnstableCacheCallback: true, - urlPathname: '/', + route: '/', + page: '/', isStaticGeneration: false, prerenderState: null, }, diff --git a/packages/next/src/shared/lib/router/utils/parse-relative-url.test.ts b/packages/next/src/shared/lib/router/utils/parse-relative-url.test.ts new file mode 100644 index 0000000000000..8c71acfda0b83 --- /dev/null +++ b/packages/next/src/shared/lib/router/utils/parse-relative-url.test.ts @@ -0,0 +1,20 @@ +import { parseRelativeUrl } from './parse-relative-url' + +describe('relative urls', () => { + it('should return valid pathname', () => { + expect(parseRelativeUrl('/').pathname).toBe('/') + expect(parseRelativeUrl('/abc').pathname).toBe('/abc') + }) + + it('should throw for invalid pathname', () => { + expect(() => parseRelativeUrl('//**y/\\')).toThrow() + expect(() => parseRelativeUrl('//google.com')).toThrow() + }) +}) + +describe('query parsing', () => { + it('should parse query string', () => { + expect(parseRelativeUrl('/?a=1&b=2').query).toEqual({ a: '1', b: '2' }) + expect(parseRelativeUrl('/').query).toEqual({}) + }) +}) diff --git a/packages/next/src/shared/lib/router/utils/parse-relative-url.ts b/packages/next/src/shared/lib/router/utils/parse-relative-url.ts index e5a49bca4d159..4abc04fa23c11 100644 --- a/packages/next/src/shared/lib/router/utils/parse-relative-url.ts +++ b/packages/next/src/shared/lib/router/utils/parse-relative-url.ts @@ -18,8 +18,19 @@ export interface ParsedRelativeUrl { */ export function parseRelativeUrl( url: string, - base?: string -): ParsedRelativeUrl { + base?: string, + parseQuery?: true +): ParsedRelativeUrl +export function parseRelativeUrl( + url: string, + base: string | undefined, + parseQuery: false +): Omit +export function parseRelativeUrl( + url: string, + base?: string, + parseQuery = true +): ParsedRelativeUrl | Omit { const globalBase = new URL( typeof window === 'undefined' ? 'http://n' : getLocationOrigin() ) @@ -36,14 +47,16 @@ export function parseRelativeUrl( url, resolvedBase ) + if (origin !== globalBase.origin) { throw new Error(`invariant: invalid relative URL, router received ${url}`) } + return { pathname, - query: searchParamsToUrlQuery(searchParams), + query: parseQuery ? searchParamsToUrlQuery(searchParams) : undefined, search, hash, - href: href.slice(globalBase.origin.length), + href: href.slice(origin.length), } } diff --git a/packages/next/src/shared/lib/router/utils/resolve-rewrites.ts b/packages/next/src/shared/lib/router/utils/resolve-rewrites.ts index c886a718d6004..4c1bb545147b6 100644 --- a/packages/next/src/shared/lib/router/utils/resolve-rewrites.ts +++ b/packages/next/src/shared/lib/router/utils/resolve-rewrites.ts @@ -5,7 +5,7 @@ import { matchHas, prepareDestination } from './prepare-destination' import { removeTrailingSlash } from './remove-trailing-slash' import { normalizeLocalePath } from '../../i18n/normalize-locale-path' import { removeBasePath } from '../../../../client/remove-base-path' -import { parseRelativeUrl } from './parse-relative-url' +import { parseRelativeUrl, type ParsedRelativeUrl } from './parse-relative-url' export default function resolveRewrites( asPath: string, @@ -20,7 +20,7 @@ export default function resolveRewrites( locales?: string[] ): { matchedPage: boolean - parsedAs: ReturnType + parsedAs: ParsedRelativeUrl asPath: string resolvedHref?: string externalDest?: boolean diff --git a/test/unit/validate-url.test.ts b/test/unit/validate-url.test.ts deleted file mode 100644 index a82e9fe985ab1..0000000000000 --- a/test/unit/validate-url.test.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { validateURL } from 'next/dist/server/app-render/validate-url' - -describe('validateUrl', () => { - it('should return valid pathname', () => { - expect(validateURL('/')).toBe('/') - expect(validateURL('/abc')).toBe('/abc') - }) - - it('should throw for invalid pathname', () => { - expect(() => validateURL('//**y/\\')).toThrow() - expect(() => validateURL('//google.com')).toThrow() - }) -}) From 65fd44b892115724599d8684e8f282299013e3a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Wed, 12 Jun 2024 05:02:10 +0900 Subject: [PATCH 34/60] build: Update `swc_core` to `v0.93.2` (#66698) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Turbopack * https://github.com/vercel/turbo/pull/8324 * https://github.com/vercel/turbo/pull/8395 ### What? Update `swc_core`. ### Why? Update `swc_core`. The regression of minifier is fixed by https://github.com/swc-project/swc/pull/9031 ### How? --- Cargo.lock | 195 ++++++++++-------- Cargo.toml | 8 +- .../crates/next-custom-transforms/Cargo.toml | 4 +- packages/next/package.json | 2 +- pnpm-lock.yaml | 8 +- 5 files changed, 117 insertions(+), 100 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 593060f5cc206..040f6ae61158f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -321,7 +321,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "serde", "smallvec", @@ -446,9 +446,9 @@ dependencies = [ [[package]] name = "binding_macros" -version = "0.66.0" +version = "0.67.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3f426fc63b42e1c6e6e0974d3fa3fe08513c5b441d80fd24d0c0a54b661dfa" +checksum = "4cb67bba3eb7ac48982404ebec9fabdb26b8263fcabe23b99d8c0e6f5b97cc81" dependencies = [ "anyhow", "console_error_panic_hook", @@ -2715,9 +2715,9 @@ dependencies = [ [[package]] name = "mdxjs" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5860860bfc09972a5d99bfb866dde39485fe397210f8a9ccf68a6c6740d687b" +checksum = "08b14a30b8511133accf39b86da3d07ebbead12aa98a220accf43a99300d9620" dependencies = [ "markdown", "serde", @@ -2853,9 +2853,9 @@ dependencies = [ [[package]] name = "modularize_imports" -version = "0.68.14" +version = "0.68.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440dfda6d4b4cfa76c0b12b564c9b8d643b5c2bc8a63ed5dfc2a46cf1c68ac61" +checksum = "3d1ed4453f3dcc7ed01304aadd254f804a915e4725243e92822e18774593dea3" dependencies = [ "convert_case", "handlebars", @@ -3092,7 +3092,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "serde", @@ -4008,9 +4008,9 @@ dependencies = [ [[package]] name = "react_remove_properties" -version = "0.24.12" +version = "0.24.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb434309dc6f664c8f531b3965dd7f99b7f8a52d4171697bb9de6af83564265" +checksum = "78d9f9011dc19b1e02182954b3ab270f779444d27a5d173f9e51e39667d74ab4" dependencies = [ "serde", "swc_atoms", @@ -4125,9 +4125,9 @@ checksum = "c707298afce11da2efef2f600116fa93ffa7a032b5d7b628aa17711ec81383ca" [[package]] name = "remove_console" -version = "0.25.12" +version = "0.25.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1f807e0b5d9565a8558139ad4f1ec9703dd8cfa15607e347f3f66c4b7a0327" +checksum = "07e328828feeecd4c01acc7abb541510f3adbd2250bf1a8ebae0b1e37d4f467d" dependencies = [ "serde", "swc_atoms", @@ -5000,9 +5000,9 @@ checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" [[package]] name = "styled_components" -version = "0.96.15" +version = "0.96.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d7e14a22b6bf299ed8c2072e719c27324be5060a39b2bd70e62ad2a9505fe71" +checksum = "b661b68dbffeb5e9186523957c3586f609c99df3ee36fa6da0e12377101f54a1" dependencies = [ "Inflector", "once_cell", @@ -5018,9 +5018,9 @@ dependencies = [ [[package]] name = "styled_jsx" -version = "0.73.21" +version = "0.73.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17e38b2334f6613c9e811cc776bc9d2329c288f4dc125df68615fe6cf19b48ae" +checksum = "598108b5402971bd12dd8936ad1b3165b44505d34e5dd7ec4afa413190453a34" dependencies = [ "anyhow", "lightningcss", @@ -5080,9 +5080,9 @@ dependencies = [ [[package]] name = "swc" -version = "0.275.1" +version = "0.276.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ac38cd938ce20693b58b26a5d1926a46074db09cf90a251d83cf17cdaea6031" +checksum = "0fecebc2d47ba1e6a0b125ea6e55d111014c78ea5bbf519f9b378dfd54f19020" dependencies = [ "anyhow", "base64 0.21.4", @@ -5125,6 +5125,7 @@ dependencies = [ "swc_plugin_proxy", "swc_plugin_runner", "swc_timer", + "swc_transform_common", "swc_visit", "tokio", "tracing", @@ -5147,9 +5148,9 @@ dependencies = [ [[package]] name = "swc_bundler" -version = "0.227.0" +version = "0.228.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1a212bd08b1121c7204a04407ea055779fc00cf80024fc666dd97b00749cf87" +checksum = "43e4698d94115ea10fe3c6fdde2d1e736c6ba6601abab0a61d95e1015d13359f" dependencies = [ "anyhow", "crc", @@ -5226,9 +5227,9 @@ dependencies = [ [[package]] name = "swc_compiler_base" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "754058388d4f51df61f9aced73dfca96d81fed1c0a46583dc7b3da07688af80d" +checksum = "fdff81d2ae11503b2cb34b37cd481c3400d19c7c05445dd5daad5cd29692ee69" dependencies = [ "anyhow", "base64 0.21.4", @@ -5236,7 +5237,9 @@ dependencies = [ "napi-derive", "once_cell", "pathdiff", + "rustc-hash", "serde", + "serde_json", "sourcemap", "swc_atoms", "swc_common", @@ -5251,9 +5254,9 @@ dependencies = [ [[package]] name = "swc_config" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be1a689e146be1eae53139482cb061dcf0fa01dff296bbe7b96fff92d8e2936" +checksum = "84b67e115ab136fe0eb03558bb0508ca7782eeb446a96d165508c48617e3fd94" dependencies = [ "anyhow", "indexmap 2.2.6", @@ -5278,9 +5281,9 @@ dependencies = [ [[package]] name = "swc_core" -version = "0.92.5" +version = "0.93.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e317f6f8b15019358d1e48631c0e6d098d9a3d00d666ea99650201661abea855" +checksum = "57f2da78bdc49a5bd2edc80213f2b95300b11a15068e18ab9a9dd943a8660d59" dependencies = [ "binding_macros", "swc", @@ -5392,9 +5395,9 @@ dependencies = [ [[package]] name = "swc_css_modules" -version = "0.29.35" +version = "0.29.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a367c7ec6afd24bb3fcc2df95a2adf5d7462367d5b13afd8e43a7beba44358" +checksum = "b20af192df5adddac04293b5072cc00befa2d6818a9fc90ac6f5c2c49e82dd1c" dependencies = [ "rustc-hash", "serde", @@ -5466,9 +5469,9 @@ dependencies = [ [[package]] name = "swc_ecma_ast" -version = "0.113.4" +version = "0.113.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1690cc0c9ab60b44ac0225ba1e231ac532f7ba1d754df761c6ee607561afae" +checksum = "98a534a8360a076a030989f6d121ba6044345594bdf0457c4629f432742026b8" dependencies = [ "bitflags 2.5.0", "bytecheck", @@ -5486,9 +5489,9 @@ dependencies = [ [[package]] name = "swc_ecma_codegen" -version = "0.149.1" +version = "0.149.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fef147127a2926ca26171c7afcbf028ff86dc543ced87d316713f25620a15b9" +checksum = "6ab6d5e7bbd9208f980b5dad2a4a6ae798c97569f809a48c3f92e6ae7e183c6c" dependencies = [ "memchr", "num-bigint", @@ -5547,9 +5550,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2015" -version = "0.5.1" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248532f9ae603be6bf4763f66f74ad0dfd82d6307be876ccf4c5d081826a1161" +checksum = "d5f902caf95f4475a8963a3f7c0d645c1d7fcd81464cfb8165b78d5aeb0bcff2" dependencies = [ "arrayvec", "indexmap 2.2.6", @@ -5711,9 +5714,9 @@ dependencies = [ [[package]] name = "swc_ecma_ext_transforms" -version = "0.114.1" +version = "0.114.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "259b7b69630aafde63c6304eeacb93fd54619cbdb199c978549acc76cd512d76" +checksum = "91b55ddf8b600f07d0086a9a782d55aa048d3c1ac5eabaa27733d9f45d960e52" dependencies = [ "phf 0.11.2", "swc_atoms", @@ -5767,9 +5770,9 @@ dependencies = [ [[package]] name = "swc_ecma_minifier" -version = "0.194.4" +version = "0.195.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dbee669d44953537b6dcaad4a07aa00034fb9eabe4974b5b60acdd1fa9ce209" +checksum = "574ca302d18880ff3809d83797a51eb96a8f4cef7c948286a59cd1937e0226d0" dependencies = [ "arrayvec", "indexmap 2.2.6", @@ -5801,9 +5804,9 @@ dependencies = [ [[package]] name = "swc_ecma_parser" -version = "0.144.1" +version = "0.144.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0499e69683ae5d67a20ff0279b94bc90f29df7922a46331b54d5dd367bf89570" +checksum = "31adf4599e8de70f3b754dfc34ec2ab09fa6841d79a9f4a888250a404eae7030" dependencies = [ "either", "new_debug_unreachable", @@ -5898,9 +5901,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_base" -version = "0.138.2" +version = "0.138.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddb95c2bdad1c9c29edf35712e1e0f9b9ddc1cdb5ba2d582fd93468cb075a03" +checksum = "f7b76d09313cdd8f99bc1519fb04f8a93427c7a6f4bfbc64b39fcc5a378ab1b7" dependencies = [ "better_scoped_tls", "bitflags 2.5.0", @@ -6012,9 +6015,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_optimization" -version = "0.199.1" +version = "0.199.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ea30b3df748236c619409f222f0ba68ebeebc08dfff109d2195664a15689f9" +checksum = "25982d69c91cd64cbfae714d9e953810b3f2835486d08108967cbd15016e7720" dependencies = [ "dashmap", "indexmap 2.2.6", @@ -6125,9 +6128,9 @@ dependencies = [ [[package]] name = "swc_ecma_usage_analyzer" -version = "0.24.1" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98a693898bd44782a234d9a4122d52b93accf447282d08c2364eb739ae864154" +checksum = "6d7d7109b3794756cc51e842dbb874d2da44293b06a9e3837b477300b0ccef8e" dependencies = [ "indexmap 2.2.6", "rustc-hash", @@ -6142,15 +6145,16 @@ dependencies = [ [[package]] name = "swc_ecma_utils" -version = "0.128.1" +version = "0.128.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe5242670bc74e0a0b64b9d4912b37be36944517ce0881314162aeb4381272c3" +checksum = "02f470d8cc31adf6189b228636201ee3cdd268c0b5a2d0407f83093dfa96ff91" dependencies = [ "indexmap 2.2.6", "num_cpus", "once_cell", "rayon", "rustc-hash", + "ryu-js", "swc_atoms", "swc_common", "swc_ecma_ast", @@ -6176,9 +6180,9 @@ dependencies = [ [[package]] name = "swc_emotion" -version = "0.72.13" +version = "0.72.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b454c1b99da4da9aab3731ab34d7582d2eab96e47670d0c62711053886ef7e2" +checksum = "038b284022103a111078a012760423d6e88ba48fabe1a9fcb9229e661e6300c3" dependencies = [ "base64 0.22.1", "byteorder", @@ -6310,9 +6314,9 @@ dependencies = [ [[package]] name = "swc_plugin_runner" -version = "0.107.1" +version = "0.107.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73640537e0967a88a537c853de4a41ba6cdf77bfff1999f7c6c449e5bc550eed" +checksum = "0cc31ec32964d3ebaebfd5a2466a2aaa909aa00722d677f89994b2b6c27d105c" dependencies = [ "anyhow", "enumset", @@ -6335,9 +6339,9 @@ dependencies = [ [[package]] name = "swc_relay" -version = "0.44.14" +version = "0.44.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14a596e01319abf55b8a8c7e36a82aa0d1ac01a18a99ce9b07a7fbcbfd544466" +checksum = "89b9cc7f85e3bd8fdd8a81a96d34e1a589c2b4deb7b5a08cd59918f612b1b3c0" dependencies = [ "once_cell", "regex", @@ -6371,6 +6375,19 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "swc_transform_common" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda3e80e1ad638d3575bc07745a914af13dcb02215098659f864731078271f2c" +dependencies = [ + "better_scoped_tls", + "once_cell", + "rustc-hash", + "serde", + "serde_json", +] + [[package]] name = "swc_visit" version = "0.5.14" @@ -6947,12 +6964,12 @@ dependencies = [ [[package]] name = "turbo-prehash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "async-trait", @@ -6984,7 +7001,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "cargo-lock", @@ -6996,7 +7013,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "bytes", @@ -7010,7 +7027,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "dotenvs", @@ -7024,7 +7041,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "lazy_static", @@ -7040,7 +7057,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "auto-hash-map", @@ -7072,7 +7089,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "md4", "turbo-tasks-macros", @@ -7082,7 +7099,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "proc-macro-error", @@ -7096,7 +7113,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "proc-macro2", "quote", @@ -7106,7 +7123,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "mimalloc", ] @@ -7114,7 +7131,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "auto-hash-map", @@ -7141,7 +7158,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "async-recursion", @@ -7171,7 +7188,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "auto-hash-map", "mdxjs", @@ -7212,7 +7229,7 @@ dependencies = [ [[package]] name = "turbopack-browser" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7235,7 +7252,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "clap", @@ -7252,7 +7269,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "async-recursion", @@ -7281,7 +7298,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7308,7 +7325,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "async-compression", @@ -7344,7 +7361,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "async-trait", @@ -7379,7 +7396,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "serde", "serde_json", @@ -7390,7 +7407,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "async-trait", @@ -7415,7 +7432,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "indoc", @@ -7431,7 +7448,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7447,7 +7464,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "base64 0.21.4", @@ -7466,7 +7483,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "serde", @@ -7481,7 +7498,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "mdxjs", @@ -7496,7 +7513,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "async-stream", @@ -7530,7 +7547,7 @@ dependencies = [ [[package]] name = "turbopack-nodejs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7550,7 +7567,7 @@ dependencies = [ [[package]] name = "turbopack-resolve" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7568,7 +7585,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "serde", @@ -7584,7 +7601,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "swc_core", "turbo-tasks", @@ -7595,7 +7612,7 @@ dependencies = [ [[package]] name = "turbopack-trace-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "either", @@ -7615,7 +7632,7 @@ dependencies = [ [[package]] name = "turbopack-trace-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "crossbeam-channel", @@ -7631,7 +7648,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240610.2#efcea7608461e2c90943cbea54ef638c7e7a25d6" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index 16ffbc9d43e30..fcb447ed1449b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,18 +30,18 @@ next-core = { path = "packages/next-swc/crates/next-core" } next-custom-transforms = { path = "packages/next-swc/crates/next-custom-transforms" } # SWC crates -swc_core = { version = "0.92.5", features = [ +swc_core = { version = "0.93.2", features = [ "ecma_loader_lru", "ecma_loader_parking_lot", ] } testing = { version = "0.35.25" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240610.2" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240611.2" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240610.2" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240611.2" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240610.2" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240611.2" } # General Deps diff --git a/packages/next-swc/crates/next-custom-transforms/Cargo.toml b/packages/next-swc/crates/next-custom-transforms/Cargo.toml index 58dd112cf5674..6a90108b47fc6 100644 --- a/packages/next-swc/crates/next-custom-transforms/Cargo.toml +++ b/packages/next-swc/crates/next-custom-transforms/Cargo.toml @@ -38,8 +38,8 @@ turbopack-binding = { workspace = true, features = [ ] } # To allow quote! macro works swc_core = { workspace = true, features = ["ecma_quote"] } -react_remove_properties = "0.24.12" -remove_console = "0.25.12" +react_remove_properties = "0.24.13" +remove_console = "0.25.13" preset_env_base = "0.4.12" [dev-dependencies] diff --git a/packages/next/package.json b/packages/next/package.json index 6bcdf71ce10e1..72ee3e8113909 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -206,7 +206,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.27.1", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240610.2", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240611.2", "acorn": "8.11.3", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2b5fe5bd0adc3..3c6c66be26388 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1090,8 +1090,8 @@ importers: specifier: 0.27.1 version: 0.27.1 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240610.2 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240610.2' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240611.2 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240611.2' acorn: specifier: 8.11.3 version: 8.11.3 @@ -25890,8 +25890,8 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240610.2': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240610.2} + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240611.2': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240611.2} name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: From b8be05c1ae71f204e0bebaadbfdae18f35813af1 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:59:43 -0700 Subject: [PATCH 35/60] fix e2e deployment test action (#66721) [Test Run](https://github.com/vercel/next.js/actions/runs/9471783416/job/26095882422) Changes: - Add a setup step that clears the project so it doesn't happen in each runner - Run when a release is published rather than on cron - Notify via Slack when a failure occurs - Leverage build_reusable for the test runner to match the build_and_test workflow - Fixes to `next-deploy` script: not properly logging/catching errors - Adds manifest to ignore known issues - Split into 6 runners with 2 concurrency (12 deploys at a time) - Adds some logging so we know what's happening - Disable Playwright trace mode (it kept failing to find a trace file and cluttering the output. Don't think we need it here anyway)
- Removed noisy output ![CleanShot 2024-06-10 at 14 08 05@2x](https://github.com/vercel/next.js/assets/1939140/f227e71c-95b4-4859-90de-a23c88c55ea8)
--- .github/workflows/build_reusable.yml | 29 ++++-- .github/workflows/test_e2e_deploy_release.yml | 95 +++++++++++++++++++ .../workflows/test_e2e_deploy_scheduled.yml | 87 ----------------- run-tests.js | 36 ++----- test/deploy-tests-manifest.json | 80 ++++++++++++++++ test/get-test-filter.js | 5 + test/lib/next-modes/next-deploy.ts | 5 +- 7 files changed, 213 insertions(+), 124 deletions(-) create mode 100644 .github/workflows/test_e2e_deploy_release.yml delete mode 100644 .github/workflows/test_e2e_deploy_scheduled.yml create mode 100644 test/deploy-tests-manifest.json diff --git a/.github/workflows/build_reusable.yml b/.github/workflows/build_reusable.yml index 6cc1bc92c6c82..34d45a0c6a851 100644 --- a/.github/workflows/build_reusable.yml +++ b/.github/workflows/build_reusable.yml @@ -49,6 +49,16 @@ on: required: true description: 'name of the step, to be used for the upload artifact unique key ' type: string + timeout_minutes: + description: 'Timeout in minutes' + required: false + type: number + default: 30 + runs_on_labels: + description: 'List of runner labels' + required: false + type: string + default: '["self-hosted", "linux", "x64", "metal"]' env: NAPI_CLI_VERSION: 2.14.7 @@ -69,15 +79,13 @@ env: DD_ENV: 'ci' TEST_TIMINGS_TOKEN: ${{ secrets.TEST_TIMINGS_TOKEN }} NEXT_TEST_JOB: 1 + VERCEL_TEST_TOKEN: ${{ secrets.VERCEL_TEST_TOKEN }} + VERCEL_TEST_TEAM: vtest314-next-e2e-tests jobs: build: - timeout-minutes: 30 - runs-on: - - 'self-hosted' - - 'linux' - - 'x64' - - 'metal' + timeout-minutes: ${{ inputs.timeout_minutes }} + runs-on: ${{ fromJson(inputs.runs_on_labels) }} outputs: input_step_key: ${{ steps.var.outputs.input_step_key }} @@ -90,7 +98,12 @@ jobs: script: | core.setOutput('input_step_key', '${{ inputs.stepName }}'.toLowerCase().replaceAll(/[/.]/g, '-').trim('-')); - - run: fnm use --install-if-missing ${{ inputs.nodeVersion || env.NODE_LTS_VERSION }} + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ inputs.nodeVersion || env.NODE_LTS_VERSION }} + check-latest: true + - run: node -v - run: corepack enable - run: pwd @@ -175,7 +188,7 @@ jobs: - run: turbo run get-test-timings -- --build ${{ github.sha }} - run: /bin/bash -c "${{ inputs.afterBuild }}" - timeout-minutes: 30 + timeout-minutes: ${{ inputs.timeout_minutes }} - name: Upload artifact uses: actions/upload-artifact@v4 diff --git a/.github/workflows/test_e2e_deploy_release.yml b/.github/workflows/test_e2e_deploy_release.yml new file mode 100644 index 0000000000000..5ef425c9a3ef4 --- /dev/null +++ b/.github/workflows/test_e2e_deploy_release.yml @@ -0,0 +1,95 @@ +name: Test E2E (Vercel Deploy), scheduled + +on: + # run on every release/prerelease + release: + types: [published] + # allow triggering manually as well + workflow_dispatch: + +env: + VERCEL_TEST_TEAM: vtest314-next-e2e-tests + VERCEL_TEST_TOKEN: ${{ secrets.VERCEL_TEST_TOKEN }} + SLACK_WEBHOOK_URL: ${{ secrets.BROKEN_DEPLOY_SLACK_WEBHOOK_URL }} + DATADOG_API_KEY: ${{ secrets.DATA_DOG_API_KEY }} + DD_ENV: 'ci' + +jobs: + setup: + runs-on: ubuntu-latest + if: github.repository_owner == 'vercel' + steps: + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_LTS_VERSION }} + check-latest: true + + - name: Setup pnpm + run: corepack enable + + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 25 + + - name: Setup test project + run: | + pnpm install + pnpm run build + node scripts/run-e2e-test-project-reset.mjs + + test-deploy: + name: test deploy + needs: setup + uses: ./.github/workflows/build_reusable.yml + secrets: inherit + strategy: + fail-fast: true + matrix: + group: [1/5, 2/5, 3/5, 4/5, 5/5, 6/6] + with: + afterBuild: NEXT_TEST_MODE=deploy NEXT_EXTERNAL_TESTS_FILTERS="test/deploy-tests-manifest.json" node run-tests.js --timings -g ${{ matrix.group }} -c 2 --type e2e + skipNativeBuild: 'yes' + stepName: 'test-deploy-${{ matrix.group }}' + timeout_minutes: 180 + runs_on_labels: '["ubuntu-latest"]' + + report-test-results-to-datadog: + needs: test-deploy + if: ${{ always() }} + + runs-on: ubuntu-latest + name: report test results to datadog + steps: + - name: Download test report artifacts + id: download-test-reports + uses: actions/download-artifact@v4 + with: + pattern: test-reports-* + path: test + merge-multiple: true + + - name: Upload test report to datadog + run: | + if [ -d ./test/test-junit-report ]; then + DD_ENV=ci npx @datadog/datadog-ci@2.23.1 junit upload --tags test.type:deploy --service nextjs ./test/test-junit-report + fi + + report-failure: + name: report failure to slack + needs: test-deploy + if: needs.test-deploy.conclusion == 'failure' + runs-on: ubuntu-latest + steps: + - name: send webhook + uses: slackapi/slack-github-action@v1.25.0 + with: + payload: | + { + "commit_title": ${{ toJSON(github.event.workflow_run.display_title) }}, + "commit_url": "github.com/${{ github.repository }}/commit/${{ github.event.workflow_run.head_sha }}", + "workflow_run_url": "github.com/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}/attempts/${{ github.event.workflow_run.run_attempt }}" + } + env: + SLACK_WEBHOOK_URL: ${{ env.SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/test_e2e_deploy_scheduled.yml b/.github/workflows/test_e2e_deploy_scheduled.yml deleted file mode 100644 index 02729a8c4a7ce..0000000000000 --- a/.github/workflows/test_e2e_deploy_scheduled.yml +++ /dev/null @@ -1,87 +0,0 @@ -name: Test E2E (Vercel Deploy), scheduled - -on: - schedule: - # run every day at midnight - - cron: '0 0 * * *' - # allow triggering manually as well - workflow_dispatch: - -jobs: - test: - if: github.repository_owner == 'vercel' - runs-on: ubuntu-latest - - env: - CARGO_PROFILE_RELEASE_LTO: 'true' - DATADOG_API_KEY: ${{ secrets.DATA_DOG_API_KEY }} - DD_ENV: 'ci' - NAPI_CLI_VERSION: 2.16.2 - NEXT_JUNIT_TEST_REPORT: 'true' - NEXT_TELEMETRY_DISABLED: 1 - NEXT_TEST_CONTINUE_ON_ERROR: 1 - NEXT_TEST_JOB: 1 - NEXT_TEST_MODE: 'deploy' - NODE_LTS_VERSION: 20 - TEST_TIMINGS_TOKEN: ${{ secrets.TEST_TIMINGS_TOKEN }} - TURBO_REMOTE_ONLY: 'true' - TURBO_TEAM: 'vercel' - TURBO_VERSION: 1.13.3-canary.2 - VERCEL_TEST_TEAM: vtest314-next-e2e-tests - VERCEL_TEST_TOKEN: ${{ secrets.VERCEL_TEST_TOKEN }} - - strategy: - fail-fast: false - matrix: - group: [1, 2] - - steps: - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_LTS_VERSION }} - check-latest: true - - - name: Setup pnpm - run: corepack enable - - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 25 - - - name: Setup tests - run: | - pnpm install - pnpm run build - npm i -g vercel@latest - node scripts/run-e2e-test-project-reset.mjs - - - name: Run tests - run: | - docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.41.2-jammy /bin/bash -c "cd /work && \ - NODE_VERSION=${{ env.NODE_LTS_VERSION }} ./scripts/setup-node.sh && \ - corepack enable > /dev/null && \ - NEXT_JUNIT_TEST_REPORT=${{ env.NEXT_JUNIT_TEST_REPORT }} \ - DATADOG_API_KEY=${{ env.DATADOG_API_KEY }} \ - DD_ENV=${{ env.DD_ENV }} \ - VERCEL_TEST_TOKEN=${{ env.VERCEL_TEST_TOKEN }} \ - VERCEL_TEST_TEAM=${{ env.VERCEL_TEST_TEAM }} \ - NEXT_TEST_JOB=${{ env.NEXT_TEST_JOB }} \ - NEXT_TEST_MODE=${{ env.NEXT_TEST_MODE }} \ - TEST_TIMINGS_TOKEN=${{ env.TEST_TIMINGS_TOKEN }} \ - xvfb-run node run-tests.js --type e2e --timings -g ${{ matrix.group }}/2 -c 1 >> /proc/1/fd/1" - - - name: Save test report as artifacts - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-reports - if-no-files-found: ignore - retention-days: 2 - path: test/test-junit-report - - - name: Upload test report to Datadog - continue-on-error: true - run: | - pnpx @datadog/datadog-ci@2.23.1 junit upload --tags test.type:nextjs_deploy_e2e --service nextjs ./test/test-junit-report diff --git a/run-tests.js b/run-tests.js index 98dd35e5de120..412f429ee16bf 100644 --- a/run-tests.js +++ b/run-tests.js @@ -227,7 +227,12 @@ async function main() { } } - console.log('Running tests with concurrency:', options.concurrency) + console.log( + 'Running tests with concurrency:', + options.concurrency, + 'in test mode', + process.env.NEXT_TEST_MODE + ) /** @type TestFile[] */ let tests = argv._.filter((arg) => @@ -470,7 +475,8 @@ ${ENDGROUP}`) RECORD_REPLAY: shouldRecordTestWithReplay, // run tests in headless mode by default HEADLESS: 'true', - TRACE_PLAYWRIGHT: 'true', + TRACE_PLAYWRIGHT: + process.env.NEXT_TEST_MODE === 'deploy' ? undefined : 'true', NEXT_TELEMETRY_DISABLED: '1', // unset CI env so CI behavior is only explicitly // tested when enabled @@ -691,32 +697,6 @@ ${ENDGROUP}`) } } - // Emit test output if test failed or if we're continuing tests on error - if ((!passed || shouldContinueTestsOnError) && isTestJob) { - try { - const testsOutput = await fsp.readFile( - `${test.file}${RESULTS_EXT}`, - 'utf8' - ) - const obj = JSON.parse(testsOutput) - obj.processEnv = { - NEXT_TEST_MODE: process.env.NEXT_TEST_MODE, - HEADLESS: process.env.HEADLESS, - } - await outputSema.acquire() - if (GROUP) console.log(`${GROUP}Result as JSON for tooling`) - console.log( - `--test output start--`, - JSON.stringify(obj), - `--test output end--` - ) - if (ENDGROUP) console.log(ENDGROUP) - outputSema.release() - } catch (err) { - console.log(`Failed to load test output`, err) - } - } - sema.release() if (dirSema) dirSema.release() }) diff --git a/test/deploy-tests-manifest.json b/test/deploy-tests-manifest.json new file mode 100644 index 0000000000000..62e9475d67139 --- /dev/null +++ b/test/deploy-tests-manifest.json @@ -0,0 +1,80 @@ +{ + "version": 2, + "suites": {}, + "rules": { + "include": [ + "test/e2e/**/*.test.{t,j}s{,x}", + "test/production/**/*.test.{t,j}s{,x}" + ], + "exclude": [ + "test/e2e/app-dir/app-client-cache/client-cache.original.test.ts", + "test/e2e/app-dir/app-routes/app-custom-routes.test.ts", + "test/e2e/app-dir/next-after-app/index.test.ts", + "test/e2e/app-dir/scss/nm-module-nested/nm-module-nested.test.ts", + "test/e2e/cancel-request/stream-cancel.test.ts", + "test/e2e/edge-pages-support/edge-document.test.ts", + "test/e2e/new-link-behavior/material-ui.test.ts", + "test/e2e/react-dnd-compile/react-dnd-compile.test.ts", + "test/e2e/next-test/next-test.test.ts", + "test/e2e/skip-trailing-slash-redirect/index.test.ts", + "test/e2e/tsconfig-module-preserve/index.test.ts", + "test/e2e/app-dir/app-compilation/index.test.ts", + "test/e2e/app-dir/parallel-route-not-found-params/parallel-route-not-found-params.test.ts", + "test/e2e/app-dir/ppr-navigations/loading-tsx-no-partial-rendering/loading-tsx-no-partial-rendering.test.ts", + "test/e2e/app-dir/ppr/ppr.test.ts", + "test/e2e/app-dir/rsc-webpack-loader/rsc-webpack-loader.test.ts", + "test/e2e/app-dir/scss/compilation-and-prefixing/compilation-and-prefixing.test.ts", + "test/e2e/app-dir/typeof-window/typeof-window.test.ts", + "test/e2e/app-dir/webpack-loader-conditions/webpack-loader-conditions.test.ts", + "test/e2e/app-dir/x-forwarded-headers/x-forwarded-headers.test.ts", + "test/e2e/edge-compiler-module-exports-preference/index.test.ts", + "test/e2e/swc-warnings/index.test.ts", + "test/e2e/third-parties/index.test.ts", + "test/e2e/useselectedlayoutsegment-s-in-pages-router/useselectedlayoutsegment-s-in-pages-router.test.ts", + "test/e2e/app-dir/app-prefetch-false-loading/app-prefetch-false-loading.test.ts", + "test/e2e/app-dir/app-client-cache/client-cache.experimental.test.ts", + "test/e2e/app-dir/app-routes-client-component/app-routes-client-component.test.ts", + "test/e2e/app-dir/app-routes/app-custom-route-base-path.test.ts", + "test/e2e/app-dir/mdx/mdx.test.ts", + "test/e2e/app-dir/modularizeimports/modularizeimports.test.ts", + "test/e2e/app-dir/navigation/navigation.test.ts", + "test/e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts", + "test/e2e/app-dir/ppr-navigations/avoid-popstate-flash/avoid-popstate-flash.test.ts", + "test/e2e/app-dir/server-components-externals/index.test.ts", + "test/e2e/app-dir/third-parties/basic.test.ts", + "test/e2e/edge-can-read-request-body/index.test.ts", + "test/e2e/esm-externals/esm-externals.test.ts", + "test/e2e/i18n-data-route/i18n-data-route.test.ts", + "test/e2e/next-phase/index.test.ts", + "test/e2e/app-dir/actions-navigation/index.test.ts", + "test/e2e/app-dir/app-static/app-static-custom-handler.test.ts", + "test/e2e/app-dir/conflicting-page-segments/conflicting-page-segments.test.ts", + "test/e2e/app-dir/interception-route-prefetch-cache/interception-route-prefetch-cache.test.ts", + "test/e2e/app-dir/missing-suspense-with-csr-bailout/missing-suspense-with-csr-bailout.test.ts", + "test/e2e/app-dir/options-request/options-request.test.ts", + "test/e2e/app-dir/next-image/next-image-proxy.test.ts", + "test/e2e/app-dir/ppr-navigations/stale-prefetch-entry/stale-prefetch-entry.test.ts", + "test/e2e/app-dir/parallel-routes-revalidation/parallel-routes-revalidation.test.ts", + "test/e2e/app-dir/revalidate-dynamic/revalidate-dynamic.test.ts", + "test/e2e/app-dir/scss/npm-import-nested/npm-import-nested.test.ts", + "test/e2e/app-dir/syntax-highlighter-crash/syntax-highlighter-crash.test.ts", + "test/e2e/favicon-short-circuit/favicon-short-circuit.test.ts", + "test/e2e/new-link-behavior/stitches.test.ts", + "test/e2e/next-image-forward-ref/index.test.ts", + "test/e2e/react-compiler/react-compiler.test.ts", + "test/e2e/revalidate-reason/revalidate-reason.test.ts", + "test/e2e/app-dir/app-static/app-static.test.ts", + "test/e2e/app-dir/actions/app-action.test.ts", + "test/e2e/app-dir/i18n-hybrid/i18n-hybrid.test.js", + "test/e2e/app-dir/metadata/metadata.test.ts", + "test/e2e/app-dir/rsc-basic/rsc-basic.test.ts", + "test/e2e/app-dir/scss/nm-module/nm-module.test.ts", + "test/e2e/app-dir/static-shell-debugging/static-shell-debugging.test.ts", + "test/e2e/basepath.test.ts", + "test/e2e/postcss-config-cjs/index.test.ts", + "test/e2e/socket-io/index.test.js", + "test/e2e/middleware-matcher/index.test.ts", + "test/e2e/next-script/index.test.ts" + ] + } +} diff --git a/test/get-test-filter.js b/test/get-test-filter.js index 76840e2e6dcc8..bf6cc218524b1 100644 --- a/test/get-test-filter.js +++ b/test/get-test-filter.js @@ -7,6 +7,11 @@ function getTestFilter() { : null if (!manifest) return null + console.log( + 'Filtering tests using manifest:', + process.env.NEXT_EXTERNAL_TESTS_FILTERS + ) + // For the legacy manifest without a version, we assume it's a complete list // of all the tests. if (!manifest.version || typeof manifest.version !== 'number') { diff --git a/test/lib/next-modes/next-deploy.ts b/test/lib/next-modes/next-deploy.ts index 78ecf836739b5..007a2ea94cd55 100644 --- a/test/lib/next-modes/next-deploy.ts +++ b/test/lib/next-modes/next-deploy.ts @@ -76,6 +76,7 @@ export class NextDeployInstance extends NextInstance { { cwd: this.testDir, env: vercelEnv, + reject: false, } ) @@ -117,12 +118,13 @@ export class NextDeployInstance extends NextInstance { { cwd: this.testDir, env: vercelEnv, + reject: false, } ) if (deployRes.exitCode !== 0) { throw new Error( - `Failed to deploy project ${linkRes.stdout} ${linkRes.stderr} (${linkRes.exitCode})` + `Failed to deploy project ${deployRes.stdout} ${deployRes.stderr} (${deployRes.exitCode})` ) } // the CLI gives just the deployment URL back when not a TTY @@ -151,6 +153,7 @@ export class NextDeployInstance extends NextInstance { ['logs', this._url, '--output', 'raw', ...vercelFlags], { env: vercelEnv, + reject: false, } ) if (logs.exitCode !== 0) { From a00555ae3a93a4822629bf645a34ef4026b45612 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Tue, 11 Jun 2024 14:39:18 -0700 Subject: [PATCH 36/60] tweak deploy failure notification condition (#66769) Make sure this doesn't get skipped [x-ref ](https://github.com/vercel/next.js/actions/runs/9472800340/job/26098835283) --- .github/workflows/test_e2e_deploy_release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test_e2e_deploy_release.yml b/.github/workflows/test_e2e_deploy_release.yml index 5ef425c9a3ef4..3afb6cb71e5bb 100644 --- a/.github/workflows/test_e2e_deploy_release.yml +++ b/.github/workflows/test_e2e_deploy_release.yml @@ -47,7 +47,7 @@ jobs: strategy: fail-fast: true matrix: - group: [1/5, 2/5, 3/5, 4/5, 5/5, 6/6] + group: [1/6, 2/6, 3/6, 4/6, 5/6, 6/6] with: afterBuild: NEXT_TEST_MODE=deploy NEXT_EXTERNAL_TESTS_FILTERS="test/deploy-tests-manifest.json" node run-tests.js --timings -g ${{ matrix.group }} -c 2 --type e2e skipNativeBuild: 'yes' @@ -79,7 +79,7 @@ jobs: report-failure: name: report failure to slack needs: test-deploy - if: needs.test-deploy.conclusion == 'failure' + if: ${{ always() && contains(needs.*.result, 'failure') }} runs-on: ubuntu-latest steps: - name: send webhook From 0c49daad3c8eaa1140c2225c915afb7c39cfa2fc Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Tue, 11 Jun 2024 15:17:44 -0700 Subject: [PATCH 37/60] fix client-cache deploy tests (#66770) - Telemetry debugging isn't available when deployed - The loading test had a race bug Verified all of these passed when deployed locally. --- test/deploy-tests-manifest.json | 2 - .../client-cache.defaults.test.ts | 18 ++--- .../client-cache.experimental.test.ts | 68 ++++++++++--------- .../client-cache.original.test.ts | 18 ++--- 4 files changed, 56 insertions(+), 50 deletions(-) diff --git a/test/deploy-tests-manifest.json b/test/deploy-tests-manifest.json index 62e9475d67139..1d1a13ee8c4b4 100644 --- a/test/deploy-tests-manifest.json +++ b/test/deploy-tests-manifest.json @@ -7,7 +7,6 @@ "test/production/**/*.test.{t,j}s{,x}" ], "exclude": [ - "test/e2e/app-dir/app-client-cache/client-cache.original.test.ts", "test/e2e/app-dir/app-routes/app-custom-routes.test.ts", "test/e2e/app-dir/next-after-app/index.test.ts", "test/e2e/app-dir/scss/nm-module-nested/nm-module-nested.test.ts", @@ -32,7 +31,6 @@ "test/e2e/third-parties/index.test.ts", "test/e2e/useselectedlayoutsegment-s-in-pages-router/useselectedlayoutsegment-s-in-pages-router.test.ts", "test/e2e/app-dir/app-prefetch-false-loading/app-prefetch-false-loading.test.ts", - "test/e2e/app-dir/app-client-cache/client-cache.experimental.test.ts", "test/e2e/app-dir/app-routes-client-component/app-routes-client-component.test.ts", "test/e2e/app-dir/app-routes/app-custom-route-base-path.test.ts", "test/e2e/app-dir/mdx/mdx.test.ts", diff --git a/test/e2e/app-dir/app-client-cache/client-cache.defaults.test.ts b/test/e2e/app-dir/app-client-cache/client-cache.defaults.test.ts index 8801cc50b63ab..459e5c87d7ec1 100644 --- a/test/e2e/app-dir/app-client-cache/client-cache.defaults.test.ts +++ b/test/e2e/app-dir/app-client-cache/client-cache.defaults.test.ts @@ -1,5 +1,5 @@ import { nextTestSetup } from 'e2e-utils' -import { check } from 'next-test-utils' +import { check, retry } from 'next-test-utils' import { BrowserInterface } from 'next-webdriver' import { browserConfigWithFixedTime, @@ -316,18 +316,20 @@ describe('app dir client cache semantics (default semantics)', () => { await browser.elementByCss('[href="/null-loading"]').click() // the page content should disappear immediately - expect( - await browser.hasElementByCssSelector('[href="/null-loading"]') - ).toBeFalse() + await retry(async () => { + expect( + await browser.hasElementByCssSelector('[href="/null-loading"]') + ).toBe(false) + }) // the root layout should still be visible - expect(await browser.hasElementByCssSelector('#root-layout')).toBeTrue() + expect(await browser.hasElementByCssSelector('#root-layout')).toBe(true) // the dynamic content should eventually appear await browser.waitForElementByCss('#random-number') - expect( - await browser.hasElementByCssSelector('#random-number') - ).toBeTrue() + expect(await browser.hasElementByCssSelector('#random-number')).toBe( + true + ) }) }) diff --git a/test/e2e/app-dir/app-client-cache/client-cache.experimental.test.ts b/test/e2e/app-dir/app-client-cache/client-cache.experimental.test.ts index b865df7202ec6..19fc74ba094b6 100644 --- a/test/e2e/app-dir/app-client-cache/client-cache.experimental.test.ts +++ b/test/e2e/app-dir/app-client-cache/client-cache.experimental.test.ts @@ -5,7 +5,7 @@ import path from 'path' describe('app dir client cache semantics (experimental staleTimes)', () => { describe('dynamic: 0', () => { - const { next, isNextDev } = nextTestSetup({ + const { next, isNextDev, isNextDeploy } = nextTestSetup({ files: path.join(__dirname, 'fixtures', 'regular'), nextConfig: { experimental: { staleTimes: { dynamic: 0 } }, @@ -222,27 +222,29 @@ describe('app dir client cache semantics (experimental staleTimes)', () => { }) }) - describe('telemetry', () => { - it('should send staleTimes feature usage event', async () => { - const events = findAllTelemetryEvents( - next.cliOutput, - 'NEXT_CLI_SESSION_STARTED' - ) + if (!isNextDeploy) { + describe('telemetry', () => { + it('should send staleTimes feature usage event', async () => { + const events = findAllTelemetryEvents( + next.cliOutput, + 'NEXT_CLI_SESSION_STARTED' + ) - expect(events).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - staticStaleTime: null, - dynamicStaleTime: 0, - }), - ]) - ) + expect(events).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + staticStaleTime: null, + dynamicStaleTime: 0, + }), + ]) + ) + }) }) - }) + } }) describe('static: 180', () => { - const { next, isNextDev } = nextTestSetup({ + const { next, isNextDev, isNextDeploy } = nextTestSetup({ files: path.join(__dirname, 'fixtures', 'regular'), nextConfig: { experimental: { staleTimes: { static: 180 } }, @@ -341,22 +343,24 @@ describe('app dir client cache semantics (experimental staleTimes)', () => { }) }) - describe('telemetry', () => { - it('should send staleTimes feature usage event', async () => { - const events = findAllTelemetryEvents( - next.cliOutput, - 'NEXT_CLI_SESSION_STARTED' - ) - expect(events).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - staticStaleTime: 180, - dynamicStaleTime: null, - }), - ]) - ) + if (!isNextDeploy) { + describe('telemetry', () => { + it('should send staleTimes feature usage event', async () => { + const events = findAllTelemetryEvents( + next.cliOutput, + 'NEXT_CLI_SESSION_STARTED' + ) + expect(events).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + staticStaleTime: 180, + dynamicStaleTime: null, + }), + ]) + ) + }) }) - }) + } }) describe('dynamic: 0, static: 0', () => { diff --git a/test/e2e/app-dir/app-client-cache/client-cache.original.test.ts b/test/e2e/app-dir/app-client-cache/client-cache.original.test.ts index 8740e0fa75918..d8fd2ab6c5b26 100644 --- a/test/e2e/app-dir/app-client-cache/client-cache.original.test.ts +++ b/test/e2e/app-dir/app-client-cache/client-cache.original.test.ts @@ -1,5 +1,5 @@ import { nextTestSetup } from 'e2e-utils' -import { check } from 'next-test-utils' +import { check, retry } from 'next-test-utils' import { BrowserInterface } from 'next-webdriver' import { browserConfigWithFixedTime, @@ -421,18 +421,20 @@ describe('app dir client cache semantics (30s/5min)', () => { await browser.elementByCss('[href="/null-loading"]').click() // the page content should disappear immediately - expect( - await browser.hasElementByCssSelector('[href="/null-loading"]') - ).toBeFalse() + await retry(async () => { + expect( + await browser.hasElementByCssSelector('[href="/null-loading"]') + ).toBe(false) + }) // the root layout should still be visible - expect(await browser.hasElementByCssSelector('#root-layout')).toBeTrue() + expect(await browser.hasElementByCssSelector('#root-layout')).toBe(true) // the dynamic content should eventually appear await browser.waitForElementByCss('#random-number') - expect( - await browser.hasElementByCssSelector('#random-number') - ).toBeTrue() + expect(await browser.hasElementByCssSelector('#random-number')).toBe( + true + ) }) }) From 561dcf6c43e2626bb504236c5e9af142601c6588 Mon Sep 17 00:00:00 2001 From: Sam Ko Date: Tue, 11 Jun 2024 15:28:01 -0700 Subject: [PATCH 38/60] chore: bump turbo to 2.0.3 (#66762) ## Why? This pull request bumps turborepo from 1.13.3-canary.2 to [2.0.3](https://github.com/vercel/turbo/releases/tag/v2.0.3) across multiple GitHub workflows and configuration files. --- .github/workflows/build_and_deploy.yml | 2 +- .github/workflows/build_and_test.yml | 2 +- .github/workflows/build_reusable.yml | 2 +- .github/workflows/code_freeze.yml | 2 +- .github/workflows/pull_request_stats.yml | 2 +- .github/workflows/trigger_release.yml | 2 +- package.json | 2 +- packages/create-next-app/package.json | 6 ++-- packages/next-swc/turbo.json | 2 +- packages/next/package.json | 6 ++-- pnpm-lock.yaml | 46 ++++++++++++------------ scripts/normalize-version-bump.js | 1 + turbo.json | 3 +- 13 files changed, 41 insertions(+), 37 deletions(-) diff --git a/.github/workflows/build_and_deploy.yml b/.github/workflows/build_and_deploy.yml index d3781cf285419..887edf7030212 100644 --- a/.github/workflows/build_and_deploy.yml +++ b/.github/workflows/build_and_deploy.yml @@ -7,7 +7,7 @@ on: env: NAPI_CLI_VERSION: 2.16.2 - TURBO_VERSION: 1.13.3-canary.2 + TURBO_VERSION: 2.0.3 NODE_LTS_VERSION: 20 CARGO_PROFILE_RELEASE_LTO: 'true' TURBO_TEAM: 'vercel' diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 4a306d1773f45..45c44ba508571 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -8,7 +8,7 @@ on: env: NAPI_CLI_VERSION: 2.14.7 - TURBO_VERSION: 1.13.3-canary.2 + TURBO_VERSION: 2.0.3 NODE_MAINTENANCE_VERSION: 18 NODE_LTS_VERSION: 20 TEST_CONCURRENCY: 8 diff --git a/.github/workflows/build_reusable.yml b/.github/workflows/build_reusable.yml index 34d45a0c6a851..3610bcba5054b 100644 --- a/.github/workflows/build_reusable.yml +++ b/.github/workflows/build_reusable.yml @@ -62,7 +62,7 @@ on: env: NAPI_CLI_VERSION: 2.14.7 - TURBO_VERSION: 1.13.3-canary.2 + TURBO_VERSION: 2.0.3 NODE_LTS_VERSION: 20.9.0 TEST_CONCURRENCY: 8 # disable backtrace for test snapshots diff --git a/.github/workflows/code_freeze.yml b/.github/workflows/code_freeze.yml index 5d005b1086350..8517359ac6100 100644 --- a/.github/workflows/code_freeze.yml +++ b/.github/workflows/code_freeze.yml @@ -17,7 +17,7 @@ name: Code Freeze env: NAPI_CLI_VERSION: 2.14.7 - TURBO_VERSION: 1.13.3-canary.2 + TURBO_VERSION: 2.0.3 NODE_LTS_VERSION: 20 jobs: diff --git a/.github/workflows/pull_request_stats.yml b/.github/workflows/pull_request_stats.yml index 64a4a3b65a992..d970f7a6a9490 100644 --- a/.github/workflows/pull_request_stats.yml +++ b/.github/workflows/pull_request_stats.yml @@ -6,7 +6,7 @@ name: Generate Pull Request Stats env: NAPI_CLI_VERSION: 2.14.7 - TURBO_VERSION: 1.13.3-canary.2 + TURBO_VERSION: 2.0.3 NODE_LTS_VERSION: 20 TEST_CONCURRENCY: 6 diff --git a/.github/workflows/trigger_release.yml b/.github/workflows/trigger_release.yml index d961f14795226..6fbd15189a539 100644 --- a/.github/workflows/trigger_release.yml +++ b/.github/workflows/trigger_release.yml @@ -35,7 +35,7 @@ name: Trigger Release env: NAPI_CLI_VERSION: 2.14.7 - TURBO_VERSION: 1.13.3-canary.2 + TURBO_VERSION: 2.0.3 NODE_LTS_VERSION: 20 jobs: diff --git a/package.json b/package.json index 07c9d84f46acd..6ce8823941c29 100644 --- a/package.json +++ b/package.json @@ -232,7 +232,7 @@ "taskr": "1.1.0", "tree-kill": "1.2.2", "tsec": "0.2.1", - "turbo": "1.13.3-canary.2", + "turbo": "2.0.3", "typescript": "5.3.3", "unfetch": "4.2.0", "wait-port": "0.2.2", diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index acc47eb880e53..c5cab4fad02e6 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -51,6 +51,8 @@ "validate-npm-package-name": "5.0.1" }, "engines": { - "node": ">=18.17.0" - } + "node": ">=18.17.0", + "pnpm": "8.15.7" + }, + "packageManager": "pnpm@8.15.7" } diff --git a/packages/next-swc/turbo.json b/packages/next-swc/turbo.json index f811943d1a917..b30afd28e2694 100644 --- a/packages/next-swc/turbo.json +++ b/packages/next-swc/turbo.json @@ -1,6 +1,6 @@ { "extends": ["//"], - "pipeline": { + "tasks": { "build-native": { "inputs": [ "../../.cargo/**", diff --git a/packages/next/package.json b/packages/next/package.json index 72ee3e8113909..1127084783b86 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -344,6 +344,8 @@ "vercel" ], "engines": { - "node": ">=18.17.0" - } + "node": ">=18.17.0", + "pnpm": "8.15.7" + }, + "packageManager": "pnpm@8.15.7" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3c6c66be26388..f4c3c352ce30a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -546,8 +546,8 @@ importers: specifier: 0.2.1 version: 0.2.1(@bazel/bazelisk@1.18.0)(typescript@5.3.3) turbo: - specifier: 1.13.3-canary.2 - version: 1.13.3-canary.2 + specifier: 2.0.3 + version: 2.0.3 typescript: specifier: 5.3.3 version: 5.3.3 @@ -14347,7 +14347,7 @@ packages: engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 - debug: 4.1.1 + debug: 4.3.4 transitivePeerDependencies: - supports-color @@ -24347,64 +24347,64 @@ packages: engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} dev: true - /turbo-darwin-64@1.13.3-canary.2: - resolution: {integrity: sha512-M8QDR6SKPSLEjSLWnIM//caHWBhcZNkIPdnnMkHm8R9/fpFSI5X//GBdR0qnXcgdqOdFgnxheabwYm5Bm+1KWQ==} + /turbo-darwin-64@2.0.3: + resolution: {integrity: sha512-v7ztJ8sxdHw3SLfO2MhGFeeU4LQhFii1hIGs9uBiXns/0YTGOvxLeifnfGqhfSrAIIhrCoByXO7nR9wlm10n3Q==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.13.3-canary.2: - resolution: {integrity: sha512-4RpdYK+XF9Lx7/nmUzbn978t4HBCmmemAazOjmhyd0pOMn8rLVexPkByDEV84SrgofkCWdTHDwcHaOQvOLrKtw==} + /turbo-darwin-arm64@2.0.3: + resolution: {integrity: sha512-LUcqvkV9Bxtng6QHbevp8IK8zzwbIxM6HMjCE7FEW6yJBN1KwvTtRtsGBwwmTxaaLO0wD1Jgl3vgkXAmQ4fqUw==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.13.3-canary.2: - resolution: {integrity: sha512-8gzyPtOmzACNwtWi5//ZHwcJb2i21pZVXQEiNwTycypyBtV2H0WChmqjulS7M3z5dxwHcx0Ehf9TqY4K023j2A==} + /turbo-linux-64@2.0.3: + resolution: {integrity: sha512-xpdY1suXoEbsQsu0kPep2zrB8ijv/S5aKKrntGuQ62hCiwDFoDcA/Z7FZ8IHQ2u+dpJARa7yfiByHmizFE0r5Q==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.13.3-canary.2: - resolution: {integrity: sha512-QzRIyO+HUMc5+hj5cVBCKpCyOiBPxzAao4zWZgz6iKMuSC6utjHLf/9AAo6NOMFgBONTYsMUArL5gDyLLOO0lw==} + /turbo-linux-arm64@2.0.3: + resolution: {integrity: sha512-MBACTcSR874L1FtLL7gkgbI4yYJWBUCqeBN/iE29D+8EFe0d3fAyviFlbQP4K/HaDYet1i26xkkOiWr0z7/V9A==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.13.3-canary.2: - resolution: {integrity: sha512-s4k+yclLr/MWuwYURPZX2v6y1PP7E2aUUao6syQ68Un+36RYBgINN/VV4HucZuiXyqLuBuaDjfrnE1TX3FREOg==} + /turbo-windows-64@2.0.3: + resolution: {integrity: sha512-zi3YuKPkM9JxMTshZo3excPk37hUrj5WfnCqh4FjI26ux6j/LJK+Dh3SebMHd9mR7wP9CMam4GhmLCT+gDfM+w==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.13.3-canary.2: - resolution: {integrity: sha512-p5qGGeb3z1Gaxq43lTFm/PyTh7xtuDCfesxGWZWESG6MyXZuZYzuEH2cSmM8jqta6EC+G+iF5sxeKUzIpsJWeQ==} + /turbo-windows-arm64@2.0.3: + resolution: {integrity: sha512-wmed4kkenLvRbidi7gISB4PU77ujBuZfgVGDZ4DXTFslE/kYpINulwzkVwJIvNXsJtHqyOq0n6jL8Zwl3BrwDg==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.13.3-canary.2: - resolution: {integrity: sha512-GqkwRxoigbjvj/m1JfY7kGDupNeuADW7Hg1+rO+KqNMEUihOfq8a1kjCbwlqOfyS8PPfMHDkDPXrfhA8A1N9vg==} + /turbo@2.0.3: + resolution: {integrity: sha512-jF1K0tTUyryEWmgqk1V0ALbSz3VdeZ8FXUo6B64WsPksCMCE48N5jUezGOH2MN0+epdaRMH8/WcPU0QQaVfeLA==} hasBin: true optionalDependencies: - turbo-darwin-64: 1.13.3-canary.2 - turbo-darwin-arm64: 1.13.3-canary.2 - turbo-linux-64: 1.13.3-canary.2 - turbo-linux-arm64: 1.13.3-canary.2 - turbo-windows-64: 1.13.3-canary.2 - turbo-windows-arm64: 1.13.3-canary.2 + turbo-darwin-64: 2.0.3 + turbo-darwin-arm64: 2.0.3 + turbo-linux-64: 2.0.3 + turbo-linux-arm64: 2.0.3 + turbo-windows-64: 2.0.3 + turbo-windows-arm64: 2.0.3 dev: true /tweetnacl@0.14.5: diff --git a/scripts/normalize-version-bump.js b/scripts/normalize-version-bump.js index e13eb4b8928fb..25bcd42519483 100755 --- a/scripts/normalize-version-bump.js +++ b/scripts/normalize-version-bump.js @@ -72,5 +72,6 @@ const writeJson = async (filePath, data) => private: true, workspaces: ['packages/*'], scripts: {}, + packageManager: 'pnpm@8.15.7', }) })() diff --git a/turbo.json b/turbo.json index 3ee8c97f8f7bc..0cb4370968adb 100644 --- a/turbo.json +++ b/turbo.json @@ -1,7 +1,6 @@ { "$schema": "https://turborepo.org/schema.json", - "experimentalUI": true, - "pipeline": { + "tasks": { "build": { "dependsOn": ["^build"], "outputs": ["dist/**"] From e167e7fb64b010e0e5c6b0aec7019e94cef45ac5 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Tue, 11 Jun 2024 15:41:37 -0700 Subject: [PATCH 39/60] fix app-custom-routes deploy test (#66773) - `next.cliOutput` will only refer to build time logs, so this particular assertion won't work - Drive-by refactor for it to use `retry` instead of `check` Verified this passes when deployed --- test/deploy-tests-manifest.json | 1 - .../app-routes/app-custom-routes.test.ts | 25 ++++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/test/deploy-tests-manifest.json b/test/deploy-tests-manifest.json index 1d1a13ee8c4b4..132772f6c2d10 100644 --- a/test/deploy-tests-manifest.json +++ b/test/deploy-tests-manifest.json @@ -7,7 +7,6 @@ "test/production/**/*.test.{t,j}s{,x}" ], "exclude": [ - "test/e2e/app-dir/app-routes/app-custom-routes.test.ts", "test/e2e/app-dir/next-after-app/index.test.ts", "test/e2e/app-dir/scss/nm-module-nested/nm-module-nested.test.ts", "test/e2e/cancel-request/stream-cancel.test.ts", diff --git a/test/e2e/app-dir/app-routes/app-custom-routes.test.ts b/test/e2e/app-dir/app-routes/app-custom-routes.test.ts index 2fd595c6f7a59..1859ffbd9b26a 100644 --- a/test/e2e/app-dir/app-routes/app-custom-routes.test.ts +++ b/test/e2e/app-dir/app-routes/app-custom-routes.test.ts @@ -1,5 +1,5 @@ import { nextTestSetup } from 'e2e-utils' -import { check, waitFor } from 'next-test-utils' +import { check, waitFor, retry } from 'next-test-utils' import { Readable } from 'stream' import { @@ -679,18 +679,19 @@ describe('app-custom-routes', () => { }) } - describe('no response returned', () => { - it('should print an error when no response is returned', async () => { - await next.fetch(basePath + '/no-response', { method: 'POST' }) - - await check(() => { - expect(next.cliOutput).toMatch( - /No response is returned from route handler '.+\/route\.ts'\. Ensure you return a `Response` or a `NextResponse` in all branches of your handler\./ - ) - return 'yes' - }, 'yes') + // This test is skipped in deploy mode because `next.cliOutput` will only contain build-time logs. + if (!isNextDeploy) { + describe('no response returned', () => { + it('should print an error when no response is returned', async () => { + await next.fetch(basePath + '/no-response', { method: 'POST' }) + await retry(() => { + expect(next.cliOutput).toMatch( + /No response is returned from route handler '.+\/route\.ts'\. Ensure you return a `Response` or a `NextResponse` in all branches of your handler\./ + ) + }) + }) }) - }) + } describe('no bundle error', () => { it('should not print bundling warning about React', async () => { From 03b5267bdbbd52ec8ea71c18fc644f47e6c779a9 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Tue, 11 Jun 2024 23:22:38 +0000 Subject: [PATCH 40/60] v15.0.0-canary.26 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 12 ++++++------ packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 14 +++++++------- 17 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lerna.json b/lerna.json index c3bdab6d1098d..9be8a6d6bc2e5 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "15.0.0-canary.25" + "version": "15.0.0-canary.26" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index c5cab4fad02e6..991264f1f89b0 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "15.0.0-canary.25", + "version": "15.0.0-canary.26", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index af8a52fad51a2..dd7c26aea11fa 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "15.0.0-canary.25", + "version": "15.0.0-canary.26", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "15.0.0-canary.25", + "@next/eslint-plugin-next": "15.0.0-canary.26", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 1655ba6ad37eb..3ada8d6c86d31 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "15.0.0-canary.25", + "version": "15.0.0-canary.26", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 21816345b5c39..9869f280a7e9e 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "15.0.0-canary.25", + "version": "15.0.0-canary.26", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 75806b74ac495..4903cb4071820 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "15.0.0-canary.25", + "version": "15.0.0-canary.26", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 2587dbe02118a..a18d444be8478 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "15.0.0-canary.25", + "version": "15.0.0-canary.26", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 47211a3f5667b..89d1a82701d96 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "15.0.0-canary.25", + "version": "15.0.0-canary.26", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index c8b38de241f7c..dd082628cbe5b 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "15.0.0-canary.25", + "version": "15.0.0-canary.26", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 5ff3cf7f0fd7f..70567711dd69c 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "15.0.0-canary.25", + "version": "15.0.0-canary.26", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 8a5c49bba3472..bcdbd97b3d972 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "15.0.0-canary.25", + "version": "15.0.0-canary.26", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 5ba0187a703c4..6ed136f68a2f4 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "15.0.0-canary.25", + "version": "15.0.0-canary.26", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 78cd19bdeb97c..d031b6b261bcb 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "15.0.0-canary.25", + "version": "15.0.0-canary.26", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 1127084783b86..4cab54159d776 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "15.0.0-canary.25", + "version": "15.0.0-canary.26", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -93,7 +93,7 @@ ] }, "dependencies": { - "@next/env": "15.0.0-canary.25", + "@next/env": "15.0.0-canary.26", "@swc/helpers": "0.5.11", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -157,10 +157,10 @@ "@jest/types": "29.5.0", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/polyfill-module": "15.0.0-canary.25", - "@next/polyfill-nomodule": "15.0.0-canary.25", - "@next/react-refresh-utils": "15.0.0-canary.25", - "@next/swc": "15.0.0-canary.25", + "@next/polyfill-module": "15.0.0-canary.26", + "@next/polyfill-nomodule": "15.0.0-canary.26", + "@next/react-refresh-utils": "15.0.0-canary.26", + "@next/swc": "15.0.0-canary.26", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.41.2", "@swc/core": "1.5.7", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index f0ad59412e96d..8217ba0fada9d 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "15.0.0-canary.25", + "version": "15.0.0-canary.26", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 8ccf3857b714e..9352c81407cf2 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "15.0.0-canary.25", + "version": "15.0.0-canary.26", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -26,7 +26,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "15.0.0-canary.25", + "next": "15.0.0-canary.26", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f4c3c352ce30a..1ab4c0fc1b84c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -753,7 +753,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 15.0.0-canary.25 + specifier: 15.0.0-canary.26 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -815,7 +815,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 15.0.0-canary.25 + specifier: 15.0.0-canary.26 version: link:../next-env '@swc/helpers': specifier: 0.5.11 @@ -943,16 +943,16 @@ importers: specifier: 1.2.0 version: 1.2.0 '@next/polyfill-module': - specifier: 15.0.0-canary.25 + specifier: 15.0.0-canary.26 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 15.0.0-canary.25 + specifier: 15.0.0-canary.26 version: link:../next-polyfill-nomodule '@next/react-refresh-utils': - specifier: 15.0.0-canary.25 + specifier: 15.0.0-canary.26 version: link:../react-refresh-utils '@next/swc': - specifier: 15.0.0-canary.25 + specifier: 15.0.0-canary.26 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1576,7 +1576,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 15.0.0-canary.25 + specifier: 15.0.0-canary.26 version: link:../next outdent: specifier: 0.8.0 From d22da49b499a88ae2953ac1178feff4b5c273d34 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Tue, 11 Jun 2024 18:17:06 -0700 Subject: [PATCH 41/60] Revert "chore: bump turbo to 2.0.3" (#66775) Seems the latest turbo version is causing issues with our rust compilation so reverting for now Reverts vercel/next.js#66762 --- .github/workflows/build_and_deploy.yml | 2 +- .github/workflows/build_and_test.yml | 2 +- .github/workflows/build_reusable.yml | 2 +- .github/workflows/code_freeze.yml | 2 +- .github/workflows/pull_request_stats.yml | 2 +- .github/workflows/trigger_release.yml | 2 +- package.json | 2 +- packages/create-next-app/package.json | 6 ++-- packages/next-swc/turbo.json | 2 +- packages/next/package.json | 6 ++-- pnpm-lock.yaml | 46 ++++++++++++------------ scripts/normalize-version-bump.js | 1 - turbo.json | 3 +- 13 files changed, 37 insertions(+), 41 deletions(-) diff --git a/.github/workflows/build_and_deploy.yml b/.github/workflows/build_and_deploy.yml index 887edf7030212..d3781cf285419 100644 --- a/.github/workflows/build_and_deploy.yml +++ b/.github/workflows/build_and_deploy.yml @@ -7,7 +7,7 @@ on: env: NAPI_CLI_VERSION: 2.16.2 - TURBO_VERSION: 2.0.3 + TURBO_VERSION: 1.13.3-canary.2 NODE_LTS_VERSION: 20 CARGO_PROFILE_RELEASE_LTO: 'true' TURBO_TEAM: 'vercel' diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 45c44ba508571..4a306d1773f45 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -8,7 +8,7 @@ on: env: NAPI_CLI_VERSION: 2.14.7 - TURBO_VERSION: 2.0.3 + TURBO_VERSION: 1.13.3-canary.2 NODE_MAINTENANCE_VERSION: 18 NODE_LTS_VERSION: 20 TEST_CONCURRENCY: 8 diff --git a/.github/workflows/build_reusable.yml b/.github/workflows/build_reusable.yml index 3610bcba5054b..34d45a0c6a851 100644 --- a/.github/workflows/build_reusable.yml +++ b/.github/workflows/build_reusable.yml @@ -62,7 +62,7 @@ on: env: NAPI_CLI_VERSION: 2.14.7 - TURBO_VERSION: 2.0.3 + TURBO_VERSION: 1.13.3-canary.2 NODE_LTS_VERSION: 20.9.0 TEST_CONCURRENCY: 8 # disable backtrace for test snapshots diff --git a/.github/workflows/code_freeze.yml b/.github/workflows/code_freeze.yml index 8517359ac6100..5d005b1086350 100644 --- a/.github/workflows/code_freeze.yml +++ b/.github/workflows/code_freeze.yml @@ -17,7 +17,7 @@ name: Code Freeze env: NAPI_CLI_VERSION: 2.14.7 - TURBO_VERSION: 2.0.3 + TURBO_VERSION: 1.13.3-canary.2 NODE_LTS_VERSION: 20 jobs: diff --git a/.github/workflows/pull_request_stats.yml b/.github/workflows/pull_request_stats.yml index d970f7a6a9490..64a4a3b65a992 100644 --- a/.github/workflows/pull_request_stats.yml +++ b/.github/workflows/pull_request_stats.yml @@ -6,7 +6,7 @@ name: Generate Pull Request Stats env: NAPI_CLI_VERSION: 2.14.7 - TURBO_VERSION: 2.0.3 + TURBO_VERSION: 1.13.3-canary.2 NODE_LTS_VERSION: 20 TEST_CONCURRENCY: 6 diff --git a/.github/workflows/trigger_release.yml b/.github/workflows/trigger_release.yml index 6fbd15189a539..d961f14795226 100644 --- a/.github/workflows/trigger_release.yml +++ b/.github/workflows/trigger_release.yml @@ -35,7 +35,7 @@ name: Trigger Release env: NAPI_CLI_VERSION: 2.14.7 - TURBO_VERSION: 2.0.3 + TURBO_VERSION: 1.13.3-canary.2 NODE_LTS_VERSION: 20 jobs: diff --git a/package.json b/package.json index 6ce8823941c29..07c9d84f46acd 100644 --- a/package.json +++ b/package.json @@ -232,7 +232,7 @@ "taskr": "1.1.0", "tree-kill": "1.2.2", "tsec": "0.2.1", - "turbo": "2.0.3", + "turbo": "1.13.3-canary.2", "typescript": "5.3.3", "unfetch": "4.2.0", "wait-port": "0.2.2", diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 991264f1f89b0..ea4210b634910 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -51,8 +51,6 @@ "validate-npm-package-name": "5.0.1" }, "engines": { - "node": ">=18.17.0", - "pnpm": "8.15.7" - }, - "packageManager": "pnpm@8.15.7" + "node": ">=18.17.0" + } } diff --git a/packages/next-swc/turbo.json b/packages/next-swc/turbo.json index b30afd28e2694..f811943d1a917 100644 --- a/packages/next-swc/turbo.json +++ b/packages/next-swc/turbo.json @@ -1,6 +1,6 @@ { "extends": ["//"], - "tasks": { + "pipeline": { "build-native": { "inputs": [ "../../.cargo/**", diff --git a/packages/next/package.json b/packages/next/package.json index 4cab54159d776..ec199fcdde534 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -344,8 +344,6 @@ "vercel" ], "engines": { - "node": ">=18.17.0", - "pnpm": "8.15.7" - }, - "packageManager": "pnpm@8.15.7" + "node": ">=18.17.0" + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1ab4c0fc1b84c..06d970e043f84 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -546,8 +546,8 @@ importers: specifier: 0.2.1 version: 0.2.1(@bazel/bazelisk@1.18.0)(typescript@5.3.3) turbo: - specifier: 2.0.3 - version: 2.0.3 + specifier: 1.13.3-canary.2 + version: 1.13.3-canary.2 typescript: specifier: 5.3.3 version: 5.3.3 @@ -14347,7 +14347,7 @@ packages: engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 - debug: 4.3.4 + debug: 4.1.1 transitivePeerDependencies: - supports-color @@ -24347,64 +24347,64 @@ packages: engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} dev: true - /turbo-darwin-64@2.0.3: - resolution: {integrity: sha512-v7ztJ8sxdHw3SLfO2MhGFeeU4LQhFii1hIGs9uBiXns/0YTGOvxLeifnfGqhfSrAIIhrCoByXO7nR9wlm10n3Q==} + /turbo-darwin-64@1.13.3-canary.2: + resolution: {integrity: sha512-M8QDR6SKPSLEjSLWnIM//caHWBhcZNkIPdnnMkHm8R9/fpFSI5X//GBdR0qnXcgdqOdFgnxheabwYm5Bm+1KWQ==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@2.0.3: - resolution: {integrity: sha512-LUcqvkV9Bxtng6QHbevp8IK8zzwbIxM6HMjCE7FEW6yJBN1KwvTtRtsGBwwmTxaaLO0wD1Jgl3vgkXAmQ4fqUw==} + /turbo-darwin-arm64@1.13.3-canary.2: + resolution: {integrity: sha512-4RpdYK+XF9Lx7/nmUzbn978t4HBCmmemAazOjmhyd0pOMn8rLVexPkByDEV84SrgofkCWdTHDwcHaOQvOLrKtw==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@2.0.3: - resolution: {integrity: sha512-xpdY1suXoEbsQsu0kPep2zrB8ijv/S5aKKrntGuQ62hCiwDFoDcA/Z7FZ8IHQ2u+dpJARa7yfiByHmizFE0r5Q==} + /turbo-linux-64@1.13.3-canary.2: + resolution: {integrity: sha512-8gzyPtOmzACNwtWi5//ZHwcJb2i21pZVXQEiNwTycypyBtV2H0WChmqjulS7M3z5dxwHcx0Ehf9TqY4K023j2A==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@2.0.3: - resolution: {integrity: sha512-MBACTcSR874L1FtLL7gkgbI4yYJWBUCqeBN/iE29D+8EFe0d3fAyviFlbQP4K/HaDYet1i26xkkOiWr0z7/V9A==} + /turbo-linux-arm64@1.13.3-canary.2: + resolution: {integrity: sha512-QzRIyO+HUMc5+hj5cVBCKpCyOiBPxzAao4zWZgz6iKMuSC6utjHLf/9AAo6NOMFgBONTYsMUArL5gDyLLOO0lw==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@2.0.3: - resolution: {integrity: sha512-zi3YuKPkM9JxMTshZo3excPk37hUrj5WfnCqh4FjI26ux6j/LJK+Dh3SebMHd9mR7wP9CMam4GhmLCT+gDfM+w==} + /turbo-windows-64@1.13.3-canary.2: + resolution: {integrity: sha512-s4k+yclLr/MWuwYURPZX2v6y1PP7E2aUUao6syQ68Un+36RYBgINN/VV4HucZuiXyqLuBuaDjfrnE1TX3FREOg==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@2.0.3: - resolution: {integrity: sha512-wmed4kkenLvRbidi7gISB4PU77ujBuZfgVGDZ4DXTFslE/kYpINulwzkVwJIvNXsJtHqyOq0n6jL8Zwl3BrwDg==} + /turbo-windows-arm64@1.13.3-canary.2: + resolution: {integrity: sha512-p5qGGeb3z1Gaxq43lTFm/PyTh7xtuDCfesxGWZWESG6MyXZuZYzuEH2cSmM8jqta6EC+G+iF5sxeKUzIpsJWeQ==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@2.0.3: - resolution: {integrity: sha512-jF1K0tTUyryEWmgqk1V0ALbSz3VdeZ8FXUo6B64WsPksCMCE48N5jUezGOH2MN0+epdaRMH8/WcPU0QQaVfeLA==} + /turbo@1.13.3-canary.2: + resolution: {integrity: sha512-GqkwRxoigbjvj/m1JfY7kGDupNeuADW7Hg1+rO+KqNMEUihOfq8a1kjCbwlqOfyS8PPfMHDkDPXrfhA8A1N9vg==} hasBin: true optionalDependencies: - turbo-darwin-64: 2.0.3 - turbo-darwin-arm64: 2.0.3 - turbo-linux-64: 2.0.3 - turbo-linux-arm64: 2.0.3 - turbo-windows-64: 2.0.3 - turbo-windows-arm64: 2.0.3 + turbo-darwin-64: 1.13.3-canary.2 + turbo-darwin-arm64: 1.13.3-canary.2 + turbo-linux-64: 1.13.3-canary.2 + turbo-linux-arm64: 1.13.3-canary.2 + turbo-windows-64: 1.13.3-canary.2 + turbo-windows-arm64: 1.13.3-canary.2 dev: true /tweetnacl@0.14.5: diff --git a/scripts/normalize-version-bump.js b/scripts/normalize-version-bump.js index 25bcd42519483..e13eb4b8928fb 100755 --- a/scripts/normalize-version-bump.js +++ b/scripts/normalize-version-bump.js @@ -72,6 +72,5 @@ const writeJson = async (filePath, data) => private: true, workspaces: ['packages/*'], scripts: {}, - packageManager: 'pnpm@8.15.7', }) })() diff --git a/turbo.json b/turbo.json index 0cb4370968adb..3ee8c97f8f7bc 100644 --- a/turbo.json +++ b/turbo.json @@ -1,6 +1,7 @@ { "$schema": "https://turborepo.org/schema.json", - "tasks": { + "experimentalUI": true, + "pipeline": { "build": { "dependsOn": ["^build"], "outputs": ["dist/**"] From 0cce20d50ac82e398a8bd0de3e5ced2830d3823a Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Wed, 12 Jun 2024 01:55:32 +0000 Subject: [PATCH 42/60] v15.0.0-canary.27 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 12 ++++++------ packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 14 +++++++------- 17 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lerna.json b/lerna.json index 9be8a6d6bc2e5..11585a1bdacd9 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "15.0.0-canary.26" + "version": "15.0.0-canary.27" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index ea4210b634910..ac030f9fc7021 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "15.0.0-canary.26", + "version": "15.0.0-canary.27", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index dd7c26aea11fa..9ae66ac85790b 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "15.0.0-canary.26", + "version": "15.0.0-canary.27", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "15.0.0-canary.26", + "@next/eslint-plugin-next": "15.0.0-canary.27", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 3ada8d6c86d31..078c5ffa93c45 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "15.0.0-canary.26", + "version": "15.0.0-canary.27", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 9869f280a7e9e..d15ca0ccb9843 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "15.0.0-canary.26", + "version": "15.0.0-canary.27", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 4903cb4071820..973ae132ceb9a 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "15.0.0-canary.26", + "version": "15.0.0-canary.27", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index a18d444be8478..9f7599388bc09 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "15.0.0-canary.26", + "version": "15.0.0-canary.27", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 89d1a82701d96..43aae5af46863 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "15.0.0-canary.26", + "version": "15.0.0-canary.27", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index dd082628cbe5b..1ceb986c24079 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "15.0.0-canary.26", + "version": "15.0.0-canary.27", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 70567711dd69c..d7f12190cb874 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "15.0.0-canary.26", + "version": "15.0.0-canary.27", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index bcdbd97b3d972..c8d5189659fb5 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "15.0.0-canary.26", + "version": "15.0.0-canary.27", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 6ed136f68a2f4..c10bd01ce2fa7 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "15.0.0-canary.26", + "version": "15.0.0-canary.27", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index d031b6b261bcb..d30ea1f4237d4 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "15.0.0-canary.26", + "version": "15.0.0-canary.27", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index ec199fcdde534..eef7d4bad1bf7 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "15.0.0-canary.26", + "version": "15.0.0-canary.27", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -93,7 +93,7 @@ ] }, "dependencies": { - "@next/env": "15.0.0-canary.26", + "@next/env": "15.0.0-canary.27", "@swc/helpers": "0.5.11", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -157,10 +157,10 @@ "@jest/types": "29.5.0", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/polyfill-module": "15.0.0-canary.26", - "@next/polyfill-nomodule": "15.0.0-canary.26", - "@next/react-refresh-utils": "15.0.0-canary.26", - "@next/swc": "15.0.0-canary.26", + "@next/polyfill-module": "15.0.0-canary.27", + "@next/polyfill-nomodule": "15.0.0-canary.27", + "@next/react-refresh-utils": "15.0.0-canary.27", + "@next/swc": "15.0.0-canary.27", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.41.2", "@swc/core": "1.5.7", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 8217ba0fada9d..8707a1981756e 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "15.0.0-canary.26", + "version": "15.0.0-canary.27", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 9352c81407cf2..086d84c5fefcf 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "15.0.0-canary.26", + "version": "15.0.0-canary.27", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -26,7 +26,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "15.0.0-canary.26", + "next": "15.0.0-canary.27", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 06d970e043f84..67527c3d04f90 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -753,7 +753,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 15.0.0-canary.26 + specifier: 15.0.0-canary.27 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -815,7 +815,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 15.0.0-canary.26 + specifier: 15.0.0-canary.27 version: link:../next-env '@swc/helpers': specifier: 0.5.11 @@ -943,16 +943,16 @@ importers: specifier: 1.2.0 version: 1.2.0 '@next/polyfill-module': - specifier: 15.0.0-canary.26 + specifier: 15.0.0-canary.27 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 15.0.0-canary.26 + specifier: 15.0.0-canary.27 version: link:../next-polyfill-nomodule '@next/react-refresh-utils': - specifier: 15.0.0-canary.26 + specifier: 15.0.0-canary.27 version: link:../react-refresh-utils '@next/swc': - specifier: 15.0.0-canary.26 + specifier: 15.0.0-canary.27 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1576,7 +1576,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 15.0.0-canary.26 + specifier: 15.0.0-canary.27 version: link:../next outdent: specifier: 0.8.0 From eb6575adb9c544e147ad5b4a755475e97d83f7e3 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Tue, 11 Jun 2024 19:38:32 -0700 Subject: [PATCH 43/60] tweak deploy test concurrency & fail condition (#66779) [x-ref](https://github.com/vercel/next.js/actions/runs/9475354204/job/26106589121) --- .github/workflows/test_e2e_deploy_release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test_e2e_deploy_release.yml b/.github/workflows/test_e2e_deploy_release.yml index 3afb6cb71e5bb..8cb8aa5c546cf 100644 --- a/.github/workflows/test_e2e_deploy_release.yml +++ b/.github/workflows/test_e2e_deploy_release.yml @@ -47,7 +47,7 @@ jobs: strategy: fail-fast: true matrix: - group: [1/6, 2/6, 3/6, 4/6, 5/6, 6/6] + group: [1/5, 2/5, 3/5, 4/5, 5/5] with: afterBuild: NEXT_TEST_MODE=deploy NEXT_EXTERNAL_TESTS_FILTERS="test/deploy-tests-manifest.json" node run-tests.js --timings -g ${{ matrix.group }} -c 2 --type e2e skipNativeBuild: 'yes' @@ -79,7 +79,7 @@ jobs: report-failure: name: report failure to slack needs: test-deploy - if: ${{ always() && contains(needs.*.result, 'failure') }} + if: ${{ always() && (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) }} runs-on: ubuntu-latest steps: - name: send webhook From 4398e348ee724d88282881137311680ee60fb23c Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 12 Jun 2024 12:38:28 +0200 Subject: [PATCH 44/60] use node js chunking context for evaluation (#66710) ### What? Refactoring to use node.js chunking context for evaluation see https://github.com/vercel/turbo/pull/8402 ### Why? ### Turbopack changes * vercel/turbo#8422 * vercel/turbo#8402 --- Cargo.lock | 74 ++++++------ Cargo.toml | 6 +- packages/next-swc/crates/next-api/src/app.rs | 10 +- .../crates/next-api/src/instrumentation.rs | 6 +- .../next-swc/crates/next-api/src/pages.rs | 15 +-- .../next-swc/crates/next-api/src/project.rs | 3 +- .../next-core/src/next_app/app_entry.rs | 4 +- .../next-core/src/next_app/app_page_entry.rs | 10 +- .../next-core/src/next_app/app_route_entry.rs | 9 +- .../src/next_client_reference/mod.rs | 2 +- .../visit_client_reference.rs | 113 +++++++----------- .../next-core/src/next_pages/page_entry.rs | 10 +- packages/next/package.json | 2 +- pnpm-lock.yaml | 8 +- 14 files changed, 108 insertions(+), 164 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 040f6ae61158f..41ca6d9d957e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -321,7 +321,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "serde", "smallvec", @@ -3092,7 +3092,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "serde", @@ -6964,12 +6964,12 @@ dependencies = [ [[package]] name = "turbo-prehash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "async-trait", @@ -7001,7 +7001,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "cargo-lock", @@ -7013,7 +7013,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "bytes", @@ -7027,7 +7027,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "dotenvs", @@ -7041,7 +7041,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "lazy_static", @@ -7057,7 +7057,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "auto-hash-map", @@ -7089,7 +7089,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "md4", "turbo-tasks-macros", @@ -7099,7 +7099,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "proc-macro-error", @@ -7113,7 +7113,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "proc-macro2", "quote", @@ -7123,7 +7123,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "mimalloc", ] @@ -7131,7 +7131,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "auto-hash-map", @@ -7158,7 +7158,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "async-recursion", @@ -7188,7 +7188,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "auto-hash-map", "mdxjs", @@ -7229,7 +7229,7 @@ dependencies = [ [[package]] name = "turbopack-browser" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7252,7 +7252,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "clap", @@ -7269,7 +7269,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "async-recursion", @@ -7298,7 +7298,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7325,7 +7325,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "async-compression", @@ -7361,7 +7361,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "async-trait", @@ -7396,7 +7396,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "serde", "serde_json", @@ -7407,7 +7407,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "async-trait", @@ -7432,7 +7432,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "indoc", @@ -7448,7 +7448,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7464,7 +7464,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "base64 0.21.4", @@ -7483,7 +7483,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "serde", @@ -7498,7 +7498,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "mdxjs", @@ -7513,7 +7513,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "async-stream", @@ -7547,7 +7547,7 @@ dependencies = [ [[package]] name = "turbopack-nodejs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7567,7 +7567,7 @@ dependencies = [ [[package]] name = "turbopack-resolve" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7585,7 +7585,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "serde", @@ -7601,7 +7601,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "swc_core", "turbo-tasks", @@ -7612,7 +7612,7 @@ dependencies = [ [[package]] name = "turbopack-trace-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "either", @@ -7632,7 +7632,7 @@ dependencies = [ [[package]] name = "turbopack-trace-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "crossbeam-channel", @@ -7648,7 +7648,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240611.2#b37b9c6ca913628cb2193b42ffc9feabaaba91f1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index fcb447ed1449b..4a001ab9c7afc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,11 +37,11 @@ swc_core = { version = "0.93.2", features = [ testing = { version = "0.35.25" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240611.2" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240612.1" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240611.2" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240612.1" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240611.2" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240612.1" } # General Deps diff --git a/packages/next-swc/crates/next-api/src/app.rs b/packages/next-swc/crates/next-api/src/app.rs index 0e24456eb943c..84e0181e8abbd 100644 --- a/packages/next-swc/crates/next-api/src/app.rs +++ b/packages/next-swc/crates/next-api/src/app.rs @@ -18,7 +18,7 @@ use next_core::{ get_client_runtime_entries, ClientContextType, RuntimeEntries, }, next_client_reference::{ - ClientReferenceGraph, ClientReferenceType, NextEcmascriptClientReferenceTransition, + client_reference_graph, ClientReferenceType, NextEcmascriptClientReferenceTransition, }, next_config::NextConfig, next_dynamic::NextDynamicTransition, @@ -47,7 +47,7 @@ use turbopack_binding::{ asset::AssetContent, chunk::{ availability_info::AvailabilityInfo, ChunkingContext, ChunkingContextExt, - EvaluatableAssets, + EntryChunkGroupResult, EvaluatableAssets, }, file_source::FileSource, module::Module, @@ -56,7 +56,6 @@ use turbopack_binding::{ source::Source, virtual_output::VirtualOutputAsset, }, - nodejs::EntryChunkGroupResult, turbopack::{ module_options::ModuleOptionsContext, resolve_options_context::ResolveOptionsContext, @@ -791,9 +790,8 @@ impl AppEndpoint { } let client_shared_availability_info = client_shared_chunk_group.availability_info; - let client_reference_graph = ClientReferenceGraph::new(Vc::cell(vec![rsc_entry_asset])); - let client_reference_types = client_reference_graph.types(); - let client_references = client_reference_graph.entry(rsc_entry_asset); + let client_references = client_reference_graph(Vc::cell(vec![rsc_entry_asset])); + let client_reference_types = client_references.types(); let ssr_chunking_context = if process_ssr { Some(match runtime { diff --git a/packages/next-swc/crates/next-api/src/instrumentation.rs b/packages/next-swc/crates/next-api/src/instrumentation.rs index 03ce17691e66c..c229ba963258a 100644 --- a/packages/next-swc/crates/next-api/src/instrumentation.rs +++ b/packages/next-swc/crates/next-api/src/instrumentation.rs @@ -12,7 +12,10 @@ use turbopack_binding::{ turbopack::{ core::{ asset::AssetContent, - chunk::{availability_info::AvailabilityInfo, ChunkingContextExt}, + chunk::{ + availability_info::AvailabilityInfo, ChunkingContext, ChunkingContextExt, + EntryChunkGroupResult, + }, context::AssetContext, module::Module, output::{OutputAsset, OutputAssets}, @@ -21,7 +24,6 @@ use turbopack_binding::{ virtual_output::VirtualOutputAsset, }, ecmascript::chunk::EcmascriptChunkPlaceable, - nodejs::EntryChunkGroupResult, }, }; diff --git a/packages/next-swc/crates/next-api/src/pages.rs b/packages/next-swc/crates/next-api/src/pages.rs index d6b0c398732a2..e25e617f352cc 100644 --- a/packages/next-swc/crates/next-api/src/pages.rs +++ b/packages/next-swc/crates/next-api/src/pages.rs @@ -37,7 +37,7 @@ use turbopack_binding::{ asset::AssetContent, chunk::{ availability_info::AvailabilityInfo, ChunkingContext, ChunkingContextExt, - EvaluatableAssets, + EntryChunkGroupResult, EvaluatableAssets, }, context::AssetContext, file_source::FileSource, @@ -51,10 +51,8 @@ use turbopack_binding::{ source::Source, virtual_output::VirtualOutputAsset, }, - ecmascript::{ - chunk::EcmascriptChunkPlaceable, resolve::esm_resolve, EcmascriptModuleAsset, - }, - nodejs::{EntryChunkGroupResult, NodeJsChunkingContext}, + ecmascript::{resolve::esm_resolve, EcmascriptModuleAsset}, + nodejs::NodeJsChunkingContext, turbopack::{ module_options::ModuleOptionsContext, resolve_options_context::ResolveOptionsContext, @@ -771,13 +769,6 @@ impl PageEndpoint { // `/_app` and `/_document` never get rendered directly so they don't need to be // wrapped in the route module. let ssr_module = if pathname == "/_app" || pathname == "/_document" { - let Some(ssr_module) = - Vc::try_resolve_downcast::>(ssr_module) - .await? - else { - bail!("expected an ECMAScript chunk placeable module"); - }; - ssr_module } else { create_page_ssr_entry_module( diff --git a/packages/next-swc/crates/next-api/src/project.rs b/packages/next-swc/crates/next-api/src/project.rs index 03a31f2878a40..797a3d52a47f7 100644 --- a/packages/next-swc/crates/next-api/src/project.rs +++ b/packages/next-swc/crates/next-api/src/project.rs @@ -35,7 +35,6 @@ use turbopack_binding::{ tasks_fs::{DiskFileSystem, FileSystem, FileSystemPath, VirtualFileSystem}, }, turbopack::{ - browser::BrowserChunkingContext, core::{ changed::content_changed, chunk::ChunkingContext, @@ -565,7 +564,7 @@ impl Project { let next_mode = self.next_mode().await?; let node_execution_chunking_context = Vc::upcast( - BrowserChunkingContext::builder( + NodeJsChunkingContext::builder( self.project_path(), node_root, node_root, diff --git a/packages/next-swc/crates/next-core/src/next_app/app_entry.rs b/packages/next-swc/crates/next-core/src/next_app/app_entry.rs index 444717924fb4d..5b712255a12e6 100644 --- a/packages/next-swc/crates/next-core/src/next_app/app_entry.rs +++ b/packages/next-swc/crates/next-core/src/next_app/app_entry.rs @@ -1,5 +1,5 @@ use turbo_tasks::{RcStr, Vc}; -use turbopack_binding::turbopack::ecmascript::chunk::EcmascriptChunkPlaceable; +use turbopack_binding::turbopack::core::module::Module; use crate::app_segment_config::NextSegmentConfig; @@ -12,7 +12,7 @@ pub struct AppEntry { /// the pathname to refer to this entry. pub original_name: RcStr, /// The RSC module asset for the route or page. - pub rsc_entry: Vc>, + pub rsc_entry: Vc>, /// The source code config for this entry. pub config: Vc, } diff --git a/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs b/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs index 9beb79635d156..6d1fddffb5374 100644 --- a/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs +++ b/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs @@ -1,6 +1,6 @@ use std::io::Write; -use anyhow::{bail, Result}; +use anyhow::Result; use indexmap::indexmap; use turbo_tasks::{RcStr, TryJoinIterExt, Value, ValueToString, Vc}; use turbopack_binding::{ @@ -14,7 +14,7 @@ use turbopack_binding::{ source::Source, virtual_source::VirtualSource, }, - ecmascript::{chunk::EcmascriptChunkPlaceable, utils::StringifyJs}, + ecmascript::utils::StringifyJs, turbopack::ModuleAssetContext, }, }; @@ -125,12 +125,6 @@ pub async fn get_app_page_entry( ); }; - let Some(rsc_entry) = - Vc::try_resolve_downcast::>(rsc_entry).await? - else { - bail!("expected an ECMAScript chunk placeable module"); - }; - Ok(AppEntry { pathname, original_name, diff --git a/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs b/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs index 06aa3e74392c4..0a95f81a93b21 100644 --- a/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs +++ b/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, Result}; +use anyhow::Result; use indexmap::indexmap; use turbo_tasks::{RcStr, Value, ValueToString, Vc}; use turbopack_binding::{ @@ -10,7 +10,6 @@ use turbopack_binding::{ reference_type::{EntryReferenceSubType, ReferenceType}, source::Source, }, - ecmascript::chunk::EcmascriptChunkPlaceable, turbopack::ModuleAssetContext, }, }; @@ -122,12 +121,6 @@ pub async fn get_app_route_entry( ); } - let Some(rsc_entry) = - Vc::try_resolve_downcast::>(rsc_entry).await? - else { - bail!("expected an ECMAScript chunk placeable module"); - }; - Ok(AppEntry { pathname, original_name, diff --git a/packages/next-swc/crates/next-core/src/next_client_reference/mod.rs b/packages/next-swc/crates/next-core/src/next_client_reference/mod.rs index 984741119c3ba..836ed29a7e14d 100644 --- a/packages/next-swc/crates/next-core/src/next_client_reference/mod.rs +++ b/packages/next-swc/crates/next-core/src/next_client_reference/mod.rs @@ -8,6 +8,6 @@ pub use ecmascript_client_reference::{ ecmascript_client_reference_transition::NextEcmascriptClientReferenceTransition, }; pub use visit_client_reference::{ - ClientReference, ClientReferenceGraph, ClientReferenceGraphResult, ClientReferenceType, + client_reference_graph, ClientReference, ClientReferenceGraphResult, ClientReferenceType, ClientReferenceTypes, }; diff --git a/packages/next-swc/crates/next-core/src/next_client_reference/visit_client_reference.rs b/packages/next-swc/crates/next-core/src/next_client_reference/visit_client_reference.rs index 330e912d0904c..7192f266e755d 100644 --- a/packages/next-swc/crates/next-core/src/next_client_reference/visit_client_reference.rs +++ b/packages/next-swc/crates/next-core/src/next_client_reference/visit_client_reference.rs @@ -48,6 +48,7 @@ pub enum ClientReferenceType { } #[turbo_tasks::value] +#[derive(Debug)] pub struct ClientReferenceGraphResult { pub client_references: Vec, pub server_component_entries: Vec>, @@ -56,84 +57,54 @@ pub struct ClientReferenceGraphResult { #[turbo_tasks::value(transparent)] pub struct ClientReferenceTypes(IndexSet); -#[turbo_tasks::value] -pub struct ClientReferenceGraph { - graph: AdjacencyMap, -} - #[turbo_tasks::value_impl] -impl ClientReferenceGraph { +impl ClientReferenceGraphResult { #[turbo_tasks::function] - pub async fn new(entries: Vc) -> Result> { - async move { - let entries = entries.await?; - - let graph = AdjacencyMap::new() - .skip_duplicates() - .visit( - entries - .iter() - .copied() - .map(|module| async move { - Ok(VisitClientReferenceNode { - server_component: None, - ty: VisitClientReferenceNodeType::Internal( - module, - module.ident().to_string().await?, - ), - }) - }) - .try_join() - .await?, - VisitClientReference, - ) - .await - .completed()? - .into_inner(); - - Ok(ClientReferenceGraph { graph }.cell()) - } - .instrument(tracing::info_span!("find client references")) - .await + pub fn types(&self) -> Vc { + Vc::cell( + self.client_references + .iter() + .map(|r| r.ty()) + .collect::>(), + ) } +} - #[turbo_tasks::function] - pub async fn types(self: Vc) -> Result> { - let this = self.await?; - let mut client_reference_types = IndexSet::new(); - - for node in this.graph.reverse_topological() { - match &node.ty { - VisitClientReferenceNodeType::Internal(..) - | VisitClientReferenceNodeType::ServerComponentEntry(..) => { - // No-op. These nodes are only useful during graph - // traversal. - } - VisitClientReferenceNodeType::ClientReference(client_reference, _) => { - client_reference_types.insert(client_reference.ty()); - } - } - } - - Ok(Vc::cell(client_reference_types)) - } +#[turbo_tasks::function] +pub async fn client_reference_graph( + entries: Vc, +) -> Result> { + async move { + let entries = entries.await?; - #[turbo_tasks::function] - pub async fn entry( - self: Vc, - entry: Vc>, - ) -> Result> { - let this = self.await?; let mut client_references = vec![]; let mut server_component_entries = vec![]; - for node in this - .graph - .reverse_topological_from_node(&VisitClientReferenceNode { - server_component: None, - ty: VisitClientReferenceNodeType::Internal(entry, entry.ident().to_string().await?), - }) - { + let graph = AdjacencyMap::new() + .skip_duplicates() + .visit( + entries + .iter() + .copied() + .map(|module| async move { + Ok(VisitClientReferenceNode { + server_component: None, + ty: VisitClientReferenceNodeType::Internal( + module, + module.ident().to_string().await?, + ), + }) + }) + .try_join() + .await?, + VisitClientReference, + ) + .await + .completed()? + .into_inner() + .into_reverse_topological(); + + for node in graph { match &node.ty { VisitClientReferenceNodeType::Internal(_asset, _) => { // No-op. These nodes are only useful during graph @@ -154,6 +125,8 @@ impl ClientReferenceGraph { } .cell()) } + .instrument(tracing::info_span!("find client references")) + .await } struct VisitClientReference; diff --git a/packages/next-swc/crates/next-core/src/next_pages/page_entry.rs b/packages/next-swc/crates/next-core/src/next_pages/page_entry.rs index 00d12456212fd..39b31f4adabda 100644 --- a/packages/next-swc/crates/next-core/src/next_pages/page_entry.rs +++ b/packages/next-swc/crates/next-core/src/next_pages/page_entry.rs @@ -20,7 +20,7 @@ use turbopack_binding::{ source::Source, virtual_source::VirtualSource, }, - ecmascript::{chunk::EcmascriptChunkPlaceable, utils::StringifyJs}, + ecmascript::utils::StringifyJs, }, }; @@ -42,7 +42,7 @@ pub async fn create_page_ssr_entry_module( pages_structure: Vc, runtime: NextRuntime, next_config: Vc, -) -> Result>> { +) -> Result>> { let definition_page = &*next_original_name.await?; let definition_pathname = &*pathname.await?; @@ -170,12 +170,6 @@ pub async fn create_page_ssr_entry_module( } } - let Some(ssr_module) = - Vc::try_resolve_downcast::>(ssr_module).await? - else { - bail!("expected an ECMAScript chunk placeable module"); - }; - Ok(ssr_module) } diff --git a/packages/next/package.json b/packages/next/package.json index eef7d4bad1bf7..d83e19ede2a15 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -206,7 +206,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.27.1", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240611.2", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240612.1", "acorn": "8.11.3", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 67527c3d04f90..4b8b9b6fba08e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1090,8 +1090,8 @@ importers: specifier: 0.27.1 version: 0.27.1 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240611.2 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240611.2' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240612.1 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240612.1' acorn: specifier: 8.11.3 version: 8.11.3 @@ -25890,8 +25890,8 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240611.2': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240611.2} + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240612.1': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-240612.1} name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: From f87dc4ae5e2c5a5f73d0aa1fe0461dedd4850d46 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Wed, 12 Jun 2024 15:05:47 +0200 Subject: [PATCH 45/60] Add bench application with heavy dependencies (#66564) ## What? Work in progress, I'm collecting some dependencies that we keep seeing in traces of slow compilation, makes it easier to optimize these. --- .eslintignore | 1 + bench/heavy-npm-deps/.eslintrc.json | 3 + bench/heavy-npm-deps/.gitignore | 40 ++ bench/heavy-npm-deps/app/favicon.ico | Bin 0 -> 25931 bytes .../heavy-npm-deps/app/fonts/GeistMonoVF.woff | Bin 0 -> 67864 bytes bench/heavy-npm-deps/app/fonts/GeistVF.woff | Bin 0 -> 66268 bytes bench/heavy-npm-deps/app/globals.css | 21 + bench/heavy-npm-deps/app/layout.js | 28 + bench/heavy-npm-deps/app/page.js | 13 + bench/heavy-npm-deps/components/lodash.js | 12 + bench/heavy-npm-deps/components/mantine.js | 12 + bench/heavy-npm-deps/components/mermaid.js | 13 + bench/heavy-npm-deps/next.config.mjs | 11 + bench/heavy-npm-deps/package.json | 18 + bench/heavy-npm-deps/postcss.config.mjs | 8 + bench/heavy-npm-deps/public/file-text.svg | 3 + bench/heavy-npm-deps/public/globe.svg | 10 + bench/heavy-npm-deps/public/next.svg | 1 + bench/heavy-npm-deps/public/vercel.svg | 10 + bench/heavy-npm-deps/public/window.svg | 3 + bench/heavy-npm-deps/tailwind.config.ts | 19 + pnpm-lock.yaml | 674 +++++++++++++++++- 22 files changed, 897 insertions(+), 3 deletions(-) create mode 100644 bench/heavy-npm-deps/.eslintrc.json create mode 100644 bench/heavy-npm-deps/.gitignore create mode 100644 bench/heavy-npm-deps/app/favicon.ico create mode 100644 bench/heavy-npm-deps/app/fonts/GeistMonoVF.woff create mode 100644 bench/heavy-npm-deps/app/fonts/GeistVF.woff create mode 100644 bench/heavy-npm-deps/app/globals.css create mode 100644 bench/heavy-npm-deps/app/layout.js create mode 100644 bench/heavy-npm-deps/app/page.js create mode 100644 bench/heavy-npm-deps/components/lodash.js create mode 100644 bench/heavy-npm-deps/components/mantine.js create mode 100644 bench/heavy-npm-deps/components/mermaid.js create mode 100644 bench/heavy-npm-deps/next.config.mjs create mode 100644 bench/heavy-npm-deps/package.json create mode 100644 bench/heavy-npm-deps/postcss.config.mjs create mode 100644 bench/heavy-npm-deps/public/file-text.svg create mode 100644 bench/heavy-npm-deps/public/globe.svg create mode 100644 bench/heavy-npm-deps/public/next.svg create mode 100644 bench/heavy-npm-deps/public/vercel.svg create mode 100644 bench/heavy-npm-deps/public/window.svg create mode 100644 bench/heavy-npm-deps/tailwind.config.ts diff --git a/.eslintignore b/.eslintignore index 95ef16d8d0d3f..5a5675691261c 100644 --- a/.eslintignore +++ b/.eslintignore @@ -37,6 +37,7 @@ test-timings.json packages/next-swc/crates/** bench/nested-deps/** bench/nested-deps-app-router/** +bench/heavy-npm-deps/** packages/next-bundle-analyzer/index.d.ts examples/with-typescript-graphql/lib/gql/ test/development/basic/hmr/components/parse-error.js diff --git a/bench/heavy-npm-deps/.eslintrc.json b/bench/heavy-npm-deps/.eslintrc.json new file mode 100644 index 0000000000000..bffb357a71225 --- /dev/null +++ b/bench/heavy-npm-deps/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/bench/heavy-npm-deps/.gitignore b/bench/heavy-npm-deps/.gitignore new file mode 100644 index 0000000000000..26b002aac1dd1 --- /dev/null +++ b/bench/heavy-npm-deps/.gitignore @@ -0,0 +1,40 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# env files (can opt-in for commiting if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/bench/heavy-npm-deps/app/favicon.ico b/bench/heavy-npm-deps/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..718d6fea4835ec2d246af9800eddb7ffb276240c GIT binary patch literal 25931 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 LrJugUA?W`A8`#=m literal 0 HcmV?d00001 diff --git a/bench/heavy-npm-deps/app/fonts/GeistMonoVF.woff b/bench/heavy-npm-deps/app/fonts/GeistMonoVF.woff new file mode 100644 index 0000000000000000000000000000000000000000..f2ae185cbfd16946a534d819e9eb03924abbcc49 GIT binary patch literal 67864 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ϣ%UY8`RWp~V-U_7 zDSM&-@cv_g11tXxtR8hhSsvhbm}^TIbEA^ zez~Ise9A5xP83c_%z83NHI&u7X>Mt9`pnf9TVC8vDso9r$$%-f#fu6f@a*df)uo-Q_5os=ED| zcEe;FMSWSJ&ct}ag!R8s`bGUZ`f~{uR>BX_16UIZu3|HQ{An_9v zHp7)lLClDc62YY@VO}JkS_2kF)MYGEO;oHS%W;YuDSf29meyQ*kC&Q@D5Y()UirbQ zeT^&uH7^72nS2!YD|zY#+SZO~YV!l{p=s^XHa8fe1Wr{Ir~lt? z&T9&mFQ)1Obn6G9RBhN4O5^az)h8(>R7Z`?G=z2B6om`t%6fF1Lre{m0c~K~0 zXZ`%Asz;D)&nPl8w^z!q(xW3qYNIS&^j=w1)?4pd)hsHQJu%L&>=IUNSr-?V@a<#y zTe$XUE|?}yQS@G4Hzyq}NAYok$^v;@M3G?#N~=Lk0A7LKEyo$`IGn`T`3c+&xhE&g zGUdOb(GqsDl}c<$s___$V9iP|P`$KE66Ka)!2y>Q0W!(Z1+^C&IwAD7-&RKDm zn@lTqPUJ4whnly4U#AuBOX0`y@9}=T_iKqGj)SrPBvyHgUX8{~cQ&n$YZMhEYGih$;=(NLFnCA; zJ<{P6EViq3GdR@A0F*j71H;Z7rbk7w@|D5)fHG%I7z!A3i&zoOG}HN^4@2Y@zZPW8k#z-2^|-~Kx5rTa2PJ#IoVGbx9( zms$_6iSdGT;U0f^Fi(^HUqEObfHCxveHQQmm5N68!ya{NsbpQ!J&T!=K7H*BqwI3( z<(8F_S1t|R9X3GYtkqCkY%MCbUS*P0tD$w9$x6L;NSmOB={inXdS_%wItd~9g6P?q zbe5ls)xwWyqa@6o*JRjjFm*JXA3Z_f7BV2Q zr|8x;r2WS3q$)JNtkgct{V{eZW>(nSUAP3`gSGb@Ta068{O(62Mo>By3C4Fb0xq|f zF($svLG@T|?ZAQUbnm64rqnxjz@vnk*h&!BzyCpfWGxn*q%`b!2z>QlqgEDaj{z0qttc?)(Dp;3e z(yy(@YjF6%)!PGZ32TFI_{e0?Tr)><@Nh}%lMmyo%EZs_SFe3u*|%^JhjHJ1XGXjI z``I;gHSp+U(PI(CA?ZoqXG6&?-|KFNIGgKWj|g#lmAvsh#qaePKkb)vfkVD7B!sBr ztwrDIu9PhVp@t9Ota(3qIW!E{Stq+;x1M+(GR!qB3mdmJ6EZTkf_M>gnYyV*G~{HY z916Bf_&5)i%wxFAr?Wy1r!~*FqLp^99NyPZ-4ZHUy`0AUEz%0+bKT6;SlXPy5^Tn9 zit~>w<74c@=Of=s&C`mfeNxu7BhA8zZ8aUPGKDEyrHnjrw?v_#{)nzNg>MHveY_6& zIahSkcjLb>)xyrl4^6X;NEoPI)mVS-Scfz&*j>UtsLUHUf3vOFe{VM$n}31R)1_Fa z4wRr_VWG*Hdy0v*FC?d$Ny$k{ruxs|=UgZ|Sy?quvZB$JfE;70t4l^6I!Tg}>eg_Y zhK81qii(yP9MQjwa+ZXOmOLc=wpjZZ^%-&YDc@d%&LQkEUp2PM-s@%<^j>Wd*zN{m z`uIvD`cpvhgNaqh?8!Rgu94tEplL>Qwr-K^bDvl+D{FmgJ(tCsl2)sp@ zO8+Z6RqvHilF0dRCY(_2%LY>mq<5f&S<@pZhp;K@gL)OlJ+wIoR9s4riQb7G*E(lM zT`eb%v_6o2fW3}!gLQdyB7{*2rErWtZ}2<$YTTn(CQ5@*lC)YA5dw-p!l1x?Fy_?9 z3leg;vQHW-#<5G;K_a7kIS|F5x2qAw4Sjry?}hr}BzXo5(-a}1Nc2lv-Ux=7dw_`8 zr#XGH9?Vo})J2ws+jH0iX=yh&74q$+tx?E~Dm3uC#iso#%yxrgdwQ4sCaS#1Ba6qP@BDTTlWER; z_Nr?)h}&+X`Ml*kd?vj9KHR?7)+4QIjnxNdB$-4<7JHBLV%V%f75QVvg=?DA@P6oP z6|+Cm*j}NeBB0y|MVZI3d#*aVv3lH!Q7ug;bw0VX0C1mpTVDuBU-JlZ&L*CrEx~@g zvWYf!%l@HoTQc76+$Rpybh9IpMMRVsTga6ck4{C19$W_b-Af|r-k^#2-F(MyP}23< zJMWV1g}YafX{Z_Rw!3?-w2Q@oq1XAOMa^scf-SjkdSwG>qy_`I@4l?3=ytXtN6RU2 zRZ?CjbKpA1i}Nb`pyH@hS5vF0`s&TH$8A47t|iq@+0wI3nn-*7ob=)T!M(+ruye(< zEom9SCd#4heQ9Q{%npGh?2m^nPetWYjy9zv4ia)CrBY?wNlG2o zo#y=B+)MHX17`SlMY?qZw;;hMoH1JbxC*NXfq=*3fcaLt)%B_ci+Z)ctA0~lZj7Ga z6vPCw82$QeeH~s2j~}m&FVF^B5Z#nSEA;WOmT~aU%`JChOSD#3x0<`7!@a5b^5klL zE{Z37&-828$DM=l8@bj!a;JCkT=(qSYNG~mYkT=r@32~Pp9^&Xo0jSK~pHT?6)f?A*>9E846baRamXh?Tkxg^BjK7qxaHX5Y=?%)&BTXb5Z*`A0_YR#@MG~i$G&mDiVqBUEQmb~ zT-b4iN)tcawMQpfkx7NKEy1{U4Vn; zOn`N`SltDeICuwP!4I|f=KE&G=pA?A`qlH(c;DggP=Hm>jkJD-jK*C)#5xi`pESX`hO z)^AT71c;{_!-jQ+x%G$xqtk23#8vBfe!c#pI5j)(Ml$E{L-uq#7#P3Dj=X_A4S*3H znBlL^`de1}*(c$r2C$6jPAg-6!zeYxwbp@XvS>GY%obNhzgT{!V7`!tha) z-OVAEZ3n1vj2wN3s5_q~K0zKsWlI+qA)%XFSW#i>btv)AF5|UYK=>9Y<6WAGKhDm9 z>~TM~Vs#Y8lnF4USHyMiR4{8lyM^>Z)dfszO%?SH*J5wT-p#cJ8(>q7#3GzJM3d!F z)-Za@re5UMqQu?&n9LL_mJ&?!G}p(vhkYsK$*YuiBRNhjbc7<@KedR3oRvOw-kVSZ zvNJxHu<3gx+=T^c628Kyo3L^%6*UVHBMCbNS2_Jlr-!(Ngw;HidJPwcpmr&Bl;U59 zAB?_`@FD&}7<>qFe0pDef`=aa3O_%Rh`BLksk z1{srtza=8k86*=_O@dPgt9HG}|0hh)8OxMT0bAv-7S4Fb0 zkDTdD6%FGH%Ue}4h>u*^j8xB_GrG5#lle?4ZT|>P~W#{+!GHsZ*!l_U6YuunTFV9Vtqf-CEsVDxn`5_ zegWYFLHw{L|BwU&fdGMe0K@i!pl&e$0rj!O=1jNPZnS(7m~FJ!;{0j+xwhQ_1~U3a z05a}_tpl|I+UO&6fZzNz(^vM}Pl59UBL=z@EIP=wKXq5@hQb5vVDO@jfd;{P@VE}| z0xY~=(gD8rGvaO%D4&jJXmxC?gP==rw>UIMnZNf={z4-^_zT*Ix}^-jB!2k zsR-f(%PW|#fZ&86H7muGRa1F6?9pIhm8d1o)(~P9%PpAKkYJU7&co?v^T_d|XN>#) z!3%Ovp#4Gk3#VVSKe7Ntf`SREr>Nwd-~$rz5UQg@HcIOd^R48sza~N%YRAc*PdML#BJHU% zJ4#DV4c^j`%%U_6meXa;{077Xkq-yUny?@_RH-3I0cN|8tC7J-Yl^_$Rx=_&M=_pvWW=AIentRL+haM^^M| z!TJ`luzS(QKo?tikn2H_8}V;H#ebuMG_;kI2~LHZbhVRt6=mpZSrx`hmuKFx z3p~}OY^Pl#R_&`Tvz(4^{RvRshVqw-X{)yH9 zEB6-L=j}?Bvia1BBkGmEU6oSnRJ0X5#9WAJ5!^$}`yjW`GO}i*_erGV6U72-gx>Mg zW9BMOQH5LzgXPRFBi|ThsvX!{k@({FMf7vMm_e4Kum+_J(dn)Lx?}A7A200KY_cH& zZ?wkfPkq{|_yzY9Mp{DUScVS29VmOGc7M+9)y?>8m5*ZX!DrXh%3k;_&I`f^Jz;aa zG6fxC5KR*@I8v{~$+WUL|Ow zdm)QEgfm<=jDTes8x>}^Dn@G@!Z^BWn9Ycf*$dbtGkju9OVo@ zN9JtXndsN)ukmMZ%1Mg5TXE=SLrr7d` zicE-1gCh69WSS7B=|11x~CP`}>r@j8`xaL>{FyB{^fQ6J{djI=f^&&_Ni6`plZ3X^D3zfCZpN`I&8SBNX_9q)=j-Lf8 zYj3Tk$k~Cdm-m&_^Hkc^D`A`*;amMNkFK47Q+u?<4Y#Q_%qirCD5S5q7wGWybg1UW z$zq7iLKXIoVfZFiSM=*s=+hIaizoRvD#CpOAc7%+GWDghfOQ{tkn;%--4Rdsk7xQ1 zgN;yU_w@wG?XGduS}l@sWdStsu_z{6;wpta-!bKJ1NAzhaD3S(Z8t)%dEs)kE+ZJX zn8YzdzDArt7?Kv}*9<8pI<*d*u?4C%O?XObZYL18(V7*eHk@GU(b-JnjL1;83=vDO zb;;T{Zg#laRQT$Wg#f8g5vXrExuj*tA6dXNu?im;@qC!!En^%oGk<^`Y5@}S?vGnV zm-(nUVZCeBf=!wptO)3Hfz9gv<&t@Q067A9>=;Xr601f*wx}hVjrJs18=Pv$yWBLbvBXw>nybvCzqLC zIvrQL3rJLYh8-HK9rX@x*;aZ$M_Xqe$PWEobiHM zan!Ew`Cb1ABg@_`z-Ti_x(?)N#Fhiceb94=| zCK|AfQTYM6Amb+3f%HP z^V4u0z!4aj5*Yk9nldObupdW=d4v&@(TVAIU?{B2Hx}l~SJ>@fP_{27JOjnY%M8y! zFSIc9J%$(=7`=%Z6NZr7BHnsLv&+2%b>kD-&{MgM;U5Wu%_=ludGG0P;EwJW zw(-;ih3{K>ko83AOA0DgEede`#!H=+2LCmb%YhpN|7{bPt;+fcyrUuMIsZgGWq{iXfqPthbyUu9!)+ zJU47kLMuMCbn6s|E6}bu>(tIG0N>CJ@Q1Pr-g*MPj?{*DqyMSS{34WyvLz~O|1T(2 zL!vZgEsOg4iI8i%i@K`0YFUfAzVi_26`4t4@Yc>Z|G;(e@^zj z$RazYfEor}cw|BSH0p1sR9{H z5rKppn$OY{68FPYH>jflNo`1d5gH7I{M`SGey=+||IUHXQR9o|yI5~A4_rC(H ziNr(c;DY1}bfi`lQWhNvTivA%hIb~>UV>O*vs~WqJra`4%34)gQ6uu5Nrd}@kHYv9 zYLbh=uF#=k5vVROQ>1en6Dca%))vuV#c!4zxpn!=w5MsUA#AfLGdLllZ>os0SP!nK zGUf>;|Jv{1!@HI8m)2JoqbVhd({sx;Gc2P>wrloU#1#(d{Nas#BgdxI^s9)uBt)ia zj2)`u`D3HwLNo5h=+lDJ($hi5Jsnrb*)+;tiWerf?GSdd)}TI|C^nUe1fMU zzfJl#(}0yS{m1j&l~1x4VgC#H{ygyC0zhBjy>E89|ET$zUp;$Yo_wD9rnt914vO=h z8n1c%Fg^%@8mg8@?$*t??Ha4AQyTA5H{7(vs4cN*@=O~5Pf3@p1hkz~1CXK?M93+i zBqXGkV^Z)=$^k*BWke}|h2YK>LY`dmskcsyQ)qfsTllME$jy-N(`S^_8bYftjv&7F z8Ads#u;?7ay*K~W7YjgFIz&}bM46)5{8eq*q3tkjjBQz9Tcgu9bLK6WQr5IK^k4On zw~f9~hp|WEiNtH`~g%s2WN=~vDAXev}Q)o5k(7`1|7#$y#ymJcr$Sy=QryTHvc8)XBDW+kk z7<8p_$g1GU=lWAVB5ZXR!o^d@Hd8*Vj7zic{OJUL zu*i!8;e3v#P+SpiNyT4P&D~X5{!z)^RZ;y>(YILzB1IicRfSYl*>y?Dc1clpNtwD? zO}kl#_f7G8LH@1RZ&~28Q1DGP z_%SQ&3;}K-54)z9MF>J-+OC5F84oRYI!c0vZBCl;q&j^Wkf}{e+uYhFxOy23Vecw%=fq6_;Z3X&;HZgK zY1LfSvQ(F;Hgl%UT50E6Rl`~r2CLAOW?%M7?g1<_MXExofEv2@z5Tuk=I$PiN@D0s zTfCdy!%fImrCanX!RW^jE3Df(1~OM1xT6oZVBbYRj>#wnO{ zo|+`GnVs#`F*RnXWG6Z8b!I=lCcmBJoZChJkMC7wns_p2^7XI{r#*n@IYX~B!#ogR zOlT6gAq5M*#~BrBdd$~P&FmZsKbSZ$9_t8WL_@A>Qcm7P$w6x)?9-(MdAPLd(0*S zkhr0RX15y8;h<;k5lrB8dc^NR2846F>eFVcY9@g1?Jm-l7o+-I%+nqdHoCs0&}=s> z?DXGMD8-uGUnTkbO@FbvT41f|(#}Dn%xFV@>_!_`*p-PNbJ^_Xbw3qD_K;Re=fS)R z_e4U~4iu!8cSHqGU%!EHfL|Ah)B%6n&xq7MGiakN!FG0??PMfDzD^s^sOFsEtIMRE zV4H;eA_%N{(s|;J;^}xkIn1gRm0tQ`$=y&bOnhe^l(^;DZ7OeOtq@yoX#4$;G^O)LQ=g=q(@lq)b>A*=H@mxy1J=1&$=^A?lTO_)l#39YQ>8=k^ zm~&c`E@4bOQGyNNKrF$Sh~dLLVPP!6y3BDP`#UzA>@I>0Kg*Lx_+7KT=$om;f_*0EcZg?l*n zX>l~XdwUjs2d6Y6=?ALU)`6ast-`jVSY9kFg9XYb+lEo4ZL)Gd#>Qpc0$t~2!Mxsk z`973z41*Q_AUwwj;u1XfJ_T!B`yZ`m@4jH3vN$gU&sE|W&*UA@enDVCMIfO5ttcQw z&|P3YpnxpMnl}zXU;{F-NNCjwaP91JN3!W8P{|Fqi^PV}lvZB|k>XffE+?6=4wOt# zY`Gjx_q{|KPW76tHd6V(PHws@UWJFTyx$&u6~BKZ*yj9=WAYzBXuaq1j1{F~C0{Yg zj8?1Ja-~2y&5qaW@s!yPPg6dU^&Md0iW0NX@4opoq*35$~QV9DpFcPN^){+Vw{?Sin6l2 z;`R3Y`llrVF`z%-BU{$GM$u10*rtbz-d6PzU(k^$lxu`asFti2E0k*mi^!(5nxy{k z_m&Ga!ew+@UJqvr_I>$;gJLn*%yt9ClnZ8nOlJH3LefdKDy>Gl!BX0vo>_0a?kgZ3 zmCNRGz8WZ@Ub#IYOH7DzF(JZf9}_2xQgk|>?uPi2%j11}7M|z#dikgK%k%zfu(N6Jwh{(y%8})eFDrzrt0CJ69iK=NHI;V{+r*cDa#0yxXyC{;s zFG9~p?Vdi!(Ed|s<}7A&NPp|sTKDv6ulf{>4cEK3Nea!4X#6K&^4C>tYAW5>>j|6vzAEsWdBL!Irzul32428BP6n;xBh z-j5>ZCV&jv%pUen`nCs)oih!Iea(RjX-G;F~W5+~{MJX+Mq8nHs{#5OWyQbLN!9dgwk7DS!-P&l$( zq@ZmKP;a=}sQjW?tVMRtAe_q)pRVBZN#jX%IA5@$KkkyBUc^C85(;0Rzm7!q*n_PNR$*tPzlZz;(il~CDJR%oms*gR}8Ky_i&nk8k@OHEOulB zF$!Zc2i>M%cUvJmYW2NHG4xn7^qe!u?FJisln=BiFwjvkz{6mQ`bo#pLW(8AtY+i6 z>Xf^LNaije4=*VZ!HY(oVW$XD7tJHSZc_oLiD!TtuK$+72{{d}JNpg54Y3Sn@I@>| z7?==DXM+s>{rzCWMV)xs@}nmZDsUx#C&Eq88WLS(Lbev4rj~YIW^lbEAK_?L|H4=K z{-HZNu@wPE4dqrnZAchZ;H&C_6wY)&+3v!7#}76D{dNyi^cqbnBIUD8y&jeR;F;bT zeSP*Q`@*{(dOtY#Hq7?^nEy7e1E=MBm^WZODTc!=VYDcbO|Lf?CY#FVhR<$ukT#z! z6sDgl1Q7$I*BPXkEr4*dSyHjZU>0Y&48(wSy1=xu$d#IB0pNqHpt5Y>(=NdA$ZVW2 zIiq#pVdzfbv|LV1hpZBwfQw?ls~@14(W{u`I_83}I2`r|XoCf#;k#p^;V~JF2ZB^b zWDzb_O{!KIjN%RFf8M-cqS<8P%HVO!;1$zkc3b1ITch;?tRAg8skQT{ZH8B7)wUAY z<<7Tyz1$^EXMUKhzK>_4n9*p|8;%B|tRxw-X2AaZp3z_^M3ZmPP;avOfB|#ckB!%H z>d7xlkv=VT66ONLL&d{pDuI+h>aTn+^}hNqE~j)|f62w=t4V#&)YE+M!8NOqLt$R;ed=V(&BdkE+%zUu*e2|WOh&KbEFp<3FTBOjQ zCpX;rFkblx;J@$8M-1M(cA}hQ+oFdr2vvvvjOq^JUy|!C_^jNZ z71pFMm#kwXB&{YK?nzgO96d9 znhQcPoU>(ZsU(eentx@bDCGuT&~ncF&15hH;w#sAbmyXRO-5db`(!MXOwUn++L-sL zxa_%NS~TC4T(y=t}1I*7Xv9 z7HY}b#P->8Q3sw@DLwUXot%8iEJC+bHB)e$ueT{=RBxgsh!Ob1p-)8jX68vxZHk!y zLf041kwvK$7B2k5Ns!v$)wQ!QDg3RnX4M;vnoaR{tG^(mxG9fQfk!E^VlCI8uPRy( zF%A9%*_@DrSPa}Ei0wqDv_9Fh3rUIPxnYRmi&JmWFXZJPg+7+Lz4Pw009IOU<6aLU zA3%EYo{PW?5@n&-P(|^|=TX-iO$jpn9zj-{qvKo*e@zpr7kCTY*8#X!lI8gKzAQuw zn73cW^i7z18lQjuDA0ra;*qr0Wn$73v?y;sMh?S~tTH&U11gX|SPE6!~{hmrgr)BMD-fX)gy|Gn%k>5a_ z*t3=Y^$SP=^}vFLKp=bc{6EoT%sv6HdZr~*B`b7BKmo`@CKr-2MUDwnSk{mSmw7*<{BVX1;{23V3J@E)J+B; zfrGG>;+&tTR(09`qC~bEPfx(Vf&9gQ>iRjzUqEo+zfcg0!7~Kp6kt_;u?jNJLOnnX z_JKzjDr!J22Td86a{$$Zdw;!PX`&L82zx4Gslc&{>dpeO;BO6Ms*f}~!fc`;3?1Cq zd}Is}b4n;G1+$RmNboad%8*Nsfj8vvkX%#bLs@8LCZ(1wSsJhB#uaUxh^Z89M*$YGX3rW5heNEJ#Q4xS9Jru^T zhao>?eJc!&rAn53YC@-}lbQr~2+65Rmw0|i=c(+cqM?ZZmHJsvN6I&ngqE zTDHjgsL{O=>f))Z%f5`~qR%TMza0G_)-6x4g7F~xDbc&E56jeZYV($5XjYYBiJpFB z*0^RbmnEH`l^~ixo`Asj5KFKif7W`_`66zsv@zh;I(T8yIabs9eqrf7+0#U?3%jxa z=ZdnW^HYx06(X2M@Y6u7j%5`y8_o_~KKKtIv?wO43~DKibExZJ>Yjb-F7Sli@1G*d zw&dR9R4*}#|M4)`2!4W*{|Q2Bd#9gHP93H?X0>T=I$tqAN3*~7e{lI>_{a1P?SK%@ zA~u2X_5(5C#{637LvtW4bpm{(y9*H(v@+;m(gV=HqAZ61L};#aC}oilL-Gtz03ak9 z80!J>I=Bnq@IFQdaGhW5eU~?|A3)#vixeox3U-U2t^&TZkSxGcg4(mdF1Wg8_66o` zh;-rBduDAYSCQfS^&Vt;0V})LBv|7jkaH4liGPxbmL!Ph<7CKS#;~90JSBVP50lHF zn=S0LvegRUES%Tl+)6-BA-Mvl6A~po*RC!gEeo4;)~S8t`Nkp-V;X4Xlh`NdQ$(b^ zNVNx$p}46&lff=jkBTzInwONU^j&k_h~k-NQ?>{IeMBv44sJJM5>QKU)lk-ZQG0ZI zb9=TI%{O@xxgn&)3q;Yx(M1_Wu7x>;pM^<8&)oWL8a!)x4%M7tvV&cZRj>7$DdG6P2@M$3P z(#9RnWAOd6ntyJt5FIF6X}MQR_wa9Bd7}jT{14xssGw* z>)y%#3i3ym=ixe&HP2QaRy2PdC4_y>UP|=wmL)Q^&cZU$GoSLVW^otPR;K5XI&$9@ z-#Xsj!x%^EZs+qd8?vY}&eGX3r!%56HZsLCb~H3xWu?U@K_|H;v8=VMEve0OfJuXy zghLCQ;_-v>85TjX3-LiNLzD+g3}K%Jn)i+!$lEZwe$q8mRI?H==MgdjY((RJtIr-< zm^J;@f|t!-n040xr(st^u8bp0$H57s?Q=T_y*>7z_krbu&=0;Ik>6{*6&Il*B36tF zfTZt7k&W;>Qyfw;0Tg|Ezw*AGCo|77xX z-nUzOM|o>`ZhL3FV&;i|j_oY+Qz(!z5Z+`yHrTF#U4XkGct>>)_CT8j5!vsX-_r{>3oi&E3=R+a4onVk4~!0^5rYw{5=~1~ORS8&j7^MvQJ`NU z<00puOky^U5Y?B~8`gu}syOQU)bFC7LD7aH4VV}fIp}$i9%Crhx3tOdQ1K;9NDG{i z#46DzJ&j`>?mL-gq<%W-wrBC^=@Am7o^u zYgKPb1%x1`o4|6^yYu{HnK`XzJ8%2$+;k9Bi#<;-9Cy8U(Pu4e`X5|N_P}EX$1)lq zYX15OC23VJo^2~5uLhH@xqn=z`Gl5u4>bIoY zLzfH=cnChWD9kcg5I)bL=|ZU@c`bn4eq}p!DCrZ5y|e|2YXmOiT#ck7Ii^Xmqu;JJI6baux0aV7kP#z8%m3JV z{6#mQfD{F_WYw;tCf~T$RcZ-K{U9SJ=XG<(bd;N!>6Dt9#z{)Y09&CdL78@N6|QY6 zl~^2(kVJ)%n~@<&ma-}a2NSgGh8YIK_c}lFG#HN1x@4drJCJ6=h)FZRz%!~v8!>Oq z%KAh6$^D>0#makW-V{7MEZX~xo75Z1&=HIXy@AV+Iw-a$P#E+V^IxwOu>WA z&N->3J?mU=3 zPv(kPphJ%>;;7R$(C0I!0vS|>>eGorms0mg0Zgq=zwRT@?E0j$OwohG7ph(FYnQ7j zX~X`qrhS=JdTnc6t!i=ESG(BozUw~leopvqltk)E#>Yk0Hl$q(oIgW72Mt@Jl-b3- zS6O(k(Q)CaRcKMAxJ;jQKJ`D$7sY0(IvS|Clq`6mYLJ|vrib92!^IGkUGCNKe!kQr z7s;R;e7`rMr6k$;$=0%AP7fHwa8j4m_`mx1e$JTyo$Lr|Zt2l)YinsqRmNBjVPy&~ zbpYf=r#^j|xmcID7Vtv~h)AF_)pYf0*ml4~TL1tLMK+vhUoxwpzOA-?)*V(0O&u0R zd3myXO>1}l5TqXQCwwDNitITG)RD06uojT24o!wO0U9#xsNn)b{{S+hfFlLnKhnR3 zhYbFJpsUCQVXlTSK0llO9{^-Po4+bH97qfqgpjKy<(9n9HqI!|I8g0)K&-r6SkQGr zQ1g{Wl>?!`unDP}+TDbiHuA_Z2xRXqq*9_NQ-`_Ao3f$aRW@{Q(Mb#6E;Y`1kpl|o z-s2rDe-L4)2n{nL2xyU^OR01;WTh+Vjg5_Th334G2u&Xx9Gui>T2*PlU8RI<)_8z6 zaWCL*st2VP0e4$;D73d%t~KN)yDP(lLa@<50%yIykfWplJOtaZ6tI$F$CM2BM(b1caS63xzb@lPh(a|h4J0!`W(8c}zVgkLAB~FBR3(=A^ zRQ3bPxX;yOg+Ay#=(Q}n@)LA}t10w@f2sbmyUy+`nR*57Koi)9Gic@^Vs|wmB53UN zB3hhAU9FGzw=lZ*cz@eNf)>&Zb+9l7;i(~jxM*GwR#yuR*TlpGFifMN$UH?E$3PM} zmyBI(!li2^?Sq*xeYCK!AV2{Iv~vETp>bf9UWbew)SF!5BQu}2W8{2IC$C#V2t!54 z2K4Z?(u#J+Xwm}uZ5dT$9Ay$VpoE3sH-x)VlL}B&MnxIlTWI4M7a6(H2@h7%qF->C zvqd$C6PB0Dng();%07IU;ItbzP6R=NpLlw@ZS(>e!{2H2ENPj9(cggU1a4lygBNzL z{}=z>Y<&4;=IE%Q(8oVl`&!crwIBU4hX2;L%)UMzh&*7f|LQs-=cnb|0PILVQ^k)6 z-wb8^3jW476ui4jJ`>IupeWmCQ2T^!l6*z^)cle8hm=pzXXrEd{)fyTosZ{*@q7p& zt8kZ``X^0sjsBB@{y@U2N#vBXO*#Du`k!EQf2R!_LW|-%+q>sf+M+q!db;aV1U?4v zs{r>&j^Nd+S5;L-4(V4`#)EaUmAQBCs5IAFqtCUy1>!9j4ElqvUs*5jcDqH+?Z(vH z<&}Q}VWTm1bF&P?63xQsb;L5VbAF?Q#35p7icL#X zi5R47)j*Vm3`C*)Dy(ibk6fdmUq)Rp0?k~Ez|gXDdeDx}Ho*egJVW+DFoWJ-dc2Q+ z(t>MWQFefp0TrQGAhT(E7p~^sg{xT7F{Hi=UvuxqSG)AO(0U`gC5&-tcWv?i{Fndo zU;fYHTJrGlFuAr2mgw@@iD`cEMWgY>7p8ea)Lt1``8dN{QMn@9=66s(EVUnP&(9M> zC6(&w0X7_Av1yu!6`WEa5RjZgVQp=#APhn@V^Gj3>iYFo)nUL!1JQJxp(tcDWZM*M z8nj;t2~$(DWqH}}&txVh&gpMFiqRx$I&_#Os*1RC6c!~z(~P7976+4LWPx*p&_OwJ z>(;@6FH0d7FvcPZn0ga%wpkk;ttoL!IeVPhUR_<4d7*Ja5G4rb=Q@EfRNy0gN{x(+ zP^TE5W=~I{VuA3HdvkLWbpPPs;K|7eeDQj{pZiM8J`8@qlu9-$%xATg4u^&g6*ru9 z&`7~a6Dzssmf zB@n`)W-vB?q}S`Rv5AiI&-OYJa)Fypa;(zwzY`thn6B@6x0*9Oyp0`$^}i2JAoiqG9`O3)RO`txe<|3SQ$9c z{R0Dk`A36r2o|FpiVE)6E+Omkw_udCG=n86@ z%b0;l7;NFBWZo6a)@Hdnnx98??AMLL5lhhx5R0%-;csZ`!-|a8*FU#tcPQhY;K?cSr|9pazyJAb&t|ac z*{tiRCxw{d?9*Ycwmu2Hl1Wk(eCG~$Hp3pjL1l955^q#^szOFdp;YT#!TJb*u4Q+qFM~S1mKL$xUgB}Wz$gTo5Jh}sxeBw8@O z^9}}H6bt!l*9trL?%mtL*REmcRXZz|t5uoah9dJ$DxUevBnT8$K1v^C3|vmGtgLV` z7%vP)UX-%BYz|Qa9$bk?f7I{X&z30BxueW_c$Ol8X1#2hK8So>>Gk^L zF#}UBsYhxZsYw&}i+i+ZpmAUIq@dD{zH1W&Xe&4z=coBG!suHFp=cJs5`?g}j?1MY z*p$Um*#!omvsOw&OIibh#IYF#-``V^IcHxuLO$5cfPmDEg#{%V9UU9bW`~DIqhW~$ z+l-gO$zS~97n^yiXLxwHhb}_*hM`z3PGXaBEQ4kHq{Nnp?5wgbh*`Jza~TY^Dm#$Z#C0)#C03ve+W95I@Sm861EQmgp2x}5R^LD?yd0CPLI^%WHm>mE#fvAi;-@$XR47hGA5)d)uq)>yotcVs(43ky>A0PZ_Sk4?p}c2E1>@49gK5I4ue& zAvlXc7h5Hoti*yd|E7l6y%Zt*9>9MD@S)RG>h#@fZAIhXvf!bGk3U{0VT;9rOWC8H zy}fXFYkTJ?%bo7+?VVae6W{*!x32~i2Td1?=p74ht?&;ZjQ#{dXv`z%%wWvN)EeL+ z4zhL#ui05sS97^sv1U4fG+pK?1V~OnWQ*qDP~94xM8GJh@?%D2vh!7cdJ*HJc!$Gb!I(8crmsB9Vej}gkPi4(7#}aK zTqo3TA=EEc>b%ca1;XD`tGdh)@xp<4iD-F{FZoJcXF&ywO?b=cWRU=mH4vL1sHcx}H`$C~~ zI$fxizje0SeZVi;GWyYsf8xUa+KWrhynYaBhDvUy9q! zMuQcgI7LC2_Q>{#k87w0Kpv+JTO^`%)VYuj?hfxDDIM)_jlezce!esOuOkc<;M1Ch zeog!aiI_sa7LI49Ef#bJdVKP#ueSXF%KFMi8se3ym#a%Z{pAB1O6~N;g9rDY=M3Mq zYu6-0an)*>40;b-kDlikh?3sl$dpKc3?e>$^OR_AMW*(5PvXE+tP`vO7fwhjkmvQW zZ~$Zp7%qoZ574Ws$QDPh7v{3_GKUGfAF7F0w2Pdl6;aOQ2#!yaBg`_@r8fO7+9VF~=~-d-u21)?NL z+&Fd(%hb@*rwQlgema{yp&|LPxtW!utU|8=PU1MbB2ycalWi;Tca33ZNz2&fGmZf4 zJmUuyA@A+mgM;7w=5KxS$?q8eQE5ek3>8kn0E&u!&%f6F!*WQq7Ku%UJfzZEU)=;^fi>*ghYy?*Hz=(h6^v5Q*YbpKf1ir$f@8dziqd3@80d-gt`AVLg)j=ZnyI^GW2R?btO%E#&0x? z8m(dC{A-2dEjZ4t|`}0*tgm} z{UPx5^tAUO#v)+jb6~3siJpAvU-@6+WR#w*5QpLl4uzn7X)RW|k zH4q#kOeWNd+hm(19oY53{hc^t;Zda;r+qg+`Z~C4$4wU~0^8e#qljtKH?Q9s84fx~ ziZM7mcH`E>^t49&?+kKYfz!C+ngi*f7EK2JB@=QCyn*Ggd#VxVM(%7Y1Q-gQ8fU0aF_okFHI>bWt zHd$zPi6=EWNLlW@_n(Vm^p}Xl3?odD7pxHq#o%UP;3okvVFzC;ot$jGI6OW+&Z{^u zFfb6LRo}ost+>19z`8Dn3{)@35 zgETb24}x==fAFP@?w(Um?BX66>+|^_O`SRfB}-@(;)7~ZX4co9o>Qpv@a4;w@KCTv zk}6GydX{$&H5${?lW$Puc(i4K*u^F$Xs85DV%`svTui}d{76lb;p1r1Tl9L1ZR6W@ zJ)1@Cb6k!SfJ8=Fr~=dv+IXT!PBPWS4?enp4`0|!0u+#J$GQUyuUu|uAT$uLDRZ25 z1ke*xp&ULjA*F!yL2UI>+2&=LmBp8P+iMW8s#KwSFDx|(7Mo0sOawYd7%lJeQ*amC z%Iw17^)7I&BfR_gB7xVt%u9D(wH>wclU!sMMRt=hMMn2N=dz<{RT|t>fL*^Q2#Hr- zN(`P9g#|ORi*INfF_atxZ{!}s+*8mWNr>7+pu!(53qlb&N(vT)PtZTd3`5=lq3GWv z{(o9Ymu{Nd`a|pHaB6FR5O4G;sMhphbr}sNY&*LX=5k+u-&6DIzCtANM<9@8G=Jd< zo%?<+HgDRc;FaJ8J)GGEDrXfEZc3^Ox+i1W_{_C_0*=t(W@gx2_Yd~5<#okQLROQJ zh#>qKK^U;Nd7suU=f`)krMWJWp6UX(T);c#w)q=;Wud}8oJ2EE5u5vOIoA(7?Bs^9 zG1+l^<}!WY&Qwix^544q10-_%hX6jz*}#Sm+J;AZD7ZoA7HI=P7A6ww6*((OX)ra= zk0+q=9TX;Mx-+7=duY=j{~5tUPT2;zA}t*BbCpBL&kff}-n*7rc#_dw!&lWaonpY; z%%qM_>*^{<$!1!v*8%#CbGUeiXgyEMS(+BDjMXY+M*x1G~m|Pm`0hD*5W=KMIjN!PyI-Khg^JH4j zU&0yu{EEHp1g>`()%C8`#m;4?)7n%_xk5RcElb6s1bX^#O=i}fz0%XfX^BD!OOiJm z4rk#B>6XllPE0~8*qd*^FWjDI>c3dSIKog7@`BG?wgJxp1D;iLxvF1P{R&57Ea>uD zypKP)dH-y8cef8p$mMb#hC+u5M}jPIDgf`2EvUaWBT^x)onz&;E+;^B zfwNtoZ;LLn&FCTp(Z!CGrnbw?OPu~znQG}EQ_aqN%yn4tC0d2M5l|7jMkJw?@9VQS z@|zpH1vkohC}-tLrEFUKey@Y2ptVoW0J9%MCZxY!Etk}?6Yc?fC=&tKW0cziHf>(1 zp=nwcHjAd;WjD*2%}wQ69iGsu#bOnKY}IuG(JU0sLem&Gs+Drh)N9}wPy&P_1Wth+ z$rgrTbnwvXvWJ2JDdcuRA?`Z#gz=rM0qy}}g;zI?Zj$(X6rlhM(FGPa&d$yn*a=3s z6BohIEs}JUVd6N2O+&V=Fc59@*VS({F?R3%@*yqkw#6h|Sa z1*8|{bhhTY9>wT3;Z6rUe|{euW2g?@_OgCi2d#503@PkQ%t(j&NSy);^5bclpeUeq-iN!hSrL{M1=Fm+Kq`Jt>;u%== zWN{WRp^hAGyykEbVW@~@Fa?FFPLcl2`=JbTpNv5-AsD68vuAF2mO1Dp&yHbumI)rg zvv1rN=ZaMbf7hX0zrMK0UBAAvv~>3ig(3gDNXwY~JLcicOnURnhlean}r~I>4-@gcb{~8(DA$nXZ zt681z1tHjPtH{xcH~`cWwwdbAh7@qKW}^flw4KBB{t6YPApVgiv7xF4nE(@`jN=Uj6dRFJBZ)_teee zSy314HptJ{YPALppMoeTazya?qJXq3UQ0a(J}3B64*g_*74E5R9UrTZ{WJ}|UX@u3 zM_X8&xctAJiHW%xLW=rJq&zvkWou#F_^6R&EPTFjD}o!CJq znGEbCJ39*>GyIR4nQ_lj+cUez%*@R9@y^cd4u-*T5;I%2n57o<|5pM#@?_xnDk-bg z>MpKVuipE;SJ+y?@( zuX8<3o<5yicKy23+F$4z^&RSJZgzgRrJy-cfvk>6?jJvR@OabQ9G7cljlXh*)ZegI zV<}J{tM&fn>qB9B|HRIq zwpUU;fm6X1aWuNMv9?xgWr#8PUYIJv8;-5rSTeQ0wliit4W2#iZft4NIfM%^#V5Za zOnab2yZm%3odvYr1W?O_k1hjm6ejO#yxL>sBV08T3(J#JpkmV#6K#aEvxSGo z62rBEymz+TTb!P}N^V5>8{`I&?YB)2#gA53$hioAj+`S$droW1PP0Y-Ec!PUNb{=(elBS%tYKF zesuFAmOwMtW*d9Z#_qvmd(PdSmC>Y&OQEbs8qn>5p>>o3rEQgT>c~!qKD#bh)|j1+ zXH9UQJ?jzpt~J3sIeBEM6Njy$-m=xvX65HC2Hiboe)#axG+<)Wm&{-JwZHb)e&rIr zpDh-F7#AUgj1}t<<;HeVgv|8DjW_-Ai3x#%nWRGe$-nz||L%!^@613JPlL-G@d^>; z+%V)vg~GXWZ+_NFmvEE=4oBc@x&O@9zIL|%V=G-|d^~gN6i+2pRVB(N5~og8*D!Y0 zs-Lyeb!;qVhuORZgv@5!d~knplh~d-&X%yol(IG-#+gZI0DCRn$@I zoubgJwKh`UjV9vj)6?m+cVx^+)YH>bLjg&W0z>Hb_5%7^AyYYci7 zw8o%UZnj3dWS84G>K-@rcKg^+?kC*LFbX2SsQSVSFQ`RqRkW~xQXCZDwB&N9PTklm za;<{&80XIqIT;Fd$S6)u7O!TrS92&p4idm%s|$L)mNzVZe>9425L+2{VV{R&6Jyn6 zl27N(OxPe$gFtF6k40rVm&y}e$4;wbfasFk?xB{QRDKzqvKEV#!_6g78|s)#K?Z;O zexhR~MH2UJnoT_6`CP7LAz#rWE-+!cSW;jpWf=yI3d*t)=A$U2M!L&paatFavUm#J zIcy=>rw^?T3#pWt2apPxk)#>uQp&Lyv$J2$w~V-k+-|93+Qp-2C|kW$ynNn$WWnV= zH&e{ljtsl3^|}?wD6$+xVUSI36@}YHAtQob!CVdVto=R%ef~nHAAz%o#xlint=dxT z_HtzgxAZVWat7(3RO4i)J1o0TW0QK?En#zeMKfVV>*?!p*~~)33aYoBS4JT{D3bH% z=fZqpH(QTzqTL&opFBqYEIfXy(fjw0d-C!iAtOa_*u`81*=BOhA@t5WQDG2GHz?#b z-}`U>?Z3UZnZqjzsYJL6QRdyOb#ASdh%$n98#a+L+EH^k8DXa!VoT_XKVYFnx%xu< zN3%}q!<_@)aLWCq0?)s9dviW9E`-Ojj;K~jqQpTl|R+h z4ZXp>fH~q)y#4)|x8Htyy{wEp+ZQ?TL4qs^To`7RKEf=}@87@M?2uy$cjdVh?k2ql zwP9MiR}=>arJ}gz>85bv#Dq9DX4E-wWL(`iI2ao%ErDxWDrpw0Ro9LY7-*diHNu8G~6{QU@DbNRaBpkL=X4lU^n-+*4IDFc(XqqJJ{db z+1glN-%pQvy}n>i@4z5JlzfI&=L_EcfX#8Z6J1@|*-h;xOIwOMbaujH6F$q-v!8dk zJ+8sA@$rclUsv+^bZTRLb#>|8pDB~iWdl0c;Tokoaq05;fW2BRHi+~jq=osVr7MFG z0r|Z4%jV_UOK!{K)r=`D2sXEW0Hf{eUth{b1dR4an=Nj;2Wj=Qb@~NLU-+q^yZl%# zH&%Mb`#s;|d8Z`Y9r`Kl@AwzMZ2kLE*}2#nD$rfA7K|Y_|wYWox#DK`^rxbvbX-y5q5GMZ@Ddtix$}H zI;nHj^Gek36Qk(lv#gshZf#xstRZhw z)s+?U-|00#If4B84fy4^G_jk73Sd!YtIOu``PSDr*S0^p{b2LSmM(C0(2fQtcqTw$ zCq0V33-)EZ0!v%7&Fhj$2D_TP5H{I7-q8Nd$B$OC^B|~U`<>-1v5n!KF&oK3C8=Gg z9!3+`D3_|agY9jf&(4PiFP;xLO}wEv-3TgQ+JddjX0C36to_WO1&!RVx_maNCi~m~ zyxR&pTbb>&1a1fc>lR1D_UR#;phsb&eoz%`gGVy@R|Z=girYnaDssHQ2z@JX)a6Ma zkckPhM%>ubyXhL8tp=V}l-z?vC)@kC-s+%JI1P#~bf$KDO`$vf}7^LX#oSNGO% zv6_DM)wE`5!s1Ofg{yIVE#ka560*R``{G46$wkppZujx-)-gzk)Y7BHN4sV=*BH`qx>%Ufcx)51bISBIsUI91 zEH8)Q1CGV{9yJC8{I04#c;GoT<#(&qS1(noK40~gDBjW}4DeT=RSSbOed(&t=X>d; zdi~O+Fn{S%z5ZEf^Uubx``c0}_m2c_3T!ov{)gJ-3+4Y1Rqh6U1TvrZ5@*XheSJIb zmz4*1gqPj5i;4F%DvDu>BC$_QGf`ym*jL0)GHV7~U*GP2wrXOyzaoNy3v(m8v(?wH zHqszFyW87)_((x24Zt5^2&Mg+6^Oq?JXYkHdfrbOhDLcKf}Vc!RC#xIWXLJxAu&Hp zQ<^@+MV6|;UZ7bdCy+NjyWI!Lt3%di$MJm>Eb36eT&>k@c86GJ7{s*R^rEL)BwmyN zr;(54JU)yulY4b_gu&<*FwDq5)5ve0XM0yR1H|~)zGpcont#2S{PR!Noa)-Kt!^)q z$?W{Yr-Olwjlkg2Kiq*##`S~F#Z`}IbLs*qO}4 zL?V$YNdqlm$-c%~v>$XJ^B1UtDwsf({eaB$yLTo@SXWF7i@aQW9*JZdU!7 z>h)6T%$dgnx0)_#en}&LDop;^yyehW-LP05KCJ0uXYx!>{Th-We?3h8@_c8ve~fL$ z4DqaO_YKFx^w1YRk^l^@7xP0KqDuN>X3~7iKFH>BM=s=v55rD-x^0Bd4y0-ROn`<86t&kmCdD_T>aOE4cMYWQU%_nKk z-d@kKV-cPw^?F#nu}^|nD1u}kLV$rRBfJSL3T`O%+*ZP@gff)bXgTOkPtT6lqnE0p z-3?j1+b&j1x<2d>bxdzvbPNx_c_jB`9{+rh7%4SfYGFx|y5W9SU_^^-$z8`JSWfG2 z`W91(I2bzclF$nFxa!*=@aR^};}~+w45^<3m|_?x{mH?Qxr0=8ASc(e5+iYKIPUpw zB}^6~`~q1ZGXKbSL%RL``|>3-F<&Axt$y*NUwQ|hl^A)~*z4U3 z9QJO@W=J^A_}6-W6z@+Co|GVU(%1?N46t-q3GfW%jsw7}rPan_>3#CS+i$C#L@(86 zj-~51@~ljW)rTvhI%40B|6q7cq=ePvNCP*;C>eH2iB|An%P}S<@Esxp#un5d<9QUT zS<&*39%=6MsZ$d{^lWeEb9%Nk%VL8`xepU^mmNsb-)SpI5nOBuQ+yE%x+JO-(X72-lRvE<&Zcp9bHT z*&nsQ8;NBf-@E9}+;Q6;)afCT|V%$&^BlYOf zxasuiiPL5RA|-}RC?b!RRif}+U9;YW5>5}TDYGv`_MxU#k~y;QBKEMsdcGc%b^vJ9Io@#0|1w$bGj1ln$P z7VtLbbXAfQqa?kw#Jm?yBrDZ;*e+Z80GW(2jBPD~S>zdu3R7ri&I;%+LuW!Q5#|quhYz$C;`^v1#)45q#q5sDCM!SNuIOv7r?bCEHA32?g}H|3lEID~d(Icgdj z84CG4zTR`i>ts&(<&Bk<#*4q~m%ZrbB*m-<95IuD__PP8;(~X&S*i)N+yI+CgwmFj zqBV=G7Tgfq-v!Phn@n4Q8#hc+pm4iD%lf>aPff)ZY`UU&$p@ixx#S1Rm%gNg1>H=N z$*`zDeym#ukNs#eyNA(!NIrJcgf>-r7Y58_0I2)>?V}eEa8DNdF-7MfpLui`A+?Ak zHLWzIu!(Jd_ld(n3XzuO>6rB^U%CFmg)5`zAdvi|Y4j^!`HFRKdFcth;U2B-F$*Tm zWwqAt?lCKP>C0c!Z#4rG-ey`Ix`T{*+;BfI;zu)Grr!xmn-+z>7C=HMO)a5UH`3J9knkm4T z6OiWqQ|D)1xOR<`jA9!6+sc!>_g&=EOazYo6k_5Ln|Ha~AL5Jg_(AkAx(MM5_dzdg zKBp1J=56|mmIqHVswhf|%|4*Bt=DgPl0nLl&E0#@p2a;KY&H}>m!7v5fb@m!N8Z_< zEHB$^%i=`(?QbO}#Ol=cI~t`l{3&|^cLzsnfBMwE`;V4}f}5Mcq2+(H3z^JrfB&xg zhg^@>yxz6Pt{-wY)9U7o2}>hz%%e2PKPOk;YjK?#<2s*VQY;UBkK%{^MVXQo@7XMa zx8o7g{gg~3AWUdVV#s$jy0*Y-V$(BOu2)V%ARJa+qS*N~7c6lTLQ|OVBSAB9yX8tO z0Zz1BWMek|fNkz{h`Sh%5g~k7Xv86nh+wGoU@yM4w6(ppy`9NGO93w|PM5>$CEJ4| z+pxWtRi#(l*hBz`D&>V%SAcT3ZcVnYNy*nQH6dT_25A^m7 z;uFR&g@b)X^1*&P1!ApF-EY9~;vVD_GvtS{#f<=hg zQw#O<5@_+G4I4jyzEl7TO6NpT$RQLfRB$I#hU8_+tZ|1_DoJj33581IAPLk|1)z2+ z$|jjqD%onSVMO}s>F?ga6kFIhsHou3u_z^p#XpG^;?fr!^869kfQa?7HGD2e{d8lGUbUjl)Fh5PKFnG~CO6^R*nrw<*zTsSd@C9 z<#99;3-=VW+$d*3d!jqhh4@$`;zl;zv z?XsHhJ;*jK5{9itK5zJ-BlViN-Hkx6*F@Q&4ba@A*nW-&P9{_>IvL2^7qH>Z+HU!S7)j4i{+9(xgE`+2MgCcMRWc+MJ1}=3 z;AMuDRtZVVUO%(+8nV$8%*pU;{cxS>st?eTW^`=@gNq|v+wZfhv&$!~tq_$b&1d0$ zbMlt#-6ZQ?@$+s zc<^w)Tw`XtRUR@lM?){>wwqo!-I(+J4o6tIa%E>FY9NGZ4Q|0IIMrf$%Ee_sOb&>t zZ#Wto8}s#g0#5jIh2X`la!7}P8hTN`kizyCyQy5*^5B6<;#uJ(nWx7+gGk7f%Y$Gl zMb|chK2pl>FM~WK3xy0UV{(S*f$HB`E$p=%nL&SAZd8qkn-fg|=6}DixX842RYqaM z)?2#`H&(Av7##HALo`V9oQ?SA<^dau4Z@tz zIZ2A?oQV_HK5~fb?WS(flxLY)-1Hb4%LzqA6V`AIVFm;G++aGnUi_i)r^AwZ(DG2QZ`gp>Q6nLIM z{=-Nu+TDJR(b#o{GGsLN2pc04ibx1Qm|3%GZ}OXTprN%jX8&K?AJ94LR$-9E6oimf z>>NmH_u>6iJ7iO-t@l5~h27;V=k=L;*fRf#0~+F?M<2UKo0|fdsyu4 zW6Jk8&qYoC;-2iy8>K=a1sYr>s>f#-)Ziox8LQRl^GcGDN+x5;T+U)iX>ZyjWFcUs z!qbqh)Zvr2S_efEZJ-KbEXHImEotZPMd^PBA>^e_>CsT}WZfKu9Mf;cs_)0_@|j60 zVMZ_^a#U!_~JZ6Q_fV38i#8It= zI<=yd`h6CWVVY|^rF<2lm>LI*b_`5T!~lTY1%D-;K2yVQ1S!ueShLL%1?9)@VERzm zLZwoVNR$|qP=2nfrhkJ_^4FPnwoXk2Ns1m;Brg*&gXT$Y2p?TiEp{Lwh=`3kVGXQE z2BwM%?;{SQu)S&6jaC3}m|c8=3+=z7{-4y_^Vd4VyX%bx z;ZY!-vcd_}D5VmKeTXh{W!_>d*-Mp@4h*>=iYA-2(I|b+M*6g|(wdL25=vfV^Rd%% zQYKS{mz&J~J_>U8FQ^7pXW1GU`S!f&W&kkE~*WNHM z1CEXj;*R`m@BPWPef_oPmjP>ZDnqQjY=N}8T-Feik6HO_+KOO76a^W7ZFZ~n@j?nH zb5PKgPr=zsyTL$<5dV{tb8SQD9d5<;nr%d$q0m{kNt5T2ciNZ2By77A|w)>mu*&6G~N zR2hNixg&DZs>h!ol>9M5h|;MCnnp33&`5-faHV275}?G!EE`CMSvEAUZ6wRCKVBz= zBXvsZk}O6PQI_h2Hc*jR>nY^wRxfU$;|qC^4|6`gUzdak=B!!!)RqZ;QpuYYR$kA8Cdn|!@soLMk^ zdi(Z#V*7?*WI!F>H~xp)u$)a+5E`7#R(^gn^?Xt@m9c<^xwtOOAKR5o3=-1AjsoCF zqsENGRLm}wFb`7&A_pr6+Mls+{2B|SgVs(E}piRag*EUQ*Bl&oX2P#YHq66YLyzLp-^4xro!ji2pI6(VTE}?agyTB z)|-S6bGgS)-}odRWmW|{oo4(QwRrtuD@S-_q}XgQpq1s%!Abl8^8F!#&RyH6py zv!6jcXFnG`{85zU#|R-*6oDc(V=@^%K9T5&t(~1BWMC01C06u-MPN>53LJB!TW8kE z<|^SVtoJh;@d)3jBR6%sNX)pU5{8kcke-eRA`whNDpwa&Ur$fKrYOzAH46zKb~+$9MZ2L2>%@%#oX-kDUAP@$^6 zL_+?Iys_bMu&DhRIS|<0Wl=lE=vkk^hBP<>|HKUk`$yC;DTGD;4*S=ABG@db3%T}6 zozz~@Oj}zHM+G#k!2Gq`yh+~rjzH*lG*ck3v(o^2lhPBGkxJ`LVzbSeS}(FBG^O<- zxp{NW)OwGl@W0^Q(~RabYTSPJ$A28c)HxF2zVwyXu9JvnKT4=m4^un2xjAy(_!GkH zciwt?RR=+_9vMaO$g+oh4!aYH!8oLdNYvCjWtFpA z@I-AbXCLj9BF@{lZ@%|osnQTYK$NR5UY?oxX1CovS0u2z=Rmu(ZktWQVKvsM&o{?m zW2Vu=!@1V)0-=b6%#*;}Ji*;AITnQyg4pJ$$)pj}+_9983h=Vi#aHk{$-Us8p_uq` zG#Uu7sPT!x(B7W`Um1o}VtpNOsnRp@)EV|xe{9?L7uZ{Btu{T4WA}QOmn|0UOSL)f zTl}A_e@Xii|C{Q+ruMhFfB5DX8-KL%N9okmSIK|FzrToo6;d%ghKHY=6a?+#NMUNz zJ3a!MZDU-x-D#Dv_WW~y!R!6P`02B!U-kK3WuL)EkAj-UGq(CQIV&%n|9CO@+hwOHcN;wotCKV-@YuD^*=L}|E(EV^R z6k60ctb}0>M0Ni8`LmV{F}1cB7DUfZy!TD=9BcGY5X9ByiUa&mdujV z8$w}Eq|Qp7O2iIYE>Qg*7Zy2Xa*_y~A%r|((GwI5PSBjJ%DzCb7ilAhoxSJ*o_q3y zY{KhKr3lugoQmyjwp0Id$NN4jdymf^7+^dIJW{L&ePUftLydHJxV?`on^m#VLXn3> z0JDbk^9Fb)-sU8Cdict%&f9uKrQzF=?fUbCLI{-Iu< zMIt#c2yw!3nu!vy4T8zx@n~J`K1TqVKxV&WZH{zsW5L0e6^tx3F>C^r+%q$7ayu>! zb5DQq7x`gxmLa)`4VxDGocdrZU4@lGEsev7PqZbq2f|XoULfXlG%Q5ZW>V0c4X-zs zGnd!P=3LI}Z8%OlG-okcuP2KZk~6t@-et;RcsMKZnAubn-D1^bj>RkKt+YnExDDBS zbJKA)EnNn)A&!qoPxaEW_Ggauq0AD;=Efwfp^~iK@j2Hf0X&bu)RGiZaseQy~jy&0bO4pDlB`{Ikjf;^aHEh?=jVCC+7^+n@)EYwG))QUTjiw z1C#9W+=*4gXc%nOXdJB?m)cfE0k_xJnm>oJMB2ePeG4nrc79GcNXB;)VIi>_PaZ^+ zB+7|`ZYAdfj~?BD@`Ro52Ds^yXA3Tbq+p;o?CK2!C8)}}s?o8yXyuzu#130C%jb1F z^3BapGxxb5MWK2JJEf8Z%HV{nQhHhyd(&nwZCKG5bX2&LZAdHiEr-oh8&_;Wjx3xn2`PbpcTW} zN{i5{6{u!68G4m7nR}VujWa|c;^AepYVQkr>~1$XZj@7NPoCa}y69ev`p=$ArSmmW zbue^!@2SDQzO^ip%hnZGfhcv&KGhe1{HU~t=MN1k@S3+)sx@S{Yv_4xCbefL0Sjkn zWD-;K#HDlz8J+egKK5JDOxJAGT*Pl(na%!ANs(;#aP(65{j$9g1A84GF9W7QOremGFpS{x`@C5o(JIgyM zZJw(Van4j&y|r36>lgjZNvnyJAQ2(fxz4T(k&v+#7ini)q`l2WZf+iKAnY9;?y%3p z%}uH~IAU-nhd#ER2hR@m7LBJ}!v zJ?zsrFksXRX@pF^Sj=bGRiSQZD)(R^&vAlGDa?^M>zVTrC&yz~8;kDug!~Q@XAo9a z!$_nM42#8Jp9$!|q@i;N!&XJH46~~tDT}hYUBO_bl!+BmhtUt;zkNI6EbTnnK4{o% z3lF!;4NDzOq&?4e8NFlqwYH^uy#d(yq8eUo(mj!}fsh~E=W62q3^&hN@#>-Q!a&YTE~*(|kKsP@f| z|LVpXUnm$ho56lP>BA`h)I3Yizr@LXU}m-q(njJ@GRNj}w;z~RSzCW$bM)xjc~kz| z&g%IupRa0v;Thh1V7tSccTQde50Ok~5*7`-qcG&zTd8SsK3_1oTuMQU@UgtbJ9qSk zgT3LlJ6w=_|0+70pEzHZfPOOa%gh%?1#JUm?Vwm-B8V3Ko)^Va?S{+XHn{oA+UtwXqtAEJRd#BM7`B25PZFv3iL zeefN=DXo3<(Hhdiw?OpG6HmI`3(@F;yP3s2eAEF*H5|jYqcq(ex>ow&gN4G?tBUEg z7AEE}Q6UV*(%0DDrgTRO^Ln9B4O8qJj&pFd<_)0n4vk1*BF%T5%6RnbOvhi6qUglQ z#6@}{L5tg)n_Dr?o=Dg=nZh_H%adwE!LHm*coU^fpt#RuDnkSqi`A*BjzjN`6Y>K@ zRp(}zi=a!Fv)PDrAK`(`8s?+X|NNh|E(G4Vy0M{}D-7zD2a+ib*`OerL(tc_V3)}` zk%qmnupnt~m<568Wfn>xk~h{%9GGJmz~rSqun}u(+Bh4GD^2S{r>)U&;8Q8AY=FVo z$Oi)XHC(J^1A#1(QY6tN6RxJ~`G^xpnHnH-=g<3u;x0faKHtZzHn9&N6~qC=#!2}D zyaKxh5Q1)ZkbSzm%gb$goMrSl+os34+&k|8&~)$KgG^ZEMZ>668^m_@{P~ET;~^9| z+}jNXJQf)o{Wp8v?!?*(LcCImv(MFp+r3e+_aQiqu*Gn)D|=yMX^C{m>BIMKf;QVho3mvrwlZ5;**ev0`sT6CB(u{yG4l>>mpli|#uH;8#bmbc-W>?XKG$ripyQ$+}P?_MM zBSZjs92%-2JbrAqg9GTcyYEQsMn=MPWMt0T60tEPEQ?2yJBDq&e}B#jA)7%dnrfr3 z@8IBnLt5wBGo_Q(ulY4$?$`Vp2;aiO*RQ?y>en?l3=m7X{QA1x&SJIEsFun{Y5)Dd zALjo4-zQ%*{+RJ~?(JV{O5fZNJl754a;>fP^hBeiRwEp*wXC2BMLd=c9_9Ae=}*1J zWPM@!+E3w|=B?Ih)k2}2Dzg;xrmS%XQpa{~qa7QCR@>GpzwoV}uVk)V$#i6_ z&xma8tp?TW*IxcYeROegRI@XYH@KbV-~Rrik<`?NV z0%x%f{8{yTt~BDIb7E-3zMen!mXCPU+p&N9cG&#Rzm08-jBK!|c{@X>P^{IQ&XYsQ z`D53^=GT7I;kb}ov|?p`$*RrG4xx%@EW@4>&73Kf1%li zx;&pGJc!pEi?y{y*-!;7)*8yrcT%Ws$UhREPnYXzX<%*9Q}zef04XF{)XnIgbk%N z45cWB5{49wVkl|dqe2!4|L!~QX0z>4QEZM1*&wx7UwifP-c9x#lPW2GUYDb=o5fSQPrQS+8lL0H2L`q@=ha|g(K@w7wx+C$h2T|U zwH|wvXY`O7Mi@+87@za%!1A)K)<_KW#twTmjdI*KRq_L6UhA?*XwSse z)i7OMowv67xkLOqGxA)^HL8_1m(dL@qX$?9ENb3XYoT&Q=QB%&=56Ki_P8D^*!RQgnlMYZ&CPlH7AK6RH^+Qqo9R)3+wx(F zljX3WCSuv#RvT6_{tw)-j&0C{6Z(B3?8Sd%)aq8_Ai2u%8??kQ}e~LsjcaE`7 z`Oex?V(e47lgY39bzzFgz4rR`*GPoC!Jao5^F%s}4#$|MHt!T66p@fulV?s(Cu4UX zZyg-&uid|S_tE-JG@UDE4_6i*FYg|fnT_g$<-=U11ZC##@}v8YcjD>9;nv#I+c(~S z|EBh8i-yNy$xMtL*Pcm1znMrLUqja!Hw3t1_p_TJH^k(mwG4tCA7q}8$kxy?RPldkM!n%AqiUfPM3J96hcgd!4h?acX1 zN?+SfWb*N~#Rrd`Z0sE5D)kb8EE~J=bioi5T1Xtk;qHi-9WJNpc(8Ea;a)Oo#cV29 zRcs?>K`&$u_Rx+s&d^hbduz*2kZUQI*j`&%xPR-`?aT%38f&#KwQ%=!@|o*=&7fR! zp2Pjnh0`PbOm{reRv!EC#nZm_9x0Wv`wRAfE?iq%>ivQ5pMXEm@u2{Oi5>_qO;(## zfTSGFRw|V%rF85NB1gEo+1h-1XJ=w~bmzgs%Erd##^zo!GXhJrH1@)|g3dALgv_qM zWU~1Kez!N!+uz^YHvl!lHLTIh?(X!kAF2`W;3-_68umT+`s}G8zrV>ZFfYq+I?VHY zVdQWNt{!&cWqc{MuS>Wt9&WSiM3K2iIN4K9o8!Tg2lp11cMcMTaP=P0S=o*CK6=Jn?r@gqk=9$!4T_O-9s{r-{Du)YJWxVF2$ zJ$C)&7hZnll@~8xnz?l8+{D=UTug-Jzs7pR`8@ltQU@3K8Regd3Z~!5a%dNS%T$lp{FMnJKTC2IHMV=`CL|#WMVWSUX&8aEY=S;clWlo_Y*~GVnAW1T5kwau~62_DNquqk~a_h zv3M+=f{9B8Xu}dTSJ|q>+$lh^!cY!WSL07Iffm41p>irMX!|0qoY=knushZ zSg$3K$-(`24SO8qjYmU*P=dUu1gtfRktihW&9&qvL>Kfde zZ$krha0ovcP*fTE;mV55CiA3GuN4!~DD+a>8|yH}e!770@b1s-pBkIk-_l+!$99(5 z7^Ds!X{C8xuC}JfXs@FUTk1fVtRY-aH4#;vHTZY5ZL?-Wm&EvQV84wLF4k?HxBq zv|K*9eqAW{1)Vn4?jJopKIn5=MGos#pufkbN*wsSGO@auUbX~uMn*TeY__GPI2y$2 zQ1omvldsJVi*|1i=H8VWRV>b)!O=daNmNv~A5{GO*~zo%Z0amH4J_?$y# z^;+YlcNJZZwFO*q=m9&+ghlUesiYKzjugv<vlkLcG0hB#eZ63kYBa^}o zJI0Z$Zs({CB)i9})xNP;baCKSJGG%bRLV%3R_>nmd+Ih=jas3IKXAcK*yjkHunXBx74o){@oimc!LM znvBLXd!tTMqb!eIF*9Z&Qz?5;phkM<>60f30CoGgMzLf_oJ(@}or1wDp|dlmLiUBl z@BI8P-N}~1G-wO^9_-|&LbMoPe(=DM?L#lVaQSr5-q_P#&Zc40luE3uF$Ka#qNEeE zD=<8|aO?dK>a|8gy7A=kZvOE*Z&mE4&zu{qZ^dA{yp`op0*8RSMVNtFETjf{P^;;c zie9f*i`k#}zF~`O@p{5EQw{qro*r9?72%iR(u}!q2><^dt-v3orz5dzOJuCq;F#^& z>mPlT%LRk4zm6uV5#i5S7t$pv^sTov>ahH2()LpG7xCs_W^|)2!*S=Mcu@iq z;Va6_PJeJ_5P!J}Kv+B5eh;Z-)^Hrxdb*fmPRW-(TEX8^rD(+)eY|*x`N1H?0S239 z#~^N343ooZ)QP0jbNe3lQmOG)g8e3KIw3r$N@ieEOy%U(fp$#? ziJUp_rb*UTIp~6u(MPwI(RcA;L$Rrr4{k&aB{V)UIXTjAQ7|xjr-B$X7@kq&oundj zX5`ehYhEvq6I0i(Uq93D7HVK9O4$ll=xWvAnbmT&n!vcO5GU z@e!wyK_(f)IXZ3_yrKOC&(pm!kwYkANFtTJr%#DN7=@r=vl};UBnyuoi7+wdU#{1Y zQqx^y(>V+>fQlO#2zIF7?E(>+ldT5F64{m2Y|Rdwti6_9TghhYHRk9MPclc3C}}dF*;Zx0eufgBlKp?x-hs6@@e{ z%3EG}`g%{6zLR>h2EE;7=LHJASe-jSL+}UuiIQt(RMnyGqS>3hX^DupkQt zmEcKB_v)JSsIWD?UCxddZbU--<>jQ|%Qs1P(;GglU zAxA!1;z*3rSfNxZ6fKq_i+F_6Z{o2(LrBMu;^bhBj91 z9%lW`B53@fT|ESD?*zsm0j*@tt<9hC1Hgo}0825UEZ*tHCHfBz{44^O2>>^cwT=oA+JLB^J`!67V9rp2|M$+e-!Vg9&92L>*QZBUOwE@ zC`F&%_(dGb@QXK|MoW#xJ#fCj<*hwkymwDKWsr>xT?b7zAb$YKEEJel$)KP>)Tosq zvMARKSW+1^ElhqyBY!hY`}@N^9+H34Z1qd_w%6vCu1OWbHjTNoc))kZ7^f-JZH zYFM3FoC{OPHF-e*So7%Wjcz|WnmRG@^rO#rOSkkGZF`ui`87B!(TB zR0W0*Uw!y4%b0$WR6C*T0S+K+9hjKl7P+2jbGf%{n%3qlNRAw*$IgVa8i$7#pK8QP zDpgByJcC4u&son(*_u;6A;S&ZH_7Jd#?z;b;=-;{Qg#-!`DT%O%KPU1Qje;I?Uc~N zyw6uKd1=8^Fg$pI6+2sZO3qqVZui1#XxZz7#Oon#;?fQ+lHhT`;W7fJ6ns~Z9;4W@EQ+?({gmaR!9ye)uyX*??MkdpTWhN%X>ak3$z9%FE!5!1@ z#FUl8N_IuxUWt(ySs`29RzG|q>2gPiS>u?ip*Jb4^bzN0c||FgBc!Hr=r!C&{~@06 zB0Sii%k^_AgnlYVtC@Ime9%ra%ub5hhDPIu6{^h%l0mp9hRqnfVa5mE(^V9B!ek%>_G0COi6aBr;`6Dlz zzhMygg#kzMPDbr#K5A4_*v2jZkXL*9cH*2pZNKQqxU|18khz<3u-j@M9_wp8W>32= zrthWg&Wz)NHaI}Ic4%(2g|=hS<1kQ#)uZTeh&q*^X)%RHMnWcbts9cT;y~-?YMR|M z7gzU6cn0^6o@uq=ZzdFxkW0Z-D#-DY<>9SG2yT6o;8y%jhYeN6vw9_aI6OJ1=uz-E zk2iLcd2nf|Tuqzva->|yt-}q`(`1cz_yazt!)4|oo>~JtF?K#&pM@(VlZhli2aWkl zHASgqa(eaR#bHzV-~oKv-P+;A26Jje1x`}c`w!Q10`o3@woho19j;zx*~qFbbP7#= zs?TL6>7CWhWWLgfc#LYX5L-s6qQwTR68n4H4pp2#mW8kr493iL-fXV%W|dXPhC!0a zPEYx{>JHx9sdBE#scfdoX;wC0SR|Aq4I|ga&rK&{xyGDre?KK! zeUq$}DMn00F$55n{e6h(TrfROrFwe6pe?bo*BF+4ruOLed+&YtBwjG!Q#lsRfS4ml z7R)Ztc{oaAR>xD9E?yWmSF@`NlHDbiH3*Hw+};NB61NH2s~#BuW0n;y7F{R2#cL7- zpHC31-u}}N8%+-M1)uSe{6fb^GDb0fuy+aH2otBLd!G*)Yht-3wfS5 zBzA~r*)~fZjyL#hHcgJtLH)Iakh2bU3fk!Kkg86NjUx=WKxb0%vooV|Et5omA5~R7 z%;pa_DOFX?e!oH_N%625fFVl^Ed-fR)7jgEgBf2}+05|f?tbt=o!r*WuCFsQnC)HY zM<7FHm6F-%QcpI^yeV{Q`pm_dS1tqs;{&~umzn8|X6d(*S~-*4-^Wm>g;Ae~zr3@s za1X7voG4Y$&Xn%&7o7kJhDrN;$g->7~;)l`enm*`XzzP%*-8e@7CipL^KQpF&bF2 z6^mkhp}ugJ<3oFa-4@FHcjMXLgY^6DCX3P_<>;O#U?$9_zrhnZ5Q;~O#Hrd%VR!o{ zy)F>i`DyO5-)nb(f+LF9aYG_|m|(LeQT6+SUMrJ5!n#am$55^99)iQh^sK=dn^Lb6 z(H0m5S|T7hBuV6re024}14?UIqru7c=1+FXfpv}6vz?!`%VIgfjAG)3L7_K*8mJd+ z28LNf6s2-}3zR2e7+kel2@2IStnyxrHE%-UQ#S`(vh9ATG#8J_=Dt&tHy z3^O~CFfrx^K&2~0!~pFH^mqu9+$4#EdG4zpY(=*Z>hJ|pNaiDizQI{t*0BFUjKE3! zITw5MeuB6!oIB$o@rMtzH<=jFXndou-e`7tDwC2Oy{KWYV+&Q=PL%9+M-dWp=CxX2 zUaX-9!(WTg@@1Vk#38#wR+3*|Tg?#WoS(U_U1N;G@Nl~pQ*G>@+h!w@KZxMYW{G~V zzaQNPjGTW6w}>F9LYN1Nz!j#A+MN68S{#NqK>imdh9DyC86LKRT1ZzAE@#sb3G3<2 zn>NP@T&7a&+XkO8!NBnUAdLUqy>s_8r55vJhCilL8aab*33Jom?wm(t?LGq{%q%7{)t6%-^%E=c$=_)q=PU*WQeRjGb{psas3xz9jI~Jq(6+a$Os&Xs+l{PjKy-< zd)Z>iXxt@oD~w~v2=GGPxKq`#v}Ca^FIz3;vPJtQTdh^=7r*8yo*qdJo6Wl|6 zlt0||uQ0B%V6~~%(HAaVIptUNs)^n4ow|JGm6?!Q+j+F`aI?y`Xf(`RW0;N1!gn(h zXGyiv(CiN$t!!p}=Pz8uidf!Wc&LrnYs`C$D3?}m-T3z798@Hp{(z}gS-*Yz?s{4F zOuhKh%jW{JHqPYF4TBQuoce~MMNTMJ?ogfJ!^K4>>7LXE)SksxTtOh|d zQh>lY-}G`s(OI;ry`gmWoy>NRqeN$rBFw~?({z_X!L$fzc&%of%r zR`FUDjiBV>JD|7g@p9PvbU&U!=IJ;b9g}i=9rt(Qx$wx-z2p0*dOb{3Vew%5$JsqW z#`k;d90wJKYHBc*gwqa{9H?gV5EEB`F_mEwtkU#Z4EVyHCNo@|@SU4CPuS^@v^Gb)h+R8>(0nT>vqHR_PY`%yj#6b>%x9CnYi}Xy0U1(1ePgo(DSWZ*;CYp?7vvZ~zVWmVF z_dwE`s4;T+^2v9hXWZP}ZREZET38kyKU{D~dnwJ7DV4^?22JP8JGiZ%I(shRzUtCW z)J5i{58nNNc?;B@#UYz&4gHntuUxz+idq*Ex%+L0!?VA=Gw3TC8mWb$-8kh4RnnR% z7Tfg%Lr)qbb!Mj{VFRB0FyTHv;Smx2VmX`s*FWjN(f9VB{MVUtnw6eCdw6*69DVR0 z5P+q&)kvxr?iJj`UATKegU~su?EBGwv5j(Ai^W8u2`O~B%w|Kgn#RxFeq1mLkMEuxR~jcU!2=$L&1x|VGA(2V zCIWh97bc95>6%O%dz@<9da4bKpPo8>dVGBB)Oq-0S4(xlWRZA*RC4f4Je6LxYj#@K zL4Rt3ZD71XL`4Z(IgzX852Fq%SB+At4RDo0D!O|6!|y)W+)TjiC@;AO&R)23=9J6I zOMO%JXWBc6N}3bzzwg=E@!X8ZZ)zO3GO6**EKidq(h})QaQ*c!5 zH#R-yvu)cRJrGUO17|{Z1$N`a&E``x!}<|7j!1}t1s-nPRZLo*S%yUD(zvE9T)(a; z3*@DjG=2}{B0?|R)joczAF>o7ZR{=df+;6UWLzx2J^em;UkvS$3*>HhKI1l9p)fuZ zwK0cUi3GL)OLNKx1_;;(?--k!eET+~7cY*E%{@P#gt>1=-4O#(GESC6<@&-)O?c8;z?pz>YOuDe?0oiT;a~br5wV@XosWlc* z?eg?=`8v@A$9Jz>{E&fK4>V`qn(@wjwWTgo0jZb6x(;h%{0gsrUESHEE4M6^~;jmTm|)s_(p0 z)uid#O|N%r>m-d$Aq_KPw+|3HzTBKHvjP^nwY9lf@$LmS6ma9Em&ljCbTVI;V}%}q zE0c^HhQ0harAfuwYsys^bWwm?cHe(h8UMb)I*l`Ge-i6Snh zZ*HNeC*LqFn1bA91u1e@oRdmglk~69eg7*K+|mDQ@~v&RcGBC_Qzn{cl61|)t;Aw0 z+(a-q0gBC}2tv~>zsWlRL9ZA4CGMohsByo4oIumNJZF0HWMH5?F!1Dwp(#u~$L585 z&gAt*qm5|P>owZ)cVFjZJ|~X}Es7)Ot*iHlxN1E&V!bbk4opzo&MjDmriaAo+`_tb zsF~*n$n!(SyGVStM1aVnrEJ}1tyZ#}V3i7mvc+61=aqUnZ!nQo!i$Re765$qy8Cs|sznVo@yRe9>H1l}1jNZS_)4wVd8il}bL#n^+-;Y~%Ae3CWlWEz9LRD2=KV zkg3$jRzxc(R-V{2e@*8J;1m!8m_=g9R#lLy1}{tDYi5%Q>MJsrSiHpq08qmazzjmV z%S&}$0=HKyl_*!w*CmOsS4#zhl42bYB@x#1HA1CIg~^g@+BFqP*90P{%+H%>YH+m% zry@mcc7=M?tWtxR>mtRwirFI64H+5bi&c)6i-j5|OPpLa!aYUgP~#cr*UFX{f>ES__dceMs1Kv;k2PdRm%u`3xCj_%;{G=3UPbUR>a3TeEBtJ`lDMX477rK-i`b)>UZBHA43SZU5`S9o5BKuPC$#ctOuKv!5)p41C@n@yRs7V6mA z$<0_V6xvj1vUOsgMP<$kJBPTbkZ2IJ4_^naK-KqjTd`DcH0q_I%}QufJKuiNT7xCF z+1#|=k!5PFa~7wCQ)N_MmesBk`DX=Dv6-Z>In?XGwBs1kB#foM$Y}v6jJ-e>`FsrC zisnJUUPOY?asU7$YGCt`FO&%<2&7TdL4d4sLkrZZwGy7J*Cm$=sBj-r@H!kavm1M! z_mh1$^M0bnPFVa~v7jYSt{F%QNPWVgCM_-H^MH7^-?-E{ zjf+$5H9*igMsqovRnMf@zOmNO{8q_GW`IURM_Ft}gA}U<0j;!ZLOr@C@L@+8KbHAQ z$rWVhd^;sx^Y3T!4ktV7LJ_JJi6_vNRr0a@{gd`XRv&`jx|K-6sYNQA&w&lDaGKX8 zp?$duF)6iT3O^kjs8+0CUZ%Fk#@>$h_Ie?GVjE0>YF@no9-5A)JQi~ zXlg z#=^oz-i&COni{m=E5jaP%twT#>)tR(UBtw&VJ&3T++VO$bRgG08;XGfwf`R&XuC!L z004La49P=a9#9Yj;F3JM z6;K#LUsp*GWl-NXLKEA}k7$7&wiia&F_>m&V7Xn1wRSyr*j>11AK-<3g?IJ?3hgia z107{;c~-VnS}Za&6FA9E=Qnow|#k}$Dp3+ zndet}1?i36gZiqkHd2u`N>ToeQLIf;lFd*Cf&m5y2FeEh*Gv{idjmlbZLyh|nXf(@ zLU43nI1b}yHZzH(_8Y^hdTNK>Qt1{im>}sGx`rMoRhk{oPD|O@?6L}_R9?xhOUyEQ z{%6YUCjE!$SG+j(5|%BzRE(#5S_BOz@q`$Xzeg=9ysD$#)y;@93Pc7kc6HCobmsVj zTW{0dlRw~D6|6G2{uME1bb2OwAP8|D52~;`Itn58PdBKBdc>{7OvEetN9q#1eKxa` z{zwf~u#Qs6X<`L;Ds618BYNo0CYtIXnMS3~6F=uZXcB&?@DCMyu}TB!HqpaWd`Gnh z)QWr5ekHJHTZuRQUT6FTzm9YIC$YgFbt?WSo3*px#@V6|Rh&3MnR2)-^dYi*r5=0F zqxR_-XW8!&?n$h@qub1nlM%|?(>GC*DM8#gO8o*2P>%Xn><@aU!<_mEUJW<6G@*ZE} zeszlc9oIUAF5@3%orF913jaB=g5HGe>)#f!N9A|{Op^t0Tt^ayzki;!Cq1op*H0@5 znNeImGt11(%uXT*Gcz+YGc$8yI%ej}F*ECCTJo#xRQGhhrmt#x5fIbKt%}U5S*&C`i`mKh zY~n-q`uhERk$3qr-)0}*<>!2fUrKyWk(Tf`eNR8r4E@`mMQ)@!PK(_M?gU-s9(GUY zYWI|TS~t4q+)KLIz2&~4JKVS2clEOSzWb$KcYlqX_C&p-{`zV(F#5DU#(jcO#wcTy zG0GTaj507J%F3+9gM6DFziG#0zg0_NWfjqN!SXNLpobm3=>|ZQWZjnJQ>HPlJf7qE*YaN~^U-Yqee*v{75MRok>(yR=(J zt4;0d(CIouXX-4St#fp~F4kqbTvzByU90PLgKpGKx>dL7cHN=7bhqx&{dzzT>LER> z$Muw+(X)C>@9I6huMhN*_Up6yvc96P>TCMCzCmm5cu)b9vD+m6M|rMnP`m0&NPl<&)K^Q|+7Yd$33D%G{lL z8T2IBy$5o8a^EfgRqngtb~7M|z7F~!=vPp6qo4C+?&bU}2vX5ru`S!_?JQ)^_A(Om zFBgYAcc}MgVC=5Wjr6^&KGYFuR&;gz&5B*Ya(m*>+qWU%e}h@k)x;HZfI;@gqb*`q z`r36CIXvBl`tDs#{RZ>v-JZ%nVHRXBHLD@b8E~%oY0rV?x41nO-CMrceVbzOQnM1` z;xM4aa=QImV1)UN?%QP}iet@6C|3Rt`{r}z0b?y^NvNs(DbQ;E*mUl+ZVroo2uwGB zpi6ScR=()1A-J+{Tkhm;A& zWxj)!K;OVOjMK<6$d29{Dj}>bNo)~=o|bl^O;N!gnpqvSQddt5Mc*XU&ng5HMppf6=t590n(@~=A1c_;D+sC z2boWHkkm0RlGlk;_ac8}IE&{=1?Q8(G&_e&*g4^r1I$ITb{LT+qP|co^6}gw(a|_ZQHiGYwGkWzgpDS^{;j(-EnuY@E5_L zvRkd!G2BlSv;?NcIQHM2(}lZ(@(ke_K0Z@;o{!HG9u)pENJ+_T;ep`+OL<_9Wtdx~ zGEa%BMV#C_i$N-Ps`V;ef6VWIg%Y_p`~`K(3eNK_w@YpYKuerg&qo#|k*|wHxp}~1 z$NbXPack-^8yRXNcjbl<@;9HeOmZfH@^ax0Hs`|B$R>1hvOb+Yo7PmfwkFZS!2t&0Js#T;{QuP)pl zlv^ch8r-5;%_S?HlzLT#upc|~687==+IynEaO_T86AOFgTD=)Q7Iup6P_Je5H|w1i zh zGHi-f6}%*>URC$G)W0CPWt=r>EeoohM!6tGpeGN>IK$X@8zxB?g)^<&1w@+v3G1D^J(s^GOP2=?S)|(zY zMj`9!t**VYWm3<{z=0SSalK0a4rr_U&*o&FaGuZUBstrFzKKS1mH_>P7XbxyuEUm@ zF|JHB1As%KX=VHOtIQ(xevsKGd*U(3Z1LU@H!d69lUbnNrc8(A1z-+ItsUIFX9A$( zai?-;!Vp}jd#g5e(^oqWRI@)u>m8E*Oub&|+pSk&y$R`;)Ekz*I9VUfEW}`>Ejd}i z25=q(%Sg^hZ9CR!KqqOTfp4+1o(k8OZqDs&bHpMciM=@;dXoadFd67X%|dOrRgU8$dH$@ddx7})xbe)rVIFo8K3Ojsl!%V35B%UMks-?tWV9v6_~ zNuH&KF{X?<_I>g#8k+uQFpb6){fuuJ1Y4Df20F{w$_P% za2lQE71*CUc#u)1+~k>JTA6;#w__N>Rx`{DXPX&m#<0VTH{;o3CYvej#mG19em*H> zCR4&1o?yjNrrAk+PD$%#)|9Ye=1>XyMM?WdNjtlw&5_!DeNIOh^zb`;Y>eglp2rDi zoQL(yPkiKuvE!#b|H!iZ5}+$S*)sfC@>_e=c*(k$hN_w%s)?fN;#HGG^@-=7NId2F zr^3}d|IG67yJ-lsWH;3(Ag!nG`_{_j+?C6@%gVW{A?L1+oV&Vu;zFKrp8~-c;Eyph zVuV@``*()575qhQ2j4@@(&=iK>!(#D{r-iFsG(!?0r2x=UWH!(et8r>0Q^ey{}a9u z_>J(qV2#e(Z!N>`r1V#!`Umi9;lBv~0{Fe~pM?(rf3RFm9z%qYnW~SWDKiK#VZoj} zFwP?d)YiWZfwmaa0lA<1S#K(}FZ0~YvLTh+0e_5fW|S(FiyWmB8C7)BF%-n08L_iyaI@PX0k^0EkiBYn-Ps|&Jg|H$1)7iem$o8 z2BPmRrGb>XS{n+dysD9?y2gA1y=Y^8004LajM4*a1qmF);hFzF)#jmWjHd#D@07ChilML(X8CnsMvy+?6BNi) zCucXqQPb0Ni#TEZrO9cWHoMUVlQ?H~VR{yq{AaKFLvL_<+rrY!Jnq?aqxtpm$flc? zmE$S30cdr=0gZk)A5g#(Hh#*~6Rao$~JHy&!Nw;JUzLf%if@AtfO_p`Os>(6Z10 zIKNy=+Yi&Y4-ernJcZ}*5?;ewcn=@p3w(ngX!J3ZcQBH%Ok^sTX9javz!Fxlh7D|C z4~ICxRk=3T=PZ}F6?fon+>871ARfkJcmhx189a{{@iJb;8+eQEb`KxmBYc9-@CClY zH~0=e;1~SP%mNl^@s?_7mSaU$W>r>aP1a^z)@MUDW-HpNwx+FXGq$14+M;b{TiJHD zlkH}EfgA^MupA?ixn0Wchh!?g~QBjiYFklkeuIZF1Fy<~6MMLd|2Pn$IdYEMPU;U@T;fTEtqln00Ci>(x>=fNYlz>69)Q z9%i>zkMv3(3{SCNt5KSy8OBVuXthd~OvnI;A3=I$P=;h!Mr2gR;F#ZH_$~B3TdW#l zacZc=t6`R)hFhWCsD@cV@f|!QEk9aJH<&ljX&AuVGtu&6{}%&tbui~K4!5c zw#TkG5GUY7oP?8c3QomoI2~u;Oq_*_a5b*M9qvE;r?$!g# znBzWTHiZ&*E^X+}YPNeuC;GcHy&24CCfi?RTIt>WJFr>=)<}W1$^siO3ic0SgJ?@v zS+XqbvQV4cyKU*+Ce5$b>fMv5ZZsLj=n3ZD9j418gejp>6$V}$5R6{95T}2He3moBCbQf{vdG&1MQbb4S>ry%X6Gmy*9#3M(H{tRb4(<8$#o#W9z)m`>}OC;VWH38!gb5psOjQ_w_{8PB&ACoQt|AswnD;^nY_@ z%IT`Wa$QFj9yg@E+?1-lCFOi;V7YFOYPaZ)z%t$C_^Ipf#?k5WsO4JZQErTm+!ph? zGbR;%VK5^Z&s05>eD4jP`;Z>h{o(UK_&ive?!!ox7+qsuF3=*a&`S5&GiF)zOg;_$ zu5anGRy)o!alDtup_TmLkXKOiANjP9@5=!>x#;PdtGJqLxR&dukMku#L9KHrp24YTInP zR%?ycYMs_=gEnfDHfN)<(b>$naFa^+ZDL%tt+@;K(EnVkAM>|q_d66f$1hH+s)k~i zRbX_-=m;S-Cwb&AO15&HSjbnQS&-Ajb+H|`)BJ}~h&^~OE&l>0;q(`H0Zodv6#_v3 zME~sKZaErW0hBHOz6o*a=wfh8txO1xk3- zY0zT8h7&#lkeI+XTdpn#jM^nasUV(f%*)S z000000RR91000313BUlr0M%91RqCtis{jB101V9x%^8{*nkHr@W-~K0Ge7`90002Q CLkb=M literal 0 HcmV?d00001 diff --git a/bench/heavy-npm-deps/app/fonts/GeistVF.woff b/bench/heavy-npm-deps/app/fonts/GeistVF.woff new file mode 100644 index 0000000000000000000000000000000000000000..1b62daacff96dad6584e71cd962051b82957c313 GIT binary patch literal 66268 zcmZsCWl$YW*X1l87)X>$?@vE);t4{YH1mFe0jBE_;zih3)d=3HtKOj};a$8LQ z;{mKizBoEx@QFoo%Q3U|F#Q_99{@n6699-amrKppH2XhZHUQxC)koh9Z`96Da}z^j z06>M|%Z~L6Y&1qSu;yQl0D#8RSN+!)NZ{U~8_aE--M@I|0KoT10055byf;V0+Ro^U zCui_=E#qI~`=w~)LS|#={?)gfz?a>x{{Y1Z*tIpZF#!PdSpa}6(AxtIw;VAx60fHIlil?>9x#H)4lkwAf#?OoR zq}|UH1-_GP?ro-XFe6E6ogAsB_lMb{eMTseU$Q#8C1b*`2YJE2UbHtB7q=F#8c?(} z7MH~UQP;KATrXR0jxH^-9xhh?btgLZV8`yP{4?~5t>#`dU`oKckttiKqS}=0h)-TL zm0*m)Fqi`0;=bZIlJL!*^OrHroA}Fuoxd5CU8V%At$}@aT%_Z<7=JytQ)D?oC4fu; zC9haKy!Hbi0eF1ipxzXiPt=aQ5wop-RG^?s>L>gO@@+lUXG(XGZgCD!0D&Zs4~^e% z(4?{(WBL;9gTH%!vIjaaOL4-?5F%AuAhqP$}Z5*a}4%FHO z__`OOSOe6f$5}vgbHKxcU-p9ue+OOu{ZSHabi?^-WyLLrt+h>i_s0J8MO%1(?6KJ{ z63srC7MKwg5YmV8R^udkjP>c;o0jS%3s1#VZSd_ZMMe}<_%<&|(8tdaVsob9SlD{! zxA!4>pO-DKVwcU1_Qs8{!D!x(rP>~w#&w_8M_z*m4KGu9`d7DfIq*xDA@Pot6Re`h`d%{lBo3am-vR=-J-SO9A>&egV84q&m&9c$A=5 z%sfs3V4GByk@8gn49E{h<(XwIcWcps58AEdX7(zpG>h`7(%)_eh+vz{k!pm%BiGC` z_=5Uzd3aO%4=d~2*uWjw8`-E&TB2z!BU(IgE;XDXw1NdI?B6(MBrV0BsbKgOQ)gVq zTiiW$Yclle$O3+`9mkU9lI}kdXSxZCVc3#pUpLeJh8n71U(M+H_oIWzXjf>?Ub;nl zgr}Vj|2|%YuvXf+F+N$AD`H8>BgpF)5=3ZV&6AF!QO#3~-9`j5fsyJ#B#%vv4OtoE zoN*Lf4;gCHrm9!=;fkWSwnDPm>OzFyN{<}u3vWw{2o9!32OW3*>roJVbmjZQzlG(e zE4}U2iH!Q@$Q{J!?*)q_&o{ma{Zw*#>>xizG(K?ovKtF`xdX~MyHu+y&V2B#8?UA} z3)GS+=ALKVHi<)w-QE08#-CNleh`G&y`sLDidTfmrv{gWy`!r=i}Q2v#-<1h==FuW zo4*3ygV;zyKBgxN{?HQ@hj_U+#I$gm{DHH5VFhB{&2 z43OeSH?8bW8=avoZjrZrTVFiF@fH_w@Xx3vrm3WK)B*ir9HxIFotJ&j?Ql0|_MlDW zFAFtz22CtP@SyIE`u?GZ)=dVaum({0Bk5$QOjPFeR;d)dg^tAMWb#XR zx1N+SC{!SJ|LgCF#-Y>9V0n)&ec+ON<`=rB^tflD@PO&5dd1P!f>fx9N5?Gz0tYaF*sLZO0G1fGI zJBmO(<#@h+D1mjw+HK82Tc@$VtNxi% zE|8*n7FS*<*b%&+mElheV^vn-j|^j#B3O7EpDyIt*oZgUdgrVD+nieQ%oCn z=tvim?Kk=%r6-5a5KYn{cSN(c#);ls)$rs z$>2WG89OeQn+$u%7X^jeuG!?UPZfU>)k2TT`WR;^in+~$27hvw5jonPA>KXZH+n=U z-HdTmV=8Uz@-l4RwROKIHX;)pYhnQ{-gA8{I9_E$1U2#W?a|Z=G1jId8eMbFB2X74 z`tO++;x+F#xG;{RF=LA2>8C&>LFr85=i$Wb6{aFrO{Wxnxot^AOP6_d{#zLQ$rDOh zmx8VSzye=SUQ$IMq75xI4HXEA59Fnh)i7cO!uVPQIAC%WY#)85)HZ%qC7?%_55Ys0-MmZ(mFLWpk4!|Q@tKYGc|M5aQKvdmMnP?P5ZYRPA@UcNk!m! zYM=N4>}|X9#ViD-@-{OA)mQFn9XsaS7Y9(?%-TyN$#35%!F`M`?q#}XOl%HVhbwjt zCD9hq%W@?Vb7iv9#SQ!^zs1Ahj*)z0u^gwJ$gQZK>LPl(dju$D&tWsLLmc6KaS3pr1Z2W;DVO|v_@95?1- zMM>VRwrEw^(?(cgn2z03cSM3w9re}A9@&J-iar~ThaWK;6qbgl9R+_nN+$C===>ifAHw@+mVJro54y_ie`FBKhGpGJfp{7P=$nYHDU85j@aE6xcjU`6`n+UdYu z;k~!=E%i><*SAqRV{@mB5+D#ad!{z`YfsejCwwfQ^S{HX?u$eA4ev+DnZ3iM@r`m+ zLRU?0^iI5+CYyk-JQeAW21GoJm#CuR4}=^0OawIPmLf^Bj+NP;px>mQ@ju91?hU?A z@^6NFDk5sm}DxK#dVoV-L%Npvrr+ooO@;l>4Y7QQ- zdW3cE{K)ywgL|nTIL7??f&XRGbC`}V$#eCsHr>w^yd7NU`;^EDQzm7ei3K5D%lm`+ z_NbNiy=Tm2b-)>1W5&6%wKhpFs?&aw_c-nSe6$OHn}oFM`AT6SSBsV1dD$@{#%ECO zaiNNq2pee!IeZP@I^E+v@_!MPqwA4mCt$2(@-z0LcW4k^>Eo>KuM~B@sNL97E6TFl z1)4A2mU)d_2f0GJOww_Oc7q4(mz@Oz)qi8`E+3Ka*{~&X^P|?>khUM&hA! za-0+zz-fA;NCpK8V8&lEAj~kov2%5g?yoc=(AvRjAGX}w(W#TavcyO)!zy( zBwy-z_~z`5c)^_D?7n6Bk6s#PY%1IH^>8*9DYTP!!0{`s;pmNC!t)DD8_4WWoHDid z?f}^jLEV%i`>#l)r6O{$EICF?lGtwyEIZdkw3-n3GcpRG_G3g24WI%{ z$9%gN{?t7?aUhEagsS=Crvcft)p%O>j4XBnA15^iRW@>yZTAu@VcFtzH z7Pjzcy@{m*?pI;}+Li)cVqSjK+o9$8<#htd>v|Z!spzHUXXhL2&VAWwmO>TOz#2F* zLKBCt%h1UO`bcZm61+W2uiv-$*AWdy4%*JD#Q%mVN~LX?P?L)W5)_vf~Eysd%ifN06o<4DrIb zo`rgBZ)aY-Er1H(R(loTgeRKc`aiNY*ov~%7tdG23sIk0S|&| zI`ym(F~+g~Z@5Ak*#hsXsk%wMma1o}98R11$`-WqDhE~YQA+mXDy(Q>%<^37G)?hj z+kV3owb?Lm^=xvbUF5qgnn3}%i9dP8l?^m`M069e_$gUu1G~Si$r#Db>RW?Xxr1i3 zU}3e66CnC_N(ryScVhF%p7!Zs;o9%K&6EYZ3oRWH+nY=r>ML5RV}UVM5LU3?&R^3c z*yGY}>NGt9GBX1LpI6=voIS=^Xvm|6n<>r?b&=nFv_-Z%Mm7gp! zSI@=w{S$c{z45YBG@x~lPoG6l=DOXaZPZVlw2+33otl)CnYysT!Y~2K-zCtw?30-Z z+j4f4G}f{>C*}kX%RUJeNc7CBpe@lm@?8X1D0HyuJA7fg9{pXg(i_i5pHz&enAz99 zWY3;MKvcgk8C$XtDv6Yv9nuV?irv9MVk&VuUm#O*IQgealiPX?FMl0-hGD?jlbT|; zME&f##=f<={Z30HDUKa?&A?`}^JL%n$By&#!^_LLX#Hw!dL^x^o6ADIYq{oZ_wI$f zBPDV!nu9vX(9U=M4q63-<+v6a=_auzKjbnp>~RgNBkd^lU158+SLy@%Fg|_0De54h z^rK{5>e-9~goCutBe7pS^s-`ZU@;qFoc`@|Uwyz__~mA3V5aaYCZ<4e6g-K3SmT;h z@it4I5vQD*>)Q*Fk+6`Eb4vzkclOo0&Bf~(wh1Wr-GBRg!}h;jXKPr10(}{2!1D1% zZnFF}mr~=Vjw0b47Mu_oQ`l$EqB>V3NVJyRF^Qh4r|cIXJIkCIu|e32zE3D{>g4&%2EEepV0ihrnN0lI*h$OJUUNEJ+f5_s5*kt zmQfjSrXy0*UszZofNBGqi063mn#*;wW}5WUXL;JVcPLTyPpbj}@IfE`+)C3>1iy6( zj@xZ`!%VYN^QX6s+4^nia$?ubBc1sgz=wkk0rC;u!2s(j`^WgqwSUq;DL&UAG&u(% ztx2nnfUn_>ZkfgUW8E9g}L@NcOjYNW~s;MKbcH~h0cpk{_HWNdfijblYz+h2z03P3!{w_^F+Z{6(m;mYyc?e=$R~S7W6r)rmnhc^ zWDY8UgC=qhHXPr6E&p}OFapx)Yqfq0c|%ScJfo!5%;`l<0^eYMGZSctYCudt4D;QS zllZXAwPzujN)eGld?PN9>@xFHYu!q3RYPgwD4^+{ZX+R4pqMO?|LJJ$&|pqT%}z(2 zws%$GBS~6_4OO$4U!NF5sidchXC;p!pWSoPq9I=D?mxL{Zt)>jI<~1LE1+Oz;S?N` zsjnlQu+gxjSKXW_*MzO^o#-wU70)7mu(uLfuB-0YqK5E?-e-<1nICGBYERzbSu?t- z1J9I?E{8Qu_&Px*?|>1;GK>itJ}M{~z2zc|c`DfS=_rwR>wbvoH*rc9Ca=CCq-4Jh z+IxAat$A_beud7*u*t20_~6e9o9BJn_Ho1ME|LyR2HWhz8j>^3+Tpo;1 z#OP$C#H+-wZB1(eXsCdjH8Y>Be8*l^l2z0+y_nU@-|33tBxzRwJX*%MM2dIi{#=IoY<7?7I@41JDTMl z|9r8UIP#bjPm~nR+<#Sib?~q)WS#taf5E>&WYVfkl0n+1X*26v+XO>&f<8pb)x%vS;$rMu{Rcy+BTIL?an0i7iczQl+`d} zYwfz$K@_rR)TcHqJ%uE`{3$4djVoPQ;Hn?ilq^IOYxj-eWN$8weIZ>f`k+fXTv4XV zxXVid5tejj=$k{SJ|9C8d_7#uwA^RYU!2J#ik0bpw9U$J7X!0I3Cu;srmBFnZmXU! zu!~xOmIrL+e;d4Fy_Yn8BTM_b>7-kEqBb{bS3=bJ-^ zArybG{xTk8B}Ff%l0yRj=@m6PP)-nCvyy%R%;|U!{>YrP!}BK`AZ-hu>ElmSHK=&> zEupkk&(|o!b>Z|PcSs`6=3@`isI1|I>wG~8HCk8BNXvslF zb2qb{NmN5#uR-97^5i7Y3#R5QJ74sp0$r%yKu?ed&+ivClsUAJZB~9o<~Q6;L}dp| zgxwnq#X_ME*@s7~+yMyT#C>E|gD=JjzeA}2|Gfez+Cs^Y@3HvO`zi4Y z2oH@RhUH`=t1aWXIifih7aEhgjrV*`ZHH6adZ_+ar&ZyfD2E$B z6i?p|;Ppl5a{2F&Nn$CdcSjfBzTQctXYmW#oGbBx!zpUKne^JrV-1O*A zte39UNS;l(F=?FNaY}cPnV{;IWxW<}kbX@ieFQx@krv%HfvG%4XlKg9O7V3+8>hFt zsZ_-g>;fy72bHS{qLMf>2diP8r87W*IH+%^i_F?^Vcf&!KcIFoE=h>1+K_QCN5_s_ z4q#&aN9h^Ld$%bf!>GnfOUhgzxE|*hE-EA?ojuK5A@-75Y%0`lR@w?JsH>*y%6tpk?I`Tui&N%cfoY1R<> ziTCSG=en`fKl@2rmFUkA)=$oTW&^T_;Wp@KWjYX;@4#NB@x@!36O)_Th#4Bu=8*MK zKC=NwyP~_@yce6Gz$)Y@)bwMU2i2q)9rf>$?y76AlgTZUdG4W6;#_}FOmo!8WcV9? z=tw8waqML#6=2IOVbtwANc83v@=3>m-{G0{Ny)8;7W=g^yEtkE^>yoYbICa)d+sE5R5 ziLK%3zGNws91-!M=Gf<__>gK>e=N=WaVosXzjacH1QSgiHH~f)O#=+XaX|Rsy<^PZ z+N0swA*aXW@XXfN_}RltlFet{@n-5?bzS1KAire&KbctG3g4A!B3yFxfvaUB0=oHU>7e+qgGXcrRVL zaJBKZ_7?3UZ~OFGJ@XP}4U>$LdyBF54(1j_{1m|hWwpUDgwKj})AR%%l7uYevu|w~ zkBOe1zQNCkzkSc_-nZ%ZL1wYmEb(6jIMU>7Yg+K%!3ogU`%s>|sEID}D>#`ArT1Xg zY3DbPR2EFVq|exiDiMyL{;h7zv1OiG^7pKqV>Nm=z2UX6`q@g1l92J6cc+a@kZm*I z1)8d3#;T!<7VjIabqo@eyQoJ)37|fr}Z$3c;pZLeiyn9}` zOV#On7kX{lo-U2XtHNsMgs1tS-$8(nM4yol$L~+TU_|hSo}B(aT+{L@Qqtw>&LoFVZ&5)JcX<|jF-?{%dp72IDUzD0V*CKhi2*j^8=68STUt&br&iVp zT&BuNStFLR+Z&i$V42R4;X^c+lSmq13oJAc!GbaOKI=Lp0;>JnzgjCjp67xP4qg9a zdR?9CTpwbT3D8_T3Xu@c7&a8<3RUEg#=nkbg0w+8cqc?u^a08zbMm@Aj|2z%eC+0^ zql|__mJH(p_&ZY9I9)`pcdL0P#sxFdeI2ZfGdQl2{heylGP}w_1jKaz3a+xS@%id) zUXNpAXIJ~d{kp)a&3uJ>KeBkF0>+^h%Q=^5J_{f0O-z>PK22*&cP1cXs-$D9ble+= z=~ByXN64k!9VyHHrr*1R(d9x1ns%vcOG)`V zQ)GPJ#*rwA?dc^MkkKtXkNRsa6q5~dJ6-YNo3j!4o!ms;ejpQ=^?m|rTJiRsg{K^5 zM7|8=3C>L;f(3o71q@ZNtzz4^=Fuj+G^&VWgU!g5T&)PxJb%5;=Q=oV5ZTVL+>-dx zhhj@57~9XMJMd%ThH!JwXU+%2)FLU@1Uk_VOT~m8v)Dkv{-tP3(1{W3lsxylL+)Ams{`mFkBBHjmQA(dV4hlVkETa_SZqb@%q znl$-FD&x1SE-}P^LFZj6804F6E=n>Fjh=Og^ix@pmsBrc;SD;KvAb}^#tTq|XnPVJ zpT2sEeG7j1wQD4@_IZCbtQ+%9$cJfH+nzm7ZuJ_=8dWlMMAS=kbX_atKBec%d{?j6 zMT6`Wiljm1dZ+vZ>{ozBVSFPAiexw&_`jBDO04g7sG4t^{7&T_s(;7^OJkPNAk7EeNPJB+3 zvnI>9baeSf@IPpZWe^9Ev^W9*!{4{x=I31$Z|j8kg4qYeZnj)K>zaEC-uPo>RSdLE zc5^nm$Is!d8}Ln;f6P3~vKgXj)_-B2uSEdl}Se4P3<09 z^@w?vWg%xH_Jh8+7{G4dT9PLFNw#Cn%B3(2XpP%XOtP_Pkbs9kV z$Q-3kxGQq+N6qKq^axgH)t_hF!-n7lva+Iw5CB1Z-2D814juglNK5g0+ch`iw<~fn zBWiwk;dB}#ap%1RpZax*IFkCNe69y@xvGr^2Afgy<;hRjPZ&4)J9UVSLbPd*Li8;& zj#t5gx0#(>uO7y{KHFrUSnY5iQ0@N6dsnw_XV|c+=cU4sBcs8D_UkF3q_a)o2PEyF zbx!;+GWe_i*JgQHGt(zo)>&;KdH-r4|K=fgzy_@zMbL|azNlnsLrvmF=z&Dr_F>=o zOyF^3ZU?9&s$M>Umkl(GgqVraCNJfNUCn%G@b_nHt!Eto8>uzL_&DQ#UKq=` zEOCp8rf~adZdQ?Loa}6dzb~63LkY2ne7g0#S%1Qt>FW9*{J};0(eM>Uzxxx+Jc=Sw zNbr5M_&QPzoZD-!SVIZ2uWzT1bQFtWLBLeutjw; z$)QUUFgL}$slTMW_j9~~-^lx*3A=|OsaHGxyolndAN+|6ft0Ht44TqVo7R95)TnNp zQPr`<3|W_hYJ{+oFnY|oclbRNqpM?1ZI3)7DWPW?MC-KgzoKB4o$cuW)CsOirDD1w zYu)U^(;c3@$p6$5*I$McZuo=gLiFH--|M}MGVvfh^UWW1Xk z488s>afB{8n19#I#%Qg?lGX-cA!ZQ4>3`_FPJvUKpF0!VF%u(QnO~)ezL2D@n4T!J z^TLk=W9ioU>M>iMaW}C(=-VESzwQY4UB6i(J)vX3hlOv*D;9`p!YA;Jo09ZALCS0x z``9xT+*}tmjgwkb^Ht;=)Ha!3m$Ej3da-!tbc8;59KaUhVqo*5YWio)fbPmVPBcs1 z+E63@FJJHMU>@vmiQydDtYDEDw-;?c`FlUhl)EW~JP2Mw#)x;w4hND9y52uN1_s_U zbd_D{vg>WVjMxf{SyxjYYv!SG;qijw`Avz%TbMSMhM?mvIZsNd^g$c$N zjY3h7e`WP_q^S_Dy4f4fx-AJ5imltL_1J#=C9HNs((E^m&@8SiY?#ONNoMOI@>V{| zzt8Ato5|}rgG6+Vlv&z@Jl89_!mE$lDYbygNM$O9HcfPZ8)J&)hQ5)GD`$Pp07xQF zz?AEtd23`xy<1Ka)JF^Wrs@gF){X)*UPwPU%$$DHY3tQ6>{Qy( zI+f9}N*VO;dNX^!aO=whm+vK|KxofHRE+nIq|`WcH)SPb3^IW+jjZ=GtMEFhD9ZBe*g4qo_y3(B`47t?#J9n|fsREt^6+oZnYE|O>VMg+UqNs?XySy+NRDe)ZhJ21Dg9^xuAx;~ADlE4?&9K+FY zLY4OquJPQc%9&G=agFz$sVapHEv;W~Z~-$7(71afdx?2z$CZQEcPm+W`E#ptJe_EF zNs=>4HZsJh-4Qn(h6^Ly;cS>|l~Oy?Vb**xPSqlKMvd+md;Jbp5$L(AjPu#&qk;SC zAt$%M%wCWtQ^L+WOVlob&+GL-GaUCk#gJ^FLpSQBfr6E<#a#buo+bMG8I6`=zw;r!Zr#``Y6%cj7(T>{_-N(%43famwv!j2H*;aMnE} z3GVb9&|gq~f{@+%UQ0=%)KWoB_Ja5(-oZW5k!XrVeL$#1)yf?DPP>*7gtBIkO=2|+ zk~!gxywqm20328+c`k!6&&}#+`iC12b(fR~H@v`kgQjgjkhYliLxiiTJFyoT;X5wY zcxSuxt=;A-b_ohLABKbb?a(Jhv(SoLXjJ*6#VgC^Io-IMR~6zl(u$kjz>u4tzd>T> z`OWiT@O8#+O-b3Dj>Cs(NV8K4hT@nw0v)>J!1}~dmAfC&V&Zcm*7+tb&a0Z2n8`=t z%UU0!STkH%} z$Gl|&T*vRGX=^F|=5m3yDO-g-DW8gQsZGYyk=GWZYos0>I=7MG=mlij%mv9*cE`-i zOfyQu?`5;Xqoa6A?@IAVZTZ+GKMps-AN9#tA#vufqKlEtZ$svUYH7;UrL&7ymjs2h z|KJgsm=GK=mx9x=_IzQv$QXlsJgVYsJOU@iW2Aue47K{Mnr(% zls~)ux`ll{bGrQkeB|0MiR_WX)dU3Fd+OF-Ge_2T_8?>Be~_-;ZvT)7Zx!wtQpoYp#(5_i;Y-fOez&Vj(Be{*bW0QNL}yF}Evr-^v_z zz`DK8xp-uCA?9=`PCl{K9OF*$Cm#5y5;OM?SL#}a#eLWpBhNG~@!M4?Z$4jfC!=gm zwl??6gY&C;;dY!;dQ0gQq^Oe0;%f}`irfoFJIxYe)A6OkkC#f3**Mwr55;81L&Q#h z4uWd~D;nFML_bM6Oc{`GjE-N8*A4VR6tbVinQavNGX(AZ9ne1yAqUQbT+waTR?Mf- z(1^OPqjl>UaH%1+UOZPb@dmn)9aTIjh$&r~avj7?&MSZ7ScL*zE({Z&cFZKv6Rs=B*a|GANc994A_xCl+Q`(OY-EcW-Fv$LZe zgIZN8U4pg4tAIGcvk0PLjwhoB7aq8huIOyN z`E5b`yf>PB|DN`}Lu}QTO#It#`Hguqc>QFXWJDlzEvMW0boIu_)MOBy(+b7MyFJ?xJ&+m}|daP2c&rshQpR z)GHe(QM5MdovXb$_%7Y(vrNMUtr4Yjn!qiQA=ixG3GH;1o_+P|hR5akMmE-M*Ms|i z1zcxF_VRVeWruX?W?FoDYr)}h6sI*;r_srH#qEkqTOKig7dN0^n|V^>(b-Xe>rT4A zPq`G!qtB#EBi#=wtL+upix1#Ta)5CyiF1vB6@sz*`dEY%4RsHD^&B9-h4mg`dY8x7 z_qZ?9dG$;j%KN(2{QcDTEikCJ_Yp)=duVdShqLMXqUZcR+3_cbp=_-2mp(`Io)J~S zFAl*AZH*t-rHT3z-tb6K2+XM0&3jcV?|oi06Z^?-6K&(f?2Z{PdVr08yrcFtJ=|C( z=PdRx-g375e6xI@43*Vhqn4SE;3Yl~Psq70Wa5WZ^LtC`1H@ip$VdGCBQf)3_^>k4 zr8Me`cr1T*IO|7V`=tNF%G35Z>{6%pImj2~0Q;yab~CH1QLk2})BHu3Nua~R0DD-H z>A@MT%`-#?+5~~3RlX7mc6-3{YnmIpgXfG=rKza{J>QoaRBXcUsfJY*4uWc4>uX>f z;YN5AT$9%>?^qn-sI$j#<{O|-pa1DOuQJgXN#A`IctZ)`h%a1qXvX{lQzj*xYo&<$ zIb$i9ixGfSF3|K1a&;?++Es`CP>1Sx_`Wq^a^Se*?(=izf-dxS^D=3}sYHF&%Wb0k za~X?P_o-`s4p?eSoIb(zv`qwQMo`-^0!B>BB+T+wm3*IbheA#Hfnr))SZBHSAZ z4eS_C>y$B@v{{G>!U8*7kWc{peLy0kp=;NT3SR=uIp1x3KEH90sVP5~g!6&rn@eo8 z)nZ&OldlPLX+U5!^1U@L)6d%grvfNvT7d~YvxXx0yJV+JW z>V$;VyO-ZZvijEI@THu7SJuJ(+inZ3f0%=5tYhab7?M?1VO-R7eYBwUm2FEiVl{W` zZsI228CZIWoMRr6?Gcg7e9e7Bm3{3${S-VrdSRM!kyYZW<<7V>3@JJj6#^W}Q#Oyi zN%4)!(CAN#GA-bbNg-<&troPLENSK6__zm49n`e(>h+4tVQV~{ntLxMDPP2`Nz9UJ zH_j{E7~py=u6`1GlT;;)+-1FmlHe*=2^YZYYFIU}s3x(QEt;e_dp5GsE}GS;Yjfwh z7WJAw0GcYg)F&#+_2+-yZTA@Mp9OM>drJzdj~zNDCUWcYDbb~6$2~;H&5@&3F5uyu zlpzWm>RN&8xG0O4^Ei0%)0XknL?Gpx5$Fvbj zrjP@9?#yj#Xi7eUK;y80gEP;1%|p0ir#CX9vKy}2+TlYwuq!QV4cjgh&3SdJ;^KdA zrd5@meTVihq&d?MrBRe1Lvi)Yf8#DlpkWs*b>Dg(qi}a)aFM=VoUPy8)Vd+T${eM{ zn89PbY{>3iDWyJGZ~XnG9eM0MKSccm4XG;XWQ%qRs+l(S3R&(59I)|IoeUosjNqhM zul>F@wJs_|#T-%vEua08J4^~3u%sFcdd&PM?upyceQ%p7e}XY*D5+1vJLo>+gy`M# zOXV{DQ0gX?5jtyb$ECyt!sTCR6s&`L{8?GvqU`*yxEA@yX5<-_Th;O~_UK4KL-(=U zgY*m8?FK(arYzh(_X*T2IqCB>qWd2pI>l;Cdf9nyNZ6I0^fkMVV=UN4-YDjfAN*9y zuGA&CPxFNRUGl;+pIsOao{pxAW5)x0aySe1>=7zh9G#0S{5Z@B+>?cFp0qknz^GCS z6Bl=f@_agDx+q83L8Vgy6^e|c04=289z#@%)S~3u$sGQ@#O=fR_;%re z{piCv?e+oLQf;nbp!Ya-t1~tpDHqL@F!dX6y%tVVF(E6JmelcdSdJpCHb}2;}aa zkk@zgTc?BFnc!0xqF%uxtrDf|_@ll}db$DzXKtS0nY$x)?oyw_<^k($+OZp!^JV3t zqH5tCLsBDTLEhi8`b=bhnJ60o|M94@fr80rc=m=vRMl{963-HZnm{mC(<||dNX8Lw^k|t^_-o{YXWA-TsoICH6tPD%?-ZfK2mpkDK zHKi;bEQ?_1qCcToxpUrTS(0QyRXrj`DSAkSu&^t51+cny?fdvNZgWPtp5Y=K{br>y z$ueJ`_-D~ANmmIx-c6(N{tjp;N!Vgxu`cM@hv^ve=8GF?zR zK=wg!M(GxY7zq#JgTlCd*rj^aIc%A`z4T~MeoS~-L$7tAqO@8?D`jRg6LZnH{+iH5 zsqdFfY~M#4AN`&5w;;*w=>1y3etqDPDNNQQ&;*UP9xbpL-8+bRstIN`Gjz0UZ(J#` zb5V!yFAQ$C^iF*Ib-~qE{BI>0DIP2a8KgkXn8~2JW=rs(roFg(d+xQ5{G~gRYcLP2 zvpxnoOKx#=3VU~tZyiKjK8;euXsnS*G_BjL2ozE;;ozoD*-Id}SCnyDq>g6J?ac@q zYtQz3*CPn8_C^exl^@oW>{DwX=u~i8@NFfLedDg<$f-MYd#yOQ$?3lZ7x=P}MZ_iG zlJ7>8Xab@bK@qRtYOg5(K;I+!z-N9NsOl+j{(mxiPTW1=EDeEB&S*32c{p8cAq2 zL-QEor6gyn{fpi$?UZdOh8;}^EcDPo46s&;TWsLb**!d-^UK>_-1y-}Jcu(7B{I8x za%>O##Iwe=R|0O=hR*i_5)Ix4L6vT%0M7~P=zec>+bfO`jH5M3@8f!a{m`j4dquPR zH_iLI2iDDHSElfWyDqG48tP>a=%I z?|0#@f`xRF@)L76(_pQ%Z>Qxv6_p$PDKAYWr_i7m@tEFPv_LU_!9@=I=3%z%KRi(a zvdOJ~bDuJ>*^y(lGt6XAHu=?Xk)O;_{6Y>hK9su*UW{^45yDx#At2tg!huQ5gq!;z z=bqLpDqHH1c5Z~|skW)Z2r0{M99}}a3r3G4=*rc`o1JiVEy*8&!Ih^?7cr;?Jipx4 z{0FUX?VG?B)}wPC&QD1c#++01q;9HUv?#Tm-7)jMX=Wt!dmbh zpWusIE@O`jmu8<(HkOy4|CEQLZIkXWYm;jei4t+)W!kBf@ML|H#M>~a`_~=ee(Nt7 z5Lhu5(x`IZgL}P!kOziuX$zKO#1s-a1Cbh;&9=*)O|~Ff4w8+~ZmwOZ^Dz1y@ATWP zV$dx^85>bx^Tde_2v(gX@_Mn3cl{)0J=G5XYOBxqw>_xj1%gLdZBTu_JvfW+f%)lQ zT6o_EhwP?1r+_(RoXlrqNHAfIAkVipcMEJPD13cfBt*f=UozVzQ9$;r(#tyc5g&fB zR6ilW?pNAe=MIEn_5bBVvx}U`Bzego8U0XWPM`I+oCWeI9UB}|Nrep<_p#0X>{z5% zD8~JGTyqiSu5rgWKXX!=-}6uS-5Z-b|AZK}v-F%&S(6 zEPe;|5fF5G|7eKpC2P5Hu@ zxXbm|NgqQx`l7Vy%KtK|P9APXPkOJ%QcpOaCG4i4Xeuyhb$w?AR-fN-UTc)L+T(FQ9VOHyPqPrC? z)grB4n=O;n**2AA=1=Yq=_l0n9+A}L**0X4Vs)YqRQZM)FQPynYW>(j->PDH{cQA7 z;z+-c0;7&W{q09lboEzA?YUd#mE41DMVt~D8t3GsmyBw{%2Er%A${%Hx`|B`HB}X_ zb4WWqF+IsX-IZd>y^L-)bxC!Neb{|%Sk{5uGyj{FKk1Y63yBbEX9|}MiAnBb500$5 zx7VE7F)#S1oo?g71etXDHPL#-%0NfmLs!}NCqH}lU+8C*GAJsH^lDL>Wtj!_RD`?< zaHfiI*blCmi>&wQD4JTq$*Z2GuQTg{;sK5M-B^^eh|UR8=khTgXo>kx50V8|r;inV z!)B0AhurOYjrd+-SGDpEThfjoK7#SYCsMWY= z>P7YkL5+9PBB1LBe=C7)A={TPH?y=;=u%4D>q4$|kgI_0(cn)AM?EKQC1+_ zKtX`)Z&cci!uc8Au;pf$*HS*@=7AL4=I*WYUQyXMoirTQcf1}d?K&q&=6^RNvgi~4 z9t^(us$1rfxe|!T=JH|w3pv*Jp|}^Re$@y;eC*>{b4_#10U`K_`~zK|CXzznaLMSQ zM88*atx|VQ(@>+G8n~djt&3|BZ!4f%4m(OHQjz<96m0ixKXfpY-=2VC!R5^CnxF*( zwKtBn{gb*N-NpN|qeQR=g8@KpQXDmac0nBla4)}2?r)G1c2LXIoX%&_!h&k6Zlxe7%cZ#Cp>b_Z#CMUt7GEg2T2-l1VO(=3oEh!?bzm z&>D)f3*B74eq%kzJ2tBGupu3k;ayq}f_rR?wA!Uivbkqe^h;{{pyZTmMSYNUz2Mam zlPq15NX;Kirpnns63I#}cUF-qq?ssZ6s^~quu%x3Ygls-sb{0Yz-X6y!kiPgQxj;a?=n<*Vp3XayHTD@# z4+Kx|fC>H$%O_?rHA%z&Yz09}1$an>(m!E8bJm-s_=QF?#~{aET=lUZEd(p8bHhpj zbu({YXPZHzKrr?rBoC4T4@#lLdWUL;K;Ark!9`|;78CR+3c{Aad~tXIOpgeA&ZUi+ zmR2VTFF0z@#$LX1+tqA2=K&wrCwY7rOs`~@J&hC>7;KjywBz(^PV7X=KY0fLj!^;d zNU((50g-@?a%j-(qJH@$o6S?V#vV$Rt~eGx3rs4iQ#%^CdhWq<*{n)R76NFhMkzy2 zgK@sU(m#7#K)|0Wm<;q)zB8p{0s5w&D_Wo)z@`@%cpZh~--IGAE`9K=mSUS+>^$Xu zeqW8$3>z9&6tWFNnqJ{Fn?-b}uvg_^%?#7R$a4K>2Gf1aBgbo%X^QLwIP$>pKBkCB zLO%UxlLbl3sjL+HZNntR;+Q;`GOG0Z>jg zmlY&Wc7YiVVHw`nZ>%*#%7Fo)p?~SI=nfO28*T;G_pQZ!sD4_62;v~;%j#8D z*q=JSpA|d$&6QQqBQe9VjC3 zh9o2m;i>M00DtxAVHEMw4=N1Ew(RWiY8FZsEiB`*$`=+<)dQB(=hiOOK44XwAuHy6 zamDmm^V<^NVe~SilUnwr*1p}T=C(|B@1tT~SQ3}{otzI=k~-!pS9H;5pCu~&`THa+ zXa0_`E<-ZbP}YXe~ecQe!#dJ*3NoDRAb<jpsxKx1@jJVeo=*MjpnVj( zEE$NdEEJSe@?tM9E^x};X)+Cdi)Cl_Gr!OJ`%D@q_N}2!8|BRZV}VzIPC8Y)kO!em z{P`^`La-O-bi^C`km6*B?ZZ!WFi%7gX|RYiV}ZrEO-+!B^(3vWxzlZorFZ+20AI16 zsk3?L%H~0FvcJGb8APAmE^m4~a-zvw>U_+;8Ur`Vij3nQ8f~P81WH49EkQaLNWm1t zM7o0H)%p{oIs0dG`uoluD3^0?Iwf0T$HO77n?1>O`-8||n5atn!MnX@D_5(>O2uAz%5r!#A7&QQqQWT37#AdY44R=aACIL%i*Vn zD1kB+ac@8e(U6LP3w*FU27y+5TGSbT6Xg9MdctdOHFnfeh0^6c%2ARj7G}QA9~p!D zIC~01GSW-?fL3JqX^ZaW0#x-9tbHN>hA|#DYRNY)Wv`;MB7<9ZtgUO&xL38?#n?eZ zq9(T;=Yh;D+iyktMfRK~xWASX%nuWkI)~qU38o5S$uN14?kQm(Dnq;Q^F8fg*cg>TA4oJQ%ZRlia zmQib%rxv0jS0I2m9;|A*qlIusT~9EdAgoJq@~=lMuzq?k24_6H&Z7^>VHNKb(zxxh0=$Op<-76-3k7Eq5H35 zhiuHU{rGE*qK5bYJtPvH6!(UZpeL90y+hvpwUK~&!I+-uL&=tfRXk!4fy7<>mg0tM z5gF2*zxlCKh1W~S3>`rYk&WRC+a;pEAN9SXOy{ff`2gWH#@>(9XYxcmc_BIEiJg!E zP6c}dE~s#gXT3(@VPW28<@VkUawKroZ!OpS$FM`CI1r;~oRo$Ph;w5?P;}beNgZMjCx#g4!?? z!&LY_^-$vBc0N2cSQCj6NAI6f>7F|H2m*!)h5|37#U=ZoIu=U-3d-WF%34!MX#A=^ z%z5PI$)x4R;g^Y+YDSs6oPji3g+>0T4J#P_qWe_nY`>vwl9pHQlJRVc zPR1Iy(h^veY%P|fu4G=7Z5WjeSRsYh=RsxWXQwHi@)BLmi+_`^mUI( zU$+l*K4j(~_z?KfLxfLCT@_ytJ?ZMMYwP*yK_XV#d1PFJtFw6I1t>;5UZK!F%l^{B zoxcsbS~yjiQVGh|!N?pHqirr2u0JA1#vzF>YU>%X3OYaK9$z?qB)*g}h(%|(fe9YD z^$pD7c%k>HaPB?O#14wkq{Zp9zD+XCE6<@^w`@k1H=u5Dtc00Q~_-C_jie3UGaF zF7FBlP>@V|{o%B^XZAV+>uOr0)LlGr`=^`Ix6(8T`ycn%zK@%6cAl<1P3K*ujBRi8 z!N)~r8u-{Ah=u5rVTP>-G0~EN*`uRe8YKQ5eSA+7LpC-NM zR!QT<-p-KjZ(F@#BAk=EU80_U`f)b$R91 zh&lcuyf`*4ETc&Jpjx7JH<2{6}dyAD#bMhmt zPI(>Lz@=zngFxv1B>?~l6D4YRAPv{OE>!)`J2ZV~?_1<}%&vLDdbr%N0S-39S+h`~ zf(cRcP^+)rJ!-yW2ejKSi^F63JjdeYhH`?Z+b?c=;Xd+)FWpscIf$x9#ZzwLPxnvy z_CkH|4d36FMx5ObxicOgwbyScPr0L*n;yk+upRv37iF~9@2s15ywam9M@lgmuIfe! zs3Pk`TjHIXez0JR4AVjXc@(8l4M`^$FojP1_1G2fs5i0YmUVaf$sgd8zbAXYaBIJ4 zaPR>700;nj0HD7!AOJi7@L$BVUm!F9U;t2eK$t$@-h6HVfLYCogCVy$$YXoA5Y3@xh)+T_)!ZjoX`QTufJRt&hP{XVFZGdlq$*Rk~GED^ZXW-&Wi7HPzgu`!Dy4PQ3K<( zywFs-+cCOHb!UPhD7lO9((Y{*j!=gcgpO^J>OS7vRtGo$`9d2+9Y7 zHHKGd*OE#6pc}7nLfksM}n%-ekpXs9W2`}q5{ zEbEwW#6gl%E-O^p!L*8bGwJHe8J9zh-kzGZL391=oYs!L)pafLQvMO*Fcl5~V z8P%27S-LGoH!k&H^)dA|?d#{)$hY+~F5J~{>%X@JKrQY*M_fE_)pG$f?6K5069Y9Na~@+#nS z0P-$QE0Apf_%5b9FmC|9JasY(ps+%?<6pynNabOge{IbXu)<9LaVpT3DPEL9U^*=3?(8-QjidsBtc1Z6$#8Uo~1tuf;mQO z%is~(#lMW=AL2{?V^&xv=Sc<}$2v;M)TJqLRb(@dV3DdQd73}Am}nGQN9HMxb=G-# zr1r$_3ghMHEB;|n#2O4|ki^)E_8lfS%5?A_E;uWb<)9I%n4@(D(h+KzHG0J964jf9 ze~iP-T$|K1rE`k)822_FY67YVR2jiCk*SB%(5vKgHRNiFxrA~>_sa2^lDJ@Y0At6_ zrkZABE1uY5v}J3_tQ z3k2`W+69lAQDn;SpoXUE9k0czguLi|uSK+m(&}BVHRGn08((njr+{}S&5c6eFLo!{ z_IKL_eg*0Fx7!7O1^xE-L#Pu`Owj$;kDMWlry#A2&?Jn^AXJIyCWvGTnH3_{ucL5D zzVl-xtWy9vmu)W7NW_Vx6Y-4-0#ENeBoDx!wAO5+I`eAtbCnZg&l>bQ+t6kI<$TtO zH?c-Iag&77e3CQ?)tG~03O7lQ1!rbdYJrP|UV9o|QR$h?d$z9$g*qx)L#Q=3*C=g6 z=_S`pFZ3C3NmUi0<4JEoR%~S^pFEpipu1D z)$y|YMV-#VwdIa8CC9F{^FrIy*3q@dOHJDF#2)HHIJmBqU9sD`*M-@AG2c=TE(*jt zm{QO{-$;CL%s{NcjlFRz4>uMsOphpLfuaHiOWd+3dSTeyiTX&+!QS1byO%d>0?{8N zB@oaCH}>eW!#ZxUy0e%`^UCxa&#X-|k4!r_%w;oQ z(xIgY1P0$%akLD@E+c##$YY1f*wNGWH8&%@9QbmFDqb5!Be5>|&Z2kgepR|Vppm|@ zzP>&)Yp$Y&HsXxkLrOr#8z?XWw_+Mn;B2Je&&{XWp0c4X@L@d@eSk0^w-NMzrobJr zDh0UGS^^=oLT;wP#%fzf`go1iEbo780mSluHlfSw#md;xacA>VDUr_4jYU??O$GNU z^)Z1@Bv454(0gvCz|5HcHhoaZkCGFY1 zBL15WE8sgG9YuNgTVz&AlXQ&$II(fOm!2Y@tRSy=SLju8KjS`UK^)l`*NLo`tT8U% zU|D=1d9z;~n!*8&P5k8HnBb=2O*>FS5o#7C*@QZHb1Xy4BTr5M!liKVCvG=)arM=M z8U?^LX6X+BpA@<{yENYyo1IdlpJ-HpU4>n7RAkW)D(PuIug-iAL%F0`e)}P@ zF0wZj%WDcn6LE{eS8WHGoHR{ha49V_Bot#VlvD1LA{&u_l0-J!Q1QQN4_X1QXS#rr zg2+X9qy3Z)`|n|rtIoca2a%&xz(1V-JiIFc;tJdGwsYL94|b4K3eI^fjJ9XD*}nI+ z=EDv#tBFKY`)FH(xHhSlmhj3iZcjN~xq`?5`GE5<0N!e8{_K7V#(e z=I56iKKyZna&ofkn~JG-0Jc)UrJq*`6mV;IXx#^DHUv7@-V++5sMAstmb*iJda>x6 z(C@R>%bg@3ZO#uREUef2(gtUO6vur(Ou8S4uezfBpby(j=$gTa$6MA$e!!#QE9*|I z#&MsDa|pJ1U$n^}uj>$5h_I%mcmQaId6-j$6N69KAM!-Bh#v?OD&g*FT}Iqg+Az;r;Y+l zV48VoQ)MbOdayno99glE@g2}(W^E2NfqvknaGOAIXTFKq+NH z!Z7V_J?breAgSDl(|F|iVp$zj9@(5~C0b3rYN#PUsy33YgKLS5K^8B{MhH=`Wb%j> z7Gf|--&xy(c;HwXfr)Y*l00V|0KTIcl9chy_il%DC0WlCzm@n9 zcWe)LLL!maQh};T2yI3B@`dG&c&yxQ@vS)l?o5i}2ZF_lLpR1bFVTWou5F(4Z!AW= z?2>bnsezZ4QD~%dW%9E0E-T9CaW=Wkn7b^i-m%Kfx5(*3pV-DtBSS7X%wX)-0X!LF zw9O}}cZ$ASB&ZjmTIIH|&{h|oQs>9D^FE6k*loa-@^tWo3F5ewm&uGbg3nK%GaKn0 zbZ`bd-}1{t;fm8#QUPZRhIZQ@OaD82^48c*!Qi(G@x!&GkiMG?E~rHx7LXbRC(8K1 z;GS^%5w>%3AgucVn9PN)`Tu$>_f9Y5PYBcAPmbSswj@6yO7A2%KtcxS@PB&F0Lmb{ zw|Bg^Z*d5vueWy>_AllEMl=QoW_+(8Sji7uw4C3-tAW5YFAO*aiZ2tx%xg`5e7|=< zf=obw0jGGZMEDs-yrRB7AVA3){4dh5JD~9la4kLq0@&@;QH9Np_5F3+`v3KYHq5qYD-Y#wFh@AZ(B%ghdn7P!NxVO&ElwQJDr& z@A@T;j+)N3KB|P4IWA&@qbUx?2j{827+bW-S0;k)G4=^rfZ|a(60qMC07&LgXyy>R z7?7Rn5UA>qy&Mom>`~cnA?R*teHFCU3a?0>4L*{-f|499n>8BJeiK-})+cRM*Fe!o-Dq1WG4@-tk0yb(LOUO^sTAb~&`N$WG>&uuf99z;YaIO1;F6$h0 zxGN0{4J%HoPMc0+PD@(7Y{XfUspMLb))p(W@7Le;+G*kG^$LKRqFTa^2_lE+Ln5FG zH1d8L+|7!i=QHXnBx9$HuKC;OvU1^Z%=YoHZSfn;YE<0kIoKI9_DzW63 z!1EoK;v6^Q9Pi^CDSsq~s>e%yQB2MKZ)pI+rQesDqqFffFfoyRk-OgyI=HA|oCX^0 z-7rAT5NyMCaUnWFZTgQ58VHbzK;=N;LEQxGjqFA2Wos$Yfy!LbazE|MRbofLih7k4`WE3lp!O7+LU5KeMq#~fmqCeo6J6Q*)nzcOo2v?1pc0S z<_^m4mLcyJcBdiBxqj3PpM*53-aM+MeR*_Ulk37-r!r0TLa}OY0INEpUA5($bE{;+ zxq93s*JggsQ~1QIk#;`lyaup*zJXIriCgr`x*=8pyGdC~h7^u0l-N+B2<^#2$VqcP zvhUFh0N7&O`Is?kjoLW&+87YLAqSWv99hHA#XURBJ-O5)y3{=s-6M|8Bg+j!oHRsP zw=^6|l7fkRMMqi7$;w)$D#L}P<$CY|M1flxNKP^B#G+S<`OxJ24k*SWg|t&tYrB-? zW{Dow^nqAF**n4k1;tS*d6fK>X7(6h7jq&s3}leG+9{0 zAw$TQbYXlM3Vo2_vCnB0o|rl| zTvIBJz6|@Orc-#+F1^(d!*W1UB{rE;`_r-X#RTSZm^t2GGQEY684MY)iz-&Fs=o)v z60|CzXI++58biO5u04{$j=XV% z`L28Dc9<8(TXrv+AV?yaGNzWl2~SbqbvsX0)AiD4rsw@MEc}9Tyxf2FuB~x0$A6|Ji!A(QdhsqoN$Q!l7WfjMHoz>v1~X^8`!V z+_`Kl#dJk;)7+(EDhCdp^K0=a&9+B~c~GdpY_DVFPv62V`=DT=x%l&^pMbrz{(mm# ztR5UeAlffVJU>VhBtq}7HBde%fahmUb8LG_YG}aU;Dp@x+Vr55n4F}B!ltUO;*5~C zvbv6zu(;Biw7jgSilXGsz{>3U$j0b`#B$C25A+{!Y)2^cUp+28O`?PRbgXUxwH+Rp=!&`}1O+oK2-)1yFUimoxl z)uYrVxKWyG)ROLsu%Mwath0K)DXvj4On#XXH?;J_83dE3v=HKq1XoD4=9Hb$Q;KZ1 zdd3+E(Wg`i0y9pQ$VAb(B=x2wC{ygrdMe4e`q+e1?}1c@f7p6X#CVETr`!X4CnO#? z5mx{pw5L#-p_whDsms9uAr5hiy=4^Lg{KGWab_9L?oC{5rtOpmn1g}Ft#wSt_JjK< zWE(83ApUq*_&cPsc%h0sV)&iQv|H&xfNvj&deJjt*`~N@#N4^ZJ+*7%#rCUV+`?0oFxes z#VA7IOHey}rEGLe)G29uQu_9Dq{ti3MQpM5XKgIwJ6DqWgPhAPM^M#~I&xNFMufp? z6<5fE{{-*~w2^7v+~*f&WDg1^+1Q=SGourJOtFSw&g#q;kPED@!yV8%m_?BIx3xf` z&L*0h*_KXs5FfZ_uKyR1TkH4cg;Qg91~G{H+5no!cZ2>ZM=%GYempSRTHTmw>Z(Z) zgu?e-Z#_*jQp1!hFS6MX92`e;5^~37^9TZD;%DOu?+32^>>ouqF2QvLS&oD39c}jG zR%GLB=g7*1>3FAQjuQ`|+(78im|DwZ!Zhu=;TVPk>-rI1l5V9E!~PcZo4YZHuXJmXS&w)mN?gKZXn$81IO$5?I zL0YHu3f15lgTDAqh3)|+QEt*MwuGYYODLO!S5(XAbF-T|$$`#|#}2qL=0`jQ6X_3R zAowK&5IKN8Ukh~{tJ43(AXSHykRy~sBvlk}NXnP~sh}4tpw*lksRs>{ub{wZHkmJ# z=!D7Yv_G9LmG1Zp2!+OAu$XQJODL60rL&lA2Z~6gR;f3cZiUKdHD9eZne7A!iN)p& z8cTD;5G$HZ>$Ex_t;cA&UGum<9bu{@j~C5UplVwGqW=MxsQ<$R?`1?v^3^Z9(0SPkzN7z`Gp_255- z15)WsMw{VEjt4Yq&3fyha+Zt#zNO7bHO~he4yWVgU>Va1t#-TP)o>Np3m&)U{pC;v z+YPVx`~B5OP58g`*5IP##^}myzrfu;I==_?{L?Sn<||FHO|fPhzK!Oo9e2@ZN~|L+ zw`mDEg$s-2+EkZHGhpnsLDS~iC8pe`?31ot5ju}GD&42dm99M*JC6;n?Wf!qpIssR zw^cIUr;HgHh9%|&%)K~F)B7|((+r!~w&M)DfDkkd>xkl14cm|uRSlb%rezJgpcvLQ z>!_;cx=2)OBd)H=;*_mMdKuCQYct+o-4K@Jx@HsC^}KciKn00#7#~D!Kq1CH%nQeU zSPK{w3WLpHIoS%C6w5vi(+~`S{6~_FCz@fJ8*O1P{XmxeEO}v?eF6_HK?JPr@HLQI z(dUdR_C5ur#QO?+=RKBLRAbkR?{!Yjmox_|^&tm;a8=?@$EpB_N%H)d!#cY-q>Jz0 zP|NkQcR2)Y1Yr~aeiZHP{p;B<@7XXQ^xemf?2f%@7?!JY!5lCdO^{&WLE<9gLzLvk zv)N*?JU}7Q=nQ(3;cQST)k=^340N9RaqJuK+cET=&)bQ-BUmG^1+DGpShubdANl7;aGW9Y+k#XhM{sM}`67t6(K$ARdRLi;RJ zl{V~Rips5R)N==_zUo2WyL;BE61q4i-#Txz#z9FbT?y)}PW3ViwxL>~ z0mjKQuF?u(-UY`YFNuwkz8l)vIRl4b#UzbhNyC zuX12_u~fVy7mo``N5y9k(}9OWW*@i_Ghhqa5$W>YvVIv4Gfk*`Bd&ZWSKsFklsi>J zCyf?&By_Jw4t;lN71}E0(^hv!?UFZ3j~9hX-ZG@Lrh8F#=I@8tSMUg)zRnR&ZM5T+ z?tI>3>#m+OylvH11G)DM`qEhicQD|Bg4A5>3rByJ+cfd42nUAhYcday?&T4W6}Omk z_io_(N(0F`QLv)2;I1D-W0Qx~*xn1SVbJ3TkM7X=$J7!AMcAoldZL@ue+cKcBCbWx zjb0Vu^>SPJ7B|uJF7Bmte5+30MQ5J0zO=`lxqNsqG~lDGdqUgtEvrTmP>U829?}&t=p^X zFgqi%udmGVI=RN{^ka_`7E<0sz9Z8bxvz<6UlP>po)Y{mJPLN<tNU_Zh? zq?&Gsil57+9up#eYjyDNgr{cOeJkQX=rXJQmQ83Xgtm z7Bmmc^!eT_A6}~;H|+b!LaiUje#XbhgT+ty9N&J@_ujK+(H1CEDFsRI>#gz><~4dm zg|c7EvB-K_c!Z8ZdN?#>pB5>DM2C-2|6jRu?Qk3vLhz7LgFp9;2xaL1OFF8DbEEx| z;tI~SCEiu^yw1v2p}--9wDX=qMqOY(j9eC^l5Q1A%ZesX{xFQ| zA%Y$hESfd9d(R#v>25wqJk0-0{|u0}$!vYOyXhQWJXXHd{RQlT*kI;IPR<`Vf49XX@pRgZ9ja2h$IK#oz?;;sHmt?@I~6p^`Yov zcwPtma5^yBKVf#i<57d^}DW{}Sy?13A znS6<4f|>W@1v$}!5Dl*71A76{>bnW}rbINgQYz~l?4H_xv(v*|{mfpKUh~0j zm4?yiP+_cWbjrI~lyFY;k07(k$XP$=ymaYQSo^8h?i*k-%ta!fo{G$?l0XvG_i&%W?PSYWux(ykS_}%|KMp@W z<)&~0#-;knw0<3r3(?4 z*Yk~A<-_*ij5(y=8~wFrlVDn7#5uEM7rMVtLaA5r15}AHk^OrfBAKiM6fgh)-lOCD z&H7^W@_XikL;v2u=;OD87$vSjj6^0~oNGP?#zHsCwg`}XbtGWr6y<`bC6wNJSQZHB z=4Hd`3AY}};pb=k*8^dg-aDA80aWB68r=a=f`9=k_yPFoE)Z%ot#3cMHK z)(#DTfk>>EZ?JNg4@n$~F(@#f`yaGsP_90EIuu$^%q~e%(%D3`sVU<`M%ARjG3-N> z$|{aEN%NnLfUB8Uqmz28)vZg3XRx$Hs)4D4W&4g+a^CV(@-rTY5i^t2oI4>gJ_0q4&m$)+_V~s+!Qg% zQj~vGk}}1yi+vn{+S<7_eanl~?kS5?GRF;$0v+W%3O^NDnqt=#u4-ac%qpmsw9cWQ zvPdmrQ~9MzkLHdoE1GiFJ+7Eg@?nvCA8Vnk!9RKx?7_6bT6!ODX}w|n2*FAC&*ZHZ zkzvJ@<~$qGb41zZoE}l5R)_B#yf)F}hMDdhJ5lk6(eHpi@qYeGyYBvp6q^qL9MHL{CrS=~6qy`BE()|<22ZF%{4Gy3BA zw)~0t;Q}IRBBCPf2_zOc&X?u_L`?9Xeh`D$TESJKY=mkE z_`yj+1g%J&A(ef|yM$y_q@vJyn6u1BVbw!^JZinfn=!lJ+;V=js_ehDCChWin1ykx zuEw@?imS|LA@rwXPp+;sUg^97zBxW@iD=hh*@J?+-d6)tHmgjTDY#>Pr>vAM$0|Zq zl8UOO5lzdS#$2tuD;QV2td;{;ijL5(SzRkWheWRWh2FDEYA3w5-leT(Te+9~wCRbX zyWA@VyVjPKnZ2}oGte_&I&=I|1U2$p1pPi6yp&OK}iH$00JPf z0%G+6FyM~^n)Kn>VXK2ic2Qp;z8T9hq@`s`0F<&VMxu>n>qRs&a7TDg5}j;XgEk?r zA@jm#M$!&Y@gAn$Y(E9RE91q;DU{J`=>^k?ve9gzYla#PdF!%A!@Guf6m`oQm6f0* zg)K>*QeCCci_z-|X5v@I!H*{HmEN$WAs>1b^ZoB@cZ4!0mq}E3MIpZ z6c!<4grR2zoR!8(8Wlq+p_6&W7yR+r(b>^2@jfxfu{6=AQLk~kvA(g(@DPbKiv)_K zjD?LAm?ato8+{w~9)&BFtu-%GBA3q27u>(ydtS$1zh6UMeP~)#6_^^I*D-9mTs6E3 zTNYPNKOU_@t({p)FtB5&hSijqz_lnUk(ZS&qH-3e4b|#dI=XoJc=hw#?m4m-dNYo+ z9eDR9TLDaK{5S_O4#G-;X{yyU$wQ{L1_${LX&zIm{6?1D5|nv6%C$XS$XKow;*n z(UxYN`Fdu4A8hjMW{$3h-dJfep2Y;uf&{9YQ&LusL$z1aHV?J8+dAdZ$lY`?M!2W7 zyu5dHz1-M%tz1nU6ci8wK`A0BN)SNC>uy`Ii*Fhq(iQ^0-Q_J*J54W58$VagZftIZ zw#c~+l+KC)!s7ru_7&}(77DUu$asfDA{CU^=`OHiD*b_>=9SCdK z3Hl*~xQ~U4E3J35m(RDf1R3t|YFYWa1kmNFfD*z6TVHs~w#S#Cwe4}tW}L(0_ipA> zABRQexw{|-`rF|QA3FZo)4v~EpXtJl*W=#U`>=16{rmY{W7wLt^ixRa8^?Dv3SVEj zmdZ()7ju9rMREf+D2d8hLt|}sS2?)i?DRA})6v>hlkH}wr>EoOuq^4-t6}-9+v}w| z?EI=2?N&&BXQLvF#!%!py=HAnA$4>WN;Gw3O@P4eIGFep=lyv%f)*9@Sc6P{3go|T z4+WkU31XHjohehcJK0s!^ZmZQ{D)${JDYjx4~+hivK%w=~%&b8TAF;M2z=)q(3=yLeG2(*J0eI_(4NfT{dzIl1YLgNjOL3s2|i+==U-#6lmGNjjorL zk%2|V#fl6Rdu8Qghd0fR?h^u2%rgZ7 zj5=DoP8Oq}1`RdqnH#5VzFm~rnAiqk3BkvTTEgXGMeG9wAzqmBw zJgy81tn5Pn;jsF^a4>-`igxs&hWZ76i5Ckw2-f`D6TV!zkPlL|T6=ly!bu>&a^Wl) zXt`n`8ECp}0cLTxULhRmS17E^t!dk3?Avt+Swxm#D@$GMZ@IagKST3*q{b}C)KX8+ z$A>R_xCmRN1;*QfJuV^s0JmaAvFLMXJa9$RAc0;k|K~vT7(1dw9(oA!4}Rl{F7I z6YVv3c{PWtPBnXf2~V{~1BvG1B?{X8i41yLMZ_#n{$KZZ=-t8jF6i{hNAbkurZ_coZ z3ELc%166D@o*>ab8c`!uRNA!OOOE=9#U2uTv8IINGi)wSyR9fJ_`l2S9RrEDU-u=l zD{E!RXELNL&^ChjDN~PGjJhvAI91rv9STm&BxYu?U;&WBNEzQqReUtl@bEUp9b1y> zl94HhXsL#h{mP2bWYpwC`@s~@m)!Laqs>G2B4#N!|1yDE}j~>b77}PNzdYxbT zL$j``C>9lenC{YmIdL_kG;>5+yjtLz^;6bxb7J2ZPCYF>_Swnm{W@h zffoE%GIRfdL)ifUb1|dbSuqiK(a&lnmBn1GHcRGj{=$M#yzH0ha`PBuQcz|D2JE{Tx99@?!K>3C( z?COjCP(C3hzhfd77@G-vDAz+7LmA^xJzJ~4qMe|4&C+^Tv|iGC6Q|mQy%c$e8YIvN zcu_1^_f`hSNH9d!icp9mmn0e*^fN0`%c)nPNFkNb)zXYM|6v+Z9b!T+o|u?0Gc!98 zRIrEk@g@~I;%+TE#!=?nuq*haJ;`9|sOUWt#(c)xRt-^kqDWp26?I6lR)ucV>`QH| z0B%{eRW6rnBB_MZKxKq={pa90*hUib5Gn_Gy8|)`t*lg{7gPma{k=yb*TJ5YhS){O zubtoR)>HJ2rN|c}mqL$ez+G=w&A+>*QrudOcs9GM&lg8iZp}(|dJC^C7dQBBpU9F= zWn&gvYm`r8;@OWB;+Qf@nNYU&^A;yWmFKr%1)^u*60yke3C`xdruu=S0Dn zHEWizn&MMs0c;=xKDU6<%uH?D_=wSmDOQa06=>#dHK zruB3@d<+Z>Iqa4^?}sTiIa{{hLgaTjG6CDF71wz)nZGk?3ECp_iTSsI#_6`np zeSFbI79N&)XY%x`TRu;eZ9#nq<8DwD-ax6TOs(Y8%v$+2TcS!T9U^hkk0YL*AkJuG zr$7~j(A-?@IsAJx*DH3NG!8 z(4AC&8}}|-wPQU`nwQbxa5@Gyl-T;Z zdfEPoLM&GiX{bEiGG#nV@o%WF)=c$-^G&B8(xKjl6=cX4UwX?X{ z9onZt#eH+P-izWybK*&Yp>YVSM8l(C8`@f%QO)>_vS)U z>NaUdNR}?W;t`Z&)m&W&&n`T>^*KV4C7KSm8{3__!m6sK?*4y@Wyz8>SS2>|{b)H`!gYk1?#iFvvqUh;x8F-j8o6*bcc4`PaZ(5y~Y+R^4 z4;wh238#OaeJ(6I1v_m_2?{)0KsdFl2-!u$H9H#1NJwTrxq@_k8{5dvA?;it0ys1K|vv>J($ zgxstXc?4laMUTr^nEnEytd24@ntmm{JHa20d+HAy1SIsM?)w+}8_ea1a^nrrdyOdh z@-bfhK(&?9fbTy)AJsrR08>JaUsmDeCN9c>YZOG&l#%0bj@;A2Fdb3~s4G}tOfHt3 zEwYR=-i4sTxDe18Rty{;>#Xw>Z+wm?xu!i#==6YIGDMP&K4lO*;vp*>Uh$0CMg;tB zFvSR-k%Rw(K5W>;c1dD0rZ_PwqBy=cdOyS#92bMsR;(-(2g!?t&g6>{QY*pGvfsU* zm}y1!yyh#dNA%0Z6=4d_w3=rwH;QL2$QnK~Hy3Gx3D7S`{6ybE>jAqK!vI;)Ir4M0Chl$znD&n4H0ILVjmM`m11Lrm5HqAtm$cHac=sF#grkL#qq#5GK(--$SUSm z;ufi_V*lo6^NGWSd}8e0XY2VyXfEUu<6?@okV|aIx?HQdM2Q^Aw z8NwLCBx83sG(Xo*cnsF(+6iO9PDp4~8PS}QIhR!XA7nUsT?d=szp0Vp>kaS{H1r%PO)+z+m z$YdZ|Yb|3Fo{}x;!nht;+5IozH{eJ$fZ&#&_YU3?W|!_p70WAYj*A|#BoX@ zucy%j)&)wSfj;$E1|VWpNYnlg=nloy4F0Q zWzW*TgY+LD?TV&x0kBl0%q)vMxpkX?Xk=k>GLcP1BUufeuSY`uQJi>JM5)I`pi?L` zd_JF_nusZ?+V^I%GKJ#BM#a*jsRKX@f+ihX2rdSrMqC-yOy0pV(1H1I)0ig-brn`K zpN_dk$3P~BRLZVSqN1f|p2cuvG0B-4>Vf7s8IP1s#zG+@COqm4T3V1TqTOCl zsn+cEVW8j`0N9@33k4i^_wKz(pGS-WTpk~VegVvT#*vJBLokOifUUzp-E=u1e_b== z2Q!YaUJ1*SLqiVRg)3LC__z|Kjn$qGW{#dOU=5L$<{ zq+aue^(qKWK1*L-o3lQaM)}Y}rKZAco}R`qOb!Vp{!+vjr%+T=i{hM-B&nU6zUiP2 z)CroQ$z|Z{R%I0s=PeY8;9u<89iBN+fA1G9O`+eXk)J`Xa8FLU;V1TeR#1p1ov?BL zxA?DK_5b8Cyd-ETDiVR8W*p~$g4Y3{nawQ3%w_UeaM3$6V~*#s$N6|w;1c@O`G(DDMO_<2mKjKVn^Ef_Z&wWk!TfY#I+_D@Tf$kTQMT)5!c1W zTC1*Xb^BO0?>%|p!i9I=?%u3hUc7i=f8CO9bLZ7}7vPwf)7x0Z5I?D~gT!Wm#y@AV zw74vw=!uH;C*;q0!u%8Ks9S$x_Bl@|)}Kf|=LzNd6XxeUkywAC{2NdF20rnd0MPLh zW?)NeYwNCd>jE!F>m%3e^g50V>CKCe!^^3 z@;onN3>QxJo;!E0_jJ!IM^7Bv+p@tNR~jzf~L);W8$JD78omzy2uvf zh;LsF-I5lFP^~mI6Us_cp3sJ3%9H&fQoD4?1Sz@cS^7&ze_5pME*Jcav)~h~t4jZ8 znu*;f&!0c}GtS0ApaA=#Tlg*jIsRo4NCE+mKiTMR8`YcBZ?fl?@0 z$0MX}Qoe|4H>4GWK9Qo*Ju6U#P=hp$5Ndjs@<>%81zJFSqmNl>B>Z|&=@cn#DXv?w zN=M-TBBc&NH~gPsd6L{7c~iPjwg#z9q{=X@$5c2TuDTWke2^O+9v=6l1S*xgA!9e$ zY;|>YN8oRW|JYwY%3>XguCA^_T}PD4BlS0mT2hmi+SghtqSd9e@ZJv2>(=S70xbb? zeuIJlcLc}^)MjJ91{e482OnNbZWh<{+k(LSfl_G@D5pgt;~OMdjkhIosf1Yxd-i=s zO`PMzgNjG)v9U!M!zdyi6j=8JN}^xG`g~sWp5FZ6;>89yfvon3z@B{>Wgw9o9wRI3 zL}}|T!uCmJI9S5Wg>svbZANC`R$NieWHREW_Aa^IS#Sxm=)9>43OzLVdXBo5#>PgE z9zA;M;?bi<*e}R*s$>p|dwLdYy#xSF+{nnp$e1fIGch_b<`20h@iH2XOm=1V0p{No zigYr(8n3}DO4}2OB<+lEVk%&#(|B4Uk1J6TR6^X&8Sz6kf1}CQa|)F~&#}XuFYfPr zv15;T!Ym#r)5bRZgbI_Y*nVtPC2bLmN~O_KrbG20$A5UKP)*3E@1vUd`mtM(yT`;& z6Yl=?cg@;Xb>YZ^@%v9a?loN)E$G6P;L^8PJ@!O*!{X~X(|z#3(IZ3;CUs3~dJtW5 z_f#4i)1gY5xQ8v=ohaESa;%QLRVKB1s|d{$Q!(^5yli*=yW zQVhj1_=8^k$7pj*4r61CM5tLbpRRs>C}6>0V}1xsMoN5!JV-uKj4_W+VgrUAuQbRp z)WC?i>$njeKwb>TX*gJou{egnP#XKXNQ`=1(zn=<))6`@O_hY2rD-{#ercK@w7fux z-8>@Fx_kFvC5t8~yAlr0O;1nH1;c>noDiPD(~Oxg+!OweYA67f_28_Y*>uSEG-=TO z%0-k?JBkVAw3a$R@AbNx=1^Sg`3u!r{$e$8P~1O?^sjQQekJ z$lbq>3o7KA!aU6M+@kN%@CeR}9Mdt}N@xO`n+(Tc4!719pHJCYIS&a`0Os9?4q|jX zzZ!0C;vntBF8<#TYbE^v3b?I7vnv8VYWv^xvZUvI0enAdd~a9AO3K7i8FVcI^`&mp4qH7sxm9Up{FUM z;*1{c=k)Y4Pm&AM=x07zO=d9%5A8PNaaIC&xt*T+{0qBg$e9Li)B1`a(qo7K$t{Ww z7gf0*&()S!qS5805FUH`UMuq_%C248(p8@0Sqd^awH9*>C`mYInY zx%X(=J32ZwGq$Qk9^q`xxR>l4CWJRBd9)g@zj5j6)weERzIy56s;W34Xp~BiJAOKE)|Wwd9|xS83+U-w1rFH*3-1V`r$96sp?%Pam&4SwEe(oOe?-@gOftvR&nK) zi55*kC8G=Bg=mUHVKC9?JSIgJGxD;U`i9yvE!SUivJoJ;xswuJ2Vn*&W*}^v6f57L z&N9Mm1@;cI_mJ)4^07$Bi&@@>ckhl)qaE?i2k}a3(Vpni;>Va$G%XSTqx<*oa~!w@ zDwDCR^EpVz@mh(e8P0A&=}s;zC&hdj?mu4)thj9I6yMtAi`N{!@SA_}7k}|9mo9zq zhxq%KUps?WcLTohy7l)ZoV*hmZG)i^>PTB~YVLyE+{W_@j%9k>zB1amikO z>eQ*O27P84`%qqPm4~M8{_p?&zyHq=zu8ID3C6&Sx{?lDRe!)>vTM);%J;aBq9!JnBWCZ&Q`2%D_QLxGszN(P0SX9kkZ0 z?zec+|H8>QSjS>OeCABpA5Eo#&>sHT2|xh` z*W}i)_6-taWO6=?5wU9#c~}Nah38$$;uojZ^xXMv{f5Y8=-z_swT8Xnlgmi3RL0^A-b84 z+>9)-gKf|;EHL>WGrisLUFy}->lE}76os1g|dZn!BMBH6^A`UV;Q(0+{6&-|c&q^JHLn5D% zsijy#?Zyc$ zU!%pI1)+^dOLQDXSnV?<3+Lj5RX)p(BRhetK_(X+UKypfh$m_WQ&|}W3$(>tMlCLi z+0{969GFUiTyCdk1|4+A!3K;N9t6-liU-^vMhp$%C7jdcXebz1Jxg=rOP%xTB|J=9 zQr905Cv){cP?gPbD(z|xQ8Z0VHj8IzTQpqOg(fe|RhC9W9L$mUyh}=6IYP^%X$7G& zX=>iE<~l-Wq^WYlb`ykJ)@ZR`KDpojvPlvXH{K9|Une5_)_Oz;BIjmt`8g0pLxU`0tLSg|$(UtwwL zCFq79NO&+L$9e?*V1sN(6pnA;bD?jzfj8iX-5XfN)bniS5|QQU4K!U84sEc5BG4t3 z`JNPoK;GoKRr*HS6#P$-UO@V{OQ{b&5$RQ=|F)FghJPv2-$gq3l)i=ZZKQ3S0x#NZ zmMskrDfrBi=Mi2{FjL`+rv6`N{{h%mk?oJ;bGy1^NtR_x?k#TV)r61)0tqY-Ah48O z>Qc7w-tu~XzETXk|JQqO-}cHbKiI+smR^>GkhsN8;@)l9mMrVaRxkh0NOCuMW$Y_m z&D^PX%9(RM=Zsn{aY;fgad?LTfdtZEMwYdyNN6!^uC1+=1lDC>nYl5r>8Q#wVI@)4 z3o`tltEv+vovpkUZd+YVO{KliXfzp&S|g_7(rwtQRyfFB zSynMD$5Ux=NH$A|ETk=Ya3qyV5rL#+O`e#JB$A8>&BSaA?xXzwGC~UDs0b8TP<&5- z>hS_`fI^Q3=qk;o(u|8`(f|YW_|j%bu`FqCPmf!prsxVmU{HLuMN`xuR_)wbw7*5g zimXOSsI42VQG5zY13mKWM)WX%!W2L3@hPi{WtvckDtO8wcAj&gc-p19I35zfo1&_4 z`}ezxFl|{XvI=HnQ$V9mQRJ|6=#WIJ5DNmV{5-wjg7Jbp1=}F1<#z6zdt-^N(h}96 zL~G|po})G5!fkx41%rTVK0S7G3)D?Et*)`G#?#Hq{lY*PTtq~RP$vww@q?BTng-KM zgcnbby_o(s5<*F`&+7?;YxVglK5!wm$W1yBLns-e`Eu0*%QyZ}9v@cMIcJTzOxH^LT##=ZVMj>`O0w`z7*a znFpNqUbG4{f5lTU;BoTgsg0E37;T+Ww9bFc9>xtUZImLk7NM$Jf^Tubci#=Z3v4C# zS~&a~zQuRBw}Q7|jQ$nhcJjB_%46hD$)7TnFCHV)KusEy9|Up3@u)6uXWgvIsi*Lp|sJrCZJ zBDa)))3G>)PJZ2=Wb#VO%4TQh!VJj=Y`IjY)(EXCE|TO#E=|%e?=dma==0AVDUqfi z8SzNA!a|#B7Dj%e1v~D2U}knv>ufj-!OQUzx1G2R?r?*X97Yx@M}0jtN^_*%sab^a z4uioUE(~6xs(rl!Gf|fg<6cmyBhdu4Wz$O5>rEFFys1`Sxzac~N=G5N%}p-6to`uA zrfEo`#&_%h&E5i?X*YDIUnVPD>3xV%>9Gh zhFSBE2(~l-pY+fYB{0Gd;hsHB9)b6UaTLI_bj_fe^c!tMOa~c`9~`t;Ixl_R(a)37 zOdlVLxVioNN#fOn^&Yf#0e0k$|pQJtdhVmBgV^jWbyd%<413SdM^2SnQ`b}-mt>4NGyk<`|k1^I98U${pVW=!>}v=EX&h> z&N?4qn8>^j<^{%mQL`C}n5ypn7A~3KIa$N;i6pt`&)c8pcU7w*8C}?d>V1Gb?yD{! zLv%5O%4|kceS5*w$&*uPi55PUBpmBP;v|`ZHu6DeBVWKkxd7S8!BeMRS#2pX(^5-l zsiWkt<+Ceu;|}=SV++0+&n$(jV$vU(oeu%@{K+RVazSRD>9m`HN{Qs_$2R4vFZPPP z6Ply5b4yVS?&qIB*<_ssC-RnCI!U?AX&px1#f0W$Y1?j$=tGUQudJnI)mUqDPSsX0 z%D=a`Kt3WDUF=1W398fQ_m4fLP<7o?F7^~TC9hi_sEv{=Zh?cXh(TW0V;LNkNybpb zFN_7B;(r0Cqh)&x1&C9K!KK3sSdPWAy7xlMG2hGNOD>*8#?T4VHY_L7)bLx#o}4;M z^CvVd8{TSu*%}R(YkFGtN!Cv;x+Rg8iu!gRr{za~-lPNG*0!Pq&hz+@U9GW-wn$iw zru?B;+O5J0on5Nk1z4h&mB6X49-mbMCslYJntF{D&U}?yHH!he*U7GEBke_Q)XJ%2 z{CnRU|AHJ}lh1CMBdI$EJ+r^G*L^|GzlL~Uobv&~;6l#)M<0Rx6jFScvwccPrNR$2 zRL<2QDi70O?%67H$5=EvcE=qWYc+(e)mBY!?;Ur<`yfT>ixUT;ojXUi&U>T96MvS% z)-R97n+b!9kWxCkwoOg7jgAUT0zEsyK&KKv?ATY^1yI*+9VH63EL|y`hKpW(wP^qT zC}#zIWaXk%Z*umt*Is)Kn&uir-n(~p_6B9#Fn{e?o~KR{1{WcfIja`_si9$eLE1l& zF=jF0PuuK6gOmP`J{lS#BanzuvkGoA01YM7Dnrif+sNEpROTF$lMZ*KHXaNHY;8uR&~%jcU9*5vcl5>(?#Isg}=`TJ4e8jVJjxk;yU(!HT{agM!k zaWs(7gTB=#0;8W@VAxn-7UcTyI3z%;B zE-KGHvA=-H0En4_{ZBlr1jT~#j46)tf?eCT?II0G2ONtUlxKf_)@a1_rKQ+%Iw%}U zw-q05_hvqvF1w$8m+q&xT(?%@?8{NqPOiV7d-wdsw)V^Kz542_=ndB{fA-0=6lBF815^G@t2V9{?dl6O-E*mZ_f%d&9p z+|pzq;bJuTvUI)eop;_j-`)EP$>@}0UU{&L6xuWMT1Ilo<=_DH13q@X?O)qI`Mmv; zbKigc+-H5TUGUzI{^hU!>R*2Js!YjU#%*8->~zouuc1adNKqluT80(iq7L_P9GgFO z8meVAHQVnz^X!W+K6~cQJ*HG@&r`?9Uy#3G?tDTPs{0uxod!oWjmB1=IzZ;motv|r zA{+J{3^Uk%`Q4Zh1p{$%@bk~{`@-w5zkXqmw4-xjt5GELCaqe-xmDv(Su9b7sn+87 z_?~?Sp7iz2BoYZ-8CVzNJMR7Z*S~)64!R@Gsw?uoV8kDFtBUd3yJp!Ht;ORx+;m0o zUA&#k7eD^sCm4Hg{_OJQUQBUUKK}Rv`i|(!!vrU@ct>ZsR5Xr_8wPQdQl@nl(M@+h z6;o&Mst)hpw{I8TRb5qC+0sWJeKZgkW#9cfui99RA3PuGP#%ufJ za=UwVFLZEa&ZBe7*0b%1tQ#7#TEAe@GZ@Bp>`)SVuy*wc<--qm>=^&(-~R32J{l*S z%&66_EhpSe-uL9Ja8&Em`YTtjbPW_5q{XS|TyNK>oI%^&t>r%akSiG&DB%VMsD7Im z^1+4DvLxkK!sSacn;svhMpBxZ=#|+Sa@UsZPaP+2@-O6nmHbM~HR`i%qgk4{xf#S78yOz*gz7E% zwnB%qw5+1C%Ij|a&#e7ycNRG+7)Hy6d{gt$g5p@Ay?W=N=9~9#HUqS6qY)du-Qg_S z)`S&n_pVvb-1OA7tDv0P+8w$6QI^wCH$j_yN1dJv27Qa6G_=}7=%F9&FL&`68pj`P zHHkleI3+Ya@Wd0(eC5kuLEAoy@Zah4yLjaF&iOSGpWR4J*Y?+c-FAb$;NQuAN4|E9 zbdfIMYyX8kA@I7}w*5_R_msmvT=>&Jy|8Xa@)z=-k!>0BfZ4WjXTqE&l$b;+f3kua zr;@3BTE0yd>OPcP*IKB{4?OWiV3U=)V>C7QT0?ak=I(wvcYkYn?kcJcAXU^DHb>Uw`^S=4!vO4_gzNwMcU5%*gH1e;??zJlU zKcHnlyGA>IPi~fQcKq$%c6hGog2RE;$nk=7DPx7#yl8kJlEQ9GOurXV&UN*lUV?H#4!A{4z4kMio z^x>_SF2H%dVBso&d0q@;jN_GIoNjvRDO-b3HE^R9Yjv*{%kI^h>Anu7--=&za=FIO zS;Kg}HhE5-+Qb_WXkB&#(0iDXnNB+1S>P*{d34XEkQ8eh75-XndY|OjAosiqGR| zYN{z~s6TYLx}>nEr12I^`^R>a>3zs;PF+N|eovp?T}o~Oi$quGFp2`u`PMvxA*J{i zXO~1tQmNroJj=+&n;I>AXaMCJ4D*&o2z;`&yCt_nwORVhg;&~@aY%MFX_rn5rkO9HDQs-?`ADV5wD-h`6AwTA^rQINljl(eFjSdG9$~_` z32PsDM2p=i)g&}YT7!yBFkHfwcd({V1Ct>K51P{pV~|su&1-le<}yN50&>qGXW7Qa zl2(Dw^a8%Z@{q?0e28kJbXO#!S^1H5mA}1_pXg~9JY};jSlXGLL^uM}d*@*RSQFjA z78VR}i2-3e)UBD~7t2Uvi7amSlo;=yF!ADfT7YbvLx^)YYr$YDC98USjmD18FMZxm zxrnj~EoAEJHIhD=!&q0&su~+f5#!QnIYf963U-jWeR3_TM`;a9i+0yCS8rWkeRtCOM9E<%#p_ zo+!=joK$tAKV`?h|NXI7kEWmJ{;<3I5AiL&%Kmh;j{GtBj-z+|YWlzl@_+Gn02uce z8DyS$<~SL|-5>GkU%hJ-0}fRd1d7DSd;_yA2=sEVS`>Sjzy;)O7cTY;dBJp_>xG-c zjc>H){Lct8KY9g5<}Q5t>1X)r8UjDOrI2Td2RN(ggub+-*yo)KaRnGv1tf)eluKhe z=3Z%lCGVS>?Ws}F*qHtxHb0p8VYJnJvQ4Dt@ zg>0khSR`o!98G__b%R~2@vQv2W(!*Z*)VZ6EHAf4>pTD8Q@wEcvY3^Z~6UKuJjCg z1@c~&e>m;t8XM#M%XuDj_0P{&RQ%{i^}BY}R(Oa;7NMJV;2_QJ^Upc{WwPE*kMNT~ zBWZ|wL)P|j8FR$4 z>8vx84|xu=8VJTVrZYj)xn=XpIY<5PhyRwAxCXkl!)zlm;FX*18EIla*KAJtI!)os z=Czm2$_Gmkw#;eF*&{1g5>%5>S;*)ijQbW?I#nzTQk!`Tnw}m_#sqXSNzLW)97liz z&|aJ-g`hqQ$@ImGuc#^+EI&-;@uzMhXUU&s{?3}8I(`$z$4$513FWLiZ?%8(n|6%k zR@o7YCIx+-$z+0%C>f2#b{7f(n1Blig}ZmlOftD?civ8G^x|@jw&&4kziFbTor3#D4^Up`fy|UF*W>IC- z&^4Ov`@pchX?K%GvqpYyS;upv-A4F0Dw7MO+r@T+02UsaJmdKlNhXhr`$&i!Ngk02 z;-a@$~)u@+;T4qvU_Hd)Fq<+MAk=lHb!DNoF&_r@SH) zGm>>YN?O-(HblDJ7#Osghj}K6O6JPdn3Id;qfA3tCxj@@Xb8XQ0!(qC(L~av>X}RE zD=I1=y3EH5sMw2jX>Wzc4{Wht_s~P&bJAHIvJEYla;bLOxp{2n0Tf!{f!;)AE8}3O zY?%{e%vs=MS0Z^JfH?iqorurt#VyAV#%zW z5vX61Nn&}#9xBVOspdSwavRE&C$x7PtV2FHp}Jb|4fz&iW2j<%v5L_Y9traC4$uY8 znwlD?rsLY1Z@zhL@yL-yVwV}MR@QDa1x8^`4=9hY}4kITblS-k;^ndestc>0OS z*38Wg+w%idg(Z--+J|SogJZHu(iKxx7K$WaiV;l1<;%($2k$#GF{8_AWoTz6&YV5~ zrbA&NMT*#$6*S1=;>3zchia=;C3A}1uH?#j^GbQhN=Y*15(She!d+||4=@DD1_c;=aBPHe-rRZJ&i zyoS<(^YgMgRt8zHC#EkebCVU$)_usU7F*Wx=6w$iWx%=qO8Uqxo4V~Ok~NGHO5~{)oo8fWhJX_D-`ad>b4;;j_?b9`?Mjd zl#Ak-_4;Ic5akoZ6DNkjS^W6Qu&h3M^ytk8_s-4jwYWIFK9O)|Y2@4tL*X2fkj1vE zAzjKJY#VGBMqGS;V^7aTxv>4n5w#7Y)uwL02A z`q^lVIyj`Z5MOm{kKE_Ngh4*XLJ)q43Fr7*jd?V(`ebSXUNCfO6`p`$L@OQ@#nsLL+!9TQ**YuHac`y4>*kI`N53)dB-j;gkIt>NfVT&V7oKm5Z_Zn(?( zyIYBiEa1=eU)pZX%K`&JY|Aaz%Fcz-V0n>`K8mc{NqhoMU(qr09r7KfXycB8d4PcY zSV?6{gNpD(l3cw-GHyq8Xi2@y6z3B{r&y^^(kbgf#qaO5)SNI zpOmV!baZqzxmB)UJ#DACH{O_Ahu1$RyVnBtiS-z95trV&4!BQA6b)@HvI^f{;R!ZV zp5W;BzBl?sbnxr4dkaF?srj{E(|i#z{G`k<%oh>FTgf4J-qF) zbwq!-wT$GMn2jr0i*am&R_yv^40!0R7BOp8)fURJ)~#2qjk^CUdna1H^|of|scz$+ za`Z$u($K0BpMIL`eL*BI$ZjyzTi4q>XLi?{(Zq@1{LC;=@}K?S-~0OJ=OfgHKCI$T zbyF$E`20MBDM7k;@%?s%8b*>BhA8dtqaT_scTY!&AtSmlkmz*x<<`1@h91~Og+Qe{ zsEnef;-;Has^}mH&Vi(D=jkV&c;enY)ztwAB&1U(ns+qqEaY91P`I;cNArnOvgy>_ z%{DUiDLuz)irAX(UPeFMl(RosvXImpVXRjbTj03R{74@-iGu_E0|N_O|L0sru9AkN zD^ZBK%Y|l^`S>hWS{Hh?c28q$iV< zU*%EqH|#Hq=;&@)ljhXggyDzpK$_;#LBsIw+mC`~C+P{cb%W;EQr4_-H}u2$rOr-C z=;#p06=4;wB}tNr#tuz=-ro|pg8(YZqyzVJ#Yu}A0 zzMDC@L0^r2R;|ySd!dd}Ntnh~z7t%UUFBe*BMOy-We@^Qu&KXniL90K(~YP0T8Q^^ zbgR$3#Ikq!1S>mXa1o-zCMZSH>2yzz7MY4QH6ggzD>^ZeNJ&K)=-NW zw3Q~EW;w#C*eRei%advUKwl4DhLV5a$>$=AoTZ%Z5pO>6rLX?RZyY(2B!^^UK~t^M zVP+IcbhSYX)1^s+wa%-N(rQy_KnrFdlVcFKEJPLt4 zUZ=v)^XbYgmNEvw38tj^!7uyf)g{fa#rLKA?>_^>11ApDk>f}@ufF~!D)6S z_l8I4Nqy)0hx{&0d@&k|gp?G9MXnB3!r;oRy-ZdHqjG4#iCz(?r4=7+b*GI&*_Jh(Eaz{dFK9y z?mP44haPy~fjjqCk-LzNlwYtNwXQSJ!xDQZCuQBab7qr71xFeKpWb*Dh?d&A;KP2; zY-O1kp6%?o-s@Rf3I+m!P+G{x(SLdIz#!Fq3vwg|L_s)}NW09Opr(hO@mH_T#^4eu zhLQD`rc!2bw<_|)&;UIPM1>Kobvl~vxNTuUEW){?XU^Pm_~>mAY#iB9!QySD3hGWi z_Sj=z+F49)M$)=`v({w}j19Fx&3(>l<)9e65KhDrvi^u8HU#9-Wo&91j~sDtI9;fy z5}KmZ)6t2EA`*}}!-4(#Wp?**38xEP{z)|IaNI;CpjMfSUp{wEX5SuPo&z95$AuTR zUqmz5%gU_y;?t=lMG1Na2Pg3rN~EmlzWS6Ot>8%+aG#f&!~J}U_E;^5Zz3>~1SK!t zrRCLt$xDntK$Xh{mpm~wkiY7f2VFX?D@KzQ>(YL|`#>>|#*r)*6Iyzs*5eNIg5#ry7l?z!jg*+;&C3{#0DsO(gPAw28S zvOHm8sWitVVV=I=&I1k(ATiEy;LbY>l9L@^V{}X=3kq^A_Eo~*!nia$9HUcl(cail zS(%r$4Jf8!0l28BDa9O8BECcYZIZA zwkmsI=F<4JYwjkSlz#N#V~rN?oM$=`3rA4Xl(uje)T?(kT7r1*3&x6l)b{872WrV} zNL*c0w;#Pi+uP-VmOY<{#F2Pxd`dR%sxhP%y0Q9QnNMh|cI|Snw~9+7YD}CkXUPQE z$D4WmyAcX%BeYc*n+@}96~<@7rnd^yWy9vT3e#u9rnU;>ZjhfU8>ZYK-o$@5O(`3e zB>9`eoY}C*`Y>TNP1lV>Hp#HF>G25rqBcq2IK?k$5$#rC+=iOnD8<`y`@w2mU!U&3 zu+rlk)ba5zSnjJsjsuqe!jiA1Vsmn%Wk1WAD$DZ1HR_Cfl%b#Mx4F=)cW&;(@O$D# zLf8M8i-t4Va1MJ#i5D}}z%KzGEgm2lTELa5E1yFrkUaNUHg8q(zT#gD|La@$Yv6C% z!e0x2?H2y|@Q-fcPxBSG@YloNu!X<*3(Bd3e|YP3Xn8hr3AwVskly_YH^P*r+&QX9 zmD^+S|G@xvCBMw46gw%EU)~TJV#dh?Lh}?0DcTs?!p$?pk5Ii)A+}9%eT5yftxMUtWj@Dq)H{<*yPWA{A|AzdJsM9)V9=??<`TL@0A_?1Y$QU(?=nfBC21Kq z#<4}>Xi&z+V4XrsCa>t-j81SB3Oa+S00&kTm<-f3Detr!I72>|qIMJ@2kkwZMavq& z)%ALeHXCTSC1SA$+-vB?GD2L!QY0Mi@24#wlvhZS#J(a5Bx8U`5J?(`QLxhZz5cQ`?)CW=W5fvjqu~`vFz1vU=o3!b{Bqc4ktk8 zsr=#5ATfeW)e}J=2HfaqVcaC`Vk6<0i(y#23fK>}D70-898_;G8KyL5luOqtqzNde zq>ODvE2HM*Z4QT7%TfA9ElFw)xRch6QgF zR6r`Wh(a#_rR-8M1SBxeLG$U0D06mpab$Lc{kUIc36ez%IkiYsgR_0nKy)xYrV8g1 zeVB~s$;yr?Yt1RikddL8C<8qxF1j!>oJ@v7BiFCY!1gvs&-p+Ios}9v)C5uAC1OB- z(6~7;wdPzr!xHR5h)OPX*o|rq=vz*0$SX*Z(o%b|-EK8o(G&C3YEl52oR=gcDrXSW z)S68^E^B9J%{qxXQOF@5?$2?h89{KFRT{#QbV;Fx#C&5D6CvztU3!M-=sV#%yHmw-E9OEo4l^K)ut6lz-l5WN7!Qh|>7B_f$nbCX1t zmfS>gv4T$Jsud0S7~NKr4WG2q45KnwQRjSv3ipyBANN)R9qKA-N1voQj&-S6jt+UA zQt~#7LBxO*4H!A;h~h(2_>@RGy=vq8bOw*Xuw&CH!CdMn(g+~W5kC=kVQdRp`Z`jJ zsK+7%9crGW7SXBrQmYH|0!g_r{LgAf7YTh%lX-0hKFO6jEP8fPSxk!@<0_C0dJ`Qp zTD3q&z1B)gof$uB6*O`&9GRt9E1Hx?k}QjthLl!b+R7~20zBO+=fP42AJw*PC&&(7QkPM{3E$~@Jy@Fo1kwAn6QS9iLkiqzp`HqfQX{lS#D9VWw z`($zeUbo)LClVXbT6Avj!Z5eGxrGHfTEWj=e>MjvG2nF)>)GrB`{ni4GGi2S3h%?vuAJ zqPPl5%avC<9J1sntSGOpzV+7D4fdmZI@^&ZMSjOZ_@=40a0#{uyIgA_n*bzl=h?hl zPu`70k@T#85vkH-`TpUdX=>1NvVXXry!&phE_dYS#7Z`aeZMG*ixbz*f5tK4*@@As z*!XpHTx`2^iDhwtyg)w-vD!RaC8*;9E{(CGWC%x1w}Unj*uRqC}!dGaNBNaFiG9y=KV^tE<%EJj=D-;OO~L_d1Ph zqE5Wq&0YJO*M`X7%fF{y$TKR=BR7?Re*C@cb0s<1lEDHq6$!!OdS4)nO@00(-+LR|?h={R6_VlmhpE4)lyd}F~(dNPhH@AED$cTI6 z88jX3v@Kr|7N7eXHBs@(`f$Nw9vdTL2%npI?5pJDa(F)4x&+}^$`}qUDsbFT`(PJ0 zHE=l~>m`r~Qb7%D9o7_p*3~9VWji20*U0pg75Gb7P}k$83ENMxg=O(q76 zL=Q0nK%VOfs%5DJCGxuH0Nni?!Ejura1Z2ULk>`gxxv`c)e~CeIBs!fh@QkTgJ}HB zymu06>%NJ}$q|<-Fhya${ZoNfM>M2>s{)&R_uYNhsh9;blLgYylaPf1XTWQ&j!woz7w_V|C_R>GGWLg zw0-LNlqB#x7nr_s;d6{`uXn5)qx(Wv_m#FbqM#Vcbf(tRbd;;pF;38FoK)?MO$)rs z3M=7SV{xI?Xt9vh_GuUypPL@MdbKC+IQaOJN-(Z3*>(V<{lwk(!3^Js7NmjJQ4f!L zddRwQ-_H69D;FL@At%xdCJ$RG8VDE|ySJVLAU3qSW%Mx8yC$A$ zdDR%<#@RswVI?KX!id2aJTZhP@)VA(?*AV@(ZcM^Jki3uNmhH`;f%IIM_VW45?#Zy z+zi?~>n^o*{P<^W5PrHqgS$+|(#3&`EAF#TeXUNc9|DmyMw>%fVm0QXa-9YoxNx|_ zt|3;rXsGXc@8A&JSW#(JRaIGGStY(oOQwg0+-q^z1f-7VC!;^{U>0Chk?*J!#e4UY zcY6W%W5n2ZvSl@`oECYV>wNRgPC8>S5!G20>t~<&>Q|q^!)_)f=34*09L-uAV^we> zMldJRJ2n=%etq;h+|b0t5WeV-2zEp!mZVv=$yVf;_IQ;j)v;!GHtA$tGR`m*?y=O} z#j@^Nm3I(sdJ&R^X?o{X6*(LSZim}dQL&4DA8b)5A)ziE{%>kovHv>GZLuz zx88jFLO2{_W2`9czvajga9r1y7lK?4E*Yi=R%CvRkM>@H>$%?7cfE(+^^T6Cyjr%a zdx>QQkc{!9%<7tUy7E|#M5*mhN0H5>X48b0mu07}!Fl6xFa4eZ*_6NQDBS+KhK9QR z^ln!^mnrX&Be(3AL>8qBhcCSS=36MQ1ZibJ<#djXE}<@b80Fmx>&m~{{p#y2%yvvw zV|Rb)?t5F9*H6pqsF~#_2e|KZuQOfSflXy!Wbb88zwRPyQzQ~c5%e7NH@+(=gZF&x zoJzlg zEA~z1uW*4Dc4sr;VtI{34X<3Ij~_sE~fL@P5Ei_B_332GIk zq9SO7(AEU|vI`bxq&L=B_j_HhcL0iE>BpR{f#juqV{m3cw{`4HY}>YHV%xTDCllM|#CGz; zwr$(CZ{B*p@5lXp`*d}k({<3hx_Y1L-M!YL%(Vv@Z?Qk8e~3bOdUkV_m9;CtCPXCT zSn}A~1YGLeXo|=~JZ}|%X%jnV`P~QwZh?#JcYk|5GpoU15Uslh3!+hoLO_V!R#Ebr zINvM~CbBXTR^^;?6AN+E*3}_y%<^0Z+vw5bUF3CF*UShQbHOIb_y0V1rg z+3{+2l|FoaCxfkIS-9TRsu@Pmc|Dy!JRnR+gsND&3D*x0)+yg_V#mih-5=hh)^d!Y z?x>6+)3TMLaR~DI&VEKKQpujM&V@BKJxNKChwnnadRl)z1T=o%tJD0DGQYWKj0`zf zSVUQC4~+kg%oFb2@O{tt^n@SX84=$K-=`vX;YEpW_dFO;=^LSgz-E(BZQcb+c92fV zQRtlP@Oi&9t_)EqDi!)u|6XxC8|&K{m6VEfShqs8p!H!_do3&M7A z2yD02R=ubKha0P0gtOQvS*5W4DlF~O?}<$mm0}Gc(V;-s@cH706!Kw5O_d2Zs04S1 zn8pfV*R&GR5t7jnDauwU^T5BekyX;xSSPeAVCcwqeXrJO&%(UX-C-O$4#X!PQvdCH zbWh3+Ol?Ud<6IAhuj}Fx&VET91&+Rl%~&2`<+>UNWU!))ZQIc~tWr>w$RGr!-L)2 z%XYOgt8CXyVA)mH>Tx|~BRc{5YQht<1zBKZcE!8o{8Ct^8{5Hl=ymrmuFT7`U+M|eDUNq|JpH>sUXVb1aXciU0K+e@BrM$Cz4m#fu2G&|LH3qUkx#+U(>4@j@3rbZ!(E2ny2fDlV@{$EA<~BZ`k2&}lQQV)<>6~70 zrOn%kKdZ<%b=TfV8-|OBe92-a{bw zuu7jk5H_4Ar@j2AXAiuU!V}YOzBAEse)_tM)6|$Vp zOAwbQF!fS0Rp$$5*{k;0meX09&JsY8aq=a~4yH$GE=y}K^t^>|GYhcqcMW0&zkb!= zmMa@^o#3Sf7WNRNwebh&0ozR8LK1ko^Xpr#_#OAh^12?0>s(F(9r4~RitXU@D=_#Y z{U8YOyna|Kf%gXD&mj{mbQ^)0m7<&|`XU&9D^msIo3x>V&IzDDc#1IwRmXaKAgQx9 z{?P|wuj$P{HnFk5KORo8RPcF*!v+)c3`Hk-WP^x;d2@6iRONdXzME zBM{sI=}2LC7yyp1X2!6oCxl^iszYyF(~*kC1S=fLvBaZxbrCv7XV#2C1gc~T(n;Xz z+5ICws2KxrpPE8ayVEg*?&!+Yd>; z%7(UQE}{YHn(}9RKwj9GI2=*m3VLa|yA+&Qb3fM^Lp_>FZvr!*2(8pmpPiKLm$g|fElhq+JDd)@N3zpl0(Gnk1o zca7tey(WnlX&lY7bF#fJzDw#Vx6{{|HTy{qCX^w% z_c7csci8eV4iO)d;G0h{<#EV0#bjYfJqFzh>#uc`L)~9MF8l-pNQ2OFHM|bvl}m)g ztVhGBuCCf~V`kXw@0F$)7Jp7vv|d0-$}D;khVlt_2{D9_ae3m4nCQoyYKDkM#Ya9a z1(Qqmhd^tx3|~0c)iX!V5Zw(QAMa_=QrL7B7Rmde8vBivh5HlMjnyej>#?t0q6vQo zkgfphGS&fhTY`2E%|9oj#6IeEQb(mhXNv$JSS+8#xFO zed`W+v%+a$<>krcWhhg2*Vb0dFE=3%V8#aULpJ#Lo`%h3c^1HDw%ge`1yCN%Mng$0 zrr~5l#-&%;D2X*f^k9(**%UHu#6ttB>ZgACEIe#9vyvjQl~uW91Y%xoVR`XTXW#gc z$YRcnz^VL{Z&RrdCj{xi;%{4u#3FRV`1F=PLl`(5h%%%$jD_`d*JF(J`KOX)F8M^zt$pw5!TXe_&Dx zsL^d2-o%86aSlz@4FF}Tr{~D;Q>SuK|jx_`&FFWdue87v#7C>u~L@` zUT)e`?YiE&U|^$oB%rb@AfAsebuN}McBkDac z=*%xM5u+5SX-b<_Z>YQTn>o1`eqCF#Od90`ym#c;I6dp@hH8U8pOhD`o!^ zeWrKQ!@HO6ot#jzfv1romiiN6okbRabli~v7YEf|8J;9*l}8OOtHOPf`TQyr?_Tec zTU0neOb?zkjNe)?h5n-lG^KVxhK`QD=YiI4*SQ}PA1)#^C=<*7cJdh-ah4H_$K%>E zCCWvr3Sqi0h49yERUhpGR7Z!eU`v0)BshG(tV_=CZ9Z2wGd4UWA;K|qvgi0HpC{Gj zDJ?6K26o+YQkoK!6PD@qas3GNMm9f#DhDLF%g9to8VP1opKJ?%!Gd|R*d+YUr~b{e zO93c%_y|J<{K<_U`w14cNrUVqbc@G~i7`@g3JI9fUpT-LkeU2-j@rDGhuBZAU*eX8 zR$(H6nnyx8V5k9ey=v0loHjmtQ!K3ivUjY>Cov%>E8TN|&&rWN{DkBR(H8zm==<(t zAZ4>SaAJsQvLq+>4>6Lu`cA*RE`#n;S66P|JMx@GErtM}_%PK?hrkv2KZP>|kYN zMOfa-uH$&OsB~)89oIXEC3efNJ3qGIq9MZZ`xAlh^=04fnp!0mVcY3hmx7#&58KYS zoMV1QlJ=519MbgDAw)xyxMK_AU$knbY=7mWOk9OE3wGfWnigpblta)|HY^nh=<+`m z4;%f1Y_}xB1=zqAEFv2XGRo9}u#663X^MJF?rJKCZr~CLo<38jmcUu=KT+IGaI|X9 z`Aj^?Bx0zB#Ymx{I>=DxdA3lB#>sSS4$!;qN;J$G+Cj=U9}m{Zi9U{|*v*|fJI&6I zvfuANj$dSa9@dBj)Wiq zVa})!t^B3rsxrja7dD%DN>N>ryjv{w_RLU0K>@fwiH9;l2%JPF(P;58rjVHrn1hXZ zn2{u>HQp*rIy4BtBKgqxo(Lw<9tp-ji7sDS9}dJ-lxO#Y5%vA@PSAGcp!RR4gyG*M z#ui)L+Hcmw*@d;V3*=uRk>h=ocDgTk-hMuiQjUpXs;c;jSIi+h8k~qziBD;_I_6yY zkoQZ{N}C@eTgCKEaacIkWCf@S75U$DH7}K;tM9wM2gAlgu~nH=^ShL1=vEvxb&*vV z>hH~3Wk=I}Ftw;sMiVm(hkH|kQK4 zCX+g zHIt17W+01jqIK}_8ro@oAVIQ;)8(-s)|TJr?dAzN+EnP%5gCyaO~ClyBTnFZ+BScg zXKtmVgA`OR?6bSI_7swWtCWxs1Zd~Ro16_mPK~?`Ivtpc$Yz@#y6yS%d2>9AOFO6( z>o;e*eHsyx2DZ^_dGM?yPRr{Ib3S=zxLS&>CH9%~QtaENv5)jG{pPMN^CVK^GEe8c z2(w{xX<=9hBPML8#;sMZ1!ok)YJu)BEAyQj{8Xvxt|9yA(|Bs&IGE1*p}dnbGXm!` zd~elj?b$Y}sa5OwdtOM>Gs#aj6_QiYm{#(*n3x8f#MzTvANgbN8x0CBm$M7*_MUOq zOwRZ~n!AXs;j6lK;gUV&woLder$%pT3Y9msz8&HNd1~ZH+P9B+wRSEl7`~lTjqLyd z(z5qz**6JVv^xgKNq43h^Z*)zz`MTz-bOiCA>Goo_Ar^Ux@iu5Nf0XMoKPd)ome9! zycH?|aJWy}!)CwtsqgQhN05He(NapL4eI{G1!QadV-SK({KU)k&ZoRb`P(yRDNmdp z6P%RHsQm4Zcsm&lQo1KoLWL^3keMa#S!XDN2F7%OH%xpjRic5LFnNb91>GoMo<@1J zwXtimYRif#kA9R=!NJYUeyOL_N-XB!kO!YU-moexPp}p2(GtA6%1PV8eca*HyC_Ic zNB_2rUMC(EY9?0qG?9l(nLnltLRRilBwxit<-hM5Zd?)xifR&|!8k%w&#c|(=KG}K z?0NwMIe^F~Uaj&&sKg{KQ6?z48!ub)=j0Q&sH!E)s5IK4ZwK@h@q$I8uk4a7*wPlA zW`OqC+Sb;U*iWY?_-gMfyyXMb;% zqft0L9jNlfdUUge}RIgR4JD0wg^N@h(qC!?mxkV`nC3cQcp+i!n88O6qL zCut3MU3Wg`cqM_SLNP%cU=}aAaQk3SvDeo2B#YF<5e_cxI*GecCQ)4KG#MBQegd_P^D&tA0<6fbpSxb2z2j$?+3 zxl7`e0^lB*lQ?X)*Ufj)A=l~k&R`w6{;>;j*`EG>9^MaWyClVzX^qz511*TKIj-JR zZz9=0VR2aldy`I5b11{)!(~d5gwPJHsf%*yFc1z1kE zN^;8RdKb2fRW%$OmvK58w-fEPI_`c46C4j)-+pxv zf2k5|c{9Bjtg;@P#d}IwQ$EO8QAO>>DQ;fgeJ>Bs;mx*ZY+~0u|GDSX1y}DE-kka8?gO70L$=s<#5OR$?|z6#lQ<+pd#0O zmo(4$(V1+>O9$w(guern8|41!Ml%L&~9hV_5ChmxjIwW{W;$KG2ZRNgZxGRit-j}=O+3D zU#;gUV+8o(SnJfcX}1C+7je18RIgGW{O$u0=v9JaJR5X!8Wbjz(r~WsouP)2HkHVm zOR>3@wMR{(sVPDANkfM^Hl-;wpuhOF6w3TVS$Z&K4v6m=k`Ep-*{n3M+2}iDmPi-O z6K|9*uWU@D9Me!B#BJ9sMMoD@^dPfU<)=r4ShD;`q-Lp)Bl`u(b}X@fZ%enQtfI0O zOPLx+Au0=_{k^r2y?BN8+D5mI{{eaJ3nYtN1w=TOKY~<(qIkPFfq-ABLJk(yIsKF% zGw0FOUeI5eaYN$f0>V?29c^m1AlHDPPuzmqvYIo=@AK-Ybsammc%{N)yQrMm-LvLU z)XyCec)grdsC8ui$M};rLQr+QaM9RC*94|`SJq)kDSd9Ua5RbjzV5WMvaSOD0$~hvNY1J70Yye!*w>O!2zT}a0ysLPSnV;< z6!c<92ECUSC+7tWZFTho+M;#0YrArmbFR9U-WJjM<#5;8$FCDH_qvJJ^X2Jy-EBQ=Ja=PU8m5fYTO$&n=9ZiJdGHza$40<~8AcPls{DyZjb$T$? zz-teug&EOyM(?TV^f(M zE91n#z~Oj?1N;o2$c39O+O|u=_Dc5n+yv~PTAK7R(fT1wj^2)FquE z7?Pe&Re5PP0;IAWL`8n&xveoNhc&46-%RIe^SGyGsO zCQKu2>5sKMVCePa{iKl?0Mnbh6xNuibG3LsevY{Ap8Sp}I8h-a^rNo+vHb;49{YN9 zB<$2c>uSL|$+&i48aX&WTu0afU3t0fb&Xd-z%N7R@truK*Jj-AEP?(U6B{_+wcL4y zD~QHoZ+p5Qn>v!otS4njL#+vJvR#vC=Pfkk5%O_<@aVQ>vB~JWhziRgajY_trJ^;} z7TBucwmvjd!FrXH*_l36H4&_tGS1wSC8S`kq4~0<%gpMWvR(4=#?iG)yd8v4?zC=W zwrpvT_b^cueC`0Nh&GR* z?bWmjy)K48?diIt2p!Z*&*wNBE&Z%`Dk~VHY^{?!-#KnuAi3uRBbNhw1rjhAmo{M`tfnU_>lN$iPZ<`6PRQk^5 zxaGdsq|jv4r5>+6|K;Wv76fZC$bfhzOF%>t`! zo0sQp>px*k2o?j3#F@R2xBac7f#~2r?YhI!+XCQZh_z#BjxBt6j!#5SP{!dH`SnI8Bs$Eb(yrC~yX} z2rYSEEx8#3(U5YIt7c(y>m`(jk^;VTAuIw(TN2m?#ku5b0?dQ2{Zd&l!yx&OWm`FlCIymY-g6DM6N>3Ra;?`&w%z+>*!en-Yn~9H z^Pb}fOmnW@Jqd1iH~@)OtW^&*8{y*{0+058jAlkQ3TBK@pPbGd9$(s41%&qXjxc%e z8~aL!mmNW%hqJqJT}X@yW+$mA5NK?7bWcz1&T|#@x`yZk*j(KEmHO&Cf#$AlZHV03 zwU$Y8xvtKBuhFq6H;MWj{DWw=vB5EA4EH$SI1$%lI2NTjaW-v`Jx)O`A)s@*uvFe) z{B!b1j;wn0m_tTj1{|WIg|oAn{)mS}qP4P9E6%Ken^S >-Aun5A4Gp>4U0IQJ zJSDj%uq;_-j;8!z8*BN3#G5`ojMF>mZtK$CmJZ>LZBP#+{!QxI(n!6=j?D+5s8yl| zCqq%@Li|olF66yc&uRtqxK_{9<1Bz%WM|3)$GtRZvu6gM<72a@tfd#+V6(pWfBD**uQxR;owP8FIttM>^4T=+ zFYN&$EludBGthdY*q;-P4l)cZvz=S2KfBDRiZdk$T!jv@&mB^%V^Q1_xXKs?qV=+O z7JK9WX_6hj5rQ5#_#XZR<>aHdT&e4ifAZwWse0~aHapMWG&cBWv{?RZ`hEHB@_nuF zy}fbqt#tNX)bur{>6ftehFiZkNd>Ryw`lrJv#{N3PTAXz)`CuJPCB~geMIozQlm#$5l!D;X zfUQ1!IFD;IjI^b*Mkgk>MUhTnv4a>qY7RRms)c0?WH-vw-S9;aXwyNe7Ta*5``;;g^I(Vd`+I0u7da=e}#F;{J_6W$C;2b`UBI+E~4_A_HQQ5 zEQ&p-|FvZ}rahkr&RN0U9c#S3P4p`5%G$~Q1Gow$7~C7M`U(n zH^FiFC6R_ryR#`dH%S4ZDE#M*I!7-^?m}M>oyQ08|KKpz^j+15&QmYy$Q`n%QO3zYhIp< zL@=uru9zHQ&p+^Mf`TE$N6+X3DXHLFHM7ULndU-NzDCgbzO@DRYM`}{g9Ucx2d0wT zg|vXtmgY(G{#9P|@KChWPlr8W`g(H1hNk~a>J&0B02gHsTNjj>*_i%Cgna)s>-q)} zxaIxqdlH*u{aqw9fqCww89ikAvHf?Q$#we#8Dn1}a=W$}OpqPy5^-&9Avuoir=($k?pgH2#cR*9FeVS_gLRc7U0k+2y92<1`CP zAP|x#R&QbPF}jnpTfaTSa3cH#v3D)=rS=>G23m#FFV*t7k4bvAKuVE8{3!#`2WN3wo)f6L0KwAkO>ECG`!KDm9U&Aj#-xeF?-Sk^#N4MY2 zU*K+D^9rFIH3hnht<#=H3WI*w_w%358;ibQ@gDcbe2?DO{khi%(YMbMP~(*oqXD#| zcd^%2_HY!2T)|3<7?dgI2@9=B zrQ>K)@X=?cYYwfUkafI;oV=Cl_)4^L)F~LK{e60f@)nUL_9PX7=P} z4(!MF^v4eT3Q6*RSm+w(M0qf7p-4!W{W=i;s*Nsw$amYf+IzTPq>erZZ$br>9Ku&G# zQ>k{y#@X0ocWW8vySn!eNXe`O3Y%_3`aNctsL8LKLf? z?6Zw>jM~rIAuZvY#F}!9x!2wyPHmY$t9Fb&-`GKKZtd5(a>#|`JwQMTK7EN7xJCFH z?SA3--bMO8tizXeA7jb64@jMGRAQ`)dyb1xr!5igNHU={3!alyt;=AmJY-u{FksRd zKX>P|+llT7=eS4T8e4a7uDcqQW855ncNZYo3G@y_xJTk2gJ92)L&;q2Qw7vz<6RhI zw69j=^56RYvX6_shj#K6oiw|&A4v9{sZgJ$*|?6mI630@V9j*%BPhV#=cM2qrIK|D zX~^2=#b_BJqjw6f(B9|fXc@G*vQPEeI0i=Wm_W(7i#qPuA#2z`m8LZXr_mU+T&hip zwl-wZS{Y*pGz4Z}7;?O?OauSAbKuX!kzq>kN!N}2zjcsT{WY;-f&2fqYxuuLt!}); zzFGn$l7;uW0FrtCtIWI(Z~-)N;#jTou6vwTdnnBt`K1nSXBWmDFf<|}SXlju8GT7c zDzz2vK5<9i|zx4aAwo>ml>7lgPd0s?QLl96URHi1yXy{%tO~s zB1rNfQ*OVcj6eJ36ND}6NeSvvnD7AKoH&5?A)dpd(bEr_K-F`5po-tN#zPiNm{fog zdTEAB$lHrs zvw2rdi&jvE*CC3{axexwRt7rIAKxW_`XF@}WU&<5Z!0Wu;|bkB=ic3t$g&s+{2=$K z31U7BBzu;|A(UkB{WVO#wKG;tPY!tm5^&I1j@<`TW zkOVQAZ7Fn3%tLi74>1hKdVCHA_siV;g=!pmqjfY@GpjhDBI`Ay&i(cDCaAr;sNF}{ z_kj!Uu;)iyu9|=&`(2GdpWSTTKSM@R6& z_?=updf73kQ0!e#x@RSg&bHodW%ofewxmL3UKv zTMJ+1vpAkWpANd$2jXtUM&UExm{Z0s*l-=Y=Amon3s0XrKTWp64IaR6*IF*$ZlUF& zIa$HMA-IAs1;!zJvsLuuvRVDy=Ijm$-`+)cj)UC@f1XM8eW_21cZw$=l-n&w$;qW9 zw`=bbZ=$nvGk%9hwTpl&c2mBe(xewGT=s0(E3A&8b1SOyS+$zk1YstbRUOg4qAl?> zwUCFwW8|FHZyoTgmud9>M}*D2IgOi#rM=uE;hQPB(l6b)Wm13d4|wPgP?H;qBq1JD zF-T_-*oR@T#)eJ+)A2>XeCadW_4;=!b4G?0~@LZY}0}fduLs=7p)>B0refS&IQ9HKyv$5Pm zG2O=VfCUAZ~&T8i~ub~MczSu)OH0Fc$8 zf#Fc77^^Tg=?-zqya)SOEr4lvciFmRh*NhwJEDl@WZI6vSQo#5X=lF}2BaMt?@+-P zEZ?dxju%+o4;6=74l={_n9x4T5I8M&UM+WK1uU2NU{7;60+}QrnOR9Ut41MqZpz>p zh46foHsXHtJm>WQTrDzft)Mw3m;$6GosoWZGT41ae13Au)u$Y(VOHATaIkeC(3Q&h z>VcPSZj`Mn;h^HXguh5)NH}XsFdQVdb%#_A_OYu;LNZ&5?Ckc5_S}UrpoM7W9e5G{H zH+LUjKRzIQpdf#+d{>tE85lf@s0+&|psOfF4I-zv&4ue#K$t&4(^&sDu= zpkFh5ae=>o9qEGs20d`c@@}}I`WHt+Y*%OaV)k!@w9a^Ccff>gYVJu5nGLi0%Eaxl z&4@=evMRjrkBM^cx%8ev=mjNp(JM5@4%^i1gWr<1!#UL)ny%Qi14)}Khz>lf)f)cd z#7#$U1fU)wQgLlm_!2yy^Y?&;-4P-XPYLlBela3c2=tLy#@u4wd1MVQ=I%fT@s284 z%HFf)FPIh|;ZB!vP2Y>(f-n$HMRt^yq`E^xYjjtBQP&WEbmPq>zVN&dnc(NpMgL^q zza9tZX=1W}Jsz233Ho}iweZR5Q^J14W3NT*V z&7`Y7z^4H(?Xq-rifx^#A)EE5_)J=zO1N~}z2}3DO}ps{3MJ=d-9>`_W&!#6&Sj7F zamHoZs_&S!*u>A%ER(KDhZ?|G0MFsW4r)OZS*@P^qaRDCoN`Ex;TKsANj{RI|6>|` zri8nBpAJfnX&-F5{c=#rif)dOs}Tq1g{%_YXthK!-KoV z{6mExa$bu*P!#;cn?y@l3HKMdUzfn0>5OpwCm8Flit9&qnU7EHQG42)JnmZ)(zdWQ zn(qC5G;*-r2sZ2VE3R9B3eUidt$(JwOhtd>EaX+O;n*OUqW^3hEz;-V`1~9Zv$3Z%2oX{`zyV*ZFoG#P_kv`siRF*W_g!otEmF)`6%U>cM7b8UK*-Ic(t z`NMNiU0vfG+qKR*&yr!`h07%UrAhyX(&mcoIsJVS^yrV@Ca-mQX0>S)mQ`^YmT7VN zVNGJu5!*d?QR^@Oq7m{9lq9WJQ=dWZ7X1e821ESUNV+1IoAMQED_lLg$z&KGl9z-n zXjxeRkdZVlf{b{?pL03 zQ*!BF198koVI*OzF)zBmeO)epNeN`$ehx6+x~2KsXLort#=Fk_;g+O$FQnKk3Vlf7 zpVNa_dGCm7c(zZcRWiw#sCP3>XMi;hr%gPp7gRm_eyvP|uUB9nRb3@tHwnE+>U8Yc zQaaS|a!X1*F!2!4Oyvcvu*rP1d}kt!5YAta^C7!oG+DQFmP*Ee*QJ zJQ8EpEHes3HOfI4kFJ7q|x*TFy`wax^-(b+5A`^^82E0<*bsX z-j?}yIXsACCY5AP8IotnI~TsiYU5&4emqafJZnP=H#V198~1Z7`w$g}Gp}fC_BcUB z*7?Wim_qy6UW32J82DI$|LWNGdltd94axExv&+@uL`aY0p;UIaU~AUfGVp!Uv?4vw z(U(>B)^E7*ZBhPwJ9Gjg!zQDGIpz?HA=GlhgBKc&<=W~cvU=t^VwXoBLD>#BSu{E| zi}a)h@p0GgMj0!IDnJWLXTk?QSu_9CWYcH*hKY2qJo-M$fnp3TwLQL>!Xg9OtDbE> za8=rqhm?}bo5;fv zU0{?;@sFUQ1PrMZeO!p*P=~=*T;{=1N1ME2@D|MVWTF15zQ`h3uU4g?Ua(ZM@b2X9 zhaZhP9~vZ1fJ%#Zi)O7+OUCDi9SnNFeC1A1p=$6rq#M3kDWf~*i=esSP2fHZU2X2} zcpt}y9*i&Ahsgfqm-l|2c*a<8HH=Q&AGhF)&@*(U;SOkz2Fdapo!v8vQjZoRQM3@T zqVXxE<0h6yewonzhCZn;fmJSiwUc1wiz&agR;S@@0e0Jo(c8jij7?lVZN=bRnC`vg z=W-Lpm&6-4DiOV#@}JfU5a*ph-fW|`4lbXbm_39hP$`0Ud^oSZ#aASh<98CzeYE6r zh;WO-kf0DZmIiJCMn8|VEe3(t`eIJW6e zY}1hXwPkhS7-KH$vwZzo-IO0>^d3zI8biH(%6x5~j)xLs`UK8Rl?$2`F1l7DnxTY} zmXsEJXVc?*_@{bOXl!$#1`b!XOKN>V{3km}0>_rb@Cz7!?ucFLSfMPouHnk?x5wUL zX`VGNw;3^UD{SA=kHc|@6rB|yC3!;OrEcGWv4VtHI4g@4##`+w*xX9GusX_`xyUMt zksR|DcXpM>h)#JBGx7gaPl27M-IB+8>-ipJQ8Z0?kmH}=Jz5_aiB;(g@dt|d)+3R7 zXsez%aLI`=s>N=J^dQ?5RODWZ{LGz_re&(YJTr+`t3T;}2yLTQtRl_m8sJ`pSs>e4 z?mD>7H#qfXGPGQzqiqhdFcx14^chAee!tQ?Mo0f{)M=QS(jHqIS@aU|I)QiOX6LTl zM*yxN$Ni>eo27sfpQt)5_0rP(*Ew_{oloN*obq~cUA`MVi*=I46*cuU>j#=96SX`> z%rPTz(FA3%xHQnen;k(NwKE61i+;bNV7(K25_td-@Lc-7;;B`ztagmRGkU?+4|z)6 zH|14o%^EEz^JNixm7Z+YkfS)V;d;QR75_9H(*q_b6_9+T)35W|n?m3-Az4=Pa*$U{$1hr^Z!Cz$X*WHAbO6o$&C$H${4HGHkB%MEI*-t zu<6pAo8MY4q}RQ{(O22?Or+GML~y5eIHCi+(PhfX|ES!5Zu+7=O*yDOwPWi&4kPMy z!z}TWVBybuKhr?9=Q43d_@EtP40dv=J)&W|+;s99N%$p1kO4QhxxYL28=E;mp|?0aB56{dI!8UAfElgz zXR#B#DY$T*!>Cnc$e41`L}6%7mEDvUk|pJsIi+hY&`QZlK&+>wB8bh?mV;Z@N&|xX zYs8T-Hqod0mv`l>(n0gVrhDRatwsY3YX#8DK)pjZM&-OJMunYK)v_i|V-*>_Re`C` z<%`mx8=hZrRS2$MPS+I(1ELVf^*^;}U51lwR*>)t(Qo4Ts%6=jc1v5SlyQ*hq6j&< z&x8(3X%8>(%xVA~-X+S_)qC28Ib#Z6*m1@TV4;uStfz!4X-0H6ExaSt7}A%w1Zt?t&Idal)10W>YDZK8p)5W*u2 zFes$Bazzdg7ruNoHD97OIZG&orKig0>xRF}$e&c}9|UaQ{f3iY|i?2RPP(-=l2(!Lp#90zHaE87&$4~*c1q4*!1Bu*t4|Y8^{xm(Y z>@D#Kb1qH8w>t;kLhRf88W!K6P2ZcrAD|a*HihoM$w{F0Ca37Z-AxRMqsDU%bM9`u z^8lMdq-Lat6>seS7Zea@p4DI0D_ijKEmPWFJHKl9^>x3!1~t;yHUhgcv1+1XeBEL@ zot-X;y7Rm}3Mm{!$;3_^s(X-dya@tBm7j(zc`8Hj#+(ynF>Y40;wmbl62XElt(CJE z9z1_kY_8MNLR(aYo;)dSVKKNDOogYwRz+RJQ%;Ru_#pD^bn)#WD~?gvsnQYpDvWSH zihsm$VZdJz`g-wmc4EL^5c)dt9e>?yyBXu5bKQhO=Vje|@5%kVVsyfoer|8l8Y7=~E?%T9 zR@QxP9_@@*Fj{TIw(OEc{j^eHi%_*;RHO4OznSC9VFNn?EcB}y2YeDP1BDft6`K{E z^%o{i9C#RfAbBT^=ij@4aqvUPR7h$ldIDukZQxSM7D0Ijdy#($I}v}1dXxP<_XUZ~ zMQ5zvn3*)u_-NjKKO~z=RmxTN#WvMt@1y5p*F=7k`6_<=9Y`2B8~A~fBBzq+N+rlpH+L46(|$A z3=yHT&`7ZgR<-=JMp^HBTi3_2EwJg30i3FuvH{kX)~5i?mu8`>4z3y5CdaEHuIV}^ z%d0Z3nVTlht3pp{d?wSYQcoG3CfBQCPw74;+pBU*hL=xT1H`xDrldRxI8;$d#B9V< zu2T+EE>ljjF0xLtZc{y+iT6lmT*I8h+`|UA)8N$<_C$Na$E3%`$EaojPH9dpPVr7b zPK8cMPK`>(*5}$6+I!k(+DF<~+Pm5k!qM1eRB56X<>%%yPIv{UKfTvK9Xl^gH^i#j zpiN;8I2WFD$S!QHPGm!{2v@pN=1j)Cu7D|9D|4{SF2c;U!kY6o`>PaU(SlA)=P1f~ zo_#0_NW8AJSLLqATAac*qf^*!%3B&|cWf?#Z_pkmGSphNAHQ#Fimvsp`LroSbH~#! zsGK?fy}eId6KEZU=7nc%R5fsph+|eHF2F6oCBP#i+c3ZPvDe6LBg<1SGG%D?-)6`r zD_t&dGH^0*GjK8R)Ns~t*KpPF*m2tZ+}A!IMJz!9T8AJS;Oz~lS zU#ON1Hn^6NHprGZ#Fn2>SW%p-DQA+l87V8YlXhE|Mmjv(`Ko(}s>c!o+gaN7WR=T| z)zD^VUx(6IRTea3*X0U4gZEYJSVX2J*E81y`XiniRE5tH2I2zccwu{;zq@aA4USu2 zjLhxT+_?Hz=;=N=o>#30?Wx1!oO5ejFsI9=9_bd_eFMYFft6%O4iqg>!ZfQ0)K-Lv z^JM!jVDgQTp9X#rl76h@ikCvVl0ElVqI*1X9l9S&COz@R5c)(@7=>B2T;?uyaX)nL zhWec$K!2K4N}uBl8r#DSJ8GvvP&g)RKcm7Kl@c&!IZ)E&N@Xc=MbC2uvT)ICaQQ$K z3Df}zxi<3&zM-6BPON72w`L8$YWD<;3nZFu`;kS$W6&jf1)KUzkz=L G)cz05(PHWV literal 0 HcmV?d00001 diff --git a/bench/heavy-npm-deps/app/globals.css b/bench/heavy-npm-deps/app/globals.css new file mode 100644 index 0000000000000..6b717ad346d3d --- /dev/null +++ b/bench/heavy-npm-deps/app/globals.css @@ -0,0 +1,21 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + --background: #ffffff; + --foreground: #171717; +} + +@media (prefers-color-scheme: dark) { + :root { + --background: #0a0a0a; + --foreground: #ededed; + } +} + +body { + color: var(--foreground); + background: var(--background); + font-family: Arial, Helvetica, sans-serif; +} diff --git a/bench/heavy-npm-deps/app/layout.js b/bench/heavy-npm-deps/app/layout.js new file mode 100644 index 0000000000000..4504374f3b2cf --- /dev/null +++ b/bench/heavy-npm-deps/app/layout.js @@ -0,0 +1,28 @@ +import localFont from 'next/font/local' +import './globals.css' + +const geistSans = localFont({ + src: './fonts/GeistVF.woff', + variable: '--font-geist-sans', + weight: '100 900', +}) +const geistMono = localFont({ + src: './fonts/GeistMonoVF.woff', + variable: '--font-geist-mono', + weight: '100 900', +}) + +export const metadata = { + title: 'Create Next App', + description: 'Generated by create next app', +} + +export default function RootLayout({ children }) { + return ( + + + {children} + + + ) +} diff --git a/bench/heavy-npm-deps/app/page.js b/bench/heavy-npm-deps/app/page.js new file mode 100644 index 0000000000000..b72213e5df00b --- /dev/null +++ b/bench/heavy-npm-deps/app/page.js @@ -0,0 +1,13 @@ +import { LodashComponent } from '../components/lodash' +// import { MantineComponent } from "../components/mantine"; +// import { MermaidComponent } from "../components/mermaid"; + +export default function Page() { + return ( + <> + {/* */} + {/* */} + + + ) +} diff --git a/bench/heavy-npm-deps/components/lodash.js b/bench/heavy-npm-deps/components/lodash.js new file mode 100644 index 0000000000000..e19abaf41b491 --- /dev/null +++ b/bench/heavy-npm-deps/components/lodash.js @@ -0,0 +1,12 @@ +'use client' +import * as Lodash from 'lodash-es' + +console.log(Lodash) + +export function LodashComponent() { + return ( + <> +

Client Component

+ + ) +} diff --git a/bench/heavy-npm-deps/components/mantine.js b/bench/heavy-npm-deps/components/mantine.js new file mode 100644 index 0000000000000..824bc52ab9d92 --- /dev/null +++ b/bench/heavy-npm-deps/components/mantine.js @@ -0,0 +1,12 @@ +'use client' +import * as Mantine from '@mantine/core' + +console.log(Mantine.Button.Group.classes) + +export function MantineComponent() { + return ( + <> +

Client Component

+ + ) +} diff --git a/bench/heavy-npm-deps/components/mermaid.js b/bench/heavy-npm-deps/components/mermaid.js new file mode 100644 index 0000000000000..68cbc0a54a864 --- /dev/null +++ b/bench/heavy-npm-deps/components/mermaid.js @@ -0,0 +1,13 @@ +'use client' +import * as Mermaid from 'mermaid' + +console.log(Mermaid) +// console.log(Mantine.Button.Group.classes); + +export function MermaidComponent() { + return ( + <> +

Client Component

+ + ) +} diff --git a/bench/heavy-npm-deps/next.config.mjs b/bench/heavy-npm-deps/next.config.mjs new file mode 100644 index 0000000000000..89a9278ccc473 --- /dev/null +++ b/bench/heavy-npm-deps/next.config.mjs @@ -0,0 +1,11 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + eslint: { + ignoreDuringBuilds: true, + }, + typescript: { + ignoreBuildErrors: true, + }, +} + +export default nextConfig diff --git a/bench/heavy-npm-deps/package.json b/bench/heavy-npm-deps/package.json new file mode 100644 index 0000000000000..8ac685a6a81c5 --- /dev/null +++ b/bench/heavy-npm-deps/package.json @@ -0,0 +1,18 @@ +{ + "name": "bench-heavy-npm-deps", + "version": "0.1.0", + "private": true, + "scripts": { + "dev-application": "next dev --turbo", + "build-application": "next build", + "start-application": "next start" + }, + "dependencies": { + "@mantine/core": "^7.10.1", + "lodash-es": "^4.17.21", + "lucide-react": "^0.383.0", + "mermaid": "^10.9.1", + "next": "workspace:*" + }, + "devDependencies": {} +} diff --git a/bench/heavy-npm-deps/postcss.config.mjs b/bench/heavy-npm-deps/postcss.config.mjs new file mode 100644 index 0000000000000..0dc456ad9c95a --- /dev/null +++ b/bench/heavy-npm-deps/postcss.config.mjs @@ -0,0 +1,8 @@ +/** @type {import('postcss-load-config').Config} */ +const config = { + plugins: { + tailwindcss: {}, + }, +} + +export default config diff --git a/bench/heavy-npm-deps/public/file-text.svg b/bench/heavy-npm-deps/public/file-text.svg new file mode 100644 index 0000000000000..9cfb3c98674c3 --- /dev/null +++ b/bench/heavy-npm-deps/public/file-text.svg @@ -0,0 +1,3 @@ + + + diff --git a/bench/heavy-npm-deps/public/globe.svg b/bench/heavy-npm-deps/public/globe.svg new file mode 100644 index 0000000000000..4230a3d2071c4 --- /dev/null +++ b/bench/heavy-npm-deps/public/globe.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/bench/heavy-npm-deps/public/next.svg b/bench/heavy-npm-deps/public/next.svg new file mode 100644 index 0000000000000..5174b28c565c2 --- /dev/null +++ b/bench/heavy-npm-deps/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bench/heavy-npm-deps/public/vercel.svg b/bench/heavy-npm-deps/public/vercel.svg new file mode 100644 index 0000000000000..0164ddc5ad9db --- /dev/null +++ b/bench/heavy-npm-deps/public/vercel.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/bench/heavy-npm-deps/public/window.svg b/bench/heavy-npm-deps/public/window.svg new file mode 100644 index 0000000000000..bbc780069c332 --- /dev/null +++ b/bench/heavy-npm-deps/public/window.svg @@ -0,0 +1,3 @@ + + + diff --git a/bench/heavy-npm-deps/tailwind.config.ts b/bench/heavy-npm-deps/tailwind.config.ts new file mode 100644 index 0000000000000..0707ee4a3a579 --- /dev/null +++ b/bench/heavy-npm-deps/tailwind.config.ts @@ -0,0 +1,19 @@ +import type { Config } from 'tailwindcss' + +const config: Config = { + content: [ + './pages/**/*.{js,ts,jsx,tsx,mdx}', + './components/**/*.{js,ts,jsx,tsx,mdx}', + './app/**/*.{js,ts,jsx,tsx,mdx}', + ], + theme: { + extend: { + colors: { + background: 'var(--background)', + foreground: 'var(--foreground)', + }, + }, + }, + plugins: [], +} +export default config diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4b8b9b6fba08e..518d4019c7113 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -603,6 +603,24 @@ importers: specifier: 16.2.0 version: 16.2.0 + bench/heavy-npm-deps: + dependencies: + '@mantine/core': + specifier: ^7.10.1 + version: 7.10.1(@mantine/hooks@7.10.1)(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + lodash-es: + specifier: ^4.17.21 + version: 4.17.21 + lucide-react: + specifier: ^0.383.0 + version: 0.383.0(react@19.0.0-rc-6230622a1a-20240610) + mermaid: + specifier: ^10.9.1 + version: 10.9.1 + next: + specifier: workspace:* + version: link:../../packages/next + bench/nested-deps: devDependencies: cross-env: @@ -3420,6 +3438,10 @@ packages: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true + /@braintree/sanitize-url@6.0.4: + resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==} + dev: false + /@bundled-es-modules/cookie@2.0.0: resolution: {integrity: sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==} dependencies: @@ -4081,6 +4103,47 @@ packages: resolution: {integrity: sha512-XcdMT5PSZHiuf7LJIhzKIe+RyYa25S3LHRRvLnZc6iFjwXkrSDJ8J/HWO6VT8d2ZTbawp3VcLEjRF/VN8glCrA==} dev: true + /@floating-ui/core@1.6.2: + resolution: {integrity: sha512-+2XpQV9LLZeanU4ZevzRnGFg2neDeKHgFLjP6YLW+tly0IvrhqT4u8enLGjLH3qeh85g19xY5rsAusfwTdn5lg==} + dependencies: + '@floating-ui/utils': 0.2.2 + dev: false + + /@floating-ui/dom@1.6.5: + resolution: {integrity: sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==} + dependencies: + '@floating-ui/core': 1.6.2 + '@floating-ui/utils': 0.2.2 + dev: false + + /@floating-ui/react-dom@2.1.0(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610): + resolution: {integrity: sha512-lNzj5EQmEKn5FFKc04+zasr09h/uX8RtJRNj5gUXsSQIXHVWTVh+hVAg1vOMCexkX8EgvemMvIFpQfkosnVNyA==} + peerDependencies: + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610 + dependencies: + '@floating-ui/dom': 1.6.5 + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + dev: false + + /@floating-ui/react@0.26.16(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610): + resolution: {integrity: sha512-HEf43zxZNAI/E781QIVpYSF3K2VH4TTYZpqecjdsFkjsaU1EbaWcM++kw0HXFffj7gDUcBFevX8s0rQGQpxkow==} + peerDependencies: + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610 + dependencies: + '@floating-ui/react-dom': 2.1.0(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610) + '@floating-ui/utils': 0.2.2 + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + tabbable: 6.2.0 + dev: false + + /@floating-ui/utils@0.2.2: + resolution: {integrity: sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==} + dev: false + /@fullhuman/postcss-purgecss@1.3.0: resolution: {integrity: sha512-zvfS3dPKD2FAtMcXapMJXGbDgEp9E++mLR6lTgSruv6y37uvV5xJ1crVktuC1gvnmMwsa7Zh1m05FeEiz4VnIQ==} dependencies: @@ -5541,6 +5604,34 @@ packages: write-file-atomic: 3.0.3 dev: true + /@mantine/core@7.10.1(@mantine/hooks@7.10.1)(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + resolution: {integrity: sha512-l9ypojKN3PjwO1CSLIsqxi7mA25+7w+xc71Q+JuCCREI0tuGwkZsKbIOpuTATIJOjPh8ycLiW7QxX1LYsRTq6w==} + peerDependencies: + '@mantine/hooks': 7.10.1 + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610 + dependencies: + '@floating-ui/react': 0.26.16(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610) + '@mantine/hooks': 7.10.1(react@19.0.0-rc-6230622a1a-20240610) + clsx: 2.1.1 + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + react-number-format: 5.4.0(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610) + react-remove-scroll: 2.5.10(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react-textarea-autosize: 8.5.3(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + type-fest: 4.18.3 + transitivePeerDependencies: + - '@types/react' + dev: false + + /@mantine/hooks@7.10.1(react@19.0.0-rc-6230622a1a-20240610): + resolution: {integrity: sha512-0EH9WBWUdtQLGU3Ak+csQ77EtUxI6pPNfwZdRJQWcaA3f8SFOLo9h9CGxiikFExerhvuCeUlaTf3s+TB9Op/rw==} + peerDependencies: + react: 19.0.0-rc-6230622a1a-20240610 + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + dev: false + /@mapbox/node-pre-gyp@1.0.5: resolution: {integrity: sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==} hasBin: true @@ -7121,6 +7212,20 @@ packages: '@types/node': 20.12.3 dev: true + /@types/d3-scale-chromatic@3.0.3: + resolution: {integrity: sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==} + dev: false + + /@types/d3-scale@4.0.8: + resolution: {integrity: sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==} + dependencies: + '@types/d3-time': 3.0.3 + dev: false + + /@types/d3-time@3.0.3: + resolution: {integrity: sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==} + dev: false + /@types/debug@4.1.5: resolution: {integrity: sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==} @@ -9819,6 +9924,11 @@ packages: engines: {node: '>=6'} dev: true + /clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + dev: false + /cmd-shim@4.1.0: resolution: {integrity: sha512-lb9L7EM4I/ZRVuljLPEtUJOP+xiQVknZ4ZMpMgEp4JzNldPb27HU03hi6K1/6CoIuit/Zm/LQXySErFeXxDprw==} engines: {node: '>=10'} @@ -10294,6 +10404,12 @@ packages: vary: 1.1.2 dev: true + /cose-base@1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} + dependencies: + layout-base: 1.0.2 + dev: false + /cosmiconfig@2.2.2: resolution: {integrity: sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==} engines: {node: '>=0.12'} @@ -10856,6 +10972,291 @@ packages: find-pkg: 0.1.2 dev: true + /cytoscape-cose-bilkent@4.1.0(cytoscape@3.29.2): + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} + peerDependencies: + cytoscape: ^3.2.0 + dependencies: + cose-base: 1.0.3 + cytoscape: 3.29.2 + dev: false + + /cytoscape@3.29.2: + resolution: {integrity: sha512-2G1ycU28Nh7OHT9rkXRLpCDP30MKH1dXJORZuBhtEhEW7pKwgPi77ImqlCWinouyE1PNepIOGZBOrE84DG7LyQ==} + engines: {node: '>=0.10'} + dev: false + + /d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + dependencies: + internmap: 1.0.1 + dev: false + + /d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + dependencies: + internmap: 2.0.3 + dev: false + + /d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + dev: false + + /d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + dev: false + + /d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + dependencies: + d3-path: 3.1.0 + dev: false + + /d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + dev: false + + /d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + dev: false + + /d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + dependencies: + delaunator: 5.0.1 + dev: false + + /d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + dev: false + + /d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + dev: false + + /d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + dev: false + + /d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + dev: false + + /d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + dependencies: + d3-dsv: 3.0.1 + dev: false + + /d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + dev: false + + /d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + dev: false + + /d3-geo@3.1.1: + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + dev: false + + /d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + dev: false + + /d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + dependencies: + d3-color: 3.1.0 + dev: false + + /d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + dev: false + + /d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + dev: false + + /d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + dev: false + + /d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + dev: false + + /d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + dev: false + + /d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + dev: false + + /d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + dev: false + + /d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + dev: false + + /d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + dev: false + + /d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + dependencies: + d3-path: 1.0.9 + dev: false + + /d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + dependencies: + d3-path: 3.1.0 + dev: false + + /d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + dependencies: + d3-time: 3.1.0 + dev: false + + /d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + dev: false + + /d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + dev: false + + /d3-transition@3.0.1(d3-selection@3.0.0): + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + dev: false + + /d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + dev: false + + /d3@7.9.0: + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.0 + d3-geo: 3.1.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + dev: false + /d@1.0.1: resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==} dependencies: @@ -10863,6 +11264,13 @@ packages: type: 1.2.0 dev: true + /dagre-d3-es@7.0.10: + resolution: {integrity: sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==} + dependencies: + d3: 7.9.0 + lodash-es: 4.17.21 + dev: false + /damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} dev: false @@ -10897,6 +11305,10 @@ packages: resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} dev: true + /dayjs@1.11.11: + resolution: {integrity: sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==} + dev: false + /dd-trace@4.12.0: resolution: {integrity: sha512-QAvlKWUn8Tx75hbos7d7hk/9iCo3tKShd3vGg4mMtl3YWYZd7wsYUtX1PJUS+CjQgOPh2XJuBLAGYoamYYTeBg==} engines: {node: '>=16'} @@ -11173,6 +11585,12 @@ packages: slash: 3.0.0 dev: true + /delaunator@5.0.1: + resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + dependencies: + robust-predicates: 3.0.2 + dev: false + /delay@4.3.0: resolution: {integrity: sha512-Lwaf3zVFDMBop1yDuFZ19F9WyGcZcGacsbdlZtWjQmM50tOcMntm1njF/Nb/Vjij3KaSvCF+sEYGKrrjObu2NA==} engines: {node: '>=6'} @@ -11244,6 +11662,10 @@ packages: engines: {node: '>=8'} dev: true + /detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + dev: false + /detective@5.2.1: resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==} engines: {node: '>=0.8.0'} @@ -11410,6 +11832,10 @@ packages: domelementtype: 2.2.0 dev: true + /dompurify@3.1.5: + resolution: {integrity: sha512-lwG+n5h8QNpxtyrJW/gJWckL+1/DQiYMX8f7t8Z2AZTPw1esVrqjI63i7Zc2Gz0aKzLVMYC1V1PL/ky+aY/NgA==} + dev: false + /domutils@1.5.1: resolution: {integrity: sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==} dependencies: @@ -11552,6 +11978,10 @@ packages: /electron-to-chromium@1.4.637: resolution: {integrity: sha512-G7j3UCOukFtxVO1vWrPQUoDk3kL70mtvjc/DC/k2o7lE0wAdq+Vwp1ipagOow+BH0uVztFysLWbkM/RTIrbK3w==} + /elkjs@0.9.3: + resolution: {integrity: sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==} + dev: false + /elliptic@6.5.3: resolution: {integrity: sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==} dependencies: @@ -13399,6 +13829,11 @@ packages: has-proto: 1.0.1 has-symbols: 1.0.3 + /get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + dev: false + /get-pkg-repo@1.4.0: resolution: {integrity: sha1-xztInAbYDMVTbCyFP54FIyBWly0=} hasBin: true @@ -14399,7 +14834,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 - dev: true /icss-replace-symbols@1.1.0: resolution: {integrity: sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==} @@ -14655,6 +15089,15 @@ packages: has: 1.0.3 side-channel: 1.0.4 + /internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + dev: false + + /internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + dev: false + /interpret@1.4.0: resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} engines: {node: '>= 0.10'} @@ -16475,12 +16918,23 @@ packages: safe-buffer: 5.2.1 dev: true + /katex@0.16.10: + resolution: {integrity: sha512-ZiqaC04tp2O5utMsl2TEZTXxa6WSC4yo0fv5ML++D3QZv/vx2Mct0mTlRx3O+uUkjfuAgOkzsCmq5MiUEsDDdA==} + hasBin: true + dependencies: + commander: 8.3.0 + dev: false + /keyv@3.1.0: resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==} dependencies: json-buffer: 3.0.0 dev: true + /khroma@2.1.0: + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + dev: false + /kind-of@3.2.2: resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} engines: {node: '>=0.10.0'} @@ -16564,6 +17018,10 @@ packages: package-json: 6.5.0 dev: true + /layout-base@1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + dev: false + /lazy-cache@1.0.4: resolution: {integrity: sha512-RE2g0b5VGZsOCFOCgP7omTRYFqydmZkBwl5oNnQ1lDYC57uyO9KqNnNVxT7COSHTxrRCWVcAVOcbjk+tvh/rgQ==} engines: {node: '>=0.10.0'} @@ -16836,6 +17294,10 @@ packages: dependencies: p-locate: 5.0.0 + /lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: false + /lodash._reinterpolate@3.0.0: resolution: {integrity: sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=} dev: true @@ -17079,6 +17541,14 @@ packages: engines: {node: '>=12'} dev: true + /lucide-react@0.383.0(react@19.0.0-rc-6230622a1a-20240610): + resolution: {integrity: sha512-13xlG0CQCJtzjSQYwwJ3WRqMHtRj3EXmLlorrARt7y+IHnxUCp3XyFNL1DfaGySWxHObDvnu1u1dV+0VMKHUSg==} + peerDependencies: + react: 19.0.0-rc-6230622a1a-20240610 + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + dev: false + /lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -17476,6 +17946,33 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + /mermaid@10.9.1: + resolution: {integrity: sha512-Mx45Obds5W1UkW1nv/7dHRsbfMM1aOKA2+Pxs/IGHNonygDHwmng8xTHyS9z4KWVi0rbko8gjiBmuwwXQ7tiNA==} + dependencies: + '@braintree/sanitize-url': 6.0.4 + '@types/d3-scale': 4.0.8 + '@types/d3-scale-chromatic': 3.0.3 + cytoscape: 3.29.2 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.29.2) + d3: 7.9.0 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.10 + dayjs: 1.11.11 + dompurify: 3.1.5 + elkjs: 0.9.3 + katex: 0.16.10 + khroma: 2.1.0 + lodash-es: 4.17.21 + mdast-util-from-markdown: 1.3.0 + non-layered-tidy-tree-layout: 2.0.2 + stylis: 4.2.0 + ts-dedent: 2.2.0 + uuid: 9.0.1 + web-worker: 1.3.0 + transitivePeerDependencies: + - supports-color + dev: false + /methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} @@ -18518,6 +19015,10 @@ packages: engines: {node: '>=6.0.0'} dev: true + /non-layered-tidy-tree-layout@2.0.2: + resolution: {integrity: sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==} + dev: false + /nopt@4.0.3: resolution: {integrity: sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==} hasBin: true @@ -21399,11 +21900,57 @@ packages: resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} dev: true + /react-number-format@5.4.0(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610): + resolution: {integrity: sha512-NWdICrqLhI7rAS8yUeLVd6Wr4cN7UjJ9IBTS0f/a9i7UB4x4Ti70kGnksBtZ7o4Z7YRbvCMMR/jQmkoOBa/4fg==} + peerDependencies: + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610 + dependencies: + prop-types: 15.8.1 + react: 19.0.0-rc-6230622a1a-20240610 + react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + dev: false + /react-refresh@0.12.0: resolution: {integrity: sha512-suLIhrU2IHKL5JEKR/fAwJv7bbeq4kJ+pJopf77jHwuR+HmJS/HbrPIGsTBUVfw7tXPOmYv7UJ7PCaN49e8x4A==} engines: {node: '>=0.10.0'} dev: true + /react-remove-scroll-bar@2.3.6(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: 19.0.0-rc-6230622a1a-20240610 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': /types-react@19.0.0-rc.0 + react: 19.0.0-rc-6230622a1a-20240610 + react-style-singleton: 2.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + tslib: 2.6.2 + dev: false + + /react-remove-scroll@2.5.10(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + resolution: {integrity: sha512-m3zvBRANPBw3qxVVjEIPEQinkcwlFZ4qyomuWVpNJdv4c6MvHfXV0C3L9Jx5rr3HeBHKNRX+1jreB5QloDIJjA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: 19.0.0-rc-6230622a1a-20240610 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': /types-react@19.0.0-rc.0 + react: 19.0.0-rc-6230622a1a-20240610 + react-remove-scroll-bar: 2.3.6(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + react-style-singleton: 2.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + tslib: 2.6.2 + use-callback-ref: 1.3.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + use-sidecar: 1.1.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + dev: false + /react-server-dom-turbopack@0.0.0-experimental-6230622a1a-20240610(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610): resolution: {integrity: sha512-U/7v8k6XS+EPSn46S8/7igwIkNdlfLRjWOCYNxXRs1/nC/BQa/gYUti4bGrMJ7b/2h7WWIHQOdGZRxOvUKIBHg==} engines: {node: '>=0.10.0'} @@ -21471,6 +22018,37 @@ packages: react-is: 19.0.0-rc-6230622a1a-20240610 dev: true + /react-style-singleton@2.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: 19.0.0-rc-6230622a1a-20240610 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': /types-react@19.0.0-rc.0 + get-nonce: 1.0.1 + invariant: 2.2.4 + react: 19.0.0-rc-6230622a1a-20240610 + tslib: 2.6.2 + dev: false + + /react-textarea-autosize@8.5.3(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + resolution: {integrity: sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ==} + engines: {node: '>=10'} + peerDependencies: + react: 19.0.0-rc-6230622a1a-20240610 + dependencies: + '@babel/runtime': 7.22.5 + react: 19.0.0-rc-6230622a1a-20240610 + use-composed-ref: 1.3.0(react@19.0.0-rc-6230622a1a-20240610) + use-latest: 1.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + transitivePeerDependencies: + - '@types/react' + dev: false + /react-virtualized@9.22.3(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610): resolution: {integrity: sha512-MKovKMxWTcwPSxE1kK1HcheQTWfuCxAuBoSTf2gwyMM21NdX/PXUhnoP8Uc5dRKd+nKm8v41R36OellhdCpkrw==} peerDependencies: @@ -22287,6 +22865,10 @@ packages: inherits: 2.0.4 dev: true + /robust-predicates@3.0.2: + resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + dev: false + /rollup-plugin-bundle-size@1.0.3: resolution: {integrity: sha512-aWj0Pvzq90fqbI5vN1IvUrlf4utOqy+AERYxwWjegH1G8PzheMnrRIgQ5tkwKVtQMDP0bHZEACW/zLDF+XgfXQ==} dependencies: @@ -22382,6 +22964,10 @@ packages: dependencies: queue-microtask: 1.2.3 + /rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + dev: false + /rxjs@5.5.12: resolution: {integrity: sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==} engines: {npm: '>=2.0.0'} @@ -23629,7 +24215,6 @@ packages: /stylis@4.2.0: resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} - dev: true /superagent@3.8.3: resolution: {integrity: sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==} @@ -23766,6 +24351,10 @@ packages: tslib: 2.6.2 dev: false + /tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + dev: false + /table@6.8.0: resolution: {integrity: sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==} engines: {node: '>=10.0.0'} @@ -24265,6 +24854,11 @@ packages: typescript: 5.3.3 dev: true + /ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + dev: false + /tsconfig-paths@3.14.2: resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} dependencies: @@ -24467,7 +25061,6 @@ packages: /type-fest@4.18.3: resolution: {integrity: sha512-Q08/0IrpvM+NMY9PA2rti9Jb+JejTddwmwmVQGskAlhtcrw1wsRzoR6ode6mR+OAabNa75w/dxedSUY2mlphaQ==} engines: {node: '>=16'} - dev: true /type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} @@ -25008,6 +25601,72 @@ packages: engines: {node: '>= 4'} dev: true + /use-callback-ref@1.3.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: 19.0.0-rc-6230622a1a-20240610 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': /types-react@19.0.0-rc.0 + react: 19.0.0-rc-6230622a1a-20240610 + tslib: 2.6.2 + dev: false + + /use-composed-ref@1.3.0(react@19.0.0-rc-6230622a1a-20240610): + resolution: {integrity: sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==} + peerDependencies: + react: 19.0.0-rc-6230622a1a-20240610 + dependencies: + react: 19.0.0-rc-6230622a1a-20240610 + dev: false + + /use-isomorphic-layout-effect@1.1.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==} + peerDependencies: + '@types/react': '*' + react: 19.0.0-rc-6230622a1a-20240610 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': /types-react@19.0.0-rc.0 + react: 19.0.0-rc-6230622a1a-20240610 + dev: false + + /use-latest@1.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + resolution: {integrity: sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==} + peerDependencies: + '@types/react': '*' + react: 19.0.0-rc-6230622a1a-20240610 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': /types-react@19.0.0-rc.0 + react: 19.0.0-rc-6230622a1a-20240610 + use-isomorphic-layout-effect: 1.1.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) + dev: false + + /use-sidecar@1.1.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': npm:types-react@19.0.0-rc.0 + react: 19.0.0-rc-6230622a1a-20240610 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': /types-react@19.0.0-rc.0 + detect-node-es: 1.1.0 + react: 19.0.0-rc-6230622a1a-20240610 + tslib: 2.6.2 + dev: false + /use-sync-external-store@1.2.0(react@19.0.0-rc-6230622a1a-20240610): resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} peerDependencies: @@ -25066,6 +25725,11 @@ packages: hasBin: true dev: true + /uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + dev: false + /uvu@0.5.6: resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} engines: {node: '>=8'} @@ -25249,6 +25913,10 @@ packages: resolution: {integrity: sha512-3Gh6rH5aetFYqfkl9V59KCvjj9vp9U2Tkaep9MO+xpAVg+JULmQfi5zEkcPLkE6iU8pNYVwdjHvIU8RFAchYyQ==} dev: true + /web-worker@1.3.0: + resolution: {integrity: sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==} + dev: false + /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: true From ac46ffe08f5cdd8490dfef4226d0116724c0ebd2 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Wed, 12 Jun 2024 07:38:02 -0700 Subject: [PATCH 46/60] disable deploy tests for incompatible suites (#66776) This disables tests that should not be run in a deployed environment, because they use incompatible APIs or there's no reason to test them outside of `next start`. Specifically disables for things like: - Using `next.patchFile`, `next.renameFile`, etc. - Attempting to use `next.cliOutput` to query runtime logs. When deployed, these are only build-time logs. [Latest Run](https://github.com/vercel/next.js/actions/runs/9483807368) --- .github/workflows/test_e2e_deploy_release.yml | 2 +- test/deploy-tests-manifest.json | 43 ++++++++----------- .../e2e/app-dir/app-compilation/index.test.ts | 6 ++- .../e2e/app-dir/app-static/app-static.test.ts | 19 ++++---- .../conflicting-page-segments.test.ts | 5 ++- .../missing-suspense-with-csr-bailout.test.ts | 2 + .../e2e/app-dir/navigation/navigation.test.ts | 2 +- test/e2e/app-dir/next-after-app/index.test.ts | 6 ++- .../next-image/next-image-proxy.test.ts | 6 ++- .../avoid-popstate-flash.test.ts | 6 ++- .../loading-tsx-no-partial-rendering.test.ts | 6 ++- .../stale-prefetch-entry.test.ts | 6 ++- .../compilation-and-prefixing.test.ts | 7 ++- .../server-components-externals/index.test.ts | 6 ++- .../static-shell-debugging.test.ts | 7 ++- .../typeof-window/typeof-window.test.ts | 7 ++- .../webpack-loader-conditions.test.ts | 6 ++- .../x-forwarded-headers.test.ts | 10 ++++- .../index.test.ts | 7 +++ .../favicon-short-circuit.test.ts | 4 +- .../i18n-data-route/i18n-data-route.test.ts | 7 ++- test/e2e/next-phase/index.test.ts | 7 ++- test/e2e/next-test/next-test.test.ts | 6 ++- .../tsconfig-module-preserve/index.test.ts | 6 ++- 24 files changed, 129 insertions(+), 60 deletions(-) diff --git a/.github/workflows/test_e2e_deploy_release.yml b/.github/workflows/test_e2e_deploy_release.yml index 8cb8aa5c546cf..8f5f07e321af0 100644 --- a/.github/workflows/test_e2e_deploy_release.yml +++ b/.github/workflows/test_e2e_deploy_release.yml @@ -47,7 +47,7 @@ jobs: strategy: fail-fast: true matrix: - group: [1/5, 2/5, 3/5, 4/5, 5/5] + group: [1/5, 2/5, 3/5, 4/5, 5/5, 6/6] with: afterBuild: NEXT_TEST_MODE=deploy NEXT_EXTERNAL_TESTS_FILTERS="test/deploy-tests-manifest.json" node run-tests.js --timings -g ${{ matrix.group }} -c 2 --type e2e skipNativeBuild: 'yes' diff --git a/test/deploy-tests-manifest.json b/test/deploy-tests-manifest.json index 132772f6c2d10..a8024b206ae6c 100644 --- a/test/deploy-tests-manifest.json +++ b/test/deploy-tests-manifest.json @@ -1,72 +1,65 @@ { "version": 2, - "suites": {}, + "suites": { + "test/e2e/app-dir/app-static/app-static.test.ts": { + "failed": [ + "app-dir static/dynamic handling new tags have been specified on subsequent fetch should not fetch from memory cache", + "app-dir static/dynamic handling new tags have been specified on subsequent fetch should not fetch from memory cache after revalidateTag is used" + ] + }, + "test/e2e/app-dir/metadata/metadata.test.ts": { + "failed": [ + "app dir - metadata navigation should render root not-found with default metadata", + "app dir - metadata react cache should have same title and page value on initial load", + "app dir - metadata react cache should have same title and page value when navigating" + ] + }, + "test/e2e/middleware-rewrites/test/index.test.ts": { + "failed": ["Middleware Rewrite should handle catch-all rewrite correctly"] + } + }, "rules": { "include": [ "test/e2e/**/*.test.{t,j}s{,x}", "test/production/**/*.test.{t,j}s{,x}" ], "exclude": [ - "test/e2e/app-dir/next-after-app/index.test.ts", "test/e2e/app-dir/scss/nm-module-nested/nm-module-nested.test.ts", "test/e2e/cancel-request/stream-cancel.test.ts", "test/e2e/edge-pages-support/edge-document.test.ts", "test/e2e/new-link-behavior/material-ui.test.ts", "test/e2e/react-dnd-compile/react-dnd-compile.test.ts", - "test/e2e/next-test/next-test.test.ts", "test/e2e/skip-trailing-slash-redirect/index.test.ts", - "test/e2e/tsconfig-module-preserve/index.test.ts", "test/e2e/app-dir/app-compilation/index.test.ts", "test/e2e/app-dir/parallel-route-not-found-params/parallel-route-not-found-params.test.ts", - "test/e2e/app-dir/ppr-navigations/loading-tsx-no-partial-rendering/loading-tsx-no-partial-rendering.test.ts", "test/e2e/app-dir/ppr/ppr.test.ts", "test/e2e/app-dir/rsc-webpack-loader/rsc-webpack-loader.test.ts", - "test/e2e/app-dir/scss/compilation-and-prefixing/compilation-and-prefixing.test.ts", - "test/e2e/app-dir/typeof-window/typeof-window.test.ts", - "test/e2e/app-dir/webpack-loader-conditions/webpack-loader-conditions.test.ts", - "test/e2e/app-dir/x-forwarded-headers/x-forwarded-headers.test.ts", - "test/e2e/edge-compiler-module-exports-preference/index.test.ts", "test/e2e/swc-warnings/index.test.ts", "test/e2e/third-parties/index.test.ts", - "test/e2e/useselectedlayoutsegment-s-in-pages-router/useselectedlayoutsegment-s-in-pages-router.test.ts", "test/e2e/app-dir/app-prefetch-false-loading/app-prefetch-false-loading.test.ts", "test/e2e/app-dir/app-routes-client-component/app-routes-client-component.test.ts", "test/e2e/app-dir/app-routes/app-custom-route-base-path.test.ts", "test/e2e/app-dir/mdx/mdx.test.ts", "test/e2e/app-dir/modularizeimports/modularizeimports.test.ts", - "test/e2e/app-dir/navigation/navigation.test.ts", "test/e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts", - "test/e2e/app-dir/ppr-navigations/avoid-popstate-flash/avoid-popstate-flash.test.ts", - "test/e2e/app-dir/server-components-externals/index.test.ts", "test/e2e/app-dir/third-parties/basic.test.ts", - "test/e2e/edge-can-read-request-body/index.test.ts", "test/e2e/esm-externals/esm-externals.test.ts", - "test/e2e/i18n-data-route/i18n-data-route.test.ts", - "test/e2e/next-phase/index.test.ts", "test/e2e/app-dir/actions-navigation/index.test.ts", "test/e2e/app-dir/app-static/app-static-custom-handler.test.ts", - "test/e2e/app-dir/conflicting-page-segments/conflicting-page-segments.test.ts", - "test/e2e/app-dir/interception-route-prefetch-cache/interception-route-prefetch-cache.test.ts", - "test/e2e/app-dir/missing-suspense-with-csr-bailout/missing-suspense-with-csr-bailout.test.ts", "test/e2e/app-dir/options-request/options-request.test.ts", - "test/e2e/app-dir/next-image/next-image-proxy.test.ts", - "test/e2e/app-dir/ppr-navigations/stale-prefetch-entry/stale-prefetch-entry.test.ts", "test/e2e/app-dir/parallel-routes-revalidation/parallel-routes-revalidation.test.ts", "test/e2e/app-dir/revalidate-dynamic/revalidate-dynamic.test.ts", "test/e2e/app-dir/scss/npm-import-nested/npm-import-nested.test.ts", "test/e2e/app-dir/syntax-highlighter-crash/syntax-highlighter-crash.test.ts", - "test/e2e/favicon-short-circuit/favicon-short-circuit.test.ts", "test/e2e/new-link-behavior/stitches.test.ts", "test/e2e/next-image-forward-ref/index.test.ts", "test/e2e/react-compiler/react-compiler.test.ts", "test/e2e/revalidate-reason/revalidate-reason.test.ts", - "test/e2e/app-dir/app-static/app-static.test.ts", "test/e2e/app-dir/actions/app-action.test.ts", "test/e2e/app-dir/i18n-hybrid/i18n-hybrid.test.js", "test/e2e/app-dir/metadata/metadata.test.ts", "test/e2e/app-dir/rsc-basic/rsc-basic.test.ts", "test/e2e/app-dir/scss/nm-module/nm-module.test.ts", - "test/e2e/app-dir/static-shell-debugging/static-shell-debugging.test.ts", "test/e2e/basepath.test.ts", "test/e2e/postcss-config-cjs/index.test.ts", "test/e2e/socket-io/index.test.js", diff --git a/test/e2e/app-dir/app-compilation/index.test.ts b/test/e2e/app-dir/app-compilation/index.test.ts index ca3b330860ef9..e1ff36fd17d8c 100644 --- a/test/e2e/app-dir/app-compilation/index.test.ts +++ b/test/e2e/app-dir/app-compilation/index.test.ts @@ -2,10 +2,14 @@ import { nextTestSetup } from 'e2e-utils' import { check, hasRedbox, waitFor } from 'next-test-utils' describe('app dir', () => { - const { next, isNextDev, isNextStart } = nextTestSetup({ + const { next, isNextDev, isNextStart, skipped } = nextTestSetup({ files: __dirname, + // This is skipped when deployed because there are no assertions outside of next start/next dev + skipDeployment: true, }) + if (skipped) return + if (isNextStart) { describe('Loading', () => { it('should render loading.js in initial html for slow page', async () => { diff --git a/test/e2e/app-dir/app-static/app-static.test.ts b/test/e2e/app-dir/app-static/app-static.test.ts index ef7a78f27f3d5..2f5d0b4d950af 100644 --- a/test/e2e/app-dir/app-static/app-static.test.ts +++ b/test/e2e/app-dir/app-static/app-static.test.ts @@ -82,14 +82,17 @@ describe('app-dir static/dynamic handling', () => { expect(echoedHeaders.headers.traceparent).toEqual('C') }) - it('should warn for too many cache tags', async () => { - const res = await next.fetch('/too-many-cache-tags') - expect(res.status).toBe(200) - await retry(() => { - expect(next.cliOutput).toContain('exceeded max tag count for') - expect(next.cliOutput).toContain('tag-65') + // Runtime logs aren't queryable in deploy mode + if (!isNextDeploy) { + it('should warn for too many cache tags', async () => { + const res = await next.fetch('/too-many-cache-tags') + expect(res.status).toBe(200) + await retry(() => { + expect(next.cliOutput).toContain('exceeded max tag count for') + expect(next.cliOutput).toContain('tag-65') + }) }) - }) + } if (isNextDeploy) { describe('new tags have been specified on subsequent fetch', () => { @@ -115,7 +118,7 @@ describe('app-dir static/dynamic handling', () => { expect(res1.status).toBe(200) const revalidateRes = await next.fetch( - '/api/revlidate-tag-node?tag=thankyounext' + '/api/revalidate-tag-node?tag=thankyounext' ) expect((await revalidateRes.json()).revalidated).toBe(true) diff --git a/test/e2e/app-dir/conflicting-page-segments/conflicting-page-segments.test.ts b/test/e2e/app-dir/conflicting-page-segments/conflicting-page-segments.test.ts index 7ef3048788c2b..5c86f04d47e53 100644 --- a/test/e2e/app-dir/conflicting-page-segments/conflicting-page-segments.test.ts +++ b/test/e2e/app-dir/conflicting-page-segments/conflicting-page-segments.test.ts @@ -4,9 +4,10 @@ import { check } from 'next-test-utils' describe('conflicting-page-segments', () => { const { next, isNextDev, skipped } = nextTestSetup({ files: __dirname, - // we skip start because the build will fail and we won't be able to catch it - // start is re-triggered but caught in the assertions below + // we skip start & deploy because the build will fail and we won't be able to catch it + // start is re-triggered but caught in the assertions below. skipStart: true, + skipDeployment: true, }) if (skipped) { diff --git a/test/e2e/app-dir/missing-suspense-with-csr-bailout/missing-suspense-with-csr-bailout.test.ts b/test/e2e/app-dir/missing-suspense-with-csr-bailout/missing-suspense-with-csr-bailout.test.ts index e03cc41cc1ba3..f946e36634618 100644 --- a/test/e2e/app-dir/missing-suspense-with-csr-bailout/missing-suspense-with-csr-bailout.test.ts +++ b/test/e2e/app-dir/missing-suspense-with-csr-bailout/missing-suspense-with-csr-bailout.test.ts @@ -4,6 +4,8 @@ describe('missing-suspense-with-csr-bailout', () => { const { next, isNextDev, skipped } = nextTestSetup({ files: __dirname, skipStart: true, + // This test is skipped when deployed because it's not possible to rename files after deployment. + skipDeployment: true, }) if (skipped) { diff --git a/test/e2e/app-dir/navigation/navigation.test.ts b/test/e2e/app-dir/navigation/navigation.test.ts index fde14d85ed6f1..787f6a04f8e79 100644 --- a/test/e2e/app-dir/navigation/navigation.test.ts +++ b/test/e2e/app-dir/navigation/navigation.test.ts @@ -176,7 +176,7 @@ describe('app dir - navigation', () => { ) } - if (isNextStart) { + if (isNextStart || isNextDeploy) { await browser.waitForIdleNetwork() // there should be an RSC call for the prefetch expect(hasRscRequest).toBe(true) diff --git a/test/e2e/app-dir/next-after-app/index.test.ts b/test/e2e/app-dir/next-after-app/index.test.ts index 8e89682e82d9a..827d028de1f20 100644 --- a/test/e2e/app-dir/next-after-app/index.test.ts +++ b/test/e2e/app-dir/next-after-app/index.test.ts @@ -15,13 +15,17 @@ describe.each(runtimes)('unstable_after() in %s runtime', (runtimeValue) => { const logFileDir = fs.mkdtempSync(path.join(os.tmpdir(), 'logs-')) const logFile = path.join(logFileDir, 'logs.jsonl') - const { next, isNextDev, isNextDeploy } = nextTestSetup({ + const { next, isNextDev, isNextDeploy, skipped } = nextTestSetup({ files: __dirname, + // `patchFile` and reading runtime logs are not supported in a deployed environment + skipDeployment: true, env: { PERSISTENT_LOG_FILE: logFile, }, }) + if (skipped) return + { const originalContents: Record = {} diff --git a/test/e2e/app-dir/next-image/next-image-proxy.test.ts b/test/e2e/app-dir/next-image/next-image-proxy.test.ts index 8ed8d71efc7da..4c55a1b202635 100644 --- a/test/e2e/app-dir/next-image/next-image-proxy.test.ts +++ b/test/e2e/app-dir/next-image/next-image-proxy.test.ts @@ -10,10 +10,14 @@ let proxyPort let proxyServer: https.Server describe('next-image-proxy', () => { - const { next } = nextTestSetup({ + const { next, skipped } = nextTestSetup({ files: __dirname, + // This test is skipped when deployed because it relies on a proxy server + skipDeployment: true, }) + if (skipped) return + beforeAll(async () => { proxyPort = await findPort() diff --git a/test/e2e/app-dir/ppr-navigations/avoid-popstate-flash/avoid-popstate-flash.test.ts b/test/e2e/app-dir/ppr-navigations/avoid-popstate-flash/avoid-popstate-flash.test.ts index b01be368aed90..668ec28b13bdc 100644 --- a/test/e2e/app-dir/ppr-navigations/avoid-popstate-flash/avoid-popstate-flash.test.ts +++ b/test/e2e/app-dir/ppr-navigations/avoid-popstate-flash/avoid-popstate-flash.test.ts @@ -4,8 +4,10 @@ import { createTestDataServer } from 'test-data-service/writer' import { createTestLog } from 'test-log' describe('avoid-popstate-flash', () => { - if ((global as any).isNextDev) { - test('ppr is disabled in dev', () => {}) + if ((global as any).isNextDev || (global as any).isNextDeploy) { + // this is skipped in dev because PPR is not enabled in dev + // and in deploy we can't rely on this test data service existing + test('should skip dev & deploy', () => {}) return } diff --git a/test/e2e/app-dir/ppr-navigations/loading-tsx-no-partial-rendering/loading-tsx-no-partial-rendering.test.ts b/test/e2e/app-dir/ppr-navigations/loading-tsx-no-partial-rendering/loading-tsx-no-partial-rendering.test.ts index 44d102054badf..4e77ab4a5cd5e 100644 --- a/test/e2e/app-dir/ppr-navigations/loading-tsx-no-partial-rendering/loading-tsx-no-partial-rendering.test.ts +++ b/test/e2e/app-dir/ppr-navigations/loading-tsx-no-partial-rendering/loading-tsx-no-partial-rendering.test.ts @@ -4,8 +4,10 @@ import { createTestDataServer } from 'test-data-service/writer' import { createTestLog } from 'test-log' describe('loading-tsx-no-partial-rendering', () => { - if ((global as any).isNextDev) { - test('ppr is disabled in dev', () => {}) + if ((global as any).isNextDev || (global as any).isNextDeploy) { + // this is skipped in dev because PPR is not enabled in dev + // and in deploy we can't rely on this test data service existing + test('should skip dev & deploy', () => {}) return } diff --git a/test/e2e/app-dir/ppr-navigations/stale-prefetch-entry/stale-prefetch-entry.test.ts b/test/e2e/app-dir/ppr-navigations/stale-prefetch-entry/stale-prefetch-entry.test.ts index 6cb1e5b6717aa..33b0c84389932 100644 --- a/test/e2e/app-dir/ppr-navigations/stale-prefetch-entry/stale-prefetch-entry.test.ts +++ b/test/e2e/app-dir/ppr-navigations/stale-prefetch-entry/stale-prefetch-entry.test.ts @@ -4,8 +4,10 @@ import { createTestDataServer } from 'test-data-service/writer' import { createTestLog } from 'test-log' describe('stale-prefetch-entry', () => { - if ((global as any).isNextDev) { - test('ppr is disabled in dev', () => {}) + if ((global as any).isNextDev || (global as any).isNextDeploy) { + // this is skipped in dev because PPR is not enabled in dev + // and in deploy we can't rely on this test data service existing + test('should skip dev & deploy', () => {}) return } diff --git a/test/e2e/app-dir/scss/compilation-and-prefixing/compilation-and-prefixing.test.ts b/test/e2e/app-dir/scss/compilation-and-prefixing/compilation-and-prefixing.test.ts index 5ccd91af24d45..f37e7c8dd6724 100644 --- a/test/e2e/app-dir/scss/compilation-and-prefixing/compilation-and-prefixing.test.ts +++ b/test/e2e/app-dir/scss/compilation-and-prefixing/compilation-and-prefixing.test.ts @@ -5,14 +5,17 @@ import { readdir, readFile } from 'fs-extra' import { join } from 'path' describe('SCSS Support', () => { - const { next, isNextDev } = nextTestSetup({ + const { next, isNextDev, skipped } = nextTestSetup({ files: __dirname, + // This test is skipped because it is reading files in the `.next` file which + // isn't available/necessary in a deployment environment. + skipDeployment: true, dependencies: { sass: '1.54.0', }, }) - // TODO: Figure out this test for dev and Turbopack + if (skipped) return // TODO: Figure out this test for dev and Turbopack ;(isNextDev ? describe.skip : describe)('Production only', () => { describe('CSS Compilation and Prefixing', () => { it(`should've compiled and prefixed`, async () => { diff --git a/test/e2e/app-dir/server-components-externals/index.test.ts b/test/e2e/app-dir/server-components-externals/index.test.ts index cad7e4c60e6bc..dcc7da157cfa3 100644 --- a/test/e2e/app-dir/server-components-externals/index.test.ts +++ b/test/e2e/app-dir/server-components-externals/index.test.ts @@ -2,10 +2,14 @@ import path from 'path' import { nextTestSetup } from 'e2e-utils' describe('app-dir - server components externals', () => { - const { next, isTurbopack } = nextTestSetup({ + const { next, isTurbopack, skipped } = nextTestSetup({ + // This test is skipped when deployed because it relies on manually patched `node_modules` + skipDeployment: true, files: __dirname, }) + if (skipped) return + it('should have externals for those in config.serverExternalPackages', async () => { const $ = await next.render$('/') diff --git a/test/e2e/app-dir/static-shell-debugging/static-shell-debugging.test.ts b/test/e2e/app-dir/static-shell-debugging/static-shell-debugging.test.ts index 438f371a53777..9a433f20bb82f 100644 --- a/test/e2e/app-dir/static-shell-debugging/static-shell-debugging.test.ts +++ b/test/e2e/app-dir/static-shell-debugging/static-shell-debugging.test.ts @@ -7,8 +7,11 @@ describe('static-shell-debugging', () => { { ppr: true, debugging: false }, { ppr: false, debugging: false }, ])('ppr = $ppr, debugging = $debugging', (context) => { - const { next } = nextTestSetup({ + const { next, skipped } = nextTestSetup({ files: __dirname, + // This test skips deployment because env vars that are doubled underscore prefixed + // are not supported. This is also intended to be used in development. + skipDeployment: true, env: { __NEXT_EXPERIMENTAL_STATIC_SHELL_DEBUGGING: context.debugging ? '1' @@ -17,6 +20,8 @@ describe('static-shell-debugging', () => { nextConfig: { experimental: { ppr: context.ppr } }, }) + if (skipped) return + if (context.debugging && context.ppr) { it('should only render the static shell', async () => { const res = await next.fetch('/?__nextppronly=1') diff --git a/test/e2e/app-dir/typeof-window/typeof-window.test.ts b/test/e2e/app-dir/typeof-window/typeof-window.test.ts index b02b59096404a..07646a8501e05 100644 --- a/test/e2e/app-dir/typeof-window/typeof-window.test.ts +++ b/test/e2e/app-dir/typeof-window/typeof-window.test.ts @@ -2,13 +2,18 @@ import { nextTestSetup } from 'e2e-utils' import path from 'path' describe('typeof-window', () => { - const { next } = nextTestSetup({ + const { next, skipped } = nextTestSetup({ files: __dirname, + // This test is skipped when deployed because the local tarball appears corrupted + // It also doesn't seem particularly useful to test when deployed + skipDeployment: true, dependencies: { 'my-differentiated-files': `file:${path.join(__dirname, 'my-differentiated-files.tar')}`, }, }) + if (skipped) return + it('should work using cheerio', async () => { const $ = await next.render$('/') expect($('h1').text()).toBe('Page loaded') diff --git a/test/e2e/app-dir/webpack-loader-conditions/webpack-loader-conditions.test.ts b/test/e2e/app-dir/webpack-loader-conditions/webpack-loader-conditions.test.ts index dee31769031af..dd1b592292755 100644 --- a/test/e2e/app-dir/webpack-loader-conditions/webpack-loader-conditions.test.ts +++ b/test/e2e/app-dir/webpack-loader-conditions/webpack-loader-conditions.test.ts @@ -1,11 +1,13 @@ import { nextTestSetup } from 'e2e-utils' describe('webpack-loader-conditions', () => { - const { next, isTurbopack } = nextTestSetup({ + const { next, isTurbopack, skipped } = nextTestSetup({ files: __dirname, + // This test is skipped because it's only expected to run in turbopack, which isn't enabled for builds + skipDeployment: true, }) - if (!isTurbopack) { + if (!isTurbopack || skipped) { it('should only run the test in turbopack', () => {}) return } diff --git a/test/e2e/app-dir/x-forwarded-headers/x-forwarded-headers.test.ts b/test/e2e/app-dir/x-forwarded-headers/x-forwarded-headers.test.ts index cfa0f57b24627..c35db95de98a8 100644 --- a/test/e2e/app-dir/x-forwarded-headers/x-forwarded-headers.test.ts +++ b/test/e2e/app-dir/x-forwarded-headers/x-forwarded-headers.test.ts @@ -1,7 +1,15 @@ import { nextTestSetup } from 'e2e-utils' describe('x-forwarded-headers', () => { - const { next } = nextTestSetup({ files: __dirname }) + const { next, skipped } = nextTestSetup({ + files: __dirname, + // This test is skipped because it sends requests with manipulated host headers + // which doesn't work in a deployed environment + skipDeployment: true, + }) + + if (skipped) return + it('should include x-forwarded-* headers', async () => { const res = await next.fetch('/') const headers = await res.json() diff --git a/test/e2e/edge-compiler-module-exports-preference/index.test.ts b/test/e2e/edge-compiler-module-exports-preference/index.test.ts index b070ad97ddbbd..83f72f550457e 100644 --- a/test/e2e/edge-compiler-module-exports-preference/index.test.ts +++ b/test/e2e/edge-compiler-module-exports-preference/index.test.ts @@ -5,6 +5,13 @@ import { fetchViaHTTP, shouldRunTurboDevTest } from 'next-test-utils' describe('Edge compiler module exports preference', () => { let next: NextInstance + if ((global as any).isNextDeploy) { + // this test is skipped when deployed because it manually creates a package in the node_modules directory + // which is unsupported + it('should skip next deploy', () => {}) + return + } + beforeAll(async () => { next = await createNext({ files: { diff --git a/test/e2e/favicon-short-circuit/favicon-short-circuit.test.ts b/test/e2e/favicon-short-circuit/favicon-short-circuit.test.ts index ee798b7a54ca8..049e9d6f5c3dd 100644 --- a/test/e2e/favicon-short-circuit/favicon-short-circuit.test.ts +++ b/test/e2e/favicon-short-circuit/favicon-short-circuit.test.ts @@ -1,7 +1,7 @@ import { nextTestSetup } from 'e2e-utils' describe('favicon-short-circuit', () => { - const { next, isNextDev, isNextStart } = nextTestSetup({ + const { next, isNextDev } = nextTestSetup({ files: __dirname, }) @@ -20,7 +20,7 @@ describe('favicon-short-circuit', () => { // Expect we didn't compile the not found route. expect(next.cliOutput).not.toContain('compiling /not-found') }) - } else if (isNextStart) { + } else { it('should not short circuit the favicon in production', async () => { const res = await next.fetch('/favicon.ico') diff --git a/test/e2e/i18n-data-route/i18n-data-route.test.ts b/test/e2e/i18n-data-route/i18n-data-route.test.ts index 5ea9895117808..18a7e7891a3f5 100644 --- a/test/e2e/i18n-data-route/i18n-data-route.test.ts +++ b/test/e2e/i18n-data-route/i18n-data-route.test.ts @@ -14,14 +14,19 @@ function checkDataRoute(data: any, page: string) { } describe('i18n-data-route', () => { - const { next } = nextTestSetup({ + const { next, skipped } = nextTestSetup({ files: __dirname, + // This test skips deployment because env vars that are doubled underscore prefixed + // are not supported. + skipDeployment: true, env: { // Disable internal header stripping so we can test the invoke output. __NEXT_NO_STRIP_INTERNAL_HEADERS: '1', }, }) + if (skipped) return + describe('with locale prefix', () => { describe.each(i18n.locales)('/%s', (locale) => { const prefixed = pages.map((page) => ({ diff --git a/test/e2e/next-phase/index.test.ts b/test/e2e/next-phase/index.test.ts index 62d4424c9a9a3..3ff81f18156f5 100644 --- a/test/e2e/next-phase/index.test.ts +++ b/test/e2e/next-phase/index.test.ts @@ -1,7 +1,10 @@ import { nextTestSetup } from 'e2e-utils' describe('next-phase', () => { - const { next, isNextDev } = nextTestSetup({ + const { next, isNextDev, skipped } = nextTestSetup({ + // This test is skipped when deployed because it asserts against runtime + // logs that cannot be queried in a deployed environment. + skipDeployment: true, files: { 'app/layout.js': `export default function Layout({ children }) { return {children} @@ -17,6 +20,8 @@ describe('next-phase', () => { }, }) + if (skipped) return + it('should render page with next phase correctly', async () => { const phases = { dev: 'phase-development-server', diff --git a/test/e2e/next-test/next-test.test.ts b/test/e2e/next-test/next-test.test.ts index 718221be73101..fa584c84d88c7 100644 --- a/test/e2e/next-test/next-test.test.ts +++ b/test/e2e/next-test/next-test.test.ts @@ -26,14 +26,18 @@ function createTemporaryFixture(fixtureName: string) { } describe('next test', () => { - const { next: basicExample } = nextTestSetup({ + const { next: basicExample, skipped } = nextTestSetup({ files: new FileRef(join(__dirname, 'basic-example')), dependencies: { '@playwright/test': '1.43.1', }, skipStart: true, + // This doesn't need to be deployed as it's using `experimental-test` mode + skipDeployment: true, }) + if (skipped) return + afterAll(async () => { await basicExample.destroy() }) diff --git a/test/e2e/tsconfig-module-preserve/index.test.ts b/test/e2e/tsconfig-module-preserve/index.test.ts index 7980d604f3840..1bbd0f9915714 100644 --- a/test/e2e/tsconfig-module-preserve/index.test.ts +++ b/test/e2e/tsconfig-module-preserve/index.test.ts @@ -3,7 +3,7 @@ import { retry } from 'next-test-utils' import stripAnsi from 'strip-ansi' describe('tsconfig module: preserve', () => { - const { next } = nextTestSetup({ + const { next, skipped } = nextTestSetup({ files: { 'tsconfig.json': JSON.stringify({ compilerOptions: { module: 'preserve' }, @@ -14,11 +14,15 @@ describe('tsconfig module: preserve', () => { } `, }, + // This test is skipped because it relies on `next.readFile` + skipDeployment: true, dependencies: { typescript: '5.4.4', }, }) + if (skipped) return + it('allows you to skip moduleResolution, esModuleInterop and resolveJsonModule when using "module: preserve"', async () => { let output = '' From f34445e25ac6a437834be146de1ee48589bec431 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Wed, 12 Jun 2024 09:07:45 -0700 Subject: [PATCH 47/60] refactor: simplified async storage wrappers (#66767) --- packages/next/src/build/utils.ts | 4 +- .../next/src/server/app-render/app-render.tsx | 8 +- .../async-storage/async-storage-wrapper.ts | 21 -- .../request-async-storage-wrapper.ts | 216 ------------------ ...static-generation-async-storage-wrapper.ts | 116 ---------- .../async-storage/with-request-store.ts | 204 +++++++++++++++++ .../with-static-generation-store.ts | 115 ++++++++++ .../src/server/async-storage/with-store.ts | 16 ++ .../server/route-modules/app-route/module.ts | 12 +- packages/next/src/server/web/adapter.ts | 6 +- 10 files changed, 350 insertions(+), 368 deletions(-) delete mode 100644 packages/next/src/server/async-storage/async-storage-wrapper.ts delete mode 100644 packages/next/src/server/async-storage/request-async-storage-wrapper.ts delete mode 100644 packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts create mode 100644 packages/next/src/server/async-storage/with-request-store.ts create mode 100644 packages/next/src/server/async-storage/with-static-generation-store.ts create mode 100644 packages/next/src/server/async-storage/with-store.ts diff --git a/packages/next/src/build/utils.ts b/packages/next/src/build/utils.ts index 666f84e71572a..73dac41f7b9bc 100644 --- a/packages/next/src/build/utils.ts +++ b/packages/next/src/build/utils.ts @@ -76,7 +76,7 @@ import { denormalizePagePath } from '../shared/lib/page-path/denormalize-page-pa import { normalizePagePath } from '../shared/lib/page-path/normalize-page-path' import { getRuntimeContext } from '../server/web/sandbox' import { isClientReference } from '../lib/client-reference' -import { StaticGenerationAsyncStorageWrapper } from '../server/async-storage/static-generation-async-storage-wrapper' +import { withStaticGenerationStore } from '../server/async-storage/with-static-generation-store' import { IncrementalCache } from '../server/lib/incremental-cache' import { nodeFs } from '../server/lib/node-fs-methods' import * as ciEnvironment from '../telemetry/ci-info' @@ -1381,7 +1381,7 @@ export async function buildAppStaticPaths({ minimalMode: ciEnvironment.hasNextSupport, }) - return StaticGenerationAsyncStorageWrapper.wrap( + return withStaticGenerationStore( ComponentMod.staticGenerationAsyncStorage, { page, diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx index a10b2d50e25bf..44dca23c4e4f3 100644 --- a/packages/next/src/server/app-render/app-render.tsx +++ b/packages/next/src/server/app-render/app-render.tsx @@ -46,8 +46,8 @@ import { createMetadataComponents, createMetadataContext, } from '../../lib/metadata/metadata' -import { RequestAsyncStorageWrapper } from '../async-storage/request-async-storage-wrapper' -import { StaticGenerationAsyncStorageWrapper } from '../async-storage/static-generation-async-storage-wrapper' +import { withRequestStore } from '../async-storage/with-request-store' +import { withStaticGenerationStore } from '../async-storage/with-static-generation-store' import { isNotFoundError } from '../../client/components/not-found' import { getURLFromRedirectError, @@ -1504,11 +1504,11 @@ export const renderToHTMLOrFlight: AppPageRender = ( const url = parseRelativeUrl(req.url, undefined, false) - return RequestAsyncStorageWrapper.wrap( + return withRequestStore( renderOpts.ComponentMod.requestAsyncStorage, { req, url, res, renderOpts }, (requestStore) => - StaticGenerationAsyncStorageWrapper.wrap( + withStaticGenerationStore( renderOpts.ComponentMod.staticGenerationAsyncStorage, { page: renderOpts.routeModule.definition.page, diff --git a/packages/next/src/server/async-storage/async-storage-wrapper.ts b/packages/next/src/server/async-storage/async-storage-wrapper.ts deleted file mode 100644 index e3c879559a003..0000000000000 --- a/packages/next/src/server/async-storage/async-storage-wrapper.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { AsyncLocalStorage } from 'async_hooks' - -/** - * Implementations provide a wrapping function that will provide the storage to - * async calls derived from the provided callback function. - */ -export interface AsyncStorageWrapper { - /** - * Wraps the callback with the underlying storage. - * - * @param storage underlying storage object - * @param context context used to create the storage object - * @param callback function to call within the scope of the storage - * @returns the result of the callback - */ - wrap( - storage: AsyncLocalStorage, - context: Context, - callback: (store: Store) => Result - ): Result -} diff --git a/packages/next/src/server/async-storage/request-async-storage-wrapper.ts b/packages/next/src/server/async-storage/request-async-storage-wrapper.ts deleted file mode 100644 index 1740a16c21712..0000000000000 --- a/packages/next/src/server/async-storage/request-async-storage-wrapper.ts +++ /dev/null @@ -1,216 +0,0 @@ -import type { BaseNextRequest, BaseNextResponse } from '../base-http' -import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from 'http' -import type { AsyncLocalStorage } from 'async_hooks' -import type { RequestStore } from '../../client/components/request-async-storage.external' -import type { RenderOpts } from '../app-render/types' -import type { AsyncStorageWrapper } from './async-storage-wrapper' -import type { NextRequest } from '../web/spec-extension/request' -import type { __ApiPreviewProps } from '../api-utils' - -import { FLIGHT_PARAMETERS } from '../../client/components/app-router-headers' -import { - HeadersAdapter, - type ReadonlyHeaders, -} from '../web/spec-extension/adapters/headers' -import { - MutableRequestCookiesAdapter, - RequestCookiesAdapter, - type ReadonlyRequestCookies, -} from '../web/spec-extension/adapters/request-cookies' -import { ResponseCookies, RequestCookies } from '../web/spec-extension/cookies' -import { DraftModeProvider } from './draft-mode-provider' -import { splitCookiesString } from '../web/utils' -import { createAfterContext, type AfterContext } from '../after/after-context' -import type { RequestLifecycleOpts } from '../base-server' - -function getHeaders(headers: Headers | IncomingHttpHeaders): ReadonlyHeaders { - const cleaned = HeadersAdapter.from(headers) - for (const param of FLIGHT_PARAMETERS) { - cleaned.delete(param.toString().toLowerCase()) - } - - return HeadersAdapter.seal(cleaned) -} - -function getMutableCookies( - headers: Headers | IncomingHttpHeaders, - onUpdateCookies?: (cookies: string[]) => void -): ResponseCookies { - const cookies = new RequestCookies(HeadersAdapter.from(headers)) - return MutableRequestCookiesAdapter.wrap(cookies, onUpdateCookies) -} - -export type WrapperRenderOpts = RequestLifecycleOpts & - Partial< - Pick< - RenderOpts, - | 'ComponentMod' - | 'onUpdateCookies' - | 'assetPrefix' - | 'reactLoadableManifest' - > - > & { - experimental: Pick - previewProps?: __ApiPreviewProps - } - -export type RequestContext = { - req: IncomingMessage | BaseNextRequest | NextRequest - /** - * The URL of the request. This only specifies the pathname and the search - * part of the URL. This is only undefined when generating static paths (ie, - * there is no request in progress, nor do we know one). - */ - url: { - /** - * The pathname of the requested URL. - */ - pathname: string - - /** - * The search part of the requested URL. If the request did not provide a - * search part, this will be an empty string. - */ - search?: string - } - res?: ServerResponse | BaseNextResponse - renderOpts?: WrapperRenderOpts -} - -export const RequestAsyncStorageWrapper: AsyncStorageWrapper< - RequestStore, - RequestContext -> = { - /** - * Wrap the callback with the given store so it can access the underlying - * store using hooks. - * - * @param storage underlying storage object returned by the module - * @param context context to seed the store - * @param callback function to call within the scope of the context - * @returns the result returned by the callback - */ - wrap( - storage: AsyncLocalStorage, - { req, url, res, renderOpts }: RequestContext, - callback: (store: RequestStore) => Result - ): Result { - const [wrapWithAfter, afterContext] = createAfterWrapper(renderOpts) - - function defaultOnUpdateCookies(cookies: string[]) { - if (res) { - res.setHeader('Set-Cookie', cookies) - } - } - - const cache: { - headers?: ReadonlyHeaders - cookies?: ReadonlyRequestCookies - mutableCookies?: ResponseCookies - draftMode?: DraftModeProvider - } = {} - - const store: RequestStore = { - // Rather than just using the whole `url` here, we pull the parts we want - // to ensure we don't use parts of the URL that we shouldn't. This also - // lets us avoid requiring an empty string for `search` in the type. - url: { pathname: url.pathname, search: url.search ?? '' }, - get headers() { - if (!cache.headers) { - // Seal the headers object that'll freeze out any methods that could - // mutate the underlying data. - cache.headers = getHeaders(req.headers) - } - - return cache.headers - }, - get cookies() { - if (!cache.cookies) { - // if middleware is setting cookie(s), then include those in - // the initial cached cookies so they can be read in render - const requestCookies = new RequestCookies( - HeadersAdapter.from(req.headers) - ) - - if ( - 'x-middleware-set-cookie' in req.headers && - typeof req.headers['x-middleware-set-cookie'] === 'string' - ) { - const setCookieValue = req.headers['x-middleware-set-cookie'] - const responseHeaders = new Headers() - - for (const cookie of splitCookiesString(setCookieValue)) { - responseHeaders.append('set-cookie', cookie) - } - - const responseCookies = new ResponseCookies(responseHeaders) - - // Transfer cookies from ResponseCookies to RequestCookies - for (const cookie of responseCookies.getAll()) { - requestCookies.set(cookie.name, cookie.value ?? '') - } - } - - // Seal the cookies object that'll freeze out any methods that could - // mutate the underlying data. - cache.cookies = RequestCookiesAdapter.seal(requestCookies) - } - - return cache.cookies - }, - get mutableCookies() { - if (!cache.mutableCookies) { - cache.mutableCookies = getMutableCookies( - req.headers, - renderOpts?.onUpdateCookies || - (res ? defaultOnUpdateCookies : undefined) - ) - } - return cache.mutableCookies - }, - get draftMode() { - if (!cache.draftMode) { - cache.draftMode = new DraftModeProvider( - renderOpts?.previewProps, - req, - this.cookies, - this.mutableCookies - ) - } - - return cache.draftMode - }, - - reactLoadableManifest: renderOpts?.reactLoadableManifest || {}, - assetPrefix: renderOpts?.assetPrefix || '', - afterContext, - } - return wrapWithAfter(store, () => storage.run(store, callback, store)) - }, -} - -function createAfterWrapper( - renderOpts: WrapperRenderOpts | undefined -): [ - wrap: (requestStore: RequestStore, callback: () => Result) => Result, - afterContext: AfterContext | undefined, -] { - const isAfterEnabled = renderOpts?.experimental?.after ?? false - if (!renderOpts || !isAfterEnabled) { - return [(_, callback) => callback(), undefined] - } - - const { waitUntil, onClose } = renderOpts - const cacheScope = renderOpts.ComponentMod?.createCacheScope() - - const afterContext = createAfterContext({ - waitUntil, - onClose, - cacheScope, - }) - - const wrap = (requestStore: RequestStore, callback: () => Result) => - afterContext.run(requestStore, callback) - - return [wrap, afterContext] -} diff --git a/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts b/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts deleted file mode 100644 index 7a4d125a18151..0000000000000 --- a/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts +++ /dev/null @@ -1,116 +0,0 @@ -import type { AsyncStorageWrapper } from './async-storage-wrapper' -import type { StaticGenerationStore } from '../../client/components/static-generation-async-storage.external' -import type { AsyncLocalStorage } from 'async_hooks' -import type { IncrementalCache } from '../lib/incremental-cache' -import type { RenderOptsPartial } from '../app-render/types' - -import { createPrerenderState } from '../app-render/dynamic-rendering' -import type { FetchMetric } from '../base-http' -import type { RequestLifecycleOpts } from '../base-server' -import { normalizeAppPath } from '../../shared/lib/router/utils/app-paths' - -export type StaticGenerationContext = { - /** - * The page that is being rendered. This relates to the path to the page file. - */ - page: string - requestEndedState?: { ended?: boolean } - renderOpts: { - incrementalCache?: IncrementalCache - isOnDemandRevalidate?: boolean - fetchCache?: StaticGenerationStore['fetchCache'] - isServerAction?: boolean - pendingWaitUntil?: Promise - experimental: Pick< - RenderOptsPartial['experimental'], - 'isRoutePPREnabled' | 'after' - > - - /** - * Fetch metrics attached in patch-fetch.ts - **/ - fetchMetrics?: FetchMetric[] - - /** - * A hack around accessing the store value outside the context of the - * request. - * - * @internal - * @deprecated should only be used as a temporary workaround - */ - // TODO: remove this when we resolve accessing the store outside the execution context - store?: StaticGenerationStore - } & Pick< - // Pull some properties from RenderOptsPartial so that the docs are also - // mirrored. - RenderOptsPartial, - | 'supportsDynamicResponse' - | 'isRevalidate' - | 'nextExport' - | 'isDraftMode' - | 'isDebugDynamicAccesses' - > & - Partial -} - -export const StaticGenerationAsyncStorageWrapper: AsyncStorageWrapper< - StaticGenerationStore, - StaticGenerationContext -> = { - wrap( - storage: AsyncLocalStorage, - { page, renderOpts, requestEndedState }: StaticGenerationContext, - callback: (store: StaticGenerationStore) => Result - ): Result { - /** - * Rules of Static & Dynamic HTML: - * - * 1.) We must generate static HTML unless the caller explicitly opts - * in to dynamic HTML support. - * - * 2.) If dynamic HTML support is requested, we must honor that request - * or throw an error. It is the sole responsibility of the caller to - * ensure they aren't e.g. requesting dynamic HTML for an AMP page. - * - * 3.) If the request is in draft mode, we must generate dynamic HTML. - * - * 4.) If the request is a server action, we must generate dynamic HTML. - * - * These rules help ensure that other existing features like request caching, - * coalescing, and ISR continue working as intended. - */ - const isStaticGeneration = - !renderOpts.supportsDynamicResponse && - !renderOpts.isDraftMode && - !renderOpts.isServerAction - - const prerenderState: StaticGenerationStore['prerenderState'] = - isStaticGeneration && renderOpts.experimental?.isRoutePPREnabled - ? createPrerenderState(renderOpts.isDebugDynamicAccesses) - : null - - const store: StaticGenerationStore = { - isStaticGeneration, - page, - route: normalizeAppPath(page), - incrementalCache: - // we fallback to a global incremental cache for edge-runtime locally - // so that it can access the fs cache without mocks - renderOpts.incrementalCache || (globalThis as any).__incrementalCache, - isRevalidate: renderOpts.isRevalidate, - isPrerendering: renderOpts.nextExport, - fetchCache: renderOpts.fetchCache, - isOnDemandRevalidate: renderOpts.isOnDemandRevalidate, - - isDraftMode: renderOpts.isDraftMode, - - prerenderState, - requestEndedState, - } - - // TODO: remove this when we resolve accessing the store outside the execution context - renderOpts.store = store - - return storage.run(store, callback, store) - }, -} diff --git a/packages/next/src/server/async-storage/with-request-store.ts b/packages/next/src/server/async-storage/with-request-store.ts new file mode 100644 index 0000000000000..571ff2210415f --- /dev/null +++ b/packages/next/src/server/async-storage/with-request-store.ts @@ -0,0 +1,204 @@ +import type { BaseNextRequest, BaseNextResponse } from '../base-http' +import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from 'http' +import type { AsyncLocalStorage } from 'async_hooks' +import type { RequestStore } from '../../client/components/request-async-storage.external' +import type { RenderOpts } from '../app-render/types' +import type { WithStore } from './with-store' +import type { NextRequest } from '../web/spec-extension/request' +import type { __ApiPreviewProps } from '../api-utils' + +import { FLIGHT_PARAMETERS } from '../../client/components/app-router-headers' +import { + HeadersAdapter, + type ReadonlyHeaders, +} from '../web/spec-extension/adapters/headers' +import { + MutableRequestCookiesAdapter, + RequestCookiesAdapter, + type ReadonlyRequestCookies, +} from '../web/spec-extension/adapters/request-cookies' +import { ResponseCookies, RequestCookies } from '../web/spec-extension/cookies' +import { DraftModeProvider } from './draft-mode-provider' +import { splitCookiesString } from '../web/utils' +import { createAfterContext, type AfterContext } from '../after/after-context' +import type { RequestLifecycleOpts } from '../base-server' + +function getHeaders(headers: Headers | IncomingHttpHeaders): ReadonlyHeaders { + const cleaned = HeadersAdapter.from(headers) + for (const param of FLIGHT_PARAMETERS) { + cleaned.delete(param.toString().toLowerCase()) + } + + return HeadersAdapter.seal(cleaned) +} + +function getMutableCookies( + headers: Headers | IncomingHttpHeaders, + onUpdateCookies?: (cookies: string[]) => void +): ResponseCookies { + const cookies = new RequestCookies(HeadersAdapter.from(headers)) + return MutableRequestCookiesAdapter.wrap(cookies, onUpdateCookies) +} + +export type WrapperRenderOpts = RequestLifecycleOpts & + Partial< + Pick< + RenderOpts, + | 'ComponentMod' + | 'onUpdateCookies' + | 'assetPrefix' + | 'reactLoadableManifest' + > + > & { + experimental: Pick + previewProps?: __ApiPreviewProps + } + +export type RequestContext = { + req: IncomingMessage | BaseNextRequest | NextRequest + /** + * The URL of the request. This only specifies the pathname and the search + * part of the URL. This is only undefined when generating static paths (ie, + * there is no request in progress, nor do we know one). + */ + url: { + /** + * The pathname of the requested URL. + */ + pathname: string + + /** + * The search part of the requested URL. If the request did not provide a + * search part, this will be an empty string. + */ + search?: string + } + res?: ServerResponse | BaseNextResponse + renderOpts?: WrapperRenderOpts +} + +export const withRequestStore: WithStore = < + Result, +>( + storage: AsyncLocalStorage, + { req, url, res, renderOpts }: RequestContext, + callback: (store: RequestStore) => Result +): Result => { + const [wrapWithAfter, afterContext] = createAfterWrapper(renderOpts) + + function defaultOnUpdateCookies(cookies: string[]) { + if (res) { + res.setHeader('Set-Cookie', cookies) + } + } + + const cache: { + headers?: ReadonlyHeaders + cookies?: ReadonlyRequestCookies + mutableCookies?: ResponseCookies + draftMode?: DraftModeProvider + } = {} + + const store: RequestStore = { + // Rather than just using the whole `url` here, we pull the parts we want + // to ensure we don't use parts of the URL that we shouldn't. This also + // lets us avoid requiring an empty string for `search` in the type. + url: { pathname: url.pathname, search: url.search ?? '' }, + get headers() { + if (!cache.headers) { + // Seal the headers object that'll freeze out any methods that could + // mutate the underlying data. + cache.headers = getHeaders(req.headers) + } + + return cache.headers + }, + get cookies() { + if (!cache.cookies) { + // if middleware is setting cookie(s), then include those in + // the initial cached cookies so they can be read in render + const requestCookies = new RequestCookies( + HeadersAdapter.from(req.headers) + ) + + if ( + 'x-middleware-set-cookie' in req.headers && + typeof req.headers['x-middleware-set-cookie'] === 'string' + ) { + const setCookieValue = req.headers['x-middleware-set-cookie'] + const responseHeaders = new Headers() + + for (const cookie of splitCookiesString(setCookieValue)) { + responseHeaders.append('set-cookie', cookie) + } + + const responseCookies = new ResponseCookies(responseHeaders) + + // Transfer cookies from ResponseCookies to RequestCookies + for (const cookie of responseCookies.getAll()) { + requestCookies.set(cookie.name, cookie.value ?? '') + } + } + + // Seal the cookies object that'll freeze out any methods that could + // mutate the underlying data. + cache.cookies = RequestCookiesAdapter.seal(requestCookies) + } + + return cache.cookies + }, + get mutableCookies() { + if (!cache.mutableCookies) { + cache.mutableCookies = getMutableCookies( + req.headers, + renderOpts?.onUpdateCookies || + (res ? defaultOnUpdateCookies : undefined) + ) + } + return cache.mutableCookies + }, + get draftMode() { + if (!cache.draftMode) { + cache.draftMode = new DraftModeProvider( + renderOpts?.previewProps, + req, + this.cookies, + this.mutableCookies + ) + } + + return cache.draftMode + }, + + reactLoadableManifest: renderOpts?.reactLoadableManifest || {}, + assetPrefix: renderOpts?.assetPrefix || '', + afterContext, + } + return wrapWithAfter(store, () => storage.run(store, callback, store)) +} + +function createAfterWrapper( + renderOpts: WrapperRenderOpts | undefined +): [ + wrap: (requestStore: RequestStore, callback: () => Result) => Result, + afterContext: AfterContext | undefined, +] { + const isAfterEnabled = renderOpts?.experimental?.after ?? false + if (!renderOpts || !isAfterEnabled) { + return [(_, callback) => callback(), undefined] + } + + const { waitUntil, onClose } = renderOpts + const cacheScope = renderOpts.ComponentMod?.createCacheScope() + + const afterContext = createAfterContext({ + waitUntil, + onClose, + cacheScope, + }) + + const wrap = (requestStore: RequestStore, callback: () => Result) => + afterContext.run(requestStore, callback) + + return [wrap, afterContext] +} diff --git a/packages/next/src/server/async-storage/with-static-generation-store.ts b/packages/next/src/server/async-storage/with-static-generation-store.ts new file mode 100644 index 0000000000000..b18abeaa77f16 --- /dev/null +++ b/packages/next/src/server/async-storage/with-static-generation-store.ts @@ -0,0 +1,115 @@ +import type { WithStore } from './with-store' +import type { StaticGenerationStore } from '../../client/components/static-generation-async-storage.external' +import type { AsyncLocalStorage } from 'async_hooks' +import type { IncrementalCache } from '../lib/incremental-cache' +import type { RenderOptsPartial } from '../app-render/types' +import type { FetchMetric } from '../base-http' +import type { RequestLifecycleOpts } from '../base-server' + +import { createPrerenderState } from '../app-render/dynamic-rendering' +import { normalizeAppPath } from '../../shared/lib/router/utils/app-paths' + +export type StaticGenerationContext = { + /** + * The page that is being rendered. This relates to the path to the page file. + */ + page: string + + requestEndedState?: { ended?: boolean } + renderOpts: { + incrementalCache?: IncrementalCache + isOnDemandRevalidate?: boolean + fetchCache?: StaticGenerationStore['fetchCache'] + isServerAction?: boolean + pendingWaitUntil?: Promise + experimental: Pick< + RenderOptsPartial['experimental'], + 'isRoutePPREnabled' | 'after' + > + + /** + * Fetch metrics attached in patch-fetch.ts + **/ + fetchMetrics?: FetchMetric[] + + /** + * A hack around accessing the store value outside the context of the + * request. + * + * @internal + * @deprecated should only be used as a temporary workaround + */ + // TODO: remove this when we resolve accessing the store outside the execution context + store?: StaticGenerationStore + } & Pick< + // Pull some properties from RenderOptsPartial so that the docs are also + // mirrored. + RenderOptsPartial, + | 'supportsDynamicResponse' + | 'isRevalidate' + | 'nextExport' + | 'isDraftMode' + | 'isDebugDynamicAccesses' + > & + Partial +} + +export const withStaticGenerationStore: WithStore< + StaticGenerationStore, + StaticGenerationContext +> = ( + storage: AsyncLocalStorage, + { page, renderOpts, requestEndedState }: StaticGenerationContext, + callback: (store: StaticGenerationStore) => Result +): Result => { + /** + * Rules of Static & Dynamic HTML: + * + * 1.) We must generate static HTML unless the caller explicitly opts + * in to dynamic HTML support. + * + * 2.) If dynamic HTML support is requested, we must honor that request + * or throw an error. It is the sole responsibility of the caller to + * ensure they aren't e.g. requesting dynamic HTML for an AMP page. + * + * 3.) If the request is in draft mode, we must generate dynamic HTML. + * + * 4.) If the request is a server action, we must generate dynamic HTML. + * + * These rules help ensure that other existing features like request caching, + * coalescing, and ISR continue working as intended. + */ + const isStaticGeneration = + !renderOpts.supportsDynamicResponse && + !renderOpts.isDraftMode && + !renderOpts.isServerAction + + const prerenderState: StaticGenerationStore['prerenderState'] = + isStaticGeneration && renderOpts.experimental?.isRoutePPREnabled + ? createPrerenderState(renderOpts.isDebugDynamicAccesses) + : null + + const store: StaticGenerationStore = { + isStaticGeneration, + page, + route: normalizeAppPath(page), + incrementalCache: + // we fallback to a global incremental cache for edge-runtime locally + // so that it can access the fs cache without mocks + renderOpts.incrementalCache || (globalThis as any).__incrementalCache, + isRevalidate: renderOpts.isRevalidate, + isPrerendering: renderOpts.nextExport, + fetchCache: renderOpts.fetchCache, + isOnDemandRevalidate: renderOpts.isOnDemandRevalidate, + + isDraftMode: renderOpts.isDraftMode, + + prerenderState, + requestEndedState, + } + + // TODO: remove this when we resolve accessing the store outside the execution context + renderOpts.store = store + + return storage.run(store, callback, store) +} diff --git a/packages/next/src/server/async-storage/with-store.ts b/packages/next/src/server/async-storage/with-store.ts new file mode 100644 index 0000000000000..d2926c62de8d5 --- /dev/null +++ b/packages/next/src/server/async-storage/with-store.ts @@ -0,0 +1,16 @@ +import type { AsyncLocalStorage } from 'async_hooks' + +/** + * Implementations provide a wrapping function that will provide the storage to + * async calls derived from the provided callback function. + * + * @param storage underlying storage object + * @param context context used to create the storage object + * @param callback function to call within the scope of the storage + * @returns the result of the callback + */ +export type WithStore = ( + storage: AsyncLocalStorage, + context: Context, + callback: (store: Store) => Result +) => Result diff --git a/packages/next/src/server/route-modules/app-route/module.ts b/packages/next/src/server/route-modules/app-route/module.ts index 0b76b07a7eae1..411df45905b16 100644 --- a/packages/next/src/server/route-modules/app-route/module.ts +++ b/packages/next/src/server/route-modules/app-route/module.ts @@ -12,13 +12,13 @@ import { type RouteModuleOptions, } from '../route-module' import { - RequestAsyncStorageWrapper, + withRequestStore, type RequestContext, -} from '../../async-storage/request-async-storage-wrapper' +} from '../../async-storage/with-request-store' import { - StaticGenerationAsyncStorageWrapper, + withStaticGenerationStore, type StaticGenerationContext, -} from '../../async-storage/static-generation-async-storage-wrapper' +} from '../../async-storage/with-static-generation-store' import { handleBadRequestResponse, handleInternalServerErrorResponse, @@ -284,11 +284,11 @@ export class AppRouteRouteModule extends RouteModule< isAction: getIsServerAction(rawRequest), }, () => - RequestAsyncStorageWrapper.wrap( + withRequestStore( this.requestAsyncStorage, requestContext, (requestStore) => - StaticGenerationAsyncStorageWrapper.wrap( + withStaticGenerationStore( this.staticGenerationAsyncStorage, staticGenerationContext, (staticGenerationStore) => { diff --git a/packages/next/src/server/web/adapter.ts b/packages/next/src/server/web/adapter.ts index 701c0c1a27217..85e345d3e9783 100644 --- a/packages/next/src/server/web/adapter.ts +++ b/packages/next/src/server/web/adapter.ts @@ -14,9 +14,9 @@ import { normalizeRscURL } from '../../shared/lib/router/utils/app-paths' import { FLIGHT_PARAMETERS } from '../../client/components/app-router-headers' import { ensureInstrumentationRegistered } from './globals' import { - RequestAsyncStorageWrapper, + withRequestStore, type WrapperRenderOpts, -} from '../async-storage/request-async-storage-wrapper' +} from '../async-storage/with-request-store' import { requestAsyncStorage } from '../../client/components/request-async-storage.external' import { getTracer } from '../lib/trace/tracer' import type { TextMapGetter } from 'next/dist/compiled/@opentelemetry/api' @@ -246,7 +246,7 @@ export async function adapter( previewModeSigningKey: '', } - return await RequestAsyncStorageWrapper.wrap( + return await withRequestStore( requestAsyncStorage, { req: request, From 73918c6711b538678dd66303fdbd61bfd10b288c Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 12 Jun 2024 09:42:50 -0700 Subject: [PATCH 48/60] Ensure turbo is setup when building in docker (#66804) This ensures we always set up turbo to the version we expect even if we're building in docker since the cache is pulled outside of docker. x-ref: https://github.com/vercel/next.js/actions/runs/9484631800/job/26134568488 --- .github/workflows/build_and_deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_deploy.yml b/.github/workflows/build_and_deploy.yml index d3781cf285419..027ec0e143591 100644 --- a/.github/workflows/build_and_deploy.yml +++ b/.github/workflows/build_and_deploy.yml @@ -279,7 +279,7 @@ jobs: # issues with turbo caching - name: pull build cache if: ${{ matrix.settings.docker }} - run: node ./scripts/pull-turbo-cache.js ${{ matrix.settings.target }} + run: npm i -g turbo@${{ env.TURBO_VERSION }} && node ./scripts/pull-turbo-cache.js ${{ matrix.settings.target }} - name: check build exists if: ${{ matrix.settings.docker }} From 535d46673430f1f9649594171baa99ae3a185490 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Wed, 12 Jun 2024 11:05:18 -0700 Subject: [PATCH 49/60] fix edge-document deploy test (#66805) No need to stop the server & patch a file for this test. This updates the setup step to create the necessary files so it can be deployed. --- test/deploy-tests-manifest.json | 1 - .../edge-pages-support/edge-document.test.ts | 58 +++++++++---------- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/test/deploy-tests-manifest.json b/test/deploy-tests-manifest.json index a8024b206ae6c..822e504742365 100644 --- a/test/deploy-tests-manifest.json +++ b/test/deploy-tests-manifest.json @@ -26,7 +26,6 @@ "exclude": [ "test/e2e/app-dir/scss/nm-module-nested/nm-module-nested.test.ts", "test/e2e/cancel-request/stream-cancel.test.ts", - "test/e2e/edge-pages-support/edge-document.test.ts", "test/e2e/new-link-behavior/material-ui.test.ts", "test/e2e/react-dnd-compile/react-dnd-compile.test.ts", "test/e2e/skip-trailing-slash-redirect/index.test.ts", diff --git a/test/e2e/edge-pages-support/edge-document.test.ts b/test/e2e/edge-pages-support/edge-document.test.ts index 355ce7f509e49..35fc2ece44007 100644 --- a/test/e2e/edge-pages-support/edge-document.test.ts +++ b/test/e2e/edge-pages-support/edge-document.test.ts @@ -1,41 +1,35 @@ -import { nextTestSetup } from 'e2e-utils' +import { nextTestSetup, FileRef } from 'e2e-utils' import { join } from 'path' // x-ref: https://github.com/vercel/next.js/issues/45189 describe('edge render - custom _document with edge runtime', () => { const { next } = nextTestSetup({ - files: join(__dirname, 'app'), - }) - - beforeAll(async () => { - await next.stop() - await next.patchFile( - 'pages/_document.js', - `import Document, { Html, Head, Main, NextScript } from 'next/document' + files: { + 'pages/index.js': new FileRef( + join(__dirname, 'app', 'pages', 'index.js') + ), + 'next.config.js': new FileRef(join(__dirname, 'app', 'next.config.js')), + 'pages/_document.js': ` + import Document, { Html, Head, Main, NextScript } from 'next/document' + export default class MyDocument extends Document { + render() { + return ( + + + +
+ + + + ) + } + } - export default class MyDocument extends Document { - render() { - return ( - - - -
- - - - ) - } - } - - export const config = { - runtime: 'experimental-edge', - } - ` - ) - await next.start() - }) - afterAll(async () => { - await next.deleteFile('pages/_document.js') + export const config = { + runtime: 'experimental-edge', + } + `, + }, }) it('should render page properly', async () => { From bebc63fce0aa9c0dbee9fb4d6c3cc8ca0caf2856 Mon Sep 17 00:00:00 2001 From: Ivan Torres <40922354+torresgol10@users.noreply.github.com> Date: Wed, 12 Jun 2024 20:25:09 +0200 Subject: [PATCH 50/60] Update devdependecy commander (#66771) Upgrade devdependecy commander to latest versio. Now in command, the optional argument is with [] and the required argument is with <>. --------- Co-authored-by: torresgol10.itd Co-authored-by: Sam Ko --- packages/create-next-app/index.ts | 9 +++++---- packages/create-next-app/package.json | 2 +- packages/next/package.json | 2 +- packages/next/src/compiled/commander/index.js | 2 +- pnpm-lock.yaml | 12 ++++++------ 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/create-next-app/index.ts b/packages/create-next-app/index.ts index dcef52ad4203b..88289f003e4b3 100644 --- a/packages/create-next-app/index.ts +++ b/packages/create-next-app/index.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node /* eslint-disable import/no-extraneous-dependencies */ import { cyan, green, red, yellow, bold, blue } from 'picocolors' -import Commander from 'commander' +import { Command } from 'commander' import Conf from 'conf' import path from 'path' import prompts from 'prompts' @@ -36,10 +36,10 @@ const onPromptState = (state: { } } -const program = new Commander.Command(packageJson.name) +const program = new Command(packageJson.name) .version(packageJson.version) - .arguments('') - .usage(`${green('')} [options]`) + .argument('[project-directory]') + .usage(`${green('[project-directory]')} [options]`) .action((name) => { projectPath = name }) @@ -169,6 +169,7 @@ const program = new Commander.Command(packageJson.name) ) .allowUnknownOption() .parse(process.argv) + .opts() const packageManager = !!program.useNpm ? 'npm' diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index ac030f9fc7021..40f5132481ca8 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -39,7 +39,7 @@ "@vercel/ncc": "0.34.0", "async-retry": "1.3.1", "ci-info": "watson/ci-info#f43f6a1cefff47fb361c88cf4b943fdbcaafe540", - "commander": "2.20.0", + "commander": "12.1.0", "conf": "10.2.0", "cross-spawn": "7.0.3", "fast-glob": "3.3.1", diff --git a/packages/next/package.json b/packages/next/package.json index d83e19ede2a15..3027179e30dbb 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -223,7 +223,7 @@ "ci-info": "watson/ci-info#f43f6a1cefff47fb361c88cf4b943fdbcaafe540", "cli-select": "1.1.2", "client-only": "0.0.1", - "commander": "12.0.0", + "commander": "12.1.0", "comment-json": "3.0.3", "compression": "1.7.4", "conf": "5.0.0", diff --git a/packages/next/src/compiled/commander/index.js b/packages/next/src/compiled/commander/index.js index 720ac85688e60..83d2f5584db83 100644 --- a/packages/next/src/compiled/commander/index.js +++ b/packages/next/src/compiled/commander/index.js @@ -1 +1 @@ -(()=>{var t={81:t=>{"use strict";t.exports=require("child_process")},361:t=>{"use strict";t.exports=require("events")},147:t=>{"use strict";t.exports=require("fs")},17:t=>{"use strict";t.exports=require("path")},282:t=>{"use strict";t.exports=require("process")},161:(t,e,i)=>{const{InvalidArgumentError:n}=i(854);class Argument{constructor(t,e){this.description=e||"";this.variadic=false;this.parseArg=undefined;this.defaultValue=undefined;this.defaultValueDescription=undefined;this.argChoices=undefined;switch(t[0]){case"<":this.required=true;this._name=t.slice(1,-1);break;case"[":this.required=false;this._name=t.slice(1,-1);break;default:this.required=true;this._name=t;break}if(this._name.length>3&&this._name.slice(-3)==="..."){this.variadic=true;this._name=this._name.slice(0,-3)}}name(){return this._name}_concatValue(t,e){if(e===this.defaultValue||!Array.isArray(e)){return[t]}return e.concat(t)}default(t,e){this.defaultValue=t;this.defaultValueDescription=e;return this}argParser(t){this.parseArg=t;return this}choices(t){this.argChoices=t.slice();this.parseArg=(t,e)=>{if(!this.argChoices.includes(t)){throw new n(`Allowed choices are ${this.argChoices.join(", ")}.`)}if(this.variadic){return this._concatValue(t,e)}return t};return this}argRequired(){this.required=true;return this}argOptional(){this.required=false;return this}}function humanReadableArgName(t){const e=t.name()+(t.variadic===true?"...":"");return t.required?"<"+e+">":"["+e+"]"}e.Argument=Argument;e.humanReadableArgName=humanReadableArgName},695:(t,e,i)=>{const n=i(361).EventEmitter;const s=i(81);const r=i(17);const o=i(147);const a=i(282);const{Argument:h,humanReadableArgName:l}=i(161);const{CommanderError:u}=i(854);const{Help:c}=i(853);const{Option:p,DualOptions:d}=i(548);const{suggestSimilar:m}=i(324);class Command extends n{constructor(t){super();this.commands=[];this.options=[];this.parent=null;this._allowUnknownOption=false;this._allowExcessArguments=true;this.registeredArguments=[];this._args=this.registeredArguments;this.args=[];this.rawArgs=[];this.processedArgs=[];this._scriptPath=null;this._name=t||"";this._optionValues={};this._optionValueSources={};this._storeOptionsAsProperties=false;this._actionHandler=null;this._executableHandler=false;this._executableFile=null;this._executableDir=null;this._defaultCommandName=null;this._exitCallback=null;this._aliases=[];this._combineFlagAndOptionalValue=true;this._description="";this._summary="";this._argsDescription=undefined;this._enablePositionalOptions=false;this._passThroughOptions=false;this._lifeCycleHooks={};this._showHelpAfterError=false;this._showSuggestionAfterError=true;this._outputConfiguration={writeOut:t=>a.stdout.write(t),writeErr:t=>a.stderr.write(t),getOutHelpWidth:()=>a.stdout.isTTY?a.stdout.columns:undefined,getErrHelpWidth:()=>a.stderr.isTTY?a.stderr.columns:undefined,outputError:(t,e)=>e(t)};this._hidden=false;this._helpOption=undefined;this._addImplicitHelpCommand=undefined;this._helpCommand=undefined;this._helpConfiguration={}}copyInheritedSettings(t){this._outputConfiguration=t._outputConfiguration;this._helpOption=t._helpOption;this._helpCommand=t._helpCommand;this._helpConfiguration=t._helpConfiguration;this._exitCallback=t._exitCallback;this._storeOptionsAsProperties=t._storeOptionsAsProperties;this._combineFlagAndOptionalValue=t._combineFlagAndOptionalValue;this._allowExcessArguments=t._allowExcessArguments;this._enablePositionalOptions=t._enablePositionalOptions;this._showHelpAfterError=t._showHelpAfterError;this._showSuggestionAfterError=t._showSuggestionAfterError;return this}_getCommandAndAncestors(){const t=[];for(let e=this;e;e=e.parent){t.push(e)}return t}command(t,e,i){let n=e;let s=i;if(typeof n==="object"&&n!==null){s=n;n=null}s=s||{};const[,r,o]=t.match(/([^ ]+) *(.*)/);const a=this.createCommand(r);if(n){a.description(n);a._executableHandler=true}if(s.isDefault)this._defaultCommandName=a._name;a._hidden=!!(s.noHelp||s.hidden);a._executableFile=s.executableFile||null;if(o)a.arguments(o);this._registerCommand(a);a.parent=this;a.copyInheritedSettings(this);if(n)return this;return a}createCommand(t){return new Command(t)}createHelp(){return Object.assign(new c,this.configureHelp())}configureHelp(t){if(t===undefined)return this._helpConfiguration;this._helpConfiguration=t;return this}configureOutput(t){if(t===undefined)return this._outputConfiguration;Object.assign(this._outputConfiguration,t);return this}showHelpAfterError(t=true){if(typeof t!=="string")t=!!t;this._showHelpAfterError=t;return this}showSuggestionAfterError(t=true){this._showSuggestionAfterError=!!t;return this}addCommand(t,e){if(!t._name){throw new Error(`Command passed to .addCommand() must have a name\n- specify the name in Command constructor or using .name()`)}e=e||{};if(e.isDefault)this._defaultCommandName=t._name;if(e.noHelp||e.hidden)t._hidden=true;this._registerCommand(t);t.parent=this;t._checkForBrokenPassThrough();return this}createArgument(t,e){return new h(t,e)}argument(t,e,i,n){const s=this.createArgument(t,e);if(typeof i==="function"){s.default(n).argParser(i)}else{s.default(i)}this.addArgument(s);return this}arguments(t){t.trim().split(/ +/).forEach((t=>{this.argument(t)}));return this}addArgument(t){const e=this.registeredArguments.slice(-1)[0];if(e&&e.variadic){throw new Error(`only the last argument can be variadic '${e.name()}'`)}if(t.required&&t.defaultValue!==undefined&&t.parseArg===undefined){throw new Error(`a default value for a required argument is never used: '${t.name()}'`)}this.registeredArguments.push(t);return this}helpCommand(t,e){if(typeof t==="boolean"){this._addImplicitHelpCommand=t;return this}t=t??"help [command]";const[,i,n]=t.match(/([^ ]+) *(.*)/);const s=e??"display help for command";const r=this.createCommand(i);r.helpOption(false);if(n)r.arguments(n);if(s)r.description(s);this._addImplicitHelpCommand=true;this._helpCommand=r;return this}addHelpCommand(t,e){if(typeof t!=="object"){this.helpCommand(t,e);return this}this._addImplicitHelpCommand=true;this._helpCommand=t;return this}_getHelpCommand(){const t=this._addImplicitHelpCommand??(this.commands.length&&!this._actionHandler&&!this._findCommand("help"));if(t){if(this._helpCommand===undefined){this.helpCommand(undefined,undefined)}return this._helpCommand}return null}hook(t,e){const i=["preSubcommand","preAction","postAction"];if(!i.includes(t)){throw new Error(`Unexpected value for event passed to hook : '${t}'.\nExpecting one of '${i.join("', '")}'`)}if(this._lifeCycleHooks[t]){this._lifeCycleHooks[t].push(e)}else{this._lifeCycleHooks[t]=[e]}return this}exitOverride(t){if(t){this._exitCallback=t}else{this._exitCallback=t=>{if(t.code!=="commander.executeSubCommandAsync"){throw t}else{}}}return this}_exit(t,e,i){if(this._exitCallback){this._exitCallback(new u(t,e,i))}a.exit(t)}action(t){const listener=e=>{const i=this.registeredArguments.length;const n=e.slice(0,i);if(this._storeOptionsAsProperties){n[i]=this}else{n[i]=this.opts()}n.push(this);return t.apply(this,n)};this._actionHandler=listener;return this}createOption(t,e){return new p(t,e)}_callParseArg(t,e,i,n){try{return t.parseArg(e,i)}catch(t){if(t.code==="commander.invalidArgument"){const e=`${n} ${t.message}`;this.error(e,{exitCode:t.exitCode,code:t.code})}throw t}}_registerOption(t){const e=t.short&&this._findOption(t.short)||t.long&&this._findOption(t.long);if(e){const i=t.long&&this._findOption(t.long)?t.long:t.short;throw new Error(`Cannot add option '${t.flags}'${this._name&&` to command '${this._name}'`} due to conflicting flag '${i}'\n- already used by option '${e.flags}'`)}this.options.push(t)}_registerCommand(t){const knownBy=t=>[t.name()].concat(t.aliases());const e=knownBy(t).find((t=>this._findCommand(t)));if(e){const i=knownBy(this._findCommand(e)).join("|");const n=knownBy(t).join("|");throw new Error(`cannot add command '${n}' as already have command '${i}'`)}this.commands.push(t)}addOption(t){this._registerOption(t);const e=t.name();const i=t.attributeName();if(t.negate){const e=t.long.replace(/^--no-/,"--");if(!this._findOption(e)){this.setOptionValueWithSource(i,t.defaultValue===undefined?true:t.defaultValue,"default")}}else if(t.defaultValue!==undefined){this.setOptionValueWithSource(i,t.defaultValue,"default")}const handleOptionValue=(e,n,s)=>{if(e==null&&t.presetArg!==undefined){e=t.presetArg}const r=this.getOptionValue(i);if(e!==null&&t.parseArg){e=this._callParseArg(t,e,r,n)}else if(e!==null&&t.variadic){e=t._concatValue(e,r)}if(e==null){if(t.negate){e=false}else if(t.isBoolean()||t.optional){e=true}else{e=""}}this.setOptionValueWithSource(i,e,s)};this.on("option:"+e,(e=>{const i=`error: option '${t.flags}' argument '${e}' is invalid.`;handleOptionValue(e,i,"cli")}));if(t.envVar){this.on("optionEnv:"+e,(e=>{const i=`error: option '${t.flags}' value '${e}' from env '${t.envVar}' is invalid.`;handleOptionValue(e,i,"env")}))}return this}_optionEx(t,e,i,n,s){if(typeof e==="object"&&e instanceof p){throw new Error("To add an Option object use addOption() instead of option() or requiredOption()")}const r=this.createOption(e,i);r.makeOptionMandatory(!!t.mandatory);if(typeof n==="function"){r.default(s).argParser(n)}else if(n instanceof RegExp){const t=n;n=(e,i)=>{const n=t.exec(e);return n?n[0]:i};r.default(s).argParser(n)}else{r.default(n)}return this.addOption(r)}option(t,e,i,n){return this._optionEx({},t,e,i,n)}requiredOption(t,e,i,n){return this._optionEx({mandatory:true},t,e,i,n)}combineFlagAndOptionalValue(t=true){this._combineFlagAndOptionalValue=!!t;return this}allowUnknownOption(t=true){this._allowUnknownOption=!!t;return this}allowExcessArguments(t=true){this._allowExcessArguments=!!t;return this}enablePositionalOptions(t=true){this._enablePositionalOptions=!!t;return this}passThroughOptions(t=true){this._passThroughOptions=!!t;this._checkForBrokenPassThrough();return this}_checkForBrokenPassThrough(){if(this.parent&&this._passThroughOptions&&!this.parent._enablePositionalOptions){throw new Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`)}}storeOptionsAsProperties(t=true){if(this.options.length){throw new Error("call .storeOptionsAsProperties() before adding options")}if(Object.keys(this._optionValues).length){throw new Error("call .storeOptionsAsProperties() before setting option values")}this._storeOptionsAsProperties=!!t;return this}getOptionValue(t){if(this._storeOptionsAsProperties){return this[t]}return this._optionValues[t]}setOptionValue(t,e){return this.setOptionValueWithSource(t,e,undefined)}setOptionValueWithSource(t,e,i){if(this._storeOptionsAsProperties){this[t]=e}else{this._optionValues[t]=e}this._optionValueSources[t]=i;return this}getOptionValueSource(t){return this._optionValueSources[t]}getOptionValueSourceWithGlobals(t){let e;this._getCommandAndAncestors().forEach((i=>{if(i.getOptionValueSource(t)!==undefined){e=i.getOptionValueSource(t)}}));return e}_prepareUserArgs(t,e){if(t!==undefined&&!Array.isArray(t)){throw new Error("first parameter to parse must be array or undefined")}e=e||{};if(t===undefined){t=a.argv;if(a.versions&&a.versions.electron){e.from="electron"}}this.rawArgs=t.slice();let i;switch(e.from){case undefined:case"node":this._scriptPath=t[1];i=t.slice(2);break;case"electron":if(a.defaultApp){this._scriptPath=t[1];i=t.slice(2)}else{i=t.slice(1)}break;case"user":i=t.slice(0);break;default:throw new Error(`unexpected parse option { from: '${e.from}' }`)}if(!this._name&&this._scriptPath)this.nameFromFilename(this._scriptPath);this._name=this._name||"program";return i}parse(t,e){const i=this._prepareUserArgs(t,e);this._parseCommand([],i);return this}async parseAsync(t,e){const i=this._prepareUserArgs(t,e);await this._parseCommand([],i);return this}_executeSubCommand(t,e){e=e.slice();let i=false;const n=[".js",".ts",".tsx",".mjs",".cjs"];function findFile(t,e){const i=r.resolve(t,e);if(o.existsSync(i))return i;if(n.includes(r.extname(e)))return undefined;const s=n.find((t=>o.existsSync(`${i}${t}`)));if(s)return`${i}${s}`;return undefined}this._checkForMissingMandatoryOptions();this._checkForConflictingOptions();let h=t._executableFile||`${this._name}-${t._name}`;let l=this._executableDir||"";if(this._scriptPath){let t;try{t=o.realpathSync(this._scriptPath)}catch(e){t=this._scriptPath}l=r.resolve(r.dirname(t),l)}if(l){let e=findFile(l,h);if(!e&&!t._executableFile&&this._scriptPath){const i=r.basename(this._scriptPath,r.extname(this._scriptPath));if(i!==this._name){e=findFile(l,`${i}-${t._name}`)}}h=e||h}i=n.includes(r.extname(h));let c;if(a.platform!=="win32"){if(i){e.unshift(h);e=incrementNodeInspectorPort(a.execArgv).concat(e);c=s.spawn(a.argv[0],e,{stdio:"inherit"})}else{c=s.spawn(h,e,{stdio:"inherit"})}}else{e.unshift(h);e=incrementNodeInspectorPort(a.execArgv).concat(e);c=s.spawn(a.execPath,e,{stdio:"inherit"})}if(!c.killed){const t=["SIGUSR1","SIGUSR2","SIGTERM","SIGINT","SIGHUP"];t.forEach((t=>{a.on(t,(()=>{if(c.killed===false&&c.exitCode===null){c.kill(t)}}))}))}const p=this._exitCallback;c.on("close",((t,e)=>{t=t??1;if(!p){a.exit(t)}else{p(new u(t,"commander.executeSubCommandAsync","(close)"))}}));c.on("error",(e=>{if(e.code==="ENOENT"){const e=l?`searched for local subcommand relative to directory '${l}'`:"no directory for search for local subcommand, use .executableDir() to supply a custom directory";const i=`'${h}' does not exist\n - if '${t._name}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead\n - if the default executable name is not suitable, use the executableFile option to supply a custom name or path\n - ${e}`;throw new Error(i)}else if(e.code==="EACCES"){throw new Error(`'${h}' not executable`)}if(!p){a.exit(1)}else{const t=new u(1,"commander.executeSubCommandAsync","(error)");t.nestedError=e;p(t)}}));this.runningCommand=c}_dispatchSubcommand(t,e,i){const n=this._findCommand(t);if(!n)this.help({error:true});let s;s=this._chainOrCallSubCommandHook(s,n,"preSubcommand");s=this._chainOrCall(s,(()=>{if(n._executableHandler){this._executeSubCommand(n,e.concat(i))}else{return n._parseCommand(e,i)}}));return s}_dispatchHelpCommand(t){if(!t){this.help()}const e=this._findCommand(t);if(e&&!e._executableHandler){e.help()}return this._dispatchSubcommand(t,[],[this._getHelpOption()?.long??this._getHelpOption()?.short??"--help"])}_checkNumberOfArguments(){this.registeredArguments.forEach(((t,e)=>{if(t.required&&this.args[e]==null){this.missingArgument(t.name())}}));if(this.registeredArguments.length>0&&this.registeredArguments[this.registeredArguments.length-1].variadic){return}if(this.args.length>this.registeredArguments.length){this._excessArguments(this.args)}}_processArguments(){const myParseArg=(t,e,i)=>{let n=e;if(e!==null&&t.parseArg){const s=`error: command-argument value '${e}' is invalid for argument '${t.name()}'.`;n=this._callParseArg(t,e,i,s)}return n};this._checkNumberOfArguments();const t=[];this.registeredArguments.forEach(((e,i)=>{let n=e.defaultValue;if(e.variadic){if(imyParseArg(e,i,t)),e.defaultValue)}}else if(n===undefined){n=[]}}else if(ie()))}return e()}_chainOrCallHooks(t,e){let i=t;const n=[];this._getCommandAndAncestors().reverse().filter((t=>t._lifeCycleHooks[e]!==undefined)).forEach((t=>{t._lifeCycleHooks[e].forEach((e=>{n.push({hookedCommand:t,callback:e})}))}));if(e==="postAction"){n.reverse()}n.forEach((t=>{i=this._chainOrCall(i,(()=>t.callback(t.hookedCommand,this)))}));return i}_chainOrCallSubCommandHook(t,e,i){let n=t;if(this._lifeCycleHooks[i]!==undefined){this._lifeCycleHooks[i].forEach((t=>{n=this._chainOrCall(n,(()=>t(this,e)))}))}return n}_parseCommand(t,e){const i=this.parseOptions(e);this._parseOptionsEnv();this._parseOptionsImplied();t=t.concat(i.operands);e=i.unknown;this.args=t.concat(e);if(t&&this._findCommand(t[0])){return this._dispatchSubcommand(t[0],t.slice(1),e)}if(this._getHelpCommand()&&t[0]===this._getHelpCommand().name()){return this._dispatchHelpCommand(t[1])}if(this._defaultCommandName){this._outputHelpIfRequested(e);return this._dispatchSubcommand(this._defaultCommandName,t,e)}if(this.commands.length&&this.args.length===0&&!this._actionHandler&&!this._defaultCommandName){this.help({error:true})}this._outputHelpIfRequested(i.unknown);this._checkForMissingMandatoryOptions();this._checkForConflictingOptions();const checkForUnknownOptions=()=>{if(i.unknown.length>0){this.unknownOption(i.unknown[0])}};const n=`command:${this.name()}`;if(this._actionHandler){checkForUnknownOptions();this._processArguments();let i;i=this._chainOrCallHooks(i,"preAction");i=this._chainOrCall(i,(()=>this._actionHandler(this.processedArgs)));if(this.parent){i=this._chainOrCall(i,(()=>{this.parent.emit(n,t,e)}))}i=this._chainOrCallHooks(i,"postAction");return i}if(this.parent&&this.parent.listenerCount(n)){checkForUnknownOptions();this._processArguments();this.parent.emit(n,t,e)}else if(t.length){if(this._findCommand("*")){return this._dispatchSubcommand("*",t,e)}if(this.listenerCount("command:*")){this.emit("command:*",t,e)}else if(this.commands.length){this.unknownCommand()}else{checkForUnknownOptions();this._processArguments()}}else if(this.commands.length){checkForUnknownOptions();this.help({error:true})}else{checkForUnknownOptions();this._processArguments()}}_findCommand(t){if(!t)return undefined;return this.commands.find((e=>e._name===t||e._aliases.includes(t)))}_findOption(t){return this.options.find((e=>e.is(t)))}_checkForMissingMandatoryOptions(){this._getCommandAndAncestors().forEach((t=>{t.options.forEach((e=>{if(e.mandatory&&t.getOptionValue(e.attributeName())===undefined){t.missingMandatoryOptionValue(e)}}))}))}_checkForConflictingLocalOptions(){const t=this.options.filter((t=>{const e=t.attributeName();if(this.getOptionValue(e)===undefined){return false}return this.getOptionValueSource(e)!=="default"}));const e=t.filter((t=>t.conflictsWith.length>0));e.forEach((e=>{const i=t.find((t=>e.conflictsWith.includes(t.attributeName())));if(i){this._conflictingOption(e,i)}}))}_checkForConflictingOptions(){this._getCommandAndAncestors().forEach((t=>{t._checkForConflictingLocalOptions()}))}parseOptions(t){const e=[];const i=[];let n=e;const s=t.slice();function maybeOption(t){return t.length>1&&t[0]==="-"}let r=null;while(s.length){const t=s.shift();if(t==="--"){if(n===i)n.push(t);n.push(...s);break}if(r&&!maybeOption(t)){this.emit(`option:${r.name()}`,t);continue}r=null;if(maybeOption(t)){const e=this._findOption(t);if(e){if(e.required){const t=s.shift();if(t===undefined)this.optionMissingArgument(e);this.emit(`option:${e.name()}`,t)}else if(e.optional){let t=null;if(s.length>0&&!maybeOption(s[0])){t=s.shift()}this.emit(`option:${e.name()}`,t)}else{this.emit(`option:${e.name()}`)}r=e.variadic?e:null;continue}}if(t.length>2&&t[0]==="-"&&t[1]!=="-"){const e=this._findOption(`-${t[1]}`);if(e){if(e.required||e.optional&&this._combineFlagAndOptionalValue){this.emit(`option:${e.name()}`,t.slice(2))}else{this.emit(`option:${e.name()}`);s.unshift(`-${t.slice(2)}`)}continue}}if(/^--[^=]+=/.test(t)){const e=t.indexOf("=");const i=this._findOption(t.slice(0,e));if(i&&(i.required||i.optional)){this.emit(`option:${i.name()}`,t.slice(e+1));continue}}if(maybeOption(t)){n=i}if((this._enablePositionalOptions||this._passThroughOptions)&&e.length===0&&i.length===0){if(this._findCommand(t)){e.push(t);if(s.length>0)i.push(...s);break}else if(this._getHelpCommand()&&t===this._getHelpCommand().name()){e.push(t);if(s.length>0)e.push(...s);break}else if(this._defaultCommandName){i.push(t);if(s.length>0)i.push(...s);break}}if(this._passThroughOptions){n.push(t);if(s.length>0)n.push(...s);break}n.push(t)}return{operands:e,unknown:i}}opts(){if(this._storeOptionsAsProperties){const t={};const e=this.options.length;for(let i=0;iObject.assign(t,e.opts())),{})}error(t,e){this._outputConfiguration.outputError(`${t}\n`,this._outputConfiguration.writeErr);if(typeof this._showHelpAfterError==="string"){this._outputConfiguration.writeErr(`${this._showHelpAfterError}\n`)}else if(this._showHelpAfterError){this._outputConfiguration.writeErr("\n");this.outputHelp({error:true})}const i=e||{};const n=i.exitCode||1;const s=i.code||"commander.error";this._exit(n,s,t)}_parseOptionsEnv(){this.options.forEach((t=>{if(t.envVar&&t.envVar in a.env){const e=t.attributeName();if(this.getOptionValue(e)===undefined||["default","config","env"].includes(this.getOptionValueSource(e))){if(t.required||t.optional){this.emit(`optionEnv:${t.name()}`,a.env[t.envVar])}else{this.emit(`optionEnv:${t.name()}`)}}}}))}_parseOptionsImplied(){const t=new d(this.options);const hasCustomOptionValue=t=>this.getOptionValue(t)!==undefined&&!["default","implied"].includes(this.getOptionValueSource(t));this.options.filter((e=>e.implied!==undefined&&hasCustomOptionValue(e.attributeName())&&t.valueFromOption(this.getOptionValue(e.attributeName()),e))).forEach((t=>{Object.keys(t.implied).filter((t=>!hasCustomOptionValue(t))).forEach((e=>{this.setOptionValueWithSource(e,t.implied[e],"implied")}))}))}missingArgument(t){const e=`error: missing required argument '${t}'`;this.error(e,{code:"commander.missingArgument"})}optionMissingArgument(t){const e=`error: option '${t.flags}' argument missing`;this.error(e,{code:"commander.optionMissingArgument"})}missingMandatoryOptionValue(t){const e=`error: required option '${t.flags}' not specified`;this.error(e,{code:"commander.missingMandatoryOptionValue"})}_conflictingOption(t,e){const findBestOptionFromValue=t=>{const e=t.attributeName();const i=this.getOptionValue(e);const n=this.options.find((t=>t.negate&&e===t.attributeName()));const s=this.options.find((t=>!t.negate&&e===t.attributeName()));if(n&&(n.presetArg===undefined&&i===false||n.presetArg!==undefined&&i===n.presetArg)){return n}return s||t};const getErrorMessage=t=>{const e=findBestOptionFromValue(t);const i=e.attributeName();const n=this.getOptionValueSource(i);if(n==="env"){return`environment variable '${e.envVar}'`}return`option '${e.flags}'`};const i=`error: ${getErrorMessage(t)} cannot be used with ${getErrorMessage(e)}`;this.error(i,{code:"commander.conflictingOption"})}unknownOption(t){if(this._allowUnknownOption)return;let e="";if(t.startsWith("--")&&this._showSuggestionAfterError){let i=[];let n=this;do{const t=n.createHelp().visibleOptions(n).filter((t=>t.long)).map((t=>t.long));i=i.concat(t);n=n.parent}while(n&&!n._enablePositionalOptions);e=m(t,i)}const i=`error: unknown option '${t}'${e}`;this.error(i,{code:"commander.unknownOption"})}_excessArguments(t){if(this._allowExcessArguments)return;const e=this.registeredArguments.length;const i=e===1?"":"s";const n=this.parent?` for '${this.name()}'`:"";const s=`error: too many arguments${n}. Expected ${e} argument${i} but got ${t.length}.`;this.error(s,{code:"commander.excessArguments"})}unknownCommand(){const t=this.args[0];let e="";if(this._showSuggestionAfterError){const i=[];this.createHelp().visibleCommands(this).forEach((t=>{i.push(t.name());if(t.alias())i.push(t.alias())}));e=m(t,i)}const i=`error: unknown command '${t}'${e}`;this.error(i,{code:"commander.unknownCommand"})}version(t,e,i){if(t===undefined)return this._version;this._version=t;e=e||"-V, --version";i=i||"output the version number";const n=this.createOption(e,i);this._versionOptionName=n.attributeName();this._registerOption(n);this.on("option:"+n.name(),(()=>{this._outputConfiguration.writeOut(`${t}\n`);this._exit(0,"commander.version",t)}));return this}description(t,e){if(t===undefined&&e===undefined)return this._description;this._description=t;if(e){this._argsDescription=e}return this}summary(t){if(t===undefined)return this._summary;this._summary=t;return this}alias(t){if(t===undefined)return this._aliases[0];let e=this;if(this.commands.length!==0&&this.commands[this.commands.length-1]._executableHandler){e=this.commands[this.commands.length-1]}if(t===e._name)throw new Error("Command alias can't be the same as its name");const i=this.parent?._findCommand(t);if(i){const e=[i.name()].concat(i.aliases()).join("|");throw new Error(`cannot add alias '${t}' to command '${this.name()}' as already have command '${e}'`)}e._aliases.push(t);return this}aliases(t){if(t===undefined)return this._aliases;t.forEach((t=>this.alias(t)));return this}usage(t){if(t===undefined){if(this._usage)return this._usage;const t=this.registeredArguments.map((t=>l(t)));return[].concat(this.options.length||this._helpOption!==null?"[options]":[],this.commands.length?"[command]":[],this.registeredArguments.length?t:[]).join(" ")}this._usage=t;return this}name(t){if(t===undefined)return this._name;this._name=t;return this}nameFromFilename(t){this._name=r.basename(t,r.extname(t));return this}executableDir(t){if(t===undefined)return this._executableDir;this._executableDir=t;return this}helpInformation(t){const e=this.createHelp();if(e.helpWidth===undefined){e.helpWidth=t&&t.error?this._outputConfiguration.getErrHelpWidth():this._outputConfiguration.getOutHelpWidth()}return e.formatHelp(this,e)}_getHelpContext(t){t=t||{};const e={error:!!t.error};let i;if(e.error){i=t=>this._outputConfiguration.writeErr(t)}else{i=t=>this._outputConfiguration.writeOut(t)}e.write=t.write||i;e.command=this;return e}outputHelp(t){let e;if(typeof t==="function"){e=t;t=undefined}const i=this._getHelpContext(t);this._getCommandAndAncestors().reverse().forEach((t=>t.emit("beforeAllHelp",i)));this.emit("beforeHelp",i);let n=this.helpInformation(i);if(e){n=e(n);if(typeof n!=="string"&&!Buffer.isBuffer(n)){throw new Error("outputHelp callback must return a string or a Buffer")}}i.write(n);if(this._getHelpOption()?.long){this.emit(this._getHelpOption().long)}this.emit("afterHelp",i);this._getCommandAndAncestors().forEach((t=>t.emit("afterAllHelp",i)))}helpOption(t,e){if(typeof t==="boolean"){if(t){this._helpOption=this._helpOption??undefined}else{this._helpOption=null}return this}t=t??"-h, --help";e=e??"display help for command";this._helpOption=this.createOption(t,e);return this}_getHelpOption(){if(this._helpOption===undefined){this.helpOption(undefined,undefined)}return this._helpOption}addHelpOption(t){this._helpOption=t;return this}help(t){this.outputHelp(t);let e=a.exitCode||0;if(e===0&&t&&typeof t!=="function"&&t.error){e=1}this._exit(e,"commander.help","(outputHelp)")}addHelpText(t,e){const i=["beforeAll","before","after","afterAll"];if(!i.includes(t)){throw new Error(`Unexpected value for position to addHelpText.\nExpecting one of '${i.join("', '")}'`)}const n=`${t}Help`;this.on(n,(t=>{let i;if(typeof e==="function"){i=e({error:t.error,command:t.command})}else{i=e}if(i){t.write(`${i}\n`)}}));return this}_outputHelpIfRequested(t){const e=this._getHelpOption();const i=e&&t.find((t=>e.is(t)));if(i){this.outputHelp();this._exit(0,"commander.helpDisplayed","(outputHelp)")}}}function incrementNodeInspectorPort(t){return t.map((t=>{if(!t.startsWith("--inspect")){return t}let e;let i="127.0.0.1";let n="9229";let s;if((s=t.match(/^(--inspect(-brk)?)$/))!==null){e=s[1]}else if((s=t.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null){e=s[1];if(/^\d+$/.test(s[3])){n=s[3]}else{i=s[3]}}else if((s=t.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null){e=s[1];i=s[3];n=s[4]}if(e&&n!=="0"){return`${e}=${i}:${parseInt(n)+1}`}return t}))}e.Command=Command},854:(t,e)=>{class CommanderError extends Error{constructor(t,e,i){super(i);Error.captureStackTrace(this,this.constructor);this.name=this.constructor.name;this.code=e;this.exitCode=t;this.nestedError=undefined}}class InvalidArgumentError extends CommanderError{constructor(t){super(1,"commander.invalidArgument",t);Error.captureStackTrace(this,this.constructor);this.name=this.constructor.name}}e.CommanderError=CommanderError;e.InvalidArgumentError=InvalidArgumentError},853:(t,e,i)=>{const{humanReadableArgName:n}=i(161);class Help{constructor(){this.helpWidth=undefined;this.sortSubcommands=false;this.sortOptions=false;this.showGlobalOptions=false}visibleCommands(t){const e=t.commands.filter((t=>!t._hidden));const i=t._getHelpCommand();if(i&&!i._hidden){e.push(i)}if(this.sortSubcommands){e.sort(((t,e)=>t.name().localeCompare(e.name())))}return e}compareOptions(t,e){const getSortKey=t=>t.short?t.short.replace(/^-/,""):t.long.replace(/^--/,"");return getSortKey(t).localeCompare(getSortKey(e))}visibleOptions(t){const e=t.options.filter((t=>!t.hidden));const i=t._getHelpOption();if(i&&!i.hidden){const n=i.short&&t._findOption(i.short);const s=i.long&&t._findOption(i.long);if(!n&&!s){e.push(i)}else if(i.long&&!s){e.push(t.createOption(i.long,i.description))}else if(i.short&&!n){e.push(t.createOption(i.short,i.description))}}if(this.sortOptions){e.sort(this.compareOptions)}return e}visibleGlobalOptions(t){if(!this.showGlobalOptions)return[];const e=[];for(let i=t.parent;i;i=i.parent){const t=i.options.filter((t=>!t.hidden));e.push(...t)}if(this.sortOptions){e.sort(this.compareOptions)}return e}visibleArguments(t){if(t._argsDescription){t.registeredArguments.forEach((e=>{e.description=e.description||t._argsDescription[e.name()]||""}))}if(t.registeredArguments.find((t=>t.description))){return t.registeredArguments}return[]}subcommandTerm(t){const e=t.registeredArguments.map((t=>n(t))).join(" ");return t._name+(t._aliases[0]?"|"+t._aliases[0]:"")+(t.options.length?" [options]":"")+(e?" "+e:"")}optionTerm(t){return t.flags}argumentTerm(t){return t.name()}longestSubcommandTermLength(t,e){return e.visibleCommands(t).reduce(((t,i)=>Math.max(t,e.subcommandTerm(i).length)),0)}longestOptionTermLength(t,e){return e.visibleOptions(t).reduce(((t,i)=>Math.max(t,e.optionTerm(i).length)),0)}longestGlobalOptionTermLength(t,e){return e.visibleGlobalOptions(t).reduce(((t,i)=>Math.max(t,e.optionTerm(i).length)),0)}longestArgumentTermLength(t,e){return e.visibleArguments(t).reduce(((t,i)=>Math.max(t,e.argumentTerm(i).length)),0)}commandUsage(t){let e=t._name;if(t._aliases[0]){e=e+"|"+t._aliases[0]}let i="";for(let e=t.parent;e;e=e.parent){i=e.name()+" "+i}return i+e+" "+t.usage()}commandDescription(t){return t.description()}subcommandDescription(t){return t.summary()||t.description()}optionDescription(t){const e=[];if(t.argChoices){e.push(`choices: ${t.argChoices.map((t=>JSON.stringify(t))).join(", ")}`)}if(t.defaultValue!==undefined){const i=t.required||t.optional||t.isBoolean()&&typeof t.defaultValue==="boolean";if(i){e.push(`default: ${t.defaultValueDescription||JSON.stringify(t.defaultValue)}`)}}if(t.presetArg!==undefined&&t.optional){e.push(`preset: ${JSON.stringify(t.presetArg)}`)}if(t.envVar!==undefined){e.push(`env: ${t.envVar}`)}if(e.length>0){return`${t.description} (${e.join(", ")})`}return t.description}argumentDescription(t){const e=[];if(t.argChoices){e.push(`choices: ${t.argChoices.map((t=>JSON.stringify(t))).join(", ")}`)}if(t.defaultValue!==undefined){e.push(`default: ${t.defaultValueDescription||JSON.stringify(t.defaultValue)}`)}if(e.length>0){const i=`(${e.join(", ")})`;if(t.description){return`${t.description} ${i}`}return i}return t.description}formatHelp(t,e){const i=e.padWidth(t,e);const n=e.helpWidth||80;const s=2;const r=2;function formatItem(t,o){if(o){const a=`${t.padEnd(i+r)}${o}`;return e.wrap(a,n-s,i+r)}return t}function formatList(t){return t.join("\n").replace(/^/gm," ".repeat(s))}let o=[`Usage: ${e.commandUsage(t)}`,""];const a=e.commandDescription(t);if(a.length>0){o=o.concat([e.wrap(a,n,0),""])}const h=e.visibleArguments(t).map((t=>formatItem(e.argumentTerm(t),e.argumentDescription(t))));if(h.length>0){o=o.concat(["Arguments:",formatList(h),""])}const l=e.visibleOptions(t).map((t=>formatItem(e.optionTerm(t),e.optionDescription(t))));if(l.length>0){o=o.concat(["Options:",formatList(l),""])}if(this.showGlobalOptions){const i=e.visibleGlobalOptions(t).map((t=>formatItem(e.optionTerm(t),e.optionDescription(t))));if(i.length>0){o=o.concat(["Global Options:",formatList(i),""])}}const u=e.visibleCommands(t).map((t=>formatItem(e.subcommandTerm(t),e.subcommandDescription(t))));if(u.length>0){o=o.concat(["Commands:",formatList(u),""])}return o.join("\n")}padWidth(t,e){return Math.max(e.longestOptionTermLength(t,e),e.longestGlobalOptionTermLength(t,e),e.longestSubcommandTermLength(t,e),e.longestArgumentTermLength(t,e))}wrap(t,e,i,n=40){const s=" \\f\\t\\v   -    \ufeff";const r=new RegExp(`[\\n][${s}]+`);if(t.match(r))return t;const o=e-i;if(o{if(t==="\n")return"";return(e>0?l:"")+t.trimEnd()})).join("\n")}}e.Help=Help},548:(t,e,i)=>{const{InvalidArgumentError:n}=i(854);class Option{constructor(t,e){this.flags=t;this.description=e||"";this.required=t.includes("<");this.optional=t.includes("[");this.variadic=/\w\.\.\.[>\]]$/.test(t);this.mandatory=false;const i=splitOptionFlags(t);this.short=i.shortFlag;this.long=i.longFlag;this.negate=false;if(this.long){this.negate=this.long.startsWith("--no-")}this.defaultValue=undefined;this.defaultValueDescription=undefined;this.presetArg=undefined;this.envVar=undefined;this.parseArg=undefined;this.hidden=false;this.argChoices=undefined;this.conflictsWith=[];this.implied=undefined}default(t,e){this.defaultValue=t;this.defaultValueDescription=e;return this}preset(t){this.presetArg=t;return this}conflicts(t){this.conflictsWith=this.conflictsWith.concat(t);return this}implies(t){let e=t;if(typeof t==="string"){e={[t]:true}}this.implied=Object.assign(this.implied||{},e);return this}env(t){this.envVar=t;return this}argParser(t){this.parseArg=t;return this}makeOptionMandatory(t=true){this.mandatory=!!t;return this}hideHelp(t=true){this.hidden=!!t;return this}_concatValue(t,e){if(e===this.defaultValue||!Array.isArray(e)){return[t]}return e.concat(t)}choices(t){this.argChoices=t.slice();this.parseArg=(t,e)=>{if(!this.argChoices.includes(t)){throw new n(`Allowed choices are ${this.argChoices.join(", ")}.`)}if(this.variadic){return this._concatValue(t,e)}return t};return this}name(){if(this.long){return this.long.replace(/^--/,"")}return this.short.replace(/^-/,"")}attributeName(){return camelcase(this.name().replace(/^no-/,""))}is(t){return this.short===t||this.long===t}isBoolean(){return!this.required&&!this.optional&&!this.negate}}class DualOptions{constructor(t){this.positiveOptions=new Map;this.negativeOptions=new Map;this.dualOptions=new Set;t.forEach((t=>{if(t.negate){this.negativeOptions.set(t.attributeName(),t)}else{this.positiveOptions.set(t.attributeName(),t)}}));this.negativeOptions.forEach(((t,e)=>{if(this.positiveOptions.has(e)){this.dualOptions.add(e)}}))}valueFromOption(t,e){const i=e.attributeName();if(!this.dualOptions.has(i))return true;const n=this.negativeOptions.get(i).presetArg;const s=n!==undefined?n:false;return e.negate===(s===t)}}function camelcase(t){return t.split("-").reduce(((t,e)=>t+e[0].toUpperCase()+e.slice(1)))}function splitOptionFlags(t){let e;let i;const n=t.split(/[ |,]+/);if(n.length>1&&!/^[[<]/.test(n[1]))e=n.shift();i=n.shift();if(!e&&/^-[^-]$/.test(i)){e=i;i=undefined}return{shortFlag:e,longFlag:i}}e.Option=Option;e.DualOptions=DualOptions},324:(t,e)=>{const i=3;function editDistance(t,e){if(Math.abs(t.length-e.length)>i)return Math.max(t.length,e.length);const n=[];for(let e=0;e<=t.length;e++){n[e]=[e]}for(let t=0;t<=e.length;t++){n[0][t]=t}for(let i=1;i<=e.length;i++){for(let s=1;s<=t.length;s++){let r=1;if(t[s-1]===e[i-1]){r=0}else{r=1}n[s][i]=Math.min(n[s-1][i]+1,n[s][i-1]+1,n[s-1][i-1]+r);if(s>1&&i>1&&t[s-1]===e[i-2]&&t[s-2]===e[i-1]){n[s][i]=Math.min(n[s][i],n[s-2][i-2]+1)}}}return n[t.length][e.length]}function suggestSimilar(t,e){if(!e||e.length===0)return"";e=Array.from(new Set(e));const n=t.startsWith("--");if(n){t=t.slice(2);e=e.map((t=>t.slice(2)))}let s=[];let r=i;const o=.4;e.forEach((e=>{if(e.length<=1)return;const i=editDistance(t,e);const n=Math.max(t.length,e.length);const a=(n-i)/n;if(a>o){if(it.localeCompare(e)));if(n){s=s.map((t=>`--${t}`))}if(s.length>1){return`\n(Did you mean one of ${s.join(", ")}?)`}if(s.length===1){return`\n(Did you mean ${s[0]}?)`}return""}e.suggestSimilar=suggestSimilar}};var e={};function __nccwpck_require__(i){var n=e[i];if(n!==undefined){return n.exports}var s=e[i]={exports:{}};var r=true;try{t[i](s,s.exports,__nccwpck_require__);r=false}finally{if(r)delete e[i]}return s.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var i={};(()=>{var t=i;const{Argument:e}=__nccwpck_require__(161);const{Command:n}=__nccwpck_require__(695);const{CommanderError:s,InvalidArgumentError:r}=__nccwpck_require__(854);const{Help:o}=__nccwpck_require__(853);const{Option:a}=__nccwpck_require__(548);t.program=new n;t.createCommand=t=>new n(t);t.createOption=(t,e)=>new a(t,e);t.createArgument=(t,i)=>new e(t,i);t.Command=n;t.Option=a;t.Argument=e;t.Help=o;t.CommanderError=s;t.InvalidArgumentError=r;t.InvalidOptionArgumentError=r})();module.exports=i})(); \ No newline at end of file +(()=>{var e={718:e=>{"use strict";e.exports=require("node:child_process")},673:e=>{"use strict";e.exports=require("node:events")},561:e=>{"use strict";e.exports=require("node:fs")},411:e=>{"use strict";e.exports=require("node:path")},742:e=>{"use strict";e.exports=require("node:process")},253:(e,t,i)=>{const{InvalidArgumentError:n}=i(299);class Argument{constructor(e,t){this.description=t||"";this.variadic=false;this.parseArg=undefined;this.defaultValue=undefined;this.defaultValueDescription=undefined;this.argChoices=undefined;switch(e[0]){case"<":this.required=true;this._name=e.slice(1,-1);break;case"[":this.required=false;this._name=e.slice(1,-1);break;default:this.required=true;this._name=e;break}if(this._name.length>3&&this._name.slice(-3)==="..."){this.variadic=true;this._name=this._name.slice(0,-3)}}name(){return this._name}_concatValue(e,t){if(t===this.defaultValue||!Array.isArray(t)){return[e]}return t.concat(e)}default(e,t){this.defaultValue=e;this.defaultValueDescription=t;return this}argParser(e){this.parseArg=e;return this}choices(e){this.argChoices=e.slice();this.parseArg=(e,t)=>{if(!this.argChoices.includes(e)){throw new n(`Allowed choices are ${this.argChoices.join(", ")}.`)}if(this.variadic){return this._concatValue(e,t)}return e};return this}argRequired(){this.required=true;return this}argOptional(){this.required=false;return this}}function humanReadableArgName(e){const t=e.name()+(e.variadic===true?"...":"");return e.required?"<"+t+">":"["+t+"]"}t.Argument=Argument;t.humanReadableArgName=humanReadableArgName},119:(e,t,i)=>{const n=i(673).EventEmitter;const s=i(718);const r=i(411);const o=i(561);const a=i(742);const{Argument:h,humanReadableArgName:l}=i(253);const{CommanderError:u}=i(299);const{Help:c}=i(638);const{Option:p,DualOptions:d}=i(77);const{suggestSimilar:m}=i(301);class Command extends n{constructor(e){super();this.commands=[];this.options=[];this.parent=null;this._allowUnknownOption=false;this._allowExcessArguments=true;this.registeredArguments=[];this._args=this.registeredArguments;this.args=[];this.rawArgs=[];this.processedArgs=[];this._scriptPath=null;this._name=e||"";this._optionValues={};this._optionValueSources={};this._storeOptionsAsProperties=false;this._actionHandler=null;this._executableHandler=false;this._executableFile=null;this._executableDir=null;this._defaultCommandName=null;this._exitCallback=null;this._aliases=[];this._combineFlagAndOptionalValue=true;this._description="";this._summary="";this._argsDescription=undefined;this._enablePositionalOptions=false;this._passThroughOptions=false;this._lifeCycleHooks={};this._showHelpAfterError=false;this._showSuggestionAfterError=true;this._outputConfiguration={writeOut:e=>a.stdout.write(e),writeErr:e=>a.stderr.write(e),getOutHelpWidth:()=>a.stdout.isTTY?a.stdout.columns:undefined,getErrHelpWidth:()=>a.stderr.isTTY?a.stderr.columns:undefined,outputError:(e,t)=>t(e)};this._hidden=false;this._helpOption=undefined;this._addImplicitHelpCommand=undefined;this._helpCommand=undefined;this._helpConfiguration={}}copyInheritedSettings(e){this._outputConfiguration=e._outputConfiguration;this._helpOption=e._helpOption;this._helpCommand=e._helpCommand;this._helpConfiguration=e._helpConfiguration;this._exitCallback=e._exitCallback;this._storeOptionsAsProperties=e._storeOptionsAsProperties;this._combineFlagAndOptionalValue=e._combineFlagAndOptionalValue;this._allowExcessArguments=e._allowExcessArguments;this._enablePositionalOptions=e._enablePositionalOptions;this._showHelpAfterError=e._showHelpAfterError;this._showSuggestionAfterError=e._showSuggestionAfterError;return this}_getCommandAndAncestors(){const e=[];for(let t=this;t;t=t.parent){e.push(t)}return e}command(e,t,i){let n=t;let s=i;if(typeof n==="object"&&n!==null){s=n;n=null}s=s||{};const[,r,o]=e.match(/([^ ]+) *(.*)/);const a=this.createCommand(r);if(n){a.description(n);a._executableHandler=true}if(s.isDefault)this._defaultCommandName=a._name;a._hidden=!!(s.noHelp||s.hidden);a._executableFile=s.executableFile||null;if(o)a.arguments(o);this._registerCommand(a);a.parent=this;a.copyInheritedSettings(this);if(n)return this;return a}createCommand(e){return new Command(e)}createHelp(){return Object.assign(new c,this.configureHelp())}configureHelp(e){if(e===undefined)return this._helpConfiguration;this._helpConfiguration=e;return this}configureOutput(e){if(e===undefined)return this._outputConfiguration;Object.assign(this._outputConfiguration,e);return this}showHelpAfterError(e=true){if(typeof e!=="string")e=!!e;this._showHelpAfterError=e;return this}showSuggestionAfterError(e=true){this._showSuggestionAfterError=!!e;return this}addCommand(e,t){if(!e._name){throw new Error(`Command passed to .addCommand() must have a name\n- specify the name in Command constructor or using .name()`)}t=t||{};if(t.isDefault)this._defaultCommandName=e._name;if(t.noHelp||t.hidden)e._hidden=true;this._registerCommand(e);e.parent=this;e._checkForBrokenPassThrough();return this}createArgument(e,t){return new h(e,t)}argument(e,t,i,n){const s=this.createArgument(e,t);if(typeof i==="function"){s.default(n).argParser(i)}else{s.default(i)}this.addArgument(s);return this}arguments(e){e.trim().split(/ +/).forEach((e=>{this.argument(e)}));return this}addArgument(e){const t=this.registeredArguments.slice(-1)[0];if(t&&t.variadic){throw new Error(`only the last argument can be variadic '${t.name()}'`)}if(e.required&&e.defaultValue!==undefined&&e.parseArg===undefined){throw new Error(`a default value for a required argument is never used: '${e.name()}'`)}this.registeredArguments.push(e);return this}helpCommand(e,t){if(typeof e==="boolean"){this._addImplicitHelpCommand=e;return this}e=e??"help [command]";const[,i,n]=e.match(/([^ ]+) *(.*)/);const s=t??"display help for command";const r=this.createCommand(i);r.helpOption(false);if(n)r.arguments(n);if(s)r.description(s);this._addImplicitHelpCommand=true;this._helpCommand=r;return this}addHelpCommand(e,t){if(typeof e!=="object"){this.helpCommand(e,t);return this}this._addImplicitHelpCommand=true;this._helpCommand=e;return this}_getHelpCommand(){const e=this._addImplicitHelpCommand??(this.commands.length&&!this._actionHandler&&!this._findCommand("help"));if(e){if(this._helpCommand===undefined){this.helpCommand(undefined,undefined)}return this._helpCommand}return null}hook(e,t){const i=["preSubcommand","preAction","postAction"];if(!i.includes(e)){throw new Error(`Unexpected value for event passed to hook : '${e}'.\nExpecting one of '${i.join("', '")}'`)}if(this._lifeCycleHooks[e]){this._lifeCycleHooks[e].push(t)}else{this._lifeCycleHooks[e]=[t]}return this}exitOverride(e){if(e){this._exitCallback=e}else{this._exitCallback=e=>{if(e.code!=="commander.executeSubCommandAsync"){throw e}else{}}}return this}_exit(e,t,i){if(this._exitCallback){this._exitCallback(new u(e,t,i))}a.exit(e)}action(e){const listener=t=>{const i=this.registeredArguments.length;const n=t.slice(0,i);if(this._storeOptionsAsProperties){n[i]=this}else{n[i]=this.opts()}n.push(this);return e.apply(this,n)};this._actionHandler=listener;return this}createOption(e,t){return new p(e,t)}_callParseArg(e,t,i,n){try{return e.parseArg(t,i)}catch(e){if(e.code==="commander.invalidArgument"){const t=`${n} ${e.message}`;this.error(t,{exitCode:e.exitCode,code:e.code})}throw e}}_registerOption(e){const t=e.short&&this._findOption(e.short)||e.long&&this._findOption(e.long);if(t){const i=e.long&&this._findOption(e.long)?e.long:e.short;throw new Error(`Cannot add option '${e.flags}'${this._name&&` to command '${this._name}'`} due to conflicting flag '${i}'\n- already used by option '${t.flags}'`)}this.options.push(e)}_registerCommand(e){const knownBy=e=>[e.name()].concat(e.aliases());const t=knownBy(e).find((e=>this._findCommand(e)));if(t){const i=knownBy(this._findCommand(t)).join("|");const n=knownBy(e).join("|");throw new Error(`cannot add command '${n}' as already have command '${i}'`)}this.commands.push(e)}addOption(e){this._registerOption(e);const t=e.name();const i=e.attributeName();if(e.negate){const t=e.long.replace(/^--no-/,"--");if(!this._findOption(t)){this.setOptionValueWithSource(i,e.defaultValue===undefined?true:e.defaultValue,"default")}}else if(e.defaultValue!==undefined){this.setOptionValueWithSource(i,e.defaultValue,"default")}const handleOptionValue=(t,n,s)=>{if(t==null&&e.presetArg!==undefined){t=e.presetArg}const r=this.getOptionValue(i);if(t!==null&&e.parseArg){t=this._callParseArg(e,t,r,n)}else if(t!==null&&e.variadic){t=e._concatValue(t,r)}if(t==null){if(e.negate){t=false}else if(e.isBoolean()||e.optional){t=true}else{t=""}}this.setOptionValueWithSource(i,t,s)};this.on("option:"+t,(t=>{const i=`error: option '${e.flags}' argument '${t}' is invalid.`;handleOptionValue(t,i,"cli")}));if(e.envVar){this.on("optionEnv:"+t,(t=>{const i=`error: option '${e.flags}' value '${t}' from env '${e.envVar}' is invalid.`;handleOptionValue(t,i,"env")}))}return this}_optionEx(e,t,i,n,s){if(typeof t==="object"&&t instanceof p){throw new Error("To add an Option object use addOption() instead of option() or requiredOption()")}const r=this.createOption(t,i);r.makeOptionMandatory(!!e.mandatory);if(typeof n==="function"){r.default(s).argParser(n)}else if(n instanceof RegExp){const e=n;n=(t,i)=>{const n=e.exec(t);return n?n[0]:i};r.default(s).argParser(n)}else{r.default(n)}return this.addOption(r)}option(e,t,i,n){return this._optionEx({},e,t,i,n)}requiredOption(e,t,i,n){return this._optionEx({mandatory:true},e,t,i,n)}combineFlagAndOptionalValue(e=true){this._combineFlagAndOptionalValue=!!e;return this}allowUnknownOption(e=true){this._allowUnknownOption=!!e;return this}allowExcessArguments(e=true){this._allowExcessArguments=!!e;return this}enablePositionalOptions(e=true){this._enablePositionalOptions=!!e;return this}passThroughOptions(e=true){this._passThroughOptions=!!e;this._checkForBrokenPassThrough();return this}_checkForBrokenPassThrough(){if(this.parent&&this._passThroughOptions&&!this.parent._enablePositionalOptions){throw new Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`)}}storeOptionsAsProperties(e=true){if(this.options.length){throw new Error("call .storeOptionsAsProperties() before adding options")}if(Object.keys(this._optionValues).length){throw new Error("call .storeOptionsAsProperties() before setting option values")}this._storeOptionsAsProperties=!!e;return this}getOptionValue(e){if(this._storeOptionsAsProperties){return this[e]}return this._optionValues[e]}setOptionValue(e,t){return this.setOptionValueWithSource(e,t,undefined)}setOptionValueWithSource(e,t,i){if(this._storeOptionsAsProperties){this[e]=t}else{this._optionValues[e]=t}this._optionValueSources[e]=i;return this}getOptionValueSource(e){return this._optionValueSources[e]}getOptionValueSourceWithGlobals(e){let t;this._getCommandAndAncestors().forEach((i=>{if(i.getOptionValueSource(e)!==undefined){t=i.getOptionValueSource(e)}}));return t}_prepareUserArgs(e,t){if(e!==undefined&&!Array.isArray(e)){throw new Error("first parameter to parse must be array or undefined")}t=t||{};if(e===undefined&&t.from===undefined){if(a.versions?.electron){t.from="electron"}const e=a.execArgv??[];if(e.includes("-e")||e.includes("--eval")||e.includes("-p")||e.includes("--print")){t.from="eval"}}if(e===undefined){e=a.argv}this.rawArgs=e.slice();let i;switch(t.from){case undefined:case"node":this._scriptPath=e[1];i=e.slice(2);break;case"electron":if(a.defaultApp){this._scriptPath=e[1];i=e.slice(2)}else{i=e.slice(1)}break;case"user":i=e.slice(0);break;case"eval":i=e.slice(1);break;default:throw new Error(`unexpected parse option { from: '${t.from}' }`)}if(!this._name&&this._scriptPath)this.nameFromFilename(this._scriptPath);this._name=this._name||"program";return i}parse(e,t){const i=this._prepareUserArgs(e,t);this._parseCommand([],i);return this}async parseAsync(e,t){const i=this._prepareUserArgs(e,t);await this._parseCommand([],i);return this}_executeSubCommand(e,t){t=t.slice();let i=false;const n=[".js",".ts",".tsx",".mjs",".cjs"];function findFile(e,t){const i=r.resolve(e,t);if(o.existsSync(i))return i;if(n.includes(r.extname(t)))return undefined;const s=n.find((e=>o.existsSync(`${i}${e}`)));if(s)return`${i}${s}`;return undefined}this._checkForMissingMandatoryOptions();this._checkForConflictingOptions();let h=e._executableFile||`${this._name}-${e._name}`;let l=this._executableDir||"";if(this._scriptPath){let e;try{e=o.realpathSync(this._scriptPath)}catch(t){e=this._scriptPath}l=r.resolve(r.dirname(e),l)}if(l){let t=findFile(l,h);if(!t&&!e._executableFile&&this._scriptPath){const i=r.basename(this._scriptPath,r.extname(this._scriptPath));if(i!==this._name){t=findFile(l,`${i}-${e._name}`)}}h=t||h}i=n.includes(r.extname(h));let c;if(a.platform!=="win32"){if(i){t.unshift(h);t=incrementNodeInspectorPort(a.execArgv).concat(t);c=s.spawn(a.argv[0],t,{stdio:"inherit"})}else{c=s.spawn(h,t,{stdio:"inherit"})}}else{t.unshift(h);t=incrementNodeInspectorPort(a.execArgv).concat(t);c=s.spawn(a.execPath,t,{stdio:"inherit"})}if(!c.killed){const e=["SIGUSR1","SIGUSR2","SIGTERM","SIGINT","SIGHUP"];e.forEach((e=>{a.on(e,(()=>{if(c.killed===false&&c.exitCode===null){c.kill(e)}}))}))}const p=this._exitCallback;c.on("close",(e=>{e=e??1;if(!p){a.exit(e)}else{p(new u(e,"commander.executeSubCommandAsync","(close)"))}}));c.on("error",(t=>{if(t.code==="ENOENT"){const t=l?`searched for local subcommand relative to directory '${l}'`:"no directory for search for local subcommand, use .executableDir() to supply a custom directory";const i=`'${h}' does not exist\n - if '${e._name}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead\n - if the default executable name is not suitable, use the executableFile option to supply a custom name or path\n - ${t}`;throw new Error(i)}else if(t.code==="EACCES"){throw new Error(`'${h}' not executable`)}if(!p){a.exit(1)}else{const e=new u(1,"commander.executeSubCommandAsync","(error)");e.nestedError=t;p(e)}}));this.runningCommand=c}_dispatchSubcommand(e,t,i){const n=this._findCommand(e);if(!n)this.help({error:true});let s;s=this._chainOrCallSubCommandHook(s,n,"preSubcommand");s=this._chainOrCall(s,(()=>{if(n._executableHandler){this._executeSubCommand(n,t.concat(i))}else{return n._parseCommand(t,i)}}));return s}_dispatchHelpCommand(e){if(!e){this.help()}const t=this._findCommand(e);if(t&&!t._executableHandler){t.help()}return this._dispatchSubcommand(e,[],[this._getHelpOption()?.long??this._getHelpOption()?.short??"--help"])}_checkNumberOfArguments(){this.registeredArguments.forEach(((e,t)=>{if(e.required&&this.args[t]==null){this.missingArgument(e.name())}}));if(this.registeredArguments.length>0&&this.registeredArguments[this.registeredArguments.length-1].variadic){return}if(this.args.length>this.registeredArguments.length){this._excessArguments(this.args)}}_processArguments(){const myParseArg=(e,t,i)=>{let n=t;if(t!==null&&e.parseArg){const s=`error: command-argument value '${t}' is invalid for argument '${e.name()}'.`;n=this._callParseArg(e,t,i,s)}return n};this._checkNumberOfArguments();const e=[];this.registeredArguments.forEach(((t,i)=>{let n=t.defaultValue;if(t.variadic){if(imyParseArg(t,i,e)),t.defaultValue)}}else if(n===undefined){n=[]}}else if(it()))}return t()}_chainOrCallHooks(e,t){let i=e;const n=[];this._getCommandAndAncestors().reverse().filter((e=>e._lifeCycleHooks[t]!==undefined)).forEach((e=>{e._lifeCycleHooks[t].forEach((t=>{n.push({hookedCommand:e,callback:t})}))}));if(t==="postAction"){n.reverse()}n.forEach((e=>{i=this._chainOrCall(i,(()=>e.callback(e.hookedCommand,this)))}));return i}_chainOrCallSubCommandHook(e,t,i){let n=e;if(this._lifeCycleHooks[i]!==undefined){this._lifeCycleHooks[i].forEach((e=>{n=this._chainOrCall(n,(()=>e(this,t)))}))}return n}_parseCommand(e,t){const i=this.parseOptions(t);this._parseOptionsEnv();this._parseOptionsImplied();e=e.concat(i.operands);t=i.unknown;this.args=e.concat(t);if(e&&this._findCommand(e[0])){return this._dispatchSubcommand(e[0],e.slice(1),t)}if(this._getHelpCommand()&&e[0]===this._getHelpCommand().name()){return this._dispatchHelpCommand(e[1])}if(this._defaultCommandName){this._outputHelpIfRequested(t);return this._dispatchSubcommand(this._defaultCommandName,e,t)}if(this.commands.length&&this.args.length===0&&!this._actionHandler&&!this._defaultCommandName){this.help({error:true})}this._outputHelpIfRequested(i.unknown);this._checkForMissingMandatoryOptions();this._checkForConflictingOptions();const checkForUnknownOptions=()=>{if(i.unknown.length>0){this.unknownOption(i.unknown[0])}};const n=`command:${this.name()}`;if(this._actionHandler){checkForUnknownOptions();this._processArguments();let i;i=this._chainOrCallHooks(i,"preAction");i=this._chainOrCall(i,(()=>this._actionHandler(this.processedArgs)));if(this.parent){i=this._chainOrCall(i,(()=>{this.parent.emit(n,e,t)}))}i=this._chainOrCallHooks(i,"postAction");return i}if(this.parent&&this.parent.listenerCount(n)){checkForUnknownOptions();this._processArguments();this.parent.emit(n,e,t)}else if(e.length){if(this._findCommand("*")){return this._dispatchSubcommand("*",e,t)}if(this.listenerCount("command:*")){this.emit("command:*",e,t)}else if(this.commands.length){this.unknownCommand()}else{checkForUnknownOptions();this._processArguments()}}else if(this.commands.length){checkForUnknownOptions();this.help({error:true})}else{checkForUnknownOptions();this._processArguments()}}_findCommand(e){if(!e)return undefined;return this.commands.find((t=>t._name===e||t._aliases.includes(e)))}_findOption(e){return this.options.find((t=>t.is(e)))}_checkForMissingMandatoryOptions(){this._getCommandAndAncestors().forEach((e=>{e.options.forEach((t=>{if(t.mandatory&&e.getOptionValue(t.attributeName())===undefined){e.missingMandatoryOptionValue(t)}}))}))}_checkForConflictingLocalOptions(){const e=this.options.filter((e=>{const t=e.attributeName();if(this.getOptionValue(t)===undefined){return false}return this.getOptionValueSource(t)!=="default"}));const t=e.filter((e=>e.conflictsWith.length>0));t.forEach((t=>{const i=e.find((e=>t.conflictsWith.includes(e.attributeName())));if(i){this._conflictingOption(t,i)}}))}_checkForConflictingOptions(){this._getCommandAndAncestors().forEach((e=>{e._checkForConflictingLocalOptions()}))}parseOptions(e){const t=[];const i=[];let n=t;const s=e.slice();function maybeOption(e){return e.length>1&&e[0]==="-"}let r=null;while(s.length){const e=s.shift();if(e==="--"){if(n===i)n.push(e);n.push(...s);break}if(r&&!maybeOption(e)){this.emit(`option:${r.name()}`,e);continue}r=null;if(maybeOption(e)){const t=this._findOption(e);if(t){if(t.required){const e=s.shift();if(e===undefined)this.optionMissingArgument(t);this.emit(`option:${t.name()}`,e)}else if(t.optional){let e=null;if(s.length>0&&!maybeOption(s[0])){e=s.shift()}this.emit(`option:${t.name()}`,e)}else{this.emit(`option:${t.name()}`)}r=t.variadic?t:null;continue}}if(e.length>2&&e[0]==="-"&&e[1]!=="-"){const t=this._findOption(`-${e[1]}`);if(t){if(t.required||t.optional&&this._combineFlagAndOptionalValue){this.emit(`option:${t.name()}`,e.slice(2))}else{this.emit(`option:${t.name()}`);s.unshift(`-${e.slice(2)}`)}continue}}if(/^--[^=]+=/.test(e)){const t=e.indexOf("=");const i=this._findOption(e.slice(0,t));if(i&&(i.required||i.optional)){this.emit(`option:${i.name()}`,e.slice(t+1));continue}}if(maybeOption(e)){n=i}if((this._enablePositionalOptions||this._passThroughOptions)&&t.length===0&&i.length===0){if(this._findCommand(e)){t.push(e);if(s.length>0)i.push(...s);break}else if(this._getHelpCommand()&&e===this._getHelpCommand().name()){t.push(e);if(s.length>0)t.push(...s);break}else if(this._defaultCommandName){i.push(e);if(s.length>0)i.push(...s);break}}if(this._passThroughOptions){n.push(e);if(s.length>0)n.push(...s);break}n.push(e)}return{operands:t,unknown:i}}opts(){if(this._storeOptionsAsProperties){const e={};const t=this.options.length;for(let i=0;iObject.assign(e,t.opts())),{})}error(e,t){this._outputConfiguration.outputError(`${e}\n`,this._outputConfiguration.writeErr);if(typeof this._showHelpAfterError==="string"){this._outputConfiguration.writeErr(`${this._showHelpAfterError}\n`)}else if(this._showHelpAfterError){this._outputConfiguration.writeErr("\n");this.outputHelp({error:true})}const i=t||{};const n=i.exitCode||1;const s=i.code||"commander.error";this._exit(n,s,e)}_parseOptionsEnv(){this.options.forEach((e=>{if(e.envVar&&e.envVar in a.env){const t=e.attributeName();if(this.getOptionValue(t)===undefined||["default","config","env"].includes(this.getOptionValueSource(t))){if(e.required||e.optional){this.emit(`optionEnv:${e.name()}`,a.env[e.envVar])}else{this.emit(`optionEnv:${e.name()}`)}}}}))}_parseOptionsImplied(){const e=new d(this.options);const hasCustomOptionValue=e=>this.getOptionValue(e)!==undefined&&!["default","implied"].includes(this.getOptionValueSource(e));this.options.filter((t=>t.implied!==undefined&&hasCustomOptionValue(t.attributeName())&&e.valueFromOption(this.getOptionValue(t.attributeName()),t))).forEach((e=>{Object.keys(e.implied).filter((e=>!hasCustomOptionValue(e))).forEach((t=>{this.setOptionValueWithSource(t,e.implied[t],"implied")}))}))}missingArgument(e){const t=`error: missing required argument '${e}'`;this.error(t,{code:"commander.missingArgument"})}optionMissingArgument(e){const t=`error: option '${e.flags}' argument missing`;this.error(t,{code:"commander.optionMissingArgument"})}missingMandatoryOptionValue(e){const t=`error: required option '${e.flags}' not specified`;this.error(t,{code:"commander.missingMandatoryOptionValue"})}_conflictingOption(e,t){const findBestOptionFromValue=e=>{const t=e.attributeName();const i=this.getOptionValue(t);const n=this.options.find((e=>e.negate&&t===e.attributeName()));const s=this.options.find((e=>!e.negate&&t===e.attributeName()));if(n&&(n.presetArg===undefined&&i===false||n.presetArg!==undefined&&i===n.presetArg)){return n}return s||e};const getErrorMessage=e=>{const t=findBestOptionFromValue(e);const i=t.attributeName();const n=this.getOptionValueSource(i);if(n==="env"){return`environment variable '${t.envVar}'`}return`option '${t.flags}'`};const i=`error: ${getErrorMessage(e)} cannot be used with ${getErrorMessage(t)}`;this.error(i,{code:"commander.conflictingOption"})}unknownOption(e){if(this._allowUnknownOption)return;let t="";if(e.startsWith("--")&&this._showSuggestionAfterError){let i=[];let n=this;do{const e=n.createHelp().visibleOptions(n).filter((e=>e.long)).map((e=>e.long));i=i.concat(e);n=n.parent}while(n&&!n._enablePositionalOptions);t=m(e,i)}const i=`error: unknown option '${e}'${t}`;this.error(i,{code:"commander.unknownOption"})}_excessArguments(e){if(this._allowExcessArguments)return;const t=this.registeredArguments.length;const i=t===1?"":"s";const n=this.parent?` for '${this.name()}'`:"";const s=`error: too many arguments${n}. Expected ${t} argument${i} but got ${e.length}.`;this.error(s,{code:"commander.excessArguments"})}unknownCommand(){const e=this.args[0];let t="";if(this._showSuggestionAfterError){const i=[];this.createHelp().visibleCommands(this).forEach((e=>{i.push(e.name());if(e.alias())i.push(e.alias())}));t=m(e,i)}const i=`error: unknown command '${e}'${t}`;this.error(i,{code:"commander.unknownCommand"})}version(e,t,i){if(e===undefined)return this._version;this._version=e;t=t||"-V, --version";i=i||"output the version number";const n=this.createOption(t,i);this._versionOptionName=n.attributeName();this._registerOption(n);this.on("option:"+n.name(),(()=>{this._outputConfiguration.writeOut(`${e}\n`);this._exit(0,"commander.version",e)}));return this}description(e,t){if(e===undefined&&t===undefined)return this._description;this._description=e;if(t){this._argsDescription=t}return this}summary(e){if(e===undefined)return this._summary;this._summary=e;return this}alias(e){if(e===undefined)return this._aliases[0];let t=this;if(this.commands.length!==0&&this.commands[this.commands.length-1]._executableHandler){t=this.commands[this.commands.length-1]}if(e===t._name)throw new Error("Command alias can't be the same as its name");const i=this.parent?._findCommand(e);if(i){const t=[i.name()].concat(i.aliases()).join("|");throw new Error(`cannot add alias '${e}' to command '${this.name()}' as already have command '${t}'`)}t._aliases.push(e);return this}aliases(e){if(e===undefined)return this._aliases;e.forEach((e=>this.alias(e)));return this}usage(e){if(e===undefined){if(this._usage)return this._usage;const e=this.registeredArguments.map((e=>l(e)));return[].concat(this.options.length||this._helpOption!==null?"[options]":[],this.commands.length?"[command]":[],this.registeredArguments.length?e:[]).join(" ")}this._usage=e;return this}name(e){if(e===undefined)return this._name;this._name=e;return this}nameFromFilename(e){this._name=r.basename(e,r.extname(e));return this}executableDir(e){if(e===undefined)return this._executableDir;this._executableDir=e;return this}helpInformation(e){const t=this.createHelp();if(t.helpWidth===undefined){t.helpWidth=e&&e.error?this._outputConfiguration.getErrHelpWidth():this._outputConfiguration.getOutHelpWidth()}return t.formatHelp(this,t)}_getHelpContext(e){e=e||{};const t={error:!!e.error};let i;if(t.error){i=e=>this._outputConfiguration.writeErr(e)}else{i=e=>this._outputConfiguration.writeOut(e)}t.write=e.write||i;t.command=this;return t}outputHelp(e){let t;if(typeof e==="function"){t=e;e=undefined}const i=this._getHelpContext(e);this._getCommandAndAncestors().reverse().forEach((e=>e.emit("beforeAllHelp",i)));this.emit("beforeHelp",i);let n=this.helpInformation(i);if(t){n=t(n);if(typeof n!=="string"&&!Buffer.isBuffer(n)){throw new Error("outputHelp callback must return a string or a Buffer")}}i.write(n);if(this._getHelpOption()?.long){this.emit(this._getHelpOption().long)}this.emit("afterHelp",i);this._getCommandAndAncestors().forEach((e=>e.emit("afterAllHelp",i)))}helpOption(e,t){if(typeof e==="boolean"){if(e){this._helpOption=this._helpOption??undefined}else{this._helpOption=null}return this}e=e??"-h, --help";t=t??"display help for command";this._helpOption=this.createOption(e,t);return this}_getHelpOption(){if(this._helpOption===undefined){this.helpOption(undefined,undefined)}return this._helpOption}addHelpOption(e){this._helpOption=e;return this}help(e){this.outputHelp(e);let t=a.exitCode||0;if(t===0&&e&&typeof e!=="function"&&e.error){t=1}this._exit(t,"commander.help","(outputHelp)")}addHelpText(e,t){const i=["beforeAll","before","after","afterAll"];if(!i.includes(e)){throw new Error(`Unexpected value for position to addHelpText.\nExpecting one of '${i.join("', '")}'`)}const n=`${e}Help`;this.on(n,(e=>{let i;if(typeof t==="function"){i=t({error:e.error,command:e.command})}else{i=t}if(i){e.write(`${i}\n`)}}));return this}_outputHelpIfRequested(e){const t=this._getHelpOption();const i=t&&e.find((e=>t.is(e)));if(i){this.outputHelp();this._exit(0,"commander.helpDisplayed","(outputHelp)")}}}function incrementNodeInspectorPort(e){return e.map((e=>{if(!e.startsWith("--inspect")){return e}let t;let i="127.0.0.1";let n="9229";let s;if((s=e.match(/^(--inspect(-brk)?)$/))!==null){t=s[1]}else if((s=e.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null){t=s[1];if(/^\d+$/.test(s[3])){n=s[3]}else{i=s[3]}}else if((s=e.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null){t=s[1];i=s[3];n=s[4]}if(t&&n!=="0"){return`${t}=${i}:${parseInt(n)+1}`}return e}))}t.Command=Command},299:(e,t)=>{class CommanderError extends Error{constructor(e,t,i){super(i);Error.captureStackTrace(this,this.constructor);this.name=this.constructor.name;this.code=t;this.exitCode=e;this.nestedError=undefined}}class InvalidArgumentError extends CommanderError{constructor(e){super(1,"commander.invalidArgument",e);Error.captureStackTrace(this,this.constructor);this.name=this.constructor.name}}t.CommanderError=CommanderError;t.InvalidArgumentError=InvalidArgumentError},638:(e,t,i)=>{const{humanReadableArgName:n}=i(253);class Help{constructor(){this.helpWidth=undefined;this.sortSubcommands=false;this.sortOptions=false;this.showGlobalOptions=false}visibleCommands(e){const t=e.commands.filter((e=>!e._hidden));const i=e._getHelpCommand();if(i&&!i._hidden){t.push(i)}if(this.sortSubcommands){t.sort(((e,t)=>e.name().localeCompare(t.name())))}return t}compareOptions(e,t){const getSortKey=e=>e.short?e.short.replace(/^-/,""):e.long.replace(/^--/,"");return getSortKey(e).localeCompare(getSortKey(t))}visibleOptions(e){const t=e.options.filter((e=>!e.hidden));const i=e._getHelpOption();if(i&&!i.hidden){const n=i.short&&e._findOption(i.short);const s=i.long&&e._findOption(i.long);if(!n&&!s){t.push(i)}else if(i.long&&!s){t.push(e.createOption(i.long,i.description))}else if(i.short&&!n){t.push(e.createOption(i.short,i.description))}}if(this.sortOptions){t.sort(this.compareOptions)}return t}visibleGlobalOptions(e){if(!this.showGlobalOptions)return[];const t=[];for(let i=e.parent;i;i=i.parent){const e=i.options.filter((e=>!e.hidden));t.push(...e)}if(this.sortOptions){t.sort(this.compareOptions)}return t}visibleArguments(e){if(e._argsDescription){e.registeredArguments.forEach((t=>{t.description=t.description||e._argsDescription[t.name()]||""}))}if(e.registeredArguments.find((e=>e.description))){return e.registeredArguments}return[]}subcommandTerm(e){const t=e.registeredArguments.map((e=>n(e))).join(" ");return e._name+(e._aliases[0]?"|"+e._aliases[0]:"")+(e.options.length?" [options]":"")+(t?" "+t:"")}optionTerm(e){return e.flags}argumentTerm(e){return e.name()}longestSubcommandTermLength(e,t){return t.visibleCommands(e).reduce(((e,i)=>Math.max(e,t.subcommandTerm(i).length)),0)}longestOptionTermLength(e,t){return t.visibleOptions(e).reduce(((e,i)=>Math.max(e,t.optionTerm(i).length)),0)}longestGlobalOptionTermLength(e,t){return t.visibleGlobalOptions(e).reduce(((e,i)=>Math.max(e,t.optionTerm(i).length)),0)}longestArgumentTermLength(e,t){return t.visibleArguments(e).reduce(((e,i)=>Math.max(e,t.argumentTerm(i).length)),0)}commandUsage(e){let t=e._name;if(e._aliases[0]){t=t+"|"+e._aliases[0]}let i="";for(let t=e.parent;t;t=t.parent){i=t.name()+" "+i}return i+t+" "+e.usage()}commandDescription(e){return e.description()}subcommandDescription(e){return e.summary()||e.description()}optionDescription(e){const t=[];if(e.argChoices){t.push(`choices: ${e.argChoices.map((e=>JSON.stringify(e))).join(", ")}`)}if(e.defaultValue!==undefined){const i=e.required||e.optional||e.isBoolean()&&typeof e.defaultValue==="boolean";if(i){t.push(`default: ${e.defaultValueDescription||JSON.stringify(e.defaultValue)}`)}}if(e.presetArg!==undefined&&e.optional){t.push(`preset: ${JSON.stringify(e.presetArg)}`)}if(e.envVar!==undefined){t.push(`env: ${e.envVar}`)}if(t.length>0){return`${e.description} (${t.join(", ")})`}return e.description}argumentDescription(e){const t=[];if(e.argChoices){t.push(`choices: ${e.argChoices.map((e=>JSON.stringify(e))).join(", ")}`)}if(e.defaultValue!==undefined){t.push(`default: ${e.defaultValueDescription||JSON.stringify(e.defaultValue)}`)}if(t.length>0){const i=`(${t.join(", ")})`;if(e.description){return`${e.description} ${i}`}return i}return e.description}formatHelp(e,t){const i=t.padWidth(e,t);const n=t.helpWidth||80;const s=2;const r=2;function formatItem(e,o){if(o){const a=`${e.padEnd(i+r)}${o}`;return t.wrap(a,n-s,i+r)}return e}function formatList(e){return e.join("\n").replace(/^/gm," ".repeat(s))}let o=[`Usage: ${t.commandUsage(e)}`,""];const a=t.commandDescription(e);if(a.length>0){o=o.concat([t.wrap(a,n,0),""])}const h=t.visibleArguments(e).map((e=>formatItem(t.argumentTerm(e),t.argumentDescription(e))));if(h.length>0){o=o.concat(["Arguments:",formatList(h),""])}const l=t.visibleOptions(e).map((e=>formatItem(t.optionTerm(e),t.optionDescription(e))));if(l.length>0){o=o.concat(["Options:",formatList(l),""])}if(this.showGlobalOptions){const i=t.visibleGlobalOptions(e).map((e=>formatItem(t.optionTerm(e),t.optionDescription(e))));if(i.length>0){o=o.concat(["Global Options:",formatList(i),""])}}const u=t.visibleCommands(e).map((e=>formatItem(t.subcommandTerm(e),t.subcommandDescription(e))));if(u.length>0){o=o.concat(["Commands:",formatList(u),""])}return o.join("\n")}padWidth(e,t){return Math.max(t.longestOptionTermLength(e,t),t.longestGlobalOptionTermLength(e,t),t.longestSubcommandTermLength(e,t),t.longestArgumentTermLength(e,t))}wrap(e,t,i,n=40){const s=" \\f\\t\\v   -    \ufeff";const r=new RegExp(`[\\n][${s}]+`);if(e.match(r))return e;const o=t-i;if(o{if(e==="\n")return"";return(t>0?l:"")+e.trimEnd()})).join("\n")}}t.Help=Help},77:(e,t,i)=>{const{InvalidArgumentError:n}=i(299);class Option{constructor(e,t){this.flags=e;this.description=t||"";this.required=e.includes("<");this.optional=e.includes("[");this.variadic=/\w\.\.\.[>\]]$/.test(e);this.mandatory=false;const i=splitOptionFlags(e);this.short=i.shortFlag;this.long=i.longFlag;this.negate=false;if(this.long){this.negate=this.long.startsWith("--no-")}this.defaultValue=undefined;this.defaultValueDescription=undefined;this.presetArg=undefined;this.envVar=undefined;this.parseArg=undefined;this.hidden=false;this.argChoices=undefined;this.conflictsWith=[];this.implied=undefined}default(e,t){this.defaultValue=e;this.defaultValueDescription=t;return this}preset(e){this.presetArg=e;return this}conflicts(e){this.conflictsWith=this.conflictsWith.concat(e);return this}implies(e){let t=e;if(typeof e==="string"){t={[e]:true}}this.implied=Object.assign(this.implied||{},t);return this}env(e){this.envVar=e;return this}argParser(e){this.parseArg=e;return this}makeOptionMandatory(e=true){this.mandatory=!!e;return this}hideHelp(e=true){this.hidden=!!e;return this}_concatValue(e,t){if(t===this.defaultValue||!Array.isArray(t)){return[e]}return t.concat(e)}choices(e){this.argChoices=e.slice();this.parseArg=(e,t)=>{if(!this.argChoices.includes(e)){throw new n(`Allowed choices are ${this.argChoices.join(", ")}.`)}if(this.variadic){return this._concatValue(e,t)}return e};return this}name(){if(this.long){return this.long.replace(/^--/,"")}return this.short.replace(/^-/,"")}attributeName(){return camelcase(this.name().replace(/^no-/,""))}is(e){return this.short===e||this.long===e}isBoolean(){return!this.required&&!this.optional&&!this.negate}}class DualOptions{constructor(e){this.positiveOptions=new Map;this.negativeOptions=new Map;this.dualOptions=new Set;e.forEach((e=>{if(e.negate){this.negativeOptions.set(e.attributeName(),e)}else{this.positiveOptions.set(e.attributeName(),e)}}));this.negativeOptions.forEach(((e,t)=>{if(this.positiveOptions.has(t)){this.dualOptions.add(t)}}))}valueFromOption(e,t){const i=t.attributeName();if(!this.dualOptions.has(i))return true;const n=this.negativeOptions.get(i).presetArg;const s=n!==undefined?n:false;return t.negate===(s===e)}}function camelcase(e){return e.split("-").reduce(((e,t)=>e+t[0].toUpperCase()+t.slice(1)))}function splitOptionFlags(e){let t;let i;const n=e.split(/[ |,]+/);if(n.length>1&&!/^[[<]/.test(n[1]))t=n.shift();i=n.shift();if(!t&&/^-[^-]$/.test(i)){t=i;i=undefined}return{shortFlag:t,longFlag:i}}t.Option=Option;t.DualOptions=DualOptions},301:(e,t)=>{const i=3;function editDistance(e,t){if(Math.abs(e.length-t.length)>i)return Math.max(e.length,t.length);const n=[];for(let t=0;t<=e.length;t++){n[t]=[t]}for(let e=0;e<=t.length;e++){n[0][e]=e}for(let i=1;i<=t.length;i++){for(let s=1;s<=e.length;s++){let r=1;if(e[s-1]===t[i-1]){r=0}else{r=1}n[s][i]=Math.min(n[s-1][i]+1,n[s][i-1]+1,n[s-1][i-1]+r);if(s>1&&i>1&&e[s-1]===t[i-2]&&e[s-2]===t[i-1]){n[s][i]=Math.min(n[s][i],n[s-2][i-2]+1)}}}return n[e.length][t.length]}function suggestSimilar(e,t){if(!t||t.length===0)return"";t=Array.from(new Set(t));const n=e.startsWith("--");if(n){e=e.slice(2);t=t.map((e=>e.slice(2)))}let s=[];let r=i;const o=.4;t.forEach((t=>{if(t.length<=1)return;const i=editDistance(e,t);const n=Math.max(e.length,t.length);const a=(n-i)/n;if(a>o){if(ie.localeCompare(t)));if(n){s=s.map((e=>`--${e}`))}if(s.length>1){return`\n(Did you mean one of ${s.join(", ")}?)`}if(s.length===1){return`\n(Did you mean ${s[0]}?)`}return""}t.suggestSimilar=suggestSimilar}};var t={};function __nccwpck_require__(i){var n=t[i];if(n!==undefined){return n.exports}var s=t[i]={exports:{}};var r=true;try{e[i](s,s.exports,__nccwpck_require__);r=false}finally{if(r)delete t[i]}return s.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var i={};(()=>{var e=i;const{Argument:t}=__nccwpck_require__(253);const{Command:n}=__nccwpck_require__(119);const{CommanderError:s,InvalidArgumentError:r}=__nccwpck_require__(299);const{Help:o}=__nccwpck_require__(638);const{Option:a}=__nccwpck_require__(77);e.program=new n;e.createCommand=e=>new n(e);e.createOption=(e,t)=>new a(e,t);e.createArgument=(e,i)=>new t(e,i);e.Command=n;e.Option=a;e.Argument=t;e.Help=o;e.CommanderError=s;e.InvalidArgumentError=r;e.InvalidOptionArgumentError=r})();module.exports=i})(); \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 518d4019c7113..0c2ef517f172a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -738,8 +738,8 @@ importers: specifier: watson/ci-info#f43f6a1cefff47fb361c88cf4b943fdbcaafe540 version: github.com/watson/ci-info/f43f6a1cefff47fb361c88cf4b943fdbcaafe540 commander: - specifier: 2.20.0 - version: 2.20.0 + specifier: 12.1.0 + version: 12.1.0 conf: specifier: 10.2.0 version: 10.2.0 @@ -1159,8 +1159,8 @@ importers: specifier: 0.0.1 version: 0.0.1 commander: - specifier: 12.0.0 - version: 12.0.0 + specifier: 12.1.0 + version: 12.1.0 comment-json: specifier: 3.0.3 version: 3.0.3 @@ -10074,8 +10074,8 @@ packages: engines: {node: '>=16'} dev: true - /commander@12.0.0: - resolution: {integrity: sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==} + /commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} dev: true From e296846427aefb59ba1ff9445b1c9ee4743960e2 Mon Sep 17 00:00:00 2001 From: Sam Ko Date: Wed, 12 Jun 2024 12:31:42 -0700 Subject: [PATCH 51/60] chore: bump turbo to 2.0.3 (#66784) ## Why? This pull request bumps turborepo from 1.13.3-canary.2 to [2.0.3](https://github.com/vercel/turbo/releases/tag/v2.0.3) across multiple GitHub workflows and configuration files. Re-attempting after we [reverted](https://github.com/vercel/next.js/pull/66775). --- .github/workflows/build_and_deploy.yml | 26 ++++++++++---- .github/workflows/build_and_test.yml | 2 +- .github/workflows/build_reusable.yml | 4 +-- .github/workflows/code_freeze.yml | 2 +- .github/workflows/pull_request_stats.yml | 2 +- .github/workflows/trigger_release.yml | 2 +- package.json | 2 +- packages/create-next-app/package.json | 6 ++-- packages/next-swc/turbo.json | 3 +- packages/next/package.json | 6 ++-- pnpm-lock.yaml | 46 ++++++++++++------------ scripts/normalize-version-bump.js | 3 +- turbo.json | 3 +- 13 files changed, 62 insertions(+), 45 deletions(-) diff --git a/.github/workflows/build_and_deploy.yml b/.github/workflows/build_and_deploy.yml index 027ec0e143591..f1209b0737ef4 100644 --- a/.github/workflows/build_and_deploy.yml +++ b/.github/workflows/build_and_deploy.yml @@ -7,7 +7,7 @@ on: env: NAPI_CLI_VERSION: 2.16.2 - TURBO_VERSION: 1.13.3-canary.2 + TURBO_VERSION: 2.0.3 NODE_LTS_VERSION: 20 CARGO_PROFILE_RELEASE_LTO: 'true' TURBO_TEAM: 'vercel' @@ -84,9 +84,11 @@ jobs: - 'arm64' target: 'x86_64-apple-darwin' + # --env-mode loose is a breaking change required with turbo 2.x since Strict mode is now the default + # TODO: we should add the relevant envs later to to switch to strict mode build: | npm i -g "@napi-rs/cli@${NAPI_CLI_VERSION}" "turbo@${TURBO_VERSION}" && corepack enable - turbo run build-native-release -vvv --remote-cache-timeout 90 --summarize -- --target x86_64-apple-darwin + turbo run build-native-release -vvv --env-mode loose --remote-cache-timeout 90 --summarize -- --target x86_64-apple-darwin strip -x packages/next-swc/native/next-swc.*.node - host: @@ -95,13 +97,15 @@ jobs: - 'arm64' target: 'aarch64-apple-darwin' + # --env-mode loose is a breaking change required with turbo 2.x since Strict mode is now the default + # TODO: we should add the relevant envs later to to switch to strict mode build: | export CC=$(xcrun -f clang); export CXX=$(xcrun -f clang++); SYSROOT=$(xcrun --sdk macosx --show-sdk-path); export CFLAGS="-isysroot $SYSROOT -isystem $SYSROOT"; npm i -g "@napi-rs/cli@${NAPI_CLI_VERSION}" "turbo@${TURBO_VERSION}" && corepack enable - turbo run build-native-release -vvv --remote-cache-timeout 90 --summarize -- --target aarch64-apple-darwin + turbo run build-native-release -vvv --env-mode loose --remote-cache-timeout 90 --summarize -- --target aarch64-apple-darwin strip -x packages/next-swc/native/next-swc.*.node - host: @@ -109,10 +113,12 @@ jobs: - 'windows' - 'x64' + # --env-mode loose is a breaking change required with turbo 2.x since Strict mode is now the default + # TODO: we should add the relevant envs later to to switch to strict mode build: | corepack enable npm i -g "@napi-rs/cli@${NAPI_CLI_VERSION}" "turbo@${TURBO_VERSION}" - turbo run build-native-release -vvv --remote-cache-timeout 90 --summarize -- --target x86_64-pc-windows-msvc + turbo run build-native-release -vvv --env-mode loose --remote-cache-timeout 90 --summarize -- --target x86_64-pc-windows-msvc target: 'x86_64-pc-windows-msvc' - host: @@ -120,10 +126,12 @@ jobs: - 'windows' - 'x64' + # --env-mode loose is a breaking change required with turbo 2.x since Strict mode is now the default + # TODO: we should add the relevant envs later to to switch to strict mode build: | corepack enable npm i -g "@napi-rs/cli@${NAPI_CLI_VERSION}" "turbo@${TURBO_VERSION}" - turbo run build-native-no-plugin-release -vvv --remote-cache-timeout 90 --summarize -- --target i686-pc-windows-msvc + turbo run build-native-no-plugin-release -vvv --env-mode loose --remote-cache-timeout 90 --summarize -- --target i686-pc-windows-msvc target: 'i686-pc-windows-msvc' - host: @@ -132,10 +140,12 @@ jobs: - 'x64' target: 'aarch64-pc-windows-msvc' + # --env-mode loose is a breaking change required with turbo 2.x since Strict mode is now the default + # TODO: we should add the relevant envs later to to switch to strict mode build: | corepack enable npm i -g "@napi-rs/cli@${NAPI_CLI_VERSION}" "turbo@${TURBO_VERSION}" - turbo run build-native-no-plugin-release -vvv --remote-cache-timeout 90 --summarize -- --target aarch64-pc-windows-msvc + turbo run build-native-no-plugin-release -vvv --env-mode loose --remote-cache-timeout 90 --summarize -- --target aarch64-pc-windows-msvc - host: - 'self-hosted' @@ -374,7 +384,9 @@ jobs: run: node scripts/normalize-version-bump.js - name: Build - run: turbo run build-wasm -vvv --remote-cache-timeout 90 --summarize -- --target ${{ matrix.target }} + # --env-mode loose is a breaking change required with turbo 2.x since Strict mode is now the default + # TODO: we should add the relevant envs later to to switch to strict mode + run: turbo run build-wasm -vvv --env-mode loose --remote-cache-timeout 90 --summarize -- --target ${{ matrix.target }} - name: Add target to folder name run: '[[ -d "packages/next-swc/crates/wasm/pkg" ]] && mv packages/next-swc/crates/wasm/pkg packages/next-swc/crates/wasm/pkg-${{ matrix.target }} || ls packages/next-swc/crates/wasm' diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 4a306d1773f45..45c44ba508571 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -8,7 +8,7 @@ on: env: NAPI_CLI_VERSION: 2.14.7 - TURBO_VERSION: 1.13.3-canary.2 + TURBO_VERSION: 2.0.3 NODE_MAINTENANCE_VERSION: 18 NODE_LTS_VERSION: 20 TEST_CONCURRENCY: 8 diff --git a/.github/workflows/build_reusable.yml b/.github/workflows/build_reusable.yml index 34d45a0c6a851..3a601a4777688 100644 --- a/.github/workflows/build_reusable.yml +++ b/.github/workflows/build_reusable.yml @@ -62,7 +62,7 @@ on: env: NAPI_CLI_VERSION: 2.14.7 - TURBO_VERSION: 1.13.3-canary.2 + TURBO_VERSION: 2.0.3 NODE_LTS_VERSION: 20.9.0 TEST_CONCURRENCY: 8 # disable backtrace for test snapshots @@ -159,7 +159,7 @@ jobs: - run: node scripts/normalize-version-bump.js name: normalize versions - - run: turbo run build-native-release -vvv --remote-cache-timeout 90 --summarize -- --target x86_64-unknown-linux-gnu + - run: turbo run build-native-release -vvv --env-mode loose --remote-cache-timeout 90 --summarize -- --target x86_64-unknown-linux-gnu if: ${{ inputs.skipNativeBuild != 'yes' }} - name: Upload next-swc artifact diff --git a/.github/workflows/code_freeze.yml b/.github/workflows/code_freeze.yml index 5d005b1086350..8517359ac6100 100644 --- a/.github/workflows/code_freeze.yml +++ b/.github/workflows/code_freeze.yml @@ -17,7 +17,7 @@ name: Code Freeze env: NAPI_CLI_VERSION: 2.14.7 - TURBO_VERSION: 1.13.3-canary.2 + TURBO_VERSION: 2.0.3 NODE_LTS_VERSION: 20 jobs: diff --git a/.github/workflows/pull_request_stats.yml b/.github/workflows/pull_request_stats.yml index 64a4a3b65a992..d970f7a6a9490 100644 --- a/.github/workflows/pull_request_stats.yml +++ b/.github/workflows/pull_request_stats.yml @@ -6,7 +6,7 @@ name: Generate Pull Request Stats env: NAPI_CLI_VERSION: 2.14.7 - TURBO_VERSION: 1.13.3-canary.2 + TURBO_VERSION: 2.0.3 NODE_LTS_VERSION: 20 TEST_CONCURRENCY: 6 diff --git a/.github/workflows/trigger_release.yml b/.github/workflows/trigger_release.yml index d961f14795226..6fbd15189a539 100644 --- a/.github/workflows/trigger_release.yml +++ b/.github/workflows/trigger_release.yml @@ -35,7 +35,7 @@ name: Trigger Release env: NAPI_CLI_VERSION: 2.14.7 - TURBO_VERSION: 1.13.3-canary.2 + TURBO_VERSION: 2.0.3 NODE_LTS_VERSION: 20 jobs: diff --git a/package.json b/package.json index 07c9d84f46acd..6ce8823941c29 100644 --- a/package.json +++ b/package.json @@ -232,7 +232,7 @@ "taskr": "1.1.0", "tree-kill": "1.2.2", "tsec": "0.2.1", - "turbo": "1.13.3-canary.2", + "turbo": "2.0.3", "typescript": "5.3.3", "unfetch": "4.2.0", "wait-port": "0.2.2", diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 40f5132481ca8..d400cb3a8a140 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -51,6 +51,8 @@ "validate-npm-package-name": "5.0.1" }, "engines": { - "node": ">=18.17.0" - } + "node": ">=18.17.0", + "pnpm": "8.15.7" + }, + "packageManager": "pnpm@8.15.7" } diff --git a/packages/next-swc/turbo.json b/packages/next-swc/turbo.json index f811943d1a917..aac2f8ea20868 100644 --- a/packages/next-swc/turbo.json +++ b/packages/next-swc/turbo.json @@ -1,6 +1,7 @@ { + "$schema": "https://turborepo.org/schema.json", "extends": ["//"], - "pipeline": { + "tasks": { "build-native": { "inputs": [ "../../.cargo/**", diff --git a/packages/next/package.json b/packages/next/package.json index 3027179e30dbb..3e97c2980b510 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -344,6 +344,8 @@ "vercel" ], "engines": { - "node": ">=18.17.0" - } + "node": ">=18.17.0", + "pnpm": "8.15.7" + }, + "packageManager": "pnpm@8.15.7" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0c2ef517f172a..20a0b8c118b2e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -546,8 +546,8 @@ importers: specifier: 0.2.1 version: 0.2.1(@bazel/bazelisk@1.18.0)(typescript@5.3.3) turbo: - specifier: 1.13.3-canary.2 - version: 1.13.3-canary.2 + specifier: 2.0.3 + version: 2.0.3 typescript: specifier: 5.3.3 version: 5.3.3 @@ -14782,7 +14782,7 @@ packages: engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 - debug: 4.1.1 + debug: 4.3.4 transitivePeerDependencies: - supports-color @@ -24941,64 +24941,64 @@ packages: engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} dev: true - /turbo-darwin-64@1.13.3-canary.2: - resolution: {integrity: sha512-M8QDR6SKPSLEjSLWnIM//caHWBhcZNkIPdnnMkHm8R9/fpFSI5X//GBdR0qnXcgdqOdFgnxheabwYm5Bm+1KWQ==} + /turbo-darwin-64@2.0.3: + resolution: {integrity: sha512-v7ztJ8sxdHw3SLfO2MhGFeeU4LQhFii1hIGs9uBiXns/0YTGOvxLeifnfGqhfSrAIIhrCoByXO7nR9wlm10n3Q==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.13.3-canary.2: - resolution: {integrity: sha512-4RpdYK+XF9Lx7/nmUzbn978t4HBCmmemAazOjmhyd0pOMn8rLVexPkByDEV84SrgofkCWdTHDwcHaOQvOLrKtw==} + /turbo-darwin-arm64@2.0.3: + resolution: {integrity: sha512-LUcqvkV9Bxtng6QHbevp8IK8zzwbIxM6HMjCE7FEW6yJBN1KwvTtRtsGBwwmTxaaLO0wD1Jgl3vgkXAmQ4fqUw==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.13.3-canary.2: - resolution: {integrity: sha512-8gzyPtOmzACNwtWi5//ZHwcJb2i21pZVXQEiNwTycypyBtV2H0WChmqjulS7M3z5dxwHcx0Ehf9TqY4K023j2A==} + /turbo-linux-64@2.0.3: + resolution: {integrity: sha512-xpdY1suXoEbsQsu0kPep2zrB8ijv/S5aKKrntGuQ62hCiwDFoDcA/Z7FZ8IHQ2u+dpJARa7yfiByHmizFE0r5Q==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.13.3-canary.2: - resolution: {integrity: sha512-QzRIyO+HUMc5+hj5cVBCKpCyOiBPxzAao4zWZgz6iKMuSC6utjHLf/9AAo6NOMFgBONTYsMUArL5gDyLLOO0lw==} + /turbo-linux-arm64@2.0.3: + resolution: {integrity: sha512-MBACTcSR874L1FtLL7gkgbI4yYJWBUCqeBN/iE29D+8EFe0d3fAyviFlbQP4K/HaDYet1i26xkkOiWr0z7/V9A==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.13.3-canary.2: - resolution: {integrity: sha512-s4k+yclLr/MWuwYURPZX2v6y1PP7E2aUUao6syQ68Un+36RYBgINN/VV4HucZuiXyqLuBuaDjfrnE1TX3FREOg==} + /turbo-windows-64@2.0.3: + resolution: {integrity: sha512-zi3YuKPkM9JxMTshZo3excPk37hUrj5WfnCqh4FjI26ux6j/LJK+Dh3SebMHd9mR7wP9CMam4GhmLCT+gDfM+w==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.13.3-canary.2: - resolution: {integrity: sha512-p5qGGeb3z1Gaxq43lTFm/PyTh7xtuDCfesxGWZWESG6MyXZuZYzuEH2cSmM8jqta6EC+G+iF5sxeKUzIpsJWeQ==} + /turbo-windows-arm64@2.0.3: + resolution: {integrity: sha512-wmed4kkenLvRbidi7gISB4PU77ujBuZfgVGDZ4DXTFslE/kYpINulwzkVwJIvNXsJtHqyOq0n6jL8Zwl3BrwDg==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.13.3-canary.2: - resolution: {integrity: sha512-GqkwRxoigbjvj/m1JfY7kGDupNeuADW7Hg1+rO+KqNMEUihOfq8a1kjCbwlqOfyS8PPfMHDkDPXrfhA8A1N9vg==} + /turbo@2.0.3: + resolution: {integrity: sha512-jF1K0tTUyryEWmgqk1V0ALbSz3VdeZ8FXUo6B64WsPksCMCE48N5jUezGOH2MN0+epdaRMH8/WcPU0QQaVfeLA==} hasBin: true optionalDependencies: - turbo-darwin-64: 1.13.3-canary.2 - turbo-darwin-arm64: 1.13.3-canary.2 - turbo-linux-64: 1.13.3-canary.2 - turbo-linux-arm64: 1.13.3-canary.2 - turbo-windows-64: 1.13.3-canary.2 - turbo-windows-arm64: 1.13.3-canary.2 + turbo-darwin-64: 2.0.3 + turbo-darwin-arm64: 2.0.3 + turbo-linux-64: 2.0.3 + turbo-linux-arm64: 2.0.3 + turbo-windows-64: 2.0.3 + turbo-windows-arm64: 2.0.3 dev: true /tweetnacl@0.14.5: diff --git a/scripts/normalize-version-bump.js b/scripts/normalize-version-bump.js index e13eb4b8928fb..b4610f053b5fb 100755 --- a/scripts/normalize-version-bump.js +++ b/scripts/normalize-version-bump.js @@ -2,7 +2,7 @@ // @ts-check /* - This prevents busting the turbo cache un-necessarily due + This prevents busting the turbo cache un-necessarily due to bumping the version in the repo's package.json files */ const path = require('path') @@ -72,5 +72,6 @@ const writeJson = async (filePath, data) => private: true, workspaces: ['packages/*'], scripts: {}, + packageManager: 'pnpm@8.15.7', }) })() diff --git a/turbo.json b/turbo.json index 3ee8c97f8f7bc..0cb4370968adb 100644 --- a/turbo.json +++ b/turbo.json @@ -1,7 +1,6 @@ { "$schema": "https://turborepo.org/schema.json", - "experimentalUI": true, - "pipeline": { + "tasks": { "build": { "dependsOn": ["^build"], "outputs": ["dist/**"] From 8f67469ba408b1dc73723ff188ce3860c35bcd52 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Wed, 12 Jun 2024 13:26:57 -0700 Subject: [PATCH 52/60] fix parallel-route-not-found-params deploy test (#66807) The rest of this test is valid for a deployed environment, we just won't have access to runtime logs. --- test/deploy-tests-manifest.json | 1 - .../parallel-route-not-found-params.test.ts | 67 +++++++++++-------- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/test/deploy-tests-manifest.json b/test/deploy-tests-manifest.json index 822e504742365..7f75b17c43ce4 100644 --- a/test/deploy-tests-manifest.json +++ b/test/deploy-tests-manifest.json @@ -30,7 +30,6 @@ "test/e2e/react-dnd-compile/react-dnd-compile.test.ts", "test/e2e/skip-trailing-slash-redirect/index.test.ts", "test/e2e/app-dir/app-compilation/index.test.ts", - "test/e2e/app-dir/parallel-route-not-found-params/parallel-route-not-found-params.test.ts", "test/e2e/app-dir/ppr/ppr.test.ts", "test/e2e/app-dir/rsc-webpack-loader/rsc-webpack-loader.test.ts", "test/e2e/swc-warnings/index.test.ts", diff --git a/test/e2e/app-dir/parallel-route-not-found-params/parallel-route-not-found-params.test.ts b/test/e2e/app-dir/parallel-route-not-found-params/parallel-route-not-found-params.test.ts index cb699e770f48e..d05b610c00da3 100644 --- a/test/e2e/app-dir/parallel-route-not-found-params/parallel-route-not-found-params.test.ts +++ b/test/e2e/app-dir/parallel-route-not-found-params/parallel-route-not-found-params.test.ts @@ -2,22 +2,26 @@ import { nextTestSetup } from 'e2e-utils' import { check } from 'next-test-utils' describe('parallel-route-not-found', () => { - const { next } = nextTestSetup({ + const { next, isNextDeploy } = nextTestSetup({ files: __dirname, }) it('should behave correctly without any errors', async () => { const browser = await next.browser('/en') - await check(() => { - if ( - next.cliOutput.includes('TypeError') || - next.cliOutput.includes('Warning') - ) { - return 'has-errors' - } - return 'success' - }, 'success') + // Deploy doesn't have access to runtime logs + if (!isNextDeploy) { + await check(() => { + if ( + next.cliOutput.includes('TypeError') || + next.cliOutput.includes('Warning') + ) { + return 'has-errors' + } + + return 'success' + }, 'success') + } expect(await browser.elementByCss('body').text()).not.toContain( 'Interception Modal' @@ -26,16 +30,19 @@ describe('parallel-route-not-found', () => { await browser.elementByCss("[href='/en/show']").click() - await check(() => { - if ( - next.cliOutput.includes('TypeError') || - next.cliOutput.includes('Warning') - ) { - return 'has-errors' - } + // Deploy doesn't have access to runtime logs + if (!isNextDeploy) { + await check(() => { + if ( + next.cliOutput.includes('TypeError') || + next.cliOutput.includes('Warning') + ) { + return 'has-errors' + } - return 'success' - }, 'success') + return 'success' + }, 'success') + } await check(() => browser.elementByCss('body').text(), /Interception Modal/) await check(() => browser.elementByCss('body').text(), /Locale: en/) @@ -47,16 +54,20 @@ describe('parallel-route-not-found', () => { it('should handle the not found case correctly without any errors', async () => { const browser = await next.browser('/de/show') - await check(() => { - if ( - next.cliOutput.includes('TypeError') || - next.cliOutput.includes('Warning') - ) { - return 'has-errors' - } - return 'success' - }, 'success') + // Deploy doesn't have access to runtime logs + if (!isNextDeploy) { + await check(() => { + if ( + next.cliOutput.includes('TypeError') || + next.cliOutput.includes('Warning') + ) { + return 'has-errors' + } + + return 'success' + }, 'success') + } expect(await browser.elementByCss('body').text()).toContain( 'Custom Not Found' From 33872bfa1e616f219bb087b9e900ca43af7d964b Mon Sep 17 00:00:00 2001 From: Will Binns-Smith Date: Wed, 12 Jun 2024 15:15:33 -0700 Subject: [PATCH 53/60] Make `InvalidImportResolvePlugin` a `BeforeResolvePlugin` (#66622) https://github.com/vercel/turbo/pull/8165 introduced plugins that operate before resolving occurs, meaning that plugins like `InvalidImportResolvePlugin` which never use the initial resolve result and report issues can avoid that work. Test Plan: `TURBOPACK_DEV=1 TURBOPACK=1 pnpm test-dev test/development/acceptance-app/invalid-imports.test.ts` --- Cargo.lock | 78 +++++------ Cargo.toml | 6 +- .../next-core/src/next_client/context.rs | 13 +- .../crates/next-core/src/next_edge/context.rs | 62 ++++---- .../next-core/src/next_font/local/mod.rs | 16 +-- .../next-core/src/next_server/context.rs | 32 ++--- .../next-core/src/next_shared/resolve.rs | 132 +++++------------- 7 files changed, 129 insertions(+), 210 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 41ca6d9d957e7..9e57979dfb84b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -321,7 +321,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "serde", "smallvec", @@ -3092,7 +3092,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "serde", @@ -5227,9 +5227,9 @@ dependencies = [ [[package]] name = "swc_compiler_base" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdff81d2ae11503b2cb34b37cd481c3400d19c7c05445dd5daad5cd29692ee69" +checksum = "95ef85116a4d22dd66ebc8d1d1c7634565569fa4b80bf6728686b38e407f00f1" dependencies = [ "anyhow", "base64 0.21.4", @@ -6964,12 +6964,12 @@ dependencies = [ [[package]] name = "turbo-prehash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "async-trait", @@ -7001,7 +7001,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "cargo-lock", @@ -7013,7 +7013,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "bytes", @@ -7027,7 +7027,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "dotenvs", @@ -7041,7 +7041,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "lazy_static", @@ -7057,7 +7057,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "auto-hash-map", @@ -7089,7 +7089,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "md4", "turbo-tasks-macros", @@ -7099,7 +7099,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "proc-macro-error", @@ -7113,7 +7113,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "proc-macro2", "quote", @@ -7123,7 +7123,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "mimalloc", ] @@ -7131,7 +7131,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "auto-hash-map", @@ -7158,7 +7158,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "async-recursion", @@ -7188,7 +7188,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "auto-hash-map", "mdxjs", @@ -7229,7 +7229,7 @@ dependencies = [ [[package]] name = "turbopack-browser" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7252,7 +7252,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "clap", @@ -7269,7 +7269,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "async-recursion", @@ -7298,7 +7298,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7325,7 +7325,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "async-compression", @@ -7361,7 +7361,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "async-trait", @@ -7396,7 +7396,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "serde", "serde_json", @@ -7407,7 +7407,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "async-trait", @@ -7432,7 +7432,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "indoc", @@ -7448,7 +7448,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7464,7 +7464,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "base64 0.21.4", @@ -7483,7 +7483,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "serde", @@ -7498,7 +7498,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "mdxjs", @@ -7513,7 +7513,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "async-stream", @@ -7547,7 +7547,7 @@ dependencies = [ [[package]] name = "turbopack-nodejs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7567,7 +7567,7 @@ dependencies = [ [[package]] name = "turbopack-resolve" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7585,7 +7585,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "serde", @@ -7601,7 +7601,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "swc_core", "turbo-tasks", @@ -7612,7 +7612,7 @@ dependencies = [ [[package]] name = "turbopack-trace-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "either", @@ -7632,7 +7632,7 @@ dependencies = [ [[package]] name = "turbopack-trace-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "crossbeam-channel", @@ -7648,7 +7648,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.1#4592752b6dea8e23aef995dac3c46187864e602f" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-240612.3#15e7a68f36429aa966ade14267044797ade1ef19" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index 4a001ab9c7afc..f54fb0227e43b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,11 +37,11 @@ swc_core = { version = "0.93.2", features = [ testing = { version = "0.35.25" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240612.1" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240612.3" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240612.1" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240612.3" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240612.1" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-240612.3" } # General Deps diff --git a/packages/next-swc/crates/next-core/src/next_client/context.rs b/packages/next-swc/crates/next-core/src/next_client/context.rs index 2df977caca867..5b8e112c4b348 100644 --- a/packages/next-swc/crates/next-core/src/next_client/context.rs +++ b/packages/next-swc/crates/next-core/src/next_client/context.rs @@ -49,7 +49,7 @@ use crate::{ next_shared::{ resolve::{ get_invalid_server_only_resolve_plugin, ModuleFeatureReportResolvePlugin, - NextSharedRuntimeResolvePlugin, UnsupportedModulesResolvePlugin, + NextSharedRuntimeResolvePlugin, }, transforms::{ emotion::get_emotion_transform_rule, relay::get_relay_transform_rule, @@ -158,13 +158,14 @@ pub async fn get_client_resolve_options_context( resolved_map: Some(next_client_resolved_map), browser: true, module: true, - before_resolve_plugins: vec![Vc::upcast(NextFontLocalResolvePlugin::new(project_path))], - after_resolve_plugins: vec![ - Vc::upcast(ModuleFeatureReportResolvePlugin::new(project_path)), - Vc::upcast(UnsupportedModulesResolvePlugin::new(project_path)), - Vc::upcast(NextSharedRuntimeResolvePlugin::new(project_path)), + before_resolve_plugins: vec![ Vc::upcast(get_invalid_server_only_resolve_plugin(project_path)), + Vc::upcast(ModuleFeatureReportResolvePlugin::new(project_path)), + Vc::upcast(NextFontLocalResolvePlugin::new(project_path)), ], + after_resolve_plugins: vec![Vc::upcast(NextSharedRuntimeResolvePlugin::new( + project_path, + ))], ..Default::default() }; Ok(ResolveOptionsContext { diff --git a/packages/next-swc/crates/next-core/src/next_edge/context.rs b/packages/next-swc/crates/next-core/src/next_edge/context.rs index acee2dc2c511a..85547a8809637 100644 --- a/packages/next-swc/crates/next-core/src/next_edge/context.rs +++ b/packages/next-swc/crates/next-core/src/next_edge/context.rs @@ -28,7 +28,6 @@ use crate::{ next_shared::resolve::{ get_invalid_client_only_resolve_plugin, get_invalid_styled_jsx_resolve_plugin, ModuleFeatureReportResolvePlugin, NextSharedRuntimeResolvePlugin, - UnsupportedModulesResolvePlugin, }, util::{foreign_code_context_condition, NextRuntime}, }; @@ -101,44 +100,37 @@ pub async fn get_edge_resolve_options_context( let ty = ty.into_value(); - let before_resolve_plugins = match ty { + let mut before_resolve_plugins = vec![Vc::upcast(ModuleFeatureReportResolvePlugin::new( + project_path, + ))]; + if matches!( + ty, ServerContextType::Pages { .. } - | ServerContextType::AppSSR { .. } - | ServerContextType::AppRSC { .. } => { - vec![Vc::upcast(NextFontLocalResolvePlugin::new(project_path))] - } - ServerContextType::PagesData { .. } - | ServerContextType::PagesApi { .. } - | ServerContextType::AppRoute { .. } - | ServerContextType::Middleware { .. } - | ServerContextType::Instrumentation => vec![], - }; + | ServerContextType::AppSSR { .. } + | ServerContextType::AppRSC { .. } + ) { + before_resolve_plugins.push(Vc::upcast(NextFontLocalResolvePlugin::new(project_path))); + } - let mut after_resolve_plugins = match ty { - ServerContextType::Pages { .. } - | ServerContextType::PagesApi { .. } - | ServerContextType::AppSSR { .. } => { - vec![] - } + if matches!( + ty, ServerContextType::AppRSC { .. } - | ServerContextType::AppRoute { .. } - | ServerContextType::PagesData { .. } - | ServerContextType::Middleware { .. } - | ServerContextType::Instrumentation => { - vec![ - Vc::upcast(get_invalid_client_only_resolve_plugin(project_path)), - Vc::upcast(get_invalid_styled_jsx_resolve_plugin(project_path)), - ] - } - }; - - let base_plugins = vec![ - Vc::upcast(ModuleFeatureReportResolvePlugin::new(project_path)), - Vc::upcast(UnsupportedModulesResolvePlugin::new(project_path)), - Vc::upcast(NextSharedRuntimeResolvePlugin::new(project_path)), - ]; + | ServerContextType::AppRoute { .. } + | ServerContextType::PagesData { .. } + | ServerContextType::Middleware { .. } + | ServerContextType::Instrumentation + ) { + before_resolve_plugins.push(Vc::upcast(get_invalid_client_only_resolve_plugin( + project_path, + ))); + before_resolve_plugins.push(Vc::upcast(get_invalid_styled_jsx_resolve_plugin( + project_path, + ))); + } - after_resolve_plugins.extend_from_slice(&base_plugins); + let after_resolve_plugins = vec![Vc::upcast(NextSharedRuntimeResolvePlugin::new( + project_path, + ))]; // https://github.com/vercel/next.js/blob/bf52c254973d99fed9d71507a2e818af80b8ade7/packages/next/src/build/webpack-config.ts#L96-L102 let mut custom_conditions = vec![mode.await?.condition().into()]; diff --git a/packages/next-swc/crates/next-core/src/next_font/local/mod.rs b/packages/next-swc/crates/next-core/src/next_font/local/mod.rs index 78740b883106b..653210411f5b8 100644 --- a/packages/next-swc/crates/next-core/src/next_font/local/mod.rs +++ b/packages/next-swc/crates/next-core/src/next_font/local/mod.rs @@ -15,7 +15,7 @@ use turbopack_binding::{ resolve::{ parse::Request, plugin::{BeforeResolvePlugin, BeforeResolvePluginCondition}, - RequestKey, ResolveResult, ResolveResultItem, ResolveResultOption, + ResolveResult, ResolveResultItem, ResolveResultOption, }, virtual_source::VirtualSource, }, @@ -70,7 +70,7 @@ impl NextFontLocalResolvePlugin { impl BeforeResolvePlugin for NextFontLocalResolvePlugin { #[turbo_tasks::function] async fn before_resolve_condition(&self) -> Vc { - BeforeResolvePluginCondition::new(Glob::new( + BeforeResolvePluginCondition::from_request_glob(Glob::new( "{next,@vercel/turbopack-next/internal}/font/local/*".into(), )) } @@ -125,16 +125,10 @@ impl BeforeResolvePlugin for NextFontLocalResolvePlugin { .emit(); return Ok(ResolveResultOption::some( - ResolveResult::primary_with_key( - RequestKey::new(font_path.clone()), - ResolveResultItem::Error(Vc::cell( - format!( - "Font file not found: Can't resolve {}'", - font_path - ) + ResolveResult::primary(ResolveResultItem::Error(Vc::cell( + format!("Font file not found: Can't resolve {}'", font_path) .into(), - )), - ) + ))) .into(), )); } diff --git a/packages/next-swc/crates/next-core/src/next_server/context.rs b/packages/next-swc/crates/next-core/src/next_server/context.rs index 897d76ea868c1..13127c3ebfb5e 100644 --- a/packages/next-swc/crates/next-core/src/next_server/context.rs +++ b/packages/next-swc/crates/next-core/src/next_server/context.rs @@ -53,7 +53,7 @@ use crate::{ resolve::{ get_invalid_client_only_resolve_plugin, get_invalid_styled_jsx_resolve_plugin, ModuleFeatureReportResolvePlugin, NextExternalResolvePlugin, - NextNodeSharedRuntimeResolvePlugin, UnsupportedModulesResolvePlugin, + NextNodeSharedRuntimeResolvePlugin, }, transforms::{ emotion::get_emotion_transform_rule, get_ecma_transform_rule, @@ -126,7 +126,6 @@ pub async fn get_server_resolve_options_context( foreign_code_context_condition(next_config, project_path).await?; let root_dir = project_path.root().resolve().await?; let module_feature_report_resolve_plugin = ModuleFeatureReportResolvePlugin::new(project_path); - let unsupported_modules_resolve_plugin = UnsupportedModulesResolvePlugin::new(project_path); let invalid_client_only_resolve_plugin = get_invalid_client_only_resolve_plugin(project_path); let invalid_styled_jsx_client_only_resolve_plugin = get_invalid_styled_jsx_resolve_plugin(project_path); @@ -202,26 +201,29 @@ pub async fn get_server_resolve_options_context( let next_node_shared_runtime_plugin = NextNodeSharedRuntimeResolvePlugin::new(project_path, Value::new(ty)); - let before_resolve_plugins = match ty { + let mut before_resolve_plugins = match ty { ServerContextType::Pages { .. } | ServerContextType::AppSSR { .. } | ServerContextType::AppRSC { .. } => { - vec![Vc::upcast(NextFontLocalResolvePlugin::new(project_path))] + vec![ + Vc::upcast(NextFontLocalResolvePlugin::new(project_path)), + Vc::upcast(module_feature_report_resolve_plugin), + ] } ServerContextType::PagesData { .. } | ServerContextType::PagesApi { .. } | ServerContextType::AppRoute { .. } | ServerContextType::Middleware { .. } - | ServerContextType::Instrumentation => vec![], + | ServerContextType::Instrumentation => { + vec![Vc::upcast(module_feature_report_resolve_plugin)] + } }; - let mut after_resolve_plugins = match ty { + let after_resolve_plugins = match ty { ServerContextType::Pages { .. } | ServerContextType::PagesApi { .. } | ServerContextType::PagesData { .. } => { vec![ - Vc::upcast(module_feature_report_resolve_plugin), - Vc::upcast(unsupported_modules_resolve_plugin), Vc::upcast(next_node_shared_runtime_plugin), Vc::upcast(external_cjs_modules_plugin), Vc::upcast(next_external_plugin), @@ -231,24 +233,16 @@ pub async fn get_server_resolve_options_context( | ServerContextType::AppRSC { .. } | ServerContextType::AppRoute { .. } => { vec![ - Vc::upcast(module_feature_report_resolve_plugin), - Vc::upcast(unsupported_modules_resolve_plugin), Vc::upcast(next_node_shared_runtime_plugin), Vc::upcast(server_external_packages_plugin), Vc::upcast(next_external_plugin), ] } ServerContextType::Middleware { .. } => { - vec![ - Vc::upcast(module_feature_report_resolve_plugin), - Vc::upcast(unsupported_modules_resolve_plugin), - Vc::upcast(next_node_shared_runtime_plugin), - ] + vec![Vc::upcast(next_node_shared_runtime_plugin)] } ServerContextType::Instrumentation { .. } => { vec![ - Vc::upcast(module_feature_report_resolve_plugin), - Vc::upcast(unsupported_modules_resolve_plugin), Vc::upcast(next_node_shared_runtime_plugin), Vc::upcast(next_external_plugin), ] @@ -271,8 +265,8 @@ pub async fn get_server_resolve_options_context( | ServerContextType::AppRoute { .. } | ServerContextType::Middleware { .. } | ServerContextType::Instrumentation => { - after_resolve_plugins.push(Vc::upcast(invalid_client_only_resolve_plugin)); - after_resolve_plugins.push(Vc::upcast(invalid_styled_jsx_client_only_resolve_plugin)); + before_resolve_plugins.push(Vc::upcast(invalid_client_only_resolve_plugin)); + before_resolve_plugins.push(Vc::upcast(invalid_styled_jsx_client_only_resolve_plugin)); } ServerContextType::AppSSR { .. } => { //[TODO] Build error in this context makes rsc-build-error.ts fail which expects runtime error code diff --git a/packages/next-swc/crates/next-core/src/next_shared/resolve.rs b/packages/next-swc/crates/next-core/src/next_shared/resolve.rs index e9792821859be..c0ced49ee23c5 100644 --- a/packages/next-swc/crates/next-core/src/next_shared/resolve.rs +++ b/packages/next-swc/crates/next-core/src/next_shared/resolve.rs @@ -1,4 +1,4 @@ -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; use anyhow::Result; use lazy_static::lazy_static; @@ -9,15 +9,14 @@ use turbopack_binding::{ turbopack::core::{ diagnostics::DiagnosticExt, file_source::FileSource, - issue::{ - unsupported_module::UnsupportedModuleIssue, Issue, IssueExt, IssueSeverity, IssueStage, - OptionStyledString, StyledString, - }, + issue::{Issue, IssueExt, IssueSeverity, IssueStage, OptionStyledString, StyledString}, reference_type::ReferenceType, resolve::{ parse::Request, - pattern::Pattern, - plugin::{AfterResolvePlugin, AfterResolvePluginCondition}, + plugin::{ + AfterResolvePlugin, AfterResolvePluginCondition, BeforeResolvePlugin, + BeforeResolvePluginCondition, + }, ExternalType, ResolveResult, ResolveResultItem, ResolveResultOption, }, }, @@ -26,8 +25,6 @@ use turbopack_binding::{ use crate::{next_server::ServerContextType, next_telemetry::ModuleFeatureTelemetry}; lazy_static! { - static ref UNSUPPORTED_PACKAGES: HashSet<&'static str> = [].into(); - static ref UNSUPPORTED_PACKAGE_PATHS: HashSet<(&'static str, &'static str)> = [].into(); // Set of the features we want to track, following existing references in webpack/plugins/telemetry-plugin. static ref FEATURE_MODULES: HashMap<&'static str, Vec<&'static str>> = HashMap::from([ ( @@ -46,69 +43,6 @@ lazy_static! { ]); } -#[turbo_tasks::value] -pub(crate) struct UnsupportedModulesResolvePlugin { - root: Vc, -} - -#[turbo_tasks::value_impl] -impl UnsupportedModulesResolvePlugin { - #[turbo_tasks::function] - pub fn new(root: Vc) -> Vc { - UnsupportedModulesResolvePlugin { root }.cell() - } -} - -#[turbo_tasks::value_impl] -impl AfterResolvePlugin for UnsupportedModulesResolvePlugin { - #[turbo_tasks::function] - fn after_resolve_condition(&self) -> Vc { - AfterResolvePluginCondition::new(self.root.root(), Glob::new("**".into())) - } - - #[turbo_tasks::function] - async fn after_resolve( - &self, - _fs_path: Vc, - file_path: Vc, - _reference_type: Value, - request: Vc, - ) -> Result> { - if let Request::Module { - module, - path, - query: _, - fragment: _, - } = &*request.await? - { - // Warn if the package is known not to be supported by Turbopack at the moment. - if UNSUPPORTED_PACKAGES.contains(module.as_str()) { - UnsupportedModuleIssue { - file_path, - package: module.clone(), - package_path: None, - } - .cell() - .emit(); - } - - if let Pattern::Constant(path) = path { - if UNSUPPORTED_PACKAGE_PATHS.contains(&(module, path)) { - UnsupportedModuleIssue { - file_path, - package: module.clone(), - package_path: Some(path.to_owned()), - } - .cell() - .emit(); - } - } - } - - Ok(ResolveResultOption::none()) - } -} - #[turbo_tasks::value(shared)] pub struct InvalidImportModuleIssue { pub file_path: Vc, @@ -187,34 +121,34 @@ impl InvalidImportResolvePlugin { } #[turbo_tasks::value_impl] -impl AfterResolvePlugin for InvalidImportResolvePlugin { +impl BeforeResolvePlugin for InvalidImportResolvePlugin { #[turbo_tasks::function] - fn after_resolve_condition(&self) -> Vc { - AfterResolvePluginCondition::new(self.root.root(), Glob::new("**".into())) + fn before_resolve_condition(&self) -> Vc { + BeforeResolvePluginCondition::from_modules(Vc::cell(vec![self.invalid_import.clone()])) } #[turbo_tasks::function] - async fn after_resolve( + async fn before_resolve( &self, - _fs_path: Vc, - context: Vc, + lookup_path: Vc, _reference_type: Value, - request: Vc, + _request: Vc, ) -> Result> { - if let Request::Module { module, .. } = &*request.await? { - if module.as_str() == self.invalid_import.as_str() { - InvalidImportModuleIssue { - file_path: context, - messages: self.message.clone(), - // styled-jsx specific resolve error have own message - skip_context_message: self.invalid_import == "styled-jsx", - } - .cell() - .emit(); - } + InvalidImportModuleIssue { + file_path: lookup_path, + messages: self.message.clone(), + // styled-jsx specific resolve error has its own message + skip_context_message: self.invalid_import == "styled-jsx", } + .cell() + .emit(); - Ok(ResolveResultOption::none()) + Ok(ResolveResultOption::some( + ResolveResult::primary(ResolveResultItem::Error(Vc::cell( + self.message.join("\n").into(), + ))) + .cell(), + )) } } @@ -402,17 +336,21 @@ impl ModuleFeatureReportResolvePlugin { } #[turbo_tasks::value_impl] -impl AfterResolvePlugin for ModuleFeatureReportResolvePlugin { +impl BeforeResolvePlugin for ModuleFeatureReportResolvePlugin { #[turbo_tasks::function] - fn after_resolve_condition(&self) -> Vc { - AfterResolvePluginCondition::new(self.root.root(), Glob::new("**".into())) + fn before_resolve_condition(&self) -> Vc { + BeforeResolvePluginCondition::from_modules(Vc::cell( + FEATURE_MODULES + .keys() + .map(|k| (*k).into()) + .collect::>(), + )) } #[turbo_tasks::function] - async fn after_resolve( + async fn before_resolve( &self, - _fs_path: Vc, - _context: Vc, + _lookup_path: Vc, _reference_type: Value, request: Vc, ) -> Result> { From 970420d78bef471d22bfde5d40091d383d707c6b Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Wed, 12 Jun 2024 22:23:29 +0000 Subject: [PATCH 54/60] v15.0.0-canary.28 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 12 ++++++------ packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 14 +++++++------- 17 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lerna.json b/lerna.json index 11585a1bdacd9..46993ad47c282 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "15.0.0-canary.27" + "version": "15.0.0-canary.28" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index d400cb3a8a140..00a5cace559fa 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "15.0.0-canary.27", + "version": "15.0.0-canary.28", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 9ae66ac85790b..6ce6ff2987970 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "15.0.0-canary.27", + "version": "15.0.0-canary.28", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "15.0.0-canary.27", + "@next/eslint-plugin-next": "15.0.0-canary.28", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 078c5ffa93c45..8ad262052d209 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "15.0.0-canary.27", + "version": "15.0.0-canary.28", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index d15ca0ccb9843..8464c7f044b01 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "15.0.0-canary.27", + "version": "15.0.0-canary.28", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 973ae132ceb9a..8ca126379b743 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "15.0.0-canary.27", + "version": "15.0.0-canary.28", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 9f7599388bc09..07985b8a6b620 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "15.0.0-canary.27", + "version": "15.0.0-canary.28", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 43aae5af46863..068653d50899a 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "15.0.0-canary.27", + "version": "15.0.0-canary.28", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 1ceb986c24079..c423fa4a46f4d 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "15.0.0-canary.27", + "version": "15.0.0-canary.28", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index d7f12190cb874..e92655040a01c 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "15.0.0-canary.27", + "version": "15.0.0-canary.28", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index c8d5189659fb5..a6a80d80be719 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "15.0.0-canary.27", + "version": "15.0.0-canary.28", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index c10bd01ce2fa7..c06b941e902dd 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "15.0.0-canary.27", + "version": "15.0.0-canary.28", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index d30ea1f4237d4..a4c06329e8d10 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "15.0.0-canary.27", + "version": "15.0.0-canary.28", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 3e97c2980b510..22ad48a095420 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "15.0.0-canary.27", + "version": "15.0.0-canary.28", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -93,7 +93,7 @@ ] }, "dependencies": { - "@next/env": "15.0.0-canary.27", + "@next/env": "15.0.0-canary.28", "@swc/helpers": "0.5.11", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -157,10 +157,10 @@ "@jest/types": "29.5.0", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/polyfill-module": "15.0.0-canary.27", - "@next/polyfill-nomodule": "15.0.0-canary.27", - "@next/react-refresh-utils": "15.0.0-canary.27", - "@next/swc": "15.0.0-canary.27", + "@next/polyfill-module": "15.0.0-canary.28", + "@next/polyfill-nomodule": "15.0.0-canary.28", + "@next/react-refresh-utils": "15.0.0-canary.28", + "@next/swc": "15.0.0-canary.28", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.41.2", "@swc/core": "1.5.7", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 8707a1981756e..2491f05b3d041 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "15.0.0-canary.27", + "version": "15.0.0-canary.28", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 086d84c5fefcf..d576c3430abbb 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "15.0.0-canary.27", + "version": "15.0.0-canary.28", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -26,7 +26,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "15.0.0-canary.27", + "next": "15.0.0-canary.28", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 20a0b8c118b2e..d249f1de6d6fe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -771,7 +771,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 15.0.0-canary.27 + specifier: 15.0.0-canary.28 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -833,7 +833,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 15.0.0-canary.27 + specifier: 15.0.0-canary.28 version: link:../next-env '@swc/helpers': specifier: 0.5.11 @@ -961,16 +961,16 @@ importers: specifier: 1.2.0 version: 1.2.0 '@next/polyfill-module': - specifier: 15.0.0-canary.27 + specifier: 15.0.0-canary.28 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 15.0.0-canary.27 + specifier: 15.0.0-canary.28 version: link:../next-polyfill-nomodule '@next/react-refresh-utils': - specifier: 15.0.0-canary.27 + specifier: 15.0.0-canary.28 version: link:../react-refresh-utils '@next/swc': - specifier: 15.0.0-canary.27 + specifier: 15.0.0-canary.28 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1594,7 +1594,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 15.0.0-canary.27 + specifier: 15.0.0-canary.28 version: link:../next outdent: specifier: 0.8.0 From 107a45fa6c5417677317f1f709155d62464fb824 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Wed, 12 Jun 2024 16:35:55 -0700 Subject: [PATCH 55/60] fix ppr deploy test (#66809) This test was only failing because `vercel logs` limit the output to 100 lines, and telemetry debugging was adding a lot of verbosity to the build logs. This bumps the log lines to a higher value to give some more breathing room, and did a drive-by `check` -> `retry` refactor. --- test/deploy-tests-manifest.json | 1 - test/e2e/app-dir/ppr/ppr.test.ts | 12 +++++------- test/lib/next-modes/next-deploy.ts | 12 +++++++++++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/test/deploy-tests-manifest.json b/test/deploy-tests-manifest.json index 7f75b17c43ce4..31186897af524 100644 --- a/test/deploy-tests-manifest.json +++ b/test/deploy-tests-manifest.json @@ -30,7 +30,6 @@ "test/e2e/react-dnd-compile/react-dnd-compile.test.ts", "test/e2e/skip-trailing-slash-redirect/index.test.ts", "test/e2e/app-dir/app-compilation/index.test.ts", - "test/e2e/app-dir/ppr/ppr.test.ts", "test/e2e/app-dir/rsc-webpack-loader/rsc-webpack-loader.test.ts", "test/e2e/swc-warnings/index.test.ts", "test/e2e/third-parties/index.test.ts", diff --git a/test/e2e/app-dir/ppr/ppr.test.ts b/test/e2e/app-dir/ppr/ppr.test.ts index e083c9dafe572..a2eb994134eaf 100644 --- a/test/e2e/app-dir/ppr/ppr.test.ts +++ b/test/e2e/app-dir/ppr/ppr.test.ts @@ -1,5 +1,5 @@ import { nextTestSetup } from 'e2e-utils' -import { check, findAllTelemetryEvents } from 'next-test-utils' +import { retry, findAllTelemetryEvents } from 'next-test-utils' describe('ppr', () => { const { next, isNextDev, isNextStart } = nextTestSetup({ @@ -10,12 +10,10 @@ describe('ppr', () => { }) it('should indicate the feature is experimental', async () => { - await check(() => { - return next.cliOutput.includes('Experiments (use with caution)') && - next.cliOutput.includes('ppr') - ? 'success' - : 'fail' - }, 'success') + await retry(() => { + expect(next.cliOutput).toContain('Experiments (use with caution)') + expect(next.cliOutput).toContain('ppr') + }) }) if (isNextStart) { describe('build output', () => { diff --git a/test/lib/next-modes/next-deploy.ts b/test/lib/next-modes/next-deploy.ts index 007a2ea94cd55..5e21c9797eac2 100644 --- a/test/lib/next-modes/next-deploy.ts +++ b/test/lib/next-modes/next-deploy.ts @@ -150,7 +150,17 @@ export class NextDeployInstance extends NextInstance { // Use the vercel logs command to get the CLI output from the build. const logs = await execa( 'vercel', - ['logs', this._url, '--output', 'raw', ...vercelFlags], + [ + 'logs', + this._url, + '--output', + 'raw', + // The default # of lines to show in the output is 100, but some of our tests have noisy output, + // so bump to 1000 + '-n', + 1000, + ...vercelFlags, + ], { env: vercelEnv, reject: false, From 7c97f56bfda8a8720cd2d173fb148d8c5edcb8f9 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Wed, 12 Jun 2024 17:13:24 -0700 Subject: [PATCH 56/60] fix app-prefetch-false-loading deploy test (#66811) This gates the part that depends on runtime logs. This test is still valuable without this particular check. --- test/deploy-tests-manifest.json | 1 - .../app-prefetch-false-loading.test.ts | 21 ++++++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/test/deploy-tests-manifest.json b/test/deploy-tests-manifest.json index 31186897af524..886fcdda1a615 100644 --- a/test/deploy-tests-manifest.json +++ b/test/deploy-tests-manifest.json @@ -33,7 +33,6 @@ "test/e2e/app-dir/rsc-webpack-loader/rsc-webpack-loader.test.ts", "test/e2e/swc-warnings/index.test.ts", "test/e2e/third-parties/index.test.ts", - "test/e2e/app-dir/app-prefetch-false-loading/app-prefetch-false-loading.test.ts", "test/e2e/app-dir/app-routes-client-component/app-routes-client-component.test.ts", "test/e2e/app-dir/app-routes/app-custom-route-base-path.test.ts", "test/e2e/app-dir/mdx/mdx.test.ts", diff --git a/test/e2e/app-dir/app-prefetch-false-loading/app-prefetch-false-loading.test.ts b/test/e2e/app-dir/app-prefetch-false-loading/app-prefetch-false-loading.test.ts index 3e1b54e7e45f0..2b1a73f8f746c 100644 --- a/test/e2e/app-dir/app-prefetch-false-loading/app-prefetch-false-loading.test.ts +++ b/test/e2e/app-dir/app-prefetch-false-loading/app-prefetch-false-loading.test.ts @@ -2,7 +2,7 @@ import { nextTestSetup } from 'e2e-utils' import { check } from 'next-test-utils' describe('app-prefetch-false-loading', () => { - const { next } = nextTestSetup({ + const { next, isNextDeploy } = nextTestSetup({ files: __dirname, }) @@ -28,12 +28,17 @@ describe('app-prefetch-false-loading', () => { expect(initialRandomNumber).toBe(newRandomNumber) - await check(() => { - const logOccurrences = - next.cliOutput.slice(logStartIndex).split('re-fetching in layout') - .length - 1 - - return logOccurrences - }, 1) + // Deploy doesn't have access to runtime logs. This assertion is also redundant since if + // the layout was re-fetched, the `no-store` on the random number would have resulted in a new value. + // Keeping this here for consistency with the original test. + if (!isNextDeploy) { + await check(() => { + const logOccurrences = + next.cliOutput.slice(logStartIndex).split('re-fetching in layout') + .length - 1 + + return logOccurrences + }, 1) + } }) }) From 36192ea36ef4eaa1be0ac2feaeaea8f535c5bf90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 13 Jun 2024 09:37:11 +0900 Subject: [PATCH 57/60] build: Update `swc_core` to `v0.93.4` (#66781) ### What? Update `swc_core` to `v0.93.4`. ### Why? To apply https://github.com/swc-project/swc/pull/9036 and https://github.com/swc-project/swc/pull/9037. Those PR makes parsing of some files 5x faster. ### How? --- Cargo.lock | 20 ++++++++++---------- Cargo.toml | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e57979dfb84b..37906d1a52870 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5281,9 +5281,9 @@ dependencies = [ [[package]] name = "swc_core" -version = "0.93.2" +version = "0.93.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57f2da78bdc49a5bd2edc80213f2b95300b11a15068e18ab9a9dd943a8660d59" +checksum = "f331506bd57c03b006b5585797c23bf10077bc8ef949d80efce3ef4b9ee8a664" dependencies = [ "binding_macros", "swc", @@ -5489,9 +5489,9 @@ dependencies = [ [[package]] name = "swc_ecma_codegen" -version = "0.149.2" +version = "0.149.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab6d5e7bbd9208f980b5dad2a4a6ae798c97569f809a48c3f92e6ae7e183c6c" +checksum = "efb2bef3f4998865b2d466fb2ef9410a03449d255d199f3eb807fb19acc3862b" dependencies = [ "memchr", "num-bigint", @@ -5770,9 +5770,9 @@ dependencies = [ [[package]] name = "swc_ecma_minifier" -version = "0.195.0" +version = "0.195.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "574ca302d18880ff3809d83797a51eb96a8f4cef7c948286a59cd1937e0226d0" +checksum = "94ed053fe91ab7c1ea79a577a49fdc3da895df802bcf9df04de4ccb51a075ff7" dependencies = [ "arrayvec", "indexmap 2.2.6", @@ -5804,9 +5804,9 @@ dependencies = [ [[package]] name = "swc_ecma_parser" -version = "0.144.2" +version = "0.144.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31adf4599e8de70f3b754dfc34ec2ab09fa6841d79a9f4a888250a404eae7030" +checksum = "fc0b4193b9c127db1990a5a08111aafe0122bc8b138646807c63f2a6521b7da4" dependencies = [ "either", "new_debug_unreachable", @@ -6128,9 +6128,9 @@ dependencies = [ [[package]] name = "swc_ecma_usage_analyzer" -version = "0.24.3" +version = "0.24.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7d7109b3794756cc51e842dbb874d2da44293b06a9e3837b477300b0ccef8e" +checksum = "104d474b77f73db1467f31d5bceb1e4821e9b471c97baa7f208e2d8edd63c107" dependencies = [ "indexmap 2.2.6", "rustc-hash", diff --git a/Cargo.toml b/Cargo.toml index f54fb0227e43b..f5605988a7b89 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ next-core = { path = "packages/next-swc/crates/next-core" } next-custom-transforms = { path = "packages/next-swc/crates/next-custom-transforms" } # SWC crates -swc_core = { version = "0.93.2", features = [ +swc_core = { version = "0.93.4", features = [ "ecma_loader_lru", "ecma_loader_parking_lot", ] } From 258726e42ba1337dd5577252a9d682540ac677a7 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Thu, 13 Jun 2024 07:43:55 -0700 Subject: [PATCH 58/60] re-add test output string in run-tests (#66828) I missed that this was used by the comment webhook when I removed it in #66721. This restores the existing code and adds a better comment explaining why it's there. --- run-tests.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/run-tests.js b/run-tests.js index 412f429ee16bf..234c83171c1cd 100644 --- a/run-tests.js +++ b/run-tests.js @@ -697,6 +697,33 @@ ${ENDGROUP}`) } } + // Emit test output if test failed or if we're continuing tests on error + // This is parsed by the commenter webhook to notify about failing tests + if ((!passed || shouldContinueTestsOnError) && isTestJob) { + try { + const testsOutput = await fsp.readFile( + `${test.file}${RESULTS_EXT}`, + 'utf8' + ) + const obj = JSON.parse(testsOutput) + obj.processEnv = { + NEXT_TEST_MODE: process.env.NEXT_TEST_MODE, + HEADLESS: process.env.HEADLESS, + } + await outputSema.acquire() + if (GROUP) console.log(`${GROUP}Result as JSON for tooling`) + console.log( + `--test output start--`, + JSON.stringify(obj), + `--test output end--` + ) + if (ENDGROUP) console.log(ENDGROUP) + outputSema.release() + } catch (err) { + console.log(`Failed to load test output`, err) + } + } + sema.release() if (dirSema) dirSema.release() }) From 96d6370572cb3e9182c427f2d61e0d74a2e1c72e Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Thu, 13 Jun 2024 08:54:59 -0700 Subject: [PATCH 59/60] fix revalidate-reason deploy test (#66830) Since `next.cliOutput` won't have access to runtime logs we can refactor this test to render text on the page instead. --- test/deploy-tests-manifest.json | 1 - test/e2e/revalidate-reason/pages/index.tsx | 6 +++--- test/e2e/revalidate-reason/pages/stale.tsx | 6 +++--- test/e2e/revalidate-reason/revalidate-reason.test.ts | 12 ++++-------- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/test/deploy-tests-manifest.json b/test/deploy-tests-manifest.json index 886fcdda1a615..612d73460d3d1 100644 --- a/test/deploy-tests-manifest.json +++ b/test/deploy-tests-manifest.json @@ -50,7 +50,6 @@ "test/e2e/new-link-behavior/stitches.test.ts", "test/e2e/next-image-forward-ref/index.test.ts", "test/e2e/react-compiler/react-compiler.test.ts", - "test/e2e/revalidate-reason/revalidate-reason.test.ts", "test/e2e/app-dir/actions/app-action.test.ts", "test/e2e/app-dir/i18n-hybrid/i18n-hybrid.test.js", "test/e2e/app-dir/metadata/metadata.test.ts", diff --git a/test/e2e/revalidate-reason/pages/index.tsx b/test/e2e/revalidate-reason/pages/index.tsx index 0e42d22ada567..cc644a7123930 100644 --- a/test/e2e/revalidate-reason/pages/index.tsx +++ b/test/e2e/revalidate-reason/pages/index.tsx @@ -7,11 +7,11 @@ export async function getStaticProps({ params, revalidateReason }) { ) return { props: { - hello: 'world', + reason: revalidateReason, }, } } -export default ({ hello }) => { - return

hello: {hello}

+export default ({ reason }) => { + return

revalidate reason: {reason}

} diff --git a/test/e2e/revalidate-reason/pages/stale.tsx b/test/e2e/revalidate-reason/pages/stale.tsx index 62b9848b2063d..a898161096775 100644 --- a/test/e2e/revalidate-reason/pages/stale.tsx +++ b/test/e2e/revalidate-reason/pages/stale.tsx @@ -7,12 +7,12 @@ export async function getStaticProps({ params, revalidateReason }) { ) return { props: { - hello: 'world', + reason: revalidateReason, }, revalidate: 5, } } -export default ({ hello }) => { - return

hello: {hello}

+export default ({ reason }) => { + return

revalidate reason: {reason}

} diff --git a/test/e2e/revalidate-reason/revalidate-reason.test.ts b/test/e2e/revalidate-reason/revalidate-reason.test.ts index 6de92cf44dce5..cc4485ba90f33 100644 --- a/test/e2e/revalidate-reason/revalidate-reason.test.ts +++ b/test/e2e/revalidate-reason/revalidate-reason.test.ts @@ -38,9 +38,8 @@ describe('revalidate-reason', () => { expect(res.status).toBe(200) - expect(next.cliOutput).toContain( - 'revalidate-reason/pages/index.tsx revalidateReason: on-demand' - ) + const $ = await next.render$('/') + expect($('#reason').text()).toBe('revalidate reason: on-demand') }) it('should support revalidateReason: "stale"', async () => { @@ -51,11 +50,8 @@ describe('revalidate-reason', () => { await waitFor(5000) await retry(async () => { - await next.fetch('/stale') - - expect(next.cliOutput).toContain( - 'revalidate-reason/pages/stale.tsx revalidateReason: stale' - ) + const $ = await next.render$('/stale') + expect($('#reason').text()).toBe('revalidate reason: stale') }) }) }) From 918af1667aa0770088446952bc607b9a972e6128 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Thu, 13 Jun 2024 08:57:50 -0700 Subject: [PATCH 60/60] fix parallel-routes-revalidation deploy test (#66831) These 2 tests use an in-memory data store that won't be necessarily shared across invocations of the lambda. This skips the tests that rely on that functionality as testing it in `next start` should be sufficient. --- test/deploy-tests-manifest.json | 1 - .../parallel-routes-revalidation.test.ts | 88 ++++++++++--------- 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/test/deploy-tests-manifest.json b/test/deploy-tests-manifest.json index 612d73460d3d1..65f9c6670bbfc 100644 --- a/test/deploy-tests-manifest.json +++ b/test/deploy-tests-manifest.json @@ -43,7 +43,6 @@ "test/e2e/app-dir/actions-navigation/index.test.ts", "test/e2e/app-dir/app-static/app-static-custom-handler.test.ts", "test/e2e/app-dir/options-request/options-request.test.ts", - "test/e2e/app-dir/parallel-routes-revalidation/parallel-routes-revalidation.test.ts", "test/e2e/app-dir/revalidate-dynamic/revalidate-dynamic.test.ts", "test/e2e/app-dir/scss/npm-import-nested/npm-import-nested.test.ts", "test/e2e/app-dir/syntax-highlighter-crash/syntax-highlighter-crash.test.ts", diff --git a/test/e2e/app-dir/parallel-routes-revalidation/parallel-routes-revalidation.test.ts b/test/e2e/app-dir/parallel-routes-revalidation/parallel-routes-revalidation.test.ts index bb61d0a4a86c2..257a02b897805 100644 --- a/test/e2e/app-dir/parallel-routes-revalidation/parallel-routes-revalidation.test.ts +++ b/test/e2e/app-dir/parallel-routes-revalidation/parallel-routes-revalidation.test.ts @@ -2,43 +2,46 @@ import { nextTestSetup } from 'e2e-utils' import { check, retry } from 'next-test-utils' describe('parallel-routes-revalidation', () => { - const { next, isNextStart } = nextTestSetup({ + const { next, isNextStart, isNextDeploy } = nextTestSetup({ files: __dirname, }) - it('should submit the action and revalidate the page data', async () => { - const browser = await next.browser('/') - await check(() => browser.hasElementByCssSelector('#create-entry'), false) + // This test is skipped when deployed as it relies on a shared data store + // For testing purposes we just use an in-memory object, but when deployed + // this could hit a separate lambda instance that won't share the same reference + if (!isNextDeploy) { + it('should submit the action and revalidate the page data', async () => { + const browser = await next.browser('/') + await check(() => browser.hasElementByCssSelector('#create-entry'), false) - // there shouldn't be any data yet - expect((await browser.elementsByCss('#entries li')).length).toBe(0) + // there shouldn't be any data yet + expect((await browser.elementsByCss('#entries li')).length).toBe(0) - await browser.elementByCss("[href='/revalidate-modal']").click() + await browser.elementByCss("[href='/revalidate-modal']").click() - await check(() => browser.hasElementByCssSelector('#create-entry'), true) + await check(() => browser.hasElementByCssSelector('#create-entry'), true) - await browser.elementById('create-entry').click() + await browser.elementById('create-entry').click() - // we created an entry and called revalidate, so we should have 1 entry - await check( - async () => (await browser.elementsByCss('#entries li')).length, - 1 - ) + // we created an entry and called revalidate, so we should have 1 entry + await retry(async () => { + expect((await browser.elementsByCss('#entries li')).length).toBe(1) + }) - await browser.elementById('create-entry').click() + await browser.elementById('create-entry').click() - // we created an entry and called revalidate, so we should have 2 entries - await check( - async () => (await browser.elementsByCss('#entries li')).length, - 2 - ) + // we created an entry and called revalidate, so we should have 2 entries + await retry(async () => { + expect((await browser.elementsByCss('#entries li')).length).toBe(2) + }) - await browser.elementByCss("[href='/']").click() + await browser.elementByCss("[href='/']").click() - // following a link back to `/` should close the modal - await check(() => browser.hasElementByCssSelector('#create-entry'), false) - await check(() => browser.elementByCss('body').text(), /Current Data/) - }) + // following a link back to `/` should close the modal + await check(() => browser.hasElementByCssSelector('#create-entry'), false) + await check(() => browser.elementByCss('body').text(), /Current Data/) + }) + } it('should handle router.refresh() when called in a slot', async () => { const browser = await next.browser('/') @@ -182,28 +185,33 @@ describe('parallel-routes-revalidation', () => { ) }) - it('should refresh the correct page when a server action triggers a redirect', async () => { - const browser = await next.browser('/redirect') - await browser.elementByCss('button').click() + // This test is skipped when deployed as it relies on a shared data store + // For testing purposes we just use an in-memory object, but when deployed + // this could hit a separate lambda instance that won't share the same reference + if (!isNextDeploy) { + it('should refresh the correct page when a server action triggers a redirect', async () => { + const browser = await next.browser('/redirect') + await browser.elementByCss('button').click() - await browser.elementByCss("[href='/revalidate-modal']").click() + await browser.elementByCss("[href='/revalidate-modal']").click() - await check(() => browser.hasElementByCssSelector('#create-entry'), true) + await check(() => browser.hasElementByCssSelector('#create-entry'), true) - await browser.elementById('clear-entries').click() + await browser.elementById('clear-entries').click() - await retry(async () => { - // confirm there aren't any entries yet - expect((await browser.elementsByCss('#entries li')).length).toBe(0) - }) + await retry(async () => { + // confirm there aren't any entries yet + expect((await browser.elementsByCss('#entries li')).length).toBe(0) + }) - await browser.elementById('create-entry').click() + await browser.elementById('create-entry').click() - await retry(async () => { - // we created an entry and called revalidate, so we should have 1 entry - expect((await browser.elementsByCss('#entries li')).length).toBe(1) + await retry(async () => { + // we created an entry and called revalidate, so we should have 1 entry + expect((await browser.elementsByCss('#entries li')).length).toBe(1) + }) }) - }) + } describe.each([ { basePath: '/refreshing', label: 'regular', withSearchParams: false },