From c79b67ccedda1ae6fd9d05cfccf1d2842b94f43f Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Wed, 17 Aug 2022 12:56:52 +0200 Subject: [PATCH 01/64] Improved server CSS handling (#39664) Upgrade experimental React, and render link tags directly in the tree during development. The client bundle won't import CSS anymore, and server CSS imports will be transpiled into no-op strings just for HMR to use. ## Follow Ups - [ ] Flash of unstyled elements when reloading styles - [ ] Collect client style imports - [ ] Console warning for duplicated resources - [ ] Tests ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm lint` - [ ] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples) --- package.json | 4 +- .../build/webpack/config/blocks/css/index.ts | 35 ++++-- .../next-flight-client-entry-loader.ts | 6 +- .../loaders/next-flight-css-dev-loader.ts | 16 +++ packages/next/server/app-render.tsx | 101 ++++++------------ .../next/server/node-web-streams-helper.ts | 7 +- pnpm-lock.yaml | 24 ++--- .../app-dir/app/app/css/css-page/style.css | 2 +- test/e2e/app-dir/app/app/css/style.css | 2 +- test/e2e/app-dir/app/app/style.css | 3 + 10 files changed, 99 insertions(+), 101 deletions(-) create mode 100644 packages/next/build/webpack/loaders/next-flight-css-dev-loader.ts diff --git a/package.json b/package.json index 698760d043cf..fbc7d8c6f297 100644 --- a/package.json +++ b/package.json @@ -177,8 +177,8 @@ "react-17": "npm:react@17.0.2", "react-dom": "18.2.0", "react-dom-17": "npm:react-dom@17.0.2", - "react-dom-exp": "npm:react-dom@0.0.0-experimental-4cd788aef-20220630", - "react-exp": "npm:react@0.0.0-experimental-4cd788aef-20220630", + "react-dom-exp": "npm:react-dom@0.0.0-experimental-6ef466c68-20220816", + "react-exp": "npm:react@0.0.0-experimental-6ef466c68-20220816", "react-ssr-prepass": "1.0.8", "react-virtualized": "9.22.3", "relay-compiler": "13.0.2", diff --git a/packages/next/build/webpack/config/blocks/css/index.ts b/packages/next/build/webpack/config/blocks/css/index.ts index 1177e746a649..2585a2202262 100644 --- a/packages/next/build/webpack/config/blocks/css/index.ts +++ b/packages/next/build/webpack/config/blocks/css/index.ts @@ -275,16 +275,31 @@ export const css = curry(async function css( } if (ctx.isServer) { - fns.push( - loader({ - oneOf: [ - markRemovable({ - test: [regexCssGlobal, regexSassGlobal], - use: require.resolve('next/dist/compiled/ignore-loader'), - }), - ], - }) - ) + if (ctx.experimental.appDir && !ctx.isProduction) { + fns.push( + loader({ + oneOf: [ + markRemovable({ + test: [regexCssGlobal, regexSassGlobal], + use: require.resolve( + '../../../loaders/next-flight-css-dev-loader' + ), + }), + ], + }) + ) + } else { + fns.push( + loader({ + oneOf: [ + markRemovable({ + test: [regexCssGlobal, regexSassGlobal], + use: require.resolve('next/dist/compiled/ignore-loader'), + }), + ], + }) + ) + } } else { fns.push( loader({ diff --git a/packages/next/build/webpack/loaders/next-flight-client-entry-loader.ts b/packages/next/build/webpack/loaders/next-flight-client-entry-loader.ts index e30d5037569d..f168350122d8 100644 --- a/packages/next/build/webpack/loaders/next-flight-client-entry-loader.ts +++ b/packages/next/build/webpack/loaders/next-flight-client-entry-loader.ts @@ -21,7 +21,11 @@ export default async function transformSource(this: any): Promise { requests // Filter out css files on the server .filter((request) => (isServer ? !request.endsWith('.css') : true)) - .map((request) => `import(/* webpackMode: "eager" */ '${request}')`) + .map((request) => + request.endsWith('.css') + ? `(() => import(/* webpackMode: "lazy" */ '${request}'))` + : `import(/* webpackMode: "eager" */ '${request}')` + ) .join(';\n') + ` export const __next_rsc__ = { diff --git a/packages/next/build/webpack/loaders/next-flight-css-dev-loader.ts b/packages/next/build/webpack/loaders/next-flight-css-dev-loader.ts new file mode 100644 index 000000000000..d2f9ab521466 --- /dev/null +++ b/packages/next/build/webpack/loaders/next-flight-css-dev-loader.ts @@ -0,0 +1,16 @@ +/** + * For server-side CSS imports, we need to ignore the actual module content but + * still trigger the hot-reloading diff mechanism. So here we put the content + * inside a comment. + */ + +const NextServerCSSLoader = function (this: any, source: string | Buffer) { + this.cacheable && this.cacheable() + + return `export default "${(typeof source === 'string' + ? Buffer.from(source) + : source + ).toString('hex')}"` +} + +export default NextServerCSSLoader diff --git a/packages/next/server/app-render.tsx b/packages/next/server/app-render.tsx index 6ae16e35cc0b..2c221e3e75e7 100644 --- a/packages/next/server/app-render.tsx +++ b/packages/next/server/app-render.tsx @@ -378,55 +378,26 @@ function getSegmentParam(segment: string): { /** * Get inline tags based on server CSS manifest. Only used when rendering to HTML. */ -// function getCssInlinedLinkTags( -// serverComponentManifest: FlightManifest, -// serverCSSManifest: FlightCSSManifest, -// filePath: string -// ): string[] { -// const layoutOrPageCss = serverCSSManifest[filePath] - -// if (!layoutOrPageCss) { -// return [] -// } - -// const chunks = new Set() +function getCssInlinedLinkTags( + serverComponentManifest: FlightManifest, + serverCSSManifest: FlightCSSManifest, + filePath: string +): string[] { + const layoutOrPageCss = serverCSSManifest[filePath] -// for (const css of layoutOrPageCss) { -// for (const chunk of serverComponentManifest[css].default.chunks) { -// chunks.add(chunk) -// } -// } + if (!layoutOrPageCss) { + return [] + } -// return [...chunks] -// } + const chunks = new Set() -/** - * Get inline tags based on server CSS manifest. Only used when rendering to HTML. - */ -function getAllCssInlinedLinkTags( - serverComponentManifest: FlightManifest, - serverCSSManifest: FlightCSSManifest -): string[] { - const chunks: { [file: string]: string[] } = {} - - // APP-TODO: Remove this once we have CSS injections at each level. - const allChunks = new Set() - - for (const layoutOrPage in serverCSSManifest) { - const uniqueChunks = new Set() - for (const css of serverCSSManifest[layoutOrPage]) { - for (const chunk of serverComponentManifest[css].default.chunks) { - if (!uniqueChunks.has(chunk)) { - uniqueChunks.add(chunk) - chunks[layoutOrPage] = chunks[layoutOrPage] || [] - chunks[layoutOrPage].push(chunk) - } - allChunks.add(chunk) - } + for (const css of layoutOrPageCss) { + for (const chunk of serverComponentManifest[css].default.chunks) { + chunks.add(chunk) } } - return [...allChunks] + return [...chunks] } export async function renderToHTMLOrFlight( @@ -618,29 +589,23 @@ export async function renderToHTMLOrFlight( */ const createComponentTree = async ({ createSegmentPath, - loaderTree: [ - segment, - parallelRoutes, - { /* filePath, */ layout, loading, page }, - ], + loaderTree: [segment, parallelRoutes, { filePath, layout, loading, page }], parentParams, firstItem, rootLayoutIncluded, - }: // parentSegmentPath, - { + }: { createSegmentPath: CreateSegmentPath loaderTree: LoaderTree parentParams: { [key: string]: any } rootLayoutIncluded?: boolean firstItem?: boolean - // parentSegmentPath: string }): Promise<{ Component: React.ComponentType }> => { // TODO-APP: enable stylesheet per layout/page - // const stylesheets = getCssInlinedLinkTags( - // serverComponentManifest, - // serverCSSManifest!, - // filePath - // ) + const stylesheets = getCssInlinedLinkTags( + serverComponentManifest, + serverCSSManifest!, + filePath + ) const Loading = loading ? await interopDefault(loading()) : undefined const isLayout = typeof layout !== 'undefined' const isPage = typeof page !== 'undefined' @@ -719,7 +684,6 @@ export async function renderToHTMLOrFlight( loaderTree: parallelRoutes[parallelRouteKey], parentParams: currentParams, rootLayoutIncluded: rootLayoutIncludedAtThisLevelOrAbove, - // parentSegmentPath: cssSegmentPath, }) const childSegment = parallelRoutes[parallelRouteKey][0] @@ -860,11 +824,20 @@ export async function renderToHTMLOrFlight( return ( <> - {/* {stylesheets + {stylesheets ? stylesheets.map((href) => ( - + )) - : null} */} + : null} child, loaderTree: loaderTree, parentParams: {}, firstItem: true, - // parentSegmentPath: '', }) // AppRouter is provided by next-app-loader @@ -1108,7 +1074,6 @@ export async function renderToHTMLOrFlight( generateStaticHTML: generateStaticHTML, flushEffectHandler, flushEffectsToHead: true, - initialStylesheets, }) } diff --git a/packages/next/server/node-web-streams-helper.ts b/packages/next/server/node-web-streams-helper.ts index 65044c328e2a..2ffaaf5bf131 100644 --- a/packages/next/server/node-web-streams-helper.ts +++ b/packages/next/server/node-web-streams-helper.ts @@ -265,14 +265,12 @@ export async function continueFromInitialStream( generateStaticHTML, flushEffectHandler, flushEffectsToHead, - initialStylesheets, }: { suffix?: string dataStream?: ReadableStream generateStaticHTML: boolean flushEffectHandler?: () => string flushEffectsToHead: boolean - initialStylesheets?: string[] } ): Promise> { const closeTag = '' @@ -291,14 +289,11 @@ export async function continueFromInitialStream( dataStream ? createInlineDataStream(dataStream) : null, suffixUnclosed != null ? createSuffixStream(closeTag) : null, createHeadInjectionTransformStream(() => { - const inlineStyleLinks = (initialStylesheets || []) - .map((href) => ``) - .join('') // TODO-APP: Inject flush effects to end of head in app layout rendering, to avoid // hydration errors. Remove this once it's ready to be handled by react itself. const flushEffectsContent = flushEffectHandler && flushEffectsToHead ? flushEffectHandler() : '' - return inlineStyleLinks + flushEffectsContent + return flushEffectsContent }), ].filter(nonNullable) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 70af320d27c8..d23d5008f024 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -140,8 +140,8 @@ importers: react-17: npm:react@17.0.2 react-dom: 18.2.0 react-dom-17: npm:react-dom@17.0.2 - react-dom-exp: npm:react-dom@0.0.0-experimental-4cd788aef-20220630 - react-exp: npm:react@0.0.0-experimental-4cd788aef-20220630 + react-dom-exp: npm:react-dom@0.0.0-experimental-6ef466c68-20220816 + react-exp: npm:react@0.0.0-experimental-6ef466c68-20220816 react-ssr-prepass: 1.0.8 react-virtualized: 9.22.3 relay-compiler: 13.0.2 @@ -294,8 +294,8 @@ importers: react-17: /react/17.0.2 react-dom: 18.2.0_react@18.2.0 react-dom-17: /react-dom/17.0.2_react@18.2.0 - react-dom-exp: /react-dom/0.0.0-experimental-4cd788aef-20220630_react@18.2.0 - react-exp: /react/0.0.0-experimental-4cd788aef-20220630 + react-dom-exp: /react-dom/0.0.0-experimental-6ef466c68-20220816_react@18.2.0 + react-exp: /react/0.0.0-experimental-6ef466c68-20220816 react-ssr-prepass: 1.0.8_qncsgtzehe3fgiqp6tr7lwq6fm react-virtualized: 9.22.3_biqbaboplfbrettd7655fr4n2y relay-compiler: 13.0.2 @@ -18138,14 +18138,14 @@ packages: strip-json-comments: 2.0.1 dev: true - /react-dom/0.0.0-experimental-4cd788aef-20220630_react@18.2.0: - resolution: {integrity: sha512-VN80AwDQ19WbcX70m/3/ho/eahBIMVsrxbP7C0KU/tNe6BRwc7+QzvdDxSb2CwLlk/MZrOansFpQYEefn90w9Q==} + /react-dom/0.0.0-experimental-6ef466c68-20220816_react@18.2.0: + resolution: {integrity: sha512-OSHyYEL5s/Wbxe0ksihDOGLKUbmqT+FeYmZ8U6upTg+V6VIDLcgolzBWbP/QXwvjR99Qc5vhb2kHHXb2zYOnJw==} peerDependencies: - react: 0.0.0-experimental-4cd788aef-20220630 + react: 0.0.0-experimental-6ef466c68-20220816 dependencies: loose-envify: 1.4.0 react: 18.2.0 - scheduler: 0.0.0-experimental-4cd788aef-20220630 + scheduler: 0.0.0-experimental-6ef466c68-20220816 dev: true /react-dom/17.0.2_react@18.2.0: @@ -18229,8 +18229,8 @@ packages: react-lifecycles-compat: 3.0.4 dev: true - /react/0.0.0-experimental-4cd788aef-20220630: - resolution: {integrity: sha512-mPez9MeF8whDoKAtz7bGvwOWn3THEzZvftQAGAlzrohcszPDOyq1GEc3sFLKDZTSgRzVzALXcfaVoJ0EqWcgnw==} + /react/0.0.0-experimental-6ef466c68-20220816: + resolution: {integrity: sha512-UixkYaiwN2Ep7tqRATjwc7sFsk4cEi6t7KLAZ7MwlZI/3+ZGPk5f1J7/YvLU7STncEY2NC6GDyVgNmrK8Ov77g==} engines: {node: '>=0.10.0'} dependencies: loose-envify: 1.4.0 @@ -19226,8 +19226,8 @@ packages: xmlchars: 2.2.0 dev: true - /scheduler/0.0.0-experimental-4cd788aef-20220630: - resolution: {integrity: sha512-ywbmX5l/JpTWQbUy9IcHO0fzaHGL/IIgM5lj1IsJA0KYn3IZx6fJkXiVRFFY1GuXAsLsalniC+SM5NLjUED8fg==} + /scheduler/0.0.0-experimental-6ef466c68-20220816: + resolution: {integrity: sha512-3d6wgYQA2rFc62tqtEPJdnd0rxfq8VTk8Toj3v7LEdZ4vB3pACNxthU3E3WPDtXbHAUQ+liMgFwuXxeE+8aDhg==} dependencies: loose-envify: 1.4.0 dev: true diff --git a/test/e2e/app-dir/app/app/css/css-page/style.css b/test/e2e/app-dir/app/app/css/css-page/style.css index 61083abf180c..adc68fa6a4df 100644 --- a/test/e2e/app-dir/app/app/css/css-page/style.css +++ b/test/e2e/app-dir/app/app/css/css-page/style.css @@ -1,3 +1,3 @@ h1 { - color: blueviolet; + color: red; } diff --git a/test/e2e/app-dir/app/app/css/style.css b/test/e2e/app-dir/app/app/css/style.css index efd81fda0528..26994cdddaee 100644 --- a/test/e2e/app-dir/app/app/css/style.css +++ b/test/e2e/app-dir/app/app/css/style.css @@ -1,3 +1,3 @@ .server-css { - color: green; + color: blue; } diff --git a/test/e2e/app-dir/app/app/style.css b/test/e2e/app-dir/app/app/style.css index e69de29bb2d1..0b8fbd008481 100644 --- a/test/e2e/app-dir/app/app/style.css +++ b/test/e2e/app-dir/app/app/style.css @@ -0,0 +1,3 @@ +body { + font-size: xx-large; +} From ab152918ad5c702eb80455ba2f866ec04f903b04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Wed, 17 Aug 2022 20:21:57 +0900 Subject: [PATCH 02/64] feat(next-swc): Update swc (#39499) This PR applies - https://github.com/swc-project/swc/pull/5487 - Closes https://github.com/vercel/next.js/issues/39538 - https://github.com/swc-project/swc/pull/5485 - Closes https://github.com/vercel/next.js/issues/39412 - https://github.com/swc-project/swc/pull/5498 - Closes https://github.com/vercel/next.js/issues/39360 --- packages/next-swc/Cargo.lock | 211 +++++++++--------- packages/next-swc/crates/core/Cargo.toml | 18 +- .../core/tests/full/auto-cjs/1/output.js | 8 +- .../crates/core/tests/full/example/output.js | 60 ++--- packages/next-swc/crates/emotion/Cargo.toml | 15 +- .../next-swc/crates/emotion/tests/fixture.rs | 6 +- .../crates/modularize_imports/Cargo.toml | 10 +- packages/next-swc/crates/napi/Cargo.toml | 14 +- .../crates/styled_components/Cargo.toml | 14 +- .../next-swc/crates/styled_jsx/Cargo.toml | 14 +- packages/next-swc/crates/wasm/Cargo.toml | 8 +- 11 files changed, 189 insertions(+), 189 deletions(-) diff --git a/packages/next-swc/Cargo.lock b/packages/next-swc/Cargo.lock index 18b43ccfe5c1..52433026a068 100644 --- a/packages/next-swc/Cargo.lock +++ b/packages/next-swc/Cargo.lock @@ -1481,7 +1481,7 @@ dependencies = [ [[package]] name = "modularize_imports" -version = "0.14.0" +version = "0.15.0" dependencies = [ "convert_case", "handlebars", @@ -2334,9 +2334,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "1f08c8062c1fe1253064043b8fc07bfea1b9702b71b4a86c11ea3588183b12e1" dependencies = [ "bytecheck", "hashbrown 0.12.1", @@ -2348,9 +2348,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "e289706df51226e84814bf6ba1a9e1013112ae29bc7a9878f73fce360520c403" dependencies = [ "proc-macro2", "quote", @@ -2899,7 +2899,7 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "styled_components" -version = "0.39.0" +version = "0.40.0" dependencies = [ "Inflector", "once_cell", @@ -2916,7 +2916,7 @@ dependencies = [ [[package]] name = "styled_jsx" -version = "0.14.0" +version = "0.15.0" dependencies = [ "easy-error", "swc_common", @@ -2964,9 +2964,9 @@ dependencies = [ [[package]] name = "swc" -version = "0.212.1" +version = "0.214.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6860819497adc7ffbda33061e0d6a36672212c6e623257927a088aa74116490a" +checksum = "66de60ec56727a44e40752aa324bb02a67467d941f60c37be99ad11fbb61446c" dependencies = [ "ahash", "anyhow", @@ -3002,7 +3002,6 @@ dependencies = [ "swc_ecma_transforms_optimization", "swc_ecma_utils", "swc_ecma_visit", - "swc_ecmascript", "swc_error_reporters", "swc_node_comments", "swc_plugin_proxy", @@ -3014,9 +3013,9 @@ dependencies = [ [[package]] name = "swc_atoms" -version = "0.3.1" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66e252fe697709a0fc8710b5b9dee2d72fd9852d3f5fd1a057ce808b6987ccba" +checksum = "454bf2d73485f6c4af9c91e70ce4fd4f17e9294d37b9f2037a3c4c2fe54b598d" dependencies = [ "bytecheck", "once_cell", @@ -3029,9 +3028,9 @@ dependencies = [ [[package]] name = "swc_bundler" -version = "0.175.0" +version = "0.177.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "181676693d25b6e1b3992f1a13cf4e5bca78bf5482d4f2ee7333796dd9ca21b2" +checksum = "b8f7d7f3b5b735aee329ed2b7a117d8e4163d4d3410bfe2b19db9b21fa398115" dependencies = [ "ahash", "anyhow", @@ -3063,9 +3062,9 @@ dependencies = [ [[package]] name = "swc_cached" -version = "0.2.0" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91448e2c3ee24c65d51c0956b62f94420c9d19e7fa9e990010072d5e05a81a51" +checksum = "395389d54bea607246bb4a400b9b3df2e55adfe8fcce7965a5b99fed7816cf4d" dependencies = [ "ahash", "anyhow", @@ -3078,9 +3077,9 @@ dependencies = [ [[package]] name = "swc_common" -version = "0.26.0" +version = "0.27.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7b3ce2fcc4e51ffb3e0556f04bf50e6cdeaaab9b019282f68acb2311c4b75f8" +checksum = "056ad401259d209007ecc55d18b2a539091eed3315846e1d923140499af08aed" dependencies = [ "ahash", "anyhow", @@ -3138,9 +3137,9 @@ dependencies = [ [[package]] name = "swc_css" -version = "0.116.0" +version = "0.120.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3aeaff3b0bc11139757bf67bf3bb1afacec05ee58d5b316f1d957b3a78db452" +checksum = "3d3025a9f4c123dfc5976940e9aa986ff06162f5e9b81601fa34dfab9bcc734d" dependencies = [ "swc_css_ast", "swc_css_codegen", @@ -3151,9 +3150,9 @@ dependencies = [ [[package]] name = "swc_css_ast" -version = "0.103.0" +version = "0.107.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "543026fef8a5f4147d944072eac313f5dd4633086a3b26b2e2b1f08384d369bd" +checksum = "102e00c896dcbbd27f079df342f65ad685a3652ff20c93f8980380956bdc02e4" dependencies = [ "is-macro", "serde", @@ -3164,9 +3163,9 @@ dependencies = [ [[package]] name = "swc_css_codegen" -version = "0.113.0" +version = "0.117.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a932c9750eed830a0e4c8b64a8e084c0adfc23356846e8fcc66a302bf3ead27e" +checksum = "5ea1374bffa56f07d14184d0ed7de1725d71c44c5e10d13347ba58e3b87dad5f" dependencies = [ "auto_impl", "bitflags", @@ -3193,9 +3192,9 @@ dependencies = [ [[package]] name = "swc_css_parser" -version = "0.112.0" +version = "0.116.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d36dc5fba19a61d395cddb6fe2f9736f1a192c45fbced6f37c6a3ad3593db0b8" +checksum = "98db1b019681e34f3b5755d1f8e79c1716ceb77eda78219f9ee1cf95c6dfbda7" dependencies = [ "bitflags", "lexical", @@ -3207,9 +3206,9 @@ dependencies = [ [[package]] name = "swc_css_prefixer" -version = "0.113.3" +version = "0.117.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3393413633e283959aad05d8943c896729cc0d9cf31a37b213460748d1eff4c4" +checksum = "b89e03bf686929c74567627055f73525794de6002143f20540c6a2d7185634d6" dependencies = [ "once_cell", "preset_env_base", @@ -3224,9 +3223,9 @@ dependencies = [ [[package]] name = "swc_css_utils" -version = "0.100.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3625a87b24e56d84fa87d993d560fb68867d07c2ded754c45135f4cd02dbdd4" +checksum = "4123740701151259c69a4b7ba151efa630ae241111de7564f288059fa3768290" dependencies = [ "once_cell", "serde", @@ -3239,9 +3238,9 @@ dependencies = [ [[package]] name = "swc_css_visit" -version = "0.102.0" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99f41381173f2371013e79304dadfd42c1b90f5bbc05129e85314a301890cc93" +checksum = "24688aa5b9533715d0f3443ff25b08eb16eddf045dd9a857dc6893fb409f3487" dependencies = [ "serde", "swc_atoms", @@ -3252,9 +3251,9 @@ dependencies = [ [[package]] name = "swc_ecma_ast" -version = "0.89.0" +version = "0.90.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce996d6d808785508fd33c252de3fa403cb1c7dd8716898d65eabeb7bfe341f" +checksum = "e4d9cb0825962e9f9baabec6270aeb6e7c21ade1a16d707916186ad5f13126d1" dependencies = [ "bitflags", "bytecheck", @@ -3271,9 +3270,9 @@ dependencies = [ [[package]] name = "swc_ecma_codegen" -version = "0.120.0" +version = "0.121.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a1b0c1a7325b011e2873de47dc862a805d39b975efa117a9f6c196e30a0d99b" +checksum = "2b0bf7259fec5655df5163eafe0fabe4619f1d507b4c19a8b2be8a9ea2c806ff" dependencies = [ "memchr", "num-bigint", @@ -3303,9 +3302,9 @@ dependencies = [ [[package]] name = "swc_ecma_ext_transforms" -version = "0.84.0" +version = "0.85.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2d13bef6e69fe871b780cc44dc6802bb098d6503b1e9873c04e8baec6e87a0" +checksum = "4f19eb16fed54a740f92e9cb2d6ee79fc69b4a3b63d4a467c709693a413f6737" dependencies = [ "phf", "swc_atoms", @@ -3317,9 +3316,9 @@ dependencies = [ [[package]] name = "swc_ecma_lints" -version = "0.57.0" +version = "0.58.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb20430ce0773f680eaa758317298ad927587bb3c204a0921aa4ddabee2fe9f4" +checksum = "931f3b19bad8a2d0e65eb2bf19771f92d6a0bf73a3b3f47f4a12c5c7259d9b85" dependencies = [ "ahash", "auto_impl", @@ -3338,9 +3337,9 @@ dependencies = [ [[package]] name = "swc_ecma_loader" -version = "0.38.0" +version = "0.39.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca95a8ebe9f6f815c35002523f0157367fec9856dcec868c7d3e27c3142954e9" +checksum = "ece6023a43222e3bd36e3d191fa5289c848245b97fbf0127d9c0923165648d18" dependencies = [ "ahash", "anyhow", @@ -3360,9 +3359,9 @@ dependencies = [ [[package]] name = "swc_ecma_minifier" -version = "0.142.1" +version = "0.144.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d047b57f9c0bcc220202750301bd66c003a242bae994e647da43b4269cec305f" +checksum = "244bf8e9472a7fc50466d3ab3a288969f82ab7d2547e445305f745c8c52ba384" dependencies = [ "ahash", "arrayvec", @@ -3371,7 +3370,6 @@ dependencies = [ "num_cpus", "once_cell", "parking_lot", - "rayon", "regex", "retain_mut", "rustc-hash", @@ -3395,9 +3393,9 @@ dependencies = [ [[package]] name = "swc_ecma_parser" -version = "0.116.0" +version = "0.117.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12740be040fa5635ac73bb38fd7340887d6b5f36e0daf4eaec662838398dd4eb" +checksum = "7a6f6a817020e88bd7084e516f67f40ef33640c1fe336e66cd0dcdeabdaa16eb" dependencies = [ "either", "enum_kind", @@ -3414,9 +3412,9 @@ dependencies = [ [[package]] name = "swc_ecma_preset_env" -version = "0.156.1" +version = "0.158.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "979e15b5b236e4a06da25cbf8b40723a709c45f9d9a70c0460ee7ae5658eec1d" +checksum = "ef62b25660684da925c7b53b1a4724bdaf1a8520a419ad736263b101ca4c9e1d" dependencies = [ "ahash", "anyhow", @@ -3439,9 +3437,9 @@ dependencies = [ [[package]] name = "swc_ecma_testing" -version = "0.13.0" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4531ecf7055a35aff99b4c668cd6e02d35e688bdb0c0c80a21805a8f0d25a636" +checksum = "871addc48b001e559cf74493d465e050b0c6ef244cf7b7112cd756b271d1beac" dependencies = [ "anyhow", "hex", @@ -3455,9 +3453,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms" -version = "0.181.0" +version = "0.183.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d0332a16280d0c0c37745fc85714d878867d490ee6747bfdfdcb6bebe80181f" +checksum = "2a8cbc090b992ae508db16c9ae38024195f5d5b39826f0a74d4091e410fbc045" dependencies = [ "swc_atoms", "swc_common", @@ -3475,16 +3473,15 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_base" -version = "0.102.0" +version = "0.103.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f8438e5cb7da4e6983117294b9d5dc911163ab221e12c8066a7a713a90c5734" +checksum = "c794bf556b57109e59ee694db25994b27dc5a632de745af40968b4f3e2622862" dependencies = [ "better_scoped_tls", "bitflags", "num_cpus", "once_cell", "phf", - "rayon", "rustc-hash", "serde", "smallvec", @@ -3499,9 +3496,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_classes" -version = "0.90.0" +version = "0.91.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3866400fe3f3959d7992ee5a37117b81def64f05db5e3f69b16ca4427c12ab6" +checksum = "f37ac07ffe2fd6704763cf6fb1ccf92ab9496ecec0cb28084775fe35d7d21665" dependencies = [ "swc_atoms", "swc_common", @@ -3513,9 +3510,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_compat" -version = "0.120.0" +version = "0.122.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96534f3661295f3ffdb64408a1f734c6d653f3ebf832ca0e12bdefae960c564" +checksum = "f6127cdb1a52d720a1559d1365ea1682de8189612b979be95b12ac17eb0f3c83" dependencies = [ "ahash", "arrayvec", @@ -3553,9 +3550,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_module" -version = "0.137.0" +version = "0.139.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad4178bac22920d57cd5734171ab50f30a609731f9a53b6e8c16730e7ff19c7d" +checksum = "930bf6a0f0ee0a5fff8da817ae5f1652408714c7198a5f50ef018facdbe9be6f" dependencies = [ "Inflector", "ahash", @@ -3581,9 +3578,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_optimization" -version = "0.150.0" +version = "0.152.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c0267c4a9f9e7183f0411e1cbd16034dc5598e4ece5110c9a71b3b8565afac8" +checksum = "b3cd48bd97dd61b382bca4aa8b316b86364900e293e3e7bc19083e3e40551055" dependencies = [ "ahash", "dashmap", @@ -3604,9 +3601,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_proposal" -version = "0.128.0" +version = "0.130.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5edd3b87166df9cb23d2a393d565b886575f1808245b8791d5b5a1bddf36e4cb" +checksum = "c5431eff966464e9eb14e31a548fea6a8fb066c0ca13ea3f334c43533ae1f6c7" dependencies = [ "either", "serde", @@ -3623,9 +3620,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_react" -version = "0.139.0" +version = "0.141.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcfba7f0dcf32d4e82c89759bd1ff851e1bfa32493271e93d34ae7fbb583ff4d" +checksum = "e25a0fb253cc8f4c91f4f097aafb110baefda11bf3584bea1a034481cb929f22" dependencies = [ "ahash", "base64 0.13.0", @@ -3649,9 +3646,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_testing" -version = "0.104.0" +version = "0.105.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2db2a705493547cce9c2d8b14ab6041409eb995e19604f42c6fa44ef1852ccb" +checksum = "55a3f0a517e598284dff81299e07c0766b81c295a90f34fba60bb0e9b92bd385" dependencies = [ "ansi_term", "anyhow", @@ -3673,9 +3670,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_typescript" -version = "0.143.0" +version = "0.145.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5faef5ccddd09093faee514d65f6c24fe6c8ec9da184299f9c9780c4c7308" +checksum = "5ece3fe114e22ed4a1711bb1f23d2991b744f89e44c061d84063335421b8f2f2" dependencies = [ "serde", "swc_atoms", @@ -3689,9 +3686,9 @@ dependencies = [ [[package]] name = "swc_ecma_utils" -version = "0.98.0" +version = "0.99.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "996ae04dfb093db26874e1fbb82a5194e3cef562737c93b9674bdef539a7fba3" +checksum = "30700fb85603ce56423770d77696c1b0c602733a57d3b5cdd93a47ba450b0cd9" dependencies = [ "indexmap", "once_cell", @@ -3705,9 +3702,9 @@ dependencies = [ [[package]] name = "swc_ecma_visit" -version = "0.75.0" +version = "0.76.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1efa6716523365a6b947388cca7e4b3b59da046fd1d0200efc02bc3395e7f4" +checksum = "02cb4c2c4213d603543e7232db69e763a9292953db511b0ed5d1bf8c1b227b90" dependencies = [ "num-bigint", "swc_atoms", @@ -3719,9 +3716,9 @@ dependencies = [ [[package]] name = "swc_ecmascript" -version = "0.186.0" +version = "0.189.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c96e447b71b8d44d2100c9a07a116c2337e4ed66691e096b7c5fe0a6c72c8ba0" +checksum = "7b16deafbca757db8f8e26d0667f93e673a8bf51d99281fd09c83139c9d99818" dependencies = [ "swc_ecma_ast", "swc_ecma_codegen", @@ -3734,7 +3731,7 @@ dependencies = [ [[package]] name = "swc_emotion" -version = "0.16.0" +version = "0.17.0" dependencies = [ "base64 0.13.0", "byteorder", @@ -3747,6 +3744,7 @@ dependencies = [ "sourcemap", "swc_atoms", "swc_common", + "swc_ecma_transforms_react", "swc_ecma_transforms_testing", "swc_ecmascript", "swc_trace_macro", @@ -3756,9 +3754,9 @@ dependencies = [ [[package]] name = "swc_eq_ignore_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c8f200a2eaed938e7c1a685faaa66e6d42fa9e17da5f62572d3cbc335898f5e" +checksum = "0c20468634668c2bbab581947bb8c75c97158d5a6959f4ba33df20983b20b4f6" dependencies = [ "pmutil", "proc-macro2", @@ -3768,9 +3766,9 @@ dependencies = [ [[package]] name = "swc_error_reporters" -version = "0.10.0" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b592b6f61697db23879762715d9e7699408e07568cae15429e608569aaed4e28" +checksum = "bb0171a43e5d90cdea0efbf5844e3780f8650a22e4152b0c49549387d5f6b3da" dependencies = [ "anyhow", "miette", @@ -3781,9 +3779,9 @@ dependencies = [ [[package]] name = "swc_fast_graph" -version = "0.14.0" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da66c4b023903dd2eb060f7544bfff04d7a468151fca56762911700c58c20b92" +checksum = "f7b0ff4fa987b8722801a7789563b8cbc71058027f2f2cc4e7e95876a0cc4960" dependencies = [ "ahash", "indexmap", @@ -3793,9 +3791,9 @@ dependencies = [ [[package]] name = "swc_graph_analyzer" -version = "0.15.0" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c06279ebbfca0cc18be7748bd891e8b3efabfe7863727dd69d678797d8e317d" +checksum = "ba02e0726abddde48fecef483fb0b067c88a6c0da736b91d3ef424be3cfcaa39" dependencies = [ "ahash", "auto_impl", @@ -3828,9 +3826,9 @@ dependencies = [ [[package]] name = "swc_node_comments" -version = "0.13.0" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65544576b5610816f4e3725319d090296362d3ff6bd441f02efe3c4958f5e9e4" +checksum = "809a8d29020a11b0171f033110c9d0bd260b8797429f9e26672afd8353a14cce" dependencies = [ "ahash", "dashmap", @@ -3840,22 +3838,24 @@ dependencies = [ [[package]] name = "swc_plugin_proxy" -version = "0.17.0" +version = "0.18.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74358e4bdd1624ecce3f70274eecd3d87a7bfe4ef840a72e5a6e3f3c7c623bdc" +checksum = "1f4cbccf3bf3b808d10371c4e0890b7a5871926519077c0a343ada9b6012aa1e" dependencies = [ "better_scoped_tls", "bytecheck", "rkyv", "swc_common", "swc_ecma_ast", + "swc_trace_macro", + "tracing", ] [[package]] name = "swc_plugin_runner" -version = "0.70.0" +version = "0.71.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c909b1dc1dc0121027a1f252e6541c0158ae38218d2d889dbc9d4d0549312da9" +checksum = "a116a790c682e2acfaa674a80320d21fb6d8c22b07b9f0a66160f44d7cc08a44" dependencies = [ "anyhow", "once_cell", @@ -3873,18 +3873,18 @@ dependencies = [ [[package]] name = "swc_timer" -version = "0.14.0" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c47e4765a73706d163039811df0d946b85219585305295b8c44df6987a1093f9" +checksum = "f94c875f92763879d638174414a94762cd8f865d237ad75b34094c18395bc796" dependencies = [ "tracing", ] [[package]] name = "swc_trace_macro" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d1a05fdb40442d687cb2eff4e5c374886a66ced1436ad87515de7d72b3ec10b" +checksum = "a4795c8d23e0de62eef9cac0a20ae52429ee2ffc719768e838490f195b7d7267" dependencies = [ "proc-macro2", "quote", @@ -3893,9 +3893,9 @@ dependencies = [ [[package]] name = "swc_visit" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce1b826c9d4c0416bbed55d245c853bc1a60da55bf92f8b00dd22b37baf72080" +checksum = "b754ef01f2614eb469fd5215789bfd319566a3bf1033056d7a7bfb5a3c9a69f5" dependencies = [ "either", "swc_visit_macros", @@ -3903,9 +3903,9 @@ dependencies = [ [[package]] name = "swc_visit_macros" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fda2daf67d99e8bc63d61b12818994863f65b7bcf52d4faab338154c7058546" +checksum = "c230bcd129d1fbcd1decd8b43cccd613fda11c895f7c04d6c966231dbc1959af" dependencies = [ "Inflector", "pmutil", @@ -3967,9 +3967,9 @@ dependencies = [ [[package]] name = "testing" -version = "0.28.0" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7613b9cfb9d4f348bba45bb9425b5d5ea35165fdb79e131e8cdb5119f13c7fde" +checksum = "ee5d89dc2a392aab3a29a2d4e430e4ec3692fd3bd91d0a54bc092f4b8ea26d96" dependencies = [ "ansi_term", "difference", @@ -3986,12 +3986,13 @@ dependencies = [ [[package]] name = "testing_macros" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adfb26385ca4db3f8aa680824013819e3b9f8d9a1b64b4f83a411e09a61f11c3" +checksum = "e74ff09d2d4d4b7ea140ff67eb7ed8fd35a708e2c327bcde5a25707d66840099" dependencies = [ "anyhow", "glob", + "once_cell", "pmutil", "proc-macro2", "quote", diff --git a/packages/next-swc/crates/core/Cargo.toml b/packages/next-swc/crates/core/Cargo.toml index 85a6769395da..8f98805cf49b 100644 --- a/packages/next-swc/crates/core/Cargo.toml +++ b/packages/next-swc/crates/core/Cargo.toml @@ -26,18 +26,18 @@ swc_emotion = {path="../emotion"} styled_components = {path="../styled_components"} styled_jsx = {path="../styled_jsx"} modularize_imports = {path="../modularize_imports"} -swc = "0.212.1" -swc_atoms = "0.3.1" -swc_common = { version = "0.26.0", features = ["concurrent", "sourcemap", "plugin_transform_schema_v1"] } -swc_ecma_loader = { version = "0.38.0", features = ["node", "lru"] } -swc_ecmascript = { version = "0.186.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } -swc_plugin_runner = { version = "0.70.0", optional = true, default-features = false, features = ["plugin_transform_schema_v1"] } -swc_cached = "0.2.0" +swc = "0.214.9" +swc_atoms = "0.4.8" +swc_common = { version = "0.27.11", features = ["concurrent", "sourcemap", "plugin_transform_schema_v1"] } +swc_ecma_loader = { version = "0.39.4", features = ["node", "lru"] } +swc_ecmascript = { version = "0.189.4", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } +swc_plugin_runner = { version = "0.71.15", optional = true, default-features = false, features = ["plugin_transform_schema_v1"] } +swc_cached = "0.3.5" tracing = { version = "0.1.32", features = ["release_max_level_info"] } wasmer = { version = "2.3.0", optional = true, default-features = false } wasmer-wasi = { version = "2.3.0", optional = true, default-features = false } [dev-dependencies] -swc_ecma_transforms_testing = "0.104.0" -testing = "0.28.0" +swc_ecma_transforms_testing = "0.105.5" +testing = "0.29.4" walkdir = "2.3.2" diff --git a/packages/next-swc/crates/core/tests/full/auto-cjs/1/output.js b/packages/next-swc/crates/core/tests/full/auto-cjs/1/output.js index 183071cf9540..076c2fcf780f 100644 --- a/packages/next-swc/crates/core/tests/full/auto-cjs/1/output.js +++ b/packages/next-swc/crates/core/tests/full/auto-cjs/1/output.js @@ -2,9 +2,9 @@ Object.defineProperty(exports, "__esModule", { value: !0 }); -var a = function(a) { - return a && a.__esModule ? a : { - default: a +var e = function(e) { + return e && e.__esModule ? e : { + default: e }; }(require("esm")); -console.log(a.default.foo), module.exports = a.default; +console.log(e.default.foo), module.exports = e.default; diff --git a/packages/next-swc/crates/core/tests/full/example/output.js b/packages/next-swc/crates/core/tests/full/example/output.js index 03ada8af92ec..3f100a93d96b 100644 --- a/packages/next-swc/crates/core/tests/full/example/output.js +++ b/packages/next-swc/crates/core/tests/full/example/output.js @@ -1,47 +1,47 @@ -function a(a, b) { - (null == b || b > a.length) && (b = a.length); - for(var c = 0, d = new Array(b); c < b; c++)d[c] = a[c]; - return d; +function n(n, t) { + (null == t || t > n.length) && (t = n.length); + for(var r = 0, e = new Array(t); r < t; r++)e[r] = n[r]; + return e; } -import b from "other"; -(function(b, c) { - return function(a) { - if (Array.isArray(a)) return a; - }(b) || function(a, b) { - var c, d, e = null == a ? null : "undefined" != typeof Symbol && a[Symbol.iterator] || a["@@iterator"]; - if (null != e) { - var f = [], g = !0, h = !1; +import t from "other"; +(function(t, r) { + return function(n) { + if (Array.isArray(n)) return n; + }(t) || function(n, t) { + var r, e, o = null == n ? null : "undefined" != typeof Symbol && n[Symbol.iterator] || n["@@iterator"]; + if (null != o) { + var u = [], l = !0, f = !1; try { - for(e = e.call(a); !(g = (c = e.next()).done) && (f.push(c.value), !b || f.length !== b); g = !0); + for(o = o.call(n); !(l = (r = o.next()).done) && (u.push(r.value), !t || u.length !== t); l = !0); } catch (i) { - h = !0, d = i; + f = !0, e = i; } finally{ try { - g || null == e.return || e.return(); + l || null == o.return || o.return(); } finally{ - if (h) throw d; + if (f) throw e; } } - return f; + return u; } - }(b, c) || function b(c, d) { - if (c) { - if ("string" == typeof c) return a(c, d); - var e = Object.prototype.toString.call(c).slice(8, -1); - if ("Object" === e && c.constructor && (e = c.constructor.name), "Map" === e || "Set" === e) return Array.from(e); - if ("Arguments" === e || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)) return a(c, d); + }(t, r) || function t(r, e) { + if (r) { + if ("string" == typeof r) return n(r, e); + var o = Object.prototype.toString.call(r).slice(8, -1); + if ("Object" === o && r.constructor && (o = r.constructor.name), "Map" === o || "Set" === o) return Array.from(o); + if ("Arguments" === o || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(o)) return n(r, e); } - }(b, c) || function() { + }(t, r) || function() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }(); -})(b, 1)[0]; -var c = function() { +})(t, 1)[0]; +var r = function() { "use strict"; - !function(a, b) { - if (!(a instanceof b)) throw new TypeError("Cannot call a class as a function"); - }(this, c); + !function(n, t) { + if (!(n instanceof t)) throw new TypeError("Cannot call a class as a function"); + }(this, r); }; export var __N_SSG = !0; -export default function d() { +export default function e() { return React.createElement("div", null); }; diff --git a/packages/next-swc/crates/emotion/Cargo.toml b/packages/next-swc/crates/emotion/Cargo.toml index e81959d07ae2..2b38b85d2f87 100644 --- a/packages/next-swc/crates/emotion/Cargo.toml +++ b/packages/next-swc/crates/emotion/Cargo.toml @@ -5,7 +5,7 @@ description = "AST Transforms for emotion" license = "Apache-2.0" name = "swc_emotion" repository = "https://github.com/vercel/next.js.git" -version = "0.16.0" +version = "0.17.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -18,13 +18,14 @@ radix_fmt = "1" regex = "1.5" serde = "1" sourcemap = "6.0.1" -swc_atoms = "0.3.1" -swc_common = { version = "0.26.0", features = ["concurrent", "sourcemap"] } -swc_ecmascript = { version = "0.186.0", features = ["codegen", "utils", "visit"] } -swc_trace_macro = "0.1.1" +swc_atoms = "0.4.8" +swc_common = { version = "0.27.11", features = ["concurrent", "sourcemap"] } +swc_ecmascript = { version = "0.189.4", features = ["codegen", "utils", "visit"] } +swc_trace_macro = "0.1.2" tracing = { version = "0.1.32", features = ["release_max_level_info"] } [dev-dependencies] -swc_ecma_transforms_testing = "0.104.0" -testing = "0.28.0" +swc_ecma_transforms_testing = "0.105.5" +testing = "0.29.4" serde_json = "1" +swc_ecma_transforms_react = "0.141.4" diff --git a/packages/next-swc/crates/emotion/tests/fixture.rs b/packages/next-swc/crates/emotion/tests/fixture.rs index b50ca93e248d..d9f878f7e69c 100644 --- a/packages/next-swc/crates/emotion/tests/fixture.rs +++ b/packages/next-swc/crates/emotion/tests/fixture.rs @@ -2,10 +2,7 @@ use std::path::PathBuf; use swc_common::{chain, comments::SingleThreadedComments, Mark}; use swc_ecma_transforms_testing::test_fixture; -use swc_ecmascript::{ - parser::{Syntax, TsConfig}, - transforms::react::{jsx, Runtime}, -}; +use swc_ecmascript::parser::{Syntax, TsConfig}; use swc_emotion::EmotionOptions; use testing::fixture; @@ -15,6 +12,7 @@ fn ts_syntax() -> Syntax { ..Default::default() }) } +use swc_ecma_transforms_react::{jsx, Runtime}; #[fixture("tests/fixture/**/input.tsx")] fn next_emotion_fixture(input: PathBuf) { diff --git a/packages/next-swc/crates/modularize_imports/Cargo.toml b/packages/next-swc/crates/modularize_imports/Cargo.toml index 209795773e17..82f19725e0b7 100644 --- a/packages/next-swc/crates/modularize_imports/Cargo.toml +++ b/packages/next-swc/crates/modularize_imports/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" license = "Apache-2.0" name = "modularize_imports" repository = "https://github.com/vercel/next.js.git" -version = "0.14.0" +version = "0.15.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -15,9 +15,9 @@ handlebars = "4.2.1" once_cell = "1.13.0" regex = "1.5" serde = "1" -swc_cached = "0.2.0" -swc_ecmascript = { version = "0.186.0", features = ["visit"] } +swc_cached = "0.3.5" +swc_ecmascript = { version = "0.189.4", features = ["visit"] } [dev-dependencies] -swc_ecma_transforms_testing = "0.104.0" -testing = "0.28.0" +swc_ecma_transforms_testing = "0.105.5" +testing = "0.29.4" diff --git a/packages/next-swc/crates/napi/Cargo.toml b/packages/next-swc/crates/napi/Cargo.toml index 996e6aa5e280..e05340a4034f 100644 --- a/packages/next-swc/crates/napi/Cargo.toml +++ b/packages/next-swc/crates/napi/Cargo.toml @@ -33,13 +33,13 @@ next-swc = {version = "0.0.0", path = "../core"} once_cell = "1.13.0" serde = "1" serde_json = "1" -swc = "0.212.1" -swc_atoms = "0.3.1" -swc_bundler = { version = "0.175.0", features = ["concurrent"] } -swc_common = { version = "0.26.0", features = ["concurrent", "sourcemap"] } -swc_ecma_loader = { version = "0.38.0", features = ["node", "lru"] } -swc_ecmascript = { version = "0.186.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } -swc_plugin_runner = { version = "0.70.0", optional = true } +swc = "0.214.9" +swc_atoms = "0.4.8" +swc_bundler = { version = "0.177.4", features = ["concurrent"] } +swc_common = { version = "0.27.11", features = ["concurrent", "sourcemap"] } +swc_ecma_loader = { version = "0.39.4", features = ["node", "lru"] } +swc_ecmascript = { version = "0.189.4", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } +swc_plugin_runner = { version = "0.71.15", optional = true } swc_node_base = "0.5.5" tracing = { version = "0.1.32", features = ["release_max_level_info"] } tracing-futures = "0.2.5" diff --git a/packages/next-swc/crates/styled_components/Cargo.toml b/packages/next-swc/crates/styled_components/Cargo.toml index 8c91c16a0a6f..ca0943ff2778 100644 --- a/packages/next-swc/crates/styled_components/Cargo.toml +++ b/packages/next-swc/crates/styled_components/Cargo.toml @@ -6,7 +6,7 @@ include = ["Cargo.toml", "src/**/*.rs"] license = "Apache-2.0" name = "styled_components" repository = "https://github.com/vercel/next.js.git" -version = "0.39.0" +version = "0.40.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -15,13 +15,13 @@ Inflector = "0.11.4" once_cell = "1.13.0" regex = {version = "1.5.4", features = ["std", "perf"], default-features = false} serde = {version = "1.0.130", features = ["derive"]} -swc_atoms = "0.3.1" -swc_common = { version = "0.26.0", features = ["concurrent"] } -swc_ecmascript = { version = "0.186.0", features = ["utils", "visit"] } +swc_atoms = "0.4.8" +swc_common = { version = "0.27.11", features = ["concurrent"] } +swc_ecmascript = { version = "0.189.4", features = ["utils", "visit"] } tracing = "0.1.32" [dev-dependencies] serde_json = "1" -swc_ecma_transforms_testing = "0.104.0" -swc_ecmascript = { version = "0.186.0", features = ["parser", "transforms"] } -testing = "0.28.0" +swc_ecma_transforms_testing = "0.105.5" +swc_ecmascript = { version = "0.189.4", features = ["parser", "transforms"] } +testing = "0.29.4" diff --git a/packages/next-swc/crates/styled_jsx/Cargo.toml b/packages/next-swc/crates/styled_jsx/Cargo.toml index b116d21f3a6b..271b2de1eaf6 100644 --- a/packages/next-swc/crates/styled_jsx/Cargo.toml +++ b/packages/next-swc/crates/styled_jsx/Cargo.toml @@ -5,18 +5,18 @@ edition = "2018" license = "Apache-2.0" name = "styled_jsx" repository = "https://github.com/vercel/next.js.git" -version = "0.14.0" +version = "0.15.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] easy-error = "1.0.0" -swc_common = { version = "0.26.0", features = ["concurrent", "sourcemap"] } -swc_css = "0.116.0" -swc_css_prefixer = "0.113.3" -swc_ecmascript = { version = "0.186.0", features = ["parser", "minifier", "utils", "visit"] } +swc_common = { version = "0.27.11", features = ["concurrent", "sourcemap"] } +swc_css = "0.120.0" +swc_css_prefixer = "0.117.0" +swc_ecmascript = { version = "0.189.4", features = ["parser", "minifier", "utils", "visit"] } tracing = "0.1.32" [dev-dependencies] -swc_ecma_transforms_testing = "0.104.0" -testing = "0.28.0" +swc_ecma_transforms_testing = "0.105.5" +testing = "0.29.4" diff --git a/packages/next-swc/crates/wasm/Cargo.toml b/packages/next-swc/crates/wasm/Cargo.toml index 650b3464450a..81c7acfcea83 100644 --- a/packages/next-swc/crates/wasm/Cargo.toml +++ b/packages/next-swc/crates/wasm/Cargo.toml @@ -25,10 +25,10 @@ parking_lot_core = "=0.8.0" path-clean = "0.1" serde = {version = "1", features = ["derive"]} serde_json = "1" -swc = "0.212.1" -swc_common = { version = "0.26.0", features = ["concurrent", "sourcemap"] } -swc_ecmascript = { version = "0.186.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } -swc_plugin_runner = { version = "0.70.0", default-features = false, optional = true } +swc = "0.214.9" +swc_common = { version = "0.27.11", features = ["concurrent", "sourcemap"] } +swc_ecmascript = { version = "0.189.4", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } +swc_plugin_runner = { version = "0.71.15", default-features = false, optional = true } tracing = { version = "0.1.32", features = ["release_max_level_off"] } wasm-bindgen = {version = "0.2", features = ["serde-serialize", "enable-interning"]} wasm-bindgen-futures = "0.4.8" From b24b1d8421b6ba403b7b71695fd2a0c5df3161f9 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 17 Aug 2022 14:12:52 +0100 Subject: [PATCH 03/64] v12.2.6-canary.1 --- 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/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 | 16 ++++++++-------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- 16 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lerna.json b/lerna.json index 08b1efcfc4c4..3029b293b96b 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "12.2.6-canary.0" + "version": "12.2.6-canary.1" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 621ff222ba14..ffb25ddc54fc 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "12.2.6-canary.0", + "version": "12.2.6-canary.1", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 1ac08e8fc7ac..0d83e86e781a 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "12.2.6-canary.0", + "version": "12.2.6-canary.1", "description": "ESLint configuration used by NextJS.", "main": "index.js", "license": "MIT", @@ -9,7 +9,7 @@ "directory": "packages/eslint-config-next" }, "dependencies": { - "@next/eslint-plugin-next": "12.2.6-canary.0", + "@next/eslint-plugin-next": "12.2.6-canary.1", "@rushstack/eslint-patch": "^1.1.3", "@typescript-eslint/parser": "^5.21.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 a0c8959ab4ef..2bfbfd69656c 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": "12.2.6-canary.0", + "version": "12.2.6-canary.1", "description": "ESLint plugin for NextJS.", "main": "lib/index.js", "license": "MIT", diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 40a152380d7c..0ea4c98bcc07 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "12.2.6-canary.0", + "version": "12.2.6-canary.1", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index bb2bd3ad9b46..24bec552bb71 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "12.2.6-canary.0", + "version": "12.2.6-canary.1", "license": "MIT", "dependencies": { "chalk": "4.1.0", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 09db53da6245..93ce11156ec0 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "12.2.6-canary.0", + "version": "12.2.6-canary.1", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index af216e03322a..a7bdaede5cb4 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "12.2.6-canary.0", + "version": "12.2.6-canary.1", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 091843862ddf..6456f3b3ebe2 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "12.2.6-canary.0", + "version": "12.2.6-canary.1", "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 08f2a42aaac6..3877410e0889 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "12.2.6-canary.0", + "version": "12.2.6-canary.1", "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 a94c9c68c96a..d72c16d23696 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "12.2.6-canary.0", + "version": "12.2.6-canary.1", "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 9dddc8147a3e..ee043fbf5d7d 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "12.2.6-canary.0", + "version": "12.2.6-canary.1", "private": true, "scripts": { "build-native": "napi build --platform -p next-swc-napi --cargo-name next_swc_napi native --features plugin", diff --git a/packages/next/package.json b/packages/next/package.json index e115b3db04ef..18dd23e393f2 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "12.2.6-canary.0", + "version": "12.2.6-canary.1", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -70,7 +70,7 @@ ] }, "dependencies": { - "@next/env": "12.2.6-canary.0", + "@next/env": "12.2.6-canary.1", "@swc/helpers": "0.4.3", "caniuse-lite": "^1.0.30001332", "postcss": "8.4.14", @@ -121,11 +121,11 @@ "@hapi/accept": "5.0.2", "@napi-rs/cli": "2.7.0", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "12.2.6-canary.0", - "@next/polyfill-nomodule": "12.2.6-canary.0", - "@next/react-dev-overlay": "12.2.6-canary.0", - "@next/react-refresh-utils": "12.2.6-canary.0", - "@next/swc": "12.2.6-canary.0", + "@next/polyfill-module": "12.2.6-canary.1", + "@next/polyfill-nomodule": "12.2.6-canary.1", + "@next/react-dev-overlay": "12.2.6-canary.1", + "@next/react-refresh-utils": "12.2.6-canary.1", + "@next/swc": "12.2.6-canary.1", "@segment/ajv-human-errors": "2.1.2", "@taskr/clear": "1.1.0", "@taskr/esnext": "1.1.0", @@ -271,9 +271,9 @@ "vm-browserify": "1.1.2", "watchpack": "2.4.0", "web-vitals": "3.0.0-beta.2", + "webpack": "5.74.0", "webpack-sources1": "npm:webpack-sources@1.4.3", "webpack-sources3": "npm:webpack-sources@3.2.3", - "webpack": "5.74.0", "ws": "8.2.3" }, "resolutions": { diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 19a9647a9f5e..ee8baf02a894 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "12.2.6-canary.0", + "version": "12.2.6-canary.1", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 9a5eb975cbe2..ab88cee6c1f6 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": "12.2.6-canary.0", + "version": "12.2.6-canary.1", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d23d5008f024..986ce59f29e4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -364,7 +364,7 @@ importers: packages/eslint-config-next: specifiers: - '@next/eslint-plugin-next': 12.2.6-canary.0 + '@next/eslint-plugin-next': 12.2.6-canary.1 '@rushstack/eslint-patch': ^1.1.3 '@typescript-eslint/parser': ^5.21.0 eslint-import-resolver-node: ^0.3.6 @@ -420,12 +420,12 @@ importers: '@hapi/accept': 5.0.2 '@napi-rs/cli': 2.7.0 '@napi-rs/triples': 1.1.0 - '@next/env': 12.2.6-canary.0 - '@next/polyfill-module': 12.2.6-canary.0 - '@next/polyfill-nomodule': 12.2.6-canary.0 - '@next/react-dev-overlay': 12.2.6-canary.0 - '@next/react-refresh-utils': 12.2.6-canary.0 - '@next/swc': 12.2.6-canary.0 + '@next/env': 12.2.6-canary.1 + '@next/polyfill-module': 12.2.6-canary.1 + '@next/polyfill-nomodule': 12.2.6-canary.1 + '@next/react-dev-overlay': 12.2.6-canary.1 + '@next/react-refresh-utils': 12.2.6-canary.1 + '@next/swc': 12.2.6-canary.1 '@segment/ajv-human-errors': 2.1.2 '@swc/helpers': 0.4.3 '@taskr/clear': 1.1.0 From 9c416341048a4467d8bcd147c1d5c399fa1ab17a Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 17 Aug 2022 19:14:03 +0200 Subject: [PATCH 04/64] fix next-app-loader on windows (#39657) ## Bug - [x] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com> Co-authored-by: Jiachi Liu <4800338+huozhi@users.noreply.github.com> --- .../next/build/webpack/loaders/next-app-loader.ts | 12 +++++++----- .../loaders/next-flight-client-entry-loader.ts | 6 ++++-- packages/next/build/webpack/loaders/utils.ts | 2 +- .../build/webpack/plugins/flight-manifest-plugin.ts | 3 ++- packages/next/server/dev/hot-reloader.ts | 9 ++++++--- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/packages/next/build/webpack/loaders/next-app-loader.ts b/packages/next/build/webpack/loaders/next-app-loader.ts index 633eedbdc95a..bf7a405e1913 100644 --- a/packages/next/build/webpack/loaders/next-app-loader.ts +++ b/packages/next/build/webpack/loaders/next-app-loader.ts @@ -12,7 +12,7 @@ async function createTreeCodeFromPath({ removeExt: (pathToRemoveExtensions: string) => string }) { let tree: undefined | string - const splittedPath = pagePath.split('/') + const splittedPath = pagePath.split(/[\\/]/) const appDirPrefix = splittedPath[0] const segments = ['', ...splittedPath.slice(1)] @@ -26,7 +26,9 @@ async function createTreeCodeFromPath({ if (i === segments.length - 1) { const resolvedPagePath = await resolve(pagePath) // Use '' for segment as it's the page. There can't be a segment called '' so this is the safest way to add it. - tree = `['', {}, {filePath: '${resolvedPagePath}', page: () => require('${resolvedPagePath}')}]` + tree = `['', {}, {filePath: ${JSON.stringify( + resolvedPagePath + )}, page: () => require(${JSON.stringify(resolvedPagePath)})}]` continue } @@ -47,15 +49,15 @@ async function createTreeCodeFromPath({ children ? `children: ${children},` : '' } }, { - filePath: '${resolvedLayoutPath}', + filePath: '${resolvedLayoutPath}', ${ resolvedLayoutPath - ? `layout: () => require('${resolvedLayoutPath}'),` + ? `layout: () => require(${JSON.stringify(resolvedLayoutPath)}),` : '' } ${ resolvedLoadingPath - ? `loading: () => require('${resolvedLoadingPath}'),` + ? `loading: () => require(${JSON.stringify(resolvedLoadingPath)}),` : '' } }]` diff --git a/packages/next/build/webpack/loaders/next-flight-client-entry-loader.ts b/packages/next/build/webpack/loaders/next-flight-client-entry-loader.ts index f168350122d8..c2fdce03388f 100644 --- a/packages/next/build/webpack/loaders/next-flight-client-entry-loader.ts +++ b/packages/next/build/webpack/loaders/next-flight-client-entry-loader.ts @@ -23,8 +23,10 @@ export default async function transformSource(this: any): Promise { .filter((request) => (isServer ? !request.endsWith('.css') : true)) .map((request) => request.endsWith('.css') - ? `(() => import(/* webpackMode: "lazy" */ '${request}'))` - : `import(/* webpackMode: "eager" */ '${request}')` + ? `(() => import(/* webpackMode: "lazy" */ ${JSON.stringify( + request + )}))` + : `import(/* webpackMode: "eager" */ ${JSON.stringify(request)})` ) .join(';\n') + ` diff --git a/packages/next/build/webpack/loaders/utils.ts b/packages/next/build/webpack/loaders/utils.ts index a06143433df1..f5274be13148 100644 --- a/packages/next/build/webpack/loaders/utils.ts +++ b/packages/next/build/webpack/loaders/utils.ts @@ -39,7 +39,7 @@ export function buildExports(moduleExports: any, isESM: boolean) { export const clientComponentRegex = new RegExp( '(' + `\\.client(\\.(${defaultJsFileExtensions.join('|')}))?|` + - `next/(${nextClientComponents.join('|')})(\\.js)?|` + + `next[\\\\/](${nextClientComponents.join('|')})(\\.js)?|` + `\\.(${imageExtensions.join('|')})` + ')$' ) diff --git a/packages/next/build/webpack/plugins/flight-manifest-plugin.ts b/packages/next/build/webpack/plugins/flight-manifest-plugin.ts index 0cf8f816557c..2dcc2997f016 100644 --- a/packages/next/build/webpack/plugins/flight-manifest-plugin.ts +++ b/packages/next/build/webpack/plugins/flight-manifest-plugin.ts @@ -155,7 +155,8 @@ export class FlightManifestPlugin { mod.resourceResolveData?.path || resource ) if (!ssrNamedModuleId.startsWith('.')) - ssrNamedModuleId = `./${ssrNamedModuleId}` + // TODO use getModuleId instead + ssrNamedModuleId = `./${ssrNamedModuleId.replace(/\\/g, '/')}` if (isCSSModule) { if (!manifest[resource]) { diff --git a/packages/next/server/dev/hot-reloader.ts b/packages/next/server/dev/hot-reloader.ts index de362f9b5a5d..ffb1e74d8b9a 100644 --- a/packages/next/server/dev/hot-reloader.ts +++ b/packages/next/server/dev/hot-reloader.ts @@ -4,7 +4,7 @@ import type { CustomRoutes } from '../../lib/load-custom-routes' import { getOverlayMiddleware } from 'next/dist/compiled/@next/react-dev-overlay/dist/middleware' import { IncomingMessage, ServerResponse } from 'http' import { WebpackHotMiddleware } from './hot-middleware' -import { join, relative, isAbsolute } from 'path' +import { join, relative, isAbsolute, posix } from 'path' import { UrlObject } from 'url' import { createEntrypoints, @@ -666,9 +666,12 @@ export default class HotReloader { this.appDir && bundlePath.startsWith('app/') ? getAppEntry({ name: bundlePath, - pagePath: join( + pagePath: posix.join( APP_DIR_ALIAS, - relative(this.appDir!, entryData.absolutePagePath) + relative( + this.appDir!, + entryData.absolutePagePath + ).replace(/\\/g, '/') ), appDir: this.appDir!, pageExtensions: this.config.pageExtensions, From 78aefee1c643ed43001b6dbacca73a2bf22aca2a Mon Sep 17 00:00:00 2001 From: magic-akari Date: Thu, 18 Aug 2022 18:02:35 +0800 Subject: [PATCH 05/64] fix(swc/emotion): Correct the `SPACE_AROUND_COLON` regex (#39710) ## Bug - [x] fixes #39672 - [x] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` --- packages/next-swc/crates/emotion/src/lib.rs | 2 +- .../crates/emotion/tests/fixture/issues/39672/input.tsx | 9 +++++++++ .../crates/emotion/tests/fixture/issues/39672/output.ts | 5 +++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 packages/next-swc/crates/emotion/tests/fixture/issues/39672/input.tsx create mode 100644 packages/next-swc/crates/emotion/tests/fixture/issues/39672/output.ts diff --git a/packages/next-swc/crates/emotion/src/lib.rs b/packages/next-swc/crates/emotion/src/lib.rs index f6ca8eb68ed0..0059bf69cc33 100644 --- a/packages/next-swc/crates/emotion/src/lib.rs +++ b/packages/next-swc/crates/emotion/src/lib.rs @@ -82,7 +82,7 @@ static EMOTION_OFFICIAL_LIBRARIES: Lazy> = Lazy::new(|| }); static SPACE_AROUND_COLON: Lazy = - Lazy::new(|| Regex::new(r"\s*(?P[:|;|,|\{,\}])\s*").unwrap()); + Lazy::new(|| Regex::new(r"\s*(?P[:;,\{,\}])\s*").unwrap()); #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] diff --git a/packages/next-swc/crates/emotion/tests/fixture/issues/39672/input.tsx b/packages/next-swc/crates/emotion/tests/fixture/issues/39672/input.tsx new file mode 100644 index 000000000000..cabfa5dfb8da --- /dev/null +++ b/packages/next-swc/crates/emotion/tests/fixture/issues/39672/input.tsx @@ -0,0 +1,9 @@ +import styled from '@emotion/styled' + +const SelectedComponent = styled.p` + color: red; + + &:after { + content: ' | '; + } +` diff --git a/packages/next-swc/crates/emotion/tests/fixture/issues/39672/output.ts b/packages/next-swc/crates/emotion/tests/fixture/issues/39672/output.ts new file mode 100644 index 000000000000..f98d584f9465 --- /dev/null +++ b/packages/next-swc/crates/emotion/tests/fixture/issues/39672/output.ts @@ -0,0 +1,5 @@ +import styled from '@emotion/styled'; +const SelectedComponent = /*#__PURE__*/ styled("p", { + target: "ekie5mj0", + label: "SelectedComponent" +})("color:red;&:after{content:' | ';}", "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQudHMiLCJzb3VyY2VzIjpbImlucHV0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzdHlsZWQgZnJvbSAnQGVtb3Rpb24vc3R5bGVkJ1xuXG5jb25zdCBTZWxlY3RlZENvbXBvbmVudCA9IHN0eWxlZC5wYFxuICBjb2xvcjogcmVkO1xuXG4gICY6YWZ0ZXIge1xuICAgIGNvbnRlbnQ6ICcgfCAnO1xuICB9XG5gXG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRTBCIn0= */"); From 53604404130bfc2c9ad9e49164741b6de8a4189b Mon Sep 17 00:00:00 2001 From: Sukka Date: Thu, 18 Aug 2022 21:53:23 +0800 Subject: [PATCH 06/64] fix(#39609): warns about suspense and ssr (#39676) Currently, `next/dynamic` will opt-in to `React.lazy` if `{ suspense: true }` is used. And React 18 will always resolve the `Suspense` boundary on the server-side, effectively ignoring the `ssr` option. The PR fixes #39609 by showing a warning message when `{ suspense: true, ssr: false }` is detected. The error documentation and the corresponding test case has also been updated. In the future, Next.js could implement a custom version of `React.lazy` that could suspense without executing the lazy-loaded component on the server-side. cc @huozhi ## Bug - [x] Related issues linked using `fixes #number` - [x] Integration tests added - [x] Errors have helpful link attached, see `contributing.md` --- errors/invalid-dynamic-suspense.md | 22 +++++++- packages/next/shared/lib/dynamic.tsx | 25 +++++++++ test/e2e/dynamic-with-suspense/index.test.ts | 55 ------------------- .../next-dynamic-with-suspense/pages/index.js | 19 +++++++ .../next-dynamic-with-suspense/pages/thing.js | 3 + .../test/index.test.ts | 41 ++++++++++++++ 6 files changed, 108 insertions(+), 57 deletions(-) delete mode 100644 test/e2e/dynamic-with-suspense/index.test.ts create mode 100644 test/integration/next-dynamic-with-suspense/pages/index.js create mode 100644 test/integration/next-dynamic-with-suspense/pages/thing.js create mode 100644 test/integration/next-dynamic-with-suspense/test/index.test.ts diff --git a/errors/invalid-dynamic-suspense.md b/errors/invalid-dynamic-suspense.md index 11e4d6134d73..f016eec897d4 100644 --- a/errors/invalid-dynamic-suspense.md +++ b/errors/invalid-dynamic-suspense.md @@ -2,11 +2,29 @@ #### Why This Error Occurred -`` is not allowed under legacy render mode when using React older than v18. +- You are using `{ suspense: true }` with React version older than 18. +- You are using `{ suspense: true, ssr: false }`. +- You are using `{ suspense: true, loading }`. #### Possible Ways to Fix It -Remove `suspense: true` option in `next/dynamic` usages. +**If you are using `{ suspense: true }` with React version older than 18** + +- You can try upgrading to React 18 or newer +- If upgrading React is not an option, remove `{ suspense: true }` from `next/dynamic` usages. + +**If you are using `{ suspense: true, ssr: false }`** + +Next.js will use `React.lazy` when `suspense` is set to true. React 18 or newer will always try to resolve the Suspense boundary on the server. This behavior can not be disabled, thus the `ssr: false` is ignored with `suspense: true`. + +- You should write code that works in both client-side and server-side. +- If rewriting the code is not an option, remove `{ suspense: true }` from `next/dynamic` usages. + +**If you are using `{ suspense: true, loading }`** + +Next.js will use `React.lazy` when `suspense` is set to true, when your dynamic-imported component is loading, React will use the closest suspense boundary's fallback. + +You should remove `loading` from `next/dynamic` usages, and use ``'s `fallback` prop. ### Useful Links diff --git a/packages/next/shared/lib/dynamic.tsx b/packages/next/shared/lib/dynamic.tsx index 91b747e4e1ea..6e7dc8fa2290 100644 --- a/packages/next/shared/lib/dynamic.tsx +++ b/packages/next/shared/lib/dynamic.tsx @@ -112,6 +112,31 @@ export default function dynamic

( ) } + if (process.env.NODE_ENV !== 'production') { + if (loadableOptions.suspense) { + /** + * TODO: Currently, next/dynamic will opt-in to React.lazy if { suspense: true } is used + * React 18 will always resolve the Suspense boundary on the server-side, effectively ignoring the ssr option + * + * In the future, when React Suspense with third-party libraries is stable, we can implement a custom version of + * React.lazy that can suspense on the server-side while only loading the component on the client-side + */ + if (loadableOptions.ssr === false) { + loadableOptions.ssr = true + console.warn( + `"ssr: false" is ignored by next/dynamic because you can not enable "suspense" while disabling "ssr" at the same time. Read more: https://nextjs.org/docs/messages/invalid-dynamic-suspense` + ) + } + + if (loadableOptions.loading != null) { + loadableOptions.loading = undefined + console.warn( + `"loading" is ignored by next/dynamic because you have enabled "suspense". Place your loading element in your suspense boundary's "fallback" prop instead. Read more: https://nextjs.org/docs/messages/invalid-dynamic-suspense` + ) + } + } + } + // coming from build/babel/plugins/react-loadable-plugin.js if (loadableOptions.loadableGenerated) { loadableOptions = { diff --git a/test/e2e/dynamic-with-suspense/index.test.ts b/test/e2e/dynamic-with-suspense/index.test.ts deleted file mode 100644 index b0f24fb96a1e..000000000000 --- a/test/e2e/dynamic-with-suspense/index.test.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { createNext } from 'e2e-utils' -import { NextInstance } from 'test/lib/next-modes/base' -import { hasRedbox, renderViaHTTP } from 'next-test-utils' -import webdriver from 'next-webdriver' - -const suite = - process.env.NEXT_TEST_REACT_VERSION === '^17' ? describe.skip : describe - -// Skip the suspense test if react version is 17 -suite('dynamic with suspense', () => { - let next: NextInstance - - beforeAll(async () => { - next = await createNext({ - files: { - 'pages/index.js': ` - import { Suspense } from "react"; - import dynamic from "next/dynamic"; - - const Thing = dynamic(() => import("./thing"), { ssr: false, suspense: true }); - - export default function IndexPage() { - return ( -

-

Next.js Example

- - - -
- ); - } - `, - 'pages/thing.js': ` - export default function Thing() { - return "Thing"; - } - `, - }, - dependencies: {}, - }) - }) - afterAll(() => next.destroy()) - - it('should render server-side', async () => { - const html = await renderViaHTTP(next.url, '/') - expect(html).toContain('Next.js Example') - expect(html).toContain('Thing') - }) - - it('should render client-side', async () => { - const browser = await webdriver(next.url, '/') - expect(await hasRedbox(browser)).toBe(false) - await browser.close() - }) -}) diff --git a/test/integration/next-dynamic-with-suspense/pages/index.js b/test/integration/next-dynamic-with-suspense/pages/index.js new file mode 100644 index 000000000000..284fcc7f7f8f --- /dev/null +++ b/test/integration/next-dynamic-with-suspense/pages/index.js @@ -0,0 +1,19 @@ +import { Suspense } from 'react' +import dynamic from 'next/dynamic' + +const Thing = dynamic(() => import('./thing'), { + ssr: false, + suspense: true, + loading: () => 'Loading...', +}) + +export default function IndexPage() { + return ( +
+

Next.js Example

+ + + +
+ ) +} diff --git a/test/integration/next-dynamic-with-suspense/pages/thing.js b/test/integration/next-dynamic-with-suspense/pages/thing.js new file mode 100644 index 000000000000..561df9831e5b --- /dev/null +++ b/test/integration/next-dynamic-with-suspense/pages/thing.js @@ -0,0 +1,3 @@ +export default function Thing() { + return 'Thing' +} diff --git a/test/integration/next-dynamic-with-suspense/test/index.test.ts b/test/integration/next-dynamic-with-suspense/test/index.test.ts new file mode 100644 index 000000000000..625fdde999d5 --- /dev/null +++ b/test/integration/next-dynamic-with-suspense/test/index.test.ts @@ -0,0 +1,41 @@ +/* eslint-env jest */ + +import webdriver from 'next-webdriver' +import { join } from 'path' +import { + renderViaHTTP, + findPort, + launchApp, + killApp, + hasRedbox, +} from 'next-test-utils' + +let app +let appPort: number +const appDir = join(__dirname, '../') + +describe('next/dynamic with suspense', () => { + beforeAll(async () => { + appPort = await findPort() + app = await launchApp(appDir, appPort) + }) + afterAll(() => killApp(app)) + + it('should render server-side', async () => { + const html = await renderViaHTTP(appPort, '/') + expect(html).toContain('Next.js Example') + expect(html).toContain('Thing') + }) + + it('should render client-side', async () => { + const browser = await webdriver(appPort, '/') + const warnings = (await browser.log()).map((log) => log.message).join('\n') + + expect(await hasRedbox(browser)).toBe(false) + expect(warnings).toMatch( + /"ssr: false" is ignored by next\/dynamic because you can not enable "suspense" while disabling "ssr" at the same time/gim + ) + + await browser.close() + }) +}) From ee134ee338579b8d12b20a5d449a67d72ca077fc Mon Sep 17 00:00:00 2001 From: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com> Date: Thu, 18 Aug 2022 15:23:10 +0100 Subject: [PATCH 07/64] Change the React Server Components CTA to the router/layout RFC (#39724) --- .../react-18/server-components.md | 26 +++++-------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/docs/advanced-features/react-18/server-components.md b/docs/advanced-features/react-18/server-components.md index fb6699fba26c..839bda3274a3 100644 --- a/docs/advanced-features/react-18/server-components.md +++ b/docs/advanced-features/react-18/server-components.md @@ -1,30 +1,18 @@ -# React Server Components (Alpha) +# React Server Components (RFC) Server Components allow us to render React components on the server. This is fundamentally different from server-side rendering (SSR) where you're pre-generating HTML on the server. With Server Components, there's **zero client-side JavaScript needed,** making page rendering faster. This improves the user experience of your application, pairing the best parts of server-rendering with client-side interactivity. -### Enable React Server Components +### Next Router and Layouts RFC -To use React Server Components, ensure you have the latest React installed: +We are currently implementing the [Next.js Router and Layouts RFC](/blog/layouts-rfc). -```jsx -npm install next@canary react@latest react-dom@latest -``` - -Then, update your `next.config.js`: +The new Next.js router will be built on top of React 18 features, including React Server Components. -```jsx -// next.config.js -module.exports = { - experimental: { - runtime: 'nodejs', - serverComponents: true, - }, -} -``` +One of the biggest proposed changes is that, by default, files inside a new `app` directory will be rendered on the server as React Server Components. -Using `runtime` also enables [Streaming SSR](/docs/advanced-features/react-18/streaming). When setting `runtime` to `'experimental-edge'`, the server will be running entirely in the [Edge Runtime](https://nextjs.org/docs/api-reference/edge-runtime). +This will allow you to automatically adopt React Server Components when migrating from `pages` to `app`. -Now, you can start using React Server Components in Next.js. [See our example](https://github.com/vercel/next-rsc-demo) for more information. +You can find more information on the [RFC](/blog/layouts-rfc) and we welcome your feedback on [Github Discussions](https://github.com/vercel/next.js/discussions/37136). ### Server Components Conventions From f7eed07945375f0b4a76efcbb5cbfe87072c2261 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 18 Aug 2022 17:07:34 +0100 Subject: [PATCH 08/64] Use realpath when emitting traced package.json (#39683) This ensures we emit the real path when emitting traced package.json files so that we don't conflict with symlinked package paths. x-ref: slack thread Bug Related issues linked using fixes #number Integration tests added Errors have helpful link attached, see contributing.md --- .../next/build/webpack/plugins/next-trace-entrypoints-plugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/build/webpack/plugins/next-trace-entrypoints-plugin.ts b/packages/next/build/webpack/plugins/next-trace-entrypoints-plugin.ts index cd99b9d530c8..9d608d86ebbf 100644 --- a/packages/next/build/webpack/plugins/next-trace-entrypoints-plugin.ts +++ b/packages/next/build/webpack/plugins/next-trace-entrypoints-plugin.ts @@ -563,7 +563,7 @@ export class TraceEntryPointsPlugin implements webpack.WebpackPluginInstance { const curPackageJsonPath = `${requestPath}/package.json` if (await job.isFile(curPackageJsonPath)) { await job.emitFile( - curPackageJsonPath, + await job.realpath(curPackageJsonPath), 'resolve', parent ) From 3466862d9dc9c8bb3131712134d38757b918d1c0 Mon Sep 17 00:00:00 2001 From: Sukka Date: Fri, 19 Aug 2022 01:57:12 +0800 Subject: [PATCH 09/64] fix(#39706): add avif support for node serve static (#39733) The PR fixes #39706 by adding `avif` mime type directly to `send`. The PR also removes the previous avif workaround for image optimizer. Note: The PR is still a workaround for now. I will submit a PR to `pillarjs/send` to help them update `mime` to fix the issue once and for all. But now `send.mime.define` just works. ## Bug - [x] Related issues linked using `fixes #number` - [x] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` --- packages/next/server/serve-static.ts | 14 ++++++-------- .../file-serving/public/vercel-icon-dark.avif | Bin 0 -> 33356 bytes .../integration/file-serving/test/index.test.js | 7 +++++++ 3 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 test/integration/file-serving/public/vercel-icon-dark.avif diff --git a/packages/next/server/serve-static.ts b/packages/next/server/serve-static.ts index 7c2a441c6b75..c51236cf5f08 100644 --- a/packages/next/server/serve-static.ts +++ b/packages/next/server/serve-static.ts @@ -1,6 +1,12 @@ import { IncomingMessage, ServerResponse } from 'http' import send from 'next/dist/compiled/send' +// TODO: Remove this once "send" has updated the "mime", or next.js use custom version of "mime" +// Although "mime" has already add avif in version 2.4.7, "send" is still using mime@1.6.0 +send.mime.define({ + 'image/avif': ['avif'], +}) + export function serveStatic( req: IncomingMessage, res: ServerResponse, @@ -21,10 +27,6 @@ export function serveStatic( } export function getContentType(extWithoutDot: string): string | null { - if (extWithoutDot === 'avif') { - // TODO: update "mime" package - return 'image/avif' - } const { mime } = send if ('getType' in mime) { // 2.0 @@ -35,10 +37,6 @@ export function getContentType(extWithoutDot: string): string | null { } export function getExtension(contentType: string): string | null { - if (contentType === 'image/avif') { - // TODO: update "mime" package - return 'avif' - } const { mime } = send if ('getExtension' in mime) { // 2.0 diff --git a/test/integration/file-serving/public/vercel-icon-dark.avif b/test/integration/file-serving/public/vercel-icon-dark.avif new file mode 100644 index 0000000000000000000000000000000000000000..48049da2b6016252071dcf9ce16465e77a48793c GIT binary patch literal 33356 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 literal 0 HcmV?d00001 diff --git a/test/integration/file-serving/test/index.test.js b/test/integration/file-serving/test/index.test.js index e25f8cfaef0d..cb886b6fd238 100644 --- a/test/integration/file-serving/test/index.test.js +++ b/test/integration/file-serving/test/index.test.js @@ -61,6 +61,13 @@ const runTests = () => { expect(await res.text()).toBe('hi') }) + it('should serve avif image with correct content-type', async () => { + // vercel-icon-dark.avif is downloaded from https://vercel.com/design and transformed to avif on avif.io + const res = await fetchViaHTTP(appPort, '/vercel-icon-dark.avif') + expect(res.status).toBe(200) + expect(res.headers.get('content-type')).toBe('image/avif') + }) + // checks against traversal requests from // https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Directory%20Traversal/Intruder/traversals-8-deep-exotic-encoding.txt From aacc0ce90f1ab59ebc8eb2b44c668611b3f2dcaf Mon Sep 17 00:00:00 2001 From: Alex Cole Date: Fri, 19 Aug 2022 10:13:33 -0700 Subject: [PATCH 10/64] Tweak Convex example (#39739) This is a followup to #39562 because I realized I made a few mistakes. Remove convex.json file. Developers using the example should generate this on their own by running npx convex init. Switch prettier to a dev dependency. Ignore formatting in Convex generated code while running lint-staged and revert them back to the default generated form (I previously was only ignoring generated code in the main .prettierignore) Change a let to a const cc @thomasballinger Documentation / Examples Make sure the linting passes by running pnpm lint The examples guidelines are followed from our contributing doc --- .prettierignore_staged | 3 +- examples/convex/convex.json | 6 ---- .../convex/convex/_generated/dataModel.ts | 14 +++++----- examples/convex/convex/_generated/react.ts | 28 +++++++++---------- examples/convex/convex/_generated/server.ts | 16 +++++------ examples/convex/convex/incrementCounter.ts | 2 +- examples/convex/package.json | 2 +- 7 files changed, 33 insertions(+), 38 deletions(-) delete mode 100644 examples/convex/convex.json diff --git a/.prettierignore_staged b/.prettierignore_staged index f6426b02078e..2ad75e98a1e2 100644 --- a/.prettierignore_staged +++ b/.prettierignore_staged @@ -7,4 +7,5 @@ packages/next/bundles/webpack/packages/*.runtime.js lerna.json packages/next-codemod/transforms/__testfixtures__/**/* packages/next-codemod/transforms/__tests__/**/* -pnpm-lock.yaml \ No newline at end of file +pnpm-lock.yaml +**/convex/_generated/** diff --git a/examples/convex/convex.json b/examples/convex/convex.json deleted file mode 100644 index 4f972abd4642..000000000000 --- a/examples/convex/convex.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "authInfo": [], - "functions": "convex/", - "instanceName": "handsome-turtle-915", - "origin": "https://handsome-turtle-915.convex.cloud" -} diff --git a/examples/convex/convex/_generated/dataModel.ts b/examples/convex/convex/_generated/dataModel.ts index 2f229880ec7c..87c7cb3c1fbe 100644 --- a/examples/convex/convex/_generated/dataModel.ts +++ b/examples/convex/convex/_generated/dataModel.ts @@ -9,8 +9,8 @@ * @module */ -import { AnyDataModel } from 'convex/server' -import { GenericId } from 'convex/values' +import { AnyDataModel } from "convex/server"; +import { GenericId } from "convex/values"; /** * No `schema.ts` file found! @@ -26,12 +26,12 @@ import { GenericId } from 'convex/values' /** * The names of all of your Convex tables. */ -export type TableNames = string +export type TableNames = string; /** * The type of a document stored in Convex. */ -export type Document = any +export type Document = any; /** * An identifier for a document in Convex. @@ -45,8 +45,8 @@ export type Document = any * Using `===` will not work because two different instances of `Id` can refer * to the same document. */ -export type Id = GenericId -export const Id = GenericId +export type Id = GenericId; +export const Id = GenericId; /** * A type describing your Convex data model. @@ -57,4 +57,4 @@ export const Id = GenericId * This type is used to parameterize methods like `queryGeneric` and * `mutationGeneric` to make them type-safe. */ -export type DataModel = AnyDataModel +export type DataModel = AnyDataModel; diff --git a/examples/convex/convex/_generated/react.ts b/examples/convex/convex/_generated/react.ts index 1859ea22336c..0ed0e5634a0c 100644 --- a/examples/convex/convex/_generated/react.ts +++ b/examples/convex/convex/_generated/react.ts @@ -9,10 +9,10 @@ * @module */ -import type getCounter from '../getCounter' -import type incrementCounter from '../incrementCounter' -import type { OptimisticLocalStore as GenericOptimisticLocalStore } from 'convex/browser' -import type { ClientMutation, ClientQuery } from 'convex/server' +import type getCounter from "../getCounter"; +import type incrementCounter from "../incrementCounter"; +import type { OptimisticLocalStore as GenericOptimisticLocalStore } from "convex/browser"; +import type { ClientMutation, ClientQuery } from "convex/server"; /** * A type describing your app's public Convex API. @@ -25,14 +25,14 @@ import type { ClientMutation, ClientQuery } from 'convex/server' */ export type ConvexAPI = { queries: { - getCounter: ClientQuery - } + getCounter: ClientQuery; + }; mutations: { - incrementCounter: ClientMutation - } -} + incrementCounter: ClientMutation; + }; +}; -import { makeUseQuery, makeUseMutation, makeUseConvex } from 'convex/react' +import { makeUseQuery, makeUseMutation, makeUseConvex } from "convex/react"; /** * Load a reactive query within a React component. @@ -46,7 +46,7 @@ import { makeUseQuery, makeUseMutation, makeUseConvex } from 'convex/react' * @param args - The arguments to the query function. * @returns `undefined` if loading and the query's return value otherwise. */ -export const useQuery = makeUseQuery() +export const useQuery = makeUseQuery(); /** * Construct a new {@link ReactMutation}. @@ -64,7 +64,7 @@ export const useQuery = makeUseQuery() * @param name - The name of the mutation. * @returns The {@link ReactMutation} object with that name. */ -export const useMutation = makeUseMutation() +export const useMutation = makeUseMutation(); /** * Get the {@link ConvexReactClient} within a React component. @@ -73,10 +73,10 @@ export const useMutation = makeUseMutation() * * @returns The active {@link ConvexReactClient} object, or `undefined`. */ -export const useConvex = makeUseConvex() +export const useConvex = makeUseConvex(); /** * A view of the query results currently in the Convex client for use within * optimistic updates. */ -export type OptimisticLocalStore = GenericOptimisticLocalStore +export type OptimisticLocalStore = GenericOptimisticLocalStore; diff --git a/examples/convex/convex/_generated/server.ts b/examples/convex/convex/_generated/server.ts index 833b51dcc8ef..0e8d913bbd0a 100644 --- a/examples/convex/convex/_generated/server.ts +++ b/examples/convex/convex/_generated/server.ts @@ -16,8 +16,8 @@ import { MutationCtx as GenericMutationCtx, DatabaseReader as GenericDatabaseReader, DatabaseWriter as GenericDatabaseWriter, -} from 'convex/server' -import { DataModel } from './dataModel.js' +} from "convex/server"; +import { DataModel } from "./dataModel.js"; /** * Define a query in this Convex app's public API. @@ -27,7 +27,7 @@ import { DataModel } from './dataModel.js' * @param func - The query function. It receives a {@link QueryCtx} as its first argument. * @returns The wrapped query. Include this as an `export` to name it and make it accessible. */ -export const query = makeQuery() +export const query = makeQuery(); /** * Define a mutation in this Convex app's public API. @@ -37,7 +37,7 @@ export const query = makeQuery() * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. */ -export const mutation = makeMutation() +export const mutation = makeMutation(); /** * A set of services for use within Convex query functions. @@ -48,7 +48,7 @@ export const mutation = makeMutation() * This differs from the {@link MutationCtx} because all of the services are * read-only. */ -export type QueryCtx = GenericQueryCtx +export type QueryCtx = GenericQueryCtx; /** * A set of services for use within Convex mutation functions. @@ -56,7 +56,7 @@ export type QueryCtx = GenericQueryCtx * The mutation context is passed as the first argument to any Convex mutation * function run on the server. */ -export type MutationCtx = GenericMutationCtx +export type MutationCtx = GenericMutationCtx; /** * An interface to read from the database within Convex query functions. @@ -65,7 +65,7 @@ export type MutationCtx = GenericMutationCtx * document by its {@link Id}, or {@link DatabaseReader.table}, which starts * building a query. */ -export type DatabaseReader = GenericDatabaseReader +export type DatabaseReader = GenericDatabaseReader; /** * An interface to read from and write to the database within Convex mutation @@ -76,4 +76,4 @@ export type DatabaseReader = GenericDatabaseReader * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control) * for the guarantees Convex provides your functions. */ -export type DatabaseWriter = GenericDatabaseWriter +export type DatabaseWriter = GenericDatabaseWriter; diff --git a/examples/convex/convex/incrementCounter.ts b/examples/convex/convex/incrementCounter.ts index 8e43836c7048..b7f6d035883d 100644 --- a/examples/convex/convex/incrementCounter.ts +++ b/examples/convex/convex/incrementCounter.ts @@ -2,7 +2,7 @@ import { mutation } from './_generated/server' export default mutation( async ({ db }, counterName: string, increment: number) => { - let counterDoc = await db + const counterDoc = await db .table('counter_table') .filter((q) => q.eq(q.field('name'), counterName)) .first() diff --git a/examples/convex/package.json b/examples/convex/package.json index 24cb00227708..2ad3f092106e 100644 --- a/examples/convex/package.json +++ b/examples/convex/package.json @@ -8,7 +8,6 @@ "dependencies": { "convex": "latest", "next": "latest", - "prettier": "^2.7.1", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -16,6 +15,7 @@ "@types/node": "~16.11.12", "@types/react": "17.0.45", "@types/react-dom": "17.0.17", + "prettier": "^2.7.1", "typescript": "^4.7.3" } } From 5b6631a5c9d74e6b51ad4c5782e6d0e2590f3532 Mon Sep 17 00:00:00 2001 From: Steven Date: Sat, 20 Aug 2022 01:21:00 +0100 Subject: [PATCH 11/64] Add section to `next/future/image` docs about Known Browser Bugs (#39759) This PR adds section to `next/future/image` docs about Known Browser Bugs. This also includes workarounds that might vary depending on the image and how the user plans to use it. --- .alexrc | 3 ++- docs/api-reference/next/future/image.md | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.alexrc b/.alexrc index 47862f2c80a1..1f1de4b4382a 100644 --- a/.alexrc +++ b/.alexrc @@ -17,6 +17,7 @@ "hooks", "host-hostess", "invalid", - "remains" + "remains", + "white" ] } diff --git a/docs/api-reference/next/future/image.md b/docs/api-reference/next/future/image.md index f7909d6bcec6..76e2ee33cddc 100644 --- a/docs/api-reference/next/future/image.md +++ b/docs/api-reference/next/future/image.md @@ -41,6 +41,15 @@ Compared to `next/image`, the new `next/future/image` component has the followin - Removes `loader` config in favor of [`loader`](#loader) prop - Note: the [`onError`](#onerror) prop might behave differently +## Known Browser Bugs + +- [Safari 15+](https://bugs.webkit.org/show_bug.cgi?id=243601) displays a gray border while loading. Possible solutions: + - Use CSS `@media not all and (min-resolution:.001dpcm) { img[loading="lazy"] { clip-path: inset(0.5px) } }` + - Use [`priority`](#priority) if the image is above the fold +- [Firefox 67+](https://bugzilla.mozilla.org/show_bug.cgi?id=1556156) displays a white background while loading progressive jpeg. Possible solutions: + - Enable [AVIF `formats`](#acceptable-formats) + - Use [`placeholder="blur"`](#blur) + ## Migration Although `layout` is not available, you can migrate `next/image` to `next/future/image` using a few props. The following code snippets compare the two components: From f4ea33327cb704de3ac12989f1420a1f67c64e4c Mon Sep 17 00:00:00 2001 From: Puneet Kathar <73285338+puneetkathar1@users.noreply.github.com> Date: Sat, 20 Aug 2022 12:44:46 +0530 Subject: [PATCH 12/64] Update contributing.md (#39767) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm lint` - [ ] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples) --- contributing.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contributing.md b/contributing.md index 6238e972f4bf..b3ec843cf2e7 100644 --- a/contributing.md +++ b/contributing.md @@ -61,7 +61,7 @@ pnpm build pnpm prepublishOnly ``` -By default the latest canary of the next-swc binaries will be installed and used. If you are actively working on Rust code or you need to test out the most recent Rust code that hasn't been published as a canary yet you can [install Rust](https://www.rust-lang.org/tools/install) and run `pnpm --filter=@next/swc build-native`. +By default, the latest canary of the next-swc binaries will be installed and used. If you are actively working on Rust code or you need to test out the most recent Rust code that hasn't been published as a canary yet you can [install Rust](https://www.rust-lang.org/tools/install) and run `pnpm --filter=@next/swc build-native`. If you want to test out the wasm build locally, you will need to [install wasm-pack](https://rustwasm.github.io/wasm-pack/installer/). Run `pnpm --filter=@next/swc build-wasm --target ` to build and `node ./scripts/setup-wasm.mjs` to copy it into your `node_modules`. Run next with `NODE_OPTIONS='--no-addons'` to force it to use the wasm binary. @@ -164,7 +164,7 @@ There are two options to develop with your local version of the codebase: to re-install all of the dependencies. - Note that Next will be copied from the locally compiled version as opposed to from being downloaded from the NPM registry. + Note that Next will be copied from the locally compiled version as opposed to being downloaded from the NPM registry. 4. Run your application as you normally would. @@ -263,7 +263,7 @@ Below are the steps to add a new link: ## Adding examples -When you add an example to the [examples](examples) directory, please follow these guidelines to ensure high quality examples: +When you add an example to the [examples](examples) directory, please follow these guidelines to ensure high-quality examples: - TypeScript should be leveraged for new examples (no need for separate JavaScript and TypeScript examples, converting old JavaScript examples is preferred) - Examples should not add custom ESLint configuration (we have specific templates for ESLint) @@ -277,7 +277,7 @@ When you add an example to the [examples](examples) directory, please follow the - Example directories should not be prefixed with `with-` - Make sure linting passes (you can run `pnpm lint-fix`) -Also don’t forget to add a `README.md` file with the following format: +Also, don’t forget to add a `README.md` file with the following format: - Replace `DIRECTORY_NAME` with the directory name you’re adding. - Fill in `Example Name` and `Description`. @@ -333,7 +333,7 @@ Issues are opened with one of these labels: - `template: bug` - unverified issue with Next.js itself, or one of the examples in the [`examples`](https://github.com/vercel/next.js/tree/canary/examples) folder - `template: documentation` - feedback for improvement or an unverified issue with the Next.js documentation -In case of a bug report, a maintainer looks at the provided reproduction. If the reproduction is missing or insufficient, a `please add a complete reproduction` label is added. If a reproduction is not provided for more than 30 days, the issue becomes stale and will be automatically closed. If a reproduction is provided within 30 days, the `please add a complete reproduction` label is removed and the issue will not become stale anymore. +In the case of a bug report, a maintainer looks at the provided reproduction. If the reproduction is missing or insufficient, a `please add a complete reproduction` label is added. If a reproduction is not provided for more than 30 days, the issue becomes stale and will be automatically closed. If a reproduction is provided within 30 days, the `please add a complete reproduction` label is removed and the issue will not become stale anymore. Bug reports must be verified against the `next@canary` release. The canary version of Next.js ships daily and includes all features and fixes that have not been released to the stable version yet. Think of canary as a public beta. Some issues may already be fixed in the canary version, so please verify that your issue reproduces before opening a new issue. Issues not verified against `next@canary` will be closed after 30 days. @@ -341,6 +341,6 @@ If the issue is specific to the project and not to Next.js itself, it might be c If the bug is verified, it will receive the `kind: bug` label and will be tracked by the maintainers. An `area:` label can be added to indicate which part of Next.js is affected. -Confirmed issues never become stale or be closed before resolution. +Confirmed issues never become stale or are closed before resolution. All **closed** PRs and Issues will be locked after 30 days of inactivity (eg.: comment, referencing from elsewhere). From 72fd04a6362309e286d692ef51db9768b7e3704d Mon Sep 17 00:00:00 2001 From: Kelvin Mok Date: Sat, 20 Aug 2022 21:01:53 +0800 Subject: [PATCH 13/64] [Docs] examples/with-redux-thunk , update README (#39555) (#39712) ## Documentation / Examples - [x] Make sure the linting passes by running `pnpm lint` - [x] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples) This change is related to issue https://github.com/vercel/next.js/issues/39555 PTAL, Thanks Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com> --- examples/with-redux-thunk/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/with-redux-thunk/README.md b/examples/with-redux-thunk/README.md index fe87bfd8b891..f3eef2d19d59 100644 --- a/examples/with-redux-thunk/README.md +++ b/examples/with-redux-thunk/README.md @@ -30,7 +30,7 @@ Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&ut ## Notes -The Redux `Provider` is implemented in `pages/_app.js`. The `MyApp` component is wrapped in a `withReduxStore` function, the redux `store` will be initialized in the function and then passed down to `MyApp` as `this.props.initialReduxState`, which will then be utilized by the `Provider` component. +The Redux `Provider` is implemented in `pages/_app.js`. The `pageProps` is wrapped in a `useStore` hook function, the redux `store` will be initialized in the function and then passed down to `Page Component` as `this.props.initialReduxState`, which will then be utilized by the `Provider` component. Every initial server-side request will utilize a new `store`. However, every `Router` or `Link` action will persist the same `store` as a user navigates through the `pages`. To demonstrate this example, we can navigate back and forth to `/show-redux-state` using the provided `Link`s. However, if we navigate directly to `/show-redux-state` (or refresh the page), this will cause a server-side render, which will then utilize a new store. @@ -40,10 +40,10 @@ In the `counter` component, we are going to display a user-interactive counter t This example includes two different ways to access the `store` or to `dispatch` actions: -1.) `pages/index.js` will utilize `connect` from `react-redux` to `dispatch` the `startClock` redux action once the component has been mounted in the browser. +1.) `pages/index.js` will utilize `useDispatch` from `react-redux` to `dispatch` the `startClock` redux action once the component has been mounted in the browser. 2.) `components/counter.js` and `components/examples.js` have access to the redux store using `useSelector` and can dispatch actions using `useDispatch` from `react-redux@^7.1.0` You can either use the `connect` function to access redux state and/or dispatch actions or use the hook variations: `useSelector` and `useDispatch`. It's up to you. -This example also includes hot-reloading when one of the `reducers` has changed. However, there is one caveat with this implementation: If you're using the `Redux DevTools` browser extension, then all previously recorded actions will be recreated when a reducer has changed (in other words, if you increment the counter by 1 using the `+1` button, and then change the increment action to add 10 in the reducer, Redux DevTools will playback all actions and adjust the counter state by 10 to reflect the reducer change). Therefore, to avoid this issue, the store has been set up to reset back initial state upon a reducer change. If you wish to persist redux state regardless (or you don't have the extension installed), then in `store.js` change (line 19) `store.replaceReducer(createNextReducer(initialState))` to `store.replaceReducer(createNextReducer)`. +This example also includes hot-reloading when one of the `reducers` has changed. However, there is one caveat with this implementation: If you're using the `Redux DevTools` browser extension, then all previously recorded actions will be recreated when a reducer has changed (in other words, if you increment the counter by 1 using the `+1` button, and then change the increment action to add 10 in the reducer, Redux DevTools will playback all actions and adjust the counter state by 10 to reflect the reducer change). Therefore, to avoid this issue, the store has been set up to reset back initial state upon a reducer change. If you wish to persist redux state regardless (or you don't have the extension installed), then in `store.js` change (line 10) `createStore(reducers,initialState,composeWithDevTools(applyMiddleware(thunkMiddleware)))` to `createStore(reducers,initialState,applyMiddleware(thunkMiddleware))`. From ea7efcb05c421f00b039b9b629b87149b4a9d0b5 Mon Sep 17 00:00:00 2001 From: Naoyuki Kanezawa Date: Sat, 20 Aug 2022 20:46:59 +0700 Subject: [PATCH 14/64] fix(next): Do not display message when middleware is removed on dev mode (#39604) Fixes https://github.com/vercel/next.js/issues/39532 ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` --- packages/next/server/next-server.ts | 1 - .../middleware-dev-update/middleware.js | 9 ++ .../middleware-dev-update/pages/index.js | 9 ++ .../middleware-dev-update/test/index.test.js | 125 ++++++++++++++++++ 4 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 test/integration/middleware-dev-update/middleware.js create mode 100644 test/integration/middleware-dev-update/pages/index.js create mode 100644 test/integration/middleware-dev-update/test/index.test.js diff --git a/packages/next/server/next-server.ts b/packages/next/server/next-server.ts index f0e869773d0c..26aafbee55c3 100644 --- a/packages/next/server/next-server.ts +++ b/packages/next/server/next-server.ts @@ -1636,7 +1636,6 @@ export default class NextNodeServer extends BaseServer { return { finished: false } } if (!(await this.hasMiddleware(middleware.page))) { - console.warn(`The Edge Function for ${middleware.page} was not found`) return { finished: false } } diff --git a/test/integration/middleware-dev-update/middleware.js b/test/integration/middleware-dev-update/middleware.js new file mode 100644 index 000000000000..f71c421319fb --- /dev/null +++ b/test/integration/middleware-dev-update/middleware.js @@ -0,0 +1,9 @@ +import { NextResponse } from 'next/server' + +export function middleware(request) { + if (request.nextUrl.pathname.startsWith('/_next/')) return + + const res = NextResponse.rewrite(new URL('/', request.url)) + res.headers.set('X-From-Middleware', 'true') + return res +} diff --git a/test/integration/middleware-dev-update/pages/index.js b/test/integration/middleware-dev-update/pages/index.js new file mode 100644 index 000000000000..c37edc772d0e --- /dev/null +++ b/test/integration/middleware-dev-update/pages/index.js @@ -0,0 +1,9 @@ +export default (props) =>
{props.fromMiddleware}
+ +export async function getServerSideProps({ res }) { + return { + props: { + fromMiddleware: res.getHeader('x-from-middleware') || '', + }, + } +} diff --git a/test/integration/middleware-dev-update/test/index.test.js b/test/integration/middleware-dev-update/test/index.test.js new file mode 100644 index 000000000000..d6a574868745 --- /dev/null +++ b/test/integration/middleware-dev-update/test/index.test.js @@ -0,0 +1,125 @@ +import { + fetchViaHTTP, + File, + findPort, + killApp, + launchApp, + retry, +} from 'next-test-utils' +import { join } from 'path' +import webdriver from 'next-webdriver' + +const context = { + appDir: join(__dirname, '../'), + logs: { output: '', stdout: '', stderr: '' }, + middleware: new File(join(__dirname, '../middleware.js')), +} + +describe('Middleware development errors', () => { + beforeEach(async () => { + context.logs = { output: '', stdout: '', stderr: '' } + context.appPort = await findPort() + context.app = await launchApp(context.appDir, context.appPort, { + onStdout(msg) { + context.logs.output += msg + context.logs.stdout += msg + }, + onStderr(msg) { + context.logs.output += msg + context.logs.stderr += msg + }, + }) + }) + + afterEach(() => { + context.middleware.restore() + if (context.app) { + killApp(context.app) + } + }) + + async function assertMiddlewareFetch(hasMiddleware, path = '/') { + const res = await fetchViaHTTP(context.appPort, path) + expect(res.status).toBe(200) + expect(res.headers.get('x-from-middleware')).toBe( + hasMiddleware ? 'true' : null + ) + } + + async function assertMiddlewareRender(hasMiddleware, path = '/') { + const browser = await webdriver(context.appPort, path) + const fromMiddleware = await browser.elementById('from-middleware').text() + expect(fromMiddleware).toBe(hasMiddleware ? 'true' : '') + } + + describe('when middleware is removed', () => { + beforeEach(async () => { + await assertMiddlewareFetch(true) + context.middleware.delete() + }) + + it('sends response correctly', async () => { + await assertMiddlewareFetch(false) + await assertMiddlewareRender(false) + + // assert no extra message on stderr + expect(context.logs.stderr).toBe('') + }) + }) + + describe('when middleware is removed and re-added', () => { + beforeEach(async () => { + await assertMiddlewareFetch(true) + context.middleware.delete() + await assertMiddlewareFetch(false) + context.middleware.restore() + }) + + it('sends response correctly', async () => { + await assertMiddlewareFetch(true) + await assertMiddlewareRender(true) + }) + }) + + describe('when middleware is added', () => { + beforeEach(async () => { + context.middleware.delete() + await assertMiddlewareFetch(false) + context.middleware.restore() + }) + + it('sends response correctly', async () => { + await retry(() => assertMiddlewareFetch(true)) + await assertMiddlewareRender(true) + }) + }) + + describe('when matcher is added', () => { + beforeEach(async () => { + context.middleware.write( + context.middleware.originalContent + + ` + export const config = { + matcher: '/', + } + ` + ) + + await assertMiddlewareFetch(true) + + context.middleware.write( + context.middleware.originalContent + + ` + export const config = { + matcher: '/asdf', + } + ` + ) + }) + + it('sends response correctly', async () => { + await retry(() => assertMiddlewareFetch(true, '/asdf')) + await retry(() => assertMiddlewareRender(true, '/asdf')) + }) + }) +}) From 05b621aa9cf236bc2bc706a6076c310e68f1e30d Mon Sep 17 00:00:00 2001 From: Sukka Date: Sun, 21 Aug 2022 17:39:43 +0800 Subject: [PATCH 15/64] refactor(portal): remove useRef from portal component (#39792) The PR is similar to #39791. Currently, `` saves the container in a ref (with initial value as `null`). The update of the ref happens during the `useEffect`, after creating the corresponding HTMLElement. However, `` has to use `forceUpdate` since mutating a ref will not cause the component to update. The PR fixes that by saving the container of the `Portal` in a state, so no more `forceUpdate`. --- packages/next/client/portal/index.tsx | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/next/client/portal/index.tsx b/packages/next/client/portal/index.tsx index 7e38a485f46b..681bcab7bc79 100644 --- a/packages/next/client/portal/index.tsx +++ b/packages/next/client/portal/index.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import { useEffect, useState } from 'react' import { createPortal } from 'react-dom' type PortalProps = { @@ -6,19 +6,17 @@ type PortalProps = { type: string } -export const Portal: React.FC = ({ children, type }) => { - let portalNode = React.useRef(null) - let [, forceUpdate] = React.useState<{}>() - React.useEffect(() => { - portalNode.current = document.createElement(type) - document.body.appendChild(portalNode.current) - forceUpdate({}) +export const Portal = ({ children, type }: PortalProps) => { + const [portalNode, setPortalNode] = useState(null) + + useEffect(() => { + const element = document.createElement(type) + document.body.appendChild(element) + setPortalNode(element) return () => { - if (portalNode.current) { - document.body.removeChild(portalNode.current) - } + document.body.removeChild(element) } }, [type]) - return portalNode.current ? createPortal(children, portalNode.current) : null + return portalNode ? createPortal(children, portalNode) : null } From bf82a47393ff1924c60a09e87fde8277223a1df6 Mon Sep 17 00:00:00 2001 From: Sukka Date: Sun, 21 Aug 2022 18:10:09 +0800 Subject: [PATCH 16/64] refactor(use-intersection): remove useRef usage (#39791) The PR neither fixes a bug nor introduces a new feature. It just makes the current code be more clearer. We track the `unobserve` method (to clear the side-effect) in a ref before this PR which is not required anymore: - The `unobserve` method can only be created during the `useEffect` - The `unobserve` method will be called during `useEffect` cleans up. In short, the "life cycle" of the `unobserve` method now only lives inside the `useEffect`. So we can remove the usage of `useRef`. --- packages/next/client/use-intersection.tsx | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/packages/next/client/use-intersection.tsx b/packages/next/client/use-intersection.tsx index 8d3ecd1bece5..0474d7bad594 100644 --- a/packages/next/client/use-intersection.tsx +++ b/packages/next/client/use-intersection.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useRef, useState } from 'react' +import { useCallback, useEffect, useState } from 'react' import { requestIdleCallback, cancelIdleCallback, @@ -100,30 +100,21 @@ export function useIntersection({ }: UseIntersection): [(element: T | null) => void, boolean, () => void] { const isDisabled: boolean = disabled || !hasIntersectionObserver - const unobserve = useRef() const [visible, setVisible] = useState(false) const [element, setElement] = useState(null) useEffect(() => { if (hasIntersectionObserver) { - if (unobserve.current) { - unobserve.current() - unobserve.current = undefined - } - if (isDisabled || visible) return if (element && element.tagName) { - unobserve.current = observe( + const unobserve = observe( element, (isVisible) => isVisible && setVisible(isVisible), { root: rootRef?.current, rootMargin } ) - } - return () => { - unobserve.current?.() - unobserve.current = undefined + return unobserve } } else { if (!visible) { From 41d4aa04c4b2e637e24a26646b7023d6aab4d98b Mon Sep 17 00:00:00 2001 From: Gal Schlezinger Date: Sun, 21 Aug 2022 13:43:02 +0300 Subject: [PATCH 17/64] allow Edge Functions to stream a compressed `fetch` response (#39608) When a user tried to have the following Edge Function: ```ts export default () => fetch("https://example.vercel.sh"); ``` The Edge Function were failing. Why is that? When `fetch` was called, an implicit `Accept-Encoding` header was added to allow the origin to return a compressed response. Then, the origin will set the `Content-Encoding` header in the response, to let the client know that the body needs to be decompressed in order to be read. That creates an issue though: `response.body` will be a `ReadableStream`, or, a stream that contains binary data that decodes into _the uncompressed data_ (or, plain text!). What it means, is that `response.body` is uncompressed data, while `response.headers.get('content-encoding')` is marking the response body as compressed payload. This confuses the HTTP clients and makes them fail. This commit removes the `content-encoding`, `transfer-encoding` and `content-length` headers from the response, as the Next.js server _always_ streams Edge Function responses. ## Bug - [ ] Related issues linked using `fixes #number` - [x] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` --- packages/next/server/web/sandbox/sandbox.ts | 12 +++++++++++- .../app/pages/api/edge.js | 10 ++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/next/server/web/sandbox/sandbox.ts b/packages/next/server/web/sandbox/sandbox.ts index 947d0d6132af..773936c75017 100644 --- a/packages/next/server/web/sandbox/sandbox.ts +++ b/packages/next/server/web/sandbox/sandbox.ts @@ -6,6 +6,12 @@ import { requestToBodyStream } from '../../body-streams' export const ErrorSource = Symbol('SandboxError') +const FORBIDDEN_HEADERS = [ + 'content-length', + 'content-encoding', + 'transfer-encoding', +] + type RunnerFn = (params: { name: string env: string[] @@ -74,12 +80,16 @@ export const run = withTaggedErrors(async (params) => { : undefined try { - return await edgeFunction({ + const result = await edgeFunction({ request: { ...params.request, body: cloned && requestToBodyStream(runtime.context, cloned), }, }) + for (const headerName of FORBIDDEN_HEADERS) { + result.response.headers.delete(headerName) + } + return result } finally { await params.request.body?.finalize() } diff --git a/test/e2e/edge-compiler-can-import-blob-assets/app/pages/api/edge.js b/test/e2e/edge-compiler-can-import-blob-assets/app/pages/api/edge.js index dd24197003cd..49da52df583b 100644 --- a/test/e2e/edge-compiler-can-import-blob-assets/app/pages/api/edge.js +++ b/test/e2e/edge-compiler-can-import-blob-assets/app/pages/api/edge.js @@ -38,20 +38,14 @@ const handlers = new Map([ 'remote-full', async () => { const url = new URL('https://example.vercel.sh') - const response = await fetch(url) - const headers = new Headers(response.headers) - headers.delete('content-encoding') - return new Response(response.body, { headers, status: response.status }) + return fetch(url) }, ], [ 'remote-with-base', async () => { const url = new URL('/', 'https://example.vercel.sh') - const response = await fetch(url) - const headers = new Headers(response.headers) - headers.delete('content-encoding') - return new Response(response.body, { headers, status: response.status }) + return fetch(url) }, ], ]) From 1ebd6a1d9409d1e1dbf51adedf18aacccd39afc9 Mon Sep 17 00:00:00 2001 From: greeble <101296083+greebl3@users.noreply.github.com> Date: Sun, 21 Aug 2022 18:16:23 -0400 Subject: [PATCH 18/64] Update next.js.configs line number (#39802) --- docs/api-reference/next.config.js/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-reference/next.config.js/introduction.md b/docs/api-reference/next.config.js/introduction.md index 994c5c78cfc5..e708004bd1a2 100644 --- a/docs/api-reference/next.config.js/introduction.md +++ b/docs/api-reference/next.config.js/introduction.md @@ -80,7 +80,7 @@ module.exports = (phase, { defaultConfig }) => { } ``` -The commented lines are the place where you can put the configs allowed by `next.config.js`, which are [defined in this file](https://github.com/vercel/next.js/blob/canary/packages/next/server/config-shared.ts#L137). +The commented lines are the place where you can put the configs allowed by `next.config.js`, which are [defined in this file](https://github.com/vercel/next.js/blob/canary/packages/next/server/config-shared.ts#L158). However, none of the configs are required, and it's not necessary to understand what each config does. Instead, search for the features you need to enable or modify in this section and they will show you what to do. From 74fb7ba03ed1d795517a9bbecf0e20bfa0e7191f Mon Sep 17 00:00:00 2001 From: Henrik Wenz Date: Mon, 22 Aug 2022 00:38:48 +0200 Subject: [PATCH 19/64] =?UTF-8?q?[Docs]=C2=A0Update=20mongodb=20example=20?= =?UTF-8?q?(#39658)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Changelog - Updated deps - Migrated to typescript ## Documentation / Examples - [x] Make sure the linting passes by running `pnpm lint` - [x] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples) --- .../lib/{mongodb.js => mongodb.ts} | 4 ++ examples/with-mongodb/package.json | 11 ++-- .../pages/{index.js => index.tsx} | 51 ++++++++++--------- examples/with-mongodb/tsconfig.json | 20 ++++++++ examples/with-mongodb/types/mongodb.d.ts | 5 ++ 5 files changed, 64 insertions(+), 27 deletions(-) rename examples/with-mongodb/lib/{mongodb.js => mongodb.ts} (90%) rename examples/with-mongodb/pages/{index.js => index.tsx} (97%) create mode 100644 examples/with-mongodb/tsconfig.json create mode 100644 examples/with-mongodb/types/mongodb.d.ts diff --git a/examples/with-mongodb/lib/mongodb.js b/examples/with-mongodb/lib/mongodb.ts similarity index 90% rename from examples/with-mongodb/lib/mongodb.js rename to examples/with-mongodb/lib/mongodb.ts index 0eef49bf4993..7aaf63e04cec 100644 --- a/examples/with-mongodb/lib/mongodb.js +++ b/examples/with-mongodb/lib/mongodb.ts @@ -1,5 +1,9 @@ import { MongoClient } from 'mongodb' +if (!process.env.MONGODB_URI) { + throw new Error('Invalid environment variable: "MONGODB_URI"') +} + const uri = process.env.MONGODB_URI const options = {} diff --git a/examples/with-mongodb/package.json b/examples/with-mongodb/package.json index f03fe2598d01..84979ab24b00 100644 --- a/examples/with-mongodb/package.json +++ b/examples/with-mongodb/package.json @@ -6,9 +6,14 @@ "start": "next start" }, "dependencies": { - "mongodb": "^4.1.3", + "mongodb": "^4.8.1", "next": "latest", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@types/node": "18.7.5", + "@types/react": "16.9.17", + "typescript": "4.6.3" } } diff --git a/examples/with-mongodb/pages/index.js b/examples/with-mongodb/pages/index.tsx similarity index 97% rename from examples/with-mongodb/pages/index.js rename to examples/with-mongodb/pages/index.tsx index 86b32f11343c..5d4050150298 100644 --- a/examples/with-mongodb/pages/index.js +++ b/examples/with-mongodb/pages/index.tsx @@ -1,7 +1,33 @@ import Head from 'next/head' import clientPromise from '../lib/mongodb' +import { InferGetServerSidePropsType } from 'next' -export default function Home({ isConnected }) { +export async function getServerSideProps(context) { + try { + await clientPromise + // `await clientPromise` will use the default database passed in the MONGODB_URI + // However you can use another database (e.g. myDatabase) by replacing the `await clientPromise` with the following code: + // + // `const client = await clientPromise` + // `const db = client.db("myDatabase")` + // + // Then you can execute queries against your database like so: + // db.find({}) or any of the MongoDB Node Driver commands + + return { + props: { isConnected: true }, + } + } catch (e) { + console.error(e) + return { + props: { isConnected: false }, + } + } +} + +export default function Home({ + isConnected, +}: InferGetServerSidePropsType) { return (
@@ -221,26 +247,3 @@ export default function Home({ isConnected }) {
) } - -export async function getServerSideProps(context) { - try { - await clientPromise - // `await clientPromise` will use the default database passed in the MONGODB_URI - // However you can use another database (e.g. myDatabase) by replacing the `await clientPromise` with the following code: - // - // `const client = await clientPromise` - // `const db = client.db("myDatabase")` - // - // Then you can execute queries against your database like so: - // db.find({}) or any of the MongoDB Node Driver commands - - return { - props: { isConnected: true }, - } - } catch (e) { - console.error(e) - return { - props: { isConnected: false }, - } - } -} diff --git a/examples/with-mongodb/tsconfig.json b/examples/with-mongodb/tsconfig.json new file mode 100644 index 000000000000..50bcb22f653d --- /dev/null +++ b/examples/with-mongodb/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "incremental": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve" + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} diff --git a/examples/with-mongodb/types/mongodb.d.ts b/examples/with-mongodb/types/mongodb.d.ts new file mode 100644 index 000000000000..440c0b199621 --- /dev/null +++ b/examples/with-mongodb/types/mongodb.d.ts @@ -0,0 +1,5 @@ +import { MongoClient } from 'mongodb' + +declare global { + var _mongoClientPromise: Promise +} From bc4d98af7209f4ef4b3c71d55da7b03b45e67182 Mon Sep 17 00:00:00 2001 From: Kasper Aamodt Date: Mon, 22 Aug 2022 00:56:51 +0200 Subject: [PATCH 20/64] Convert with-goober example to TS (#39761) ## Documentation / Examples - [x] Make sure the linting passes by running `pnpm lint` - [x] The examples guidelines are followed from [our contributing doc] Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com> --- examples/with-goober/package.json | 13 ++++++++---- .../with-goober/pages/{_app.js => _app.tsx} | 9 +++++---- .../pages/{_document.js => _document.tsx} | 19 ++++++++++++++---- .../with-goober/pages/{index.js => index.tsx} | 0 examples/with-goober/tsconfig.json | 20 +++++++++++++++++++ 5 files changed, 49 insertions(+), 12 deletions(-) rename examples/with-goober/pages/{_app.js => _app.tsx} (53%) rename examples/with-goober/pages/{_document.js => _document.tsx} (63%) rename examples/with-goober/pages/{index.js => index.tsx} (100%) create mode 100644 examples/with-goober/tsconfig.json diff --git a/examples/with-goober/package.json b/examples/with-goober/package.json index 8793b454ca5b..a92c1009be0d 100644 --- a/examples/with-goober/package.json +++ b/examples/with-goober/package.json @@ -6,10 +6,15 @@ "start": "next start" }, "dependencies": { - "goober": "^2.0.2", - "goober-autoprefixer": "^1.2.0", + "goober": "^2.1.10", + "goober-autoprefixer": "^1.2.3", "next": "latest", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@types/node": "^18.7.7", + "@types/react": "^18.0.17", + "typescript": "^4.7.4" } } diff --git a/examples/with-goober/pages/_app.js b/examples/with-goober/pages/_app.tsx similarity index 53% rename from examples/with-goober/pages/_app.js rename to examples/with-goober/pages/_app.tsx index 1c7e527a9750..09fb2bf00f1b 100644 --- a/examples/with-goober/pages/_app.js +++ b/examples/with-goober/pages/_app.tsx @@ -1,12 +1,13 @@ -import React from 'react' -import { prefix } from 'goober-autoprefixer' +import { createElement } from 'react' import { setup } from 'goober' +import { prefix } from 'goober/prefixer' +import type { AppProps } from 'next/app' // goober's needs to know how to render the `styled` nodes. // So to let it know, we run the `setup` function with the // `createElement` function and prefixer function. -setup(React.createElement, prefix) +setup(createElement, prefix) -export default function App({ Component, pageProps }) { +export default function App({ Component, pageProps }: AppProps) { return } diff --git a/examples/with-goober/pages/_document.js b/examples/with-goober/pages/_document.tsx similarity index 63% rename from examples/with-goober/pages/_document.js rename to examples/with-goober/pages/_document.tsx index c7550d37d991..b3c283a033c7 100644 --- a/examples/with-goober/pages/_document.js +++ b/examples/with-goober/pages/_document.tsx @@ -1,10 +1,19 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' import { extractCss } from 'goober' +import NextDocument, { + DocumentContext, + Head, + Html, + Main, + NextScript, +} from 'next/document' -export default class MyDocument extends Document { - static async getInitialProps({ renderPage }) { +type Props = { + css: string +} + +class Document extends NextDocument { + static async getInitialProps({ renderPage }: DocumentContext) { const page = await renderPage() - // Extrach the css for each page render const css = extractCss() return { ...page, css } } @@ -27,3 +36,5 @@ export default class MyDocument extends Document { ) } } + +export default Document diff --git a/examples/with-goober/pages/index.js b/examples/with-goober/pages/index.tsx similarity index 100% rename from examples/with-goober/pages/index.js rename to examples/with-goober/pages/index.tsx diff --git a/examples/with-goober/tsconfig.json b/examples/with-goober/tsconfig.json new file mode 100644 index 000000000000..b8d597880a1a --- /dev/null +++ b/examples/with-goober/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": false, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} From b7c2bd104d48781021d229dce7066fc9f36d6a1a Mon Sep 17 00:00:00 2001 From: Chase Adams Date: Sun, 21 Aug 2022 17:25:10 -0600 Subject: [PATCH 21/64] fix meaninglessFileNames type in compiler options schema (#39698) # Bug I would assume that this should be generated from TypeScript, but based on the [original PR](https://github.com/vercel/next.js/pull/38498/files) it wasn't clear that there was a way to generate these automatically. Fixes the type of `styledComponents. topLevelImportPaths` and `styledComponents.meaninglessFileNames` so that it matches the [TypeScript type](https://github.com/vercel/next.js/blob/canary/packages/next/server/config-shared.ts#L457). This was causing a warning here: ``` warn - Invalid next.config.js options detected: - The value at .compiler.styledComponents must be a boolean but it was an object. - The value at .compiler.styledComponents.meaninglessFileNames must be a boolean but it was an array. - The value at .compiler.styledComponents must match exactly one schema in oneOf. ``` ## Documentation / Examples - [x] Make sure the linting passes by running `pnpm lint` Co-authored-by: chaseadamsio <103162876+chaseadamsio@users.noreply.github.com> --- packages/next/server/config-schema.ts | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/next/server/config-schema.ts b/packages/next/server/config-schema.ts index 3895876984c1..db74156d29e3 100644 --- a/packages/next/server/config-schema.ts +++ b/packages/next/server/config-schema.ts @@ -111,11 +111,16 @@ const configSchema = { type: 'boolean', }, topLevelImportPaths: { - type: 'array', - items: { - type: 'string', - minLength: 1, - }, + oneOf: [ + { type: 'boolean' }, + { + type: 'array', + items: { + type: 'string', + minLength: 1, + }, + }, + ], }, ssr: { type: 'boolean', @@ -124,7 +129,16 @@ const configSchema = { type: 'boolean', }, meaninglessFileNames: { - type: 'boolean', + oneOf: [ + { type: 'boolean' }, + { + type: 'array', + items: { + type: 'string', + minLength: 1, + }, + }, + ], }, minify: { type: 'boolean', From 63651a63de417e5d1fa8ed068fc891ea4dbba0db Mon Sep 17 00:00:00 2001 From: Faris Masad Date: Sun, 21 Aug 2022 19:30:18 -0700 Subject: [PATCH 22/64] Add note about using the /_error page directly to custom error page article (#39671) See https://github.com/vercel/next.js/issues/39144 It's not completely clear that `/_error` should not be used as a normal page. Added a note under `Caveats` in the custom error page article --- docs/advanced-features/custom-error-page.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/advanced-features/custom-error-page.md b/docs/advanced-features/custom-error-page.md index e3f4b2ddf79d..6b3a2b860b1b 100644 --- a/docs/advanced-features/custom-error-page.md +++ b/docs/advanced-features/custom-error-page.md @@ -98,3 +98,4 @@ If you have a custom `Error` component be sure to import that one instead. `next ### Caveats - `Error` does not currently support Next.js [Data Fetching methods](/docs/basic-features/data-fetching.md) like [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md) or [`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md). +- `_error`, like `_app`, is a reserved pathname. `_error` is used to define the customized layouts and behaviors of the error pages. `/_error` will render 404 when accessed directly via [routing](/docs/routing/introduction) or rendering in a [custom server](/docs/advanced-features/custom-server). From 28746520b630fb323b51ac5127906bc560287d1f Mon Sep 17 00:00:00 2001 From: Kiko Beats Date: Mon, 22 Aug 2022 11:28:58 +0200 Subject: [PATCH 23/64] build: upgrade edge-runtime (#39749) https://github.com/vercel/edge-runtime/compare/v1.1.0-beta.26...v1.1.0-beta.27 --- package.json | 2 +- .../@edge-runtime/primitives/console.js | 420 ++++++++++++++---- .../@edge-runtime/primitives/package.json | 2 +- .../babel-packages/packages-bundle.js | 2 +- packages/next/compiled/edge-runtime/index.js | 2 +- packages/next/package.json | 4 +- pnpm-lock.yaml | 93 ++-- 7 files changed, 378 insertions(+), 147 deletions(-) diff --git a/package.json b/package.json index fbc7d8c6f297..b577e007ef80 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "@babel/plugin-proposal-object-rest-spread": "7.14.7", "@babel/preset-flow": "7.14.5", "@babel/preset-react": "7.14.5", - "@edge-runtime/jest-environment": "1.1.0-beta.26", + "@edge-runtime/jest-environment": "1.1.0-beta.27", "@fullhuman/postcss-purgecss": "1.3.0", "@mdx-js/loader": "0.18.0", "@next/bundle-analyzer": "workspace:*", diff --git a/packages/next/compiled/@edge-runtime/primitives/console.js b/packages/next/compiled/@edge-runtime/primitives/console.js index ace6cc41b553..e6c27210c2e4 100644 --- a/packages/next/compiled/@edge-runtime/primitives/console.js +++ b/packages/next/compiled/@edge-runtime/primitives/console.js @@ -34,11 +34,87 @@ var init_define_process = __esm({ // ../format/dist/index.js var require_dist = __commonJS({ - "../format/dist/index.js"(exports) { - "use strict"; + "../format/dist/index.js"(exports, module2) { init_define_process(); - Object.defineProperty(exports, "__esModule", { value: true }); - exports.createFormat = void 0; + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export2 = /* @__PURE__ */ __name((target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }, "__export"); + var __copyProps2 = /* @__PURE__ */ __name((to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }, "__copyProps"); + var __toCommonJS2 = /* @__PURE__ */ __name((mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod), "__toCommonJS"); + var src_exports = {}; + __export2(src_exports, { + createFormat: () => createFormat2 + }); + module2.exports = __toCommonJS2(src_exports); + var ReflectGetOwnPropertyDescriptor = Reflect.getOwnPropertyDescriptor; + function GetOwnGetter(target, key) { + const descriptor = ReflectGetOwnPropertyDescriptor(target, key); + return descriptor ? descriptor.get : void 0; + } + __name(GetOwnGetter, "GetOwnGetter"); + var ReflectGetPrototypeOf = Reflect.getPrototypeOf; + var TypedArray = ReflectGetPrototypeOf(Uint8Array); + var ArrayPrototypeFilter = Array.prototype.filter; + var ArrayPrototypePush = Array.prototype.push; + var DatePrototypeGetTime = Date.prototype.getTime; + var DatePrototypeToISOString = Date.prototype.toISOString; + var ObjectGetOwnPropertyDescriptors = Object.getOwnPropertyDescriptors; + var ObjectGetOwnPropertyNames = Object.getOwnPropertyNames; + var ObjectGetOwnPropertySymbols = Object.getOwnPropertySymbols; + var ObjectKeys = Object.keys; + var ObjectPrototypePropertyIsEnumerable = Object.prototype.propertyIsEnumerable; + var ObjectPrototypeToString = Object.prototype.toString; + var MapPrototypeGetSize = GetOwnGetter(Map.prototype, "size"); + var SetPrototypeGetSize = GetOwnGetter(Set.prototype, "size"); + var StringPrototypeIncludes = String.prototype.includes; + var SymbolIterator = Symbol.iterator; + var SymbolPrototypeToString = Symbol.prototype.toString; + var TypedArrayPrototypeGetLength = GetOwnGetter(TypedArray.prototype, "length"); + var typedArrayStrings = /* @__PURE__ */ new Set([ + "[object BigInt64Array]", + "[object BigUint64Array]", + "[object Float32Array]", + "[object Float64Array]", + "[object Int8Array]", + "[object Int16Array]", + "[object Int32Array]", + "[object Uint8Array]", + "[object Uint8ClampedArray]", + "[object Uint16Array]", + "[object Uint32Array]" + ]); + function getOwnNonIndexProperties(object, filter) { + const indexes = Array.isArray(object) || isTypedArray(object) ? new Set([...object.keys()].map((v) => v.toString())) : void 0; + return Object.entries(ObjectGetOwnPropertyDescriptors(object)).filter(([key, desc]) => { + if (indexes && indexes.has(key)) { + return false; + } + if (filter === 1 && !desc.enumerable) { + return false; + } + return true; + }).map(([key]) => key); + } + __name(getOwnNonIndexProperties, "getOwnNonIndexProperties"); + var isTypedArray = /* @__PURE__ */ __name((value) => kind(value, "object") && typedArrayStrings.has(ObjectPrototypeToString.call(value)), "isTypedArray"); + function kind(value, type) { + return typeof value === type; + } + __name(kind, "kind"); + var getConstructorName = /* @__PURE__ */ __name((object) => object.constructor.name, "getConstructorName"); + var getPrefix = /* @__PURE__ */ __name((constructor, size = "") => `${constructor}${size} `, "getPrefix"); function createFormat2(opts = {}) { if (opts.customInspectSymbol === void 0) { opts.customInspectSymbol = Symbol.for("edge-runtime.inspect.custom"); @@ -65,12 +141,24 @@ var require_dist = __commonJS({ switch (token) { case "%s": { const arg = args[index++]; - return hasCustomSymbol(arg, customInspectSymbol) ? format2(arg[customInspectSymbol]()) : String(arg); + if (hasCustomSymbol(arg, customInspectSymbol)) { + return format2(arg[customInspectSymbol]()); + } else if (isDate(arg) || isError(arg) || kind(arg, "bigint")) { + return format2(arg); + } else { + return String(arg); + } } case "%j": return safeStringify(args[index++]); - case "%d": - return String(Number(args[index++])); + case "%d": { + const arg = args[index++]; + if (kind(arg, "bigint")) { + return format2(arg); + } else { + return String(Number(arg)); + } + } case "%O": return inspect(args[index++], { customInspectSymbol }); case "%o": @@ -79,8 +167,14 @@ var require_dist = __commonJS({ showHidden: true, depth: 4 }); - case "%i": - return String(parseInt(args[index++], 10)); + case "%i": { + const arg = args[index++]; + if (kind(arg, "bigint")) { + return format2(arg); + } else { + return String(parseInt(arg, 10)); + } + } case "%f": return String(parseFloat(args[index++])); default: @@ -97,7 +191,7 @@ var require_dist = __commonJS({ return str; } __name(format2, "format"); - function formatValue(ctx, value, recurseTimes) { + function formatValue(ctx, value, recurseTimes, typedArray) { if (hasCustomSymbol(value, customInspectSymbol)) { return format2(value[customInspectSymbol]()); } @@ -105,58 +199,133 @@ var require_dist = __commonJS({ if (formattedPrimitive !== void 0) { return formattedPrimitive; } - const symbols = Object.getOwnPropertySymbols(value); - if (symbols.length > 0) { - symbols.forEach((symbol) => { - const obj = value; - const symbolKey = `[${symbol.toString()}]`; - obj[symbolKey] = obj[symbol]; - delete obj[symbol]; - }); + if (ctx.seen.includes(value)) { + let index = 1; + if (ctx.circular === void 0) { + ctx.circular = /* @__PURE__ */ new Map(); + ctx.circular.set(value, index); + } else { + index = ctx.circular.get(value); + if (index === void 0) { + index = ctx.circular.size + 1; + ctx.circular.set(value, index); + } + } + return `[Circular *${index}]`; } - const keys = ctx.showHidden ? Object.getOwnPropertyNames(value) : Object.keys(value); - const visibleKeys = /* @__PURE__ */ new Set(); - keys.forEach((key) => visibleKeys.add(key)); - if (keys.length === 0) { - if (kind(value, "function")) { - return `[Function${value.name ? ": " + value.name : ""}]`; + return formatRaw(ctx, value, recurseTimes); + } + __name(formatValue, "formatValue"); + function formatRaw(ctx, value, recurseTimes) { + let keys = []; + const constructor = getConstructorName(value); + let base = ""; + let formatter = /* @__PURE__ */ __name(() => [], "formatter"); + let braces = ["", ""]; + let noIterator = true; + const filter = ctx.showHidden ? 0 : 1; + if (SymbolIterator in value) { + noIterator = false; + if (Array.isArray(value)) { + const prefix = constructor !== "Array" ? getPrefix(constructor, `(${value.length})`) : ""; + keys = getOwnNonIndexProperties(value, filter); + braces = [`${prefix}[`, "]"]; + if (value.length === 0 && keys.length === 0) { + return `${braces[0]}]`; + } + formatter = formatArray; + } else if (isSet(value)) { + const size = SetPrototypeGetSize.call(value); + const prefix = getPrefix(constructor, `(${size})`); + keys = getKeys(value, ctx.showHidden); + formatter = formatSet; + if (size === 0 && keys.length === 0) { + return `${prefix}{}`; + } + braces = [`${prefix}{`, "}"]; + } else if (isMap(value)) { + const size = MapPrototypeGetSize.call(value); + const prefix = getPrefix(constructor, `(${size})`); + keys = getKeys(value, ctx.showHidden); + formatter = formatMap; + if (size === 0 && keys.length === 0) { + return `${prefix}{}`; + } + braces = [`${prefix}{`, "}"]; + } else if (isTypedArray(value)) { + keys = getOwnNonIndexProperties(value, filter); + const size = TypedArrayPrototypeGetLength.call(value); + const prefix = getPrefix(constructor, `(${size})`); + braces = [`${prefix}[`, "]"]; + if (value.length === 0 && keys.length === 0) + return `${braces[0]}]`; + formatter = formatTypedArray.bind(null, size); + } else { + noIterator = true; + } + } + let isValueFunction = false; + if (noIterator) { + keys = getKeys(value, ctx.showHidden); + braces = ["{", "}"]; + if (constructor === "Object") { + if (keys.length === 0) { + return `{}`; + } + } else if (kind(value, "function")) { + isValueFunction = true; + base = `[Function${value.name ? ": " + value.name : ""}]`; + if (keys.length === 0) { + return base; + } } else if (isRegExp(value)) { - return RegExp.prototype.toString.call(value); + base = RegExp.prototype.toString.call(value); + if (keys.length === 0) { + return base; + } + base = " " + base; } else if (isDate(value)) { - return Date.prototype.toString.call(value); + base = Number.isNaN(DatePrototypeGetTime.call(value)) ? Date.prototype.toString.call(value) : DatePrototypeToISOString.call(value); + if (keys.length === 0) { + return base; + } + base = " " + base; } else if (isError(value)) { - return formatError(value); + base = formatError(value); + if (keys.length === 0) { + return base; + } + base = " " + base; } else if (hasCustomSymbol(value, ctx.customInspectSymbol)) { - return format2(value[ctx.customInspectSymbol]()); + base = format2(value[ctx.customInspectSymbol]()); + if (keys.length === 0) { + return base; + } + base = " " + base; + } else { + braces[0] = `${getPrefix(constructor)}{`; } } - const isValueFunction = kind(value, "function"); - const isValueArray = Array.isArray(value); - let base = ""; - if (isValueFunction) { - base = `[Function${value.name ? ": " + value.name : ""}]`; - } else if (isRegExp(value)) { - base = " " + RegExp.prototype.toString.call(value); - } else if (isDate(value)) { - base = " " + Date.prototype.toUTCString.call(value); - } else if (isError(value)) { - base = " " + formatError(value); - } else if (hasCustomSymbol(value, ctx.customInspectSymbol)) { - base = " " + value[ctx.customInspectSymbol](); - } - const braces = isValueArray ? ["[", "]"] : isValueFunction ? ["", ""] : ["{", "}"]; - if (keys.length === 0 && (!isValueArray || value.length === 0)) { - return braces[0] + base + braces[1]; - } if (recurseTimes && recurseTimes < 0) { return isRegExp(value) ? RegExp.prototype.toString.call(value) : "[Object]"; } ctx.seen.push(value); - let output = isValueArray ? formatArray(ctx, value, recurseTimes, visibleKeys, keys) : keys.map((key) => formatProperty(ctx, value, recurseTimes, visibleKeys, key, false)); + const visibleKeys = new Set(keys); + const output = formatter(ctx, value, recurseTimes, visibleKeys, keys); + for (let i = 0; i < keys.length; i++) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, keys[i], false)); + } + if (ctx.circular !== void 0) { + const index = ctx.circular.get(value); + if (index !== void 0) { + const reference = ``; + base = base === "" ? reference : `${reference} ${base}`; + } + } ctx.seen.pop(); return reduceToSingleString(output, base, braces, isValueFunction); } - __name(formatValue, "formatValue"); + __name(formatRaw, "formatRaw"); function inspect(value, opts2) { opts2 = Object.assign({ seen: [], depth: 2 }, opts2); return formatValue(opts2, value, opts2.depth); @@ -168,34 +337,26 @@ var require_dist = __commonJS({ const desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { + if (desc.value !== void 0) { + str = formatValue(ctx, desc.value, recurseTimes); + } else if (desc.get) { str = desc.set ? "[Getter/Setter]" : "[Getter]"; } else if (desc.set) { str = "[Setter]"; + } else { + str = "undefined"; } - if (!visibleKeys.has(key)) { - name = "[" + key + "]"; + if (isArray) { + return str; } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - str = formatValue(ctx, desc.value, recurseTimes === null || recurseTimes === void 0 ? null : recurseTimes - 1); - if (str.indexOf("\n") > -1) { - if (isArray) { - str = str.split("\n").map((line) => ` ${line}`).join("\n").slice(2); - } else { - str = "\n" + str.split("\n").map((line) => ` ${line}`).join("\n"); - } - } - } else { - str = "[Circular]"; - } - } - if (name === void 0) { - if (isArray && key.match(/^\d+$/)) { - return str; - } + if (kind(key, "symbol")) { + name = `[${SymbolPrototypeToString.call(key)}]`; + } else if (!visibleKeys.has(key)) { + name = "[" + key + "]"; + } else { + name = key; } - return `${key}: ${str}`; + return `${name}: ${str}`; } __name(formatProperty, "formatProperty"); function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { @@ -207,18 +368,53 @@ var require_dist = __commonJS({ output.push(""); } } - keys.forEach((key) => { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, key, true)); - } - }); return output; } __name(formatArray, "formatArray"); + function formatTypedArray(length, ctx, value, recurseTimes) { + const output = new Array(length); + for (let i = 0; i < length; ++i) { + output[i] = value.length > 0 && kind(value[0], "number") ? String(value[i]) : formatBigInt(value[i]); + } + if (ctx.showHidden) { + for (const key of [ + "BYTES_PER_ELEMENT", + "length", + "byteLength", + "byteOffset", + "buffer" + ]) { + const str = formatValue(ctx, value[key], recurseTimes, true); + ArrayPrototypePush.call(output, `[${String(key)}]: ${str}`); + } + } + return output; + } + __name(formatTypedArray, "formatTypedArray"); + function formatSet(ctx, value, recurseTimes) { + const output = []; + for (const v of value) { + ArrayPrototypePush.call(output, formatValue(ctx, v, recurseTimes)); + } + return output; + } + __name(formatSet, "formatSet"); + function formatMap(ctx, value, recurseTimes) { + const output = []; + for (const { 0: k, 1: v } of value) { + output.push(`${formatValue(ctx, k, recurseTimes)} => ${formatValue(ctx, v, recurseTimes)}`); + } + return output; + } + __name(formatMap, "formatMap"); return format2; } __name(createFormat2, "createFormat"); - exports.createFormat = createFormat2; + function formatBigInt(bigint) { + const str = String(bigint); + return `${str}n`; + } + __name(formatBigInt, "formatBigInt"); function formatPrimitive(value) { if (value === null) return "null"; @@ -232,7 +428,7 @@ var require_dist = __commonJS({ if (kind(value, "number")) return "" + value; if (kind(value, "bigint")) - return "" + value; + return formatBigInt(value); if (kind(value, "symbol")) return value.toString(); } @@ -241,10 +437,6 @@ var require_dist = __commonJS({ return value !== null && kind(value, "object") && customInspectSymbol in value && kind(value[customInspectSymbol], "function"); } __name(hasCustomSymbol, "hasCustomSymbol"); - function kind(value, type) { - return typeof value === type; - } - __name(kind, "kind"); function isRegExp(value) { return kind(value, "object") && Object.prototype.toString.call(value) === "[object RegExp]"; } @@ -257,25 +449,42 @@ var require_dist = __commonJS({ return kind(value, "object") && (Object.prototype.toString.call(value) === "[object Error]" || value instanceof Error); } __name(isError, "isError"); + function isMap(value) { + return kind(value, "object") && Object.prototype.toString.call(value) === "[object Map]"; + } + __name(isMap, "isMap"); + function isSet(value) { + return kind(value, "object") && Object.prototype.toString.call(value) === "[object Set]"; + } + __name(isSet, "isSet"); + function isBelowBreakLength(output, start, base) { + const breakLength = 80; + let totalLength = output.length + start; + if (totalLength + output.length > breakLength) { + return false; + } + for (let i = 0; i < output.length; i++) { + totalLength += output[i].length; + if (totalLength > breakLength) { + return false; + } + } + return base === "" || !StringPrototypeIncludes.call(base, "\n"); + } + __name(isBelowBreakLength, "isBelowBreakLength"); function reduceToSingleString(output, base, braces, isValueFunction) { - const length = output.reduce((prev, cur) => { - return prev + cur.replace(/\u001b\[\d\d?m/g, "").length + 1; - }, 0); - if (length > 60) { - const prefix2 = isValueFunction ? " {" : ""; - const suffix2 = isValueFunction ? "\n}" : " "; - return braces[0] + (base === "" ? "" : base + prefix2 + "\n ") + ` ${output.join(",\n ")}` + suffix2 + braces[1]; + const start = output.length + braces[0].length + base.length + 10; + if (!isBelowBreakLength(output, start, base)) { + return (base ? base + " " : "") + braces[0] + "\n " + output.join(",\n ") + "\n" + braces[1]; } - const prefix = isValueFunction ? " { " : " "; - const suffix = isValueFunction ? " } " : " "; - return (braces[0] + base + prefix + output.join(", ") + suffix + braces[1]).trim(); + return ((base ? base + " " : "") + braces[0] + " " + output.join(", ") + " " + braces[1]).trim(); } __name(reduceToSingleString, "reduceToSingleString"); - function safeStringify(object) { - if (Array.isArray(object)) { - object = object.map((element) => JSON.parse(JSON.stringify(element, makeCircularReplacer()))); + function safeStringify(input) { + if (Array.isArray(input)) { + input = input.map((element) => JSON.parse(JSON.stringify(element, makeCircularReplacer()))); } - return JSON.stringify(object, makeCircularReplacer()); + return JSON.stringify(input, makeCircularReplacer()); } __name(safeStringify, "safeStringify"); function makeCircularReplacer() { @@ -290,6 +499,27 @@ var require_dist = __commonJS({ }; } __name(makeCircularReplacer, "makeCircularReplacer"); + function getKeys(value, showHidden = false) { + let keys; + const symbols = ObjectGetOwnPropertySymbols(value); + if (showHidden) { + keys = ObjectGetOwnPropertyNames(value); + if (symbols.length !== 0) + ArrayPrototypePush.apply(keys, symbols); + } else { + try { + keys = ObjectKeys(value); + } catch (err) { + keys = ObjectGetOwnPropertyNames(value); + } + if (symbols.length !== 0) { + const filter = /* @__PURE__ */ __name((key) => ObjectPrototypePropertyIsEnumerable.call(value, key), "filter"); + ArrayPrototypePush.apply(keys, ArrayPrototypeFilter.call(symbols, filter)); + } + } + return keys; + } + __name(getKeys, "getKeys"); } }); diff --git a/packages/next/compiled/@edge-runtime/primitives/package.json b/packages/next/compiled/@edge-runtime/primitives/package.json index f313ba0b2bba..fa65adbc5366 100644 --- a/packages/next/compiled/@edge-runtime/primitives/package.json +++ b/packages/next/compiled/@edge-runtime/primitives/package.json @@ -1 +1 @@ -{"name":"@edge-runtime/primitives","version":"1.1.0-beta.26","main":"./index.js","license":"MPLv2"} +{"name":"@edge-runtime/primitives","version":"1.1.0-beta.27","main":"./index.js","license":"MPLv2"} diff --git a/packages/next/compiled/babel-packages/packages-bundle.js b/packages/next/compiled/babel-packages/packages-bundle.js index 05a6b599f3cb..274302d9cd29 100644 --- a/packages/next/compiled/babel-packages/packages-bundle.js +++ b/packages/next/compiled/babel-packages/packages-bundle.js @@ -141,7 +141,7 @@ ${n.types.cloneNode(v)} !== null && ${n.types.cloneNode(x)} !== void 0`;y.replaceWith(n.types.logicalExpression("&&",e,j));y=o.skipTransparentExprWrappers(y.get("right"))}else{const e=r?l`${n.types.cloneNode(v)} == null`:l` ${n.types.cloneNode(v)} === null || ${n.types.cloneNode(x)} === void 0`;const t=u?l`true`:l`void 0`;y.replaceWith(n.types.conditionalExpression(e,t,j));y=o.skipTransparentExprWrappers(y.get("alternate"))}}}var c=s.declare(((e,t)=>{var r,s;e.assertVersion(7);const{loose:a=false}=t;const n=(r=e.assumption("noDocumentAll"))!=null?r:a;const o=(s=e.assumption("pureGetters"))!=null?s:a;return{name:"proposal-optional-chaining",inherits:i["default"].default,visitor:{"OptionalCallExpression|OptionalMemberExpression"(e){transform(e,{noDocumentAll:n,pureGetters:o})}}}}));t["default"]=c;t.transform=transform},7806:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=r(2924);var n=(0,s.declare)(((e,t)=>{e.assertVersion(7);return(0,a.createClassFeaturePlugin)({name:"proposal-private-methods",api:e,feature:a.FEATURES.privateMethods,loose:t.loose,manipulateOptions(e,t){t.plugins.push("classPrivateMethods")}})}));t["default"]=n},6722:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=r(1603);var n=r(2924);var o=r(9102);var i=(0,s.declare)(((e,t)=>{e.assertVersion(7);const{types:r,template:s}=e;const{loose:i}=t;const l=new WeakMap;const c=new WeakMap;function unshadow(e,t,r){while(r!==t){if(r.hasOwnBinding(e))r.rename(e);r=r.parent}}function injectToFieldInit(e,t,s=false){if(e.node.value){if(s){e.get("value").insertBefore(t)}else{e.get("value").insertAfter(t)}}else{e.set("value",r.unaryExpression("void",t))}}function injectInitialization(e,t){let s;let a;for(const t of e.get("body.body")){if((t.isClassProperty()||t.isClassPrivateProperty())&&!t.node.static){s=t;break}if(!a&&t.isClassMethod({kind:"constructor"})){a=t}}if(s){injectToFieldInit(s,t,true)}else{(0,n.injectInitialization)(e,a,[r.expressionStatement(t)])}}function getWeakSetId(e,t,a,n="",i){let c=l.get(a.node);if(!c){c=t.scope.generateUidIdentifier(`${n||""} brandCheck`);l.set(a.node,c);i(a,s.expression.ast`${r.cloneNode(c)}.add(this)`);const e=r.newExpression(r.identifier("WeakSet"),[]);(0,o.default)(e);t.insertBefore(s.ast`var ${c} = ${e}`)}return r.cloneNode(c)}return{name:"proposal-private-property-in-object",inherits:a.default,pre(){(0,n.enableFeature)(this.file,n.FEATURES.privateIn,i)},visitor:{BinaryExpression(e){const{node:t}=e;if(t.operator!=="in")return;if(!r.isPrivateName(t.left))return;const{name:a}=t.left.id;let n;const o=e.findParent((e=>{if(!e.isClass())return false;n=e.get("body.body").find((({node:e})=>r.isPrivate(e)&&e.key.id.name===a));return!!n}));if(o.parentPath.scope.path.isPattern()){o.replaceWith(s.ast`(() => ${o.node})()`);return}if(n.isMethod()){if(n.node.static){if(o.node.id){unshadow(o.node.id.name,o.scope,e.scope)}else{o.set("id",e.scope.generateUidIdentifier("class"))}e.replaceWith(s.expression.ast` ${r.cloneNode(o.node.id)} === ${e.node.right} - `)}else{var i;const t=getWeakSetId(l,o,o,(i=o.node.id)==null?void 0:i.name,injectInitialization);e.replaceWith(s.expression.ast`${t}.has(${e.node.right})`)}}else{const t=getWeakSetId(c,o,n,n.node.key.id.name,injectToFieldInit);e.replaceWith(s.expression.ast`${t}.has(${e.node.right})`)}}}}}));t["default"]=i},8226:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(6741);var a=r(3242);var n=(0,a.declare)(((e,t)=>{e.assertVersion(7);const{useUnicodeFlag:r=true}=t;if(typeof r!=="boolean"){throw new Error(".useUnicodeFlag must be a boolean, or undefined")}return(0,s.createRegExpFeaturePlugin)({name:"proposal-unicode-property-regex",feature:"unicodePropertyEscape",options:{useUnicodeFlag:r}})}));t["default"]=n},7978:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-async-generators",manipulateOptions(e,t){t.plugins.push("asyncGenerators")}}}));t["default"]=a},9140:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-bigint",manipulateOptions(e,t){t.plugins.push("bigInt")}}}));t["default"]=a},749:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-class-properties",manipulateOptions(e,t){t.plugins.push("classProperties","classPrivateProperties","classPrivateMethods")}}}));t["default"]=a},2288:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-class-static-block",manipulateOptions(e,t){t.plugins.push("classStaticBlock")}}}));t["default"]=a},9854:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-dynamic-import",manipulateOptions(e,t){t.plugins.push("dynamicImport")}}}));t["default"]=a},9081:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-export-namespace-from",manipulateOptions(e,t){t.plugins.push("exportNamespaceFrom")}}}));t["default"]=a},9905:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-import-assertions",manipulateOptions(e,t){t.plugins.push(["importAssertions"])}}}));t["default"]=a},2228:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-import-assertions",manipulateOptions(e,t){t.plugins.push("importAssertions")}}}));t["default"]=a},4602:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-json-strings",manipulateOptions(e,t){t.plugins.push("jsonStrings")}}}));t["default"]=a},6178:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-jsx",manipulateOptions(e,t){if(t.plugins.some((e=>(Array.isArray(e)?e[0]:e)==="typescript"))){return}t.plugins.push("jsx")}}}));t["default"]=a},6709:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-logical-assignment-operators",manipulateOptions(e,t){t.plugins.push("logicalAssignment")}}}));t["default"]=a},3835:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-nullish-coalescing-operator",manipulateOptions(e,t){t.plugins.push("nullishCoalescingOperator")}}}));t["default"]=a},3537:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-numeric-separator",manipulateOptions(e,t){t.plugins.push("numericSeparator")}}}));t["default"]=a},4396:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-object-rest-spread",manipulateOptions(e,t){t.plugins.push("objectRestSpread")}}}));t["default"]=a},2690:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-optional-catch-binding",manipulateOptions(e,t){t.plugins.push("optionalCatchBinding")}}}));t["default"]=a},1648:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-optional-chaining",manipulateOptions(e,t){t.plugins.push("optionalChaining")}}}));t["default"]=a},1603:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-private-property-in-object",manipulateOptions(e,t){t.plugins.push("privateIn")}}}));t["default"]=a},9723:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-top-level-await",manipulateOptions(e,t){t.plugins.push("topLevelAwait")}}}));t["default"]=a},7386:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);function removePlugin(e,t){const r=[];e.forEach(((e,s)=>{const a=Array.isArray(e)?e[0]:e;if(a===t){r.unshift(s)}}));for(const t of r){e.splice(t,1)}}var a=(0,s.declare)(((e,{isTSX:t,disallowAmbiguousJSXLike:r})=>{e.assertVersion(7);return{name:"syntax-typescript",manipulateOptions(e,s){const{plugins:a}=s;removePlugin(a,"flow");removePlugin(a,"jsx");a.push(["typescript",{disallowAmbiguousJSXLike:r}],"classProperties");{a.push("objectRestSpread")}if(t){a.push("jsx")}}}}));t["default"]=a},8137:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=(0,s.declare)(((e,t)=>{var r;e.assertVersion(7);const s=(r=e.assumption("noNewArrows"))!=null?r:!t.spec;return{name:"transform-arrow-functions",visitor:{ArrowFunctionExpression(e){if(!e.isArrowFunctionExpression())return;e.arrowFunctionToExpression({allowInsertArrow:false,noNewArrows:s,specCompliant:!s})}}}}));t["default"]=a},5333:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=r(9567);var n=r(2786);var o=r(8304);var i=(0,s.declare)(((e,t)=>{var r,s;e.assertVersion(7);const{method:i,module:l}=t;const c=(r=e.assumption("noNewArrows"))!=null?r:true;const u=(s=e.assumption("ignoreFunctionLength"))!=null?s:false;if(i&&l){return{name:"transform-async-to-generator",visitor:{Function(e,t){if(!e.node.async||e.node.generator)return;let r=t.methodWrapper;if(r){r=o.types.cloneNode(r)}else{r=t.methodWrapper=(0,n.addNamed)(e,i,l)}(0,a.default)(e,{wrapAsync:r},c,u)}}}}return{name:"transform-async-to-generator",visitor:{Function(e,t){if(!e.node.async||e.node.generator)return;(0,a.default)(e,{wrapAsync:t.addHelper("asyncToGenerator")},c,u)}}}}));t["default"]=i},141:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=r(8304);var n=(0,s.declare)((e=>{e.assertVersion(7);function statementList(e,t){const r=t.get(e);for(const e of r){const t=e.node;if(!e.isFunctionDeclaration())continue;const r=a.types.variableDeclaration("let",[a.types.variableDeclarator(t.id,a.types.toExpression(t))]);r._blockHoist=2;t.id=null;e.replaceWith(r)}}return{name:"transform-block-scoped-functions",visitor:{BlockStatement(e){const{node:t,parent:r}=e;if(a.types.isFunction(r,{body:t})||a.types.isExportDeclaration(r)){return}statementList("body",e)},SwitchCase(e){statementList("consequent",e)}}}}));t["default"]=n},265:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=r(9987);var n=r(8304);const o=new WeakSet;var i=(0,s.declare)(((e,t)=>{e.assertVersion(7);const{throwIfClosureRequired:r=false,tdz:s=false}=t;if(typeof r!=="boolean"){throw new Error(`.throwIfClosureRequired must be a boolean, or undefined`)}if(typeof s!=="boolean"){throw new Error(`.tdz must be a boolean, or undefined`)}return{name:"transform-block-scoping",visitor:{VariableDeclaration(e){const{node:t,parent:r,scope:s}=e;if(!isBlockScoped(t))return;convertBlockScopedToVar(e,null,r,s,true);if(t._tdzThis){const r=[t];for(let e=0;ee.isLoop()||e.isFunction()));return t==null?void 0:t.isLoop()}function convertBlockScopedToVar(e,t,r,s,a=false){if(!t){t=e.node}if(isInLoop(e)&&!n.types.isFor(r)){for(let e=0;e0){e.traverse(u,t)}else{e.traverse(a.visitor,t)}return e.skip()}},a.visitor]);const u=n.traverse.visitors.merge([{ReferencedIdentifier(e,t){const r=t.letReferences.get(e.node.name);if(!r)return;const s=e.scope.getBindingIdentifier(e.node.name);if(s&&s!==r)return;t.closurify=true}},a.visitor]);const p={enter(e,t){if(e.isForStatement()){const{node:r}=e;if(isVar(r.init)){const e=t.pushDeclar(r.init);if(e.length===1){r.init=e[0]}else{r.init=n.types.sequenceExpression(e)}}}else if(e.isForInStatement()||e.isForOfStatement()){const{node:r}=e;if(isVar(r.left)){t.pushDeclar(r.left);r.left=r.left.declarations[0].id}}else if(isVar(e.node)){e.replaceWithMultiple(t.pushDeclar(e.node).map((e=>n.types.expressionStatement(e))))}else if(e.isFunction()){return e.skip()}}};const d={LabeledStatement({node:e},t){t.innerLabels.push(e.label.name)}};const f={enter(e,t){if(e.isAssignmentExpression()||e.isUpdateExpression()){for(const r of Object.keys(e.getBindingIdentifiers())){if(t.outsideReferences.get(r)!==e.scope.getBindingIdentifier(r)){continue}t.reassignments[r]=true}}else if(e.isReturnStatement()){t.returnStatements.push(e)}}};function loopNodeTo(e){if(n.types.isBreakStatement(e)){return"break"}else if(n.types.isContinueStatement(e)){return"continue"}}const y={Loop(e,t){const r=t.ignoreLabeless;t.ignoreLabeless=true;e.traverse(y,t);t.ignoreLabeless=r;e.skip()},Function(e){e.skip()},SwitchCase(e,t){const r=t.inSwitchCase;t.inSwitchCase=true;e.traverse(y,t);t.inSwitchCase=r;e.skip()},"BreakStatement|ContinueStatement|ReturnStatement"(e,t){const{node:r,scope:s}=e;if(t.loopIgnored.has(r))return;let a;let o=loopNodeTo(r);if(o){if(n.types.isReturnStatement(r)){throw new Error("Internal error: unexpected return statement with `loopText`")}if(r.label){if(t.innerLabels.indexOf(r.label.name)>=0){return}o=`${o}|${r.label.name}`}else{if(t.ignoreLabeless)return;if(n.types.isBreakStatement(r)&&t.inSwitchCase)return}t.hasBreakContinue=true;t.map[o]=r;a=n.types.stringLiteral(o)}if(n.types.isReturnStatement(r)){t.hasReturn=true;a=n.types.objectExpression([n.types.objectProperty(n.types.identifier("v"),r.argument||s.buildUndefinedNode())])}if(a){a=n.types.returnStatement(a);t.loopIgnored.add(a);e.skip();e.replaceWith(n.types.inherits(a,r))}}};function isStrict(e){return!!e.find((({node:e})=>{if(n.types.isProgram(e)){if(e.sourceType==="module")return true}else if(!n.types.isBlockStatement(e))return false;return e.directives.some((e=>e.value.value==="use strict"))}))}class BlockScoping{constructor(e,t,r,s,a,o,i){this.parent=void 0;this.state=void 0;this.scope=void 0;this.throwIfClosureRequired=void 0;this.tdzEnabled=void 0;this.blockPath=void 0;this.block=void 0;this.outsideLetReferences=void 0;this.hasLetReferences=void 0;this.letReferences=void 0;this.body=void 0;this.loopParent=void 0;this.loopLabel=void 0;this.loopPath=void 0;this.loop=void 0;this.has=void 0;this.parent=r;this.scope=s;this.state=i;this.throwIfClosureRequired=a;this.tdzEnabled=o;this.blockPath=t;this.block=t.node;this.outsideLetReferences=new Map;this.hasLetReferences=false;this.letReferences=new Map;this.body=[];if(e){this.loopParent=e.parent;this.loopLabel=n.types.isLabeledStatement(this.loopParent)&&this.loopParent.label;this.loopPath=e;this.loop=e.node}}run(){const e=this.block;if(o.has(e))return;o.add(e);const t=this.getLetReferences();this.checkConstants();if(n.types.isFunction(this.parent)||n.types.isProgram(this.block)){this.updateScopeInfo();return}if(!this.hasLetReferences)return;if(t){this.wrapClosure()}else{this.remap()}this.updateScopeInfo(t);if(this.loopLabel&&!n.types.isLabeledStatement(this.loopParent)){return n.types.labeledStatement(this.loopLabel,this.loop)}}checkConstants(){const e=this.scope;const t=this.state;for(const r of Object.keys(e.bindings)){const s=e.bindings[r];if(s.kind!=="const")continue;for(const e of s.constantViolations){const s=t.addHelper("readOnlyError");const a=n.types.callExpression(s,[n.types.stringLiteral(r)]);if(e.isAssignmentExpression()){const{operator:t}=e.node;if(t==="="){e.replaceWith(n.types.sequenceExpression([e.get("right").node,a]))}else if(["&&=","||=","??="].includes(t)){e.replaceWith(n.types.logicalExpression(t.slice(0,-1),e.get("left").node,n.types.sequenceExpression([e.get("right").node,a])))}else{e.replaceWith(n.types.sequenceExpression([n.types.binaryExpression(t.slice(0,-1),e.get("left").node,e.get("right").node),a]))}}else if(e.isUpdateExpression()){e.replaceWith(n.types.sequenceExpression([n.types.unaryExpression("+",e.get("argument").node),a]))}else if(e.isForXStatement()){e.ensureBlock();e.get("left").replaceWith(n.types.variableDeclaration("var",[n.types.variableDeclarator(e.scope.generateUidIdentifier(r))]));e.node.body.body.unshift(n.types.expressionStatement(a))}}}}updateScopeInfo(e){const t=this.blockPath.scope;const r=t.getFunctionParent()||t.getProgramParent();const s=this.letReferences;for(const a of s.keys()){const n=s.get(a);const o=t.getBinding(n.name);if(!o)continue;if(o.kind==="let"||o.kind==="const"){o.kind="var";if(e){if(t.hasOwnBinding(n.name)){t.removeBinding(n.name)}}else{t.moveBindingTo(n.name,r)}}}}remap(){const e=this.letReferences;const t=this.outsideLetReferences;const r=this.scope;const s=this.blockPath.scope;for(const t of e.keys()){const a=e.get(t);if(r.parentHasBinding(t)||r.hasGlobal(t)){const e=r.getOwnBinding(t);if(e){const s=r.parent.getOwnBinding(t);if(e.kind==="hoisted"&&!e.path.node.async&&!e.path.node.generator&&(!s||isVar(s.path.parent))&&!isStrict(e.path.parentPath)){continue}r.rename(a.name)}if(s.hasOwnBinding(t)){s.rename(a.name)}}}for(const r of t.keys()){const t=e.get(r);if(isInLoop(this.blockPath)&&s.hasOwnBinding(r)){s.rename(t.name)}}}wrapClosure(){if(this.throwIfClosureRequired){throw this.blockPath.buildCodeFrameError("Compiling let/const in this block would add a closure "+"(throwIfClosureRequired).")}const e=this.block;const t=this.outsideLetReferences;if(this.loop){for(const e of Array.from(t.keys())){const r=t.get(e);if(this.scope.hasGlobal(r.name)||this.scope.parentHasBinding(r.name)){t.delete(r.name);this.letReferences.delete(r.name);this.scope.rename(r.name);this.letReferences.set(r.name,r);t.set(r.name,r)}}}this.has=this.checkLoop();this.hoistVarDeclarations();const r=Array.from(t.values(),(e=>n.types.cloneNode(e)));const s=r.map((e=>n.types.cloneNode(e)));const a=this.blockPath.isSwitchStatement();const o=n.types.functionExpression(null,s,n.types.blockStatement(a?[e]:e.body));this.addContinuations(o);let i=n.types.callExpression(n.types.nullLiteral(),r);let l=".callee";const c=n.traverse.hasType(o.body,"YieldExpression",n.types.FUNCTION_TYPES);if(c){o.generator=true;i=n.types.yieldExpression(i,true);l=".argument"+l}const u=n.traverse.hasType(o.body,"AwaitExpression",n.types.FUNCTION_TYPES);if(u){o.async=true;i=n.types.awaitExpression(i);l=".argument"+l}let p;let d;if(this.has.hasReturn||this.has.hasBreakContinue){const e=this.scope.generateUid("ret");this.body.push(n.types.variableDeclaration("var",[n.types.variableDeclarator(n.types.identifier(e),i)]));p="declarations.0.init"+l;d=this.body.length-1;this.buildHas(e)}else{this.body.push(n.types.expressionStatement(i));p="expression"+l;d=this.body.length-1}let f;if(a){const{parentPath:e,listKey:t,key:r}=this.blockPath;this.blockPath.replaceWithMultiple(this.body);f=e.get(t)[r+d]}else{e.body=this.body;f=this.blockPath.get("body")[d]}const y=f.get(p);let g;if(this.loop){const e=this.scope.generateUid("loop");const t=this.loopPath.insertBefore(n.types.variableDeclaration("var",[n.types.variableDeclarator(n.types.identifier(e),o)]));y.replaceWith(n.types.identifier(e));g=t[0].get("declarations.0.init")}else{y.replaceWith(o);g=y}g.unwrapFunctionEnvironment()}addContinuations(e){const t={reassignments:{},returnStatements:[],outsideReferences:this.outsideLetReferences};this.scope.traverse(e,f,t);for(let r=0;r{e.insertBefore(n.types.expressionStatement(n.types.assignmentExpression("=",n.types.identifier(a),n.types.identifier(o))))}));e.body.body.push(n.types.expressionStatement(n.types.assignmentExpression("=",n.types.identifier(a),n.types.identifier(o))))}}getLetReferences(){const e=this.block;const t=[];if(this.loop){const e=this.loop.left||this.loop.init;if(isBlockScoped(e)){t.push(e);const r=n.types.getBindingIdentifiers(e);for(const e of Object.keys(r)){this.outsideLetReferences.set(e,r[e])}}}const addDeclarationsFromChild=(r,s)=>{s=s||r.node;if(n.types.isClassDeclaration(s)||n.types.isFunctionDeclaration(s)||isBlockScoped(s)){if(isBlockScoped(s)){convertBlockScopedToVar(r,s,e,this.scope)}if(s.declarations){for(let e=0;ethis.state.addHelper(e)};if(isInLoop(this.blockPath)){r.loopDepth++}this.blockPath.traverse(c,r);return r.closurify}checkLoop(){const e={hasBreakContinue:false,ignoreLabeless:false,inSwitchCase:false,innerLabels:[],hasReturn:false,isLoop:!!this.loop,map:{},loopIgnored:new WeakSet};this.blockPath.traverse(d,e);this.blockPath.traverse(y,e);return e}hoistVarDeclarations(){this.blockPath.traverse(p,this)}pushDeclar(e){const t=[];const r=n.types.getBindingIdentifiers(e);for(const e of Object.keys(r)){t.push(n.types.variableDeclarator(r[e]))}this.body.push(n.types.variableDeclaration(e.kind,t));const s=[];for(let t=0;t{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.visitor=void 0;var s=r(8304);function getTDZStatus(e,t){const r=t._guessExecutionStatusRelativeTo(e);if(r==="before"){return"outside"}else if(r==="after"){return"inside"}else{return"maybe"}}function buildTDZAssert(e,t){return s.types.callExpression(t.addHelper("temporalRef"),[e,s.types.stringLiteral(e.name)])}function isReference(e,t,r){const s=r.letReferences.get(e.name);if(!s)return false;return t.getBindingIdentifier(e.name)===s}const a=new WeakSet;const n={ReferencedIdentifier(e,t){if(!t.tdzEnabled)return;const{node:r,parent:n,scope:o}=e;if(e.parentPath.isFor({left:r}))return;if(!isReference(r,o,t))return;const i=o.getBinding(r.name).path;if(i.isFunctionDeclaration())return;const l=getTDZStatus(e,i);if(l==="outside")return;if(l==="maybe"){if(a.has(r)){return}a.add(r);const o=buildTDZAssert(r,t);i.parent._tdzThis=true;if(e.parentPath.isUpdateExpression()){if(n._ignoreBlockScopingTDZ)return;e.parentPath.replaceWith(s.types.sequenceExpression([o,n]))}else{e.replaceWith(o)}}else if(l==="inside"){e.replaceWith(s.template.ast`${t.addHelper("tdz")}("${r.name}")`)}},AssignmentExpression:{exit(e,t){if(!t.tdzEnabled)return;const{node:r}=e;if(r._ignoreBlockScopingTDZ)return;const a=[];const n=e.getBindingIdentifiers();for(const r of Object.keys(n)){const s=n[r];if(isReference(s,e.scope,t)){a.push(s)}}if(a.length){r._ignoreBlockScopingTDZ=true;a.push(r);e.replaceWithMultiple(a.map((e=>s.types.expressionStatement(e))))}}}};t.visitor=n},8323:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=r(9102);var n=r(1113);var o=r(821);var i=r(8304);var l=r(3315);var c=r(1685);const getBuiltinClasses=e=>Object.keys(l[e]).filter((e=>/^[A-Z]/.test(e)));const u=new Set([...getBuiltinClasses("builtin"),...getBuiltinClasses("browser")]);var p=(0,s.declare)(((e,t)=>{var r,s,l,p;e.assertVersion(7);const{loose:d=false}=t;const f=(r=e.assumption("setClassMethods"))!=null?r:d;const y=(s=e.assumption("constantSuper"))!=null?s:d;const g=(l=e.assumption("superIsCallableConstructor"))!=null?l:d;const h=(p=e.assumption("noClassCalls"))!=null?p:d;const b=new WeakSet;return{name:"transform-classes",visitor:{ExportDefaultDeclaration(e){if(!e.get("declaration").isClassDeclaration())return;(0,o.default)(e)},ClassDeclaration(e){const{node:t}=e;const r=t.id||e.scope.generateUidIdentifier("class");e.replaceWith(i.types.variableDeclaration("let",[i.types.variableDeclarator(r,i.types.toExpression(t))]))},ClassExpression(e,t){const{node:r}=e;if(b.has(r))return;const s=(0,n.default)(e);if(s&&s!==r){e.replaceWith(s);return}b.add(r);e.replaceWith((0,c.default)(e,t.file,u,d,{setClassMethods:f,constantSuper:y,superIsCallableConstructor:g,noClassCalls:h}));if(e.isCallExpression()){(0,a.default)(e);const t=e.get("callee");if(t.isArrowFunctionExpression()){t.arrowFunctionToExpression()}}}}}}));t["default"]=p},2088:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=addCreateSuperHelper;var s=r(8304);const a=new WeakMap;function addCreateSuperHelper(e){if(a.has(e)){return(s.types.cloneNode||s.types.clone)(a.get(e))}try{return e.addHelper("createSuper")}catch(e){}const t=e.scope.generateUidIdentifier("createSuper");a.set(e,t);const r=n({CREATE_SUPER:t,GET_PROTOTYPE_OF:e.addHelper("getPrototypeOf"),POSSIBLE_CONSTRUCTOR_RETURN:e.addHelper("possibleConstructorReturn")});e.path.unshiftContainer("body",[r]);e.scope.registerDeclaration(e.path.get("body.0"));return s.types.cloneNode(t)}const n=s.template.statement` + `)}else{var i;const t=getWeakSetId(l,o,o,(i=o.node.id)==null?void 0:i.name,injectInitialization);e.replaceWith(s.expression.ast`${t}.has(${e.node.right})`)}}else{const t=getWeakSetId(c,o,n,n.node.key.id.name,injectToFieldInit);e.replaceWith(s.expression.ast`${t}.has(${e.node.right})`)}}}}}));t["default"]=i},8226:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(6741);var a=r(3242);var n=(0,a.declare)(((e,t)=>{e.assertVersion(7);const{useUnicodeFlag:r=true}=t;if(typeof r!=="boolean"){throw new Error(".useUnicodeFlag must be a boolean, or undefined")}return(0,s.createRegExpFeaturePlugin)({name:"proposal-unicode-property-regex",feature:"unicodePropertyEscape",options:{useUnicodeFlag:r}})}));t["default"]=n},7978:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-async-generators",manipulateOptions(e,t){t.plugins.push("asyncGenerators")}}}));t["default"]=a},9140:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-bigint",manipulateOptions(e,t){t.plugins.push("bigInt")}}}));t["default"]=a},749:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-class-properties",manipulateOptions(e,t){t.plugins.push("classProperties","classPrivateProperties","classPrivateMethods")}}}));t["default"]=a},2288:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-class-static-block",manipulateOptions(e,t){t.plugins.push("classStaticBlock")}}}));t["default"]=a},9854:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-dynamic-import",manipulateOptions(e,t){t.plugins.push("dynamicImport")}}}));t["default"]=a},9081:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-export-namespace-from",manipulateOptions(e,t){t.plugins.push("exportNamespaceFrom")}}}));t["default"]=a},9905:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-import-assertions",manipulateOptions(e,t){t.plugins.push(["importAssertions"])}}}));t["default"]=a},2228:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-import-assertions",manipulateOptions(e,t){t.plugins.push("importAssertions")}}}));t["default"]=a},4602:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-json-strings",manipulateOptions(e,t){t.plugins.push("jsonStrings")}}}));t["default"]=a},6178:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-jsx",manipulateOptions(e,t){if(t.plugins.some((e=>(Array.isArray(e)?e[0]:e)==="typescript"))){return}t.plugins.push("jsx")}}}));t["default"]=a},6709:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-logical-assignment-operators",manipulateOptions(e,t){t.plugins.push("logicalAssignment")}}}));t["default"]=a},3835:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-nullish-coalescing-operator",manipulateOptions(e,t){t.plugins.push("nullishCoalescingOperator")}}}));t["default"]=a},3537:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-numeric-separator",manipulateOptions(e,t){t.plugins.push("numericSeparator")}}}));t["default"]=a},4396:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-object-rest-spread",manipulateOptions(e,t){t.plugins.push("objectRestSpread")}}}));t["default"]=a},2690:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-optional-catch-binding",manipulateOptions(e,t){t.plugins.push("optionalCatchBinding")}}}));t["default"]=a},1648:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-optional-chaining",manipulateOptions(e,t){t.plugins.push("optionalChaining")}}}));t["default"]=a},1603:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-private-property-in-object",manipulateOptions(e,t){t.plugins.push("privateIn")}}}));t["default"]=a},9723:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3962);var a=(0,s.declare)((e=>{e.assertVersion(7);return{name:"syntax-top-level-await",manipulateOptions(e,t){t.plugins.push("topLevelAwait")}}}));t["default"]=a},7386:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);function removePlugin(e,t){const r=[];e.forEach(((e,s)=>{const a=Array.isArray(e)?e[0]:e;if(a===t){r.unshift(s)}}));for(const t of r){e.splice(t,1)}}var a=(0,s.declare)(((e,{isTSX:t,disallowAmbiguousJSXLike:r})=>{e.assertVersion(7);return{name:"syntax-typescript",manipulateOptions(e,s){const{plugins:a}=s;removePlugin(a,"flow");removePlugin(a,"jsx");a.push(["typescript",{disallowAmbiguousJSXLike:r}],"classProperties");{a.push("objectRestSpread")}if(t){a.push("jsx")}}}}));t["default"]=a},8137:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=(0,s.declare)(((e,t)=>{var r;e.assertVersion(7);const s=(r=e.assumption("noNewArrows"))!=null?r:!t.spec;return{name:"transform-arrow-functions",visitor:{ArrowFunctionExpression(e){if(!e.isArrowFunctionExpression())return;e.arrowFunctionToExpression({allowInsertArrow:false,noNewArrows:s,specCompliant:!s})}}}}));t["default"]=a},5333:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=r(9567);var n=r(2786);var o=r(8304);var i=(0,s.declare)(((e,t)=>{var r,s;e.assertVersion(7);const{method:i,module:l}=t;const c=(r=e.assumption("noNewArrows"))!=null?r:true;const u=(s=e.assumption("ignoreFunctionLength"))!=null?s:false;if(i&&l){return{name:"transform-async-to-generator",visitor:{Function(e,t){if(!e.node.async||e.node.generator)return;let r=t.methodWrapper;if(r){r=o.types.cloneNode(r)}else{r=t.methodWrapper=(0,n.addNamed)(e,i,l)}(0,a.default)(e,{wrapAsync:r},c,u)}}}}return{name:"transform-async-to-generator",visitor:{Function(e,t){if(!e.node.async||e.node.generator)return;(0,a.default)(e,{wrapAsync:t.addHelper("asyncToGenerator")},c,u)}}}}));t["default"]=i},141:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=r(8304);var n=(0,s.declare)((e=>{e.assertVersion(7);function statementList(e,t){const r=t.get(e);for(const e of r){const t=e.node;if(!e.isFunctionDeclaration())continue;const r=a.types.variableDeclaration("let",[a.types.variableDeclarator(t.id,a.types.toExpression(t))]);r._blockHoist=2;t.id=null;e.replaceWith(r)}}return{name:"transform-block-scoped-functions",visitor:{BlockStatement(e){const{node:t,parent:r}=e;if(a.types.isFunction(r,{body:t})||a.types.isExportDeclaration(r)){return}statementList("body",e)},SwitchCase(e){statementList("consequent",e)}}}}));t["default"]=n},265:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=r(9987);var n=r(8304);const o=new WeakSet;var i=(0,s.declare)(((e,t)=>{e.assertVersion(7);const{throwIfClosureRequired:r=false,tdz:s=false}=t;if(typeof r!=="boolean"){throw new Error(`.throwIfClosureRequired must be a boolean, or undefined`)}if(typeof s!=="boolean"){throw new Error(`.tdz must be a boolean, or undefined`)}return{name:"transform-block-scoping",visitor:{VariableDeclaration(e){const{node:t,parent:r,scope:s}=e;if(!isBlockScoped(t))return;convertBlockScopedToVar(e,null,r,s,true);if(t._tdzThis){const r=[t];for(let e=0;ee.isLoop()||e.isFunction()));return t==null?void 0:t.isLoop()}function convertBlockScopedToVar(e,t,r,s,a=false){if(!t){t=e.node}if(isInLoop(e)&&!n.types.isFor(r)){for(let e=0;e0){e.traverse(u,t)}else{e.traverse(a.visitor,t)}return e.skip()}},a.visitor]);const u=n.traverse.visitors.merge([{ReferencedIdentifier(e,t){const r=t.letReferences.get(e.node.name);if(!r)return;const s=e.scope.getBindingIdentifier(e.node.name);if(s&&s!==r)return;t.closurify=true}},a.visitor]);const p={enter(e,t){if(e.isForStatement()){const{node:r}=e;if(isVar(r.init)){const e=t.pushDeclar(r.init);if(e.length===1){r.init=e[0]}else{r.init=n.types.sequenceExpression(e)}}}else if(e.isForInStatement()||e.isForOfStatement()){const{node:r}=e;if(isVar(r.left)){t.pushDeclar(r.left);r.left=r.left.declarations[0].id}}else if(isVar(e.node)){e.replaceWithMultiple(t.pushDeclar(e.node).map((e=>n.types.expressionStatement(e))))}else if(e.isFunction()){return e.skip()}}};const d={LabeledStatement({node:e},t){t.innerLabels.push(e.label.name)}};const f={enter(e,t){if(e.isAssignmentExpression()||e.isUpdateExpression()){for(const r of Object.keys(e.getBindingIdentifiers())){if(t.outsideReferences.get(r)!==e.scope.getBindingIdentifier(r)){continue}t.reassignments[r]=true}}else if(e.isReturnStatement()){t.returnStatements.push(e)}}};function loopNodeTo(e){if(n.types.isBreakStatement(e)){return"break"}else if(n.types.isContinueStatement(e)){return"continue"}}const y={Loop(e,t){const r=t.ignoreLabeless;t.ignoreLabeless=true;e.traverse(y,t);t.ignoreLabeless=r;e.skip()},Function(e){e.skip()},SwitchCase(e,t){const r=t.inSwitchCase;t.inSwitchCase=true;e.traverse(y,t);t.inSwitchCase=r;e.skip()},"BreakStatement|ContinueStatement|ReturnStatement"(e,t){const{node:r,scope:s}=e;if(t.loopIgnored.has(r))return;let a;let o=loopNodeTo(r);if(o){if(n.types.isReturnStatement(r)){throw new Error("Internal error: unexpected return statement with `loopText`")}if(r.label){if(t.innerLabels.indexOf(r.label.name)>=0){return}o=`${o}|${r.label.name}`}else{if(t.ignoreLabeless)return;if(n.types.isBreakStatement(r)&&t.inSwitchCase)return}t.hasBreakContinue=true;t.map[o]=r;a=n.types.stringLiteral(o)}if(n.types.isReturnStatement(r)){t.hasReturn=true;a=n.types.objectExpression([n.types.objectProperty(n.types.identifier("v"),r.argument||s.buildUndefinedNode())])}if(a){a=n.types.returnStatement(a);t.loopIgnored.add(a);e.skip();e.replaceWith(n.types.inherits(a,r))}}};function isStrict(e){return!!e.find((({node:e})=>{if(n.types.isProgram(e)){if(e.sourceType==="module")return true}else if(!n.types.isBlockStatement(e))return false;return e.directives.some((e=>e.value.value==="use strict"))}))}class BlockScoping{constructor(e,t,r,s,a,o,i){this.parent=void 0;this.state=void 0;this.scope=void 0;this.throwIfClosureRequired=void 0;this.tdzEnabled=void 0;this.blockPath=void 0;this.block=void 0;this.outsideLetReferences=void 0;this.hasLetReferences=void 0;this.letReferences=void 0;this.body=void 0;this.loopParent=void 0;this.loopLabel=void 0;this.loopPath=void 0;this.loop=void 0;this.has=void 0;this.parent=r;this.scope=s;this.state=i;this.throwIfClosureRequired=a;this.tdzEnabled=o;this.blockPath=t;this.block=t.node;this.outsideLetReferences=new Map;this.hasLetReferences=false;this.letReferences=new Map;this.body=[];if(e){this.loopParent=e.parent;this.loopLabel=n.types.isLabeledStatement(this.loopParent)&&this.loopParent.label;this.loopPath=e;this.loop=e.node}}run(){const e=this.block;if(o.has(e))return;o.add(e);const t=this.getLetReferences();this.checkConstants();if(n.types.isFunction(this.parent)||n.types.isProgram(this.block)){this.updateScopeInfo();return}if(!this.hasLetReferences)return;if(t){this.wrapClosure()}else{this.remap()}this.updateScopeInfo(t);if(this.loopLabel&&!n.types.isLabeledStatement(this.loopParent)){return n.types.labeledStatement(this.loopLabel,this.loop)}}checkConstants(){const e=this.scope;const t=this.state;for(const r of Object.keys(e.bindings)){const s=e.bindings[r];if(s.kind!=="const")continue;for(const e of s.constantViolations){const s=t.addHelper("readOnlyError");const a=n.types.callExpression(s,[n.types.stringLiteral(r)]);if(e.isAssignmentExpression()){const{operator:t}=e.node;if(t==="="){e.replaceWith(n.types.sequenceExpression([e.get("right").node,a]))}else if(["&&=","||=","??="].includes(t)){e.replaceWith(n.types.logicalExpression(t.slice(0,-1),e.get("left").node,n.types.sequenceExpression([e.get("right").node,a])))}else{e.replaceWith(n.types.sequenceExpression([n.types.binaryExpression(t.slice(0,-1),e.get("left").node,e.get("right").node),a]))}}else if(e.isUpdateExpression()){e.replaceWith(n.types.sequenceExpression([n.types.unaryExpression("+",e.get("argument").node),a]))}else if(e.isForXStatement()){e.ensureBlock();e.get("left").replaceWith(n.types.variableDeclaration("var",[n.types.variableDeclarator(e.scope.generateUidIdentifier(r))]));e.node.body.body.unshift(n.types.expressionStatement(a))}}}}updateScopeInfo(e){const t=this.blockPath.scope;const r=t.getFunctionParent()||t.getProgramParent();const s=this.letReferences;for(const a of s.keys()){const n=s.get(a);const o=t.getBinding(n.name);if(!o)continue;if(o.kind==="let"||o.kind==="const"){o.kind="var";if(e){if(t.hasOwnBinding(n.name)){t.removeBinding(n.name)}}else{t.moveBindingTo(n.name,r)}}}}remap(){const e=this.letReferences;const t=this.outsideLetReferences;const r=this.scope;const s=this.blockPath.scope;for(const t of e.keys()){const a=e.get(t);if(r.parentHasBinding(t)||r.hasGlobal(t)){const e=r.getOwnBinding(t);if(e){const s=r.parent.getOwnBinding(t);if(e.kind==="hoisted"&&!e.path.node.async&&!e.path.node.generator&&(!s||isVar(s.path.parent))&&!isStrict(e.path.parentPath)){continue}r.rename(a.name)}if(s.hasOwnBinding(t)){s.rename(a.name)}}}for(const r of t.keys()){const t=e.get(r);if(isInLoop(this.blockPath)&&s.hasOwnBinding(r)){s.rename(t.name)}}}wrapClosure(){if(this.throwIfClosureRequired){throw this.blockPath.buildCodeFrameError("Compiling let/const in this block would add a closure "+"(throwIfClosureRequired).")}const e=this.block;const t=this.outsideLetReferences;if(this.loop){for(const e of Array.from(t.keys())){const r=t.get(e);if(this.scope.hasGlobal(r.name)||this.scope.parentHasBinding(r.name)){t.delete(r.name);this.letReferences.delete(r.name);this.scope.rename(r.name);this.letReferences.set(r.name,r);t.set(r.name,r)}}}this.has=this.checkLoop();this.hoistVarDeclarations();const r=Array.from(t.values(),(e=>n.types.cloneNode(e)));const s=r.map((e=>n.types.cloneNode(e)));const a=this.blockPath.isSwitchStatement();const o=n.types.functionExpression(null,s,n.types.blockStatement(a?[e]:e.body));this.addContinuations(o);let i=n.types.callExpression(n.types.nullLiteral(),r);let l=".callee";const c=n.traverse.hasType(o.body,"YieldExpression",n.types.FUNCTION_TYPES);if(c){o.generator=true;i=n.types.yieldExpression(i,true);l=".argument"+l}const u=n.traverse.hasType(o.body,"AwaitExpression",n.types.FUNCTION_TYPES);if(u){o.async=true;i=n.types.awaitExpression(i);l=".argument"+l}let p;let d;if(this.has.hasReturn||this.has.hasBreakContinue){const e=this.scope.generateUid("ret");this.body.push(n.types.variableDeclaration("var",[n.types.variableDeclarator(n.types.identifier(e),i)]));p="declarations.0.init"+l;d=this.body.length-1;this.buildHas(e)}else{this.body.push(n.types.expressionStatement(i));p="expression"+l;d=this.body.length-1}let f;if(a){const{parentPath:e,listKey:t,key:r}=this.blockPath;this.blockPath.replaceWithMultiple(this.body);f=e.get(t)[r+d]}else{e.body=this.body;f=this.blockPath.get("body")[d]}const y=f.get(p);let g;if(this.loop){const e=this.scope.generateUid("loop");const t=this.loopPath.insertBefore(n.types.variableDeclaration("var",[n.types.variableDeclarator(n.types.identifier(e),o)]));y.replaceWith(n.types.identifier(e));g=t[0].get("declarations.0.init")}else{y.replaceWith(o);g=y}g.unwrapFunctionEnvironment()}addContinuations(e){const t={reassignments:{},returnStatements:[],outsideReferences:this.outsideLetReferences};this.scope.traverse(e,f,t);for(let r=0;r{e.insertBefore(n.types.expressionStatement(n.types.assignmentExpression("=",n.types.identifier(a),n.types.identifier(o))))}));e.body.body.push(n.types.expressionStatement(n.types.assignmentExpression("=",n.types.identifier(a),n.types.identifier(o))))}}getLetReferences(){const e=this.block;const t=[];if(this.loop){const e=this.loop.left||this.loop.init;if(isBlockScoped(e)){t.push(e);const r=n.types.getBindingIdentifiers(e);for(const e of Object.keys(r)){this.outsideLetReferences.set(e,r[e])}}}const addDeclarationsFromChild=(r,s)=>{s=s||r.node;if(n.types.isClassDeclaration(s)||n.types.isFunctionDeclaration(s)||isBlockScoped(s)){if(isBlockScoped(s)){convertBlockScopedToVar(r,s,e,this.scope)}if(s.declarations){for(let e=0;ethis.state.addHelper(e)};if(isInLoop(this.blockPath)){r.loopDepth++}this.blockPath.traverse(c,r);return r.closurify}checkLoop(){const e={hasBreakContinue:false,ignoreLabeless:false,inSwitchCase:false,innerLabels:[],hasReturn:false,isLoop:!!this.loop,map:{},loopIgnored:new WeakSet};this.blockPath.traverse(d,e);this.blockPath.traverse(y,e);return e}hoistVarDeclarations(){this.blockPath.traverse(p,this)}pushDeclar(e){const t=[];const r=n.types.getBindingIdentifiers(e);for(const e of Object.keys(r)){t.push(n.types.variableDeclarator(r[e]))}this.body.push(n.types.variableDeclaration(e.kind,t));const s=[];for(let t=0;t{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.visitor=void 0;var s=r(8304);function getTDZStatus(e,t){const r=t._guessExecutionStatusRelativeTo(e);if(r==="before"){return"outside"}else if(r==="after"){return"inside"}else{return"maybe"}}function buildTDZAssert(e,t){return s.types.callExpression(t.addHelper("temporalRef"),[e,s.types.stringLiteral(e.name)])}function isReference(e,t,r){const s=r.letReferences.get(e.name);if(!s)return false;return t.getBindingIdentifier(e.name)===s}const a=new WeakSet;const n={ReferencedIdentifier(e,t){if(!t.tdzEnabled)return;const{node:r,parent:n,scope:o}=e;if(e.parentPath.isFor({left:r}))return;if(!isReference(r,o,t))return;const i=o.getBinding(r.name).path;if(i.isFunctionDeclaration())return;const l=getTDZStatus(e,i);if(l==="outside")return;if(l==="maybe"){if(a.has(r)){return}a.add(r);const o=buildTDZAssert(r,t);i.parent._tdzThis=true;if(e.parentPath.isUpdateExpression()){if(n._ignoreBlockScopingTDZ)return;e.parentPath.replaceWith(s.types.sequenceExpression([o,n]))}else{e.replaceWith(o)}}else if(l==="inside"){e.replaceWith(s.template.ast`${t.addHelper("tdz")}("${r.name}")`)}},AssignmentExpression:{exit(e,t){if(!t.tdzEnabled)return;const{node:r}=e;if(r._ignoreBlockScopingTDZ)return;const a=[];const n=e.getBindingIdentifiers();for(const r of Object.keys(n)){const s=n[r];if(isReference(s,e.scope,t)){a.push(s)}}if(a.length){r._ignoreBlockScopingTDZ=true;a.push(r);e.replaceWithMultiple(a.map((e=>s.types.expressionStatement(e))))}}}};t.visitor=n},8323:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var s=r(3242);var a=r(9102);var n=r(1113);var o=r(821);var i=r(8304);var l=r(3315);var c=r(1685);const getBuiltinClasses=e=>Object.keys(l[e]).filter((e=>/^[A-Z]/.test(e)));const u=new Set([...getBuiltinClasses("builtin"),...getBuiltinClasses("browser")]);var p=(0,s.declare)(((e,t)=>{var r,s,l,p;e.assertVersion(7);const{loose:d=false}=t;const f=(r=e.assumption("setClassMethods"))!=null?r:d;const y=(s=e.assumption("constantSuper"))!=null?s:d;const g=(l=e.assumption("superIsCallableConstructor"))!=null?l:d;const h=(p=e.assumption("noClassCalls"))!=null?p:d;const b=new WeakSet;return{name:"transform-classes",visitor:{ExportDefaultDeclaration(e){if(!e.get("declaration").isClassDeclaration())return;(0,o.default)(e)},ClassDeclaration(e){const{node:t}=e;const r=t.id||e.scope.generateUidIdentifier("class");e.replaceWith(i.types.variableDeclaration("let",[i.types.variableDeclarator(r,i.types.toExpression(t))]))},ClassExpression(e,t){const{node:r}=e;if(b.has(r))return;const s=(0,n.default)(e);if(s&&s!==r){e.replaceWith(s);return}b.add(r);e.replaceWith((0,c.default)(e,t.file,u,d,{setClassMethods:f,constantSuper:y,superIsCallableConstructor:g,noClassCalls:h}));if(e.isCallExpression()){(0,a.default)(e);const t=e.get("callee");if(t.isArrowFunctionExpression()){t.arrowFunctionToExpression()}}}}}}));t["default"]=p},2088:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t["default"]=addCreateSuperHelper;var s=r(8304);const a=new WeakMap;function addCreateSuperHelper(e){if(a.has(e)){return(s.types.cloneNode||s.types.clone)(a.get(e))}try{return e.addHelper("createSuper")}catch(e){}const t=e.scope.generateUidIdentifier("createSuper");a.set(e,t);const r=n({CREATE_SUPER:t,GET_PROTOTYPE_OF:e.addHelper("getPrototypeOf"),POSSIBLE_CONSTRUCTOR_RETURN:e.addHelper("possibleConstructorReturn")});e.path.unshiftContainer("body",[r]);e.scope.registerDeclaration(e.path.get("body.0"));return s.types.cloneNode(t)}const n=s.template.statement` function CREATE_SUPER(Derived) { function isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; diff --git a/packages/next/compiled/edge-runtime/index.js b/packages/next/compiled/edge-runtime/index.js index dd1b86049f7b..1ac3b7818c40 100644 --- a/packages/next/compiled/edge-runtime/index.js +++ b/packages/next/compiled/edge-runtime/index.js @@ -1 +1 @@ -(()=>{var __webpack_modules__={162:(__unused_webpack_module,exports,__nccwpck_require__)=>{"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.EdgeVM=void 0;const buffer_1=__nccwpck_require__(300);const require_1=__nccwpck_require__(986);const vm_1=__nccwpck_require__(218);const vm_2=__nccwpck_require__(144);class EdgeVM extends vm_1.VM{constructor(e={}){super({...e,extend:t=>e.extend?e.extend(addPrimitives(t)):addPrimitives(t)})}}exports.EdgeVM=EdgeVM;function addPrimitives(context){defineProperty(context,"self",{enumerable:true,value:context});defineProperty(context,"globalThis",{value:context});defineProperty(context,"Symbol",{value:Symbol});defineProperty(context,"clearInterval",{value:clearInterval});defineProperty(context,"clearTimeout",{value:clearTimeout});defineProperty(context,"setInterval",{value:setInterval});defineProperty(context,"setTimeout",{value:setTimeout});defineProperty(context,"EdgeRuntime",{value:"edge-runtime"});defineProperties(context,{exports:(0,require_1.requireWithCache)({context:context,path:require.resolve("next/dist/compiled/@edge-runtime/primitives/console"),scopedContext:{console:console}}),nonenumerable:["console"]});const encodings=(0,require_1.requireWithCache)({context:context,path:require.resolve("next/dist/compiled/@edge-runtime/primitives/encoding"),scopedContext:{Buffer:buffer_1.Buffer,global:{ArrayBuffer:ArrayBuffer}}});defineProperties(context,{exports:encodings,nonenumerable:["atob","btoa","TextEncoder","TextDecoder"]});const streams=(0,require_1.requireWithCache)({path:require.resolve("next/dist/compiled/@edge-runtime/primitives/streams"),context:context});defineProperties(context,{exports:streams,nonenumerable:["ReadableStream","ReadableStreamBYOBReader","ReadableStreamDefaultReader","TransformStream","WritableStream","WritableStreamDefaultWriter"]});const abort=(0,require_1.requireWithCache)({context:context,path:require.resolve("next/dist/compiled/@edge-runtime/primitives/abort-controller")});defineProperties(context,{exports:abort,nonenumerable:["AbortController","AbortSignal"]});defineProperties(context,{exports:(0,require_1.requireWithCache)({cache:new Map([["punycode",{exports:__nccwpck_require__(477)}]]),context:context,path:require.resolve("next/dist/compiled/@edge-runtime/primitives/url"),scopedContext:{TextEncoder:encodings.TextEncoder,TextDecoder:encodings.TextDecoder}}),nonenumerable:["URL","URLSearchParams","URLPattern"]});const blob=(0,require_1.requireWithCache)({context:context,path:require.resolve("next/dist/compiled/@edge-runtime/primitives/blob")});defineProperties(context,{exports:blob,nonenumerable:["Blob"]});const webFetch=(0,require_1.requireWithCache)({context:context,cache:new Map([["abort-controller",{exports:abort}],["assert",{exports:__nccwpck_require__(491)}],["buffer",{exports:__nccwpck_require__(300)}],["events",{exports:__nccwpck_require__(361)}],["http",{exports:__nccwpck_require__(685)}],["net",{exports:__nccwpck_require__(808)}],["perf_hooks",{exports:__nccwpck_require__(74)}],["stream",{exports:__nccwpck_require__(781)}],["tls",{exports:__nccwpck_require__(404)}],["util",{exports:__nccwpck_require__(837)}],["zlib",{exports:__nccwpck_require__(796)}],[require.resolve("next/dist/compiled/@edge-runtime/primitives/streams"),{exports:streams}],[require.resolve("next/dist/compiled/@edge-runtime/primitives/blob"),{exports:blob}]]),path:require.resolve("next/dist/compiled/@edge-runtime/primitives/fetch"),scopedContext:{Buffer:buffer_1.Buffer,FinalizationRegistry:function(){return{register:function(){}}},global:{},queueMicrotask:queueMicrotask,setImmediate:setImmediate}});defineProperties(context,{exports:webFetch,nonenumerable:["fetch","File","FormData","Headers","Request","Response"]});defineProperties(context,{exports:(0,require_1.requireWithCache)({cache:new Map([[require.resolve("next/dist/compiled/@edge-runtime/primitives/fetch"),{exports:webFetch}]]),context:context,path:require.resolve("next/dist/compiled/@edge-runtime/primitives/cache"),scopedContext:{global:{}}}),enumerable:["caches"],nonenumerable:["Cache","CacheStorage"]});defineProperties(context,{exports:(0,require_1.requireWithCache)({context:context,cache:new Map([["crypto",{exports:__nccwpck_require__(113)}],["process",{exports:__nccwpck_require__(282)}]]),path:require.resolve("next/dist/compiled/@edge-runtime/primitives/crypto"),scopedContext:{Buffer:buffer_1.Buffer,Uint8Array:new Proxy((0,vm_2.runInContext)("Uint8Array",context),{construct(e,t){const r=new e(...t);if(!(t[0]instanceof buffer_1.Buffer)){return r}return new e([...r])}})}}),enumerable:["crypto"],nonenumerable:["Crypto","CryptoKey","SubtleCrypto"]});defineProperties(context,{exports:(0,require_1.requireWithCache)({context:context,path:require.resolve("next/dist/compiled/@edge-runtime/primitives/events")}),nonenumerable:["Event","EventTarget","FetchEvent","PromiseRejectionEvent"]});defineProperties(context,{exports:(0,require_1.requireWithCache)({context:context,path:require.resolve("next/dist/compiled/@edge-runtime/primitives/structured-clone")}),nonenumerable:["structuredClone"]});return context}function defineProperty(e,t,r){var n,o,s;Object.defineProperty(e,t,{configurable:(n=r.configurable)!==null&&n!==void 0?n:false,enumerable:(o=r.enumerable)!==null&&o!==void 0?o:false,value:r.value,writable:(s=r.writable)!==null&&s!==void 0?s:true})}function defineProperties(e,t){var r,n;for(const n of(r=t.enumerable)!==null&&r!==void 0?r:[]){if(!t.exports[n]){throw new Error(`Attempt to export a nullable value for "${n}"`)}defineProperty(e,n,{enumerable:true,value:t.exports[n]})}for(const r of(n=t.nonenumerable)!==null&&n!==void 0?n:[]){if(!t.exports[r]){throw new Error(`Attempt to export a nullable value for "${r}"`)}defineProperty(e,r,{value:t.exports[r]})}}},135:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.VM=t.EdgeVM=void 0;var n=r(162);Object.defineProperty(t,"EdgeVM",{enumerable:true,get:function(){return n.EdgeVM}});var o=r(218);Object.defineProperty(t,"VM",{enumerable:true,get:function(){return o.VM}})},986:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.requireWithCache=t.createRequire=t.requireDependencies=void 0;const n=r(147);const o=r(144);const s=r(17);function requireDependencies(e){const{context:t,requireCache:r,dependencies:n}=e;const o=createRequire(t,r);for(const{path:e,mapExports:r}of n){const n=o(e,e);for(const e of Object.keys(r)){t[r[e]]=n[e]}}}t.requireDependencies=requireDependencies;function createRequire(e,t,r,i={}){return function requireFn(a,E){const c=require.resolve(E,{paths:[(0,s.dirname)(a)]});const u=t.get(E)||t.get(c);if(u!==undefined&&u!==null){return u.exports}const _={exports:{},loaded:false,id:c};t.set(c,_);r===null||r===void 0?void 0:r.add(c);const d=(0,o.runInContext)(`(function(module,exports,require,__dirname,__filename,${Object.keys(i).join(",")}) {${(0,n.readFileSync)(c,"utf-8")}\n})`,e);try{d(_,_.exports,requireFn.bind(null,c),(0,s.dirname)(c),c,...Object.values(i))}catch(e){t.delete(c);throw e}_.loaded=true;return _.exports}}t.createRequire=createRequire;function requireWithCache(e){var t;return createRequire(e.context,(t=e.cache)!==null&&t!==void 0?t:new Map,e.references,e.scopedContext).call(null,e.path,e.path)}t.requireWithCache=requireWithCache},266:function(e,t,r){"use strict";var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.tempFile=void 0;const o=r(277);const s=n(r(17));const i=n(r(147));const a=n(r(37));function tempFile(e){const t=s.default.join(a.default.tmpdir(),o.crypto.randomUUID());i.default.writeFileSync(t,e);return{path:t,remove:()=>i.default.unlinkSync(t)}}t.tempFile=tempFile},218:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.VM=void 0;const n=r(144);const o=r(986);const s=r(266);class VM{constructor(e={}){var t,r,s,i;const a=(0,n.createContext)({},{name:"Edge Runtime",codeGeneration:(t=e.codeGeneration)!==null&&t!==void 0?t:{strings:false,wasm:true}});this.requireCache=(r=e.requireCache)!==null&&r!==void 0?r:new Map;this.context=(i=(s=e.extend)===null||s===void 0?void 0:s.call(e,a))!==null&&i!==void 0?i:a;this.requireFn=(0,o.createRequire)(this.context,this.requireCache)}evaluate(e){return(0,n.runInContext)(e,this.context)}require(e){return this.requireFn(e,e)}requireInContext(e){const t=this.require(e);for(const[e,r]of Object.entries(t)){this.context[e]=r}}requireInlineInContext(e){const t=(0,s.tempFile)(e);this.requireInContext(t.path);t.remove()}}t.VM=VM},734:e=>{"use strict";e.exports=e=>{const t=e[0]*1e9+e[1];const r=t/1e6;const n=t/1e9;return{seconds:n,milliseconds:r,nanoseconds:t}}},593:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.EdgeRuntime=void 0;const n=r(135);let o;let s;class EdgeRuntime extends n.EdgeVM{constructor(e){super({...e,extend:t=>{var r,n;return(n=(r=e===null||e===void 0?void 0:e.extend)===null||r===void 0?void 0:r.call(e,t))!==null&&n!==void 0?n:t}});defineHandlerProps({object:this,setterName:"__onUnhandledRejectionHandler",setter:e=>o=e,getterName:"__rejectionHandlers",getter:()=>o});defineHandlerProps({object:this,setterName:"__onErrorHandler",setter:e=>s=e,getterName:"__errorHandlers",getter:()=>s});this.evaluate(getDefineEventListenersCode());this.dispatchFetch=this.evaluate(getDispatchFetchCode());if(e===null||e===void 0?void 0:e.initialCode){this.evaluate(e.initialCode)}}}t.EdgeRuntime=EdgeRuntime;process.on("unhandledRejection",(function invokeRejectionHandlers(e,t){o===null||o===void 0?void 0:o.forEach((r=>r(e,t)))}));process.on("uncaughtException",(function invokeErrorHandlers(e){s===null||s===void 0?void 0:s.forEach((t=>t(e)))}));function getDefineEventListenersCode(){return`\n Object.defineProperty(self, '__listeners', {\n configurable: false,\n enumerable: false,\n value: {},\n writable: true,\n })\n\n function __conditionallyUpdatesHandlerList(eventType) {\n if (eventType === 'unhandledrejection') {\n self.__onUnhandledRejectionHandler = self.__listeners[eventType];\n } else if (eventType === 'error') {\n self.__onErrorHandler = self.__listeners[eventType];\n }\n }\n\n function addEventListener(type, handler) {\n const eventType = type.toLowerCase();\n if (eventType === 'fetch' && self.__listeners.fetch) {\n throw new TypeError('You can register just one "fetch" event listener');\n }\n\n self.__listeners[eventType] = self.__listeners[eventType] || [];\n self.__listeners[eventType].push(handler);\n __conditionallyUpdatesHandlerList(eventType);\n }\n\n function removeEventListener(type, handler) {\n const eventType = type.toLowerCase();\n if (self.__listeners[eventType]) {\n self.__listeners[eventType] = self.__listeners[eventType].filter(item => {\n return item !== handler;\n });\n\n if (self.__listeners[eventType].length === 0) {\n delete self.__listeners[eventType];\n }\n }\n __conditionallyUpdatesHandlerList(eventType);\n }\n `}function getDispatchFetchCode(){return`(async function dispatchFetch(input, init) {\n const request = new Request(input, init);\n const event = new FetchEvent(request);\n if (!self.__listeners.fetch) {\n throw new Error("No fetch event listeners found");\n }\n\n const getResponse = ({ response, error }) => {\n if (error || !response || !(response instanceof Response)) {\n console.error(error ? error : 'The event listener did not respond')\n response = new Response(null, {\n statusText: 'Internal Server Error',\n status: 500\n })\n }\n\n response.waitUntil = () => Promise.all(event.awaiting);\n return response;\n }\n\n try {\n await self.__listeners.fetch[0].call(event, event)\n } catch (error) {\n return getResponse({ error })\n }\n\n return Promise.resolve(event.response)\n .then(response => getResponse({ response }))\n .catch(error => getResponse({ error }))\n })`}function defineHandlerProps({object:e,setterName:t,setter:r,getterName:n,getter:o}){Object.defineProperty(e.context,t,{set:r,configurable:false,enumerable:false});Object.defineProperty(e,n,{get:o,configurable:false,enumerable:false})}},882:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.getClonableBodyStream=void 0;const n=r(781);function getClonableBodyStream(e,t){let r=null;return{finalize(){if(r){replaceRequestBody(e,bodyStreamToNodeStream(r))}},cloneBodyStream(){const n=r!==null&&r!==void 0?r:requestToBodyStream(e,t);const[o,s]=n.tee();r=o;return s}}}t.getClonableBodyStream=getClonableBodyStream;function requestToBodyStream(e,t){const r=new t({start(t){e.on("data",(e=>t.enqueue(e)));e.on("end",(()=>t.terminate()));e.on("error",(e=>t.error(e)))}});return r.readable}function bodyStreamToNodeStream(e){const t=e.getReader();return n.Readable.from(async function*(){while(true){const{done:e,value:r}=await t.read();if(e){return}yield r}}())}function replaceRequestBody(e,t){for(const r in t){let n=t[r];if(typeof n==="function"){n=n.bind(t)}e[r]=n}return e}},12:function(e,t,r){"use strict";var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.createHandler=void 0;const o=r(882);const s=n(r(720));const i=n(r(242));const a=n(r(504));function createHandler(e){const t=new Set;return{handler:async(r,n)=>{var E,c;const u=(0,a.default)();const _=r.method!=="GET"&&r.method!=="HEAD"?(0,o.getClonableBodyStream)(r,e.runtime.context.TransformStream):undefined;const d=await e.runtime.dispatchFetch(String(getURL(r)),{headers:toRequestInitHeaders(r),method:r.method,body:_===null||_===void 0?void 0:_.cloneBodyStream()});const l=d.waitUntil();t.add(l);l.finally((()=>t.delete(l)));n.statusCode=d.status;n.statusMessage=d.statusText;for(const[e,t]of Object.entries(toNodeHeaders(d.headers))){if(e!=="content-encoding"&&t!==undefined){n.setHeader(e,t)}}if(d.body){for await(const e of d.body){n.write(e)}}const S=`${r.socket.remoteAddress} ${r.method} ${r.url}`;const R=`${(E=(0,s.default)(u()).match(/[a-zA-Z]+|[0-9]+/g))===null||E===void 0?void 0:E.join(" ")}`;const h=`${n.statusCode} ${i.default[n.statusCode]}`;(c=e.logger)===null||c===void 0?void 0:c.debug(`${S} → ${h} in ${R}`);n.end()},waitUntil:()=>Promise.all(t)}}t.createHandler=createHandler;function getURL(e){var t;const r=((t=e.socket)===null||t===void 0?void 0:t.encrypted)?"https":"http";return new URL(String(e.url),`${r}://${String(e.headers.host)}`)}function toRequestInitHeaders(e){return Object.keys(e.headers).map((t=>{const r=e.headers[t];return[t,Array.isArray(r)?r.join(", "):r!==null&&r!==void 0?r:""]}))}function toNodeHeaders(e){const t={};if(e){for(const[r,n]of e.entries()){t[r]=r.toLowerCase()==="set-cookie"?e.getAll("set-cookie"):n}}return t}},742:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.runServer=t.createHandler=void 0;var n=r(12);Object.defineProperty(t,"createHandler",{enumerable:true,get:function(){return n.createHandler}});var o=r(653);Object.defineProperty(t,"runServer",{enumerable:true,get:function(){return o.runServer}})},653:function(e,t,r){"use strict";var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.runServer=void 0;const o=r(12);const s=r(361);const i=n(r(685));async function runServer(e){const{handler:t,waitUntil:r}=(0,o.createHandler)(e);const n=i.default.createServer(t);n.listen(e.port);try{await(0,s.once)(n,"listening")}catch(t){if((t===null||t===void 0?void 0:t.code)==="EADDRINUSE"){return runServer({...e,port:undefined})}throw t}const a=n.address();const E=typeof a==="string"||a==null?String(a):`http://localhost:${a.port}`;return{url:E,close:async()=>{await r();await new Promise(((e,t)=>n.close((r=>{if(r)t(r);e()}))))},waitUntil:r}}t.runServer=runServer},242:e=>{var t;t={"1xx":"Informational","1xx_NAME":"INFORMATIONAL","1xx_MESSAGE":"Indicates an interim response for communicating connection status or request progress prior to completing the requested action and sending a final response.",INFORMATIONAL:"1xx","2xx":"Successful","2xx_NAME":"SUCCESSFUL","2xx_MESSAGE":"Indicates that the client's request was successfully received, understood, and accepted.",SUCCESSFUL:"2xx","3xx":"Redirection","3xx_NAME":"REDIRECTION","3xx_MESSAGE":"Indicates that further action needs to be taken by the user agent in order to fulfill the request.",REDIRECTION:"3xx","4xx":"Client Error","4xx_NAME":"CLIENT_ERROR","4xx_MESSAGE":"Indicates that the client seems to have erred.",CLIENT_ERROR:"4xx","5xx":"Server Error","5xx_NAME":"SERVER_ERROR","5xx_MESSAGE":"Indicates that the server is aware that it has erred or is incapable of performing the requested method.",SERVER_ERROR:"5xx"};e.exports={classes:t,100:"Continue","100_NAME":"CONTINUE","100_MESSAGE":"The server has received the request headers and the client should proceed to send the request body.","100_CLASS":t.INFORMATIONAL,CONTINUE:100,101:"Switching Protocols","101_NAME":"SWITCHING_PROTOCOLS","101_MESSAGE":"The requester has asked the server to switch protocols and the server has agreed to do so.","101_CLASS":t.INFORMATIONAL,SWITCHING_PROTOCOLS:101,102:"Processing","102_NAME":"PROCESSING","102_MESSAGE":"A WebDAV request may contain many sub-requests involving file operations, requiring a long time to complete the request. This code indicates that the server has received and is processing the request, but no response is available yet.[7] This prevents the client from timing out and assuming the request was lost.","102_CLASS":t.INFORMATIONAL,PROCESSING:102,103:"Early Hints","103_NAME":"EARLY_HINTS","103_MESSAGE":"Used to return some response headers before final HTTP message.","103_CLASS":t.INFORMATIONAL,EARLY_HINTS:103,200:"OK","200_NAME":"OK","200_MESSAGE":"Standard response for successful HTTP requests.","200_CLASS":t.SUCCESSFUL,OK:200,201:"Created","201_NAME":"CREATED","201_MESSAGE":"The request has been fulfilled, resulting in the creation of a new resource.","201_CLASS":t.SUCCESSFUL,CREATED:201,202:"Accepted","202_NAME":"ACCEPTED","202_MESSAGE":"The request has been accepted for processing, but the processing has not been completed.","202_CLASS":t.SUCCESSFUL,ACCEPTED:202,203:"Non-Authoritative Information","203_NAME":"NON_AUTHORITATIVE_INFORMATION","203_MESSAGE":"The server is a transforming proxy (e.g. a Web accelerator) that received a 200 OK from its origin, but is returning a modified version of the origin's response.","203_CLASS":t.SUCCESSFUL,NON_AUTHORITATIVE_INFORMATION:203,204:"No Content","204_NAME":"NO_CONTENT","204_MESSAGE":"The server successfully processed the request and is not returning any content.","204_CLASS":t.SUCCESSFUL,NO_CONTENT:204,205:"Reset Content","205_NAME":"RESET_CONTENT","205_MESSAGE":"The server successfully processed the request, but is not returning any content. Unlike a 204 response, this response requires that the requester reset the document view.","205_CLASS":t.SUCCESSFUL,RESET_CONTENT:205,206:"Partial Content","206_NAME":"PARTIAL_CONTENT","206_MESSAGE":"The server is delivering only part of the resource (byte serving) due to a range header sent by the client.","206_CLASS":t.SUCCESSFUL,PARTIAL_CONTENT:206,207:"Multi Status","207_NAME":"MULTI_STATUS","207_MESSAGE":"The message body that follows is by default an XML message and can contain a number of separate response codes, depending on how many sub-requests were made.","207_CLASS":t.SUCCESSFUL,MULTI_STATUS:207,208:"Already Reported","208_NAME":"ALREADY_REPORTED","208_MESSAGE":"The members of a DAV binding have already been enumerated in a preceding part of the (multistatus) response, and are not being included again.","208_CLASS":t.SUCCESSFUL,ALREADY_REPORTED:208,226:"IM Used","226_NAME":"IM_USED","226_MESSAGE":"The server has fulfilled a request for the resource, and the response is a representation of the result of one or more instance-manipulations applied to the current instance.","226_CLASS":t.SUCCESSFUL,IM_USED:226,300:"Multiple Choices","300_NAME":"MULTIPLE_CHOICES","300_MESSAGE":"Indicates multiple options for the resource from which the client may choose.","300_CLASS":t.REDIRECTION,MULTIPLE_CHOICES:300,301:"Moved Permanently","301_NAME":"MOVED_PERMANENTLY","301_MESSAGE":"This and all future requests should be directed to the given URI.","301_CLASS":t.REDIRECTION,MOVED_PERMANENTLY:301,302:"Found","302_NAME":"FOUND","302_MESSAGE":'This is an example of industry practice contradicting the standard. The HTTP/1.0 specification (RFC 1945) required the client to perform a temporary redirect (the original describing phrase was "Moved Temporarily"), but popular browsers implemented 302 with the functionality of a 303 See Other. Therefore, HTTP/1.1 added status codes 303 and 307 to distinguish between the two behaviours.',"302_CLASS":t.REDIRECTION,FOUND:302,303:"See Other","303_NAME":"SEE_OTHER","303_MESSAGE":"The response to the request can be found under another URI using the GET method.","303_CLASS":t.REDIRECTION,SEE_OTHER:303,304:"Not Modified","304_NAME":"NOT_MODIFIED","304_MESSAGE":"Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-None-Match.","304_CLASS":t.REDIRECTION,NOT_MODIFIED:304,305:"Use Proxy","305_NAME":"USE_PROXY","305_MESSAGE":"The requested resource is available only through a proxy, the address for which is provided in the response.","305_CLASS":t.REDIRECTION,USE_PROXY:305,306:"Switch Proxy","306_NAME":"SWITCH_PROXY","306_MESSAGE":'No longer used. Originally meant "Subsequent requests should use the specified proxy.',"306_CLASS":t.REDIRECTION,SWITCH_PROXY:306,307:"Temporary Redirect","307_NAME":"TEMPORARY_REDIRECT","307_MESSAGE":"In this case, the request should be repeated with another URI; however, future requests should still use the original URI.","307_CLASS":t.REDIRECTION,TEMPORARY_REDIRECT:307,308:"Permanent Redirect","308_NAME":"PERMANENT_REDIRECT","308_MESSAGE":"The request and all future requests should be repeated using another URI.","308_CLASS":t.REDIRECTION,PERMANENT_REDIRECT:308,400:"Bad Request","400_NAME":"BAD_REQUEST","400_MESSAGE":"The server cannot or will not process the request due to an apparent client error.","400_CLASS":t.CLIENT_ERROR,BAD_REQUEST:400,401:"Unauthorized","401_NAME":"UNAUTHORIZED","401_MESSAGE":"Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided.","401_CLASS":t.CLIENT_ERROR,UNAUTHORIZED:401,402:"Payment Required","402_NAME":"PAYMENT_REQUIRED","402_MESSAGE":"Reserved for future use. The original intention was that this code might be used as part of some form of digital cash or micropayment scheme, as proposed for example by GNU Taler, but that has not yet happened, and this code is not usually used.","402_CLASS":t.CLIENT_ERROR,PAYMENT_REQUIRED:402,403:"Forbidden","403_NAME":"FORBIDDEN","403_MESSAGE":"The request was valid, but the server is refusing action.","403_CLASS":t.CLIENT_ERROR,FORBIDDEN:403,404:"Not Found","404_NAME":"NOT_FOUND","404_MESSAGE":"The requested resource could not be found but may be available in the future. Subsequent requests by the client are permissible.","404_CLASS":t.CLIENT_ERROR,NOT_FOUND:404,405:"Method Not Allowed","405_NAME":"METHOD_NOT_ALLOWED","405_MESSAGE":"A request method is not supported for the requested resource.","405_CLASS":t.CLIENT_ERROR,METHOD_NOT_ALLOWED:405,406:"Not Acceptable","406_NAME":"NOT_ACCEPTABLE","406_MESSAGE":"The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.","406_CLASS":t.CLIENT_ERROR,NOT_ACCEPTABLE:406,407:"Proxy Authentication Required","407_NAME":"PROXY_AUTHENTICATION_REQUIRED","407_MESSAGE":"The client must first authenticate itself with the proxy.","407_CLASS":t.CLIENT_ERROR,PROXY_AUTHENTICATION_REQUIRED:407,408:"Request Time-out","408_NAME":"REQUEST_TIMEOUT","408_MESSAGE":"The server timed out waiting for the request.","408_CLASS":t.CLIENT_ERROR,REQUEST_TIMEOUT:408,409:"Conflict","409_NAME":"CONFLICT","409_MESSAGE":"Indicates that the request could not be processed because of conflict in the request, such as an edit conflict between multiple simultaneous updates.","409_CLASS":t.CLIENT_ERROR,CONFLICT:409,410:"Gone","410_NAME":"GONE","410_MESSAGE":"Indicates that the resource requested is no longer available and will not be available again.","410_CLASS":t.CLIENT_ERROR,GONE:410,411:"Length Required","411_NAME":"LENGTH_REQUIRED","411_MESSAGE":"The request did not specify the length of its content, which is required by the requested resource.","411_CLASS":t.CLIENT_ERROR,LENGTH_REQUIRED:411,412:"Precondition Failed","412_NAME":"PRECONDITION_FAILED","412_MESSAGE":"The server does not meet one of the preconditions that the requester put on the request.","412_CLASS":t.CLIENT_ERROR,PRECONDITION_FAILED:412,413:"Request Entity Too Large","413_NAME":"REQUEST_ENTITY_TOO_LARGE","413_MESSAGE":'The request is larger than the server is willing or able to process. Previously called "Request Entity Too Large".',"413_CLASS":t.CLIENT_ERROR,REQUEST_ENTITY_TOO_LARGE:413,414:"Request-URI Too Large","414_NAME":"REQUEST_URI_TOO_LONG","414_MESSAGE":"The URI provided was too long for the server to process.","414_CLASS":t.CLIENT_ERROR,REQUEST_URI_TOO_LONG:414,415:"Unsupported Media Type","415_NAME":"UNSUPPORTED_MEDIA_TYPE","415_MESSAGE":"The request entity has a media type which the server or resource does not support.","415_CLASS":t.CLIENT_ERROR,UNSUPPORTED_MEDIA_TYPE:415,416:"Requested Range not Satisfiable","416_NAME":"REQUESTED_RANGE_NOT_SATISFIABLE","416_MESSAGE":"The client has asked for a portion of the file (byte serving), but the server cannot supply that portion.","416_CLASS":t.CLIENT_ERROR,REQUESTED_RANGE_NOT_SATISFIABLE:416,417:"Expectation Failed","417_NAME":"EXPECTATION_FAILED","417_MESSAGE":"The server cannot meet the requirements of the Expect request-header field.","417_CLASS":t.CLIENT_ERROR,EXPECTATION_FAILED:417,418:"I'm a teapot","418_NAME":"IM_A_TEAPOT","418_MESSAGE":'Any attempt to brew coffee with a teapot should result in the error code "418 I\'m a teapot". The resulting entity body MAY be short and stout.',"418_CLASS":t.CLIENT_ERROR,IM_A_TEAPOT:418,421:"Misdirected Request","421_NAME":"MISDIRECTED_REQUEST","421_MESSAGE":"The request was directed at a server that is not able to produce a response.","421_CLASS":t.CLIENT_ERROR,MISDIRECTED_REQUEST:421,422:"Unprocessable Entity","422_NAME":"UNPROCESSABLE_ENTITY","422_MESSAGE":"The request was well-formed but was unable to be followed due to semantic errors.","422_CLASS":t.CLIENT_ERROR,UNPROCESSABLE_ENTITY:422,423:"Locked","423_NAME":"LOCKED","423_MESSAGE":"The resource that is being accessed is locked.","423_CLASS":t.CLIENT_ERROR,LOCKED:423,424:"Failed Dependency","424_NAME":"FAILED_DEPENDENCY","424_MESSAGE":"The request failed because it depended on another request and that request failed.","424_CLASS":t.CLIENT_ERROR,FAILED_DEPENDENCY:424,426:"Upgrade Required","426_NAME":"UPGRADE_REQUIRED","426_MESSAGE":"The client should switch to a different protocol such as TLS/1.0, given in the Upgrade header field.","426_CLASS":t.CLIENT_ERROR,UPGRADE_REQUIRED:426,428:"Precondition Required","428_NAME":"PRECONDITION_REQUIRED","428_MESSAGE":"The origin server requires the request to be conditional.","428_CLASS":t.CLIENT_ERROR,PRECONDITION_REQUIRED:428,429:"Too Many Requests","429_NAME":"TOO_MANY_REQUESTS","429_MESSAGE":"The user has sent too many requests in a given amount of time.","429_CLASS":t.CLIENT_ERROR,TOO_MANY_REQUESTS:429,431:"Request Header Fields Too Large","431_NAME":"REQUEST_HEADER_FIELDS_TOO_LARGE","431_MESSAGE":"The server is unwilling to process the request because either an individual header field, or all the header fields collectively, are too large.","431_CLASS":t.CLIENT_ERROR,REQUEST_HEADER_FIELDS_TOO_LARGE:431,451:"Unavailable For Legal Reasons","451_NAME":"UNAVAILABLE_FOR_LEGAL_REASONS","451_MESSAGE":"A server operator has received a legal demand to deny access to a resource or to a set of resources that includes the requested resource.","451_CLASS":t.CLIENT_ERROR,UNAVAILABLE_FOR_LEGAL_REASONS:451,500:"Internal Server Error","500_NAME":"INTERNAL_SERVER_ERROR","500_MESSAGE":"A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.","500_CLASS":t.SERVER_ERROR,INTERNAL_SERVER_ERROR:500,501:"Not Implemented","501_NAME":"NOT_IMPLEMENTED","501_MESSAGE":"The server either does not recognize the request method, or it lacks the ability to fulfil the request. Usually this implies future availability.","501_CLASS":t.SERVER_ERROR,NOT_IMPLEMENTED:501,502:"Bad Gateway","502_NAME":"BAD_GATEWAY","502_MESSAGE":"The server was acting as a gateway or proxy and received an invalid response from the upstream server.","502_CLASS":t.SERVER_ERROR,BAD_GATEWAY:502,503:"Service Unavailable","503_NAME":"SERVICE_UNAVAILABLE","503_MESSAGE":"The server is currently unavailable (because it is overloaded or down for maintenance). Generally, this is a temporary state.","503_CLASS":t.SERVER_ERROR,SERVICE_UNAVAILABLE:503,504:"Gateway Time-out","504_NAME":"GATEWAY_TIMEOUT","504_MESSAGE":"The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.","504_CLASS":t.SERVER_ERROR,GATEWAY_TIMEOUT:504,505:"HTTP Version not Supported","505_NAME":"HTTP_VERSION_NOT_SUPPORTED","505_MESSAGE":"The server does not support the HTTP protocol version used in the request.","505_CLASS":t.SERVER_ERROR,HTTP_VERSION_NOT_SUPPORTED:505,506:"Variant Also Negotiates","506_NAME":"VARIANT_ALSO_NEGOTIATES","506_MESSAGE":"Transparent content negotiation for the request results in a circular reference.","506_CLASS":t.SERVER_ERROR,VARIANT_ALSO_NEGOTIATES:506,507:"Insufficient Storage","507_NAME":"INSUFFICIENT_STORAGE","507_MESSAGE":"The server is unable to store the representation needed to complete the request.","507_CLASS":t.SERVER_ERROR,INSUFFICIENT_STORAGE:507,508:"Loop Detected","508_NAME":"LOOP_DETECTED","508_MESSAGE":"The server detected an infinite loop while processing the request.","508_CLASS":t.SERVER_ERROR,LOOP_DETECTED:508,510:"Not Extended","510_NAME":"NOT_EXTENDED","510_MESSAGE":"Further extensions to the request are required for the server to fulfil it.","510_CLASS":t.SERVER_ERROR,NOT_EXTENDED:510,511:"Network Authentication Required","511_NAME":"NETWORK_AUTHENTICATION_REQUIRED","511_MESSAGE":"The client needs to authenticate to gain network access. Intended for use by intercepting proxies used to control access to the network.","511_CLASS":t.SERVER_ERROR,NETWORK_AUTHENTICATION_REQUIRED:511,extra:{unofficial:{103:"Checkpoint","103_NAME":"CHECKPOINT","103_MESSAGE":"Used in the resumable requests proposal to resume aborted PUT or POST requests.","103_CLASS":t.INFORMATIONAL,CHECKPOINT:103,419:"Page Expired","419_NAME":"PAGE_EXPIRED","419_MESSAGE":"Used by the Laravel Framework when a CSRF Token is missing or expired.","419_CLASS":t.CLIENT_ERROR,PAGE_EXPIRED:419,218:"This is fine","218_NAME":"THIS_IS_FINE","218_MESSAGE":"Used as a catch-all error condition for allowing response bodies to flow through Apache when ProxyErrorOverride is enabled. When ProxyErrorOverride is enabled in Apache, response bodies that contain a status code of 4xx or 5xx are automatically discarded by Apache in favor of a generic response or a custom response specified by the ErrorDocument directive.","218_CLASS":t.SUCCESSFUL,THIS_IS_FINE:218,420:"Enhance Your Calm","420_NAME":"ENHANCE_YOUR_CALM","420_MESSAGE":"Returned by version 1 of the Twitter Search and Trends API when the client is being rate limited; versions 1.1 and later use the 429 Too Many Requests response code instead.","420_CLASS":t.CLIENT_ERROR,ENHANCE_YOUR_CALM:420,450:"Blocked by Windows Parental Controls","450_NAME":"BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS","450_MESSAGE":"The Microsoft extension code indicated when Windows Parental Controls are turned on and are blocking access to the requested webpage.","450_CLASS":t.CLIENT_ERROR,BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS:450,498:"Invalid Token","498_NAME":"INVALID_TOKEN","498_MESSAGE":"Returned by ArcGIS for Server. Code 498 indicates an expired or otherwise invalid token.","498_CLASS":t.CLIENT_ERROR,INVALID_TOKEN:498,499:"Token Required","499_NAME":"TOKEN_REQUIRED","499_MESSAGE":"Returned by ArcGIS for Server. Code 499 indicates that a token is required but was not submitted.","499_CLASS":t.CLIENT_ERROR,TOKEN_REQUIRED:499,509:"Bandwidth Limit Exceeded","509_NAME":"BANDWIDTH_LIMIT_EXCEEDED","509_MESSAGE":"The server has exceeded the bandwidth specified by the server administrator.","509_CLASS":t.SERVER_ERROR,BANDWIDTH_LIMIT_EXCEEDED:509,530:"Site is frozen","530_NAME":"SITE_IS_FROZEN","530_MESSAGE":"Used by the Pantheon web platform to indicate a site that has been frozen due to inactivity.","530_CLASS":t.SERVER_ERROR,SITE_IS_FROZEN:530,598:"Network read timeout error","598_NAME":"NETWORK_READ_TIMEOUT_ERROR","598_MESSAGE":"Used by some HTTP proxies to signal a network read timeout behind the proxy to a client in front of the proxy.","598_CLASS":t.SERVER_ERROR,NETWORK_READ_TIMEOUT_ERROR:598},iis:{440:"Login Time-out","440_NAME":"LOGIN_TIME_OUT","440_MESSAGE":"The client's session has expired and must log in again.","440_CLASS":t.CLIENT_ERROR,LOGIN_TIME_OUT:440,449:"Retry With","449_NAME":"RETRY_WITH","449_MESSAGE":"The server cannot honour the request because the user has not provided the required information.","449_CLASS":t.CLIENT_ERROR,RETRY_WITH:449,451:"Redirect","451_NAME":"REDIRECT","451_MESSAGE":"Used in Exchange ActiveSync when either a more efficient server is available or the server cannot access the users' mailbox.","451_CLASS":t.CLIENT_ERROR,REDIRECT:451},nginx:{444:"No Response","444_NAME":"NO_RESPONSE","444_MESSAGE":"Used internally to instruct the server to return no information to the client and close the connection immediately.","444_CLASS":t.CLIENT_ERROR,NO_RESPONSE:444,494:"Request header too large","494_NAME":"REQUEST_HEADER_TOO_LARGE","494_MESSAGE":"Client sent too large request or too long header line.","494_CLASS":t.CLIENT_ERROR,REQUEST_HEADER_TOO_LARGE:494,495:"SSL Certificate Error","495_NAME":"SSL_CERTIFICATE_ERROR","495_MESSAGE":"An expansion of the 400 Bad Request response code, used when the client has provided an invalid client certificate.","495_CLASS":t.CLIENT_ERROR,SSL_CERTIFICATE_ERROR:495,496:"SSL Certificate Required","496_NAME":"SSL_CERTIFICATE_REQUIRED","496_MESSAGE":"An expansion of the 400 Bad Request response code, used when a client certificate is required but not provided.","496_CLASS":t.CLIENT_ERROR,SSL_CERTIFICATE_REQUIRED:496,497:"HTTP Request Sent to HTTPS Port","497_NAME":"HTTP_REQUEST_SENT_TO_HTTPS_PORT","497_MESSAGE":"An expansion of the 400 Bad Request response code, used when the client has made a HTTP request to a port listening for HTTPS requests.","497_CLASS":t.CLIENT_ERROR,HTTP_REQUEST_SENT_TO_HTTPS_PORT:497,499:"Client Closed Request","499_NAME":"CLIENT_CLOSED_REQUEST","499_MESSAGE":"Used when the client has closed the request before the server could send a response.","499_CLASS":t.CLIENT_ERROR,CLIENT_CLOSED_REQUEST:499},cloudflare:{520:"Unknown Error","520_NAME":"UNKNOWN_ERROR","520_MESSAGE":'The 520 error is used as a "catch-all response for when the origin server returns something unexpected", listing connection resets, large headers, and empty or invalid responses as common triggers.',"520_CLASS":t.SERVER_ERROR,UNKNOWN_ERROR:520,521:"Web Server Is Down","521_NAME":"WEB_SERVER_IS_DOWN","521_MESSAGE":"The origin server has refused the connection from Cloudflare.","521_CLASS":t.SERVER_ERROR,WEB_SERVER_IS_DOWN:521,522:"Connection Timed Out","522_NAME":"CONNECTION_TIMED_OUT","522_MESSAGE":"Cloudflare could not negotiate a TCP handshake with the origin server.","522_CLASS":t.SERVER_ERROR,CONNECTION_TIMED_OUT:522,523:"Origin Is Unreachable","523_NAME":"ORIGIN_IS_UNREACHABLE","523_MESSAGE":"Cloudflare could not reach the origin server.","523_CLASS":t.SERVER_ERROR,ORIGIN_IS_UNREACHABLE:523,524:"A Timeout Occurred","524_NAME":"A_TIMEOUT_OCCURRED","524_MESSAGE":"Cloudflare was able to complete a TCP connection to the origin server, but did not receive a timely HTTP response.","524_CLASS":t.SERVER_ERROR,A_TIMEOUT_OCCURRED:524,525:"SSL Handshake Failed","525_NAME":"SSL_HANDSHAKE_FAILED","525_MESSAGE":"Cloudflare could not negotiate a SSL/TLS handshake with the origin server.","525_CLASS":t.SERVER_ERROR,SSL_HANDSHAKE_FAILED:525,526:"Invalid SSL Certificate","526_NAME":"INVALID_SSL_CERTIFICATE","526_MESSAGE":"Cloudflare could not validate the SSL/TLS certificate that the origin server presented.","526_CLASS":t.SERVER_ERROR,INVALID_SSL_CERTIFICATE:526,527:"Railgun Error","527_NAME":"RAILGUN_ERROR","527_MESSAGE":"Error 527 indicates that the request timed out or failed after the WAN connection had been established.","527_CLASS":t.SERVER_ERROR,RAILGUN_ERROR:527}}}},672:e=>{"use strict";e.exports=e=>{if(typeof e!=="number"){throw new TypeError("Expected a number")}const t=e>0?Math.floor:Math.ceil;return{days:t(e/864e5),hours:t(e/36e5)%24,minutes:t(e/6e4)%60,seconds:t(e/1e3)%60,milliseconds:t(e)%1e3,microseconds:t(e*1e3)%1e3,nanoseconds:t(e*1e6)%1e3}}},720:(e,t,r)=>{"use strict";const n=r(672);const pluralize=(e,t)=>t===1?e:`${e}s`;const o=1e-7;e.exports=(e,t={})=>{if(!Number.isFinite(e)){throw new TypeError("Expected a finite number")}if(t.colonNotation){t.compact=false;t.formatSubMilliseconds=false;t.separateMilliseconds=false;t.verbose=false}if(t.compact){t.secondsDecimalDigits=0;t.millisecondsDecimalDigits=0}const r=[];const floorDecimals=(e,t)=>{const r=Math.floor(e*10**t+o);const n=Math.round(r)/10**t;return n.toFixed(t)};const add=(e,n,o,s)=>{if((r.length===0||!t.colonNotation)&&e===0&&!(t.colonNotation&&o==="m")){return}s=(s||e||"0").toString();let i;let a;if(t.colonNotation){i=r.length>0?":":"";a="";const e=s.includes(".")?s.split(".")[0].length:s.length;const t=r.length>0?2:1;s="0".repeat(Math.max(0,t-e))+s}else{i="";a=t.verbose?" "+pluralize(n,e):o}r.push(i+s+a)};const s=n(e);add(Math.trunc(s.days/365),"year","y");add(s.days%365,"day","d");add(s.hours,"hour","h");add(s.minutes,"minute","m");if(t.separateMilliseconds||t.formatSubMilliseconds||!t.colonNotation&&e<1e3){add(s.seconds,"second","s");if(t.formatSubMilliseconds){add(s.milliseconds,"millisecond","ms");add(s.microseconds,"microsecond","µs");add(s.nanoseconds,"nanosecond","ns")}else{const e=s.milliseconds+s.microseconds/1e3+s.nanoseconds/1e6;const r=typeof t.millisecondsDecimalDigits==="number"?t.millisecondsDecimalDigits:0;const n=e>=1?Math.round(e):Math.ceil(e);const o=r?e.toFixed(r):n;add(Number.parseFloat(o,10),"millisecond","ms",o)}}else{const r=e/1e3%60;const n=typeof t.secondsDecimalDigits==="number"?t.secondsDecimalDigits:1;const o=floorDecimals(r,n);const s=t.keepDecimalsOnWholeSeconds?o:o.replace(/\.0+$/,"");add(Number.parseFloat(s,10),"second","s",s)}if(r.length===0){return"0"+(t.verbose?" milliseconds":"ms")}if(t.compact){return r[0]}if(typeof t.unitCount==="number"){const e=t.colonNotation?"":" ";return r.slice(0,Math.max(t.unitCount,1)).join(e)}return t.colonNotation?r.join(""):r.join(" ")}},504:(e,t,r)=>{"use strict";const n=r(734);e.exports=()=>{const e=process.hrtime();const end=t=>n(process.hrtime(e))[t];const returnValue=()=>end("milliseconds");returnValue.rounded=()=>Math.round(end("milliseconds"));returnValue.seconds=()=>end("seconds");returnValue.nanoseconds=()=>end("nanoseconds");return returnValue}},491:e=>{"use strict";e.exports=require("assert")},300:e=>{"use strict";e.exports=require("buffer")},113:e=>{"use strict";e.exports=require("crypto")},361:e=>{"use strict";e.exports=require("events")},147:e=>{"use strict";e.exports=require("fs")},685:e=>{"use strict";e.exports=require("http")},808:e=>{"use strict";e.exports=require("net")},277:e=>{"use strict";e.exports=require("next/dist/compiled/@edge-runtime/primitives/crypto")},37:e=>{"use strict";e.exports=require("os")},17:e=>{"use strict";e.exports=require("path")},74:e=>{"use strict";e.exports=require("perf_hooks")},282:e=>{"use strict";e.exports=require("process")},477:e=>{"use strict";e.exports=require("punycode")},781:e=>{"use strict";e.exports=require("stream")},404:e=>{"use strict";e.exports=require("tls")},837:e=>{"use strict";e.exports=require("util")},144:e=>{"use strict";e.exports=require("vm")},796:e=>{"use strict";e.exports=require("zlib")}};var __webpack_module_cache__={};function __nccwpck_require__(e){var t=__webpack_module_cache__[e];if(t!==undefined){return t.exports}var r=__webpack_module_cache__[e]={exports:{}};var n=true;try{__webpack_modules__[e].call(r.exports,r,r.exports,__nccwpck_require__);n=false}finally{if(n)delete __webpack_module_cache__[e]}return r.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var __webpack_exports__={};(()=>{"use strict";var e=__webpack_exports__;Object.defineProperty(e,"__esModule",{value:true});e.EdgeRuntime=e.runServer=e.createHandler=void 0;var t=__nccwpck_require__(742);Object.defineProperty(e,"createHandler",{enumerable:true,get:function(){return t.createHandler}});Object.defineProperty(e,"runServer",{enumerable:true,get:function(){return t.runServer}});var r=__nccwpck_require__(593);Object.defineProperty(e,"EdgeRuntime",{enumerable:true,get:function(){return r.EdgeRuntime}})})();module.exports=__webpack_exports__})(); \ No newline at end of file +(()=>{var __webpack_modules__={1:(__unused_webpack_module,exports,__nccwpck_require__)=>{"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.EdgeVM=void 0;const buffer_1=__nccwpck_require__(300);const require_1=__nccwpck_require__(317);const vm_1=__nccwpck_require__(140);const vm_2=__nccwpck_require__(144);class EdgeVM extends vm_1.VM{constructor(e={}){super({...e,extend:t=>e.extend?e.extend(addPrimitives(t)):addPrimitives(t)})}}exports.EdgeVM=EdgeVM;function addPrimitives(context){defineProperty(context,"self",{enumerable:true,value:context});defineProperty(context,"globalThis",{value:context});defineProperty(context,"Symbol",{value:Symbol});defineProperty(context,"clearInterval",{value:clearInterval});defineProperty(context,"clearTimeout",{value:clearTimeout});defineProperty(context,"setInterval",{value:setInterval});defineProperty(context,"setTimeout",{value:setTimeout});defineProperty(context,"EdgeRuntime",{value:"edge-runtime"});defineProperties(context,{exports:(0,require_1.requireWithCache)({context:context,path:require.resolve("next/dist/compiled/@edge-runtime/primitives/console"),scopedContext:{console:console}}),nonenumerable:["console"]});const encodings=(0,require_1.requireWithCache)({context:context,path:require.resolve("next/dist/compiled/@edge-runtime/primitives/encoding"),scopedContext:{Buffer:buffer_1.Buffer,global:{}}});defineProperties(context,{exports:encodings,nonenumerable:["atob","btoa","TextEncoder","TextDecoder"]});const streams=(0,require_1.requireWithCache)({path:require.resolve("next/dist/compiled/@edge-runtime/primitives/streams"),context:context});defineProperties(context,{exports:streams,nonenumerable:["ReadableStream","ReadableStreamBYOBReader","ReadableStreamDefaultReader","TransformStream","WritableStream","WritableStreamDefaultWriter"]});const abort=(0,require_1.requireWithCache)({context:context,path:require.resolve("next/dist/compiled/@edge-runtime/primitives/abort-controller")});defineProperties(context,{exports:abort,nonenumerable:["AbortController","AbortSignal"]});defineProperties(context,{exports:(0,require_1.requireWithCache)({cache:new Map([["punycode",{exports:__nccwpck_require__(477)}]]),context:context,path:require.resolve("next/dist/compiled/@edge-runtime/primitives/url"),scopedContext:{TextEncoder:encodings.TextEncoder,TextDecoder:encodings.TextDecoder}}),nonenumerable:["URL","URLSearchParams","URLPattern"]});const blob=(0,require_1.requireWithCache)({context:context,path:require.resolve("next/dist/compiled/@edge-runtime/primitives/blob")});defineProperties(context,{exports:blob,nonenumerable:["Blob"]});const webFetch=(0,require_1.requireWithCache)({context:context,cache:new Map([["abort-controller",{exports:abort}],["assert",{exports:__nccwpck_require__(491)}],["buffer",{exports:__nccwpck_require__(300)}],["events",{exports:__nccwpck_require__(361)}],["http",{exports:__nccwpck_require__(685)}],["net",{exports:__nccwpck_require__(808)}],["perf_hooks",{exports:__nccwpck_require__(74)}],["stream",{exports:__nccwpck_require__(781)}],["tls",{exports:__nccwpck_require__(404)}],["util",{exports:__nccwpck_require__(837)}],["zlib",{exports:__nccwpck_require__(796)}],[require.resolve("next/dist/compiled/@edge-runtime/primitives/streams"),{exports:streams}],[require.resolve("next/dist/compiled/@edge-runtime/primitives/blob"),{exports:blob}]]),path:require.resolve("next/dist/compiled/@edge-runtime/primitives/fetch"),scopedContext:{Uint8Array:createUint8ArrayForContext(context),Buffer:buffer_1.Buffer,FinalizationRegistry:function(){return{register:function(){}}},global:{},queueMicrotask:queueMicrotask,setImmediate:setImmediate}});defineProperties(context,{exports:webFetch,nonenumerable:["fetch","File","FormData","Headers","Request","Response"]});defineProperties(context,{exports:(0,require_1.requireWithCache)({cache:new Map([[require.resolve("next/dist/compiled/@edge-runtime/primitives/fetch"),{exports:webFetch}]]),context:context,path:require.resolve("next/dist/compiled/@edge-runtime/primitives/cache"),scopedContext:{global:{}}}),enumerable:["caches"],nonenumerable:["Cache","CacheStorage"]});defineProperties(context,{exports:(0,require_1.requireWithCache)({context:context,cache:new Map([["crypto",{exports:__nccwpck_require__(113)}],["process",{exports:__nccwpck_require__(282)}]]),path:require.resolve("next/dist/compiled/@edge-runtime/primitives/crypto"),scopedContext:{Buffer:buffer_1.Buffer,Uint8Array:createUint8ArrayForContext(context)}}),enumerable:["crypto"],nonenumerable:["Crypto","CryptoKey","SubtleCrypto"]});defineProperties(context,{exports:(0,require_1.requireWithCache)({context:context,path:require.resolve("next/dist/compiled/@edge-runtime/primitives/events")}),nonenumerable:["Event","EventTarget","FetchEvent","PromiseRejectionEvent"]});defineProperties(context,{exports:(0,require_1.requireWithCache)({context:context,path:require.resolve("next/dist/compiled/@edge-runtime/primitives/structured-clone")}),nonenumerable:["structuredClone"]});return context}function defineProperty(e,t,r){var n,o,s;Object.defineProperty(e,t,{configurable:(n=r.configurable)!==null&&n!==void 0?n:false,enumerable:(o=r.enumerable)!==null&&o!==void 0?o:false,value:r.value,writable:(s=r.writable)!==null&&s!==void 0?s:true})}function defineProperties(e,t){var r,n;for(const n of(r=t.enumerable)!==null&&r!==void 0?r:[]){if(!t.exports[n]){throw new Error(`Attempt to export a nullable value for "${n}"`)}defineProperty(e,n,{enumerable:true,value:t.exports[n]})}for(const r of(n=t.nonenumerable)!==null&&n!==void 0?n:[]){if(!t.exports[r]){throw new Error(`Attempt to export a nullable value for "${r}"`)}defineProperty(e,r,{value:t.exports[r]})}}function createUint8ArrayForContext(e){return new Proxy((0,vm_2.runInContext)("Uint8Array",e),{construct(e,t){const r=new e(...t);if(!(t[0]instanceof buffer_1.Buffer)){return r}return new e([...r])}})}},0:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.VM=t.EdgeVM=void 0;var n=r(1);Object.defineProperty(t,"EdgeVM",{enumerable:true,get:function(){return n.EdgeVM}});var o=r(140);Object.defineProperty(t,"VM",{enumerable:true,get:function(){return o.VM}})},317:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.requireWithCache=t.createRequire=t.requireDependencies=void 0;const n=r(147);const o=r(144);const s=r(17);function requireDependencies(e){const{context:t,requireCache:r,dependencies:n}=e;const o=createRequire(t,r);for(const{path:e,mapExports:r}of n){const n=o(e,e);for(const e of Object.keys(r)){t[r[e]]=n[e]}}}t.requireDependencies=requireDependencies;function createRequire(e,t,r,i={}){return function requireFn(a,E){const c=require.resolve(E,{paths:[(0,s.dirname)(a)]});const u=t.get(E)||t.get(c);if(u!==undefined&&u!==null){return u.exports}const _={exports:{},loaded:false,id:c};t.set(c,_);r===null||r===void 0?void 0:r.add(c);const d=(0,o.runInContext)(`(function(module,exports,require,__dirname,__filename,${Object.keys(i).join(",")}) {${(0,n.readFileSync)(c,"utf-8")}\n})`,e);try{d(_,_.exports,requireFn.bind(null,c),(0,s.dirname)(c),c,...Object.values(i))}catch(e){t.delete(c);throw e}_.loaded=true;return _.exports}}t.createRequire=createRequire;function requireWithCache(e){var t;return createRequire(e.context,(t=e.cache)!==null&&t!==void 0?t:new Map,e.references,e.scopedContext).call(null,e.path,e.path)}t.requireWithCache=requireWithCache},370:function(e,t,r){"use strict";var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.tempFile=void 0;const o=r(277);const s=n(r(17));const i=n(r(147));const a=n(r(37));function tempFile(e){const t=s.default.join(a.default.tmpdir(),o.crypto.randomUUID());i.default.writeFileSync(t,e);return{path:t,remove:()=>i.default.unlinkSync(t)}}t.tempFile=tempFile},140:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.VM=void 0;const n=r(144);const o=r(317);const s=r(370);class VM{constructor(e={}){var t,r,s,i;const a=(0,n.createContext)({},{name:"Edge Runtime",codeGeneration:(t=e.codeGeneration)!==null&&t!==void 0?t:{strings:false,wasm:true}});this.requireCache=(r=e.requireCache)!==null&&r!==void 0?r:new Map;this.context=(i=(s=e.extend)===null||s===void 0?void 0:s.call(e,a))!==null&&i!==void 0?i:a;this.requireFn=(0,o.createRequire)(this.context,this.requireCache)}evaluate(e){return(0,n.runInContext)(e,this.context)}require(e){return this.requireFn(e,e)}requireInContext(e){const t=this.require(e);for(const[e,r]of Object.entries(t)){this.context[e]=r}}requireInlineInContext(e){const t=(0,s.tempFile)(e);this.requireInContext(t.path);t.remove()}}t.VM=VM},734:e=>{"use strict";e.exports=e=>{const t=e[0]*1e9+e[1];const r=t/1e6;const n=t/1e9;return{seconds:n,milliseconds:r,nanoseconds:t}}},14:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.EdgeRuntime=void 0;const n=r(0);let o;let s;class EdgeRuntime extends n.EdgeVM{constructor(e){super({...e,extend:t=>{var r,n;return(n=(r=e===null||e===void 0?void 0:e.extend)===null||r===void 0?void 0:r.call(e,t))!==null&&n!==void 0?n:t}});defineHandlerProps({object:this,setterName:"__onUnhandledRejectionHandler",setter:e=>o=e,getterName:"__rejectionHandlers",getter:()=>o});defineHandlerProps({object:this,setterName:"__onErrorHandler",setter:e=>s=e,getterName:"__errorHandlers",getter:()=>s});this.evaluate(getDefineEventListenersCode());this.dispatchFetch=this.evaluate(getDispatchFetchCode());if(e===null||e===void 0?void 0:e.initialCode){this.evaluate(e.initialCode)}}}t.EdgeRuntime=EdgeRuntime;process.on("unhandledRejection",(function invokeRejectionHandlers(e,t){o===null||o===void 0?void 0:o.forEach((r=>r(e,t)))}));process.on("uncaughtException",(function invokeErrorHandlers(e){s===null||s===void 0?void 0:s.forEach((t=>t(e)))}));function getDefineEventListenersCode(){return`\n Object.defineProperty(self, '__listeners', {\n configurable: false,\n enumerable: false,\n value: {},\n writable: true,\n })\n\n function __conditionallyUpdatesHandlerList(eventType) {\n if (eventType === 'unhandledrejection') {\n self.__onUnhandledRejectionHandler = self.__listeners[eventType];\n } else if (eventType === 'error') {\n self.__onErrorHandler = self.__listeners[eventType];\n }\n }\n\n function addEventListener(type, handler) {\n const eventType = type.toLowerCase();\n if (eventType === 'fetch' && self.__listeners.fetch) {\n throw new TypeError('You can register just one "fetch" event listener');\n }\n\n self.__listeners[eventType] = self.__listeners[eventType] || [];\n self.__listeners[eventType].push(handler);\n __conditionallyUpdatesHandlerList(eventType);\n }\n\n function removeEventListener(type, handler) {\n const eventType = type.toLowerCase();\n if (self.__listeners[eventType]) {\n self.__listeners[eventType] = self.__listeners[eventType].filter(item => {\n return item !== handler;\n });\n\n if (self.__listeners[eventType].length === 0) {\n delete self.__listeners[eventType];\n }\n }\n __conditionallyUpdatesHandlerList(eventType);\n }\n `}function getDispatchFetchCode(){return`(async function dispatchFetch(input, init) {\n const request = new Request(input, init);\n const event = new FetchEvent(request);\n if (!self.__listeners.fetch) {\n throw new Error("No fetch event listeners found");\n }\n\n const getResponse = ({ response, error }) => {\n if (error || !response || !(response instanceof Response)) {\n console.error(error ? error : 'The event listener did not respond')\n response = new Response(null, {\n statusText: 'Internal Server Error',\n status: 500\n })\n }\n\n response.waitUntil = () => Promise.all(event.awaiting);\n\n response.headers.delete('content-encoding');\n response.headers.delete('transform-encoding');\n response.headers.delete('content-length');\n\n return response;\n }\n\n try {\n await self.__listeners.fetch[0].call(event, event)\n } catch (error) {\n return getResponse({ error })\n }\n\n return Promise.resolve(event.response)\n .then(response => getResponse({ response }))\n .catch(error => getResponse({ error }))\n })`}function defineHandlerProps({object:e,setterName:t,setter:r,getterName:n,getter:o}){Object.defineProperty(e.context,t,{set:r,configurable:false,enumerable:false});Object.defineProperty(e,n,{get:o,configurable:false,enumerable:false})}},547:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.getClonableBodyStream=void 0;const n=r(781);function getClonableBodyStream(e,t){let r=null;return{finalize(){if(r){replaceRequestBody(e,bodyStreamToNodeStream(r))}},cloneBodyStream(){const n=r!==null&&r!==void 0?r:requestToBodyStream(e,t);const[o,s]=n.tee();r=o;return s}}}t.getClonableBodyStream=getClonableBodyStream;function requestToBodyStream(e,t){const r=new t({start(t){e.on("data",(e=>t.enqueue(e)));e.on("end",(()=>t.terminate()));e.on("error",(e=>t.error(e)))}});return r.readable}function bodyStreamToNodeStream(e){const t=e.getReader();return n.Readable.from(async function*(){while(true){const{done:e,value:r}=await t.read();if(e){return}yield r}}())}function replaceRequestBody(e,t){for(const r in t){let n=t[r];if(typeof n==="function"){n=n.bind(t)}e[r]=n}return e}},302:function(e,t,r){"use strict";var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.createHandler=void 0;const o=r(547);const s=n(r(720));const i=n(r(242));const a=n(r(504));function createHandler(e){const t=new Set;return{handler:async(r,n)=>{var E,c;const u=(0,a.default)();const _=r.method!=="GET"&&r.method!=="HEAD"?(0,o.getClonableBodyStream)(r,e.runtime.context.TransformStream):undefined;const d=await e.runtime.dispatchFetch(String(getURL(r)),{headers:toRequestInitHeaders(r),method:r.method,body:_===null||_===void 0?void 0:_.cloneBodyStream()});const l=d.waitUntil();t.add(l);l.finally((()=>t.delete(l)));n.statusCode=d.status;n.statusMessage=d.statusText;for(const[e,t]of Object.entries(toNodeHeaders(d.headers))){if(t!==undefined){n.setHeader(e,t)}}if(d.body){for await(const e of d.body){n.write(e)}}const S=`${r.socket.remoteAddress} ${r.method} ${r.url}`;const R=`${(E=(0,s.default)(u()).match(/[a-zA-Z]+|[0-9]+/g))===null||E===void 0?void 0:E.join(" ")}`;const h=`${n.statusCode} ${i.default[n.statusCode]}`;(c=e.logger)===null||c===void 0?void 0:c.debug(`${S} → ${h} in ${R}`);n.end()},waitUntil:()=>Promise.all(t)}}t.createHandler=createHandler;function getURL(e){var t;const r=((t=e.socket)===null||t===void 0?void 0:t.encrypted)?"https":"http";return new URL(String(e.url),`${r}://${String(e.headers.host)}`)}function toRequestInitHeaders(e){return Object.keys(e.headers).map((t=>{const r=e.headers[t];return[t,Array.isArray(r)?r.join(", "):r!==null&&r!==void 0?r:""]}))}function toNodeHeaders(e){const t={};if(e){for(const[r,n]of e.entries()){t[r]=r.toLowerCase()==="set-cookie"?e.getAll("set-cookie"):n}}return t}},707:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.runServer=t.createHandler=void 0;var n=r(302);Object.defineProperty(t,"createHandler",{enumerable:true,get:function(){return n.createHandler}});var o=r(719);Object.defineProperty(t,"runServer",{enumerable:true,get:function(){return o.runServer}})},719:function(e,t,r){"use strict";var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.runServer=void 0;const o=r(302);const s=r(361);const i=n(r(685));async function runServer(e){const{handler:t,waitUntil:r}=(0,o.createHandler)(e);const n=i.default.createServer(t);n.listen(e.port);try{await(0,s.once)(n,"listening")}catch(t){if((t===null||t===void 0?void 0:t.code)==="EADDRINUSE"){return runServer({...e,port:undefined})}throw t}const a=n.address();const E=typeof a==="string"||a==null?String(a):`http://localhost:${a.port}`;return{url:E,close:async()=>{await r();await new Promise(((e,t)=>n.close((r=>{if(r)t(r);e()}))))},waitUntil:r}}t.runServer=runServer},242:e=>{var t;t={"1xx":"Informational","1xx_NAME":"INFORMATIONAL","1xx_MESSAGE":"Indicates an interim response for communicating connection status or request progress prior to completing the requested action and sending a final response.",INFORMATIONAL:"1xx","2xx":"Successful","2xx_NAME":"SUCCESSFUL","2xx_MESSAGE":"Indicates that the client's request was successfully received, understood, and accepted.",SUCCESSFUL:"2xx","3xx":"Redirection","3xx_NAME":"REDIRECTION","3xx_MESSAGE":"Indicates that further action needs to be taken by the user agent in order to fulfill the request.",REDIRECTION:"3xx","4xx":"Client Error","4xx_NAME":"CLIENT_ERROR","4xx_MESSAGE":"Indicates that the client seems to have erred.",CLIENT_ERROR:"4xx","5xx":"Server Error","5xx_NAME":"SERVER_ERROR","5xx_MESSAGE":"Indicates that the server is aware that it has erred or is incapable of performing the requested method.",SERVER_ERROR:"5xx"};e.exports={classes:t,100:"Continue","100_NAME":"CONTINUE","100_MESSAGE":"The server has received the request headers and the client should proceed to send the request body.","100_CLASS":t.INFORMATIONAL,CONTINUE:100,101:"Switching Protocols","101_NAME":"SWITCHING_PROTOCOLS","101_MESSAGE":"The requester has asked the server to switch protocols and the server has agreed to do so.","101_CLASS":t.INFORMATIONAL,SWITCHING_PROTOCOLS:101,102:"Processing","102_NAME":"PROCESSING","102_MESSAGE":"A WebDAV request may contain many sub-requests involving file operations, requiring a long time to complete the request. This code indicates that the server has received and is processing the request, but no response is available yet.[7] This prevents the client from timing out and assuming the request was lost.","102_CLASS":t.INFORMATIONAL,PROCESSING:102,103:"Early Hints","103_NAME":"EARLY_HINTS","103_MESSAGE":"Used to return some response headers before final HTTP message.","103_CLASS":t.INFORMATIONAL,EARLY_HINTS:103,200:"OK","200_NAME":"OK","200_MESSAGE":"Standard response for successful HTTP requests.","200_CLASS":t.SUCCESSFUL,OK:200,201:"Created","201_NAME":"CREATED","201_MESSAGE":"The request has been fulfilled, resulting in the creation of a new resource.","201_CLASS":t.SUCCESSFUL,CREATED:201,202:"Accepted","202_NAME":"ACCEPTED","202_MESSAGE":"The request has been accepted for processing, but the processing has not been completed.","202_CLASS":t.SUCCESSFUL,ACCEPTED:202,203:"Non-Authoritative Information","203_NAME":"NON_AUTHORITATIVE_INFORMATION","203_MESSAGE":"The server is a transforming proxy (e.g. a Web accelerator) that received a 200 OK from its origin, but is returning a modified version of the origin's response.","203_CLASS":t.SUCCESSFUL,NON_AUTHORITATIVE_INFORMATION:203,204:"No Content","204_NAME":"NO_CONTENT","204_MESSAGE":"The server successfully processed the request and is not returning any content.","204_CLASS":t.SUCCESSFUL,NO_CONTENT:204,205:"Reset Content","205_NAME":"RESET_CONTENT","205_MESSAGE":"The server successfully processed the request, but is not returning any content. Unlike a 204 response, this response requires that the requester reset the document view.","205_CLASS":t.SUCCESSFUL,RESET_CONTENT:205,206:"Partial Content","206_NAME":"PARTIAL_CONTENT","206_MESSAGE":"The server is delivering only part of the resource (byte serving) due to a range header sent by the client.","206_CLASS":t.SUCCESSFUL,PARTIAL_CONTENT:206,207:"Multi Status","207_NAME":"MULTI_STATUS","207_MESSAGE":"The message body that follows is by default an XML message and can contain a number of separate response codes, depending on how many sub-requests were made.","207_CLASS":t.SUCCESSFUL,MULTI_STATUS:207,208:"Already Reported","208_NAME":"ALREADY_REPORTED","208_MESSAGE":"The members of a DAV binding have already been enumerated in a preceding part of the (multistatus) response, and are not being included again.","208_CLASS":t.SUCCESSFUL,ALREADY_REPORTED:208,226:"IM Used","226_NAME":"IM_USED","226_MESSAGE":"The server has fulfilled a request for the resource, and the response is a representation of the result of one or more instance-manipulations applied to the current instance.","226_CLASS":t.SUCCESSFUL,IM_USED:226,300:"Multiple Choices","300_NAME":"MULTIPLE_CHOICES","300_MESSAGE":"Indicates multiple options for the resource from which the client may choose.","300_CLASS":t.REDIRECTION,MULTIPLE_CHOICES:300,301:"Moved Permanently","301_NAME":"MOVED_PERMANENTLY","301_MESSAGE":"This and all future requests should be directed to the given URI.","301_CLASS":t.REDIRECTION,MOVED_PERMANENTLY:301,302:"Found","302_NAME":"FOUND","302_MESSAGE":'This is an example of industry practice contradicting the standard. The HTTP/1.0 specification (RFC 1945) required the client to perform a temporary redirect (the original describing phrase was "Moved Temporarily"), but popular browsers implemented 302 with the functionality of a 303 See Other. Therefore, HTTP/1.1 added status codes 303 and 307 to distinguish between the two behaviours.',"302_CLASS":t.REDIRECTION,FOUND:302,303:"See Other","303_NAME":"SEE_OTHER","303_MESSAGE":"The response to the request can be found under another URI using the GET method.","303_CLASS":t.REDIRECTION,SEE_OTHER:303,304:"Not Modified","304_NAME":"NOT_MODIFIED","304_MESSAGE":"Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-None-Match.","304_CLASS":t.REDIRECTION,NOT_MODIFIED:304,305:"Use Proxy","305_NAME":"USE_PROXY","305_MESSAGE":"The requested resource is available only through a proxy, the address for which is provided in the response.","305_CLASS":t.REDIRECTION,USE_PROXY:305,306:"Switch Proxy","306_NAME":"SWITCH_PROXY","306_MESSAGE":'No longer used. Originally meant "Subsequent requests should use the specified proxy.',"306_CLASS":t.REDIRECTION,SWITCH_PROXY:306,307:"Temporary Redirect","307_NAME":"TEMPORARY_REDIRECT","307_MESSAGE":"In this case, the request should be repeated with another URI; however, future requests should still use the original URI.","307_CLASS":t.REDIRECTION,TEMPORARY_REDIRECT:307,308:"Permanent Redirect","308_NAME":"PERMANENT_REDIRECT","308_MESSAGE":"The request and all future requests should be repeated using another URI.","308_CLASS":t.REDIRECTION,PERMANENT_REDIRECT:308,400:"Bad Request","400_NAME":"BAD_REQUEST","400_MESSAGE":"The server cannot or will not process the request due to an apparent client error.","400_CLASS":t.CLIENT_ERROR,BAD_REQUEST:400,401:"Unauthorized","401_NAME":"UNAUTHORIZED","401_MESSAGE":"Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided.","401_CLASS":t.CLIENT_ERROR,UNAUTHORIZED:401,402:"Payment Required","402_NAME":"PAYMENT_REQUIRED","402_MESSAGE":"Reserved for future use. The original intention was that this code might be used as part of some form of digital cash or micropayment scheme, as proposed for example by GNU Taler, but that has not yet happened, and this code is not usually used.","402_CLASS":t.CLIENT_ERROR,PAYMENT_REQUIRED:402,403:"Forbidden","403_NAME":"FORBIDDEN","403_MESSAGE":"The request was valid, but the server is refusing action.","403_CLASS":t.CLIENT_ERROR,FORBIDDEN:403,404:"Not Found","404_NAME":"NOT_FOUND","404_MESSAGE":"The requested resource could not be found but may be available in the future. Subsequent requests by the client are permissible.","404_CLASS":t.CLIENT_ERROR,NOT_FOUND:404,405:"Method Not Allowed","405_NAME":"METHOD_NOT_ALLOWED","405_MESSAGE":"A request method is not supported for the requested resource.","405_CLASS":t.CLIENT_ERROR,METHOD_NOT_ALLOWED:405,406:"Not Acceptable","406_NAME":"NOT_ACCEPTABLE","406_MESSAGE":"The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.","406_CLASS":t.CLIENT_ERROR,NOT_ACCEPTABLE:406,407:"Proxy Authentication Required","407_NAME":"PROXY_AUTHENTICATION_REQUIRED","407_MESSAGE":"The client must first authenticate itself with the proxy.","407_CLASS":t.CLIENT_ERROR,PROXY_AUTHENTICATION_REQUIRED:407,408:"Request Time-out","408_NAME":"REQUEST_TIMEOUT","408_MESSAGE":"The server timed out waiting for the request.","408_CLASS":t.CLIENT_ERROR,REQUEST_TIMEOUT:408,409:"Conflict","409_NAME":"CONFLICT","409_MESSAGE":"Indicates that the request could not be processed because of conflict in the request, such as an edit conflict between multiple simultaneous updates.","409_CLASS":t.CLIENT_ERROR,CONFLICT:409,410:"Gone","410_NAME":"GONE","410_MESSAGE":"Indicates that the resource requested is no longer available and will not be available again.","410_CLASS":t.CLIENT_ERROR,GONE:410,411:"Length Required","411_NAME":"LENGTH_REQUIRED","411_MESSAGE":"The request did not specify the length of its content, which is required by the requested resource.","411_CLASS":t.CLIENT_ERROR,LENGTH_REQUIRED:411,412:"Precondition Failed","412_NAME":"PRECONDITION_FAILED","412_MESSAGE":"The server does not meet one of the preconditions that the requester put on the request.","412_CLASS":t.CLIENT_ERROR,PRECONDITION_FAILED:412,413:"Request Entity Too Large","413_NAME":"REQUEST_ENTITY_TOO_LARGE","413_MESSAGE":'The request is larger than the server is willing or able to process. Previously called "Request Entity Too Large".',"413_CLASS":t.CLIENT_ERROR,REQUEST_ENTITY_TOO_LARGE:413,414:"Request-URI Too Large","414_NAME":"REQUEST_URI_TOO_LONG","414_MESSAGE":"The URI provided was too long for the server to process.","414_CLASS":t.CLIENT_ERROR,REQUEST_URI_TOO_LONG:414,415:"Unsupported Media Type","415_NAME":"UNSUPPORTED_MEDIA_TYPE","415_MESSAGE":"The request entity has a media type which the server or resource does not support.","415_CLASS":t.CLIENT_ERROR,UNSUPPORTED_MEDIA_TYPE:415,416:"Requested Range not Satisfiable","416_NAME":"REQUESTED_RANGE_NOT_SATISFIABLE","416_MESSAGE":"The client has asked for a portion of the file (byte serving), but the server cannot supply that portion.","416_CLASS":t.CLIENT_ERROR,REQUESTED_RANGE_NOT_SATISFIABLE:416,417:"Expectation Failed","417_NAME":"EXPECTATION_FAILED","417_MESSAGE":"The server cannot meet the requirements of the Expect request-header field.","417_CLASS":t.CLIENT_ERROR,EXPECTATION_FAILED:417,418:"I'm a teapot","418_NAME":"IM_A_TEAPOT","418_MESSAGE":'Any attempt to brew coffee with a teapot should result in the error code "418 I\'m a teapot". The resulting entity body MAY be short and stout.',"418_CLASS":t.CLIENT_ERROR,IM_A_TEAPOT:418,421:"Misdirected Request","421_NAME":"MISDIRECTED_REQUEST","421_MESSAGE":"The request was directed at a server that is not able to produce a response.","421_CLASS":t.CLIENT_ERROR,MISDIRECTED_REQUEST:421,422:"Unprocessable Entity","422_NAME":"UNPROCESSABLE_ENTITY","422_MESSAGE":"The request was well-formed but was unable to be followed due to semantic errors.","422_CLASS":t.CLIENT_ERROR,UNPROCESSABLE_ENTITY:422,423:"Locked","423_NAME":"LOCKED","423_MESSAGE":"The resource that is being accessed is locked.","423_CLASS":t.CLIENT_ERROR,LOCKED:423,424:"Failed Dependency","424_NAME":"FAILED_DEPENDENCY","424_MESSAGE":"The request failed because it depended on another request and that request failed.","424_CLASS":t.CLIENT_ERROR,FAILED_DEPENDENCY:424,426:"Upgrade Required","426_NAME":"UPGRADE_REQUIRED","426_MESSAGE":"The client should switch to a different protocol such as TLS/1.0, given in the Upgrade header field.","426_CLASS":t.CLIENT_ERROR,UPGRADE_REQUIRED:426,428:"Precondition Required","428_NAME":"PRECONDITION_REQUIRED","428_MESSAGE":"The origin server requires the request to be conditional.","428_CLASS":t.CLIENT_ERROR,PRECONDITION_REQUIRED:428,429:"Too Many Requests","429_NAME":"TOO_MANY_REQUESTS","429_MESSAGE":"The user has sent too many requests in a given amount of time.","429_CLASS":t.CLIENT_ERROR,TOO_MANY_REQUESTS:429,431:"Request Header Fields Too Large","431_NAME":"REQUEST_HEADER_FIELDS_TOO_LARGE","431_MESSAGE":"The server is unwilling to process the request because either an individual header field, or all the header fields collectively, are too large.","431_CLASS":t.CLIENT_ERROR,REQUEST_HEADER_FIELDS_TOO_LARGE:431,451:"Unavailable For Legal Reasons","451_NAME":"UNAVAILABLE_FOR_LEGAL_REASONS","451_MESSAGE":"A server operator has received a legal demand to deny access to a resource or to a set of resources that includes the requested resource.","451_CLASS":t.CLIENT_ERROR,UNAVAILABLE_FOR_LEGAL_REASONS:451,500:"Internal Server Error","500_NAME":"INTERNAL_SERVER_ERROR","500_MESSAGE":"A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.","500_CLASS":t.SERVER_ERROR,INTERNAL_SERVER_ERROR:500,501:"Not Implemented","501_NAME":"NOT_IMPLEMENTED","501_MESSAGE":"The server either does not recognize the request method, or it lacks the ability to fulfil the request. Usually this implies future availability.","501_CLASS":t.SERVER_ERROR,NOT_IMPLEMENTED:501,502:"Bad Gateway","502_NAME":"BAD_GATEWAY","502_MESSAGE":"The server was acting as a gateway or proxy and received an invalid response from the upstream server.","502_CLASS":t.SERVER_ERROR,BAD_GATEWAY:502,503:"Service Unavailable","503_NAME":"SERVICE_UNAVAILABLE","503_MESSAGE":"The server is currently unavailable (because it is overloaded or down for maintenance). Generally, this is a temporary state.","503_CLASS":t.SERVER_ERROR,SERVICE_UNAVAILABLE:503,504:"Gateway Time-out","504_NAME":"GATEWAY_TIMEOUT","504_MESSAGE":"The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.","504_CLASS":t.SERVER_ERROR,GATEWAY_TIMEOUT:504,505:"HTTP Version not Supported","505_NAME":"HTTP_VERSION_NOT_SUPPORTED","505_MESSAGE":"The server does not support the HTTP protocol version used in the request.","505_CLASS":t.SERVER_ERROR,HTTP_VERSION_NOT_SUPPORTED:505,506:"Variant Also Negotiates","506_NAME":"VARIANT_ALSO_NEGOTIATES","506_MESSAGE":"Transparent content negotiation for the request results in a circular reference.","506_CLASS":t.SERVER_ERROR,VARIANT_ALSO_NEGOTIATES:506,507:"Insufficient Storage","507_NAME":"INSUFFICIENT_STORAGE","507_MESSAGE":"The server is unable to store the representation needed to complete the request.","507_CLASS":t.SERVER_ERROR,INSUFFICIENT_STORAGE:507,508:"Loop Detected","508_NAME":"LOOP_DETECTED","508_MESSAGE":"The server detected an infinite loop while processing the request.","508_CLASS":t.SERVER_ERROR,LOOP_DETECTED:508,510:"Not Extended","510_NAME":"NOT_EXTENDED","510_MESSAGE":"Further extensions to the request are required for the server to fulfil it.","510_CLASS":t.SERVER_ERROR,NOT_EXTENDED:510,511:"Network Authentication Required","511_NAME":"NETWORK_AUTHENTICATION_REQUIRED","511_MESSAGE":"The client needs to authenticate to gain network access. Intended for use by intercepting proxies used to control access to the network.","511_CLASS":t.SERVER_ERROR,NETWORK_AUTHENTICATION_REQUIRED:511,extra:{unofficial:{103:"Checkpoint","103_NAME":"CHECKPOINT","103_MESSAGE":"Used in the resumable requests proposal to resume aborted PUT or POST requests.","103_CLASS":t.INFORMATIONAL,CHECKPOINT:103,419:"Page Expired","419_NAME":"PAGE_EXPIRED","419_MESSAGE":"Used by the Laravel Framework when a CSRF Token is missing or expired.","419_CLASS":t.CLIENT_ERROR,PAGE_EXPIRED:419,218:"This is fine","218_NAME":"THIS_IS_FINE","218_MESSAGE":"Used as a catch-all error condition for allowing response bodies to flow through Apache when ProxyErrorOverride is enabled. When ProxyErrorOverride is enabled in Apache, response bodies that contain a status code of 4xx or 5xx are automatically discarded by Apache in favor of a generic response or a custom response specified by the ErrorDocument directive.","218_CLASS":t.SUCCESSFUL,THIS_IS_FINE:218,420:"Enhance Your Calm","420_NAME":"ENHANCE_YOUR_CALM","420_MESSAGE":"Returned by version 1 of the Twitter Search and Trends API when the client is being rate limited; versions 1.1 and later use the 429 Too Many Requests response code instead.","420_CLASS":t.CLIENT_ERROR,ENHANCE_YOUR_CALM:420,450:"Blocked by Windows Parental Controls","450_NAME":"BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS","450_MESSAGE":"The Microsoft extension code indicated when Windows Parental Controls are turned on and are blocking access to the requested webpage.","450_CLASS":t.CLIENT_ERROR,BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS:450,498:"Invalid Token","498_NAME":"INVALID_TOKEN","498_MESSAGE":"Returned by ArcGIS for Server. Code 498 indicates an expired or otherwise invalid token.","498_CLASS":t.CLIENT_ERROR,INVALID_TOKEN:498,499:"Token Required","499_NAME":"TOKEN_REQUIRED","499_MESSAGE":"Returned by ArcGIS for Server. Code 499 indicates that a token is required but was not submitted.","499_CLASS":t.CLIENT_ERROR,TOKEN_REQUIRED:499,509:"Bandwidth Limit Exceeded","509_NAME":"BANDWIDTH_LIMIT_EXCEEDED","509_MESSAGE":"The server has exceeded the bandwidth specified by the server administrator.","509_CLASS":t.SERVER_ERROR,BANDWIDTH_LIMIT_EXCEEDED:509,530:"Site is frozen","530_NAME":"SITE_IS_FROZEN","530_MESSAGE":"Used by the Pantheon web platform to indicate a site that has been frozen due to inactivity.","530_CLASS":t.SERVER_ERROR,SITE_IS_FROZEN:530,598:"Network read timeout error","598_NAME":"NETWORK_READ_TIMEOUT_ERROR","598_MESSAGE":"Used by some HTTP proxies to signal a network read timeout behind the proxy to a client in front of the proxy.","598_CLASS":t.SERVER_ERROR,NETWORK_READ_TIMEOUT_ERROR:598},iis:{440:"Login Time-out","440_NAME":"LOGIN_TIME_OUT","440_MESSAGE":"The client's session has expired and must log in again.","440_CLASS":t.CLIENT_ERROR,LOGIN_TIME_OUT:440,449:"Retry With","449_NAME":"RETRY_WITH","449_MESSAGE":"The server cannot honour the request because the user has not provided the required information.","449_CLASS":t.CLIENT_ERROR,RETRY_WITH:449,451:"Redirect","451_NAME":"REDIRECT","451_MESSAGE":"Used in Exchange ActiveSync when either a more efficient server is available or the server cannot access the users' mailbox.","451_CLASS":t.CLIENT_ERROR,REDIRECT:451},nginx:{444:"No Response","444_NAME":"NO_RESPONSE","444_MESSAGE":"Used internally to instruct the server to return no information to the client and close the connection immediately.","444_CLASS":t.CLIENT_ERROR,NO_RESPONSE:444,494:"Request header too large","494_NAME":"REQUEST_HEADER_TOO_LARGE","494_MESSAGE":"Client sent too large request or too long header line.","494_CLASS":t.CLIENT_ERROR,REQUEST_HEADER_TOO_LARGE:494,495:"SSL Certificate Error","495_NAME":"SSL_CERTIFICATE_ERROR","495_MESSAGE":"An expansion of the 400 Bad Request response code, used when the client has provided an invalid client certificate.","495_CLASS":t.CLIENT_ERROR,SSL_CERTIFICATE_ERROR:495,496:"SSL Certificate Required","496_NAME":"SSL_CERTIFICATE_REQUIRED","496_MESSAGE":"An expansion of the 400 Bad Request response code, used when a client certificate is required but not provided.","496_CLASS":t.CLIENT_ERROR,SSL_CERTIFICATE_REQUIRED:496,497:"HTTP Request Sent to HTTPS Port","497_NAME":"HTTP_REQUEST_SENT_TO_HTTPS_PORT","497_MESSAGE":"An expansion of the 400 Bad Request response code, used when the client has made a HTTP request to a port listening for HTTPS requests.","497_CLASS":t.CLIENT_ERROR,HTTP_REQUEST_SENT_TO_HTTPS_PORT:497,499:"Client Closed Request","499_NAME":"CLIENT_CLOSED_REQUEST","499_MESSAGE":"Used when the client has closed the request before the server could send a response.","499_CLASS":t.CLIENT_ERROR,CLIENT_CLOSED_REQUEST:499},cloudflare:{520:"Unknown Error","520_NAME":"UNKNOWN_ERROR","520_MESSAGE":'The 520 error is used as a "catch-all response for when the origin server returns something unexpected", listing connection resets, large headers, and empty or invalid responses as common triggers.',"520_CLASS":t.SERVER_ERROR,UNKNOWN_ERROR:520,521:"Web Server Is Down","521_NAME":"WEB_SERVER_IS_DOWN","521_MESSAGE":"The origin server has refused the connection from Cloudflare.","521_CLASS":t.SERVER_ERROR,WEB_SERVER_IS_DOWN:521,522:"Connection Timed Out","522_NAME":"CONNECTION_TIMED_OUT","522_MESSAGE":"Cloudflare could not negotiate a TCP handshake with the origin server.","522_CLASS":t.SERVER_ERROR,CONNECTION_TIMED_OUT:522,523:"Origin Is Unreachable","523_NAME":"ORIGIN_IS_UNREACHABLE","523_MESSAGE":"Cloudflare could not reach the origin server.","523_CLASS":t.SERVER_ERROR,ORIGIN_IS_UNREACHABLE:523,524:"A Timeout Occurred","524_NAME":"A_TIMEOUT_OCCURRED","524_MESSAGE":"Cloudflare was able to complete a TCP connection to the origin server, but did not receive a timely HTTP response.","524_CLASS":t.SERVER_ERROR,A_TIMEOUT_OCCURRED:524,525:"SSL Handshake Failed","525_NAME":"SSL_HANDSHAKE_FAILED","525_MESSAGE":"Cloudflare could not negotiate a SSL/TLS handshake with the origin server.","525_CLASS":t.SERVER_ERROR,SSL_HANDSHAKE_FAILED:525,526:"Invalid SSL Certificate","526_NAME":"INVALID_SSL_CERTIFICATE","526_MESSAGE":"Cloudflare could not validate the SSL/TLS certificate that the origin server presented.","526_CLASS":t.SERVER_ERROR,INVALID_SSL_CERTIFICATE:526,527:"Railgun Error","527_NAME":"RAILGUN_ERROR","527_MESSAGE":"Error 527 indicates that the request timed out or failed after the WAN connection had been established.","527_CLASS":t.SERVER_ERROR,RAILGUN_ERROR:527}}}},672:e=>{"use strict";e.exports=e=>{if(typeof e!=="number"){throw new TypeError("Expected a number")}const t=e>0?Math.floor:Math.ceil;return{days:t(e/864e5),hours:t(e/36e5)%24,minutes:t(e/6e4)%60,seconds:t(e/1e3)%60,milliseconds:t(e)%1e3,microseconds:t(e*1e3)%1e3,nanoseconds:t(e*1e6)%1e3}}},720:(e,t,r)=>{"use strict";const n=r(672);const pluralize=(e,t)=>t===1?e:`${e}s`;const o=1e-7;e.exports=(e,t={})=>{if(!Number.isFinite(e)){throw new TypeError("Expected a finite number")}if(t.colonNotation){t.compact=false;t.formatSubMilliseconds=false;t.separateMilliseconds=false;t.verbose=false}if(t.compact){t.secondsDecimalDigits=0;t.millisecondsDecimalDigits=0}const r=[];const floorDecimals=(e,t)=>{const r=Math.floor(e*10**t+o);const n=Math.round(r)/10**t;return n.toFixed(t)};const add=(e,n,o,s)=>{if((r.length===0||!t.colonNotation)&&e===0&&!(t.colonNotation&&o==="m")){return}s=(s||e||"0").toString();let i;let a;if(t.colonNotation){i=r.length>0?":":"";a="";const e=s.includes(".")?s.split(".")[0].length:s.length;const t=r.length>0?2:1;s="0".repeat(Math.max(0,t-e))+s}else{i="";a=t.verbose?" "+pluralize(n,e):o}r.push(i+s+a)};const s=n(e);add(Math.trunc(s.days/365),"year","y");add(s.days%365,"day","d");add(s.hours,"hour","h");add(s.minutes,"minute","m");if(t.separateMilliseconds||t.formatSubMilliseconds||!t.colonNotation&&e<1e3){add(s.seconds,"second","s");if(t.formatSubMilliseconds){add(s.milliseconds,"millisecond","ms");add(s.microseconds,"microsecond","µs");add(s.nanoseconds,"nanosecond","ns")}else{const e=s.milliseconds+s.microseconds/1e3+s.nanoseconds/1e6;const r=typeof t.millisecondsDecimalDigits==="number"?t.millisecondsDecimalDigits:0;const n=e>=1?Math.round(e):Math.ceil(e);const o=r?e.toFixed(r):n;add(Number.parseFloat(o,10),"millisecond","ms",o)}}else{const r=e/1e3%60;const n=typeof t.secondsDecimalDigits==="number"?t.secondsDecimalDigits:1;const o=floorDecimals(r,n);const s=t.keepDecimalsOnWholeSeconds?o:o.replace(/\.0+$/,"");add(Number.parseFloat(s,10),"second","s",s)}if(r.length===0){return"0"+(t.verbose?" milliseconds":"ms")}if(t.compact){return r[0]}if(typeof t.unitCount==="number"){const e=t.colonNotation?"":" ";return r.slice(0,Math.max(t.unitCount,1)).join(e)}return t.colonNotation?r.join(""):r.join(" ")}},504:(e,t,r)=>{"use strict";const n=r(734);e.exports=()=>{const e=process.hrtime();const end=t=>n(process.hrtime(e))[t];const returnValue=()=>end("milliseconds");returnValue.rounded=()=>Math.round(end("milliseconds"));returnValue.seconds=()=>end("seconds");returnValue.nanoseconds=()=>end("nanoseconds");return returnValue}},491:e=>{"use strict";e.exports=require("assert")},300:e=>{"use strict";e.exports=require("buffer")},113:e=>{"use strict";e.exports=require("crypto")},361:e=>{"use strict";e.exports=require("events")},147:e=>{"use strict";e.exports=require("fs")},685:e=>{"use strict";e.exports=require("http")},808:e=>{"use strict";e.exports=require("net")},277:e=>{"use strict";e.exports=require("next/dist/compiled/@edge-runtime/primitives/crypto")},37:e=>{"use strict";e.exports=require("os")},17:e=>{"use strict";e.exports=require("path")},74:e=>{"use strict";e.exports=require("perf_hooks")},282:e=>{"use strict";e.exports=require("process")},477:e=>{"use strict";e.exports=require("punycode")},781:e=>{"use strict";e.exports=require("stream")},404:e=>{"use strict";e.exports=require("tls")},837:e=>{"use strict";e.exports=require("util")},144:e=>{"use strict";e.exports=require("vm")},796:e=>{"use strict";e.exports=require("zlib")}};var __webpack_module_cache__={};function __nccwpck_require__(e){var t=__webpack_module_cache__[e];if(t!==undefined){return t.exports}var r=__webpack_module_cache__[e]={exports:{}};var n=true;try{__webpack_modules__[e].call(r.exports,r,r.exports,__nccwpck_require__);n=false}finally{if(n)delete __webpack_module_cache__[e]}return r.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var __webpack_exports__={};(()=>{"use strict";var e=__webpack_exports__;Object.defineProperty(e,"__esModule",{value:true});e.EdgeRuntime=e.runServer=e.createHandler=void 0;var t=__nccwpck_require__(707);Object.defineProperty(e,"createHandler",{enumerable:true,get:function(){return t.createHandler}});Object.defineProperty(e,"runServer",{enumerable:true,get:function(){return t.runServer}});var r=__nccwpck_require__(14);Object.defineProperty(e,"EdgeRuntime",{enumerable:true,get:function(){return r.EdgeRuntime}})})();module.exports=__webpack_exports__})(); \ No newline at end of file diff --git a/packages/next/package.json b/packages/next/package.json index 18dd23e393f2..91f730ba99b7 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -117,7 +117,7 @@ "@babel/runtime": "7.15.4", "@babel/traverse": "7.18.0", "@babel/types": "7.18.0", - "@edge-runtime/primitives": "1.1.0-beta.26", + "@edge-runtime/primitives": "1.1.0-beta.27", "@hapi/accept": "5.0.2", "@napi-rs/cli": "2.7.0", "@napi-rs/triples": "1.1.0", @@ -195,7 +195,7 @@ "debug": "4.1.1", "devalue": "2.0.1", "domain-browser": "4.19.0", - "edge-runtime": "1.1.0-beta.26", + "edge-runtime": "1.1.0-beta.27", "events": "3.3.0", "find-cache-dir": "3.3.1", "find-up": "4.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 986ce59f29e4..9485aee0ec1e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,7 +19,7 @@ importers: '@babel/plugin-proposal-object-rest-spread': 7.14.7 '@babel/preset-flow': 7.14.5 '@babel/preset-react': 7.14.5 - '@edge-runtime/jest-environment': 1.1.0-beta.26 + '@edge-runtime/jest-environment': 1.1.0-beta.27 '@fullhuman/postcss-purgecss': 1.3.0 '@mdx-js/loader': 0.18.0 '@next/bundle-analyzer': workspace:* @@ -173,7 +173,7 @@ importers: '@babel/plugin-proposal-object-rest-spread': 7.14.7_@babel+core@7.18.0 '@babel/preset-flow': 7.14.5_@babel+core@7.18.0 '@babel/preset-react': 7.14.5_@babel+core@7.18.0 - '@edge-runtime/jest-environment': 1.1.0-beta.26 + '@edge-runtime/jest-environment': 1.1.0-beta.27 '@fullhuman/postcss-purgecss': 1.3.0 '@mdx-js/loader': 0.18.0_uuaxwgga6hqycsez5ok7v2wg4i '@next/bundle-analyzer': link:packages/next-bundle-analyzer @@ -416,7 +416,7 @@ importers: '@babel/runtime': 7.15.4 '@babel/traverse': 7.18.0 '@babel/types': 7.18.0 - '@edge-runtime/primitives': 1.1.0-beta.26 + '@edge-runtime/primitives': 1.1.0-beta.27 '@hapi/accept': 5.0.2 '@napi-rs/cli': 2.7.0 '@napi-rs/triples': 1.1.0 @@ -497,7 +497,7 @@ importers: debug: 4.1.1 devalue: 2.0.1 domain-browser: 4.19.0 - edge-runtime: 1.1.0-beta.26 + edge-runtime: 1.1.0-beta.27 events: 3.3.0 find-cache-dir: 3.3.1 find-up: 4.1.0 @@ -609,7 +609,7 @@ importers: '@babel/runtime': 7.15.4 '@babel/traverse': 7.18.0 '@babel/types': 7.18.0 - '@edge-runtime/primitives': 1.1.0-beta.26 + '@edge-runtime/primitives': 1.1.0-beta.27 '@hapi/accept': 5.0.2 '@napi-rs/cli': 2.7.0 '@napi-rs/triples': 1.1.0 @@ -687,7 +687,7 @@ importers: debug: 4.1.1 devalue: 2.0.1 domain-browser: 4.19.0 - edge-runtime: 1.1.0-beta.26 + edge-runtime: 1.1.0-beta.27 events: 3.3.0 find-cache-dir: 3.3.1 find-up: 4.1.0 @@ -1886,7 +1886,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.18.0 - '@babel/helper-plugin-utils': 7.16.7 + '@babel/helper-plugin-utils': 7.17.12 /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.18.0: resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} @@ -3216,14 +3216,14 @@ packages: protobufjs: 6.11.2 dev: true - /@edge-runtime/format/1.1.0-beta.26: - resolution: {integrity: sha512-05wywSsBZVE1iMezvYXW1ZMak6y2riJPVmEDK9RW9BECazykJtYOOQ+GG+oVaicNfxh2YtQTQD/WaI/4K3yKWA==} + /@edge-runtime/format/1.1.0-beta.27: + resolution: {integrity: sha512-67ig1yISH1M7OHxS/PxgXbrQ99X8c47GFqP6qrDx+uWw1gBnknNHIykL3OgeIt4yk1OPKKHtrLe/Gnrw9Lc9tQ==} dev: true - /@edge-runtime/jest-environment/1.1.0-beta.26: - resolution: {integrity: sha512-NnnYjF3Kaw83Vrkoy0lpuZCk49VjR5Ruo5XDjZ9dKqslA6lNVBkirTDvQrQBYSTaZM8lu3Ed39o50zH2Ua4lTw==} + /@edge-runtime/jest-environment/1.1.0-beta.27: + resolution: {integrity: sha512-zCKFLqhvQ3OWV2H1cvl6CD7pnRKR+hUtGaJU4fYVjHAOoIpv5R9W+qw+9rXu5CpZJ7F4k/+1vLicAxaXKVKJOg==} dependencies: - '@edge-runtime/vm': 1.1.0-beta.26 + '@edge-runtime/vm': 1.1.0-beta.27 '@jest/environment': 28.1.3 '@jest/fake-timers': 28.1.3 '@jest/types': 28.1.3 @@ -3231,14 +3231,14 @@ packages: jest-util: 28.1.3 dev: true - /@edge-runtime/primitives/1.1.0-beta.26: - resolution: {integrity: sha512-SsbXbw2+bAHbcjAmT+e5WoADmU/yDO5glNFkYd/971Zo26cJoW/1W3n4IMm5gOtyvLHbezSRKt8t5GteX0wYdA==} + /@edge-runtime/primitives/1.1.0-beta.27: + resolution: {integrity: sha512-9RLySRgIfNhPXzqprwk5jojUec4WmVRphXIGgXmqZs/22UPF50mKcmrstPVVutGiX0mt4YkHuUarLj0VtLjX1Q==} dev: true - /@edge-runtime/vm/1.1.0-beta.26: - resolution: {integrity: sha512-hxWtmuO13zgNkM3zHvRENfMeavM+PAKSoHhvzt+sHjSothxGlA06XXN38t/NT6LD4ND8p8FmPJ70+fTptL4a/A==} + /@edge-runtime/vm/1.1.0-beta.27: + resolution: {integrity: sha512-1ua5EI3GXKDDdjF6+1CUi37rmpxXMSWItCCl5sIMLBaIaf2klgnVYzIFVXORvXp0fKh1N3jEcS+Ykkutg/uzaw==} dependencies: - '@edge-runtime/primitives': 1.1.0-beta.26 + '@edge-runtime/primitives': 1.1.0-beta.27 dev: true /@emotion/is-prop-valid/0.8.8: @@ -4618,7 +4618,7 @@ packages: /@mdx-js/mdx/0.18.2_@babel+core@7.18.0: resolution: {integrity: sha512-7DqNBOGPV+36qpH8YZmKI5uvuXhrGZFhJ4C9+9uaQSpH2hQg9xAfdzjSSEO8FQhAlu6wJtUgb72J5/eWdc1HFw==} dependencies: - '@babel/plugin-proposal-object-rest-spread': 7.14.7_@babel+core@7.18.0 + '@babel/plugin-proposal-object-rest-spread': 7.18.0_@babel+core@7.18.0 '@babel/plugin-syntax-jsx': 7.14.5_@babel+core@7.18.0 change-case: 3.1.0 detab: 2.0.4 @@ -9741,12 +9741,12 @@ packages: safe-buffer: 5.2.0 dev: true - /edge-runtime/1.1.0-beta.26: - resolution: {integrity: sha512-2JZlxpISnRv3p0yh6Oo9QZF06lWcgJH0RMxVbJ5Az0Grde7B1PLw34oCIcOu23Zu7Icn4Lh2wojA6riq3jyDqg==} + /edge-runtime/1.1.0-beta.27: + resolution: {integrity: sha512-6Epw2VvkgQKNCZf1LpFdzrEpsSgnVAkLI3zGW5V7VduB8eNz5We/bpcNnFJTjGPUshhW+C5WxY7QNyioucMpDQ==} hasBin: true dependencies: - '@edge-runtime/format': 1.1.0-beta.26 - '@edge-runtime/vm': 1.1.0-beta.26 + '@edge-runtime/format': 1.1.0-beta.27 + '@edge-runtime/vm': 1.1.0-beta.27 exit-hook: 2.2.1 http-status: 1.5.2 mri: 1.2.0 @@ -11301,7 +11301,7 @@ packages: dev: true /get-stdin/4.0.1: - resolution: {integrity: sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=} + resolution: {integrity: sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==} engines: {node: '>=0.10.0'} dev: true @@ -11977,7 +11977,7 @@ packages: dev: true /header-case/1.0.1: - resolution: {integrity: sha1-lTWXMZfBRLCWE81l0xfvGZY70C0=} + resolution: {integrity: sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==} dependencies: no-case: 2.3.2 upper-case: 1.1.3 @@ -12219,7 +12219,7 @@ packages: dev: true /humanize-ms/1.2.1: - resolution: {integrity: sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=} + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} dependencies: ms: 2.1.2 dev: true @@ -12815,11 +12815,11 @@ packages: dev: true /is-lambda/1.0.1: - resolution: {integrity: sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=} + resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} dev: true /is-lower-case/1.1.3: - resolution: {integrity: sha1-fhR75HaNxGbbO/shzGCzHmrWk5M=} + resolution: {integrity: sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==} dependencies: lower-case: 1.1.4 dev: true @@ -13050,7 +13050,7 @@ packages: dev: true /is-upper-case/1.1.2: - resolution: {integrity: sha1-jQsfp+eTOh5YSDYA7H2WYcuvdW8=} + resolution: {integrity: sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==} dependencies: upper-case: 1.1.3 dev: true @@ -14670,13 +14670,13 @@ packages: dev: true /lower-case-first/1.0.2: - resolution: {integrity: sha1-5dp8JvKacHO+AtUrrJmA5ZIq36E=} + resolution: {integrity: sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA==} dependencies: lower-case: 1.1.4 dev: true /lower-case/1.1.4: - resolution: {integrity: sha1-miyr0bno4K6ZOkv31YdcOcQujqw=} + resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==} dev: true /lower-case/2.0.2: @@ -14926,7 +14926,7 @@ packages: dev: true /mdurl/1.0.1: - resolution: {integrity: sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=} + resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} dev: true /media-typer/0.3.0: @@ -16419,7 +16419,7 @@ packages: dev: true /param-case/2.1.1: - resolution: {integrity: sha1-35T9jPZTHs915r75oIWPvHK+Ikc=} + resolution: {integrity: sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==} dependencies: no-case: 2.3.2 dev: true @@ -16590,7 +16590,7 @@ packages: dev: true /pascal-case/2.0.1: - resolution: {integrity: sha1-LVeNNFX2YNpl7KGO+VtODekSdh4=} + resolution: {integrity: sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==} dependencies: camel-case: 3.0.0 upper-case-first: 1.1.2 @@ -16613,7 +16613,7 @@ packages: dev: true /path-case/2.1.1: - resolution: {integrity: sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU=} + resolution: {integrity: sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==} dependencies: no-case: 2.3.2 dev: true @@ -18794,7 +18794,7 @@ packages: dev: true /replace-ext/1.0.0: - resolution: {integrity: sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=} + resolution: {integrity: sha512-vuNYXC7gG7IeVNBC1xUllqCcZKRbJoSPOBhnTEcAIiKCsbuef6zO3F0Rve3isPMMoNoQRWjQwbAgAjHUHniyEA==} engines: {node: '>= 0.10'} dev: true @@ -19352,7 +19352,7 @@ packages: dev: true /sentence-case/2.1.1: - resolution: {integrity: sha1-H24t2jnBaL+S0T+G1KkYkz9mftQ=} + resolution: {integrity: sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==} dependencies: no-case: 2.3.2 upper-case-first: 1.1.2 @@ -19543,7 +19543,7 @@ packages: dev: true /snake-case/2.1.0: - resolution: {integrity: sha1-Qb2xtz8w7GagTU4srRt2OH1NbZ8=} + resolution: {integrity: sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==} dependencies: no-case: 2.3.2 dev: true @@ -20222,7 +20222,7 @@ packages: dev: true /swap-case/1.1.2: - resolution: {integrity: sha1-w5IDpFhzhfrTyFCgvRvK+ggZdOM=} + resolution: {integrity: sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==} dependencies: lower-case: 1.1.4 upper-case: 1.1.3 @@ -20431,7 +20431,7 @@ packages: acorn: optional: true dependencies: - acorn: 8.6.0 + acorn: 8.8.0 commander: 2.20.3 source-map: 0.7.3 source-map-support: 0.5.20 @@ -20546,7 +20546,7 @@ packages: dev: true /title-case/2.1.1: - resolution: {integrity: sha1-PhJyFtpY0rxb7PE3q5Ha46fNj6o=} + resolution: {integrity: sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==} dependencies: no-case: 2.3.2 upper-case: 1.1.3 @@ -20620,7 +20620,7 @@ packages: safe-regex: 1.1.0 /to-style/1.3.3: - resolution: {integrity: sha1-Y6K3Cm9KfU/cLtV6C+TnI1y2aZw=} + resolution: {integrity: sha512-9K8KYegr9hrdm8yPpu5iZjJp5t6RPAp4gFDU5hD9zR8hwqgF4fsoSitMtkRKQG2qkP5j/uG3wajbgV09rjmIqg==} dev: true /to-vfile/6.1.0: @@ -20705,7 +20705,7 @@ packages: dev: true /trim/0.0.1: - resolution: {integrity: sha1-WFhUf2spB1fulczMZm+1AITEYN0=} + resolution: {integrity: sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==} dev: true /trough/1.0.4: @@ -21136,6 +21136,7 @@ packages: /unified/9.2.1: resolution: {integrity: sha512-juWjuI8Z4xFg8pJbnEZ41b5xjGUWGHqXALmBZ3FC3WX0PIx1CZBIIJ6mXbYMcf6Yw4Fi0rFUTA1cdz/BglbOhA==} dependencies: + '@types/unist': 2.0.3 bail: 1.0.4 extend: 3.0.2 is-buffer: 2.0.4 @@ -21380,7 +21381,7 @@ packages: dev: true /upper-case-first/1.1.2: - resolution: {integrity: sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=} + resolution: {integrity: sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==} dependencies: upper-case: 1.1.3 dev: true @@ -21392,7 +21393,7 @@ packages: dev: true /upper-case/1.1.3: - resolution: {integrity: sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=} + resolution: {integrity: sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==} dev: true /upper-case/2.0.2: @@ -21532,7 +21533,7 @@ packages: dev: true /verror/1.10.0: - resolution: {integrity: sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=} + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} engines: {'0': node >=0.6.0} dependencies: assert-plus: 1.0.0 @@ -22015,7 +22016,7 @@ packages: dev: true /x-is-string/0.1.0: - resolution: {integrity: sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=} + resolution: {integrity: sha512-GojqklwG8gpzOVEVki5KudKNoq7MbbjYZCbyWzEz7tyPA7eleiE0+ePwOWQQRb5fm86rD3S8Tc0tSFf3AOv50w==} dev: true /xdg-basedir/3.0.0: From 8bc93d02099dca1c09c584a6e5d412a9a491bc64 Mon Sep 17 00:00:00 2001 From: Dave Welsh <33357025+davewelsh@users.noreply.github.com> Date: Mon, 22 Aug 2022 05:42:24 -0400 Subject: [PATCH 24/64] Typescript Documentation Improvement for Persistent Layouts (#33659) By making `NextPageWithLayout` generic and passing the type parameters to `NextPage`, our pages can continue to specify the props explicitly. This gives us type safety in `getInitialProps`, for example. ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have helpful link attached, see `contributing.md` ## Documentation / Examples - [x] Make sure the linting passes by running `yarn lint` --- docs/basic-features/layouts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/basic-features/layouts.md b/docs/basic-features/layouts.md index 5afa956ec29e..394169e9f0a6 100644 --- a/docs/basic-features/layouts.md +++ b/docs/basic-features/layouts.md @@ -128,7 +128,7 @@ import type { ReactElement, ReactNode } from 'react' import type { NextPage } from 'next' import type { AppProps } from 'next/app' -export type NextPageWithLayout = NextPage & { +export type NextPageWithLayout

= NextPage & { getLayout?: (page: ReactElement) => ReactNode } From 628d72fb037f1bb182a85bec88e3c948bceac860 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 22 Aug 2022 08:30:35 -0500 Subject: [PATCH 25/64] Update ubuntu CI version due to deprecation (#39817) GitHub actions is deprecating the Ubuntu 18.04 runner so this updates our CI to no longer leverage it in favor of the latest Ubuntu runner. x-ref: https://github.com/vercel/next.js/actions/runs/2904029539 x-ref: https://github.com/actions/runner-images --- .github/workflows/build_test_deploy.yml | 18 +++++++++--------- .github/workflows/pull_request_stats.yml | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build_test_deploy.yml b/.github/workflows/build_test_deploy.yml index b22bb436c1c3..fd346920c8d6 100644 --- a/.github/workflows/build_test_deploy.yml +++ b/.github/workflows/build_test_deploy.yml @@ -1060,7 +1060,7 @@ jobs: build-native-test: name: Build native binary for tests and metrics - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest steps: # https://github.com/actions/virtual-environments/issues/1187 - name: tune linux network @@ -1092,14 +1092,14 @@ jobs: if: ${{ steps.docs-change.outputs.DOCS_CHANGE == 'nope' }} with: path: ~/.cargo/registry - key: stable-ubuntu-18.04-cargo-registry + key: stable-ubuntu-latest-cargo-registry - name: Cache cargo index uses: actions/cache@v3 if: ${{ steps.docs-change.outputs.DOCS_CHANGE == 'nope' }} with: path: ~/.cargo/git - key: stable-ubuntu-18.04-cargo-index + key: stable-ubuntu-latest-cargo-index # We use week in the turbo cache key to keep the cache from infinitely growing - id: get-week @@ -1125,9 +1125,9 @@ jobs: uses: actions/cache@v3 with: path: ./packages/next-swc/target - key: next-swc-cargo-cache-dev-ubuntu-18.04-${{ hashFiles('**/Cargo.lock') }} + key: next-swc-cargo-cache-dev-ubuntu-latest-${{ hashFiles('**/Cargo.lock') }} restore-keys: | - next-swc-cargo-cache-dev-ubuntu-18.04 + next-swc-cargo-cache-dev-ubuntu-latest # since the repo's dependencies aren't installed we need # to install napi globally @@ -1152,7 +1152,7 @@ jobs: test-native: name: Unit Test Native Code - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -1176,7 +1176,7 @@ jobs: test-wasm: name: Test the wasm build - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest needs: [build, build-native-test, build-wasm-dev] steps: @@ -1294,7 +1294,7 @@ jobs: export CC_aarch64_unknown_linux_gnu=/usr/aarch64-unknown-linux-gnu/bin/aarch64-unknown-linux-gnu-gcc && turbo run build-native --cache-dir=".turbo" -- --release --target aarch64-unknown-linux-gnu && llvm-strip -x packages/next-swc/native/next-swc.*.node - - host: ubuntu-18.04 + - host: ubuntu-latest target: 'armv7-unknown-linux-gnueabihf' setup: | sudo apt-get update @@ -1357,7 +1357,7 @@ jobs: # https://github.com/actions/virtual-environments/issues/1187 - name: tune linux network run: sudo ethtool -K eth0 tx off rx off - if: ${{ matrix.settings.host == 'ubuntu-18.04' }} + if: ${{ matrix.settings.host == 'ubuntu-latest' }} - name: tune linux network run: sudo ethtool -K eth0 tx off rx off if: ${{ matrix.settings.host == 'ubuntu-latest' }} diff --git a/.github/workflows/pull_request_stats.yml b/.github/workflows/pull_request_stats.yml index 0971e1b6221e..5a9dc25f116d 100644 --- a/.github/workflows/pull_request_stats.yml +++ b/.github/workflows/pull_request_stats.yml @@ -13,7 +13,7 @@ env: jobs: build-native-dev: name: Build dev binary for tests - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest steps: # https://github.com/actions/virtual-environments/issues/1187 - name: tune linux network @@ -46,14 +46,14 @@ jobs: if: ${{ steps.docs-change.outputs.DOCS_CHANGE == 'nope' }} with: path: ~/.cargo/registry - key: stable-ubuntu-18.04-node@14-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }} + key: stable-ubuntu-latest-node@14-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }} - name: Cache cargo index uses: actions/cache@v1 if: ${{ steps.docs-change.outputs.DOCS_CHANGE == 'nope' }} with: path: ~/.cargo/git - key: stable-ubuntu-18.04-node@14-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }} + key: stable-ubuntu-latest-node@14-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }} # We use week in the turbo cache key to keep the cache from infinitely growing - id: get-week @@ -78,9 +78,9 @@ jobs: uses: actions/cache@v3 with: path: ./packages/next-target - key: next-swc-cargo-cache-ubuntu-18.04--${{ hashFiles('**/Cargo.lock') }} + key: next-swc-cargo-cache-ubuntu-latest--${{ hashFiles('**/Cargo.lock') }} restore-keys: | - next-swc-cargo-cache-ubuntu-18.04 + next-swc-cargo-cache-ubuntu-latest # since the repo's dependencies aren't installed we need # to install napi globally From 827e120740c07e9027bc5933228f83a9f8ce6442 Mon Sep 17 00:00:00 2001 From: Henrik Wenz Date: Mon, 22 Aug 2022 15:37:36 +0200 Subject: [PATCH 26/64] [docs] Migrate dynamic routing example to typescript (#39806) Changelog Migrated example to typescript Remove obsolete Link->as prop Normalize Module exports Documentation / Examples Make sure the linting passes by running pnpm lint The examples guidelines are followed from our contributing doc Co-authored-by: JJ Kasper --- examples/dynamic-routing/components/header.js | 30 ------------------- .../dynamic-routing/components/header.tsx | 30 +++++++++++++++++++ examples/dynamic-routing/package.json | 11 +++++-- examples/dynamic-routing/pages/about.js | 10 ------- examples/dynamic-routing/pages/about.tsx | 10 +++++++ examples/dynamic-routing/pages/index.js | 10 ------- examples/dynamic-routing/pages/index.tsx | 10 +++++++ .../post/[id]/{[comment].js => [comment].tsx} | 7 ++--- .../pages/post/[id]/{index.js => index.tsx} | 10 +++---- examples/dynamic-routing/tsconfig.json | 20 +++++++++++++ 10 files changed, 85 insertions(+), 63 deletions(-) delete mode 100644 examples/dynamic-routing/components/header.js create mode 100644 examples/dynamic-routing/components/header.tsx delete mode 100644 examples/dynamic-routing/pages/about.js create mode 100644 examples/dynamic-routing/pages/about.tsx delete mode 100644 examples/dynamic-routing/pages/index.js create mode 100644 examples/dynamic-routing/pages/index.tsx rename examples/dynamic-routing/pages/post/[id]/{[comment].js => [comment].tsx} (64%) rename examples/dynamic-routing/pages/post/[id]/{index.js => index.tsx} (63%) create mode 100644 examples/dynamic-routing/tsconfig.json diff --git a/examples/dynamic-routing/components/header.js b/examples/dynamic-routing/components/header.js deleted file mode 100644 index e7349ba94d11..000000000000 --- a/examples/dynamic-routing/components/header.js +++ /dev/null @@ -1,30 +0,0 @@ -import Link from 'next/link' - -const Header = () => ( -

- -
-) - -export default Header diff --git a/examples/dynamic-routing/components/header.tsx b/examples/dynamic-routing/components/header.tsx new file mode 100644 index 000000000000..e71ccc603b93 --- /dev/null +++ b/examples/dynamic-routing/components/header.tsx @@ -0,0 +1,30 @@ +import Link from 'next/link' + +export default function Header() { + return ( +
+ +
+ ) +} diff --git a/examples/dynamic-routing/package.json b/examples/dynamic-routing/package.json index 349de02f4d84..6a0d14f6b52d 100644 --- a/examples/dynamic-routing/package.json +++ b/examples/dynamic-routing/package.json @@ -6,8 +6,13 @@ "start": "next start" }, "dependencies": { - "next": "latest", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "next": "12.2.5", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@types/node": "18.7.9", + "@types/react": "18.0.17", + "typescript": "4.7.4" } } diff --git a/examples/dynamic-routing/pages/about.js b/examples/dynamic-routing/pages/about.js deleted file mode 100644 index 255d0764b446..000000000000 --- a/examples/dynamic-routing/pages/about.js +++ /dev/null @@ -1,10 +0,0 @@ -import Header from '../components/header' - -const About = () => ( - <> -
-

About page

- -) - -export default About diff --git a/examples/dynamic-routing/pages/about.tsx b/examples/dynamic-routing/pages/about.tsx new file mode 100644 index 000000000000..d646cba7b626 --- /dev/null +++ b/examples/dynamic-routing/pages/about.tsx @@ -0,0 +1,10 @@ +import Header from '../components/header' + +export default function AboutPage() { + return ( + <> +
+

About page

+ + ) +} diff --git a/examples/dynamic-routing/pages/index.js b/examples/dynamic-routing/pages/index.js deleted file mode 100644 index 0f56525ada21..000000000000 --- a/examples/dynamic-routing/pages/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import Header from '../components/header' - -const Home = () => ( - <> -
-

Hello World!

- -) - -export default Home diff --git a/examples/dynamic-routing/pages/index.tsx b/examples/dynamic-routing/pages/index.tsx new file mode 100644 index 000000000000..0280a6da7aa3 --- /dev/null +++ b/examples/dynamic-routing/pages/index.tsx @@ -0,0 +1,10 @@ +import Header from '../components/header' + +export default function IndexPage() { + return ( + <> +
+

Hello World!

+ + ) +} diff --git a/examples/dynamic-routing/pages/post/[id]/[comment].js b/examples/dynamic-routing/pages/post/[id]/[comment].tsx similarity index 64% rename from examples/dynamic-routing/pages/post/[id]/[comment].js rename to examples/dynamic-routing/pages/post/[id]/[comment].tsx index 6aa93ef597d2..1c33af5e0f24 100644 --- a/examples/dynamic-routing/pages/post/[id]/[comment].js +++ b/examples/dynamic-routing/pages/post/[id]/[comment].tsx @@ -1,9 +1,10 @@ import { useRouter } from 'next/router' import Header from '../../../components/header' -const Comment = () => { +export default function CommentPage() { const router = useRouter() - const { id, comment } = router.query + const id = router.query.id as string + const comment = router.query.comment as string return ( <> @@ -13,5 +14,3 @@ const Comment = () => { ) } - -export default Comment diff --git a/examples/dynamic-routing/pages/post/[id]/index.js b/examples/dynamic-routing/pages/post/[id]/index.tsx similarity index 63% rename from examples/dynamic-routing/pages/post/[id]/index.js rename to examples/dynamic-routing/pages/post/[id]/index.tsx index c8f4a77ca386..ffad6732b960 100644 --- a/examples/dynamic-routing/pages/post/[id]/index.js +++ b/examples/dynamic-routing/pages/post/[id]/index.tsx @@ -2,9 +2,9 @@ import { useRouter } from 'next/router' import Link from 'next/link' import Header from '../../../components/header' -const Post = () => { +export default function PostPage() { const router = useRouter() - const { id } = router.query + const id = router.query.id as string return ( <> @@ -12,12 +12,12 @@ const Post = () => {

Post: {id}

  • - + First comment
  • - + Second comment
  • @@ -25,5 +25,3 @@ const Post = () => { ) } - -export default Post diff --git a/examples/dynamic-routing/tsconfig.json b/examples/dynamic-routing/tsconfig.json new file mode 100644 index 000000000000..50bcb22f653d --- /dev/null +++ b/examples/dynamic-routing/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "incremental": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve" + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} From e307096e2f31b50c840d88098087057ea24778fe Mon Sep 17 00:00:00 2001 From: Maedah Batool Date: Mon, 22 Aug 2022 18:50:56 +0500 Subject: [PATCH 27/64] Add clarity in docs for using `exportPathMap` with `getStaticPaths` (#39813) This PR adds a warning note for using the exportPathMap function with getStaticPaths. Any routes defined with EPM will get overridden if that page uses GSP. Bug Related issues linked using #534 Integration tests added Errors have helpful link attached, see contributing.md Feature Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. Related issues linked using fixes #number Integration tests added Documentation added Telemetry added. In case of a feature if it's used or not. Errors have helpful link attached, see contributing.md Documentation / Examples Make sure the linting passes by running pnpm lint The examples guidelines are followed from our contributing doc --- docs/advanced-features/static-html-export.md | 2 ++ docs/api-reference/next.config.js/exportPathMap.md | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/advanced-features/static-html-export.md b/docs/advanced-features/static-html-export.md index a2a7a7f2b80a..107a348a4f3f 100644 --- a/docs/advanced-features/static-html-export.md +++ b/docs/advanced-features/static-html-export.md @@ -31,6 +31,8 @@ Running `npm run build` will generate an `out` directory. For more advanced scenarios, you can define a parameter called [`exportPathMap`](/docs/api-reference/next.config.js/exportPathMap.md) in your [`next.config.js`](/docs/api-reference/next.config.js/introduction.md) file to configure exactly which pages will be generated. +> **Warning**: Using `exportPathMap` for defining routes with any `getStaticPaths` powered page is now ignored and gets overridden. We recommend not to use them together. + ## Supported Features The majority of core Next.js features needed to build a static site are supported, including: diff --git a/docs/api-reference/next.config.js/exportPathMap.md b/docs/api-reference/next.config.js/exportPathMap.md index a1ef9f65021f..4180363e6dcf 100644 --- a/docs/api-reference/next.config.js/exportPathMap.md +++ b/docs/api-reference/next.config.js/exportPathMap.md @@ -40,7 +40,7 @@ module.exports = { } ``` -Note: the `query` field in `exportPathMap` cannot be used with [automatically statically optimized pages](/docs/advanced-features/automatic-static-optimization) or [`getStaticProps` pages](/docs/basic-features/data-fetching/get-static-props.md) as they are rendered to HTML files at build-time and additional query information cannot be provided during `next export`. +> Note: the `query` field in `exportPathMap` cannot be used with [automatically statically optimized pages](/docs/advanced-features/automatic-static-optimization) or [`getStaticProps` pages](/docs/basic-features/data-fetching/get-static-props.md) as they are rendered to HTML files at build-time and additional query information cannot be provided during `next export`. The pages will then be exported as HTML files, for example, `/about` will become `/about.html`. @@ -79,6 +79,8 @@ module.exports = { next export -o outdir ``` +> **Warning**: Using `exportPathMap` for defining routes with any `getStaticPaths` powered page is now ignored and gets overridden. We recommend not to use them together. + ## Related
    From 8f023992a2072209be8db1345fbbbcc293eee13a Mon Sep 17 00:00:00 2001 From: Adrian Bienias Date: Mon, 22 Aug 2022 16:01:14 +0200 Subject: [PATCH 28/64] Update links to point to more accurate docs (#39818) Initial links were pointing to basic features which don't describe redirections. --- docs/api-reference/next.config.js/redirects.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-reference/next.config.js/redirects.md b/docs/api-reference/next.config.js/redirects.md index 988a5fa97522..05b50a62a3d7 100644 --- a/docs/api-reference/next.config.js/redirects.md +++ b/docs/api-reference/next.config.js/redirects.md @@ -300,4 +300,4 @@ In some rare cases, you might need to assign a custom status code for older HTTP ## Other Redirects - Inside [API Routes](/docs/api-routes/response-helpers.md), you can use `res.redirect()`. -- Inside [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md) and [`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md), you can redirect specific pages at request-time. +- Inside [`getStaticProps`](/docs/api-reference/data-fetching/get-static-props.md) and [`getServerSideProps`](/docs/api-reference/data-fetching/get-server-side-props.md), you can redirect specific pages at request-time. From c172d461c8cac5b732f270123b850fa968e52510 Mon Sep 17 00:00:00 2001 From: Michael Oliver Date: Mon, 22 Aug 2022 15:18:40 +0100 Subject: [PATCH 29/64] Remove unnecessary type reference in Vitest example (#39819) Documentation / Examples Make sure the linting passes by running pnpm lint The examples guidelines are followed from our contributing doc The Vitest docs state that /// is only required when importing defineConfig from vite. --- examples/with-vitest/vitest.config.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/with-vitest/vitest.config.ts b/examples/with-vitest/vitest.config.ts index e82ca6b60b1d..0a37d9af6ee2 100644 --- a/examples/with-vitest/vitest.config.ts +++ b/examples/with-vitest/vitest.config.ts @@ -1,5 +1,3 @@ -/// - import { defineConfig } from 'vitest/config' import react from '@vitejs/plugin-react' From b431bd4ba05d63c8b8a8b62c4efd085a8a8f21f2 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 22 Aug 2022 09:54:25 -0500 Subject: [PATCH 30/64] Leverage VERCEL_CLI_VERSION env for deploy tests (#39823) This updates our next-e2e test deploy mode to auto pass along the VERCEL_CLI_VERSION env variable to allow testing builder changes easier. cc @nkzawa who encountered this. --- test/lib/next-modes/next-deploy.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/lib/next-modes/next-deploy.ts b/test/lib/next-modes/next-deploy.ts index 2264014aacb6..a06c85f51469 100644 --- a/test/lib/next-modes/next-deploy.ts +++ b/test/lib/next-modes/next-deploy.ts @@ -74,6 +74,13 @@ export class NextDeployInstance extends NextInstance { additionalEnv.push(`${key}=${this.env[key]}`) } + if (process.env.VERCEL_CLI_VERSION) { + additionalEnv.push('--build-env') + additionalEnv.push( + `VERCEL_CLI_VERSION="${process.env.VERCEL_CLI_VERSION}"` + ) + } + const deployRes = await execa( 'vercel', [ @@ -81,8 +88,6 @@ export class NextDeployInstance extends NextInstance { '--build-env', 'NEXT_PRIVATE_TEST_MODE=1', '--build-env', - 'FORCE_RUNTIME_TAG=canary', - '--build-env', 'NEXT_TELEMETRY_DISABLED=1', ...additionalEnv, '--force', From 4955da9eed1f55570039cf61b219c39b6b77320f Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 22 Aug 2022 11:32:30 -0500 Subject: [PATCH 31/64] Update stalled ensure log to use debug instead (#39826) This updates the stalled ensure log to use debug instead the log isn't really actionable by the user and is more so meant for debugging purposes. x-ref: slack thread --- packages/next/server/dev/on-demand-entry-handler.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/next/server/dev/on-demand-entry-handler.ts b/packages/next/server/dev/on-demand-entry-handler.ts index f3c820da209d..06110c5f42e8 100644 --- a/packages/next/server/dev/on-demand-entry-handler.ts +++ b/packages/next/server/dev/on-demand-entry-handler.ts @@ -1,5 +1,5 @@ import type ws from 'ws' -import * as Log from '../../build/output/log' +import origDebug from 'next/dist/compiled/debug' import type { webpack } from 'next/dist/compiled/webpack/webpack' import type { NextConfigComplete } from '../config-shared' import { EventEmitter } from 'events' @@ -23,6 +23,8 @@ import { COMPILER_NAMES, } from '../../shared/lib/constants' +const debug = origDebug('next:on-demand-entry-handler') + /** * Returns object keys with type inferred from the object key */ @@ -517,7 +519,7 @@ export function onDemandEntryHandler({ async ensurePage(page: string, clientOnly: boolean): Promise { const stalledTime = 60 const stalledEnsureTimeout = setTimeout(() => { - Log.warn( + debug( `Ensuring ${page} has taken longer than ${stalledTime}s, if this continues to stall this may be a bug` ) }, stalledTime * 1000) From d2a2cc780843f88b3c78ef203d52f017e3292733 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 22 Aug 2022 11:59:23 -0500 Subject: [PATCH 32/64] Skip building /500 in dev mode (#39828) Follow-up to #39826 this skips ensuring the /500 page when in development as it's not used since we use the error overlay instead. This also fixes the case where we don't clear the stalled timeout debug log when an error is thrown during ensuring. --- packages/next/server/base-server.ts | 8 +- .../server/dev/on-demand-entry-handler.ts | 197 +++++++++--------- 2 files changed, 106 insertions(+), 99 deletions(-) diff --git a/packages/next/server/base-server.ts b/packages/next/server/base-server.ts index d3e89af197c7..99b44c8378d8 100644 --- a/packages/next/server/base-server.ts +++ b/packages/next/server/base-server.ts @@ -1705,14 +1705,18 @@ export default abstract class Server { let using404Page = false // use static 404 page if available and is 404 response - if (is404) { + if (is404 && (await this.hasPage('/404'))) { result = await this.findPageComponents('/404', query) using404Page = result !== null } let statusPage = `/${res.statusCode}` if (!result && STATIC_STATUS_PAGES.includes(statusPage)) { - result = await this.findPageComponents(statusPage, query) + // skip ensuring /500 in dev mode as it isn't used and the + // dev overlay is used instead + if (statusPage !== '/500' || !this.renderOpts.dev) { + result = await this.findPageComponents(statusPage, query) + } } if (!result) { diff --git a/packages/next/server/dev/on-demand-entry-handler.ts b/packages/next/server/dev/on-demand-entry-handler.ts index 06110c5f42e8..00561904706e 100644 --- a/packages/next/server/dev/on-demand-entry-handler.ts +++ b/packages/next/server/dev/on-demand-entry-handler.ts @@ -524,123 +524,126 @@ export function onDemandEntryHandler({ ) }, stalledTime * 1000) - const pagePathData = await findPagePathData( - rootDir, - pagesDir, - page, - nextConfig.pageExtensions, - appDir - ) + try { + const pagePathData = await findPagePathData( + rootDir, + pagesDir, + page, + nextConfig.pageExtensions, + appDir + ) + + const isServerComponent = serverComponentRegex.test( + pagePathData.absolutePagePath + ) + const isInsideAppDir = + appDir && pagePathData.absolutePagePath.startsWith(appDir) + + const addEntry = ( + compilerType: CompilerNameValues + ): { + entryKey: string + newEntry: boolean + shouldInvalidate: boolean + } => { + const entryKey = `${compilerType}${pagePathData.page}` + + if (entries[entryKey]) { + entries[entryKey].dispose = false + entries[entryKey].lastActiveTime = Date.now() + if (entries[entryKey].status === BUILT) { + return { + entryKey, + newEntry: false, + shouldInvalidate: false, + } + } - const isServerComponent = serverComponentRegex.test( - pagePathData.absolutePagePath - ) - const isInsideAppDir = - appDir && pagePathData.absolutePagePath.startsWith(appDir) - - const addEntry = ( - compilerType: CompilerNameValues - ): { - entryKey: string - newEntry: boolean - shouldInvalidate: boolean - } => { - const entryKey = `${compilerType}${pagePathData.page}` - - if (entries[entryKey]) { - entries[entryKey].dispose = false - entries[entryKey].lastActiveTime = Date.now() - if (entries[entryKey].status === BUILT) { return { entryKey, newEntry: false, - shouldInvalidate: false, + shouldInvalidate: true, } } + entries[entryKey] = { + type: EntryTypes.ENTRY, + absolutePagePath: pagePathData.absolutePagePath, + request: pagePathData.absolutePagePath, + bundlePath: pagePathData.bundlePath, + dispose: false, + lastActiveTime: Date.now(), + status: ADDED, + } + return { - entryKey, - newEntry: false, + entryKey: entryKey, + newEntry: true, shouldInvalidate: true, } } - entries[entryKey] = { - type: EntryTypes.ENTRY, - absolutePagePath: pagePathData.absolutePagePath, - request: pagePathData.absolutePagePath, - bundlePath: pagePathData.bundlePath, - dispose: false, - lastActiveTime: Date.now(), - status: ADDED, - } + const staticInfo = await getPageStaticInfo({ + pageFilePath: pagePathData.absolutePagePath, + nextConfig, + }) - return { - entryKey: entryKey, - newEntry: true, - shouldInvalidate: true, - } - } + const added = new Map>() - const staticInfo = await getPageStaticInfo({ - pageFilePath: pagePathData.absolutePagePath, - nextConfig, - }) + await runDependingOnPageType({ + page: pagePathData.page, + pageRuntime: staticInfo.runtime, + onClient: () => { + // Skip adding the client entry for app / Server Components. + if (isServerComponent || isInsideAppDir) { + return + } + added.set(COMPILER_NAMES.client, addEntry(COMPILER_NAMES.client)) + }, + onServer: () => { + added.set(COMPILER_NAMES.server, addEntry(COMPILER_NAMES.server)) + }, + onEdgeServer: () => { + added.set( + COMPILER_NAMES.edgeServer, + addEntry(COMPILER_NAMES.edgeServer) + ) + }, + }) - const added = new Map>() + const addedValues = [...added.values()] + const entriesThatShouldBeInvalidated = addedValues.filter( + (entry) => entry.shouldInvalidate + ) + const hasNewEntry = addedValues.some((entry) => entry.newEntry) - await runDependingOnPageType({ - page: pagePathData.page, - pageRuntime: staticInfo.runtime, - onClient: () => { - // Skip adding the client entry for app / Server Components. - if (isServerComponent || isInsideAppDir) { - return - } - added.set(COMPILER_NAMES.client, addEntry(COMPILER_NAMES.client)) - }, - onServer: () => { - added.set(COMPILER_NAMES.server, addEntry(COMPILER_NAMES.server)) - }, - onEdgeServer: () => { - added.set( - COMPILER_NAMES.edgeServer, - addEntry(COMPILER_NAMES.edgeServer) + if (hasNewEntry) { + reportTrigger( + !clientOnly && hasNewEntry + ? `${pagePathData.page} (client and server)` + : pagePathData.page ) - }, - }) - - const addedValues = [...added.values()] - const entriesThatShouldBeInvalidated = addedValues.filter( - (entry) => entry.shouldInvalidate - ) - const hasNewEntry = addedValues.some((entry) => entry.newEntry) - - if (hasNewEntry) { - reportTrigger( - !clientOnly && hasNewEntry - ? `${pagePathData.page} (client and server)` - : pagePathData.page - ) - } + } - if (entriesThatShouldBeInvalidated.length > 0) { - const invalidatePromises = entriesThatShouldBeInvalidated.map( - ({ entryKey }) => { - return new Promise((resolve, reject) => { - doneCallbacks!.once(entryKey, (err: Error) => { - if (err) { - return reject(err) - } - resolve() + if (entriesThatShouldBeInvalidated.length > 0) { + const invalidatePromises = entriesThatShouldBeInvalidated.map( + ({ entryKey }) => { + return new Promise((resolve, reject) => { + doneCallbacks!.once(entryKey, (err: Error) => { + if (err) { + return reject(err) + } + resolve() + }) }) - }) - } - ) - invalidator.invalidate([...added.keys()]) - await Promise.all(invalidatePromises) + } + ) + invalidator.invalidate([...added.keys()]) + await Promise.all(invalidatePromises) + } + } finally { + clearTimeout(stalledEnsureTimeout) } - clearTimeout(stalledEnsureTimeout) }, onHMR(client: ws) { From b6bbbc813f6ce39b2c65aa0b72fbfca2ab5cbad1 Mon Sep 17 00:00:00 2001 From: Steven Date: Mon, 22 Aug 2022 13:31:57 -0400 Subject: [PATCH 33/64] Update docs `next/future/image` with details about computed aspect ratio (#39829) The browser support for this feature was added to caniuse so we can link there instead of linking to each browser bug tracker. --- docs/api-reference/next/future/image.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/api-reference/next/future/image.md b/docs/api-reference/next/future/image.md index 76e2ee33cddc..2438cad0c84e 100644 --- a/docs/api-reference/next/future/image.md +++ b/docs/api-reference/next/future/image.md @@ -16,7 +16,7 @@ description: Try the latest Image Optimization with the experimental `next/futur The `next/future/image` component is an experiment to improve both the performance and developer experience of `next/image` by using the native `` element with better default behavior. -This new component is considered experimental and therefore not covered by semver, and may cause unexpected or broken application behavior. This component uses browser native [lazy loading](https://caniuse.com/loading-lazy-attr), which may fallback to eager loading for older browsers before Safari 15.4. When using the blur-up placeholder, older browsers before Safari 12 will fallback to empty placeholder. When using styles with `width`/`height` of `auto`, it is possible to cause [Layout Shift](https://web.dev/cls/) on older browsers before [Chrome 79](https://chromestatus.com/feature/5695266130755584), [Firefox 69](https://bugzilla.mozilla.org/show_bug.cgi?id=1547231), and [Safari 14.2](https://bugs.webkit.org/show_bug.cgi?id=201641). For more details, see [this MDN video](https://www.youtube.com/watch?v=4-d_SoCHeWE). +This new component is considered experimental and therefore not covered by semver, and may cause unexpected or broken application behavior. This component uses browser native [lazy loading](https://caniuse.com/loading-lazy-attr), which may fallback to eager loading for older browsers before Safari 15.4. When using the blur-up placeholder, older browsers before Safari 12 will fallback to empty placeholder. When using styles with `width`/`height` of `auto`, it is possible to cause [Layout Shift](https://web.dev/cls/) on older browsers before Safari 15 that don't [preserve the aspect ratio](https://caniuse.com/mdn-html_elements_img_aspect_ratio_computed_from_attributes). For more details, see [this MDN video](https://www.youtube.com/watch?v=4-d_SoCHeWE). To use `next/future/image`, add the following to your `next.config.js` file: @@ -34,10 +34,14 @@ module.exports = { Compared to `next/image`, the new `next/future/image` component has the following changes: -- Renders a single `` without `
    ` or `` wrappers +- Removes `` wrapper around `` in favor of [native computed aspect ratio](https://caniuse.com/mdn-html_elements_img_aspect_ratio_computed_from_attributes) - Adds support for canonical `style` prop -- Removes `layout`, `objectFit`, and `objectPosition` props in favor of `style` or `className` + - Removes `layout` prop in favor of `style` or `className` + - Removes `objectFit` prop in favor of `style` or `className` + - Removes `objectPosition` prop in favor of `style` or `className` - Removes `IntersectionObserver` implementation in favor of [native lazy loading](https://caniuse.com/loading-lazy-attr) + - Removes `lazyBoundary` prop since there is no native equivalent + - Removes `lazyRoot` prop since there is no native equivalent - Removes `loader` config in favor of [`loader`](#loader) prop - Note: the [`onError`](#onerror) prop might behave differently From d2ab9bcc85f8ee38912eefe7866a8b023421cac4 Mon Sep 17 00:00:00 2001 From: Arthur Denner Date: Mon, 22 Aug 2022 21:46:54 +0200 Subject: [PATCH 34/64] Mention router.isPreview on Preview Mode page (#39830) The documentation is concise and straightforward, so I just added a sentence. Let me know if you'd like to describe more, add an example, etc. Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com> --- docs/advanced-features/preview-mode.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/advanced-features/preview-mode.md b/docs/advanced-features/preview-mode.md index a6700718692d..e9cd56f40f61 100644 --- a/docs/advanced-features/preview-mode.md +++ b/docs/advanced-features/preview-mode.md @@ -173,6 +173,8 @@ https:///api/preview?secret=&slug= ## More Details +> **Note**: during rendering `next/router` exposes an `isPreview` flag, see the [router object docs](/docs/api-reference/next/router.md#router-object) for more info. + ### Clear the Preview Mode cookies By default, no expiration date is set for Preview Mode cookies, so the preview session ends when the browser is closed. From 6bc7cdaf470fe708b571f2af70b38613a675bb36 Mon Sep 17 00:00:00 2001 From: sumiren <42498227+sumiren@users.noreply.github.com> Date: Tue, 23 Aug 2022 04:55:46 +0900 Subject: [PATCH 35/64] doc: improve a word client side rendering (#39771) The term client-side rendering is ambiguous and misleading. Some people would assume the architecture where a blank page is returned from the server and HTML generation is totally done on the frontend. So I changed the term to `client-side data fetching`, which is widely used throughout the rest of the document. ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have helpful link attached, see `contributing.md` ## Documentation / Examples - [x] Make sure the linting passes by running `pnpm lint` - [x] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples) --- docs/basic-features/pages.md | 4 ++-- docs/faq.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/basic-features/pages.md b/docs/basic-features/pages.md index 519e8a18bece..46314a3ac16c 100644 --- a/docs/basic-features/pages.md +++ b/docs/basic-features/pages.md @@ -41,7 +41,7 @@ Importantly, Next.js lets you **choose** which pre-rendering form you'd like to We **recommend** using **Static Generation** over Server-side Rendering for performance reasons. Statically generated pages can be cached by CDN with no extra configuration to boost performance. However, in some cases, Server-side Rendering might be the only option. -You can also use **Client-side Rendering** along with Static Generation or Server-side Rendering. That means some parts of a page can be rendered entirely by client side JavaScript. To learn more, take a look at the [Data Fetching](/docs/basic-features/data-fetching/client-side.md) documentation. +You can also use **Client-side data fetching** along with Static Generation or Server-side Rendering. That means some parts of a page can be rendered entirely by client side JavaScript. To learn more, take a look at the [Data Fetching](/docs/basic-features/data-fetching/client-side.md) documentation. ## Static Generation (Recommended) @@ -217,7 +217,7 @@ On the other hand, Static Generation is **not** a good idea if you cannot pre-re In cases like this, you can do one of the following: -- Use Static Generation with **Client-side Rendering:** You can skip pre-rendering some parts of a page and then use client-side JavaScript to populate them. To learn more about this approach, check out the [Data Fetching documentation](/docs/basic-features/data-fetching/client-side.md). +- Use Static Generation with **Client-side data fetching:** You can skip pre-rendering some parts of a page and then use client-side JavaScript to populate them. To learn more about this approach, check out the [Data Fetching documentation](/docs/basic-features/data-fetching/client-side.md). - Use **Server-Side Rendering:** Next.js pre-renders a page on each request. It will be slower because the page cannot be cached by a CDN, but the pre-rendered page will always be up-to-date. We'll talk about this approach below. ## Server-side Rendering diff --git a/docs/faq.md b/docs/faq.md index fe9ca6838034..216db88c40ce 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -14,7 +14,7 @@ description: Get to know more about Next.js with the frequently asked questions. How do I fetch data in Next.js? Next.js provides a variety of methods depending on your use case. You can use:
      -
    • Client-side rendering: Fetch data with useEffect or SWR inside your React components
    • +
    • Client-side data fetching: Fetch data with useEffect or SWR inside your React components
    • Server-side rendering with getServerSideProps
    • Static-site generation with getStaticProps
    • Incremental Static Regeneration by adding the `revalidate` prop to getStaticProps
    • From 1f5da04dad73406c10e80908cd9ddd41bafc43da Mon Sep 17 00:00:00 2001 From: Miguel Oller Date: Mon, 22 Aug 2022 17:02:19 -0400 Subject: [PATCH 36/64] Update cms-makeswift example (#39834) Upgrade @makeswift/runtime to the latest version. This removes the need for the MAKESWIFT_API_HOST environment variable and improves error messages when integrating Next.js with Makeswift. ## Documentation / Examples - [x] Make sure the linting passes by running `pnpm lint` - [x] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples) --- examples/cms-makeswift/.env.local.example | 1 - examples/cms-makeswift/package.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/cms-makeswift/.env.local.example b/examples/cms-makeswift/.env.local.example index 6d8f3c9ad0ed..3685b7a9930b 100644 --- a/examples/cms-makeswift/.env.local.example +++ b/examples/cms-makeswift/.env.local.example @@ -1,2 +1 @@ -MAKESWIFT_API_HOST=https://api.makeswift.com MAKESWIFT_SITE_API_KEY= diff --git a/examples/cms-makeswift/package.json b/examples/cms-makeswift/package.json index f3b32cf70fa4..eb27abb4320f 100644 --- a/examples/cms-makeswift/package.json +++ b/examples/cms-makeswift/package.json @@ -6,7 +6,7 @@ "start": "next start" }, "dependencies": { - "@makeswift/runtime": "0.1.2", + "@makeswift/runtime": "0.1.5", "next": "latest", "react": "18.2.0", "react-dom": "18.2.0" From 7e9f9bfbef2cf4d63ceb899eeccf5bd0fcba2ec5 Mon Sep 17 00:00:00 2001 From: Steven Date: Mon, 22 Aug 2022 17:37:16 -0400 Subject: [PATCH 37/64] Fix `onError` handling in `next/future/image` (#39824) This PR fixes a race condition where the `onError` handler was never called because the error happened before react attached the error handler. --- docs/api-reference/next/future/image.md | 5 +---- packages/next/client/future/image.tsx | 17 ++++++++++++-- .../pages/on-error-before-hydration.js | 22 +++++++++++++++++++ .../image-future/default/test/index.test.ts | 8 +++++++ 4 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 test/integration/image-future/default/pages/on-error-before-hydration.js diff --git a/docs/api-reference/next/future/image.md b/docs/api-reference/next/future/image.md index 2438cad0c84e..aeeacf7eac26 100644 --- a/docs/api-reference/next/future/image.md +++ b/docs/api-reference/next/future/image.md @@ -43,7 +43,6 @@ Compared to `next/image`, the new `next/future/image` component has the followin - Removes `lazyBoundary` prop since there is no native equivalent - Removes `lazyRoot` prop since there is no native equivalent - Removes `loader` config in favor of [`loader`](#loader) prop -- Note: the [`onError`](#onerror) prop might behave differently ## Known Browser Bugs @@ -316,7 +315,7 @@ The callback function will be called with one argument, an object with the follo A callback function that is invoked when the image is loaded. -Note that the load event might occur before client-side hydration completes, so this callback might not be invoked in that case. +Note that the load event might occur before the placeholder is removed and the image is fully decoded. Instead, use [`onLoadingComplete`](#onloadingcomplete). @@ -324,8 +323,6 @@ Instead, use [`onLoadingComplete`](#onloadingcomplete). A callback function that is invoked if the image fails to load. -Note that the error might occur before client-side hydration completes, so this callback might not be invoked in that case. - ### loading > **Attention**: This property is only meant for advanced usage. Switching an diff --git a/packages/next/client/future/image.tsx b/packages/next/client/future/image.tsx index 81cc5e45d964..5fe483f337fe 100644 --- a/packages/next/client/future/image.tsx +++ b/packages/next/client/future/image.tsx @@ -358,7 +358,14 @@ const ImageElement = ({ loading={loading} style={{ ...imgStyle, ...blurStyle }} ref={useCallback( - (img: ImgElementWithDataProp) => { + (img: ImgElementWithDataProp | null) => { + if (img && onError) { + // If the image has an error before react hydrates, then the error is lost. + // The workaround is to wait until the image is mounted which is after hydration, + // then we set the src again to trigger the error handler (if there was an error). + // eslint-disable-next-line no-self-assign + img.src = img.src + } if (process.env.NODE_ENV !== 'production') { if (img && !srcString) { console.error(`Image is missing required "src" property:`, img) @@ -374,7 +381,13 @@ const ImageElement = ({ ) } }, - [srcString, placeholder, onLoadingCompleteRef, setBlurComplete] + [ + srcString, + placeholder, + onLoadingCompleteRef, + setBlurComplete, + onError, + ] )} onLoad={(event) => { const img = event.currentTarget as ImgElementWithDataProp diff --git a/test/integration/image-future/default/pages/on-error-before-hydration.js b/test/integration/image-future/default/pages/on-error-before-hydration.js new file mode 100644 index 000000000000..ac68b482a3fc --- /dev/null +++ b/test/integration/image-future/default/pages/on-error-before-hydration.js @@ -0,0 +1,22 @@ +import { useState } from 'react' +import Image from 'next/future/image' + +const Page = () => { + const [msg, setMsg] = useState(`default state`) + return ( +
      + { + setMsg(`error state`) + }} + /> +

      {msg}

      +
      + ) +} + +export default Page diff --git a/test/integration/image-future/default/test/index.test.ts b/test/integration/image-future/default/test/index.test.ts index bf6a00d046e4..a21d1112da25 100644 --- a/test/integration/image-future/default/test/index.test.ts +++ b/test/integration/image-future/default/test/index.test.ts @@ -387,6 +387,14 @@ function runTests(mode) { ) }) + it('should callback native onError even when error before hydration', async () => { + let browser = await webdriver(appPort, '/on-error-before-hydration') + await check( + () => browser.eval(`document.getElementById("msg").textContent`), + 'error state' + ) + }) + it('should work with image with blob src', async () => { let browser try { From 3d0d09002a3cd15463afe919dd6791003ff206d2 Mon Sep 17 00:00:00 2001 From: Steven Date: Mon, 22 Aug 2022 19:07:41 -0400 Subject: [PATCH 38/64] Improve error message on `next/future/image` when `objectFit` or `objectPosition` (#39614) Improve PR improves the error message on `next/future/image` when `objectFit` or `objectPosition` is provided and suggests using `style` instead. It also prints the stack trace so its clear where the error came from. --- packages/next/client/future/image.tsx | 38 ++++++++++++------- .../default/pages/invalid-objectfit.js | 18 +++++++++ .../image-future/default/test/index.test.ts | 14 +++++++ 3 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 test/integration/image-future/default/pages/invalid-objectfit.js diff --git a/packages/next/client/future/image.tsx b/packages/next/client/future/image.tsx index 5fe483f337fe..4ca2d06ec3c5 100644 --- a/packages/next/client/future/image.tsx +++ b/packages/next/client/future/image.tsx @@ -359,7 +359,10 @@ const ImageElement = ({ style={{ ...imgStyle, ...blurStyle }} ref={useCallback( (img: ImgElementWithDataProp | null) => { - if (img && onError) { + if (!img) { + return + } + if (onError) { // If the image has an error before react hydrates, then the error is lost. // The workaround is to wait until the image is mounted which is after hydration, // then we set the src again to trigger the error handler (if there was an error). @@ -367,11 +370,29 @@ const ImageElement = ({ img.src = img.src } if (process.env.NODE_ENV !== 'production') { - if (img && !srcString) { + if (!srcString) { console.error(`Image is missing required "src" property:`, img) } + if ( + img.getAttribute('objectFit') || + img.getAttribute('objectfit') + ) { + console.error( + `Image has unknown prop "objectFit". Did you mean to use the "style" prop instead?`, + img + ) + } + if ( + img.getAttribute('objectPosition') || + img.getAttribute('objectposition') + ) { + console.error( + `Image has unknown prop "objectPosition". Did you mean to use the "style" prop instead?`, + img + ) + } } - if (img?.complete) { + if (img.complete) { handleLoading( img, srcString, @@ -666,17 +687,6 @@ export default function Image({ ) } - if ('objectFit' in rest) { - throw new Error( - `Image with src "${src}" has unknown prop "objectFit". This style should be specified using the "style" property.` - ) - } - if ('objectPosition' in rest) { - throw new Error( - `Image with src "${src}" has unknown prop "objectPosition". This style should be specified using the "style" property.` - ) - } - if (placeholder === 'blur') { if ((widthInt || 0) * (heightInt || 0) < 1600) { warnOnce( diff --git a/test/integration/image-future/default/pages/invalid-objectfit.js b/test/integration/image-future/default/pages/invalid-objectfit.js new file mode 100644 index 000000000000..5164a61b7ade --- /dev/null +++ b/test/integration/image-future/default/pages/invalid-objectfit.js @@ -0,0 +1,18 @@ +import React from 'react' +import Image from 'next/future/image' + +const Page = () => { + return ( +
      + +
      + ) +} + +export default Page diff --git a/test/integration/image-future/default/test/index.test.ts b/test/integration/image-future/default/test/index.test.ts index a21d1112da25..0b779d5fa4d8 100644 --- a/test/integration/image-future/default/test/index.test.ts +++ b/test/integration/image-future/default/test/index.test.ts @@ -858,6 +858,20 @@ function runTests(mode) { ) expect(warnings.length).toBe(1) }) + + it('should show console error for objectFit and objectPosition', async () => { + const browser = await webdriver(appPort, '/invalid-objectfit') + + expect(await hasRedbox(browser)).toBe(false) + + await check(async () => { + return (await browser.log()).map((log) => log.message).join('\n') + }, /Image has unknown prop "objectFit"/gm) + + await check(async () => { + return (await browser.log()).map((log) => log.message).join('\n') + }, /Image has unknown prop "objectPosition"/gm) + }) } else { //server-only tests it('should not create an image folder in server/chunks', async () => { From cb1038cb6d21bd6f51b70b3d4e52e03a46dc22b0 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Tue, 23 Aug 2022 00:09:56 +0100 Subject: [PATCH 39/64] Refactor client CSS imports (#39758) Removed the hack of client-side CSS injection via `chunk`. Instead collect them with the manifest plugin and SSR them as link tags. Next step is to adjust HMR to not relying on mini-css-extract plugin and webpack. --- .../plugins/flight-client-entry-plugin.ts | 19 +++---- .../webpack/plugins/flight-manifest-plugin.ts | 51 +++++++------------ packages/next/client/app-index.tsx | 12 ----- packages/next/server/app-render.tsx | 4 +- .../app/app/css/css-client/client-foo.css | 3 ++ .../app/app/css/css-client/client-layout.css | 3 ++ .../app/app/css/css-client/client-page.css | 6 +++ .../e2e/app-dir/app/app/css/css-client/foo.js | 5 ++ .../app/app/css/css-client/layout.client.js | 12 +++++ .../app/app/css/css-client/page.client.js | 5 ++ 10 files changed, 66 insertions(+), 54 deletions(-) create mode 100644 test/e2e/app-dir/app/app/css/css-client/client-foo.css create mode 100644 test/e2e/app-dir/app/app/css/css-client/client-layout.css create mode 100644 test/e2e/app-dir/app/app/css/css-client/client-page.css create mode 100644 test/e2e/app-dir/app/app/css/css-client/foo.js create mode 100644 test/e2e/app-dir/app/app/css/css-client/layout.client.js create mode 100644 test/e2e/app-dir/app/app/css/css-client/page.client.js diff --git a/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts b/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts index e67e005704b1..358f8707bbac 100644 --- a/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts +++ b/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts @@ -71,11 +71,6 @@ export class FlightClientEntryPlugin { // For each SC server compilation entry, we need to create its corresponding // client component entry. for (const [name, entry] of compilation.entries.entries()) { - // If the request is not for `app` directory entry skip it. - // if (!entry.request || !entry.request.startsWith('next-app-loader')) { - // continue - // } - // Check if the page entry is a server component or not. const entryDependency = entry.dependencies?.[0] // Ensure only next-app-loader entries are handled. @@ -193,7 +188,10 @@ export class FlightClientEntryPlugin { const clientComponentImports: ClientComponentImports = [] const serverCSSImports: CssImports = {} - const filterClientComponents = (dependencyToFilter: any): void => { + const filterClientComponents = ( + dependencyToFilter: any, + inClientComponentBoundary: boolean + ): void => { const mod: webpack.NormalModule = compilation.moduleGraph.getResolvedModule(dependencyToFilter) if (!mod) return @@ -236,7 +234,7 @@ export class FlightClientEntryPlugin { } // Check if request is for css file. - if (isClientComponent || isCSS) { + if ((!inClientComponentBoundary && isClientComponent) || isCSS) { clientComponentImports.push(modRequest) return } @@ -244,12 +242,15 @@ export class FlightClientEntryPlugin { compilation.moduleGraph .getOutgoingConnections(mod) .forEach((connection: any) => { - filterClientComponents(connection.dependency) + filterClientComponents( + connection.dependency, + inClientComponentBoundary || isClientComponent + ) }) } // Traverse the module graph to find all client components. - filterClientComponents(dependency) + filterClientComponents(dependency, false) return [clientComponentImports, serverCSSImports] } diff --git a/packages/next/build/webpack/plugins/flight-manifest-plugin.ts b/packages/next/build/webpack/plugins/flight-manifest-plugin.ts index 2dcc2997f016..e3e721c06f8a 100644 --- a/packages/next/build/webpack/plugins/flight-manifest-plugin.ts +++ b/packages/next/build/webpack/plugins/flight-manifest-plugin.ts @@ -114,6 +114,9 @@ export class FlightManifestPlugin { const dev = this.dev compilation.chunkGroups.forEach((chunkGroup) => { + const cssResourcesInChunkGroup: string[] = [] + let entryFilepath: string = '' + function recordModule( chunk: webpack.Chunk, id: ModuleId, @@ -176,6 +179,11 @@ export class FlightManifestPlugin { } manifest.__ssr_module_mapping__ = moduleIdMapping } + + if (chunkGroup.name) { + cssResourcesInChunkGroup.push(resource) + } + return } @@ -186,6 +194,10 @@ export class FlightManifestPlugin { return } + if (/\/(page|layout)\.client\.(ts|js)x?$/.test(resource)) { + entryFilepath = resource + } + const exportsInfo = compilation.moduleGraph.getExportsInfo(mod) const cjsExports = [ ...new Set([ @@ -218,37 +230,6 @@ export class FlightManifestPlugin { ) .filter((name) => name !== null) - // Get all CSS files imported from the module's dependencies. - const visitedModule = new Set() - const cssChunks: Set = new Set() - - function collectClientImportedCss(module: any) { - if (!module) return - - const modRequest = module.userRequest - if (visitedModule.has(modRequest)) return - visitedModule.add(modRequest) - - if (/\.css$/.test(modRequest)) { - // collect relative imported css chunks - compilation.chunkGraph.getModuleChunks(module).forEach((c) => { - ;[...c.files] - .filter((file) => file.endsWith('.css')) - .forEach((file) => cssChunks.add(file)) - }) - } - - const connections = Array.from( - compilation.moduleGraph.getOutgoingConnections(module) - ) - connections.forEach((connection) => { - collectClientImportedCss( - compilation.moduleGraph.getResolvedModule(connection.dependency!) - ) - }) - } - collectClientImportedCss(mod) - moduleExportedKeys.forEach((name) => { let requiredChunks: ManifestChunks = [] if (!moduleExports[name]) { @@ -273,7 +254,7 @@ export class FlightManifestPlugin { moduleExports[name] = { id, name, - chunks: requiredChunks.concat([...cssChunks]), + chunks: requiredChunks, } } @@ -310,6 +291,12 @@ export class FlightManifestPlugin { } } }) + + const clientCSSManifest: any = manifest.__client_css_manifest__ || {} + if (entryFilepath) { + clientCSSManifest[entryFilepath] = cssResourcesInChunkGroup + } + manifest.__client_css_manifest__ = clientCSSManifest }) const file = 'server/' + FLIGHT_MANIFEST diff --git a/packages/next/client/app-index.tsx b/packages/next/client/app-index.tsx index 9d0ec8accb6f..4f148f9b74d4 100644 --- a/packages/next/client/app-index.tsx +++ b/packages/next/client/app-index.tsx @@ -32,18 +32,6 @@ self.__next_require__ = __webpack_require__ // eslint-disable-next-line no-undef ;(self as any).__next_chunk_load__ = (chunk: string) => { if (!chunk) return Promise.resolve() - if (chunk.endsWith('.css')) { - // @ts-expect-error __webpack_public_path__ is inlined by webpack - const chunkPath = `${__webpack_public_path__ || ''}${chunk}` - const existingTag = document.querySelector(`link[href="${chunkPath}"]`) - if (!existingTag) { - const link = document.createElement('link') - link.rel = 'stylesheet' - link.href = chunkPath - document.head.appendChild(link) - } - return Promise.resolve() - } const [chunkId, chunkFileName] = chunk.split(':') chunkFilenameMap[chunkId] = `static/chunks/${chunkFileName}.js` diff --git a/packages/next/server/app-render.tsx b/packages/next/server/app-render.tsx index 2c221e3e75e7..012a0682d01a 100644 --- a/packages/next/server/app-render.tsx +++ b/packages/next/server/app-render.tsx @@ -383,7 +383,9 @@ function getCssInlinedLinkTags( serverCSSManifest: FlightCSSManifest, filePath: string ): string[] { - const layoutOrPageCss = serverCSSManifest[filePath] + const layoutOrPageCss = + serverCSSManifest[filePath] || + serverComponentManifest.__client_css_manifest__?.[filePath] if (!layoutOrPageCss) { return [] diff --git a/test/e2e/app-dir/app/app/css/css-client/client-foo.css b/test/e2e/app-dir/app/app/css/css-client/client-foo.css new file mode 100644 index 000000000000..94ff8d4b4895 --- /dev/null +++ b/test/e2e/app-dir/app/app/css/css-client/client-foo.css @@ -0,0 +1,3 @@ +.foo { + color: blue; +} diff --git a/test/e2e/app-dir/app/app/css/css-client/client-layout.css b/test/e2e/app-dir/app/app/css/css-client/client-layout.css new file mode 100644 index 000000000000..5bc2906308a0 --- /dev/null +++ b/test/e2e/app-dir/app/app/css/css-client/client-layout.css @@ -0,0 +1,3 @@ +body { + background: cyan; +} diff --git a/test/e2e/app-dir/app/app/css/css-client/client-page.css b/test/e2e/app-dir/app/app/css/css-client/client-page.css new file mode 100644 index 000000000000..4b2edc961d9d --- /dev/null +++ b/test/e2e/app-dir/app/app/css/css-client/client-page.css @@ -0,0 +1,6 @@ +h1 { + color: red !important; +} +h1::after { + content: ' (from css-client!!)'; +} diff --git a/test/e2e/app-dir/app/app/css/css-client/foo.js b/test/e2e/app-dir/app/app/css/css-client/foo.js new file mode 100644 index 000000000000..98d4f855cc4e --- /dev/null +++ b/test/e2e/app-dir/app/app/css/css-client/foo.js @@ -0,0 +1,5 @@ +import './client-foo.css' + +export default function Foo() { + return foo +} diff --git a/test/e2e/app-dir/app/app/css/css-client/layout.client.js b/test/e2e/app-dir/app/app/css/css-client/layout.client.js new file mode 100644 index 000000000000..2add562cce69 --- /dev/null +++ b/test/e2e/app-dir/app/app/css/css-client/layout.client.js @@ -0,0 +1,12 @@ +import './client-layout.css' + +import Foo from './foo' + +export default function ServerLayout({ children }) { + return ( + <> + {children} + + + ) +} diff --git a/test/e2e/app-dir/app/app/css/css-client/page.client.js b/test/e2e/app-dir/app/app/css/css-client/page.client.js new file mode 100644 index 000000000000..24df05926ff9 --- /dev/null +++ b/test/e2e/app-dir/app/app/css/css-client/page.client.js @@ -0,0 +1,5 @@ +import './client-page.css' + +export default function Page() { + return

      Page!!!

      +} From 31bcd044ffbd0a145d9b93515251223d9de666a8 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 22 Aug 2022 18:36:36 -0500 Subject: [PATCH 40/64] Ensure moduleResolution is written correctly (#39836) This removes the usage of `Node12` from the `parsedValues` for `moduleResolution` as this caused false detection of `undefined` being a valid value when it was removed in TypeScript. This also copies over the test from https://github.com/vercel/next.js/pull/37302 to ensure we don't regress on this. ## Bug - [x] Related issues linked using `fixes #number` - [x] Integration tests added - [x] Errors have helpful link attached, see `contributing.md` Fixes: https://github.com/vercel/next.js/issues/37296 Closes: https://github.com/vercel/next.js/pull/37302 --- .../typescript/writeConfigurationDefaults.ts | 11 ++++- .../correct-tsconfig-defaults/index.test.ts | 41 +++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 test/development/correct-tsconfig-defaults/index.test.ts diff --git a/packages/next/lib/typescript/writeConfigurationDefaults.ts b/packages/next/lib/typescript/writeConfigurationDefaults.ts index c534f63154eb..0aad82db632f 100644 --- a/packages/next/lib/typescript/writeConfigurationDefaults.ts +++ b/packages/next/lib/typescript/writeConfigurationDefaults.ts @@ -3,10 +3,11 @@ import chalk from 'next/dist/compiled/chalk' import * as CommentJson from 'next/dist/compiled/comment-json' import semver from 'next/dist/compiled/semver' import os from 'os' +import type { CompilerOptions } from 'typescript' import { getTypeScriptConfiguration } from './getTypeScriptConfiguration' type DesiredCompilerOptionsShape = { - [key: string]: + [K in keyof CompilerOptions]: | { suggested: any } | { parsedValue?: any @@ -58,8 +59,11 @@ function getDesiredCompilerOptions( parsedValues: [ ts.ModuleResolutionKind.NodeJs, ts.ModuleResolutionKind.Node12, + // only newer TypeScript versions have this field, it + // will be filtered for older ones + (ts.ModuleResolutionKind as any).Node16, ts.ModuleResolutionKind.NodeNext, - ], + ].filter((val) => typeof val !== 'undefined'), value: 'node', reason: 'to match webpack resolution', }, @@ -86,6 +90,9 @@ export function getRequiredConfiguration( const desiredCompilerOptions = getDesiredCompilerOptions(ts) for (const optionKey of Object.keys(desiredCompilerOptions)) { const ev = desiredCompilerOptions[optionKey] + if (optionKey === 'moduleResolution') { + console.log({ optionKey, ev, current: res[optionKey] }) + } if (!('value' in ev)) { continue } diff --git a/test/development/correct-tsconfig-defaults/index.test.ts b/test/development/correct-tsconfig-defaults/index.test.ts new file mode 100644 index 000000000000..c271bd9cbb89 --- /dev/null +++ b/test/development/correct-tsconfig-defaults/index.test.ts @@ -0,0 +1,41 @@ +import { createNext } from 'e2e-utils' +import fs from 'fs' +import { waitFor } from 'next-test-utils' +import path from 'path' +import { NextInstance } from 'test/lib/next-modes/base' + +describe('correct tsconfig.json defaults', () => { + let next: NextInstance + + beforeAll(async () => { + next = await createNext({ + files: { + 'pages/index.tsx': 'export default function Page() {}', + }, + skipStart: true, + dependencies: { + typescript: 'latest', + '@types/react': 'latest', + '@types/node': 'latest', + }, + }) + }) + afterAll(() => next.destroy()) + + it('should add `moduleResoution` when generating tsconfig.json in dev', async () => { + const tsconfigPath = path.join(next.testDir, 'tsconfig.json') + expect(fs.existsSync(tsconfigPath)).toBeFalse() + + await next.start() + await waitFor(1000) + await next.stop() + + expect(fs.existsSync(tsconfigPath)).toBeTrue() + + const tsconfig = JSON.parse(await next.readFile('tsconfig.json')) + + expect(tsconfig.compilerOptions).toEqual( + expect.objectContaining({ moduleResolution: 'node' }) + ) + }) +}) From 611e13f5159457fedf96d850845650616a1f75dd Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Tue, 23 Aug 2022 02:23:43 -0500 Subject: [PATCH 41/64] Fix disposing active entries in dev compilers (#39845) As noticed in https://github.com/markdoc/markdoc/issues/131 it seems we are incorrectly disposing active entries causing HMR to fail after the configured `maxInactiveAge`. To fix this instead of only updating lastActiveTime for one compiler type's entry we update all active compiler types for the active entry. This also updates an existing test to catch this by waiting the `maxInactiveAge` before attempting a change that should trigger HMR. ## Bug - [x] Related issues linked using `fixes #number` - [x] Integration tests added - [x] Errors have helpful link attached, see `contributing.md` Fixes: https://github.com/markdoc/markdoc/issues/131 --- .../server/dev/on-demand-entry-handler.ts | 96 +++++++++++-------- .../test/index.test.ts | 6 +- 2 files changed, 62 insertions(+), 40 deletions(-) diff --git a/packages/next/server/dev/on-demand-entry-handler.ts b/packages/next/server/dev/on-demand-entry-handler.ts index 00561904706e..09570760812f 100644 --- a/packages/next/server/dev/on-demand-entry-handler.ts +++ b/packages/next/server/dev/on-demand-entry-handler.ts @@ -453,65 +453,83 @@ export function onDemandEntryHandler({ tree: FlightRouterState ): { success: true } | { invalid: true } { const pages = getEntrypointsFromTree(tree, true) + let toSend: { invalid: true } | { success: true } = { invalid: true } for (const page of pages) { - const pageKey = `server/${page}` + for (const compilerType of [ + COMPILER_NAMES.client, + COMPILER_NAMES.server, + COMPILER_NAMES.edgeServer, + ]) { + const pageKey = `${compilerType}/${page}` + const entryInfo = entries[pageKey] + + // If there's no entry, it may have been invalidated and needs to be re-built. + if (!entryInfo) { + // if (page !== lastEntry) client pings, but there's no entry for page + continue + } + + // We don't need to maintain active state of anything other than BUILT entries + if (entryInfo.status !== BUILT) continue + + // If there's an entryInfo + if (!lastServerAccessPagesForAppDir.includes(pageKey)) { + lastServerAccessPagesForAppDir.unshift(pageKey) + + // Maintain the buffer max length + // TODO: verify that the current pageKey is not at the end of the array as multiple entrypoints can exist + if (lastServerAccessPagesForAppDir.length > pagesBufferLength) { + lastServerAccessPagesForAppDir.pop() + } + } + entryInfo.lastActiveTime = Date.now() + entryInfo.dispose = false + toSend = { success: true } + } + } + return toSend + } + + function handlePing(pg: string) { + const page = normalizePathSep(pg) + let toSend: { invalid: true } | { success: true } = { invalid: true } + + for (const compilerType of [ + COMPILER_NAMES.client, + COMPILER_NAMES.server, + COMPILER_NAMES.edgeServer, + ]) { + const pageKey = `${compilerType}${page}` const entryInfo = entries[pageKey] // If there's no entry, it may have been invalidated and needs to be re-built. if (!entryInfo) { // if (page !== lastEntry) client pings, but there's no entry for page - return { invalid: true } + if (compilerType === COMPILER_NAMES.client) { + return { invalid: true } + } + continue } + // 404 is an on demand entry but when a new page is added we have to refresh the page + toSend = page === '/_error' ? { invalid: true } : { success: true } + // We don't need to maintain active state of anything other than BUILT entries if (entryInfo.status !== BUILT) continue // If there's an entryInfo - if (!lastServerAccessPagesForAppDir.includes(pageKey)) { - lastServerAccessPagesForAppDir.unshift(pageKey) + if (!lastClientAccessPages.includes(pageKey)) { + lastClientAccessPages.unshift(pageKey) // Maintain the buffer max length - // TODO: verify that the current pageKey is not at the end of the array as multiple entrypoints can exist - if (lastServerAccessPagesForAppDir.length > pagesBufferLength) { - lastServerAccessPagesForAppDir.pop() + if (lastClientAccessPages.length > pagesBufferLength) { + lastClientAccessPages.pop() } } entryInfo.lastActiveTime = Date.now() entryInfo.dispose = false } - - return { success: true } - } - - function handlePing(pg: string) { - const page = normalizePathSep(pg) - const pageKey = `client${page}` - const entryInfo = entries[pageKey] - - // If there's no entry, it may have been invalidated and needs to be re-built. - if (!entryInfo) { - // if (page !== lastEntry) client pings, but there's no entry for page - return { invalid: true } - } - - // 404 is an on demand entry but when a new page is added we have to refresh the page - const toSend = page === '/_error' ? { invalid: true } : { success: true } - - // We don't need to maintain active state of anything other than BUILT entries - if (entryInfo.status !== BUILT) return - - // If there's an entryInfo - if (!lastClientAccessPages.includes(pageKey)) { - lastClientAccessPages.unshift(pageKey) - - // Maintain the buffer max length - if (lastClientAccessPages.length > pagesBufferLength) { - lastClientAccessPages.pop() - } - } - entryInfo.lastActiveTime = Date.now() - entryInfo.dispose = false return toSend } diff --git a/test/development/basic/gssp-ssr-change-reloading/test/index.test.ts b/test/development/basic/gssp-ssr-change-reloading/test/index.test.ts index 8d8cf6d63643..072943ed482c 100644 --- a/test/development/basic/gssp-ssr-change-reloading/test/index.test.ts +++ b/test/development/basic/gssp-ssr-change-reloading/test/index.test.ts @@ -3,7 +3,7 @@ import { join } from 'path' import webdriver from 'next-webdriver' import { createNext, FileRef } from 'e2e-utils' -import { check, getRedboxHeader, hasRedbox } from 'next-test-utils' +import { check, getRedboxHeader, hasRedbox, waitFor } from 'next-test-utils' import { NextInstance } from 'test/lib/next-modes/base' const installCheckVisible = (browser) => { @@ -319,6 +319,10 @@ describe('GS(S)P Server-Side Change Reloading', () => { expect(props.count).toBe(1) expect(props.data).toEqual({ hello: 'world' }) + // wait longer than the max inactive age for on-demand entries + // to ensure we aren't incorrectly disposing the active entry + await waitFor(20 * 1000) + const page = 'lib/data.json' const originalContent = await next.readFile(page) From ca9fef6ef6c34ff83f52e367f45dafead7c735b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Born=C3=B6?= Date: Tue, 23 Aug 2022 16:15:09 +0200 Subject: [PATCH 42/64] Docs: Updated note about using next/head in basic-features/font-optimization (#39863) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm lint` - [ ] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples) --- docs/basic-features/font-optimization.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/basic-features/font-optimization.md b/docs/basic-features/font-optimization.md index bcd1498072fa..139a09b32d5d 100644 --- a/docs/basic-features/font-optimization.md +++ b/docs/basic-features/font-optimization.md @@ -53,7 +53,13 @@ class MyDocument extends Document { export default MyDocument ``` -Note that we don't recommend adding fonts with `next/head`, as this only applies the font to the particular page and won't work with a streaming architecture. +Although it's possible to add fonts in a page with [`next/head`](/docs/api-reference/next/head) it comes with some drawbacks: + +- It only applies the font to that particular page. +- The font optimization will only work on page load, not on client side navigation. +- It won't work with a streaming architecture. + +Thus it's highly recommended to add the font in a [Custom `Document`](/docs/advanced-features/custom-document.md), like in the code snippet above. Automatic Webfont Optimization currently supports Google Fonts and Typekit with support for other font providers coming soon. We're also planning to add control over [loading strategies](https://github.com/vercel/next.js/issues/21555) and `font-display` values. From 16838d5dd46f3abad5fc1c61e4f8232d96a0f25c Mon Sep 17 00:00:00 2001 From: Henrik Wenz Date: Tue, 23 Aug 2022 16:23:38 +0200 Subject: [PATCH 43/64] [Docs] Migrate data-fetch example to typescript (#39852) ## Changelog - Updated deps - Migrated to Typescript - Replaced `div` with `Fragment` ## Documentation / Examples - [x] Make sure the linting passes by running `pnpm lint` - [x] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples) --- examples/data-fetch/package.json | 11 +++++-- .../data-fetch/pages/{index.js => index.tsx} | 31 ++++++++++--------- .../{preact-stars.js => preact-stars.tsx} | 29 ++++++++--------- examples/data-fetch/tsconfig.json | 19 ++++++++++++ examples/data-fetch/types/github.d.ts | 10 ++++++ 5 files changed, 68 insertions(+), 32 deletions(-) rename examples/data-fetch/pages/{index.js => index.tsx} (52%) rename examples/data-fetch/pages/{preact-stars.js => preact-stars.tsx} (57%) create mode 100644 examples/data-fetch/tsconfig.json create mode 100644 examples/data-fetch/types/github.d.ts diff --git a/examples/data-fetch/package.json b/examples/data-fetch/package.json index 349de02f4d84..6d7b78181046 100644 --- a/examples/data-fetch/package.json +++ b/examples/data-fetch/package.json @@ -6,8 +6,13 @@ "start": "next start" }, "dependencies": { - "next": "latest", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "next": "12.2.5", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@types/node": "18.7.11", + "@types/react": "18.0.17", + "typescript": "4.7.4" } } diff --git a/examples/data-fetch/pages/index.js b/examples/data-fetch/pages/index.tsx similarity index 52% rename from examples/data-fetch/pages/index.js rename to examples/data-fetch/pages/index.tsx index d668c07e8fd6..a85b350fab30 100644 --- a/examples/data-fetch/pages/index.js +++ b/examples/data-fetch/pages/index.tsx @@ -1,25 +1,26 @@ import Link from 'next/link' - -function Index({ stars }) { - return ( -
      -

      Next.js has {stars} ⭐️

      - - How about preact? - -
      - ) -} +import type { InferGetStaticPropsType } from 'next' +import type { Repository } from '../types/github' export async function getStaticProps() { const res = await fetch('https://api.github.com/repos/vercel/next.js') - const json = await res.json() - + const data: Repository = await res.json() return { props: { - stars: json.stargazers_count, + stars: data.stargazers_count, }, } } -export default Index +export default function IndexPage({ + stars, +}: InferGetStaticPropsType) { + return ( + <> +

      Next.js has {stars} ⭐️

      + + How about preact? + + + ) +} diff --git a/examples/data-fetch/pages/preact-stars.js b/examples/data-fetch/pages/preact-stars.tsx similarity index 57% rename from examples/data-fetch/pages/preact-stars.js rename to examples/data-fetch/pages/preact-stars.tsx index 9039129474ed..f7e7f70e3978 100644 --- a/examples/data-fetch/pages/preact-stars.js +++ b/examples/data-fetch/pages/preact-stars.tsx @@ -1,20 +1,10 @@ import Link from 'next/link' - -function PreactStars({ stars }) { - return ( -
      -

      Preact has {stars} ⭐

      - - I bet Next.js has more stars (?) - -
      - ) -} +import type { InferGetStaticPropsType } from 'next' +import type { Repository } from '../types/github' export async function getStaticProps() { const res = await fetch('https://api.github.com/repos/preactjs/preact') - const json = await res.json() - + const json: Repository = await res.json() return { props: { stars: json.stargazers_count, @@ -22,4 +12,15 @@ export async function getStaticProps() { } } -export default PreactStars +export default function PreactStarsPage({ + stars, +}: InferGetStaticPropsType) { + return ( + <> +

      Preact has {stars} ⭐

      + + I bet Next.js has more stars (?) + + + ) +} diff --git a/examples/data-fetch/tsconfig.json b/examples/data-fetch/tsconfig.json new file mode 100644 index 000000000000..93a83a407c40 --- /dev/null +++ b/examples/data-fetch/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": false, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve" + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} diff --git a/examples/data-fetch/types/github.d.ts b/examples/data-fetch/types/github.d.ts new file mode 100644 index 000000000000..1d373d98bc27 --- /dev/null +++ b/examples/data-fetch/types/github.d.ts @@ -0,0 +1,10 @@ +// For simplicity we are creating our own types here. +// If you want the full types check out: +// https://github.com/octokit/openapi-types.ts +export type Repository = { + id: number + name: string + full_name: string + stargazers_count: number + private: boolean +} & Record From cb430cce90ec7120dbc6e0e1020a3f42c4b901a4 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Tue, 23 Aug 2022 09:29:24 -0500 Subject: [PATCH 44/64] v12.2.6-canary.2 --- 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/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 | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- 16 files changed, 29 insertions(+), 29 deletions(-) diff --git a/lerna.json b/lerna.json index 3029b293b96b..b05277fca861 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "12.2.6-canary.1" + "version": "12.2.6-canary.2" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index ffb25ddc54fc..87af8d4630ff 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "12.2.6-canary.1", + "version": "12.2.6-canary.2", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 0d83e86e781a..a63ee538edb1 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "12.2.6-canary.1", + "version": "12.2.6-canary.2", "description": "ESLint configuration used by NextJS.", "main": "index.js", "license": "MIT", @@ -9,7 +9,7 @@ "directory": "packages/eslint-config-next" }, "dependencies": { - "@next/eslint-plugin-next": "12.2.6-canary.1", + "@next/eslint-plugin-next": "12.2.6-canary.2", "@rushstack/eslint-patch": "^1.1.3", "@typescript-eslint/parser": "^5.21.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 2bfbfd69656c..4da94c63594d 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": "12.2.6-canary.1", + "version": "12.2.6-canary.2", "description": "ESLint plugin for NextJS.", "main": "lib/index.js", "license": "MIT", diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 0ea4c98bcc07..0285ba5e4c5f 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "12.2.6-canary.1", + "version": "12.2.6-canary.2", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 24bec552bb71..192f17c55657 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "12.2.6-canary.1", + "version": "12.2.6-canary.2", "license": "MIT", "dependencies": { "chalk": "4.1.0", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 93ce11156ec0..fabac3120cfb 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "12.2.6-canary.1", + "version": "12.2.6-canary.2", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index a7bdaede5cb4..c09c169d04d2 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "12.2.6-canary.1", + "version": "12.2.6-canary.2", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 6456f3b3ebe2..fc72351336cd 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "12.2.6-canary.1", + "version": "12.2.6-canary.2", "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 3877410e0889..76871108f50d 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "12.2.6-canary.1", + "version": "12.2.6-canary.2", "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 d72c16d23696..e66a22894050 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "12.2.6-canary.1", + "version": "12.2.6-canary.2", "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 ee043fbf5d7d..20cc3c60fc07 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "12.2.6-canary.1", + "version": "12.2.6-canary.2", "private": true, "scripts": { "build-native": "napi build --platform -p next-swc-napi --cargo-name next_swc_napi native --features plugin", diff --git a/packages/next/package.json b/packages/next/package.json index 91f730ba99b7..6507ff9f3ada 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "12.2.6-canary.1", + "version": "12.2.6-canary.2", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -70,7 +70,7 @@ ] }, "dependencies": { - "@next/env": "12.2.6-canary.1", + "@next/env": "12.2.6-canary.2", "@swc/helpers": "0.4.3", "caniuse-lite": "^1.0.30001332", "postcss": "8.4.14", @@ -121,11 +121,11 @@ "@hapi/accept": "5.0.2", "@napi-rs/cli": "2.7.0", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "12.2.6-canary.1", - "@next/polyfill-nomodule": "12.2.6-canary.1", - "@next/react-dev-overlay": "12.2.6-canary.1", - "@next/react-refresh-utils": "12.2.6-canary.1", - "@next/swc": "12.2.6-canary.1", + "@next/polyfill-module": "12.2.6-canary.2", + "@next/polyfill-nomodule": "12.2.6-canary.2", + "@next/react-dev-overlay": "12.2.6-canary.2", + "@next/react-refresh-utils": "12.2.6-canary.2", + "@next/swc": "12.2.6-canary.2", "@segment/ajv-human-errors": "2.1.2", "@taskr/clear": "1.1.0", "@taskr/esnext": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index ee8baf02a894..d9f78c9e2300 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "12.2.6-canary.1", + "version": "12.2.6-canary.2", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index ab88cee6c1f6..285d25ed7974 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": "12.2.6-canary.1", + "version": "12.2.6-canary.2", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9485aee0ec1e..55a283d0b290 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -364,7 +364,7 @@ importers: packages/eslint-config-next: specifiers: - '@next/eslint-plugin-next': 12.2.6-canary.1 + '@next/eslint-plugin-next': 12.2.6-canary.2 '@rushstack/eslint-patch': ^1.1.3 '@typescript-eslint/parser': ^5.21.0 eslint-import-resolver-node: ^0.3.6 @@ -420,12 +420,12 @@ importers: '@hapi/accept': 5.0.2 '@napi-rs/cli': 2.7.0 '@napi-rs/triples': 1.1.0 - '@next/env': 12.2.6-canary.1 - '@next/polyfill-module': 12.2.6-canary.1 - '@next/polyfill-nomodule': 12.2.6-canary.1 - '@next/react-dev-overlay': 12.2.6-canary.1 - '@next/react-refresh-utils': 12.2.6-canary.1 - '@next/swc': 12.2.6-canary.1 + '@next/env': 12.2.6-canary.2 + '@next/polyfill-module': 12.2.6-canary.2 + '@next/polyfill-nomodule': 12.2.6-canary.2 + '@next/react-dev-overlay': 12.2.6-canary.2 + '@next/react-refresh-utils': 12.2.6-canary.2 + '@next/swc': 12.2.6-canary.2 '@segment/ajv-human-errors': 2.1.2 '@swc/helpers': 0.4.3 '@taskr/clear': 1.1.0 From 8dfab19d6ede702925340e048649450176d349c9 Mon Sep 17 00:00:00 2001 From: Sukka Date: Wed, 24 Aug 2022 02:06:44 +0800 Subject: [PATCH 45/64] fix(#39807): ignore width/height from webpack with "fill" (#39849) Fixes #39807. When statically importing an image, the `width` and `height` will always be provided alongside the `src` by the Webpack. `next/image` will ignore `width` and `height` come from Webpack when `layout === 'fill'`, while `next/future/image` will not, hence the issue. The PR fixes that. The corresponding integration test cases are also added. cc @styfle ## Bug - [x] Related issues linked using `fixes #number` - [x] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` --- packages/next/client/future/image.tsx | 7 +- .../image-future/default/pages/static-img.js | 4 + .../image-future/default/test/static.test.ts | 112 ++++++++++++------ 3 files changed, 82 insertions(+), 41 deletions(-) diff --git a/packages/next/client/future/image.tsx b/packages/next/client/future/image.tsx index 4ca2d06ec3c5..f3ffe5b7033e 100644 --- a/packages/next/client/future/image.tsx +++ b/packages/next/client/future/image.tsx @@ -591,8 +591,11 @@ export default function Image({ blurDataURL = blurDataURL || staticImageData.blurDataURL staticSrc = staticImageData.src - height = height || staticImageData.height - width = width || staticImageData.width + // Ignore width and height (come from the bundler) when "fill" is used + if (!fill) { + height = height || staticImageData.height + width = width || staticImageData.width + } if (!staticImageData.height || !staticImageData.width) { throw new Error( `An object should only be passed to the image component src parameter if it comes from a static image import. It must include height and width. Received ${JSON.stringify( diff --git a/test/integration/image-future/default/pages/static-img.js b/test/integration/image-future/default/pages/static-img.js index d5ce76c12898..6b6b4cfd5739 100644 --- a/test/integration/image-future/default/pages/static-img.js +++ b/test/integration/image-future/default/pages/static-img.js @@ -36,6 +36,10 @@ const Page = () => { + + + +
    diff --git a/test/integration/image-future/default/test/static.test.ts b/test/integration/image-future/default/test/static.test.ts index 7e02bf407b2b..e40d548ba17d 100644 --- a/test/integration/image-future/default/test/static.test.ts +++ b/test/integration/image-future/default/test/static.test.ts @@ -6,6 +6,7 @@ import { renderViaHTTP, File, waitFor, + launchApp, } from 'next-test-utils' import webdriver from 'next-webdriver' import { join } from 'path' @@ -18,7 +19,7 @@ let html const indexPage = new File(join(appDir, 'pages/static-img.js')) -const runTests = () => { +const runTests = (isDev = false) => { it('Should allow an image with a static src to omit height and width', async () => { expect(await browser.elementById('basic-static')).toBeTruthy() expect(await browser.elementById('blur-png')).toBeTruthy() @@ -29,44 +30,62 @@ const runTests = () => { expect(await browser.elementById('static-gif')).toBeTruthy() expect(await browser.elementById('static-bmp')).toBeTruthy() expect(await browser.elementById('static-ico')).toBeTruthy() + expect(await browser.elementById('static-svg-fill')).toBeTruthy() + expect(await browser.elementById('static-gif-fill')).toBeTruthy() + expect(await browser.elementById('static-bmp-fill')).toBeTruthy() + expect(await browser.elementById('static-ico-fill')).toBeTruthy() expect(await browser.elementById('static-unoptimized')).toBeTruthy() }) - it('Should use immutable cache-control header for static import', async () => { - await browser.eval( - `document.getElementById("basic-static").scrollIntoView()` - ) - await waitFor(1000) - const url = await browser.eval( - `document.getElementById("basic-static").src` - ) - const res = await fetch(url) - expect(res.headers.get('cache-control')).toBe( - 'public, max-age=315360000, immutable' - ) - }) - it('Should use immutable cache-control header even when unoptimized', async () => { - await browser.eval( - `document.getElementById("static-unoptimized").scrollIntoView()` - ) - await waitFor(1000) - const url = await browser.eval( - `document.getElementById("static-unoptimized").src` - ) - const res = await fetch(url) - expect(res.headers.get('cache-control')).toBe( - 'public, max-age=31536000, immutable' - ) - }) + + if (!isDev) { + // cache-control is set to "0, no-store" in dev mode + it('Should use immutable cache-control header for static import', async () => { + await browser.eval( + `document.getElementById("basic-static").scrollIntoView()` + ) + await waitFor(1000) + const url = await browser.eval( + `document.getElementById("basic-static").src` + ) + const res = await fetch(url) + expect(res.headers.get('cache-control')).toBe( + 'public, max-age=315360000, immutable' + ) + }) + + it('Should use immutable cache-control header even when unoptimized', async () => { + await browser.eval( + `document.getElementById("static-unoptimized").scrollIntoView()` + ) + await waitFor(1000) + const url = await browser.eval( + `document.getElementById("static-unoptimized").src` + ) + const res = await fetch(url) + expect(res.headers.get('cache-control')).toBe( + 'public, max-age=31536000, immutable' + ) + }) + } it('Should automatically provide an image height and width', async () => { expect(html).toContain('width="400" height="300"') }) it('Should allow provided width and height to override intrinsic', async () => { expect(html).toContain('width="150" height="150"') }) + it('Should add a blur to a statically imported image in "raw" mode', async () => { - expect(html).toContain( - `style="background-size:cover;background-position:0% 0%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='50'/%3E%3C/filter%3E%3Cimage filter='url(%23b)' x='0' y='0' height='100%25' width='100%25' href='data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoKCgoKCgsMDAsPEA4QDxYUExMUFiIYGhgaGCIzICUgICUgMy03LCksNy1RQDg4QFFeT0pPXnFlZXGPiI+7u/sBCgoKCgoKCwwMCw8QDhAPFhQTExQWIhgaGBoYIjMgJSAgJSAzLTcsKSw3LVFAODhAUV5PSk9ecWVlcY+Ij7u7+//CABEIAAYACAMBIgACEQEDEQH/xAAnAAEBAAAAAAAAAAAAAAAAAAAABwEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAAmgP/xAAcEAACAQUBAAAAAAAAAAAAAAASFBMAAQMFERX/2gAIAQEAAT8AZ1HjrKZX55JysIc4Ff/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Af//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Af//Z'/%3E%3C/svg%3E")` - ) + // next-image-loader uses different blur behavior for dev/prod mode + // See next/build/webpack/loaders/next-image-loader + if (isDev) { + expect(html).toContain( + `style="background-size:cover;background-position:0% 0%;filter:blur(20px);background-image:url("/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest-rect.f323a148.jpg&w=8&q=70")"` + ) + } else { + expect(html).toContain( + `style="background-size:cover;background-position:0% 0%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='50'/%3E%3C/filter%3E%3Cimage filter='url(%23b)' x='0' y='0' height='100%25' width='100%25' href='data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoKCgoKCgsMDAsPEA4QDxYUExMUFiIYGhgaGCIzICUgICUgMy03LCksNy1RQDg4QFFeT0pPXnFlZXGPiI+7u/sBCgoKCgoKCwwMCw8QDhAPFhQTExQWIhgaGBoYIjMgJSAgJSAzLTcsKSw3LVFAODhAUV5PSk9ecWVlcY+Ij7u7+//CABEIAAYACAMBIgACEQEDEQH/xAAnAAEBAAAAAAAAAAAAAAAAAAAABwEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAAAmgP/xAAcEAACAQUBAAAAAAAAAAAAAAASFBMAAQMFERX/2gAIAQEAAT8AZ1HjrKZX55JysIc4Ff/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Af//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Af//Z'/%3E%3C/svg%3E")` + ) + } }) } @@ -90,15 +109,30 @@ describe('Build Error Tests', () => { }) }) describe('Future Static Image Component Tests', () => { - beforeAll(async () => { - await nextBuild(appDir) - appPort = await findPort() - app = await nextStart(appDir, appPort) - html = await renderViaHTTP(appPort, '/static-img') - browser = await webdriver(appPort, '/static-img') + describe('production mode', () => { + beforeAll(async () => { + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + html = await renderViaHTTP(appPort, '/static-img') + browser = await webdriver(appPort, '/static-img') + }) + afterAll(() => { + killApp(app) + }) + runTests(false) }) - afterAll(() => { - killApp(app) + + describe('dev mode', () => { + beforeAll(async () => { + appPort = await findPort() + app = await launchApp(appDir, appPort) + html = await renderViaHTTP(appPort, '/static-img') + browser = await webdriver(appPort, '/static-img') + }) + afterAll(() => { + killApp(app) + }) + runTests(true) }) - runTests() }) From ec25b4742b1087e76f2b3378d41a8ab0f6686ca4 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Tue, 23 Aug 2022 13:16:47 -0500 Subject: [PATCH 46/64] Add handling for auto installing TypeScript deps and HMRing tsconfig (#39838) This adds handling for auto-detecting TypeScript being added to a project and installing the necessary dependencies instead of printing the command and requiring the user run the command. We have been testing the auto install handling for a while now with the `next lint` command and it has worked out pretty well. This also adds HMR handling for `jsconfig.json`/`tsconfig.json` in development so if the `baseURL` or `paths` configs are modified it doesn't require a dev server restart for the updates to be picked up. This also corrects our required dependencies detection as previously an incorrect `paths: []` value was being passed to `require.resolve` causing it to fail in specific situations. Closes: https://github.com/vercel/next.js/issues/36201 ### `next build` before https://user-images.githubusercontent.com/22380829/186039578-75f8c128-a13d-4e07-b5da-13bf186ee011.mp4 ### `next build` after https://user-images.githubusercontent.com/22380829/186039662-57af22a4-da5c-4ede-94ea-96541a032cca.mp4 ### `next dev` automatic setup and HMR handling https://user-images.githubusercontent.com/22380829/186039678-d78469ef-d00b-4ee6-8163-a4706394a7b4.mp4 ## Bug - [x] Related issues linked using `fixes #number` - [x] Integration tests added - [x] Errors have helpful link attached, see `contributing.md` --- packages/create-next-app/helpers/install.ts | 9 +- packages/next/build/index.ts | 6 +- packages/next/build/load-jsconfig.ts | 10 +- packages/next/build/webpack-config.ts | 34 +--- .../webpack/plugins/jsconfig-paths-plugin.ts | 24 ++- .../next/lib/has-necessary-dependencies.ts | 51 +++-- packages/next/lib/helpers/install.ts | 9 +- packages/next/lib/resolve-from.ts | 55 +++++ .../lib/typescript/missingDependencyError.ts | 43 ---- packages/next/lib/verifyTypeScriptSetup.ts | 58 ++++-- packages/next/server/dev/next-dev-server.ts | 190 ++++++++++++++---- .../app/components/button-1.js | 3 + .../app/components/button-2.js | 3 + .../app/components/button-3.js | 3 + .../jsconfig-path-reloading/app/jsconfig.json | 26 +++ .../app/lib/first-lib/first-data.js | 3 + .../app/lib/second-lib/second-data.js | 3 + .../app/pages/index.js | 13 ++ .../jsconfig-path-reloading/index.test.ts | 190 ++++++++++++++++++ .../app/components/button-1.tsx | 3 + .../app/components/button-2.tsx | 3 + .../app/components/button-3.tsx | 3 + .../app/lib/first-lib/first-data.ts | 3 + .../app/lib/second-lib/second-data.ts | 3 + .../app/pages/index.tsx | 13 ++ .../tsconfig-path-reloading/app/tsconfig.json | 26 +++ .../tsconfig-path-reloading/index.test.ts | 190 ++++++++++++++++++ .../typescript-auto-install/index.test.ts | 61 ++++++ .../app/node_modules/typescript/index.js | 5 - .../node_modules/typescript/lib/typescript.js | 5 + .../app/node_modules/typescript/package.json | 2 +- .../app/tsconfig.json | 3 +- .../test/index.test.js | 2 +- .../missing-dep-error/index.test.ts | 28 --- 34 files changed, 886 insertions(+), 197 deletions(-) create mode 100644 packages/next/lib/resolve-from.ts delete mode 100644 packages/next/lib/typescript/missingDependencyError.ts create mode 100644 test/development/jsconfig-path-reloading/app/components/button-1.js create mode 100644 test/development/jsconfig-path-reloading/app/components/button-2.js create mode 100644 test/development/jsconfig-path-reloading/app/components/button-3.js create mode 100644 test/development/jsconfig-path-reloading/app/jsconfig.json create mode 100644 test/development/jsconfig-path-reloading/app/lib/first-lib/first-data.js create mode 100644 test/development/jsconfig-path-reloading/app/lib/second-lib/second-data.js create mode 100644 test/development/jsconfig-path-reloading/app/pages/index.js create mode 100644 test/development/jsconfig-path-reloading/index.test.ts create mode 100644 test/development/tsconfig-path-reloading/app/components/button-1.tsx create mode 100644 test/development/tsconfig-path-reloading/app/components/button-2.tsx create mode 100644 test/development/tsconfig-path-reloading/app/components/button-3.tsx create mode 100644 test/development/tsconfig-path-reloading/app/lib/first-lib/first-data.ts create mode 100644 test/development/tsconfig-path-reloading/app/lib/second-lib/second-data.ts create mode 100644 test/development/tsconfig-path-reloading/app/pages/index.tsx create mode 100644 test/development/tsconfig-path-reloading/app/tsconfig.json create mode 100644 test/development/tsconfig-path-reloading/index.test.ts create mode 100644 test/development/typescript-auto-install/index.test.ts delete mode 100644 test/integration/typescript-version-warning/app/node_modules/typescript/index.js create mode 100644 test/integration/typescript-version-warning/app/node_modules/typescript/lib/typescript.js delete mode 100644 test/production/missing-dep-error/index.test.ts diff --git a/packages/create-next-app/helpers/install.ts b/packages/create-next-app/helpers/install.ts index 8a36345297ac..4cac7d9747f5 100644 --- a/packages/create-next-app/helpers/install.ts +++ b/packages/create-next-app/helpers/install.ts @@ -95,7 +95,14 @@ export function install( */ const child = spawn(command, args, { stdio: 'inherit', - env: { ...process.env, ADBLOCK: '1', DISABLE_OPENCOLLECTIVE: '1' }, + env: { + ...process.env, + ADBLOCK: '1', + // we set NODE_ENV to development as pnpm skips dev + // dependencies when production + NODE_ENV: 'development', + DISABLE_OPENCOLLECTIVE: '1', + }, }) child.on('close', (code) => { if (code !== 0) { diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index e07653513653..5b1980ef2975 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -187,14 +187,14 @@ function verifyTypeScriptSetup( typeCheckWorker.getStderr().pipe(process.stderr) return typeCheckWorker - .verifyTypeScriptSetup( + .verifyTypeScriptSetup({ dir, intentDirs, typeCheckPreflight, tsconfigPath, disableStaticImages, - cacheDir - ) + cacheDir, + }) .then((result) => { typeCheckWorker.end() return result diff --git a/packages/next/build/load-jsconfig.ts b/packages/next/build/load-jsconfig.ts index aa775327fc94..7dac1bab01bb 100644 --- a/packages/next/build/load-jsconfig.ts +++ b/packages/next/build/load-jsconfig.ts @@ -5,6 +5,7 @@ import * as Log from './output/log' import { getTypeScriptConfiguration } from '../lib/typescript/getTypeScriptConfiguration' import { readFileSync } from 'fs' import isError from '../lib/is-error' +import { hasNecessaryDependencies } from '../lib/has-necessary-dependencies' let TSCONFIG_WARNED = false @@ -42,7 +43,14 @@ export default async function loadJsConfig( ) { let typeScriptPath: string | undefined try { - typeScriptPath = require.resolve('typescript', { paths: [dir] }) + const deps = await hasNecessaryDependencies(dir, [ + { + pkg: 'typescript', + file: 'typescript/lib/typescript.js', + exportsRestrict: true, + }, + ]) + typeScriptPath = deps.resolved.get('typescript') } catch (_) {} const tsConfigPath = path.join(dir, config.typescript.tsconfigPath) const useTypeScript = Boolean( diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index 646fb93e2eca..581cec0af01e 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -531,10 +531,7 @@ export default async function getBaseWebpackConfig( const isClient = compilerType === COMPILER_NAMES.client const isEdgeServer = compilerType === COMPILER_NAMES.edgeServer const isNodeServer = compilerType === COMPILER_NAMES.server - const { useTypeScript, jsConfig, resolvedBaseUrl } = await loadJsConfig( - dir, - config - ) + const { jsConfig, resolvedBaseUrl } = await loadJsConfig(dir, config) const supportedBrowsers = await getSupportedBrowsers(dir, dev, config) @@ -832,22 +829,8 @@ export default async function getBaseWebpackConfig( const resolveConfig = { // Disable .mjs for node_modules bundling extensions: isNodeServer - ? [ - '.js', - '.mjs', - ...(useTypeScript ? ['.tsx', '.ts'] : []), - '.jsx', - '.json', - '.wasm', - ] - : [ - '.mjs', - '.js', - ...(useTypeScript ? ['.tsx', '.ts'] : []), - '.jsx', - '.json', - '.wasm', - ], + ? ['.js', '.mjs', '.tsx', '.ts', '.jsx', '.json', '.wasm'] + : ['.mjs', '.js', '.tsx', '.ts', '.jsx', '.json', '.wasm'], modules: [ 'node_modules', ...nodePathList, // Support for NODE_PATH environment variable @@ -1831,11 +1814,14 @@ export default async function getBaseWebpackConfig( webpackConfig.resolve?.modules?.push(resolvedBaseUrl) } - if (jsConfig?.compilerOptions?.paths && resolvedBaseUrl) { - webpackConfig.resolve?.plugins?.unshift( - new JsConfigPathsPlugin(jsConfig.compilerOptions.paths, resolvedBaseUrl) + // allows add JsConfigPathsPlugin to allow hot-reloading + // if the config is added/removed + webpackConfig.resolve?.plugins?.unshift( + new JsConfigPathsPlugin( + jsConfig?.compilerOptions?.paths || {}, + resolvedBaseUrl || dir ) - } + ) const webpack5Config = webpackConfig as webpack.Configuration diff --git a/packages/next/build/webpack/plugins/jsconfig-paths-plugin.ts b/packages/next/build/webpack/plugins/jsconfig-paths-plugin.ts index 287a07ffb782..25b73740cdd4 100644 --- a/packages/next/build/webpack/plugins/jsconfig-paths-plugin.ts +++ b/packages/next/build/webpack/plugins/jsconfig-paths-plugin.ts @@ -169,23 +169,16 @@ type Paths = { [match: string]: string[] } export class JsConfigPathsPlugin implements webpack.ResolvePluginInstance { paths: Paths resolvedBaseUrl: string + jsConfigPlugin: true + constructor(paths: Paths, resolvedBaseUrl: string) { this.paths = paths this.resolvedBaseUrl = resolvedBaseUrl + this.jsConfigPlugin = true log('tsconfig.json or jsconfig.json paths: %O', paths) log('resolved baseUrl: %s', resolvedBaseUrl) } apply(resolver: any) { - const paths = this.paths - const pathsKeys = Object.keys(paths) - - // If no aliases are added bail out - if (pathsKeys.length === 0) { - log('paths are empty, bailing out') - return - } - - const baseDirectory = this.resolvedBaseUrl const target = resolver.ensureHook('resolve') resolver .getHook('described-resolve') @@ -196,6 +189,15 @@ export class JsConfigPathsPlugin implements webpack.ResolvePluginInstance { resolveContext: any, callback: (err?: any, result?: any) => void ) => { + const paths = this.paths + const pathsKeys = Object.keys(paths) + + // If no aliases are added bail out + if (pathsKeys.length === 0) { + log('paths are empty, bailing out') + return callback() + } + const moduleName = request.request // Exclude node_modules from paths support (speeds up resolving) @@ -246,7 +248,7 @@ export class JsConfigPathsPlugin implements webpack.ResolvePluginInstance { // try next path candidate return pathCallback() } - const candidate = path.join(baseDirectory, curPath) + const candidate = path.join(this.resolvedBaseUrl, curPath) const obj = Object.assign({}, request, { request: candidate, }) diff --git a/packages/next/lib/has-necessary-dependencies.ts b/packages/next/lib/has-necessary-dependencies.ts index 10c3bd67f92d..5b81a859d2ac 100644 --- a/packages/next/lib/has-necessary-dependencies.ts +++ b/packages/next/lib/has-necessary-dependencies.ts @@ -1,5 +1,7 @@ -import { existsSync } from 'fs' -import { join, relative } from 'path' +import { promises as fs } from 'fs' +import { fileExists } from './file-exists' +import { resolveFrom } from './resolve-from' +import { dirname, join, relative } from 'path' export interface MissingDependency { file: string @@ -17,31 +19,36 @@ export async function hasNecessaryDependencies( requiredPackages: MissingDependency[] ): Promise { let resolutions = new Map() - const missingPackages = requiredPackages.filter((p) => { - try { - if (p.exportsRestrict) { - const pkgPath = require.resolve(`${p.pkg}/package.json`, { - paths: [baseDir], - }) - const fileNameToVerify = relative(p.pkg, p.file) - if (fileNameToVerify) { - const fileToVerify = join(pkgPath, '..', fileNameToVerify) - if (existsSync(fileToVerify)) { - resolutions.set(p.pkg, join(pkgPath, '..')) + const missingPackages: MissingDependency[] = [] + + await Promise.all( + requiredPackages.map(async (p) => { + try { + const pkgPath = await fs.realpath( + resolveFrom(baseDir, `${p.pkg}/package.json`) + ) + const pkgDir = dirname(pkgPath) + + if (p.exportsRestrict) { + const fileNameToVerify = relative(p.pkg, p.file) + if (fileNameToVerify) { + const fileToVerify = join(pkgDir, fileNameToVerify) + if (await fileExists(fileToVerify)) { + resolutions.set(p.pkg, fileToVerify) + } else { + return missingPackages.push(p) + } } else { - return true + resolutions.set(p.pkg, pkgPath) } } else { - resolutions.set(p.pkg, pkgPath) + resolutions.set(p.pkg, resolveFrom(baseDir, p.file)) } - } else { - resolutions.set(p.pkg, require.resolve(p.file, { paths: [baseDir] })) + } catch (_) { + return missingPackages.push(p) } - return false - } catch (_) { - return true - } - }) + }) + ) return { resolved: resolutions, diff --git a/packages/next/lib/helpers/install.ts b/packages/next/lib/helpers/install.ts index f6d252a0b43f..a0108c58b1e4 100644 --- a/packages/next/lib/helpers/install.ts +++ b/packages/next/lib/helpers/install.ts @@ -95,7 +95,14 @@ export function install( */ const child = spawn(command, args, { stdio: 'inherit', - env: { ...process.env, ADBLOCK: '1', DISABLE_OPENCOLLECTIVE: '1' }, + env: { + ...process.env, + ADBLOCK: '1', + // we set NODE_ENV to development as pnpm skips dev + // dependencies when production + NODE_ENV: 'development', + DISABLE_OPENCOLLECTIVE: '1', + }, }) child.on('close', (code) => { if (code !== 0) { diff --git a/packages/next/lib/resolve-from.ts b/packages/next/lib/resolve-from.ts new file mode 100644 index 000000000000..503690ab81e1 --- /dev/null +++ b/packages/next/lib/resolve-from.ts @@ -0,0 +1,55 @@ +// source: https://github.com/sindresorhus/resolve-from +import fs from 'fs' +import path from 'path' +import isError from './is-error' + +const Module = require('module') + +export const resolveFrom = ( + fromDirectory: string, + moduleId: string, + silent?: boolean +) => { + if (typeof fromDirectory !== 'string') { + throw new TypeError( + `Expected \`fromDir\` to be of type \`string\`, got \`${typeof fromDirectory}\`` + ) + } + + if (typeof moduleId !== 'string') { + throw new TypeError( + `Expected \`moduleId\` to be of type \`string\`, got \`${typeof moduleId}\`` + ) + } + + try { + fromDirectory = fs.realpathSync(fromDirectory) + } catch (error: unknown) { + if (isError(error) && error.code === 'ENOENT') { + fromDirectory = path.resolve(fromDirectory) + } else if (silent) { + return + } else { + throw error + } + } + + const fromFile = path.join(fromDirectory, 'noop.js') + + const resolveFileName = () => + Module._resolveFilename(moduleId, { + id: fromFile, + filename: fromFile, + paths: Module._nodeModulePaths(fromDirectory), + }) + + if (silent) { + try { + return resolveFileName() + } catch (error) { + return + } + } + + return resolveFileName() +} diff --git a/packages/next/lib/typescript/missingDependencyError.ts b/packages/next/lib/typescript/missingDependencyError.ts deleted file mode 100644 index 49c21d99d07a..000000000000 --- a/packages/next/lib/typescript/missingDependencyError.ts +++ /dev/null @@ -1,43 +0,0 @@ -import chalk from 'next/dist/compiled/chalk' - -import { getOxfordCommaList } from '../oxford-comma-list' -import { MissingDependency } from '../has-necessary-dependencies' -import { FatalError } from '../fatal-error' -import { getPkgManager } from '../helpers/get-pkg-manager' - -export async function missingDepsError( - dir: string, - missingPackages: MissingDependency[] -) { - const packagesHuman = getOxfordCommaList(missingPackages.map((p) => p.pkg)) - const packagesCli = missingPackages.map((p) => p.pkg).join(' ') - const packageManager = getPkgManager(dir) - - const removalMsg = - '\n\n' + - chalk.bold( - 'If you are not trying to use TypeScript, please remove the ' + - chalk.cyan('tsconfig.json') + - ' file from your package root (and any TypeScript files in your pages directory).' - ) - - throw new FatalError( - chalk.bold.red( - `It looks like you're trying to use TypeScript but do not have the required package(s) installed.` - ) + - '\n\n' + - chalk.bold(`Please install ${chalk.bold(packagesHuman)} by running:`) + - '\n\n' + - `\t${chalk.bold.cyan( - (packageManager === 'yarn' - ? 'yarn add --dev' - : packageManager === 'pnpm' - ? 'pnpm install --save-dev' - : 'npm install --save-dev') + - ' ' + - packagesCli - )}` + - removalMsg + - '\n' - ) -} diff --git a/packages/next/lib/verifyTypeScriptSetup.ts b/packages/next/lib/verifyTypeScriptSetup.ts index 9062e2e278ba..9f06333166a3 100644 --- a/packages/next/lib/verifyTypeScriptSetup.ts +++ b/packages/next/lib/verifyTypeScriptSetup.ts @@ -13,10 +13,14 @@ import { getTypeScriptIntent } from './typescript/getTypeScriptIntent' import { TypeCheckResult } from './typescript/runTypeCheck' import { writeAppTypeDeclarations } from './typescript/writeAppTypeDeclarations' import { writeConfigurationDefaults } from './typescript/writeConfigurationDefaults' -import { missingDepsError } from './typescript/missingDependencyError' +import { installDependencies } from './install-dependencies' const requiredPackages = [ - { file: 'typescript', pkg: 'typescript', exportsRestrict: false }, + { + file: 'typescript/lib/typescript.js', + pkg: 'typescript', + exportsRestrict: true, + }, { file: '@types/react/index.d.ts', pkg: '@types/react', @@ -25,18 +29,25 @@ const requiredPackages = [ { file: '@types/node/index.d.ts', pkg: '@types/node', - exportsRestrict: false, + exportsRestrict: true, }, ] -export async function verifyTypeScriptSetup( - dir: string, - intentDirs: string[], - typeCheckPreflight: boolean, - tsconfigPath: string, - disableStaticImages: boolean, +export async function verifyTypeScriptSetup({ + dir, + cacheDir, + intentDirs, + tsconfigPath, + typeCheckPreflight, + disableStaticImages, +}: { + dir: string cacheDir?: string -): Promise<{ result?: TypeCheckResult; version: string | null }> { + tsconfigPath: string + intentDirs: string[] + typeCheckPreflight: boolean + disableStaticImages: boolean +}): Promise<{ result?: TypeCheckResult; version: string | null }> { const resolvedTsConfigPath = path.join(dir, tsconfigPath) try { @@ -47,13 +58,36 @@ export async function verifyTypeScriptSetup( } // Ensure TypeScript and necessary `@types/*` are installed: - const deps: NecessaryDependencies = await hasNecessaryDependencies( + let deps: NecessaryDependencies = await hasNecessaryDependencies( dir, requiredPackages ) if (deps.missing?.length > 0) { - await missingDepsError(dir, deps.missing) + console.log( + chalk.bold.yellow( + `It looks like you're trying to use TypeScript but do not have the required package(s) installed.` + ) + + '\n' + + 'Installing dependencies' + + '\n\n' + + chalk.bold( + 'If you are not trying to use TypeScript, please remove the ' + + chalk.cyan('tsconfig.json') + + ' file from your package root (and any TypeScript files in your pages directory).' + ) + + '\n' + ) + await installDependencies(dir, deps.missing, true).catch((err) => { + if (err && typeof err === 'object' && 'command' in err) { + console.error( + `Failed to install required TypeScript dependencies, please install them manually to continue:\n` + + (err as any).command + ) + } + throw err + }) + deps = await hasNecessaryDependencies(dir, requiredPackages) } // Load TypeScript after we're sure it exists: diff --git a/packages/next/server/dev/next-dev-server.ts b/packages/next/server/dev/next-dev-server.ts index 5f538ced0a2e..799928af22db 100644 --- a/packages/next/server/dev/next-dev-server.ts +++ b/packages/next/server/dev/next-dev-server.ts @@ -46,7 +46,10 @@ import { setGlobal } from '../../trace' import HotReloader from './hot-reloader' import { findPageFile } from '../lib/find-page-file' import { getNodeOptionsWithoutInspect } from '../lib/utils' -import { withCoalescedInvoke } from '../../lib/coalesced-function' +import { + UnwrapPromise, + withCoalescedInvoke, +} from '../../lib/coalesced-function' import { loadDefaultErrorComponents } from '../load-components' import { DecodeError, MiddlewareNotFoundError } from '../../shared/lib/utils' import { @@ -73,6 +76,7 @@ import { NestedMiddlewareError, } from '../../build/utils' import { getDefineEnv } from '../../build/webpack-config' +import loadJsConfig from '../../build/load-jsconfig' // Load ReactDevOverlay only when needed let ReactDevOverlayImpl: React.FunctionComponent @@ -104,6 +108,8 @@ export default class DevServer extends Server { private actualMiddlewareFile?: string private middleware?: RoutingItem private edgeFunctions?: RoutingItem[] + private verifyingTypeScript?: boolean + private usingTypeScript?: boolean protected staticPathsWorker?: { [key: string]: any } & { loadStaticPaths: typeof import('./static-paths-worker').loadStaticPaths @@ -287,8 +293,17 @@ export default class DevServer extends Server { ].map((file) => pathJoin(this.dir, file)) files.push(...envFiles) + + // tsconfig/jsonfig paths hot-reloading + const tsconfigPaths = [ + pathJoin(this.dir, 'tsconfig.json'), + pathJoin(this.dir, 'jsconfig.json'), + ] + files.push(...tsconfigPaths) + wp.watch({ directories: [this.dir], startTime: 0 }) - const envFileTimes = new Map() + const fileWatchTimes = new Map() + let enabledTypeScript = this.usingTypeScript wp.on('aggregated', async () => { let middlewareMatcher: RegExp | undefined @@ -297,6 +312,7 @@ export default class DevServer extends Server { const appPaths: Record = {} const edgeRoutesSet = new Set() let envChange = false + let tsconfigChange = false for (const [fileName, meta] of knownFiles) { if ( @@ -306,14 +322,24 @@ export default class DevServer extends Server { continue } + const watchTime = fileWatchTimes.get(fileName) + const watchTimeChange = watchTime && watchTime !== meta?.timestamp + fileWatchTimes.set(fileName, meta.timestamp) + if (envFiles.includes(fileName)) { - if ( - envFileTimes.get(fileName) && - envFileTimes.get(fileName) !== meta.timestamp - ) { + if (watchTimeChange) { envChange = true } - envFileTimes.set(fileName, meta.timestamp) + continue + } + + if (tsconfigPaths.includes(fileName)) { + if (fileName.endsWith('tsconfig.json')) { + enabledTypeScript = true + } + if (watchTimeChange) { + tsconfigChange = true + } continue } @@ -350,6 +376,10 @@ export default class DevServer extends Server { continue } + if (fileName.endsWith('.ts') || fileName.endsWith('.tsx')) { + enabledTypeScript = true + } + let pageName = absolutePathToPage(fileName, { pagesDir: isAppPath ? this.appDir! : this.pagesDir, extensions: this.nextConfig.pageExtensions, @@ -392,8 +422,31 @@ export default class DevServer extends Server { }) } - if (envChange) { - this.loadEnvConfig({ dev: true, forceReload: true }) + if (!this.usingTypeScript && enabledTypeScript) { + // we tolerate the error here as this is best effort + // and the manual install command will be shown + await this.verifyTypeScript() + .then(() => { + tsconfigChange = true + }) + .catch(() => {}) + } + + if (envChange || tsconfigChange) { + if (envChange) { + this.loadEnvConfig({ dev: true, forceReload: true }) + } + let tsconfigResult: + | UnwrapPromise> + | undefined + + if (tsconfigChange) { + try { + tsconfigResult = await loadJsConfig(this.dir, this.nextConfig) + } catch (_) { + /* do we want to log if there are syntax errors in tsconfig while editing? */ + } + } this.hotReloader?.activeConfigs?.forEach((config, idx) => { const isClient = idx === 0 @@ -404,34 +457,69 @@ export default class DevServer extends Server { this.customRoutes.rewrites.beforeFiles.length > 0 || this.customRoutes.rewrites.fallback.length > 0 - config.plugins?.forEach((plugin: any) => { - // we look for the DefinePlugin definitions so we can - // update them on the active compilers - if ( - plugin && - typeof plugin.definitions === 'object' && - plugin.definitions.__NEXT_DEFINE_ENV - ) { - const newDefine = getDefineEnv({ - dev: true, - config: this.nextConfig, - distDir: this.distDir, - isClient, - hasRewrites, - hasReactRoot: this.hotReloader?.hasReactRoot, - isNodeServer, - isEdgeServer, - hasServerComponents: this.hotReloader?.hasServerComponents, - }) - - Object.keys(plugin.definitions).forEach((key) => { - if (!(key in newDefine)) { - delete plugin.definitions[key] + if (tsconfigChange) { + config.resolve?.plugins?.forEach((plugin: any) => { + // look for the JsConfigPathsPlugin and update with + // the latest paths/baseUrl config + if (plugin && plugin.jsConfigPlugin && tsconfigResult) { + const { resolvedBaseUrl, jsConfig } = tsconfigResult + const currentResolvedBaseUrl = plugin.resolvedBaseUrl + const resolvedUrlIndex = config.resolve?.modules?.findIndex( + (item) => item === currentResolvedBaseUrl + ) + + if ( + resolvedBaseUrl && + resolvedBaseUrl !== currentResolvedBaseUrl + ) { + // remove old baseUrl and add new one + if (resolvedUrlIndex && resolvedUrlIndex > -1) { + config.resolve?.modules?.splice(resolvedUrlIndex, 1) + } + config.resolve?.modules?.push(resolvedBaseUrl) } - }) - Object.assign(plugin.definitions, newDefine) - } - }) + + if (jsConfig?.compilerOptions?.paths && resolvedBaseUrl) { + Object.keys(plugin.paths).forEach((key) => { + delete plugin.paths[key] + }) + Object.assign(plugin.paths, jsConfig.compilerOptions.paths) + plugin.resolvedBaseUrl = resolvedBaseUrl + } + } + }) + } + + if (envChange) { + config.plugins?.forEach((plugin: any) => { + // we look for the DefinePlugin definitions so we can + // update them on the active compilers + if ( + plugin && + typeof plugin.definitions === 'object' && + plugin.definitions.__NEXT_DEFINE_ENV + ) { + const newDefine = getDefineEnv({ + dev: true, + config: this.nextConfig, + distDir: this.distDir, + isClient, + hasRewrites, + hasReactRoot: this.hotReloader?.hasReactRoot, + isNodeServer, + isEdgeServer, + hasServerComponents: this.hotReloader?.hasServerComponents, + }) + + Object.keys(plugin.definitions).forEach((key) => { + if (!(key in newDefine)) { + delete plugin.definitions[key] + } + }) + Object.assign(plugin.definitions, newDefine) + } + }) + } }) this.hotReloader?.invalidate() } @@ -516,17 +604,33 @@ export default class DevServer extends Server { this.webpackWatcher = null } + private async verifyTypeScript() { + if (this.verifyingTypeScript) { + return + } + try { + this.verifyingTypeScript = true + const verifyResult = await verifyTypeScriptSetup({ + dir: this.dir, + intentDirs: [this.pagesDir!, this.appDir].filter(Boolean) as string[], + typeCheckPreflight: false, + tsconfigPath: this.nextConfig.typescript.tsconfigPath, + disableStaticImages: this.nextConfig.images.disableStaticImages, + }) + + if (verifyResult.version) { + this.usingTypeScript = true + } + } finally { + this.verifyingTypeScript = false + } + } + async prepare(): Promise { setGlobal('distDir', this.distDir) setGlobal('phase', PHASE_DEVELOPMENT_SERVER) - await verifyTypeScriptSetup( - this.dir, - [this.pagesDir!, this.appDir].filter(Boolean) as string[], - false, - this.nextConfig.typescript.tsconfigPath, - this.nextConfig.images.disableStaticImages - ) + await this.verifyTypeScript() this.customRoutes = await loadCustomRoutes(this.nextConfig) // reload router diff --git a/test/development/jsconfig-path-reloading/app/components/button-1.js b/test/development/jsconfig-path-reloading/app/components/button-1.js new file mode 100644 index 000000000000..296068bbb66d --- /dev/null +++ b/test/development/jsconfig-path-reloading/app/components/button-1.js @@ -0,0 +1,3 @@ +export function Button1(props) { + return +} diff --git a/test/development/jsconfig-path-reloading/app/components/button-2.js b/test/development/jsconfig-path-reloading/app/components/button-2.js new file mode 100644 index 000000000000..f1208886efac --- /dev/null +++ b/test/development/jsconfig-path-reloading/app/components/button-2.js @@ -0,0 +1,3 @@ +export function Button2(props) { + return +} diff --git a/test/development/jsconfig-path-reloading/app/components/button-3.js b/test/development/jsconfig-path-reloading/app/components/button-3.js new file mode 100644 index 000000000000..0359c00285d0 --- /dev/null +++ b/test/development/jsconfig-path-reloading/app/components/button-3.js @@ -0,0 +1,3 @@ +export function Button2(props) { + return +} diff --git a/test/development/jsconfig-path-reloading/app/jsconfig.json b/test/development/jsconfig-path-reloading/app/jsconfig.json new file mode 100644 index 000000000000..36f88fd7b2e8 --- /dev/null +++ b/test/development/jsconfig-path-reloading/app/jsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": false, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "incremental": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "baseUrl": ".", + "paths": { + "@c/*": ["components/*"], + "@lib/*": ["lib/first-lib/*"], + "@mybutton": ["components/button-2.js"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} diff --git a/test/development/jsconfig-path-reloading/app/lib/first-lib/first-data.js b/test/development/jsconfig-path-reloading/app/lib/first-lib/first-data.js new file mode 100644 index 000000000000..fec1d03f066e --- /dev/null +++ b/test/development/jsconfig-path-reloading/app/lib/first-lib/first-data.js @@ -0,0 +1,3 @@ +export const firstData = { + hello: 'world', +} diff --git a/test/development/jsconfig-path-reloading/app/lib/second-lib/second-data.js b/test/development/jsconfig-path-reloading/app/lib/second-lib/second-data.js new file mode 100644 index 000000000000..86498777ff51 --- /dev/null +++ b/test/development/jsconfig-path-reloading/app/lib/second-lib/second-data.js @@ -0,0 +1,3 @@ +export const secondData = { + hello: 'again', +} diff --git a/test/development/jsconfig-path-reloading/app/pages/index.js b/test/development/jsconfig-path-reloading/app/pages/index.js new file mode 100644 index 000000000000..859719d413a9 --- /dev/null +++ b/test/development/jsconfig-path-reloading/app/pages/index.js @@ -0,0 +1,13 @@ +import { Button1 } from '@c/button-1' +import { Button2 } from '@mybutton' +import { firstData } from '@lib/first-data' + +export default function Page(props) { + return ( + <> + + +

    {JSON.stringify(firstData)}

    + + ) +} diff --git a/test/development/jsconfig-path-reloading/index.test.ts b/test/development/jsconfig-path-reloading/index.test.ts new file mode 100644 index 000000000000..a24b0a435a58 --- /dev/null +++ b/test/development/jsconfig-path-reloading/index.test.ts @@ -0,0 +1,190 @@ +import { createNext, FileRef } from 'e2e-utils' +import { NextInstance } from 'test/lib/next-modes/base' +import { + check, + hasRedbox, + renderViaHTTP, + getRedboxSource, +} from 'next-test-utils' +import cheerio from 'cheerio' +import { join } from 'path' +import webdriver from 'next-webdriver' +import fs from 'fs-extra' + +describe('jsconfig-path-reloading', () => { + let next: NextInstance + const tsConfigFile = 'jsconfig.json' + const indexPage = 'pages/index.js' + + function runTests({ addAfterStart }: { addAfterStart?: boolean }) { + beforeAll(async () => { + let tsConfigContent = await fs.readFile( + join(__dirname, 'app/jsconfig.json'), + 'utf8' + ) + + next = await createNext({ + files: { + components: new FileRef(join(__dirname, 'app/components')), + pages: new FileRef(join(__dirname, 'app/pages')), + lib: new FileRef(join(__dirname, 'app/lib')), + ...(addAfterStart + ? {} + : { + [tsConfigFile]: tsConfigContent, + }), + }, + dependencies: { + typescript: 'latest', + '@types/react': 'latest', + '@types/node': 'latest', + }, + }) + + if (addAfterStart) { + await next.patchFile(tsConfigFile, tsConfigContent) + } + }) + afterAll(() => next.destroy()) + + it('should load with initial paths config correctly', async () => { + const html = await renderViaHTTP(next.url, '/') + const $ = cheerio.load(html) + expect(html).toContain('first button') + expect(html).toContain('second button') + expect($('#first-data').text()).toContain( + JSON.stringify({ + hello: 'world', + }) + ) + }) + + it('should recover from module not found when paths is updated', async () => { + const indexContent = await next.readFile(indexPage) + const tsconfigContent = await next.readFile(tsConfigFile) + const parsedTsConfig = JSON.parse(tsconfigContent) + + const browser = await webdriver(next.url, '/') + + try { + const html = await browser.eval('document.documentElement.innerHTML') + expect(html).toContain('first button') + expect(html).toContain('second button') + expect(html).toContain('first-data') + expect(html).not.toContain('second-data') + + await next.patchFile( + indexPage, + `import {secondData} from "@lib/second-data"\n${indexContent.replace( + '

    ', + `

    {JSON.stringify(secondData)}

    ` + )}` + ) + + expect(await hasRedbox(browser, true)).toBe(true) + expect(await getRedboxSource(browser)).toContain('"@lib/second-data"') + + await next.patchFile( + tsConfigFile, + JSON.stringify( + { + ...parsedTsConfig, + compilerOptions: { + ...parsedTsConfig.compilerOptions, + paths: { + ...parsedTsConfig.compilerOptions.paths, + '@lib/*': ['lib/first-lib/*', 'lib/second-lib/*'], + }, + }, + }, + null, + 2 + ) + ) + + expect(await hasRedbox(browser, false)).toBe(false) + + const html2 = await browser.eval('document.documentElement.innerHTML') + expect(html2).toContain('first button') + expect(html2).toContain('second button') + expect(html2).toContain('first-data') + expect(html2).toContain('second-data') + } finally { + await next.patchFile(indexPage, indexContent) + await next.patchFile(tsConfigFile, tsconfigContent) + await check(async () => { + const html3 = await browser.eval('document.documentElement.innerHTML') + return html3.includes('first-data') && !html3.includes('second-data') + ? 'success' + : html3 + }, 'success') + } + }) + + it('should automatically fast refresh content when path is added without error', async () => { + const indexContent = await next.readFile(indexPage) + const tsconfigContent = await next.readFile(tsConfigFile) + const parsedTsConfig = JSON.parse(tsconfigContent) + + const browser = await webdriver(next.url, '/') + + try { + const html = await browser.eval('document.documentElement.innerHTML') + expect(html).toContain('first button') + expect(html).toContain('second button') + expect(html).toContain('first-data') + + await next.patchFile( + tsConfigFile, + JSON.stringify( + { + ...parsedTsConfig, + compilerOptions: { + ...parsedTsConfig.compilerOptions, + paths: { + ...parsedTsConfig.compilerOptions.paths, + '@myotherbutton': ['components/button-3.js'], + }, + }, + }, + null, + 2 + ) + ) + await next.patchFile( + indexPage, + indexContent.replace('@mybutton', '@myotherbutton') + ) + + expect(await hasRedbox(browser, false)).toBe(false) + + await check(async () => { + const html2 = await browser.eval('document.documentElement.innerHTML') + expect(html2).toContain('first button') + expect(html2).not.toContain('second button') + expect(html2).toContain('third button') + expect(html2).toContain('first-data') + return 'success' + }, 'success') + } finally { + await next.patchFile(indexPage, indexContent) + await next.patchFile(tsConfigFile, tsconfigContent) + await check(async () => { + const html3 = await browser.eval('document.documentElement.innerHTML') + return html3.includes('first button') && + !html3.includes('third button') + ? 'success' + : html3 + }, 'success') + } + }) + } + + describe('jsconfig', () => { + runTests({}) + }) + + describe('jsconfig added after starting dev', () => { + runTests({ addAfterStart: true }) + }) +}) diff --git a/test/development/tsconfig-path-reloading/app/components/button-1.tsx b/test/development/tsconfig-path-reloading/app/components/button-1.tsx new file mode 100644 index 000000000000..296068bbb66d --- /dev/null +++ b/test/development/tsconfig-path-reloading/app/components/button-1.tsx @@ -0,0 +1,3 @@ +export function Button1(props) { + return +} diff --git a/test/development/tsconfig-path-reloading/app/components/button-2.tsx b/test/development/tsconfig-path-reloading/app/components/button-2.tsx new file mode 100644 index 000000000000..f1208886efac --- /dev/null +++ b/test/development/tsconfig-path-reloading/app/components/button-2.tsx @@ -0,0 +1,3 @@ +export function Button2(props) { + return +} diff --git a/test/development/tsconfig-path-reloading/app/components/button-3.tsx b/test/development/tsconfig-path-reloading/app/components/button-3.tsx new file mode 100644 index 000000000000..0359c00285d0 --- /dev/null +++ b/test/development/tsconfig-path-reloading/app/components/button-3.tsx @@ -0,0 +1,3 @@ +export function Button2(props) { + return +} diff --git a/test/development/tsconfig-path-reloading/app/lib/first-lib/first-data.ts b/test/development/tsconfig-path-reloading/app/lib/first-lib/first-data.ts new file mode 100644 index 000000000000..fec1d03f066e --- /dev/null +++ b/test/development/tsconfig-path-reloading/app/lib/first-lib/first-data.ts @@ -0,0 +1,3 @@ +export const firstData = { + hello: 'world', +} diff --git a/test/development/tsconfig-path-reloading/app/lib/second-lib/second-data.ts b/test/development/tsconfig-path-reloading/app/lib/second-lib/second-data.ts new file mode 100644 index 000000000000..86498777ff51 --- /dev/null +++ b/test/development/tsconfig-path-reloading/app/lib/second-lib/second-data.ts @@ -0,0 +1,3 @@ +export const secondData = { + hello: 'again', +} diff --git a/test/development/tsconfig-path-reloading/app/pages/index.tsx b/test/development/tsconfig-path-reloading/app/pages/index.tsx new file mode 100644 index 000000000000..859719d413a9 --- /dev/null +++ b/test/development/tsconfig-path-reloading/app/pages/index.tsx @@ -0,0 +1,13 @@ +import { Button1 } from '@c/button-1' +import { Button2 } from '@mybutton' +import { firstData } from '@lib/first-data' + +export default function Page(props) { + return ( + <> + + +

    {JSON.stringify(firstData)}

    + + ) +} diff --git a/test/development/tsconfig-path-reloading/app/tsconfig.json b/test/development/tsconfig-path-reloading/app/tsconfig.json new file mode 100644 index 000000000000..3075aad9c676 --- /dev/null +++ b/test/development/tsconfig-path-reloading/app/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": false, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "incremental": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "baseUrl": ".", + "paths": { + "@c/*": ["components/*"], + "@lib/*": ["lib/first-lib/*"], + "@mybutton": ["components/button-2.tsx"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} diff --git a/test/development/tsconfig-path-reloading/index.test.ts b/test/development/tsconfig-path-reloading/index.test.ts new file mode 100644 index 000000000000..ef679796d489 --- /dev/null +++ b/test/development/tsconfig-path-reloading/index.test.ts @@ -0,0 +1,190 @@ +import { createNext, FileRef } from 'e2e-utils' +import { NextInstance } from 'test/lib/next-modes/base' +import { + check, + hasRedbox, + renderViaHTTP, + getRedboxSource, +} from 'next-test-utils' +import cheerio from 'cheerio' +import { join } from 'path' +import webdriver from 'next-webdriver' +import fs from 'fs-extra' + +describe('tsconfig-path-reloading', () => { + let next: NextInstance + const tsConfigFile = 'tsconfig.json' + const indexPage = 'pages/index.tsx' + + function runTests({ addAfterStart }: { addAfterStart?: boolean }) { + beforeAll(async () => { + let tsConfigContent = await fs.readFile( + join(__dirname, 'app/tsconfig.json'), + 'utf8' + ) + + next = await createNext({ + files: { + components: new FileRef(join(__dirname, 'app/components')), + pages: new FileRef(join(__dirname, 'app/pages')), + lib: new FileRef(join(__dirname, 'app/lib')), + ...(addAfterStart + ? {} + : { + [tsConfigFile]: tsConfigContent, + }), + }, + dependencies: { + typescript: 'latest', + '@types/react': 'latest', + '@types/node': 'latest', + }, + }) + + if (addAfterStart) { + await next.patchFile(tsConfigFile, tsConfigContent) + } + }) + afterAll(() => next.destroy()) + + it('should load with initial paths config correctly', async () => { + const html = await renderViaHTTP(next.url, '/') + const $ = cheerio.load(html) + expect(html).toContain('first button') + expect(html).toContain('second button') + expect($('#first-data').text()).toContain( + JSON.stringify({ + hello: 'world', + }) + ) + }) + + it('should recover from module not found when paths is updated', async () => { + const indexContent = await next.readFile(indexPage) + const tsconfigContent = await next.readFile(tsConfigFile) + const parsedTsConfig = JSON.parse(tsconfigContent) + + const browser = await webdriver(next.url, '/') + + try { + const html = await browser.eval('document.documentElement.innerHTML') + expect(html).toContain('first button') + expect(html).toContain('second button') + expect(html).toContain('first-data') + expect(html).not.toContain('second-data') + + await next.patchFile( + indexPage, + `import {secondData} from "@lib/second-data"\n${indexContent.replace( + '

    ', + `

    {JSON.stringify(secondData)}

    ` + )}` + ) + + expect(await hasRedbox(browser, true)).toBe(true) + expect(await getRedboxSource(browser)).toContain('"@lib/second-data"') + + await next.patchFile( + tsConfigFile, + JSON.stringify( + { + ...parsedTsConfig, + compilerOptions: { + ...parsedTsConfig.compilerOptions, + paths: { + ...parsedTsConfig.compilerOptions.paths, + '@lib/*': ['lib/first-lib/*', 'lib/second-lib/*'], + }, + }, + }, + null, + 2 + ) + ) + + expect(await hasRedbox(browser, false)).toBe(false) + + const html2 = await browser.eval('document.documentElement.innerHTML') + expect(html2).toContain('first button') + expect(html2).toContain('second button') + expect(html2).toContain('first-data') + expect(html2).toContain('second-data') + } finally { + await next.patchFile(indexPage, indexContent) + await next.patchFile(tsConfigFile, tsconfigContent) + await check(async () => { + const html3 = await browser.eval('document.documentElement.innerHTML') + return html3.includes('first-data') && !html3.includes('second-data') + ? 'success' + : html3 + }, 'success') + } + }) + + it('should automatically fast refresh content when path is added without error', async () => { + const indexContent = await next.readFile(indexPage) + const tsconfigContent = await next.readFile(tsConfigFile) + const parsedTsConfig = JSON.parse(tsconfigContent) + + const browser = await webdriver(next.url, '/') + + try { + const html = await browser.eval('document.documentElement.innerHTML') + expect(html).toContain('first button') + expect(html).toContain('second button') + expect(html).toContain('first-data') + + await next.patchFile( + tsConfigFile, + JSON.stringify( + { + ...parsedTsConfig, + compilerOptions: { + ...parsedTsConfig.compilerOptions, + paths: { + ...parsedTsConfig.compilerOptions.paths, + '@myotherbutton': ['components/button-3.tsx'], + }, + }, + }, + null, + 2 + ) + ) + await next.patchFile( + indexPage, + indexContent.replace('@mybutton', '@myotherbutton') + ) + + expect(await hasRedbox(browser, false)).toBe(false) + + await check(async () => { + const html2 = await browser.eval('document.documentElement.innerHTML') + expect(html2).toContain('first button') + expect(html2).not.toContain('second button') + expect(html2).toContain('third button') + expect(html2).toContain('first-data') + return 'success' + }, 'success') + } finally { + await next.patchFile(indexPage, indexContent) + await next.patchFile(tsConfigFile, tsconfigContent) + await check(async () => { + const html3 = await browser.eval('document.documentElement.innerHTML') + return html3.includes('first button') && + !html3.includes('third button') + ? 'success' + : html3 + }, 'success') + } + }) + } + + describe('tsconfig', () => { + runTests({}) + }) + + describe('tsconfig added after starting dev', () => { + runTests({ addAfterStart: true }) + }) +}) diff --git a/test/development/typescript-auto-install/index.test.ts b/test/development/typescript-auto-install/index.test.ts new file mode 100644 index 000000000000..4f5cca72d8ea --- /dev/null +++ b/test/development/typescript-auto-install/index.test.ts @@ -0,0 +1,61 @@ +import { createNext } from 'e2e-utils' +import { NextInstance } from 'test/lib/next-modes/base' +import { check, renderViaHTTP } from 'next-test-utils' +import webdriver from 'next-webdriver' +// @ts-expect-error missing types +import stripAnsi from 'strip-ansi' + +describe('typescript-auto-install', () => { + let next: NextInstance + + beforeAll(async () => { + next = await createNext({ + files: { + 'pages/index.js': ` + export default function Page() { + return

    hello world

    + } + `, + }, + startCommand: 'yarn next dev', + installCommand: 'yarn', + dependencies: {}, + }) + }) + afterAll(() => next.destroy()) + + it('should work', async () => { + const html = await renderViaHTTP(next.url, '/') + expect(html).toContain('hello world') + }) + + it('should detect TypeScript being added and auto setup', async () => { + const browser = await webdriver(next.url, '/') + const pageContent = await next.readFile('pages/index.js') + + await check( + () => browser.eval('document.documentElement.innerHTML'), + /hello world/ + ) + await next.renameFile('pages/index.js', 'pages/index.tsx') + + await check( + () => stripAnsi(next.cliOutput), + /We detected TypeScript in your project and created a tsconfig\.json file for you/i + ) + + await check( + () => browser.eval('document.documentElement.innerHTML'), + /hello world/ + ) + await next.patchFile( + 'pages/index.tsx', + pageContent.replace('hello world', 'hello again') + ) + + await check( + () => browser.eval('document.documentElement.innerHTML'), + /hello again/ + ) + }) +}) diff --git a/test/integration/typescript-version-warning/app/node_modules/typescript/index.js b/test/integration/typescript-version-warning/app/node_modules/typescript/index.js deleted file mode 100644 index 740559576178..000000000000 --- a/test/integration/typescript-version-warning/app/node_modules/typescript/index.js +++ /dev/null @@ -1,5 +0,0 @@ -const mod = require('../../../../../../node_modules/typescript') - -mod.version = '3.8.3' - -module.exports = mod diff --git a/test/integration/typescript-version-warning/app/node_modules/typescript/lib/typescript.js b/test/integration/typescript-version-warning/app/node_modules/typescript/lib/typescript.js new file mode 100644 index 000000000000..ca151aa41523 --- /dev/null +++ b/test/integration/typescript-version-warning/app/node_modules/typescript/lib/typescript.js @@ -0,0 +1,5 @@ +const mod = require('../../../../../../../node_modules/typescript') + +mod.version = '3.8.3' + +module.exports = mod diff --git a/test/integration/typescript-version-warning/app/node_modules/typescript/package.json b/test/integration/typescript-version-warning/app/node_modules/typescript/package.json index 5331dd9817e3..69c3d513633e 100644 --- a/test/integration/typescript-version-warning/app/node_modules/typescript/package.json +++ b/test/integration/typescript-version-warning/app/node_modules/typescript/package.json @@ -1,5 +1,5 @@ { "name": "typescript", "version": "3.8.3", - "main": "./index.js" + "main": "./lib/typescript.js" } diff --git a/test/integration/typescript-version-warning/app/tsconfig.json b/test/integration/typescript-version-warning/app/tsconfig.json index 93a83a407c40..b8d597880a1a 100644 --- a/test/integration/typescript-version-warning/app/tsconfig.json +++ b/test/integration/typescript-version-warning/app/tsconfig.json @@ -12,7 +12,8 @@ "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve" + "jsx": "preserve", + "incremental": true }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], "exclude": ["node_modules"] diff --git a/test/integration/typescript-version-warning/test/index.test.js b/test/integration/typescript-version-warning/test/index.test.js index f47f1be582da..a37ae2ad57a6 100644 --- a/test/integration/typescript-version-warning/test/index.test.js +++ b/test/integration/typescript-version-warning/test/index.test.js @@ -4,7 +4,7 @@ import { join } from 'path' import { nextBuild, findPort, launchApp, killApp } from 'next-test-utils' const appDir = join(__dirname, '../app') -const tsFile = join(appDir, 'node_modules/typescript/index.js') +const tsFile = join(appDir, 'node_modules/typescript/lib/typescript.js') describe('Minimum TypeScript Warning', () => { it('should show warning during next build with old version', async () => { diff --git a/test/production/missing-dep-error/index.test.ts b/test/production/missing-dep-error/index.test.ts deleted file mode 100644 index d888763af1ca..000000000000 --- a/test/production/missing-dep-error/index.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { createNext } from 'e2e-utils' -import { NextInstance } from 'test/lib/next-modes/base' - -describe('missing-dep-error', () => { - let next: NextInstance - - beforeAll(async () => { - next = await createNext({ - files: { - 'pages/index.tsx': ` - export default function Page() { - return

    hello world

    - } - `, - }, - skipStart: true, - }) - }) - afterAll(() => next.destroy()) - - it('should only show error once', async () => { - await next.start().catch(() => {}) - expect( - next.cliOutput.match(/It looks like you're trying to use TypeScript/g) - ?.length - ).toBe(1) - }) -}) From 7f5bc717120829580e5bb01788ec3dc4e220d71d Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Tue, 23 Aug 2022 13:29:17 -0500 Subject: [PATCH 47/64] Update flakey relay analytics test (#39877) Implements `check` on relay analytics test as the timing can be indeterminate. Fixes: https://github.com/vercel/next.js/runs/7979410199?check_suite_focus=true#step:9:230 --- test/integration/relay-analytics/test/index.test.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/test/integration/relay-analytics/test/index.test.js b/test/integration/relay-analytics/test/index.test.js index 2accc97815e8..5ee12ffa9e39 100644 --- a/test/integration/relay-analytics/test/index.test.js +++ b/test/integration/relay-analytics/test/index.test.js @@ -117,9 +117,15 @@ function runTest() { ) // INP metric is only reported on pagehide or visibilitychange event, so refresh the page await browser.refresh() - const INP = parseInt(await browser.eval('localStorage.getItem("INP")'), 10) - // We introduced a delay of 100ms, so INP duration should be >= 100 - expect(INP).toBeGreaterThanOrEqual(100) + await check(async () => { + const INP = parseInt( + await browser.eval('localStorage.getItem("INP")'), + 10 + ) + // We introduced a delay of 100ms, so INP duration should be >= 100 + expect(INP).toBeGreaterThanOrEqual(100) + return 'success' + }, 'success') await browser.close() }) } From b85628392bd66e8d2d3ff86924886b33deec48da Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Tue, 23 Aug 2022 13:42:36 -0500 Subject: [PATCH 48/64] Remove eslint warning when no eslint config is present (#39872) We shouldn't be warning when no eslint config file is present as it's valid not to use eslint. The warning is still shown if an empty eslint config file is added as this gives intent to using eslint. x-ref: [slack thread](https://vercel.slack.com/archives/CGU8HUTUH/p1661268593890619?thread_ts=1661266342.496699&cid=CGU8HUTUH) ## Bug - [x] Related issues linked using `fixes #number` - [x] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` --- .../next/lib/eslint/hasEslintConfiguration.ts | 6 +- packages/next/lib/eslint/runLintCheck.ts | 9 ++- .../index.test.ts | 69 +++++++++++++++++++ 3 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 test/e2e/no-eslint-warn-with-no-eslint-config/index.test.ts diff --git a/packages/next/lib/eslint/hasEslintConfiguration.ts b/packages/next/lib/eslint/hasEslintConfiguration.ts index 2b3418f7966b..113e72926192 100644 --- a/packages/next/lib/eslint/hasEslintConfiguration.ts +++ b/packages/next/lib/eslint/hasEslintConfiguration.ts @@ -31,6 +31,7 @@ export async function hasEslintConfiguration( ) { return { ...configObject, emptyEslintrc: true } } + return { ...configObject, exists: true } } else if (packageJsonConfig?.eslintConfig) { if (Object.entries(packageJsonConfig?.eslintConfig).length === 0) { return { @@ -38,9 +39,6 @@ export async function hasEslintConfiguration( emptyPkgJsonConfig: true, } } - } else { - return configObject } - - return { ...configObject, exists: true } + return configObject } diff --git a/packages/next/lib/eslint/runLintCheck.ts b/packages/next/lib/eslint/runLintCheck.ts index 3e3a46af5e68..05c49caeb027 100644 --- a/packages/next/lib/eslint/runLintCheck.ts +++ b/packages/next/lib/eslint/runLintCheck.ts @@ -321,8 +321,13 @@ export async function runLintCheck( outputFile ) } else { - // Display warning if no ESLint configuration is present during "next build" - if (lintDuringBuild) { + // Display warning if no ESLint configuration is present inside + // config file during "next build", no warning is shown when + // no eslintrc file is present + if ( + lintDuringBuild && + (config.emptyPkgJsonConfig || config.emptyEslintrc) + ) { Log.warn( `No ESLint configuration detected. Run ${chalk.bold.cyan( 'next lint' diff --git a/test/e2e/no-eslint-warn-with-no-eslint-config/index.test.ts b/test/e2e/no-eslint-warn-with-no-eslint-config/index.test.ts new file mode 100644 index 000000000000..d24e7755b4ed --- /dev/null +++ b/test/e2e/no-eslint-warn-with-no-eslint-config/index.test.ts @@ -0,0 +1,69 @@ +import { createNext } from 'e2e-utils' +import { NextInstance } from 'test/lib/next-modes/base' +import { renderViaHTTP } from 'next-test-utils' + +describe('no-eslint-warn-with-no-eslint-config', () => { + let next: NextInstance + + if ((global as any).isNextDeploy) { + it('should skip for deploy', () => {}) + return + } + + beforeAll(async () => { + next = await createNext({ + files: { + 'pages/index.js': ` + export default function Page() { + return

    hello world

    + } + `, + }, + dependencies: {}, + }) + }) + afterAll(() => next.destroy()) + + it('should render', async () => { + const html = await renderViaHTTP(next.url, '/') + expect(html).toContain('hello world') + }) + + it('should not have eslint warnings when no eslint config', async () => { + expect(next.cliOutput).not.toContain( + 'No ESLint configuration detected. Run next lint to begin setup' + ) + expect(next.cliOutput).not.toBe('warn') + }) + + if (!(global as any).isNextDev) { + it('should warn with empty eslintrc', async () => { + await next.stop() + await next.patchFile('.eslintrc.json', '{}') + await next.start() + + expect(next.cliOutput).toContain( + 'No ESLint configuration detected. Run next lint to begin setup' + ) + }) + + it('should warn with empty eslint config in package.json', async () => { + await next.stop() + await next.deleteFile('.eslintrc.json') + const origPkgJson = await next.readFile('package.json') + const pkgJson = JSON.parse(origPkgJson) + pkgJson.eslintConfig = {} + + try { + await next.patchFile('package.json', JSON.stringify(pkgJson)) + await next.start() + + expect(next.cliOutput).toContain( + 'No ESLint configuration detected. Run next lint to begin setup' + ) + } finally { + await next.patchFile('package.json', origPkgJson) + } + }) + } +}) From 64a3697d05d4d256d84ccab8aacd6fd968971795 Mon Sep 17 00:00:00 2001 From: Henrik Wenz Date: Tue, 23 Aug 2022 20:52:31 +0200 Subject: [PATCH 49/64] =?UTF-8?q?[Docs]=C2=A0Update=20examples=20to=20favo?= =?UTF-8?q?ur=20functional=20=5Fdocument=20(#39871)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Changes - Migrate class based `_document`s to functional documents - Removed `_document.js` where default - Removed `MyDocument.getInitialProps` where default ## Motivation This removes some boilerplate and prepares examples for server components. ## Documentation / Examples - [x] Make sure the linting passes by running `pnpm lint` - [x] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples) --- examples/auth-with-stytch/pages/_document.tsx | 47 +++------ examples/blog-starter/pages/_document.tsx | 24 +++-- examples/blog/pages/_document.tsx | 70 +++++-------- examples/cms-contentful/pages/_document.js | 24 +++-- examples/cms-cosmic/pages/_document.js | 24 +++-- examples/cms-datocms/pages/_document.js | 24 +++-- examples/cms-drupal/pages/_document.js | 24 +++-- examples/cms-ghost/pages/_document.js | 24 +++-- examples/cms-graphcms/pages/_document.js | 24 +++-- examples/cms-kontent/pages/_document.js | 24 +++-- examples/cms-prepr/pages/_document.js | 24 +++-- examples/cms-prismic/pages/_document.js | 24 +++-- examples/cms-sanity/pages/_document.js | 24 +++-- examples/cms-storyblok/pages/_document.js | 24 +++-- examples/cms-strapi/pages/_document.js | 24 +++-- examples/cms-takeshape/pages/_document.js | 24 +++-- examples/cms-tina/pages/_document.js | 24 +++-- .../cms-umbraco-heartcore/pages/_document.js | 24 +++-- examples/cms-wordpress/pages/_document.tsx | 24 +++-- examples/with-babel-macros/pages/_document.js | 28 +++--- .../with-facebook-pixel/pages/_document.js | 42 ++++---- .../pages/_document.js | 98 +++++++++---------- .../pages/_document.js | 40 ++++---- examples/with-next-offline/pages/_document.js | 35 +++---- .../pages/_document.js | 45 ++++----- examples/with-portals/pages/_document.js | 28 +++--- examples/with-rebass/pages/_document.js | 30 +++--- examples/with-strict-csp/pages/_document.js | 40 ++++---- .../with-typescript-types/pages/_document.jsx | 17 ---- examples/with-unsplash/pages/_document.tsx | 31 +++--- 30 files changed, 419 insertions(+), 540 deletions(-) delete mode 100644 examples/with-typescript-types/pages/_document.jsx diff --git a/examples/auth-with-stytch/pages/_document.tsx b/examples/auth-with-stytch/pages/_document.tsx index 83d9080a67d7..496f4c465e5c 100644 --- a/examples/auth-with-stytch/pages/_document.tsx +++ b/examples/auth-with-stytch/pages/_document.tsx @@ -1,33 +1,18 @@ -import Document, { - Html, - Head, - Main, - NextScript, - DocumentContext, -} from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -class MyDocument extends Document { - static async getInitialProps(ctx: DocumentContext) { - const initialProps = await Document.getInitialProps(ctx) - return { ...initialProps } - } - - render() { - return ( - - - - - -
    - - - - ) - } +export default function Document() { + return ( + + + + + +
    + + + + ) } - -export default MyDocument diff --git a/examples/blog-starter/pages/_document.tsx b/examples/blog-starter/pages/_document.tsx index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/blog-starter/pages/_document.tsx +++ b/examples/blog-starter/pages/_document.tsx @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/blog/pages/_document.tsx b/examples/blog/pages/_document.tsx index 40ab3703fb31..d480d60cc696 100644 --- a/examples/blog/pages/_document.tsx +++ b/examples/blog/pages/_document.tsx @@ -1,47 +1,31 @@ -import Document, { - Html, - Head, - Main, - NextScript, - DocumentContext, -} from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -class MyDocument extends Document { - static async getInitialProps(ctx: DocumentContext) { - const initialProps = await Document.getInitialProps(ctx) - return { ...initialProps } +export default function Document() { + const meta = { + title: 'Next.js Blog Starter Kit', + description: 'Clone and deploy your own Next.js portfolio in minutes.', + image: 'https://assets.vercel.com/image/upload/q_auto/front/vercel/dps.png', } - render() { - const meta = { - title: 'Next.js Blog Starter Kit', - description: 'Clone and deploy your own Next.js portfolio in minutes.', - image: - 'https://assets.vercel.com/image/upload/q_auto/front/vercel/dps.png', - } - - return ( - - - - - - - - - - - - - - - -
    - - - - ) - } + return ( + + + + + + + + + + + + + + + +
    + + + + ) } - -export default MyDocument diff --git a/examples/cms-contentful/pages/_document.js b/examples/cms-contentful/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-contentful/pages/_document.js +++ b/examples/cms-contentful/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-cosmic/pages/_document.js b/examples/cms-cosmic/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-cosmic/pages/_document.js +++ b/examples/cms-cosmic/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-datocms/pages/_document.js b/examples/cms-datocms/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-datocms/pages/_document.js +++ b/examples/cms-datocms/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-drupal/pages/_document.js b/examples/cms-drupal/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-drupal/pages/_document.js +++ b/examples/cms-drupal/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-ghost/pages/_document.js b/examples/cms-ghost/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-ghost/pages/_document.js +++ b/examples/cms-ghost/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-graphcms/pages/_document.js b/examples/cms-graphcms/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-graphcms/pages/_document.js +++ b/examples/cms-graphcms/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-kontent/pages/_document.js b/examples/cms-kontent/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-kontent/pages/_document.js +++ b/examples/cms-kontent/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-prepr/pages/_document.js b/examples/cms-prepr/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-prepr/pages/_document.js +++ b/examples/cms-prepr/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-prismic/pages/_document.js b/examples/cms-prismic/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-prismic/pages/_document.js +++ b/examples/cms-prismic/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-sanity/pages/_document.js b/examples/cms-sanity/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-sanity/pages/_document.js +++ b/examples/cms-sanity/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-storyblok/pages/_document.js b/examples/cms-storyblok/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-storyblok/pages/_document.js +++ b/examples/cms-storyblok/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-strapi/pages/_document.js b/examples/cms-strapi/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-strapi/pages/_document.js +++ b/examples/cms-strapi/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-takeshape/pages/_document.js b/examples/cms-takeshape/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-takeshape/pages/_document.js +++ b/examples/cms-takeshape/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-tina/pages/_document.js b/examples/cms-tina/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-tina/pages/_document.js +++ b/examples/cms-tina/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-umbraco-heartcore/pages/_document.js b/examples/cms-umbraco-heartcore/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100755 --- a/examples/cms-umbraco-heartcore/pages/_document.js +++ b/examples/cms-umbraco-heartcore/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-wordpress/pages/_document.tsx b/examples/cms-wordpress/pages/_document.tsx index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-wordpress/pages/_document.tsx +++ b/examples/cms-wordpress/pages/_document.tsx @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/with-babel-macros/pages/_document.js b/examples/with-babel-macros/pages/_document.js index dfbe440013fd..eb39cf4e4fda 100644 --- a/examples/with-babel-macros/pages/_document.js +++ b/examples/with-babel-macros/pages/_document.js @@ -1,17 +1,15 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - - - -
    - - - - ) - } + + +
    + + + + ) } diff --git a/examples/with-portals/pages/_document.js b/examples/with-portals/pages/_document.js index 9b7ed4536e34..980f43e2324d 100644 --- a/examples/with-portals/pages/_document.js +++ b/examples/with-portals/pages/_document.js @@ -1,17 +1,15 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - {/* Here we will mount our modal portal */} -