From 7de3cf5f8962f28ff667aedeb2331c4b0a33ee65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 16 Aug 2022 19:05:03 +0100 Subject: [PATCH 01/41] fix(next-server): Fix priority for edge routes (#39462) Fixes #39411 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 Co-authored-by: JJ Kasper --- packages/next/server/base-server.ts | 2 +- packages/next/server/dev/next-dev-server.ts | 1 + .../server/dev/on-demand-entry-handler.ts | 9 ++ packages/next/server/next-server.ts | 124 +++++++----------- packages/next/server/router.ts | 11 +- .../index.test.ts | 33 +++++ test/lib/next-test-utils.js | 1 + 7 files changed, 98 insertions(+), 83 deletions(-) create mode 100644 test/e2e/edge-vs.-non-edge-api-route-priority/index.test.ts diff --git a/packages/next/server/base-server.ts b/packages/next/server/base-server.ts index c4e247a4e5b5..d3e89af197c7 100644 --- a/packages/next/server/base-server.ts +++ b/packages/next/server/base-server.ts @@ -127,7 +127,7 @@ export interface BaseRequestHandler { ): Promise } -type RequestContext = { +export type RequestContext = { req: BaseNextRequest res: BaseNextResponse pathname: string diff --git a/packages/next/server/dev/next-dev-server.ts b/packages/next/server/dev/next-dev-server.ts index a43f65c1ed3f..5f538ced0a2e 100644 --- a/packages/next/server/dev/next-dev-server.ts +++ b/packages/next/server/dev/next-dev-server.ts @@ -386,6 +386,7 @@ export default class DevServer extends Server { routedPages.push(pageName) }, onEdgeServer: () => { + routedPages.push(pageName) edgeRoutesSet.add(pageName) }, }) diff --git a/packages/next/server/dev/on-demand-entry-handler.ts b/packages/next/server/dev/on-demand-entry-handler.ts index da43d221be0a..f3c820da209d 100644 --- a/packages/next/server/dev/on-demand-entry-handler.ts +++ b/packages/next/server/dev/on-demand-entry-handler.ts @@ -1,4 +1,5 @@ import type ws from 'ws' +import * as Log from '../../build/output/log' import type { webpack } from 'next/dist/compiled/webpack/webpack' import type { NextConfigComplete } from '../config-shared' import { EventEmitter } from 'events' @@ -514,6 +515,13 @@ export function onDemandEntryHandler({ return { async ensurePage(page: string, clientOnly: boolean): Promise { + const stalledTime = 60 + const stalledEnsureTimeout = setTimeout(() => { + Log.warn( + `Ensuring ${page} has taken longer than ${stalledTime}s, if this continues to stall this may be a bug` + ) + }, stalledTime * 1000) + const pagePathData = await findPagePathData( rootDir, pagesDir, @@ -630,6 +638,7 @@ export function onDemandEntryHandler({ invalidator.invalidate([...added.keys()]) await Promise.all(invalidatePromises) } + clearTimeout(stalledEnsureTimeout) }, onHMR(client: ws) { diff --git a/packages/next/server/next-server.ts b/packages/next/server/next-server.ts index 333bd82e1360..f0e869773d0c 100644 --- a/packages/next/server/next-server.ts +++ b/packages/next/server/next-server.ts @@ -73,6 +73,7 @@ import BaseServer, { prepareServerlessUrl, RoutingItem, NoFallbackError, + RequestContext, } from './base-server' import { getPagePath, requireFontManifest } from './require' import { denormalizePagePath } from '../shared/lib/page-path/denormalize-page-path' @@ -95,7 +96,6 @@ import { checkIsManualRevalidate } from './api-utils' import { shouldUseReactRoot, isTargetLikeServerless } from './utils' import ResponseCache from './response-cache' import { IncrementalCache } from './lib/incremental-cache' -import { getSortedRoutes } from '../shared/lib/router/utils/sorted-routes' if (shouldUseReactRoot) { ;(process.env as any).__NEXT_REACT_ROOT = 'true' @@ -673,16 +673,22 @@ export default class NextNodeServer extends BaseServer { page: string, builtPagePath: string ): Promise { - const handledAsEdgeFunction = await this.runEdgeFunction({ - req, - res, - query, - params, - page, - }) + const edgeFunctions = this.getEdgeFunctions() + + for (const item of edgeFunctions) { + if (item.page === page) { + const handledAsEdgeFunction = await this.runEdgeFunction({ + req, + res, + query, + params, + page, + }) - if (handledAsEdgeFunction) { - return true + if (handledAsEdgeFunction) { + return true + } + } } const pageModule = await require(builtPagePath) @@ -801,6 +807,28 @@ export default class NextNodeServer extends BaseServer { ) } + protected async renderPageComponent( + ctx: RequestContext, + bubbleNoFallback: boolean + ) { + const edgeFunctions = this.getEdgeFunctions() + + for (const item of edgeFunctions) { + if (item.page === ctx.pathname) { + await this.runEdgeFunction({ + req: ctx.req, + res: ctx.res, + query: ctx.query, + params: ctx.renderOpts.params, + page: ctx.pathname, + }) + return null + } + } + + return super.renderPageComponent(ctx, bubbleNoFallback) + } + protected async findPageComponents( pathname: string, query: NextParsedUrlQuery = {}, @@ -1452,20 +1480,16 @@ export default class NextNodeServer extends BaseServer { return manifest } - /** - * Return a list of middleware routing items. This method exists to be later - * overridden by the development server in order to use a different source - * to get the list. - */ + /** Returns the middleware routing item if there is one. */ protected getMiddleware(): RoutingItem | undefined { const manifest = this.getMiddlewareManifest() - const rootMiddleware = manifest?.middleware?.['/'] - if (!rootMiddleware) { + const middleware = manifest?.middleware?.['/'] + if (!middleware) { return } return { - match: getMiddlewareMatcher(rootMiddleware), + match: getMiddlewareMatcher(middleware), page: '/', } } @@ -1476,13 +1500,10 @@ export default class NextNodeServer extends BaseServer { return [] } - // Make sure to sort function routes too. - return getSortedRoutes(Object.keys(manifest.functions)).map((page) => { - return { - match: getMiddlewareMatcher(manifest.functions[page]), - page, - } - }) + return Object.keys(manifest.functions).map((page) => ({ + match: getMiddlewareMatcher(manifest.functions[page]), + page, + })) } /** @@ -1857,45 +1878,6 @@ export default class NextNodeServer extends BaseServer { routes.push(middlewareCatchAllRoute) } - if (this.getEdgeFunctions().length) { - const edgeCatchAllRoute: Route = { - match: getPathMatch('/:path*'), - type: 'route', - name: 'edge functions catchall', - fn: async (req, res, _params, parsed) => { - const edgeFunctions = this.getEdgeFunctions() - if (!edgeFunctions.length) return { finished: false } - - const { query, pathname } = parsed - const normalizedPathname = removeTrailingSlash(pathname || '') - let page = normalizedPathname - let params: Params | undefined = undefined - - for (const edgeFunction of edgeFunctions) { - const matched = edgeFunction.match(page) - if (matched) { - params = matched - page = edgeFunction.page - break - } - } - - const edgeSSRResult = await this.runEdgeFunction({ - req, - res, - query, - params, - page, - }) - - return { - finished: !!edgeSSRResult, - } - }, - } - - routes.push(edgeCatchAllRoute) - } } return routes @@ -1946,15 +1928,11 @@ export default class NextNodeServer extends BaseServer { }): Promise { let middlewareInfo: ReturnType | undefined - try { - await this.ensureEdgeFunction(params.page) - middlewareInfo = this.getEdgeFunctionInfo({ - page: params.page, - middleware: false, - }) - } catch { - return null - } + await this.ensureEdgeFunction(params.page) + middlewareInfo = this.getEdgeFunctionInfo({ + page: params.page, + middleware: false, + }) if (!middlewareInfo) { return null diff --git a/packages/next/server/router.ts b/packages/next/server/router.ts index f06b4443249a..0cb309f823af 100644 --- a/packages/next/server/router.ts +++ b/packages/next/server/router.ts @@ -220,8 +220,7 @@ export default class Router { - User rewrites (checking filesystem and pages each match) */ - const [middlewareCatchAllRoute, edgeSSRCatchAllRoute] = - this.catchAllMiddleware + const [middlewareCatchAllRoute] = this.catchAllMiddleware const allRoutes = [ ...(middlewareCatchAllRoute ? this.fsRoutes @@ -244,7 +243,6 @@ export default class Router { // disabled ...(this.useFileSystemPublicRoutes ? [ - ...(edgeSSRCatchAllRoute ? [edgeSSRCatchAllRoute] : []), { type: 'route', name: 'page checker', @@ -299,12 +297,7 @@ export default class Router { // We only check the catch-all route if public page routes hasn't been // disabled - ...(this.useFileSystemPublicRoutes - ? [ - ...(edgeSSRCatchAllRoute ? [edgeSSRCatchAllRoute] : []), - this.catchAllRoute, - ] - : []), + ...(this.useFileSystemPublicRoutes ? [this.catchAllRoute] : []), ] for (const testRoute of allRoutes) { diff --git a/test/e2e/edge-vs.-non-edge-api-route-priority/index.test.ts b/test/e2e/edge-vs.-non-edge-api-route-priority/index.test.ts new file mode 100644 index 000000000000..48fe0a3e92ba --- /dev/null +++ b/test/e2e/edge-vs.-non-edge-api-route-priority/index.test.ts @@ -0,0 +1,33 @@ +import { createNext } from 'e2e-utils' +import { NextInstance } from 'test/lib/next-modes/base' +import { fetchViaHTTP } from 'next-test-utils' + +describe('Edge vs. non-Edge API route priority', () => { + let next: NextInstance + + beforeAll(async () => { + next = await createNext({ + files: { + 'pages/api/user/login.js': ` + export default async function handler(_, res) { + res.send('from login.js') + } + `, + 'pages/api/user/[id].js': ` + export const config = { + runtime: 'experimental-edge', + } + export default async function handler() { + return new Response('from [id].js') + }`, + }, + dependencies: {}, + }) + }) + afterAll(() => next.destroy()) + + it('more specific route should match', async () => { + const res = await fetchViaHTTP(next.url, '/api/user/login') + expect(await res.text()).toBe('from login.js') + }) +}) diff --git a/test/lib/next-test-utils.js b/test/lib/next-test-utils.js index 1bcb877dac75..d46441e156f3 100644 --- a/test/lib/next-test-utils.js +++ b/test/lib/next-test-utils.js @@ -114,6 +114,7 @@ export function renderViaHTTP(appPort, pathname, query, opts) { return fetchViaHTTP(appPort, pathname, query, opts).then((res) => res.text()) } +/** @return {Promise} */ export function fetchViaHTTP(appPort, pathname, query, opts) { const url = `${pathname}${ typeof query === 'string' ? query : query ? `?${qs.stringify(query)}` : '' From 53f0e2b31c1478832811a6d24f391a27b8b07360 Mon Sep 17 00:00:00 2001 From: Steven Date: Wed, 17 Aug 2022 00:29:55 +0100 Subject: [PATCH 02/41] Update image tests files from *.js to *.ts (#39663) Let's utilize typescript for our tests --- package.json | 2 +- pnpm-lock.yaml | 8 ++-- .../test/{index.test.js => index.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 12 +++--- .../test/{static.test.js => static.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 40 +++++++++---------- .../test/{static.test.js => static.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 0 .../react-virtualized/test/index.test.ts} | 4 +- .../test/{index.test.js => index.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 4 +- .../test/{index.test.js => index.test.ts} | 18 ++++----- .../test/{static.test.js => static.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 0 .../react-virtualized/test/index.test.ts} | 4 +- .../test/{index.test.js => index.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 0 .../test/{index.test.js => index.test.ts} | 4 +- test/lib/browsers/base.ts | 4 +- test/lib/browsers/playwright.ts | 4 +- test/lib/browsers/selenium.ts | 4 +- test/lib/next-webdriver.ts | 14 +++---- 32 files changed, 56 insertions(+), 66 deletions(-) rename test/integration/image-component/asset-prefix/test/{index.test.js => index.test.ts} (100%) rename test/integration/image-component/base-path/test/{index.test.js => index.test.ts} (98%) rename test/integration/image-component/base-path/test/{static.test.js => static.test.ts} (100%) rename test/integration/image-component/basic/test/{index.test.js => index.test.ts} (100%) rename test/integration/image-component/custom-resolver/test/{index.test.js => index.test.ts} (100%) rename test/integration/image-component/default/test/{index.test.js => index.test.ts} (98%) rename test/integration/image-component/default/test/{static.test.js => static.test.ts} (100%) rename test/integration/image-component/image-from-node-modules/test/{index.test.js => index.test.ts} (100%) rename test/integration/image-component/no-intersection-observer-fallback/test/{index.test.js => index.test.ts} (100%) rename test/integration/image-component/noscript/test/{index.test.js => index.test.ts} (100%) rename test/integration/{image-future/react-virtualized/test/index.test.js => image-component/react-virtualized/test/index.test.ts} (96%) rename test/integration/image-component/svgo-webpack/test/{index.test.js => index.test.ts} (100%) rename test/integration/image-component/trailing-slash/test/{index.test.js => index.test.ts} (100%) rename test/integration/image-component/typescript/test/{index.test.js => index.test.ts} (100%) rename test/integration/image-component/unicode/test/{index.test.js => index.test.ts} (100%) rename test/integration/image-component/unoptimized/test/{index.test.js => index.test.ts} (98%) rename test/integration/image-future/default/test/{index.test.js => index.test.ts} (98%) rename test/integration/image-future/default/test/{static.test.js => static.test.ts} (100%) rename test/integration/image-future/image-from-node-modules/test/{index.test.js => index.test.ts} (100%) rename test/integration/image-future/noscript/test/{index.test.js => index.test.ts} (100%) rename test/integration/{image-component/react-virtualized/test/index.test.js => image-future/react-virtualized/test/index.test.ts} (96%) rename test/integration/image-future/svgo-webpack/test/{index.test.js => index.test.ts} (100%) rename test/integration/image-future/trailing-slash/test/{index.test.js => index.test.ts} (100%) rename test/integration/image-future/typescript/test/{index.test.js => index.test.ts} (100%) rename test/integration/image-future/unicode/test/{index.test.js => index.test.ts} (100%) rename test/integration/image-future/unoptimized/test/{index.test.js => index.test.ts} (98%) diff --git a/package.json b/package.json index cea308b687be..698760d043cf 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "@testing-library/react": "13.0.0", "@types/cheerio": "0.22.16", "@types/fs-extra": "8.1.0", - "@types/html-validator": "5.0.2", + "@types/html-validator": "5.0.3", "@types/http-proxy": "1.17.3", "@types/jest": "24.0.13", "@types/node": "13.11.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 51bd7f91bd02..70af320d27c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -37,7 +37,7 @@ importers: '@testing-library/react': 13.0.0 '@types/cheerio': 0.22.16 '@types/fs-extra': 8.1.0 - '@types/html-validator': 5.0.2 + '@types/html-validator': 5.0.3 '@types/http-proxy': 1.17.3 '@types/jest': 24.0.13 '@types/node': 13.11.0 @@ -191,7 +191,7 @@ importers: '@testing-library/react': 13.0.0_biqbaboplfbrettd7655fr4n2y '@types/cheerio': 0.22.16 '@types/fs-extra': 8.1.0 - '@types/html-validator': 5.0.2 + '@types/html-validator': 5.0.3 '@types/http-proxy': 1.17.3 '@types/jest': 24.0.13 '@types/node': 13.11.0 @@ -5635,8 +5635,8 @@ packages: '@types/unist': 2.0.3 dev: true - /@types/html-validator/5.0.2: - resolution: {integrity: sha512-10KDAqGQ29BTEdOOWTYyJF6R1oSLDtFlSgDc6P02Y6CXo8kA0SHeRPoieX/EXiMOLpM1e6G1QlKgFCbhxrtxuQ==} + /@types/html-validator/5.0.3: + resolution: {integrity: sha512-QcKpR0cAWhLy7T3J24dwCuviRyS8xj/gVtFxcfZer9lfRgHdSAUFvE02nI/rsgIxSr71Z/2moXVYvWl2fTAzHQ==} dependencies: '@types/node': 17.0.21 dev: true diff --git a/test/integration/image-component/asset-prefix/test/index.test.js b/test/integration/image-component/asset-prefix/test/index.test.ts similarity index 100% rename from test/integration/image-component/asset-prefix/test/index.test.js rename to test/integration/image-component/asset-prefix/test/index.test.ts diff --git a/test/integration/image-component/base-path/test/index.test.js b/test/integration/image-component/base-path/test/index.test.ts similarity index 98% rename from test/integration/image-component/base-path/test/index.test.js rename to test/integration/image-component/base-path/test/index.test.ts index c26a714fde1b..e85b1e3f3a8d 100644 --- a/test/integration/image-component/base-path/test/index.test.js +++ b/test/integration/image-component/base-path/test/index.test.ts @@ -308,16 +308,16 @@ function runTests(mode) { expect(await getComputed(browser, id, 'width')).toBe(width) expect(await getComputed(browser, id, 'height')).toBe(height) const delta = 150 - const largeWidth = width + delta - const largeHeight = height + delta + const largeWidth = Number(width) + delta + const largeHeight = Number(height) + delta await browser.setDimensions({ width: largeWidth, height: largeHeight, }) expect(await getComputed(browser, id, 'width')).toBe(largeWidth) expect(await getComputed(browser, id, 'height')).toBe(largeHeight) - const smallWidth = width - delta - const smallHeight = height - delta + const smallWidth = Number(width) - delta + const smallHeight = Number(height) - delta await browser.setDimensions({ width: smallWidth, height: smallHeight, @@ -389,9 +389,7 @@ function runTests(mode) { expect(await hasRedbox(browser)).toBe(false) await check(async () => { - return (await browser.log('browser')) - .map((log) => log.message) - .join('\n') + return (await browser.log()).map((log) => log.message).join('\n') }, /Image is missing required "src" property/gm) }) diff --git a/test/integration/image-component/base-path/test/static.test.js b/test/integration/image-component/base-path/test/static.test.ts similarity index 100% rename from test/integration/image-component/base-path/test/static.test.js rename to test/integration/image-component/base-path/test/static.test.ts diff --git a/test/integration/image-component/basic/test/index.test.js b/test/integration/image-component/basic/test/index.test.ts similarity index 100% rename from test/integration/image-component/basic/test/index.test.js rename to test/integration/image-component/basic/test/index.test.ts diff --git a/test/integration/image-component/custom-resolver/test/index.test.js b/test/integration/image-component/custom-resolver/test/index.test.ts similarity index 100% rename from test/integration/image-component/custom-resolver/test/index.test.js rename to test/integration/image-component/custom-resolver/test/index.test.ts diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.ts similarity index 98% rename from test/integration/image-component/default/test/index.test.js rename to test/integration/image-component/default/test/index.test.ts index 4401c4fff933..ba142e170638 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.ts @@ -151,7 +151,7 @@ function runTests(mode) { await browser.elementById('responsive2').getAttribute('loading') ).toBe(null) - const warnings = (await browser.log('browser')) + const warnings = (await browser.log()) .map((log) => log.message) .join('\n') expect(warnings).not.toMatch( @@ -607,16 +607,16 @@ function runTests(mode) { expect(await getComputed(browser, id, 'width')).toBe(width) expect(await getComputed(browser, id, 'height')).toBe(height) const delta = 150 - const largeWidth = width + delta - const largeHeight = height + delta + const largeWidth = Number(width) + delta + const largeHeight = Number(height) + delta await browser.setDimensions({ width: largeWidth, height: largeHeight, }) expect(await getComputed(browser, id, 'width')).toBe(largeWidth) expect(await getComputed(browser, id, 'height')).toBe(largeHeight) - const smallWidth = width - delta - const smallHeight = height - delta + const smallWidth = Number(width) - delta + const smallHeight = Number(height) - delta await browser.setDimensions({ width: smallWidth, height: smallHeight, @@ -722,7 +722,7 @@ function runTests(mode) { if (mode === 'dev') { await waitFor(1000) - const warnings = (await browser.log('browser')) + const warnings = (await browser.log()) .map((log) => log.message) .join('\n') expect(warnings).toMatch( @@ -749,9 +749,7 @@ function runTests(mode) { expect(await hasRedbox(browser)).toBe(false) await check(async () => { - return (await browser.log('browser')) - .map((log) => log.message) - .join('\n') + return (await browser.log()).map((log) => log.message).join('\n') }, /Image is missing required "src" property/gm) }) @@ -807,9 +805,7 @@ function runTests(mode) { const browser = await webdriver(appPort, '/layout-responsive-inside-flex') await browser.eval(`document.getElementById("img").scrollIntoView()`) await check(async () => { - return (await browser.log('browser')) - .map((log) => log.message) - .join('\n') + return (await browser.log()).map((log) => log.message).join('\n') }, /Image with src (.*)jpg(.*) may not render properly as a child of a flex container. Consider wrapping the image with a div to configure the width/gm) expect(await hasRedbox(browser)).toBe(false) }) @@ -821,7 +817,7 @@ function runTests(mode) { ) await browser.eval(`document.querySelector("footer").scrollIntoView()`) await waitFor(1000) - const warnings = (await browser.log('browser')) + const warnings = (await browser.log()) .map((log) => log.message) .join('\n') expect(warnings).toMatch( @@ -842,7 +838,7 @@ function runTests(mode) { it('should warn when using a very small image with placeholder=blur', async () => { const browser = await webdriver(appPort, '/small-img-import') - const warnings = (await browser.log('browser')) + const warnings = (await browser.log()) .map((log) => log.message) .join('\n') expect(await hasRedbox(browser)).toBe(false) @@ -854,7 +850,7 @@ function runTests(mode) { it('should not warn when Image is child of p', async () => { const browser = await webdriver(appPort, '/inside-paragraph') - const warnings = (await browser.log('browser')) + const warnings = (await browser.log()) .map((log) => log.message) .join('\n') expect(await hasRedbox(browser)).toBe(false) @@ -879,7 +875,7 @@ function runTests(mode) { return 'done' }, 'done') await waitFor(1000) - const warnings = (await browser.log('browser')) + const warnings = (await browser.log()) .map((log) => log.message) .join('\n') expect(await hasRedbox(browser)).toBe(false) @@ -896,7 +892,7 @@ function runTests(mode) { it('should warn when loader is missing width', async () => { const browser = await webdriver(appPort, '/invalid-loader') await browser.eval(`document.querySelector("footer").scrollIntoView()`) - const warnings = (await browser.log('browser')) + const warnings = (await browser.log()) .map((log) => log.message) .join('\n') expect(await hasRedbox(browser)).toBe(false) @@ -920,7 +916,7 @@ function runTests(mode) { it('should warn when using sizes with incorrect layout', async () => { const browser = await webdriver(appPort, '/invalid-sizes') await browser.eval(`document.querySelector("footer").scrollIntoView()`) - const warnings = (await browser.log('browser')) + const warnings = (await browser.log()) .map((log) => log.message) .join('\n') expect(await hasRedbox(browser)).toBe(false) @@ -941,7 +937,7 @@ function runTests(mode) { it('should not warn when svg, even if with loader prop or without', async () => { const browser = await webdriver(appPort, '/loader-svg') await browser.eval(`document.querySelector("footer").scrollIntoView()`) - const warnings = (await browser.log('browser')) + const warnings = (await browser.log()) .map((log) => log.message) .join('\n') expect(await hasRedbox(browser)).toBe(false) @@ -981,7 +977,7 @@ function runTests(mode) { return 'done' }, 'done') await waitFor(1000) - const warnings = (await browser.log('browser')) + const warnings = (await browser.log()) .map((log) => log.message) .filter((log) => log.startsWith('Image with src')) expect(warnings[0]).toMatch( @@ -1397,12 +1393,12 @@ function runTests(mode) { await waitFor(1000) expect(await browser.hasElementByCssSelector('img')).toBeTruthy() const url = await browser.url() - const result = await validateHTML({ + const result = (await validateHTML({ url, format: 'json', isLocal: true, validator: 'whatwg', - }) + })) as any expect(result.isValid).toBe(true) expect(result.errors).toEqual([]) } finally { diff --git a/test/integration/image-component/default/test/static.test.js b/test/integration/image-component/default/test/static.test.ts similarity index 100% rename from test/integration/image-component/default/test/static.test.js rename to test/integration/image-component/default/test/static.test.ts diff --git a/test/integration/image-component/image-from-node-modules/test/index.test.js b/test/integration/image-component/image-from-node-modules/test/index.test.ts similarity index 100% rename from test/integration/image-component/image-from-node-modules/test/index.test.js rename to test/integration/image-component/image-from-node-modules/test/index.test.ts diff --git a/test/integration/image-component/no-intersection-observer-fallback/test/index.test.js b/test/integration/image-component/no-intersection-observer-fallback/test/index.test.ts similarity index 100% rename from test/integration/image-component/no-intersection-observer-fallback/test/index.test.js rename to test/integration/image-component/no-intersection-observer-fallback/test/index.test.ts diff --git a/test/integration/image-component/noscript/test/index.test.js b/test/integration/image-component/noscript/test/index.test.ts similarity index 100% rename from test/integration/image-component/noscript/test/index.test.js rename to test/integration/image-component/noscript/test/index.test.ts diff --git a/test/integration/image-future/react-virtualized/test/index.test.js b/test/integration/image-component/react-virtualized/test/index.test.ts similarity index 96% rename from test/integration/image-future/react-virtualized/test/index.test.js rename to test/integration/image-component/react-virtualized/test/index.test.ts index 6e98101e95e5..84bdd65188fb 100644 --- a/test/integration/image-future/react-virtualized/test/index.test.js +++ b/test/integration/image-component/react-virtualized/test/index.test.ts @@ -16,7 +16,7 @@ import http from 'http' const appDir = join(__dirname, '../') let appPort let app -let proxyServer +let proxyServer: http.Server let cancelCount = 0 describe('react-virtualized wrapping next/image', () => { describe('production', () => { @@ -51,7 +51,7 @@ describe('react-virtualized wrapping next/image', () => { console.warn('Failed to proxy', err) }) - await new Promise((resolve) => { + await new Promise((resolve) => { proxyServer.listen(appPort, () => resolve()) }) }) diff --git a/test/integration/image-component/svgo-webpack/test/index.test.js b/test/integration/image-component/svgo-webpack/test/index.test.ts similarity index 100% rename from test/integration/image-component/svgo-webpack/test/index.test.js rename to test/integration/image-component/svgo-webpack/test/index.test.ts diff --git a/test/integration/image-component/trailing-slash/test/index.test.js b/test/integration/image-component/trailing-slash/test/index.test.ts similarity index 100% rename from test/integration/image-component/trailing-slash/test/index.test.js rename to test/integration/image-component/trailing-slash/test/index.test.ts diff --git a/test/integration/image-component/typescript/test/index.test.js b/test/integration/image-component/typescript/test/index.test.ts similarity index 100% rename from test/integration/image-component/typescript/test/index.test.js rename to test/integration/image-component/typescript/test/index.test.ts diff --git a/test/integration/image-component/unicode/test/index.test.js b/test/integration/image-component/unicode/test/index.test.ts similarity index 100% rename from test/integration/image-component/unicode/test/index.test.js rename to test/integration/image-component/unicode/test/index.test.ts diff --git a/test/integration/image-component/unoptimized/test/index.test.js b/test/integration/image-component/unoptimized/test/index.test.ts similarity index 98% rename from test/integration/image-component/unoptimized/test/index.test.js rename to test/integration/image-component/unoptimized/test/index.test.ts index 552749031632..2ad21978a2eb 100644 --- a/test/integration/image-component/unoptimized/test/index.test.js +++ b/test/integration/image-component/unoptimized/test/index.test.ts @@ -107,7 +107,7 @@ describe('Unoptimized Image Tests', () => { await killApp(app) }) - runTests('dev') + runTests() }) describe('server mode', () => { @@ -120,6 +120,6 @@ describe('Unoptimized Image Tests', () => { await killApp(app) }) - runTests('server') + runTests() }) }) diff --git a/test/integration/image-future/default/test/index.test.js b/test/integration/image-future/default/test/index.test.ts similarity index 98% rename from test/integration/image-future/default/test/index.test.js rename to test/integration/image-future/default/test/index.test.ts index 95570ddbd14c..bf6a00d046e4 100644 --- a/test/integration/image-future/default/test/index.test.js +++ b/test/integration/image-future/default/test/index.test.ts @@ -624,9 +624,7 @@ function runTests(mode) { expect(await hasRedbox(browser)).toBe(false) await check(async () => { - return (await browser.log('browser')) - .map((log) => log.message) - .join('\n') + return (await browser.log()).map((log) => log.message).join('\n') }, /Image is missing required "src" property/gm) }) @@ -726,7 +724,7 @@ function runTests(mode) { it('should warn when using a very small image with placeholder=blur', async () => { const browser = await webdriver(appPort, '/small-img-import') - const warnings = (await browser.log('browser')) + const warnings = (await browser.log()) .map((log) => log.message) .join('\n') expect(await hasRedbox(browser)).toBe(false) @@ -738,7 +736,7 @@ function runTests(mode) { it('should not warn when Image is child of p', async () => { const browser = await webdriver(appPort, '/inside-paragraph') - const warnings = (await browser.log('browser')) + const warnings = (await browser.log()) .map((log) => log.message) .join('\n') expect(await hasRedbox(browser)).toBe(false) @@ -780,7 +778,7 @@ function runTests(mode) { it('should warn when loader is missing width', async () => { const browser = await webdriver(appPort, '/invalid-loader') await browser.eval(`document.querySelector("footer").scrollIntoView()`) - const warnings = (await browser.log('browser')) + const warnings = (await browser.log()) .map((log) => log.message) .join('\n') expect(await hasRedbox(browser)).toBe(false) @@ -804,7 +802,7 @@ function runTests(mode) { it('should not warn when svg, even if with loader prop or without', async () => { const browser = await webdriver(appPort, '/loader-svg') await browser.eval(`document.querySelector("footer").scrollIntoView()`) - const warnings = (await browser.log('browser')) + const warnings = (await browser.log()) .map((log) => log.message) .join('\n') expect(await hasRedbox(browser)).toBe(false) @@ -844,7 +842,7 @@ function runTests(mode) { return 'done' }, 'done') await waitFor(1000) - const warnings = (await browser.log('browser')) + const warnings = (await browser.log()) .map((log) => log.message) .filter((log) => log.startsWith('Image with src')) expect(warnings[0]).toMatch( @@ -1120,12 +1118,12 @@ function runTests(mode) { await waitFor(1000) expect(await browser.hasElementByCssSelector('img')).toBeTruthy() const url = await browser.url() - const result = await validateHTML({ + const result = (await validateHTML({ url, format: 'json', isLocal: true, validator: 'whatwg', - }) + })) as any expect(result.isValid).toBe(true) expect(result.errors).toEqual([]) } finally { diff --git a/test/integration/image-future/default/test/static.test.js b/test/integration/image-future/default/test/static.test.ts similarity index 100% rename from test/integration/image-future/default/test/static.test.js rename to test/integration/image-future/default/test/static.test.ts diff --git a/test/integration/image-future/image-from-node-modules/test/index.test.js b/test/integration/image-future/image-from-node-modules/test/index.test.ts similarity index 100% rename from test/integration/image-future/image-from-node-modules/test/index.test.js rename to test/integration/image-future/image-from-node-modules/test/index.test.ts diff --git a/test/integration/image-future/noscript/test/index.test.js b/test/integration/image-future/noscript/test/index.test.ts similarity index 100% rename from test/integration/image-future/noscript/test/index.test.js rename to test/integration/image-future/noscript/test/index.test.ts diff --git a/test/integration/image-component/react-virtualized/test/index.test.js b/test/integration/image-future/react-virtualized/test/index.test.ts similarity index 96% rename from test/integration/image-component/react-virtualized/test/index.test.js rename to test/integration/image-future/react-virtualized/test/index.test.ts index 6e98101e95e5..84bdd65188fb 100644 --- a/test/integration/image-component/react-virtualized/test/index.test.js +++ b/test/integration/image-future/react-virtualized/test/index.test.ts @@ -16,7 +16,7 @@ import http from 'http' const appDir = join(__dirname, '../') let appPort let app -let proxyServer +let proxyServer: http.Server let cancelCount = 0 describe('react-virtualized wrapping next/image', () => { describe('production', () => { @@ -51,7 +51,7 @@ describe('react-virtualized wrapping next/image', () => { console.warn('Failed to proxy', err) }) - await new Promise((resolve) => { + await new Promise((resolve) => { proxyServer.listen(appPort, () => resolve()) }) }) diff --git a/test/integration/image-future/svgo-webpack/test/index.test.js b/test/integration/image-future/svgo-webpack/test/index.test.ts similarity index 100% rename from test/integration/image-future/svgo-webpack/test/index.test.js rename to test/integration/image-future/svgo-webpack/test/index.test.ts diff --git a/test/integration/image-future/trailing-slash/test/index.test.js b/test/integration/image-future/trailing-slash/test/index.test.ts similarity index 100% rename from test/integration/image-future/trailing-slash/test/index.test.js rename to test/integration/image-future/trailing-slash/test/index.test.ts diff --git a/test/integration/image-future/typescript/test/index.test.js b/test/integration/image-future/typescript/test/index.test.ts similarity index 100% rename from test/integration/image-future/typescript/test/index.test.js rename to test/integration/image-future/typescript/test/index.test.ts diff --git a/test/integration/image-future/unicode/test/index.test.js b/test/integration/image-future/unicode/test/index.test.ts similarity index 100% rename from test/integration/image-future/unicode/test/index.test.js rename to test/integration/image-future/unicode/test/index.test.ts diff --git a/test/integration/image-future/unoptimized/test/index.test.js b/test/integration/image-future/unoptimized/test/index.test.ts similarity index 98% rename from test/integration/image-future/unoptimized/test/index.test.js rename to test/integration/image-future/unoptimized/test/index.test.ts index 81c815ab244e..cad697645aa2 100644 --- a/test/integration/image-future/unoptimized/test/index.test.js +++ b/test/integration/image-future/unoptimized/test/index.test.ts @@ -102,7 +102,7 @@ describe('Unoptimized Image Tests', () => { await killApp(app) }) - runTests('dev') + runTests() }) describe('server mode', () => { @@ -115,6 +115,6 @@ describe('Unoptimized Image Tests', () => { await killApp(app) }) - runTests('server') + runTests() }) }) diff --git a/test/lib/browsers/base.ts b/test/lib/browsers/base.ts index 499f4855353c..748270aca302 100644 --- a/test/lib/browsers/base.ts +++ b/test/lib/browsers/base.ts @@ -97,7 +97,9 @@ export class BrowserInterface { async hasElementByCssSelector(selector: string): Promise { return false } - async log(): Promise { + async log(): Promise< + { source: 'error' | 'info' | 'log'; message: string }[] + > { return [] } async websocketFrames(): Promise { diff --git a/test/lib/browsers/playwright.ts b/test/lib/browsers/playwright.ts index 772441482c45..cfa313108c03 100644 --- a/test/lib/browsers/playwright.ts +++ b/test/lib/browsers/playwright.ts @@ -27,7 +27,7 @@ export async function quit() { browser = undefined } -class Playwright extends BrowserInterface { +export class Playwright extends BrowserInterface { private activeTrace?: string private eventCallbacks: Record void>> = { request: new Set(), @@ -385,5 +385,3 @@ class Playwright extends BrowserInterface { return this.chain(() => page.evaluate('window.location.href')) as any } } - -export default Playwright diff --git a/test/lib/browsers/selenium.ts b/test/lib/browsers/selenium.ts index b85f0c6b148a..e6e8c1aa001e 100644 --- a/test/lib/browsers/selenium.ts +++ b/test/lib/browsers/selenium.ts @@ -42,7 +42,7 @@ export async function quit() { seleniumServer = undefined } -class Selenium extends BrowserInterface { +export class Selenium extends BrowserInterface { private browserName: string // TODO: support setting locale @@ -356,5 +356,3 @@ class Selenium extends BrowserInterface { return this.chain(() => browser.getCurrentUrl()) as any } } - -export default Selenium diff --git a/test/lib/next-webdriver.ts b/test/lib/next-webdriver.ts index dd3f7a67faae..a2d3ab211321 100644 --- a/test/lib/next-webdriver.ts +++ b/test/lib/next-webdriver.ts @@ -26,7 +26,7 @@ if (isBrowserStack) { } } -let browserQuit +let browserQuit: () => Promise if (typeof afterAll === 'function') { afterAll(async () => { @@ -81,13 +81,13 @@ export default async function webdriver( // we import only the needed interface if (USE_SELENIUM) { - const browserMod = require('./browsers/selenium') - CurrentInterface = browserMod.default - browserQuit = browserMod.quit + const { Selenium, quit } = await import('./browsers/selenium') + CurrentInterface = Selenium + browserQuit = quit } else { - const browserMod = require('./browsers/playwright') - CurrentInterface = browserMod.default - browserQuit = browserMod.quit + const { Playwright, quit } = await import('./browsers/playwright') + CurrentInterface = Playwright + browserQuit = quit } const browser = new CurrentInterface() From 7fe5c883fcef99e49bffc7e4c83c4206a4ecddbf Mon Sep 17 00:00:00 2001 From: Sukka Date: Wed, 17 Aug 2022 09:59:32 +0800 Subject: [PATCH 03/41] fix(create-app): support github url has trailing slash (#39665) ## Bug - [x] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` The PR fixes #39642, by supporting GitHub repo URLs with a trailing slash while without branch and path. --- packages/create-next-app/helpers/examples.ts | 12 ++++++-- .../integration/create-next-app/index.test.ts | 30 +++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/packages/create-next-app/helpers/examples.ts b/packages/create-next-app/helpers/examples.ts index 62b3d3cd6afb..44af47b2acff 100644 --- a/packages/create-next-app/helpers/examples.ts +++ b/packages/create-next-app/helpers/examples.ts @@ -25,9 +25,15 @@ export async function getRepoInfo( const [, username, name, t, _branch, ...file] = url.pathname.split('/') const filePath = examplePath ? examplePath.replace(/^\//, '') : file.join('/') - // Support repos whose entire purpose is to be a NextJS example, e.g. - // https://github.com/:username/:my-cool-nextjs-example-repo-name. - if (t === undefined) { + if ( + // Support repos whose entire purpose is to be a NextJS example, e.g. + // https://github.com/:username/:my-cool-nextjs-example-repo-name. + t === undefined || + // Support GitHub URL that ends with a trailing slash, e.g. + // https://github.com/:username/:my-cool-nextjs-example-repo-name/ + // In this case "t" will be an empty string while the next part "_branch" will be undefined + (t === '' && _branch === undefined) + ) { const infoResponse = await got( `https://api.github.com/repos/${username}/${name}` ).catch((e) => e) diff --git a/test/integration/create-next-app/index.test.ts b/test/integration/create-next-app/index.test.ts index 2b7ba01131b7..ba7fd5df86c7 100644 --- a/test/integration/create-next-app/index.test.ts +++ b/test/integration/create-next-app/index.test.ts @@ -186,6 +186,36 @@ describe('create next app', () => { }) }) + it('should allow example with GitHub URL with trailing slash', async () => { + await usingTempDir(async (cwd) => { + const projectName = 'github-app' + const res = await run( + [ + projectName, + '--example', + 'https://github.com/vercel/nextjs-portfolio-starter/', + ], + { + cwd, + } + ) + + expect(res.exitCode).toBe(0) + expect( + fs.existsSync(path.join(cwd, projectName, 'package.json')) + ).toBeTruthy() + expect( + fs.existsSync(path.join(cwd, projectName, 'pages/index.mdx')) + ).toBeTruthy() + expect( + fs.existsSync(path.join(cwd, projectName, '.gitignore')) + ).toBeTruthy() + expect( + fs.existsSync(path.join(cwd, projectName, 'node_modules/next')) + ).toBe(true) + }) + }) + it('should allow example with GitHub URL and example-path', async () => { await usingTempDir(async (cwd) => { const projectName = 'github-example-path' From d4a98a15f7498ed93b4a9ec548e3a0f5c3849956 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Wed, 17 Aug 2022 10:39:37 +0100 Subject: [PATCH 04/41] Add todo for dependsOn (#39677) --- .../next/build/webpack/plugins/flight-client-entry-plugin.ts | 1 + 1 file changed, 1 insertion(+) 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 cd9a10fb2ab6..e67e005704b1 100644 --- a/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts +++ b/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts @@ -335,6 +335,7 @@ export class FlightClientEntryPlugin { return shouldInvalidate } + // TODO-APP: make sure dependsOn is added for layouts/pages addEntry( compilation: any, context: string, From c79b67ccedda1ae6fd9d05cfccf1d2842b94f43f Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Wed, 17 Aug 2022 12:56:52 +0200 Subject: [PATCH 05/41] 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 06/41] 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 07/41] 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 08/41] 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 09/41] 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 10/41] 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 11/41] 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 12/41] 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 13/41] 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 14/41] 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 15/41] 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 16/41] 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 17/41] [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 18/41] 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 19/41] 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 20/41] 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 21/41] 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 22/41] 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 23/41] =?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 24/41] 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 25/41] 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 26/41] 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 27/41] 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 28/41] 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 29/41] 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 30/41] [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 31/41] 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 32/41] 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 33/41] 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 34/41] 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 35/41] 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 36/41] 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 37/41] 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 38/41] 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 39/41] 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 40/41] 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 41/41] 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 {