From 524b31513a58e58e15862ac8aa3f27da8a47a267 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Thu, 5 Oct 2023 12:30:39 +0200 Subject: [PATCH 01/15] Fix logging level in actions test (#56473) This test was using the old format and because of that failed in Turbopack. This fixes that. --- test/e2e/app-dir/actions/next.config.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/e2e/app-dir/actions/next.config.js b/test/e2e/app-dir/actions/next.config.js index fcfc7dcc99ba..bec00d8d3b47 100644 --- a/test/e2e/app-dir/actions/next.config.js +++ b/test/e2e/app-dir/actions/next.config.js @@ -2,7 +2,9 @@ module.exports = { productionBrowserSourceMaps: true, experimental: { - logging: 'verbose', + logging: { + level: 'verbose', + }, serverActions: true, }, } From 7e1f31118bb53a57c9209b709e6f93598272a6db Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 5 Oct 2023 09:28:45 -0600 Subject: [PATCH 02/15] Component Module Types (#56454) This adds types for the component modules so that the modules no longer need to rely on `ComponentMod` being `any`. This allows stricter typing for those elements. This also improves types around template files to allow their exports to form the `ComponentMod` types. --- packages/next/src/build/templates/app-page.ts | 12 ++-- .../next/src/build/templates/app-route.ts | 12 ++-- .../src/build/templates/edge-app-route.ts | 1 - .../next/src/build/templates/middleware.ts | 5 +- .../next/src/build/templates/pages-api.ts | 9 +-- .../src/build/templates/pages-edge-api.ts | 5 +- packages/next/src/build/templates/pages.ts | 9 +-- packages/next/src/build/utils.ts | 27 ++------ .../build/webpack/loaders/next-app-loader.ts | 2 +- .../next/src/server/app-render/app-render.tsx | 68 +++++++------------ .../create-server-components-renderer.tsx | 9 +-- .../next/src/server/app-render/entry-base.ts | 8 +-- packages/next/src/server/app-render/types.ts | 6 +- .../app-page/module.compiled.d.ts | 1 + ...{module.compiled.ts => module.compiled.js} | 0 .../future/route-modules/app-page/module.ts | 7 ++ .../app-route/module.compiled.d.ts | 1 + ...{module.compiled.ts => module.compiled.js} | 0 .../future/route-modules/app-route/module.ts | 7 ++ .../pages-api/module.compiled.d.ts | 1 + ...{module.compiled.ts => module.compiled.js} | 0 .../future/route-modules/pages-api/module.ts | 7 ++ .../route-modules/pages/module.compiled.d.ts | 1 + ...{module.compiled.ts => module.compiled.js} | 0 .../future/route-modules/pages/module.ts | 6 ++ packages/next/src/server/lib/patch-fetch.ts | 10 +-- packages/next/src/server/load-components.ts | 8 +-- packages/next/src/server/render.tsx | 4 +- packages/next/types/compiled.d.ts | 9 +++ packages/next/types/misc.d.ts | 5 ++ packages/next/types/webpack.d.ts | 5 +- 31 files changed, 121 insertions(+), 124 deletions(-) create mode 100644 packages/next/src/server/future/route-modules/app-page/module.compiled.d.ts rename packages/next/src/server/future/route-modules/app-page/{module.compiled.ts => module.compiled.js} (100%) create mode 100644 packages/next/src/server/future/route-modules/app-route/module.compiled.d.ts rename packages/next/src/server/future/route-modules/app-route/{module.compiled.ts => module.compiled.js} (100%) create mode 100644 packages/next/src/server/future/route-modules/pages-api/module.compiled.d.ts rename packages/next/src/server/future/route-modules/pages-api/{module.compiled.ts => module.compiled.js} (100%) create mode 100644 packages/next/src/server/future/route-modules/pages/module.compiled.d.ts rename packages/next/src/server/future/route-modules/pages/{module.compiled.ts => module.compiled.js} (100%) diff --git a/packages/next/src/build/templates/app-page.ts b/packages/next/src/build/templates/app-page.ts index f0d2ab692e2a..11dba21ddded 100644 --- a/packages/next/src/build/templates/app-page.ts +++ b/packages/next/src/build/templates/app-page.ts @@ -1,13 +1,14 @@ import type { LoaderTree } from '../../server/lib/app-dir-module' -// @ts-ignore this need to be imported from next/dist to be external -import * as module from 'next/dist/server/future/route-modules/app-page/module.compiled' +import { AppPageRouteModule } from '../../server/future/route-modules/app-page/module.compiled' import { RouteKind } from '../../server/future/route-kind' -const AppPageRouteModule = - module.AppPageRouteModule as unknown as typeof import('../../server/future/route-modules/app-page/module').AppPageRouteModule - // These are injected by the loader afterwards. + +/** + * The tree created in next-app-loader that holds component segments and modules + * and I've updated it. + */ declare const tree: LoaderTree declare const pages: any @@ -18,7 +19,6 @@ declare const pages: any export { tree, pages } -// @ts-expect-error - replaced by webpack/turbopack loader export { default as GlobalError } from 'VAR_MODULE_GLOBAL_ERROR' // These are injected by the loader afterwards. diff --git a/packages/next/src/build/templates/app-route.ts b/packages/next/src/build/templates/app-route.ts index b4b8e5b0fe6c..2b8f9d101aee 100644 --- a/packages/next/src/build/templates/app-route.ts +++ b/packages/next/src/build/templates/app-route.ts @@ -1,17 +1,13 @@ import '../../server/node-polyfill-headers' -// @ts-ignore this need to be imported from next/dist to be external -import * as module from 'next/dist/server/future/route-modules/app-route/module.compiled' - -import type { AppRouteRouteModuleOptions } from '../../server/future/route-modules/app-route/module' +import { + AppRouteRouteModule, + type AppRouteRouteModuleOptions, +} from '../../server/future/route-modules/app-route/module.compiled' import { RouteKind } from '../../server/future/route-kind' -// @ts-expect-error - replaced by webpack/turbopack loader import * as userland from 'VAR_USERLAND' -const AppRouteRouteModule = - module.AppRouteRouteModule as unknown as typeof import('../../server/future/route-modules/app-route/module').AppRouteRouteModule - // These are injected by the loader afterwards. This is injected as a variable // instead of a replacement because this could also be `undefined` instead of // an empty string. diff --git a/packages/next/src/build/templates/edge-app-route.ts b/packages/next/src/build/templates/edge-app-route.ts index 69b12643ecfa..226252d06908 100644 --- a/packages/next/src/build/templates/edge-app-route.ts +++ b/packages/next/src/build/templates/edge-app-route.ts @@ -1,7 +1,6 @@ import { EdgeRouteModuleWrapper } from '../../server/web/edge-route-module-wrapper' // Import the userland code. -// @ts-expect-error - replaced by webpack/turbopack loader import * as module from 'VAR_USERLAND' export const ComponentMod = module diff --git a/packages/next/src/build/templates/middleware.ts b/packages/next/src/build/templates/middleware.ts index 15dda841e113..3ede209e4d28 100644 --- a/packages/next/src/build/templates/middleware.ts +++ b/packages/next/src/build/templates/middleware.ts @@ -1,9 +1,10 @@ -import '../../server/web/globals' import type { AdapterOptions } from '../../server/web/adapter' + +import '../../server/web/globals' + import { adapter } from '../../server/web/adapter' // Import the userland code. -// @ts-expect-error - replaced by webpack/turbopack loader import * as _mod from 'VAR_USERLAND' const mod = { ..._mod } diff --git a/packages/next/src/build/templates/pages-api.ts b/packages/next/src/build/templates/pages-api.ts index eaeec836cb61..54033fe42908 100644 --- a/packages/next/src/build/templates/pages-api.ts +++ b/packages/next/src/build/templates/pages-api.ts @@ -1,14 +1,9 @@ -// @ts-ignore this need to be imported from next/dist to be external -import * as module from 'next/dist/server/future/route-modules/pages-api/module.compiled' - +import { PagesAPIRouteModule } from '../../server/future/route-modules/pages-api/module.compiled' import { RouteKind } from '../../server/future/route-kind' -import { hoist } from './helpers' -const PagesAPIRouteModule = - module.PagesAPIRouteModule as unknown as typeof import('../../server/future/route-modules/pages-api/module').PagesAPIRouteModule +import { hoist } from './helpers' // Import the userland code. -// @ts-expect-error - replaced by webpack/turbopack loader import * as userland from 'VAR_USERLAND' // Re-export the handler (should be the default export). diff --git a/packages/next/src/build/templates/pages-edge-api.ts b/packages/next/src/build/templates/pages-edge-api.ts index 7d453a69720b..90b31feb21aa 100644 --- a/packages/next/src/build/templates/pages-edge-api.ts +++ b/packages/next/src/build/templates/pages-edge-api.ts @@ -1,10 +1,11 @@ -import '../../server/web/globals' import type { AdapterOptions } from '../../server/web/adapter' + +import '../../server/web/globals' + import { adapter } from '../../server/web/adapter' import { IncrementalCache } from '../../server/lib/incremental-cache' // Import the userland code. -// @ts-expect-error - replaced by webpack/turbopack loader import handler from 'VAR_USERLAND' const page = 'VAR_DEFINITION_PAGE' diff --git a/packages/next/src/build/templates/pages.ts b/packages/next/src/build/templates/pages.ts index b5def5d13c55..87093f682e65 100644 --- a/packages/next/src/build/templates/pages.ts +++ b/packages/next/src/build/templates/pages.ts @@ -1,21 +1,14 @@ -// @ts-ignore this need to be imported from next/dist to be external -import * as module from 'next/dist/server/future/route-modules/pages/module.compiled' +import { PagesRouteModule } from '../../server/future/route-modules/pages/module.compiled' import { RouteKind } from '../../server/future/route-kind' import { hoist } from './helpers' // Import the app and document modules. -// @ts-expect-error - replaced by webpack/turbopack loader import Document from 'VAR_MODULE_DOCUMENT' -// @ts-expect-error - replaced by webpack/turbopack loader import App from 'VAR_MODULE_APP' // Import the userland code. -// @ts-expect-error - replaced by webpack/turbopack loader import * as userland from 'VAR_USERLAND' -const PagesRouteModule = - module.PagesRouteModule as unknown as typeof import('../../server/future/route-modules/pages/module').PagesRouteModule - // Re-export the component (should be the default export). export default hoist(userland, 'default') diff --git a/packages/next/src/build/utils.ts b/packages/next/src/build/utils.ts index b12532aad7b1..824d86b9845e 100644 --- a/packages/next/src/build/utils.ts +++ b/packages/next/src/build/utils.ts @@ -14,8 +14,8 @@ import type { EdgeFunctionDefinition, MiddlewareManifest, } from './webpack/plugins/middleware-plugin' -import type { StaticGenerationAsyncStorage } from '../client/components/static-generation-async-storage.external' import type { WebpackLayerName } from '../lib/constants' +import type { AppPageModule } from '../server/future/route-modules/app-page/module' import '../server/require-hook' import '../server/node-polyfill-fetch' @@ -68,9 +68,7 @@ import { nodeFs } from '../server/lib/node-fs-methods' import * as ciEnvironment from '../telemetry/ci-info' import { normalizeAppPath } from '../shared/lib/router/utils/app-paths' import { denormalizeAppPagePath } from '../shared/lib/page-path/denormalize-app-path' - -const { AppRouteRouteModule } = - require('../server/future/route-modules/app-route/module.compiled') as typeof import('../server/future/route-modules/app-route/module') +import { AppRouteRouteModule } from '../server/future/route-modules/app-route/module.compiled' export type ROUTER_TYPE = 'pages' | 'app' @@ -1469,25 +1467,12 @@ export async function isPageStatic({ | undefined if (pageType === 'app') { - isClientComponent = isClientReference(componentsResult.ComponentMod) - const tree = componentsResult.ComponentMod.tree - - const staticGenerationAsyncStorage: StaticGenerationAsyncStorage = - componentsResult.ComponentMod.staticGenerationAsyncStorage - if (!staticGenerationAsyncStorage) { - throw new Error( - 'Invariant: staticGenerationAsyncStorage should be defined on the module' - ) - } + const ComponentMod: AppPageModule = componentsResult.ComponentMod - const serverHooks = componentsResult.ComponentMod.serverHooks - if (!serverHooks) { - throw new Error( - 'Invariant: serverHooks should be defined on the module' - ) - } + isClientComponent = isClientReference(componentsResult.ComponentMod) - const { routeModule } = componentsResult + const { tree, staticGenerationAsyncStorage, serverHooks, routeModule } = + ComponentMod const generateParams: GenerateParams = routeModule && AppRouteRouteModule.is(routeModule) diff --git a/packages/next/src/build/webpack/loaders/next-app-loader.ts b/packages/next/src/build/webpack/loaders/next-app-loader.ts index 017536bbc73d..69e97eb0812a 100644 --- a/packages/next/src/build/webpack/loaders/next-app-loader.ts +++ b/packages/next/src/build/webpack/loaders/next-app-loader.ts @@ -1,4 +1,4 @@ -import type webpack from 'webpack' +import type webpack from 'next/dist/compiled/webpack/webpack' import type { ValueOf } from '../../../shared/lib/constants' import type { ModuleReference, CollectedMetadata } from './metadata/types' diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx index 7245a38e788c..fcc5089e693c 100644 --- a/packages/next/src/server/app-render/app-render.tsx +++ b/packages/next/src/server/app-render/app-render.tsx @@ -10,9 +10,6 @@ import type { RenderOpts, Segment, } from './types' -import type { StaticGenerationAsyncStorage } from '../../client/components/static-generation-async-storage.external' -import type { StaticGenerationBailout } from '../../client/components/static-generation-bailout' -import type { RequestAsyncStorage } from '../../client/components/request-async-storage.external' import React from 'react' import { createServerComponentRenderer } from './create-server-components-renderer' @@ -237,6 +234,7 @@ export const renderToHTMLOrFlight: AppPageRender = ( }) patchFetch(ComponentMod) + /** * Rules of Static & Dynamic HTML: * @@ -252,12 +250,25 @@ export const renderToHTMLOrFlight: AppPageRender = ( */ const generateStaticHTML = supportsDynamicHTML !== true - const staticGenerationAsyncStorage: StaticGenerationAsyncStorage = - ComponentMod.staticGenerationAsyncStorage - const requestAsyncStorage: RequestAsyncStorage = - ComponentMod.requestAsyncStorage - const staticGenerationBailout: StaticGenerationBailout = - ComponentMod.staticGenerationBailout + // Pull out the hooks/references from the component. + const { + staticGenerationAsyncStorage, + requestAsyncStorage, + staticGenerationBailout, + LayoutRouter, + RenderFromTemplateContext, + createSearchParamsBailoutProxy, + StaticGenerationSearchParamsBailoutProvider, + serverHooks: { DynamicServerError }, + NotFoundBoundary, + renderToReadableStream, + AppRouter, + GlobalError, + tree: loaderTree, + preloadFont, + preconnect, + preloadStyle, + } = ComponentMod // we wrap the render in an AsyncLocalStorage context const wrappedRender = async () => { @@ -294,11 +305,6 @@ export const renderToHTMLOrFlight: AppPageRender = ( ) : undefined - /** - * The tree created in next-app-loader that holds component segments and modules - */ - const loaderTree: LoaderTree = ComponentMod.tree - /** * The metadata items array created in next-app-loader with all relevant information * that we need to resolve the final metadata. @@ -312,15 +318,6 @@ export const renderToHTMLOrFlight: AppPageRender = ( requestId = require('next/dist/compiled/nanoid').nanoid() } - const LayoutRouter = - ComponentMod.LayoutRouter as typeof import('../../client/components/layout-router').default - const RenderFromTemplateContext = - ComponentMod.RenderFromTemplateContext as typeof import('../../client/components/render-from-template-context').default - const createSearchParamsBailoutProxy = - ComponentMod.createSearchParamsBailoutProxy as typeof import('../../client/components/searchparams-bailout-proxy').createSearchParamsBailoutProxy - const StaticGenerationSearchParamsBailoutProvider = - ComponentMod.StaticGenerationSearchParamsBailoutProvider as typeof import('../../client/components/static-generation-searchparams-bailout-provider').default - const isStaticGeneration = staticGenerationStore.isStaticGeneration // During static generation we need to call the static generation bailout when reading searchParams const providedSearchParams = isStaticGeneration @@ -511,16 +508,16 @@ export const renderToHTMLOrFlight: AppPageRender = ( const ext = /\.(woff|woff2|eot|ttf|otf)$/.exec(fontFilename)![1] const type = `font/${ext}` const href = `${assetPrefix}/_next/${fontFilename}` - ComponentMod.preloadFont(href, type, renderOpts.crossOrigin) + preloadFont(href, type, renderOpts.crossOrigin) } } else { try { let url = new URL(assetPrefix) - ComponentMod.preconnect(url.origin, 'anonymous') + preconnect(url.origin, 'anonymous') } catch (error) { // assetPrefix must not be a fully qualified domain name. We assume // we should preconnect to same origin instead - ComponentMod.preconnect('/', 'anonymous') + preconnect('/', 'anonymous') } } } @@ -546,7 +543,7 @@ export const renderToHTMLOrFlight: AppPageRender = ( const precedence = process.env.NODE_ENV === 'development' ? 'next_' + href : 'next' - ComponentMod.preloadStyle(fullHref, renderOpts.crossOrigin) + preloadStyle(fullHref, renderOpts.crossOrigin) return ( 1 if (hasSlotKey && rootLayoutAtThisLevel) { - const NotFoundBoundary = - ComponentMod.NotFoundBoundary as typeof import('../../client/components/not-found-boundary').NotFoundBoundary Component = (componentProps: any) => { const NotFoundComponent = NotFound const RootLayoutComponent = LayoutOrPage @@ -1287,7 +1279,7 @@ export const renderToHTMLOrFlight: AppPageRender = ( // For app dir, use the bundled version of Flight server renderer (renderToReadableStream) // which contains the subset React. - const flightReadableStream = ComponentMod.renderToReadableStream( + const flightReadableStream = renderToReadableStream( options ? [options.actionResult, buildIdFlightDataPair] : buildIdFlightDataPair, @@ -1305,16 +1297,6 @@ export const renderToHTMLOrFlight: AppPageRender = ( return generateFlight() } - // Below this line is handling for rendering to HTML. - - // AppRouter is provided by next-app-loader - const AppRouter = - ComponentMod.AppRouter as typeof import('../../client/components/app-router').default - - const GlobalError = - /** GlobalError can be either the default error boundary or the overwritten app/global-error.js **/ - ComponentMod.GlobalError as typeof import('../../client/components/error-boundary').GlobalError - // Get the nonce from the incoming request if it has one. const csp = req.headers['content-security-policy'] let nonce: string | undefined diff --git a/packages/next/src/server/app-render/create-server-components-renderer.tsx b/packages/next/src/server/app-render/create-server-components-renderer.tsx index 2b4321cfbf24..d88f5492c61d 100644 --- a/packages/next/src/server/app-render/create-server-components-renderer.tsx +++ b/packages/next/src/server/app-render/create-server-components-renderer.tsx @@ -1,5 +1,6 @@ import type { RenderOpts } from './types' import type { FlightResponseRef } from './flight-response-ref' +import type { AppPageModule } from '../future/route-modules/app-page/module' import React, { use } from 'react' import { createErrorHandler } from './create-error-handler' @@ -11,13 +12,7 @@ import { useFlightResponse } from './use-flight-response' */ export function createServerComponentRenderer( ComponentToRender: (props: Props) => any, - ComponentMod: { - renderToReadableStream: any - __next_app__?: { - require: any - loadChunk: any - } - }, + ComponentMod: AppPageModule, { inlinedDataTransformStream, clientReferenceManifest, diff --git a/packages/next/src/server/app-render/entry-base.ts b/packages/next/src/server/app-render/entry-base.ts index aeb65ba62125..ae7e186764a4 100644 --- a/packages/next/src/server/app-render/entry-base.ts +++ b/packages/next/src/server/app-render/entry-base.ts @@ -1,10 +1,10 @@ -const { +export { renderToReadableStream, decodeReply, decodeAction, decodeFormState, // eslint-disable-next-line import/no-extraneous-dependencies -} = require('react-server-dom-webpack/server.edge') +} from 'react-server-dom-webpack/server.edge' import AppRouter from '../../client/components/app-router' import LayoutRouter from '../../client/components/layout-router' @@ -36,10 +36,6 @@ export { staticGenerationBailout, createSearchParamsBailoutProxy, serverHooks, - renderToReadableStream, - decodeReply, - decodeAction, - decodeFormState, preloadStyle, preloadFont, preconnect, diff --git a/packages/next/src/server/app-render/types.ts b/packages/next/src/server/app-render/types.ts index 085b63629b4c..59d23ef98243 100644 --- a/packages/next/src/server/app-render/types.ts +++ b/packages/next/src/server/app-render/types.ts @@ -1,9 +1,10 @@ import type { LoadComponentsReturnType } from '../load-components' import type { ServerRuntime, SizeLimit } from '../../../types' -import { NextConfigComplete } from '../../server/config-shared' +import type { NextConfigComplete } from '../../server/config-shared' import type { ClientReferenceManifest } from '../../build/webpack/plugins/flight-manifest-plugin' import type { NextFontManifest } from '../../build/webpack/plugins/next-font-manifest-plugin' import type { ParsedUrlQuery } from 'querystring' +import type { AppPageModule } from '../future/route-modules/app-page/module' import s from 'next/dist/compiled/superstruct' @@ -135,4 +136,5 @@ export interface RenderOptsPartial { isPrefetch?: boolean } -export type RenderOpts = LoadComponentsReturnType & RenderOptsPartial +export type RenderOpts = LoadComponentsReturnType & + RenderOptsPartial diff --git a/packages/next/src/server/future/route-modules/app-page/module.compiled.d.ts b/packages/next/src/server/future/route-modules/app-page/module.compiled.d.ts new file mode 100644 index 000000000000..5401340695ab --- /dev/null +++ b/packages/next/src/server/future/route-modules/app-page/module.compiled.d.ts @@ -0,0 +1 @@ +export * from './module' diff --git a/packages/next/src/server/future/route-modules/app-page/module.compiled.ts b/packages/next/src/server/future/route-modules/app-page/module.compiled.js similarity index 100% rename from packages/next/src/server/future/route-modules/app-page/module.compiled.ts rename to packages/next/src/server/future/route-modules/app-page/module.compiled.js diff --git a/packages/next/src/server/future/route-modules/app-page/module.ts b/packages/next/src/server/future/route-modules/app-page/module.ts index 5a34be6759ad..0c5e7cbcb17d 100644 --- a/packages/next/src/server/future/route-modules/app-page/module.ts +++ b/packages/next/src/server/future/route-modules/app-page/module.ts @@ -22,6 +22,13 @@ if (process.env.NEXT_RUNTIME !== 'edge') { vendoredReactSSR = require('./vendored/ssr/entrypoints') } +/** + * The AppPageModule is the type of the module exported by the bundled app page + * module. + */ +export type AppPageModule = + typeof import('../../../../build/templates/app-page') + type AppPageUserlandModule = { /** * The tree created in next-app-loader that holds component segments and modules diff --git a/packages/next/src/server/future/route-modules/app-route/module.compiled.d.ts b/packages/next/src/server/future/route-modules/app-route/module.compiled.d.ts new file mode 100644 index 000000000000..5401340695ab --- /dev/null +++ b/packages/next/src/server/future/route-modules/app-route/module.compiled.d.ts @@ -0,0 +1 @@ +export * from './module' diff --git a/packages/next/src/server/future/route-modules/app-route/module.compiled.ts b/packages/next/src/server/future/route-modules/app-route/module.compiled.js similarity index 100% rename from packages/next/src/server/future/route-modules/app-route/module.compiled.ts rename to packages/next/src/server/future/route-modules/app-route/module.compiled.js diff --git a/packages/next/src/server/future/route-modules/app-route/module.ts b/packages/next/src/server/future/route-modules/app-route/module.ts index 41ea0ea87f06..4caf96f791a5 100644 --- a/packages/next/src/server/future/route-modules/app-route/module.ts +++ b/packages/next/src/server/future/route-modules/app-route/module.ts @@ -44,6 +44,13 @@ import { staticGenerationAsyncStorage } from '../../../../client/components/stat import { actionAsyncStorage } from '../../../../client/components/action-async-storage.external' import * as sharedModules from './shared-modules' +/** + * The AppRouteModule is the type of the module exported by the bundled App + * Route module. + */ +export type AppRouteModule = + typeof import('../../../../build/templates/app-route') + /** * AppRouteRouteHandlerContext is the context that is passed to the route * handler for app routes. diff --git a/packages/next/src/server/future/route-modules/pages-api/module.compiled.d.ts b/packages/next/src/server/future/route-modules/pages-api/module.compiled.d.ts new file mode 100644 index 000000000000..5401340695ab --- /dev/null +++ b/packages/next/src/server/future/route-modules/pages-api/module.compiled.d.ts @@ -0,0 +1 @@ +export * from './module' diff --git a/packages/next/src/server/future/route-modules/pages-api/module.compiled.ts b/packages/next/src/server/future/route-modules/pages-api/module.compiled.js similarity index 100% rename from packages/next/src/server/future/route-modules/pages-api/module.compiled.ts rename to packages/next/src/server/future/route-modules/pages-api/module.compiled.js diff --git a/packages/next/src/server/future/route-modules/pages-api/module.ts b/packages/next/src/server/future/route-modules/pages-api/module.ts index 4f9c4fe5749c..70940f443172 100644 --- a/packages/next/src/server/future/route-modules/pages-api/module.ts +++ b/packages/next/src/server/future/route-modules/pages-api/module.ts @@ -16,6 +16,13 @@ type PagesAPIHandleFn = ( res: ServerResponse ) => Promise +/** + * The PagesAPIModule is the type of the module exported by the bundled Pages + * API module. + */ +export type PagesAPIModule = + typeof import('../../../../build/templates/pages-api') + type PagesAPIUserlandModule = { /** * The exported handler method. diff --git a/packages/next/src/server/future/route-modules/pages/module.compiled.d.ts b/packages/next/src/server/future/route-modules/pages/module.compiled.d.ts new file mode 100644 index 000000000000..5401340695ab --- /dev/null +++ b/packages/next/src/server/future/route-modules/pages/module.compiled.d.ts @@ -0,0 +1 @@ +export * from './module' diff --git a/packages/next/src/server/future/route-modules/pages/module.compiled.ts b/packages/next/src/server/future/route-modules/pages/module.compiled.js similarity index 100% rename from packages/next/src/server/future/route-modules/pages/module.compiled.ts rename to packages/next/src/server/future/route-modules/pages/module.compiled.js diff --git a/packages/next/src/server/future/route-modules/pages/module.ts b/packages/next/src/server/future/route-modules/pages/module.ts index 3abbe1da064e..c50b9c3eb718 100644 --- a/packages/next/src/server/future/route-modules/pages/module.ts +++ b/packages/next/src/server/future/route-modules/pages/module.ts @@ -20,6 +20,12 @@ import { import { renderToHTMLImpl, renderToHTML } from '../../../render' import * as vendoredContexts from './vendored/contexts/entrypoints' +/** + * The PagesModule is the type of the module exported by the bundled pages + * module. + */ +export type PagesModule = typeof import('../../../../build/templates/pages') + /** * The userland module for a page. This is the module that is exported from the * page file that contains the page component, page config, and any page data diff --git a/packages/next/src/server/lib/patch-fetch.ts b/packages/next/src/server/lib/patch-fetch.ts index 7f250860f51f..2e1b23a24172 100644 --- a/packages/next/src/server/lib/patch-fetch.ts +++ b/packages/next/src/server/lib/patch-fetch.ts @@ -141,15 +141,17 @@ function trackFetchMetric( }) } +interface PatchableModule { + serverHooks: typeof ServerHooks + staticGenerationAsyncStorage: StaticGenerationAsyncStorage +} + // we patch fetch to collect cache information used for // determining if a page is static or not export function patchFetch({ serverHooks, staticGenerationAsyncStorage, -}: { - serverHooks: typeof ServerHooks - staticGenerationAsyncStorage: StaticGenerationAsyncStorage -}) { +}: PatchableModule) { if (!(globalThis as any)._nextOriginalFetch) { ;(globalThis as any)._nextOriginalFetch = globalThis.fetch } diff --git a/packages/next/src/server/load-components.ts b/packages/next/src/server/load-components.ts index eb53b2736db6..042b3788e989 100644 --- a/packages/next/src/server/load-components.ts +++ b/packages/next/src/server/load-components.ts @@ -33,7 +33,7 @@ export type ManifestItem = { export type ReactLoadableManifest = { [moduleId: string]: ManifestItem } -export type LoadComponentsReturnType = { +export type LoadComponentsReturnType = { Component: NextComponentType pageConfig: PageConfig buildManifest: BuildManifest @@ -46,7 +46,7 @@ export type LoadComponentsReturnType = { getStaticProps?: GetStaticProps getStaticPaths?: GetStaticPaths getServerSideProps?: GetServerSideProps - ComponentMod: any + ComponentMod: NextModule routeModule?: RouteModule isAppPath?: boolean page: string @@ -88,7 +88,7 @@ async function loadClientReferenceManifest( } } -async function loadComponentsImpl({ +async function loadComponentsImpl({ distDir, page, isAppPath, @@ -96,7 +96,7 @@ async function loadComponentsImpl({ distDir: string page: string isAppPath: boolean -}): Promise { +}): Promise> { let DocumentMod = {} let AppMod = {} if (!isAppPath) { diff --git a/packages/next/src/server/render.tsx b/packages/next/src/server/render.tsx index f23df5d7cf84..a67ba29583d5 100644 --- a/packages/next/src/server/render.tsx +++ b/packages/next/src/server/render.tsx @@ -34,6 +34,7 @@ import type { UnwrapPromise } from '../lib/coalesced-function' import type { ReactReadableStream } from './stream-utils/node-web-streams-helper' import type { ClientReferenceManifest } from '../build/webpack/plugins/flight-manifest-plugin' import type { NextFontManifest } from '../build/webpack/plugins/next-font-manifest-plugin' +import type { PagesModule } from './future/route-modules/pages/module' import React from 'react' import ReactDOMServer from 'react-dom/server.browser' @@ -286,7 +287,8 @@ export type RenderOptsPartial = { isPrefetch?: boolean } -export type RenderOpts = LoadComponentsReturnType & RenderOptsPartial +export type RenderOpts = LoadComponentsReturnType & + RenderOptsPartial /** * RenderOptsExtra is being used to split away functionality that's within the diff --git a/packages/next/types/compiled.d.ts b/packages/next/types/compiled.d.ts index e53f2a5d2657..7d6707c1e657 100644 --- a/packages/next/types/compiled.d.ts +++ b/packages/next/types/compiled.d.ts @@ -8,6 +8,8 @@ declare module 'next/dist/compiled/webpack/webpack' { export let GraphHelpers: any export let sources: any export let StringXor: any + // eslint-disable-next-line @typescript-eslint/no-unused-vars + export type LoaderDefinitionFunction = any namespace webpack { export type Compiler = any export type WebpackPluginInstance = any @@ -44,3 +46,10 @@ declare module 'next/dist/compiled/superstruct' { // eslint-disable-next-line @typescript-eslint/no-unused-vars export type Describe = any } + +declare module 'react-server-dom-webpack/server.edge' + +declare module 'VAR_MODULE_GLOBAL_ERROR' +declare module 'VAR_USERLAND' +declare module 'VAR_MODULE_DOCUMENT' +declare module 'VAR_MODULE_APP' diff --git a/packages/next/types/misc.d.ts b/packages/next/types/misc.d.ts index f3c438e780ad..00633f5acfc7 100644 --- a/packages/next/types/misc.d.ts +++ b/packages/next/types/misc.d.ts @@ -35,6 +35,11 @@ declare module 'react-dom/server-rendering-stub' declare module 'react-dom/server.browser' declare module 'react-dom/server.edge' +declare module 'VAR_MODULE_GLOBAL_ERROR' +declare module 'VAR_USERLAND' +declare module 'VAR_MODULE_DOCUMENT' +declare module 'VAR_MODULE_APP' + declare module 'next/dist/compiled/@next/react-dev-overlay/dist/client' { export * from '@next/react-dev-overlay/dist/client' } diff --git a/packages/next/types/webpack.d.ts b/packages/next/types/webpack.d.ts index caba6a1b1688..64e68d48e904 100644 --- a/packages/next/types/webpack.d.ts +++ b/packages/next/types/webpack.d.ts @@ -34,6 +34,7 @@ declare module 'next/dist/compiled/webpack/webpack' { export let sources: typeof webpackSources export let StringXor: any export { + default as webpack, Compiler, Compilation, Module, @@ -43,6 +44,8 @@ declare module 'next/dist/compiled/webpack/webpack' { RuntimeGlobals, NormalModule, ResolvePluginInstance, + ModuleFilenameHelpers, + LoaderDefinitionFunction, + LoaderContext, } from 'webpack' - export { default as webpack, ModuleFilenameHelpers } from 'webpack' } From d21025cc3a50e2ff8a7137d5d5c94576218f01e7 Mon Sep 17 00:00:00 2001 From: Sukka Date: Thu, 5 Oct 2023 23:46:53 +0800 Subject: [PATCH 03/15] refactor: rewrite config schema in zod (#56383) The PR supersedes the https://github.com/vercel/next.js/pull/53150, which is way too outdated, has way too many conflicts, and also heavily relies on GitHub Copilot (which makes the progress slow and tedious). The PR uses [`json-schema-to-zod`](https://github.com/StefanTerdell/json-schema-to-zod) (instead of the GitHub Copilot) to generate the zod schema, and manually replaces all generated `z.customRefine` with my hand-written zod schema. TODO: - [x] Convert schema - [x] Reduce `z.any()` usage - [x] Create human-readable errors from the `ZodError` - [x] Update test cases to reflect the latest error message ----- The benefit of using zod over ajv: - Easier maintenance: zod schema is straightforward to compose. - Better typescript support: config schema now strictly reflects the `NextConfig` type. - Smaller installation size: by replacing `ajv` and `@segment/ajv-human-errors` w/ `zod`, I am able to reduce installation size by 114 KiB. - Better Extension: the zod error message is easy to customize. ----- In the previous PR https://github.com/vercel/next.js/pull/56083, @feedthejim replaces `zod` w/ `superstruct`. `superstruct` is lightweight and fast, which makes it perfect for creating simple schemas for RSC payload. But, this also means `superstruct` has its limitations compared to `zod`: - `superstruct`'s syntax is different, and some utilities's usage is counter-intuitive: - `z.array(z.string()).gt(1)` vs `s.size(s.array(s.string()), 1)` - `z.numer().gt(1)` vs `s.size(s.number(), 1)`, `s.min(s.number(), 1)` - `z.boolean().optional().nullable()` vs `s.nullable(s.optional(z.boolean()))` - `superstruct` has weaker TypeScript support and worse DX compared to `zod` when composing huge schema: - `zod.ZodType + z.object()` can provide a more detailed type mismatch message on which specific property is the culprit, while `Describe + s.object()` provides almost no information at all. - `zod`'s schema is more powerful - `z.function()` supports `z.args()` and `z.returns()`, while `superstruct` only has `s.func()` - zod also has Promise type `z.promise()` and intersection type `z.and()` - `superstruct`'s error is harder to parse compared to `zod`'s `ZodError` So in the PR, I re-introduced `zod` for `next.config.js` validation. --- packages/next/package.json | 5 +- packages/next/src/compiled/sass-loader/cjs.js | 2 +- packages/next/src/compiled/zod/LICENSE | 21 + packages/next/src/compiled/zod/index.js | 1 + packages/next/src/compiled/zod/package.json | 1 + packages/next/src/server/config-schema.ts | 1329 +++++++---------- packages/next/src/server/config-shared.ts | 16 - packages/next/src/server/config.ts | 133 +- packages/next/taskfile.js | 76 +- packages/next/types/misc.d.ts | 10 +- pnpm-lock.yaml | 32 +- .../config-validation/test/index.test.ts | 10 +- test/integration/dist-dir/test/index.test.js | 4 +- .../image-optimizer/test/index.test.ts | 32 +- 14 files changed, 698 insertions(+), 974 deletions(-) create mode 100644 packages/next/src/compiled/zod/LICENSE create mode 100644 packages/next/src/compiled/zod/index.js create mode 100644 packages/next/src/compiled/zod/package.json diff --git a/packages/next/package.json b/packages/next/package.json index 842f76584ca4..fc8b1aabde29 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -151,7 +151,6 @@ "@next/swc": "13.5.5-canary.2", "@opentelemetry/api": "1.4.1", "@playwright/test": "^1.35.1", - "@segment/ajv-human-errors": "2.1.2", "@taskr/clear": "1.1.0", "@taskr/esnext": "1.1.0", "@types/amphtml-validator": "1.0.0", @@ -194,7 +193,6 @@ "@vercel/nft": "0.22.6", "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231002.1", "acorn": "8.5.0", - "ajv": "8.11.0", "amphtml-validator": "1.0.35", "anser": "1.4.9", "arg": "4.1.0", @@ -314,7 +312,8 @@ "webpack": "5.86.0", "webpack-sources1": "npm:webpack-sources@1.4.3", "webpack-sources3": "npm:webpack-sources@3.2.3", - "ws": "8.2.3" + "ws": "8.2.3", + "zod": "3.22.3" }, "engines": { "node": ">=16.14.0" diff --git a/packages/next/src/compiled/sass-loader/cjs.js b/packages/next/src/compiled/sass-loader/cjs.js index 558d97da1149..f852edbe570a 100644 --- a/packages/next/src/compiled/sass-loader/cjs.js +++ b/packages/next/src/compiled/sass-loader/cjs.js @@ -1 +1 @@ -(function(){var __webpack_modules__={12:function(e,t){function set(e,t,s){if(typeof s.value==="object")s.value=klona(s.value);if(!s.enumerable||s.get||s.set||!s.configurable||!s.writable||t==="__proto__"){Object.defineProperty(e,t,s)}else e[t]=s.value}function klona(e){if(typeof e!=="object")return e;var t=0,s,r,n,o=Object.prototype.toString.call(e);if(o==="[object Object]"){n=Object.create(e.__proto__||null)}else if(o==="[object Array]"){n=Array(e.length)}else if(o==="[object Set]"){n=new Set;e.forEach((function(e){n.add(klona(e))}))}else if(o==="[object Map]"){n=new Map;e.forEach((function(e,t){n.set(klona(t),klona(e))}))}else if(o==="[object Date]"){n=new Date(+e)}else if(o==="[object RegExp]"){n=new RegExp(e.source,e.flags)}else if(o==="[object DataView]"){n=new e.constructor(klona(e.buffer))}else if(o==="[object ArrayBuffer]"){n=e.slice(0)}else if(o.slice(-6)==="Array]"){n=new e.constructor(e)}if(n){for(r=Object.getOwnPropertySymbols(e);t{if(e){if(e.file){this.addDependency(r.default.normalize(e.file))}s(new a.default(e));return}let n=t.map?JSON.parse(t.map):null;if(n&&c){n=(0,o.normalizeSourceMap)(n,this.rootContext)}t.stats.includedFiles.forEach((e=>{const t=r.default.normalize(e);if(r.default.isAbsolute(t)){this.addDependency(t)}}));s(null,t.css.toString(),n)}))}var i=loader;t["default"]=i},636:function(__unused_webpack_module,exports,__nccwpck_require__){"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.getRenderFunctionFromSassImplementation=getRenderFunctionFromSassImplementation;exports.getSassImplementation=getSassImplementation;exports.getSassOptions=getSassOptions;exports.getWebpackImporter=getWebpackImporter;exports.getWebpackResolver=getWebpackResolver;exports.isSupportedFibers=isSupportedFibers;exports.normalizeSourceMap=normalizeSourceMap;var _url=_interopRequireDefault(__nccwpck_require__(310));var _path=_interopRequireDefault(__nccwpck_require__(17));var _full=__nccwpck_require__(12);var _neoAsync=_interopRequireDefault(__nccwpck_require__(175));var _SassWarning=_interopRequireDefault(__nccwpck_require__(955));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function getDefaultSassImplementation(){let sassImplPkg="sass";try{eval("require").resolve("sass")}catch(error){try{eval("require").resolve("node-sass");sassImplPkg="node-sass"}catch(e){sassImplPkg="sass"}}return __nccwpck_require__(438)}function getSassImplementation(e,t){let s=t;if(!s){try{s=getDefaultSassImplementation()}catch(t){e.emitError(t);return}}if(typeof s==="string"){try{s=require(s)}catch(t){e.emitError(t);return}}const{info:r}=s;if(!r){e.emitError(new Error("Unknown Sass implementation."));return}const n=r.split("\t");if(n.length<2){e.emitError(new Error(`Unknown Sass implementation "${r}".`));return}const[o]=n;if(o==="dart-sass"){return s}else if(o==="node-sass"){return s}e.emitError(new Error(`Unknown Sass implementation "${o}".`))}function isProductionLikeMode(e){return e.mode==="production"||!e.mode}function proxyCustomImporters(e,t){return[].concat(e).map((e=>function proxyImporter(...s){const r={...this,webpackLoaderContext:t};return e.apply(r,s)}))}function isSupportedFibers(){const[e]=process.versions.node.split(".");return Number(e)<16}async function getSassOptions(e,t,s,r,n){const o=(0,_full.klona)(t.sassOptions?typeof t.sassOptions==="function"?t.sassOptions(e)||{}:t.sassOptions:{});const a=r.info.includes("dart-sass");if(a&&isSupportedFibers()){const e=!o.fiber&&o.fiber!==false;if(e){let e;try{e=require.resolve("fibers")}catch(e){}if(e){o.fiber=require(e)}}else if(o.fiber===false){delete o.fiber}}else{delete o.fiber}o.file=e.resourcePath;o.data=t.additionalData?typeof t.additionalData==="function"?await t.additionalData(s,e):`${t.additionalData}\n${s}`:s;if(!o.outputStyle&&isProductionLikeMode(e)){o.outputStyle="compressed"}if(n){o.sourceMap=true;o.outFile=_path.default.join(e.rootContext,"style.css.map");o.sourceMapContents=true;o.omitSourceMapUrl=true;o.sourceMapEmbed=false}const{resourcePath:i}=e;const c=_path.default.extname(i);if(c&&c.toLowerCase()===".sass"&&typeof o.indentedSyntax==="undefined"){o.indentedSyntax=true}else{o.indentedSyntax=Boolean(o.indentedSyntax)}o.importer=o.importer?proxyCustomImporters(Array.isArray(o.importer)?o.importer:[o.importer],e):[];o.includePaths=[].concat(process.cwd()).concat((o.includePaths||[]).map((e=>_path.default.isAbsolute(e)?e:_path.default.join(process.cwd(),e)))).concat(process.env.SASS_PATH?process.env.SASS_PATH.split(process.platform==="win32"?";":":"):[]);if(typeof o.charset==="undefined"){o.charset=true}if(!o.logger){const s=t.warnRuleAsWarning===true;const r=e.getLogger("sass-loader");const formatSpan=e=>`${e.url||"-"}:${e.start.line}:${e.start.column}: `;o.logger={debug(e,t){let s="";if(t.span){s=formatSpan(t.span)}s+=e;r.debug(s)},warn(t,n){let o="";if(n.deprecation){o+="Deprecation "}if(n.span&&!n.stack){o=formatSpan(n.span)}o+=t;if(n.stack){o+=`\n\n${n.stack}`}if(s){e.emitWarning(new _SassWarning.default(o,n))}else{r.warn(o)}}}}return o}const MODULE_REQUEST_REGEX=/^[^?]*~/;const IS_MODULE_IMPORT=/^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/;function getPossibleRequests(e,t=false,s=false){let r=e;if(t){if(MODULE_REQUEST_REGEX.test(e)){r=r.replace(MODULE_REQUEST_REGEX,"")}if(IS_MODULE_IMPORT.test(e)){r=r[r.length-1]==="/"?r:`${r}/`;return[...new Set([r,e])]}}const n=_path.default.extname(r).toLowerCase();if(n===".css"){return[]}const o=_path.default.dirname(r);const a=o==="."?"":`${o}/`;const i=_path.default.basename(r);const c=_path.default.basename(r,n);return[...new Set([].concat(s?[`${a}_${c}.import${n}`,`${a}${c}.import${n}`]:[]).concat([`${a}_${i}`,`${a}${i}`]).concat(t?[e]:[]))]}function promiseResolve(e){return(t,s)=>new Promise(((r,n)=>{e(t,s,((e,t)=>{if(e){n(e)}else{r(t)}}))}))}const IS_SPECIAL_MODULE_IMPORT=/^~[^/]+$/;const IS_NATIVE_WIN32_PATH=/^[a-z]:[/\\]|^\\\\/i;function getWebpackResolver(e,t,s=[]){async function startResolving(e){if(e.length===0){return Promise.reject()}const[{possibleRequests:t}]=e;if(t.length===0){return Promise.reject()}const[{resolve:s,context:r}]=e;try{return await s(r,t[0])}catch(s){const[,...r]=t;if(r.length===0){const[,...t]=e;return startResolving(t)}e[0].possibleRequests=r;return startResolving(e)}}const r=t.info.includes("dart-sass");const n=promiseResolve(e({alias:[],aliasFields:[],conditionNames:[],descriptionFiles:[],extensions:[".sass",".scss",".css"],exportsFields:[],mainFields:[],mainFiles:["_index","index"],modules:[],restrictions:[/\.((sa|sc|c)ss)$/i],preferRelative:true}));const o=promiseResolve(e({alias:[],aliasFields:[],conditionNames:[],descriptionFiles:[],extensions:[".sass",".scss",".css"],exportsFields:[],mainFields:[],mainFiles:["_index.import","_index","index.import","index"],modules:[],restrictions:[/\.((sa|sc|c)ss)$/i],preferRelative:true}));const a=promiseResolve(e({dependencyType:"sass",conditionNames:["sass","style"],mainFields:["sass","style","main","..."],mainFiles:["_index","index","..."],extensions:[".sass",".scss",".css"],restrictions:[/\.((sa|sc|c)ss)$/i],preferRelative:true}));const i=promiseResolve(e({dependencyType:"sass",conditionNames:["sass","style"],mainFields:["sass","style","main","..."],mainFiles:["_index.import","_index","index.import","index","..."],extensions:[".sass",".scss",".css"],restrictions:[/\.((sa|sc|c)ss)$/i],preferRelative:true}));return(e,t,c)=>{if(!r&&!_path.default.isAbsolute(e)){return Promise.reject()}const l=t;const u=l.slice(0,5).toLowerCase()==="file:";if(u){try{t=_url.default.fileURLToPath(l)}catch(e){t=t.slice(7)}}let p=[];const f=!IS_SPECIAL_MODULE_IMPORT.test(t)&&!u&&!l.startsWith("/")&&!IS_NATIVE_WIN32_PATH.test(l);if(s.length>0&&f){const a=getPossibleRequests(t,false,c);if(!r){p=p.concat({resolve:c?o:n,context:_path.default.dirname(e),possibleRequests:a})}p=p.concat(s.map((e=>({resolve:c?o:n,context:e,possibleRequests:a}))))}const d=getPossibleRequests(t,true,c);p=p.concat({resolve:c?i:a,context:_path.default.dirname(e),possibleRequests:d});return startResolving(p)}}const MATCH_CSS=/\.css$/i;function getWebpackImporter(e,t,s){const r=getWebpackResolver(e.getResolve,t,s);return function importer(t,s,n){const{fromImport:o}=this;r(s,t,o).then((t=>{e.addDependency(_path.default.normalize(t));n({file:t.replace(MATCH_CSS,"")})})).catch((()=>{n({file:t})}))}}let nodeSassJobQueue=null;function getRenderFunctionFromSassImplementation(e){const t=e.info.includes("dart-sass");if(t){return e.render.bind(e)}if(nodeSassJobQueue===null){const t=Number(process.env.UV_THREADPOOL_SIZE||4);nodeSassJobQueue=_neoAsync.default.queue(e.render.bind(e),t-1)}return nodeSassJobQueue.push.bind(nodeSassJobQueue)}const ABSOLUTE_SCHEME=/^[A-Za-z0-9+\-.]+:/;function getURLType(e){if(e[0]==="/"){if(e[1]==="/"){return"scheme-relative"}return"path-absolute"}if(IS_NATIVE_WIN32_PATH.test(e)){return"path-absolute"}return ABSOLUTE_SCHEME.test(e)?"absolute":"path-relative"}function normalizeSourceMap(e,t){const s=e;delete s.file;s.sourceRoot="";s.sources=s.sources.map((e=>{const s=getURLType(e);if(s==="path-relative"){return _path.default.resolve(t,_path.default.normalize(e))}return e}));return s}},175:function(e){"use strict";e.exports=require("next/dist/compiled/neo-async")},17:function(e){"use strict";e.exports=require("path")},438:function(e){"use strict";e.exports=require("sass")},310:function(e){"use strict";e.exports=require("url")},921:function(e){"use strict";e.exports=JSON.parse('{"title":"Sass Loader options","type":"object","properties":{"implementation":{"description":"The implementation of the sass to be used.","link":"https://github.com/webpack-contrib/sass-loader#implementation","anyOf":[{"type":"string"},{"type":"object"}]},"sassOptions":{"description":"Options for `node-sass` or `sass` (`Dart Sass`) implementation.","link":"https://github.com/webpack-contrib/sass-loader#sassoptions","anyOf":[{"type":"object","additionalProperties":true},{"instanceof":"Function"}]},"additionalData":{"description":"Prepends/Appends `Sass`/`SCSS` code before the actual entry file.","link":"https://github.com/webpack-contrib/sass-loader#additionaldata","anyOf":[{"type":"string"},{"instanceof":"Function"}]},"sourceMap":{"description":"Enables/Disables generation of source maps.","link":"https://github.com/webpack-contrib/sass-loader#sourcemap","type":"boolean"},"webpackImporter":{"description":"Enables/Disables default `webpack` importer.","link":"https://github.com/webpack-contrib/sass-loader#webpackimporter","type":"boolean"},"warnRuleAsWarning":{"description":"Treats the \'@warn\' rule as a webpack warning.","link":"https://github.com/webpack-contrib/sass-loader#warnruleaswarning","type":"boolean"}},"additionalProperties":false}')}};var __webpack_module_cache__={};function __nccwpck_require__(e){var t=__webpack_module_cache__[e];if(t!==undefined){return t.exports}var s=__webpack_module_cache__[e]={exports:{}};var r=true;try{__webpack_modules__[e](s,s.exports,__nccwpck_require__);r=false}finally{if(r)delete __webpack_module_cache__[e]}return s.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var __webpack_exports__=__nccwpck_require__(601);module.exports=__webpack_exports__})(); \ No newline at end of file +(function(){var __webpack_modules__={12:function(e,t){function set(e,t,s){if(typeof s.value==="object")s.value=klona(s.value);if(!s.enumerable||s.get||s.set||!s.configurable||!s.writable||t==="__proto__"){Object.defineProperty(e,t,s)}else e[t]=s.value}function klona(e){if(typeof e!=="object")return e;var t=0,s,r,n,o=Object.prototype.toString.call(e);if(o==="[object Object]"){n=Object.create(e.__proto__||null)}else if(o==="[object Array]"){n=Array(e.length)}else if(o==="[object Set]"){n=new Set;e.forEach((function(e){n.add(klona(e))}))}else if(o==="[object Map]"){n=new Map;e.forEach((function(e,t){n.set(klona(t),klona(e))}))}else if(o==="[object Date]"){n=new Date(+e)}else if(o==="[object RegExp]"){n=new RegExp(e.source,e.flags)}else if(o==="[object DataView]"){n=new e.constructor(klona(e.buffer))}else if(o==="[object ArrayBuffer]"){n=e.slice(0)}else if(o.slice(-6)==="Array]"){n=new e.constructor(e)}if(n){for(r=Object.getOwnPropertySymbols(e);t{if(e){if(e.file){this.addDependency(r.default.normalize(e.file))}s(new a.default(e));return}let n=t.map?JSON.parse(t.map):null;if(n&&c){n=(0,o.normalizeSourceMap)(n,this.rootContext)}t.stats.includedFiles.forEach((e=>{const t=r.default.normalize(e);if(r.default.isAbsolute(t)){this.addDependency(t)}}));s(null,t.css.toString(),n)}))}var i=loader;t["default"]=i},125:function(__unused_webpack_module,exports,__nccwpck_require__){"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.getRenderFunctionFromSassImplementation=getRenderFunctionFromSassImplementation;exports.getSassImplementation=getSassImplementation;exports.getSassOptions=getSassOptions;exports.getWebpackImporter=getWebpackImporter;exports.getWebpackResolver=getWebpackResolver;exports.isSupportedFibers=isSupportedFibers;exports.normalizeSourceMap=normalizeSourceMap;var _url=_interopRequireDefault(__nccwpck_require__(310));var _path=_interopRequireDefault(__nccwpck_require__(17));var _full=__nccwpck_require__(12);var _neoAsync=_interopRequireDefault(__nccwpck_require__(175));var _SassWarning=_interopRequireDefault(__nccwpck_require__(186));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function getDefaultSassImplementation(){let sassImplPkg="sass";try{eval("require").resolve("sass")}catch(error){try{eval("require").resolve("node-sass");sassImplPkg="node-sass"}catch(e){sassImplPkg="sass"}}return __nccwpck_require__(438)}function getSassImplementation(e,t){let s=t;if(!s){try{s=getDefaultSassImplementation()}catch(t){e.emitError(t);return}}if(typeof s==="string"){try{s=require(s)}catch(t){e.emitError(t);return}}const{info:r}=s;if(!r){e.emitError(new Error("Unknown Sass implementation."));return}const n=r.split("\t");if(n.length<2){e.emitError(new Error(`Unknown Sass implementation "${r}".`));return}const[o]=n;if(o==="dart-sass"){return s}else if(o==="node-sass"){return s}e.emitError(new Error(`Unknown Sass implementation "${o}".`))}function isProductionLikeMode(e){return e.mode==="production"||!e.mode}function proxyCustomImporters(e,t){return[].concat(e).map((e=>function proxyImporter(...s){const r={...this,webpackLoaderContext:t};return e.apply(r,s)}))}function isSupportedFibers(){const[e]=process.versions.node.split(".");return Number(e)<16}async function getSassOptions(e,t,s,r,n){const o=(0,_full.klona)(t.sassOptions?typeof t.sassOptions==="function"?t.sassOptions(e)||{}:t.sassOptions:{});const a=r.info.includes("dart-sass");if(a&&isSupportedFibers()){const e=!o.fiber&&o.fiber!==false;if(e){let e;try{e=require.resolve("fibers")}catch(e){}if(e){o.fiber=require(e)}}else if(o.fiber===false){delete o.fiber}}else{delete o.fiber}o.file=e.resourcePath;o.data=t.additionalData?typeof t.additionalData==="function"?await t.additionalData(s,e):`${t.additionalData}\n${s}`:s;if(!o.outputStyle&&isProductionLikeMode(e)){o.outputStyle="compressed"}if(n){o.sourceMap=true;o.outFile=_path.default.join(e.rootContext,"style.css.map");o.sourceMapContents=true;o.omitSourceMapUrl=true;o.sourceMapEmbed=false}const{resourcePath:i}=e;const c=_path.default.extname(i);if(c&&c.toLowerCase()===".sass"&&typeof o.indentedSyntax==="undefined"){o.indentedSyntax=true}else{o.indentedSyntax=Boolean(o.indentedSyntax)}o.importer=o.importer?proxyCustomImporters(Array.isArray(o.importer)?o.importer:[o.importer],e):[];o.includePaths=[].concat(process.cwd()).concat((o.includePaths||[]).map((e=>_path.default.isAbsolute(e)?e:_path.default.join(process.cwd(),e)))).concat(process.env.SASS_PATH?process.env.SASS_PATH.split(process.platform==="win32"?";":":"):[]);if(typeof o.charset==="undefined"){o.charset=true}if(!o.logger){const s=t.warnRuleAsWarning===true;const r=e.getLogger("sass-loader");const formatSpan=e=>`${e.url||"-"}:${e.start.line}:${e.start.column}: `;o.logger={debug(e,t){let s="";if(t.span){s=formatSpan(t.span)}s+=e;r.debug(s)},warn(t,n){let o="";if(n.deprecation){o+="Deprecation "}if(n.span&&!n.stack){o=formatSpan(n.span)}o+=t;if(n.stack){o+=`\n\n${n.stack}`}if(s){e.emitWarning(new _SassWarning.default(o,n))}else{r.warn(o)}}}}return o}const MODULE_REQUEST_REGEX=/^[^?]*~/;const IS_MODULE_IMPORT=/^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/;function getPossibleRequests(e,t=false,s=false){let r=e;if(t){if(MODULE_REQUEST_REGEX.test(e)){r=r.replace(MODULE_REQUEST_REGEX,"")}if(IS_MODULE_IMPORT.test(e)){r=r[r.length-1]==="/"?r:`${r}/`;return[...new Set([r,e])]}}const n=_path.default.extname(r).toLowerCase();if(n===".css"){return[]}const o=_path.default.dirname(r);const a=o==="."?"":`${o}/`;const i=_path.default.basename(r);const c=_path.default.basename(r,n);return[...new Set([].concat(s?[`${a}_${c}.import${n}`,`${a}${c}.import${n}`]:[]).concat([`${a}_${i}`,`${a}${i}`]).concat(t?[e]:[]))]}function promiseResolve(e){return(t,s)=>new Promise(((r,n)=>{e(t,s,((e,t)=>{if(e){n(e)}else{r(t)}}))}))}const IS_SPECIAL_MODULE_IMPORT=/^~[^/]+$/;const IS_NATIVE_WIN32_PATH=/^[a-z]:[/\\]|^\\\\/i;function getWebpackResolver(e,t,s=[]){async function startResolving(e){if(e.length===0){return Promise.reject()}const[{possibleRequests:t}]=e;if(t.length===0){return Promise.reject()}const[{resolve:s,context:r}]=e;try{return await s(r,t[0])}catch(s){const[,...r]=t;if(r.length===0){const[,...t]=e;return startResolving(t)}e[0].possibleRequests=r;return startResolving(e)}}const r=t.info.includes("dart-sass");const n=promiseResolve(e({alias:[],aliasFields:[],conditionNames:[],descriptionFiles:[],extensions:[".sass",".scss",".css"],exportsFields:[],mainFields:[],mainFiles:["_index","index"],modules:[],restrictions:[/\.((sa|sc|c)ss)$/i],preferRelative:true}));const o=promiseResolve(e({alias:[],aliasFields:[],conditionNames:[],descriptionFiles:[],extensions:[".sass",".scss",".css"],exportsFields:[],mainFields:[],mainFiles:["_index.import","_index","index.import","index"],modules:[],restrictions:[/\.((sa|sc|c)ss)$/i],preferRelative:true}));const a=promiseResolve(e({dependencyType:"sass",conditionNames:["sass","style"],mainFields:["sass","style","main","..."],mainFiles:["_index","index","..."],extensions:[".sass",".scss",".css"],restrictions:[/\.((sa|sc|c)ss)$/i],preferRelative:true}));const i=promiseResolve(e({dependencyType:"sass",conditionNames:["sass","style"],mainFields:["sass","style","main","..."],mainFiles:["_index.import","_index","index.import","index","..."],extensions:[".sass",".scss",".css"],restrictions:[/\.((sa|sc|c)ss)$/i],preferRelative:true}));return(e,t,c)=>{if(!r&&!_path.default.isAbsolute(e)){return Promise.reject()}const l=t;const u=l.slice(0,5).toLowerCase()==="file:";if(u){try{t=_url.default.fileURLToPath(l)}catch(e){t=t.slice(7)}}let p=[];const f=!IS_SPECIAL_MODULE_IMPORT.test(t)&&!u&&!l.startsWith("/")&&!IS_NATIVE_WIN32_PATH.test(l);if(s.length>0&&f){const a=getPossibleRequests(t,false,c);if(!r){p=p.concat({resolve:c?o:n,context:_path.default.dirname(e),possibleRequests:a})}p=p.concat(s.map((e=>({resolve:c?o:n,context:e,possibleRequests:a}))))}const d=getPossibleRequests(t,true,c);p=p.concat({resolve:c?i:a,context:_path.default.dirname(e),possibleRequests:d});return startResolving(p)}}const MATCH_CSS=/\.css$/i;function getWebpackImporter(e,t,s){const r=getWebpackResolver(e.getResolve,t,s);return function importer(t,s,n){const{fromImport:o}=this;r(s,t,o).then((t=>{e.addDependency(_path.default.normalize(t));n({file:t.replace(MATCH_CSS,"")})})).catch((()=>{n({file:t})}))}}let nodeSassJobQueue=null;function getRenderFunctionFromSassImplementation(e){const t=e.info.includes("dart-sass");if(t){return e.render.bind(e)}if(nodeSassJobQueue===null){const t=Number(process.env.UV_THREADPOOL_SIZE||4);nodeSassJobQueue=_neoAsync.default.queue(e.render.bind(e),t-1)}return nodeSassJobQueue.push.bind(nodeSassJobQueue)}const ABSOLUTE_SCHEME=/^[A-Za-z0-9+\-.]+:/;function getURLType(e){if(e[0]==="/"){if(e[1]==="/"){return"scheme-relative"}return"path-absolute"}if(IS_NATIVE_WIN32_PATH.test(e)){return"path-absolute"}return ABSOLUTE_SCHEME.test(e)?"absolute":"path-relative"}function normalizeSourceMap(e,t){const s=e;delete s.file;s.sourceRoot="";s.sources=s.sources.map((e=>{const s=getURLType(e);if(s==="path-relative"){return _path.default.resolve(t,_path.default.normalize(e))}return e}));return s}},175:function(e){"use strict";e.exports=require("next/dist/compiled/neo-async")},17:function(e){"use strict";e.exports=require("path")},438:function(e){"use strict";e.exports=require("sass")},310:function(e){"use strict";e.exports=require("url")},596:function(e){"use strict";e.exports=JSON.parse('{"title":"Sass Loader options","type":"object","properties":{"implementation":{"description":"The implementation of the sass to be used.","link":"https://github.com/webpack-contrib/sass-loader#implementation","anyOf":[{"type":"string"},{"type":"object"}]},"sassOptions":{"description":"Options for `node-sass` or `sass` (`Dart Sass`) implementation.","link":"https://github.com/webpack-contrib/sass-loader#sassoptions","anyOf":[{"type":"object","additionalProperties":true},{"instanceof":"Function"}]},"additionalData":{"description":"Prepends/Appends `Sass`/`SCSS` code before the actual entry file.","link":"https://github.com/webpack-contrib/sass-loader#additionaldata","anyOf":[{"type":"string"},{"instanceof":"Function"}]},"sourceMap":{"description":"Enables/Disables generation of source maps.","link":"https://github.com/webpack-contrib/sass-loader#sourcemap","type":"boolean"},"webpackImporter":{"description":"Enables/Disables default `webpack` importer.","link":"https://github.com/webpack-contrib/sass-loader#webpackimporter","type":"boolean"},"warnRuleAsWarning":{"description":"Treats the \'@warn\' rule as a webpack warning.","link":"https://github.com/webpack-contrib/sass-loader#warnruleaswarning","type":"boolean"}},"additionalProperties":false}')}};var __webpack_module_cache__={};function __nccwpck_require__(e){var t=__webpack_module_cache__[e];if(t!==undefined){return t.exports}var s=__webpack_module_cache__[e]={exports:{}};var r=true;try{__webpack_modules__[e](s,s.exports,__nccwpck_require__);r=false}finally{if(r)delete __webpack_module_cache__[e]}return s.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var __webpack_exports__=__nccwpck_require__(917);module.exports=__webpack_exports__})(); \ No newline at end of file diff --git a/packages/next/src/compiled/zod/LICENSE b/packages/next/src/compiled/zod/LICENSE new file mode 100644 index 000000000000..2c93bb52b933 --- /dev/null +++ b/packages/next/src/compiled/zod/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Colin McDonnell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/next/src/compiled/zod/index.js b/packages/next/src/compiled/zod/index.js new file mode 100644 index 000000000000..daacf47c5dbb --- /dev/null +++ b/packages/next/src/compiled/zod/index.js @@ -0,0 +1 @@ +(()=>{"use strict";var e={815:(e,t,s)=>{Object.defineProperty(t,"__esModule",{value:true});t.ZodError=t.quotelessJson=t.ZodIssueCode=void 0;const r=s(900);t.ZodIssueCode=r.util.arrayToEnum(["invalid_type","invalid_literal","custom","invalid_union","invalid_union_discriminator","invalid_enum_value","unrecognized_keys","invalid_arguments","invalid_return_type","invalid_date","invalid_string","too_small","too_big","invalid_intersection_types","not_multiple_of","not_finite"]);const quotelessJson=e=>{const t=JSON.stringify(e,null,2);return t.replace(/"([^"]+)":/g,"$1:")};t.quotelessJson=quotelessJson;class ZodError extends Error{constructor(e){super();this.issues=[];this.addIssue=e=>{this.issues=[...this.issues,e]};this.addIssues=(e=[])=>{this.issues=[...this.issues,...e]};const t=new.target.prototype;if(Object.setPrototypeOf){Object.setPrototypeOf(this,t)}else{this.__proto__=t}this.name="ZodError";this.issues=e}get errors(){return this.issues}format(e){const t=e||function(e){return e.message};const s={_errors:[]};const processError=e=>{for(const r of e.issues){if(r.code==="invalid_union"){r.unionErrors.map(processError)}else if(r.code==="invalid_return_type"){processError(r.returnTypeError)}else if(r.code==="invalid_arguments"){processError(r.argumentsError)}else if(r.path.length===0){s._errors.push(t(r))}else{let e=s;let a=0;while(ae.message)){const t={};const s=[];for(const r of this.issues){if(r.path.length>0){t[r.path[0]]=t[r.path[0]]||[];t[r.path[0]].push(e(r))}else{s.push(e(r))}}return{formErrors:s,fieldErrors:t}}get formErrors(){return this.flatten()}}t.ZodError=ZodError;ZodError.create=e=>{const t=new ZodError(e);return t}},564:function(e,t,s){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.getErrorMap=t.setErrorMap=t.defaultErrorMap=void 0;const a=r(s(209));t.defaultErrorMap=a.default;let n=a.default;function setErrorMap(e){n=e}t.setErrorMap=setErrorMap;function getErrorMap(){return n}t.getErrorMap=getErrorMap},631:function(e,t,s){var r=this&&this.__createBinding||(Object.create?function(e,t,s,r){if(r===undefined)r=s;Object.defineProperty(e,r,{enumerable:true,get:function(){return t[s]}})}:function(e,t,s,r){if(r===undefined)r=s;e[r]=t[s]});var a=this&&this.__exportStar||function(e,t){for(var s in e)if(s!=="default"&&!Object.prototype.hasOwnProperty.call(t,s))r(t,e,s)};Object.defineProperty(t,"__esModule",{value:true});a(s(564),t);a(s(79),t);a(s(212),t);a(s(900),t);a(s(973),t);a(s(815),t)},97:(e,t)=>{Object.defineProperty(t,"__esModule",{value:true});t.errorUtil=void 0;var s;(function(e){e.errToObj=e=>typeof e==="string"?{message:e}:e||{};e.toString=e=>typeof e==="string"?e:e===null||e===void 0?void 0:e.message})(s=t.errorUtil||(t.errorUtil={}))},79:function(e,t,s){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.isAsync=t.isValid=t.isDirty=t.isAborted=t.OK=t.DIRTY=t.INVALID=t.ParseStatus=t.addIssueToContext=t.EMPTY_PATH=t.makeIssue=void 0;const a=s(564);const n=r(s(209));const makeIssue=e=>{const{data:t,path:s,errorMaps:r,issueData:a}=e;const n=[...s,...a.path||[]];const o={...a,path:n};let i="";const d=r.filter((e=>!!e)).slice().reverse();for(const e of d){i=e(o,{data:t,defaultError:i}).message}return{...a,path:n,message:a.message||i}};t.makeIssue=makeIssue;t.EMPTY_PATH=[];function addIssueToContext(e,s){const r=(0,t.makeIssue)({issueData:s,data:e.data,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,(0,a.getErrorMap)(),n.default].filter((e=>!!e))});e.common.issues.push(r)}t.addIssueToContext=addIssueToContext;class ParseStatus{constructor(){this.value="valid"}dirty(){if(this.value==="valid")this.value="dirty"}abort(){if(this.value!=="aborted")this.value="aborted"}static mergeArray(e,s){const r=[];for(const a of s){if(a.status==="aborted")return t.INVALID;if(a.status==="dirty")e.dirty();r.push(a.value)}return{status:e.value,value:r}}static async mergeObjectAsync(e,t){const s=[];for(const e of t){s.push({key:await e.key,value:await e.value})}return ParseStatus.mergeObjectSync(e,s)}static mergeObjectSync(e,s){const r={};for(const a of s){const{key:s,value:n}=a;if(s.status==="aborted")return t.INVALID;if(n.status==="aborted")return t.INVALID;if(s.status==="dirty")e.dirty();if(n.status==="dirty")e.dirty();if(s.value!=="__proto__"&&(typeof n.value!=="undefined"||a.alwaysSet)){r[s.value]=n.value}}return{status:e.value,value:r}}}t.ParseStatus=ParseStatus;t.INVALID=Object.freeze({status:"aborted"});const DIRTY=e=>({status:"dirty",value:e});t.DIRTY=DIRTY;const OK=e=>({status:"valid",value:e});t.OK=OK;const isAborted=e=>e.status==="aborted";t.isAborted=isAborted;const isDirty=e=>e.status==="dirty";t.isDirty=isDirty;const isValid=e=>e.status==="valid";t.isValid=isValid;const isAsync=e=>typeof Promise!=="undefined"&&e instanceof Promise;t.isAsync=isAsync},212:(e,t)=>{Object.defineProperty(t,"__esModule",{value:true})},900:(e,t)=>{Object.defineProperty(t,"__esModule",{value:true});t.getParsedType=t.ZodParsedType=t.objectUtil=t.util=void 0;var s;(function(e){e.assertEqual=e=>e;function assertIs(e){}e.assertIs=assertIs;function assertNever(e){throw new Error}e.assertNever=assertNever;e.arrayToEnum=e=>{const t={};for(const s of e){t[s]=s}return t};e.getValidEnumValues=t=>{const s=e.objectKeys(t).filter((e=>typeof t[t[e]]!=="number"));const r={};for(const e of s){r[e]=t[e]}return e.objectValues(r)};e.objectValues=t=>e.objectKeys(t).map((function(e){return t[e]}));e.objectKeys=typeof Object.keys==="function"?e=>Object.keys(e):e=>{const t=[];for(const s in e){if(Object.prototype.hasOwnProperty.call(e,s)){t.push(s)}}return t};e.find=(e,t)=>{for(const s of e){if(t(s))return s}return undefined};e.isInteger=typeof Number.isInteger==="function"?e=>Number.isInteger(e):e=>typeof e==="number"&&isFinite(e)&&Math.floor(e)===e;function joinValues(e,t=" | "){return e.map((e=>typeof e==="string"?`'${e}'`:e)).join(t)}e.joinValues=joinValues;e.jsonStringifyReplacer=(e,t)=>{if(typeof t==="bigint"){return t.toString()}return t}})(s=t.util||(t.util={}));var r;(function(e){e.mergeShapes=(e,t)=>({...e,...t})})(r=t.objectUtil||(t.objectUtil={}));t.ZodParsedType=s.arrayToEnum(["string","nan","number","integer","float","boolean","date","bigint","symbol","function","undefined","null","array","object","unknown","promise","void","never","map","set"]);const getParsedType=e=>{const s=typeof e;switch(s){case"undefined":return t.ZodParsedType.undefined;case"string":return t.ZodParsedType.string;case"number":return isNaN(e)?t.ZodParsedType.nan:t.ZodParsedType.number;case"boolean":return t.ZodParsedType.boolean;case"function":return t.ZodParsedType.function;case"bigint":return t.ZodParsedType.bigint;case"symbol":return t.ZodParsedType.symbol;case"object":if(Array.isArray(e)){return t.ZodParsedType.array}if(e===null){return t.ZodParsedType.null}if(e.then&&typeof e.then==="function"&&e.catch&&typeof e.catch==="function"){return t.ZodParsedType.promise}if(typeof Map!=="undefined"&&e instanceof Map){return t.ZodParsedType.map}if(typeof Set!=="undefined"&&e instanceof Set){return t.ZodParsedType.set}if(typeof Date!=="undefined"&&e instanceof Date){return t.ZodParsedType.date}return t.ZodParsedType.object;default:return t.ZodParsedType.unknown}};t.getParsedType=getParsedType},773:function(e,t,s){var r=this&&this.__createBinding||(Object.create?function(e,t,s,r){if(r===undefined)r=s;Object.defineProperty(e,r,{enumerable:true,get:function(){return t[s]}})}:function(e,t,s,r){if(r===undefined)r=s;e[r]=t[s]});var a=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var s in e)if(s!=="default"&&Object.prototype.hasOwnProperty.call(e,s))r(t,e,s);a(t,e);return t};var o=this&&this.__exportStar||function(e,t){for(var s in e)if(s!=="default"&&!Object.prototype.hasOwnProperty.call(t,s))r(t,e,s)};Object.defineProperty(t,"__esModule",{value:true});t.z=void 0;const i=n(s(631));t.z=i;o(s(631),t);t["default"]=i},209:(e,t,s)=>{Object.defineProperty(t,"__esModule",{value:true});const r=s(900);const a=s(815);const errorMap=(e,t)=>{let s;switch(e.code){case a.ZodIssueCode.invalid_type:if(e.received===r.ZodParsedType.undefined){s="Required"}else{s=`Expected ${e.expected}, received ${e.received}`}break;case a.ZodIssueCode.invalid_literal:s=`Invalid literal value, expected ${JSON.stringify(e.expected,r.util.jsonStringifyReplacer)}`;break;case a.ZodIssueCode.unrecognized_keys:s=`Unrecognized key(s) in object: ${r.util.joinValues(e.keys,", ")}`;break;case a.ZodIssueCode.invalid_union:s=`Invalid input`;break;case a.ZodIssueCode.invalid_union_discriminator:s=`Invalid discriminator value. Expected ${r.util.joinValues(e.options)}`;break;case a.ZodIssueCode.invalid_enum_value:s=`Invalid enum value. Expected ${r.util.joinValues(e.options)}, received '${e.received}'`;break;case a.ZodIssueCode.invalid_arguments:s=`Invalid function arguments`;break;case a.ZodIssueCode.invalid_return_type:s=`Invalid function return type`;break;case a.ZodIssueCode.invalid_date:s=`Invalid date`;break;case a.ZodIssueCode.invalid_string:if(typeof e.validation==="object"){if("includes"in e.validation){s=`Invalid input: must include "${e.validation.includes}"`;if(typeof e.validation.position==="number"){s=`${s} at one or more positions greater than or equal to ${e.validation.position}`}}else if("startsWith"in e.validation){s=`Invalid input: must start with "${e.validation.startsWith}"`}else if("endsWith"in e.validation){s=`Invalid input: must end with "${e.validation.endsWith}"`}else{r.util.assertNever(e.validation)}}else if(e.validation!=="regex"){s=`Invalid ${e.validation}`}else{s="Invalid"}break;case a.ZodIssueCode.too_small:if(e.type==="array")s=`Array must contain ${e.exact?"exactly":e.inclusive?`at least`:`more than`} ${e.minimum} element(s)`;else if(e.type==="string")s=`String must contain ${e.exact?"exactly":e.inclusive?`at least`:`over`} ${e.minimum} character(s)`;else if(e.type==="number")s=`Number must be ${e.exact?`exactly equal to `:e.inclusive?`greater than or equal to `:`greater than `}${e.minimum}`;else if(e.type==="date")s=`Date must be ${e.exact?`exactly equal to `:e.inclusive?`greater than or equal to `:`greater than `}${new Date(Number(e.minimum))}`;else s="Invalid input";break;case a.ZodIssueCode.too_big:if(e.type==="array")s=`Array must contain ${e.exact?`exactly`:e.inclusive?`at most`:`less than`} ${e.maximum} element(s)`;else if(e.type==="string")s=`String must contain ${e.exact?`exactly`:e.inclusive?`at most`:`under`} ${e.maximum} character(s)`;else if(e.type==="number")s=`Number must be ${e.exact?`exactly`:e.inclusive?`less than or equal to`:`less than`} ${e.maximum}`;else if(e.type==="bigint")s=`BigInt must be ${e.exact?`exactly`:e.inclusive?`less than or equal to`:`less than`} ${e.maximum}`;else if(e.type==="date")s=`Date must be ${e.exact?`exactly`:e.inclusive?`smaller than or equal to`:`smaller than`} ${new Date(Number(e.maximum))}`;else s="Invalid input";break;case a.ZodIssueCode.custom:s=`Invalid input`;break;case a.ZodIssueCode.invalid_intersection_types:s=`Intersection results could not be merged`;break;case a.ZodIssueCode.not_multiple_of:s=`Number must be a multiple of ${e.multipleOf}`;break;case a.ZodIssueCode.not_finite:s="Number must be finite";break;default:s=t.defaultError;r.util.assertNever(e)}return{message:s}};t["default"]=errorMap},973:(e,t,s)=>{Object.defineProperty(t,"__esModule",{value:true});t.date=t.boolean=t.bigint=t.array=t.any=t.coerce=t.ZodFirstPartyTypeKind=t.late=t.ZodSchema=t.Schema=t.custom=t.ZodReadonly=t.ZodPipeline=t.ZodBranded=t.BRAND=t.ZodNaN=t.ZodCatch=t.ZodDefault=t.ZodNullable=t.ZodOptional=t.ZodTransformer=t.ZodEffects=t.ZodPromise=t.ZodNativeEnum=t.ZodEnum=t.ZodLiteral=t.ZodLazy=t.ZodFunction=t.ZodSet=t.ZodMap=t.ZodRecord=t.ZodTuple=t.ZodIntersection=t.ZodDiscriminatedUnion=t.ZodUnion=t.ZodObject=t.ZodArray=t.ZodVoid=t.ZodNever=t.ZodUnknown=t.ZodAny=t.ZodNull=t.ZodUndefined=t.ZodSymbol=t.ZodDate=t.ZodBoolean=t.ZodBigInt=t.ZodNumber=t.ZodString=t.ZodType=void 0;t.NEVER=t["void"]=t.unknown=t.union=t.undefined=t.tuple=t.transformer=t.symbol=t.string=t.strictObject=t.set=t.record=t.promise=t.preprocess=t.pipeline=t.ostring=t.optional=t.onumber=t.oboolean=t.object=t.number=t.nullable=t["null"]=t.never=t.nativeEnum=t.nan=t.map=t.literal=t.lazy=t.intersection=t["instanceof"]=t["function"]=t["enum"]=t.effect=t.discriminatedUnion=void 0;const r=s(564);const a=s(97);const n=s(79);const o=s(900);const i=s(815);class ParseInputLazyPath{constructor(e,t,s,r){this._cachedPath=[];this.parent=e;this.data=t;this._path=s;this._key=r}get path(){if(!this._cachedPath.length){if(this._key instanceof Array){this._cachedPath.push(...this._path,...this._key)}else{this._cachedPath.push(...this._path,this._key)}}return this._cachedPath}}const handleResult=(e,t)=>{if((0,n.isValid)(t)){return{success:true,data:t.value}}else{if(!e.common.issues.length){throw new Error("Validation failed but no issues detected.")}return{success:false,get error(){if(this._error)return this._error;const t=new i.ZodError(e.common.issues);this._error=t;return this._error}}}};function processCreateParams(e){if(!e)return{};const{errorMap:t,invalid_type_error:s,required_error:r,description:a}=e;if(t&&(s||r)){throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`)}if(t)return{errorMap:t,description:a};const customMap=(e,t)=>{if(e.code!=="invalid_type")return{message:t.defaultError};if(typeof t.data==="undefined"){return{message:r!==null&&r!==void 0?r:t.defaultError}}return{message:s!==null&&s!==void 0?s:t.defaultError}};return{errorMap:customMap,description:a}}class ZodType{constructor(e){this.spa=this.safeParseAsync;this._def=e;this.parse=this.parse.bind(this);this.safeParse=this.safeParse.bind(this);this.parseAsync=this.parseAsync.bind(this);this.safeParseAsync=this.safeParseAsync.bind(this);this.spa=this.spa.bind(this);this.refine=this.refine.bind(this);this.refinement=this.refinement.bind(this);this.superRefine=this.superRefine.bind(this);this.optional=this.optional.bind(this);this.nullable=this.nullable.bind(this);this.nullish=this.nullish.bind(this);this.array=this.array.bind(this);this.promise=this.promise.bind(this);this.or=this.or.bind(this);this.and=this.and.bind(this);this.transform=this.transform.bind(this);this.brand=this.brand.bind(this);this.default=this.default.bind(this);this.catch=this.catch.bind(this);this.describe=this.describe.bind(this);this.pipe=this.pipe.bind(this);this.readonly=this.readonly.bind(this);this.isNullable=this.isNullable.bind(this);this.isOptional=this.isOptional.bind(this)}get description(){return this._def.description}_getType(e){return(0,o.getParsedType)(e.data)}_getOrReturnCtx(e,t){return t||{common:e.parent.common,data:e.data,parsedType:(0,o.getParsedType)(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}_processInputParams(e){return{status:new n.ParseStatus,ctx:{common:e.parent.common,data:e.data,parsedType:(0,o.getParsedType)(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}}_parseSync(e){const t=this._parse(e);if((0,n.isAsync)(t)){throw new Error("Synchronous parse encountered promise.")}return t}_parseAsync(e){const t=this._parse(e);return Promise.resolve(t)}parse(e,t){const s=this.safeParse(e,t);if(s.success)return s.data;throw s.error}safeParse(e,t){var s;const r={common:{issues:[],async:(s=t===null||t===void 0?void 0:t.async)!==null&&s!==void 0?s:false,contextualErrorMap:t===null||t===void 0?void 0:t.errorMap},path:(t===null||t===void 0?void 0:t.path)||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:(0,o.getParsedType)(e)};const a=this._parseSync({data:e,path:r.path,parent:r});return handleResult(r,a)}async parseAsync(e,t){const s=await this.safeParseAsync(e,t);if(s.success)return s.data;throw s.error}async safeParseAsync(e,t){const s={common:{issues:[],contextualErrorMap:t===null||t===void 0?void 0:t.errorMap,async:true},path:(t===null||t===void 0?void 0:t.path)||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:(0,o.getParsedType)(e)};const r=this._parse({data:e,path:s.path,parent:s});const a=await((0,n.isAsync)(r)?r:Promise.resolve(r));return handleResult(s,a)}refine(e,t){const getIssueProperties=e=>{if(typeof t==="string"||typeof t==="undefined"){return{message:t}}else if(typeof t==="function"){return t(e)}else{return t}};return this._refinement(((t,s)=>{const r=e(t);const setError=()=>s.addIssue({code:i.ZodIssueCode.custom,...getIssueProperties(t)});if(typeof Promise!=="undefined"&&r instanceof Promise){return r.then((e=>{if(!e){setError();return false}else{return true}}))}if(!r){setError();return false}else{return true}}))}refinement(e,t){return this._refinement(((s,r)=>{if(!e(s)){r.addIssue(typeof t==="function"?t(s,r):t);return false}else{return true}}))}_refinement(e){return new ZodEffects({schema:this,typeName:y.ZodEffects,effect:{type:"refinement",refinement:e}})}superRefine(e){return this._refinement(e)}optional(){return ZodOptional.create(this,this._def)}nullable(){return ZodNullable.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return ZodArray.create(this,this._def)}promise(){return ZodPromise.create(this,this._def)}or(e){return ZodUnion.create([this,e],this._def)}and(e){return ZodIntersection.create(this,e,this._def)}transform(e){return new ZodEffects({...processCreateParams(this._def),schema:this,typeName:y.ZodEffects,effect:{type:"transform",transform:e}})}default(e){const t=typeof e==="function"?e:()=>e;return new ZodDefault({...processCreateParams(this._def),innerType:this,defaultValue:t,typeName:y.ZodDefault})}brand(){return new ZodBranded({typeName:y.ZodBranded,type:this,...processCreateParams(this._def)})}catch(e){const t=typeof e==="function"?e:()=>e;return new ZodCatch({...processCreateParams(this._def),innerType:this,catchValue:t,typeName:y.ZodCatch})}describe(e){const t=this.constructor;return new t({...this._def,description:e})}pipe(e){return ZodPipeline.create(this,e)}readonly(){return ZodReadonly.create(this)}isOptional(){return this.safeParse(undefined).success}isNullable(){return this.safeParse(null).success}}t.ZodType=ZodType;t.Schema=ZodType;t.ZodSchema=ZodType;const d=/^c[^\s-]{8,}$/i;const u=/^[a-z][a-z0-9]*$/;const c=/[0-9A-HJKMNP-TV-Z]{26}/;const l=/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i;const p=/^(?!\.)(?!.*\.\.)([A-Z0-9_+-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i;const f=/^(\p{Extended_Pictographic}|\p{Emoji_Component})+$/u;const h=/^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/;const m=/^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/;const datetimeRegex=e=>{if(e.precision){if(e.offset){return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{${e.precision}}(([+-]\\d{2}(:?\\d{2})?)|Z)$`)}else{return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{${e.precision}}Z$`)}}else if(e.precision===0){if(e.offset){return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(([+-]\\d{2}(:?\\d{2})?)|Z)$`)}else{return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$`)}}else{if(e.offset){return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(([+-]\\d{2}(:?\\d{2})?)|Z)$`)}else{return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$`)}}};function isValidIP(e,t){if((t==="v4"||!t)&&h.test(e)){return true}if((t==="v6"||!t)&&m.test(e)){return true}return false}class ZodString extends ZodType{constructor(){super(...arguments);this._regex=(e,t,s)=>this.refinement((t=>e.test(t)),{validation:t,code:i.ZodIssueCode.invalid_string,...a.errorUtil.errToObj(s)});this.nonempty=e=>this.min(1,a.errorUtil.errToObj(e));this.trim=()=>new ZodString({...this._def,checks:[...this._def.checks,{kind:"trim"}]});this.toLowerCase=()=>new ZodString({...this._def,checks:[...this._def.checks,{kind:"toLowerCase"}]});this.toUpperCase=()=>new ZodString({...this._def,checks:[...this._def.checks,{kind:"toUpperCase"}]})}_parse(e){if(this._def.coerce){e.data=String(e.data)}const t=this._getType(e);if(t!==o.ZodParsedType.string){const t=this._getOrReturnCtx(e);(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.string,received:t.parsedType});return n.INVALID}const s=new n.ParseStatus;let r=undefined;for(const t of this._def.checks){if(t.kind==="min"){if(e.data.lengtht.value){r=this._getOrReturnCtx(e,r);(0,n.addIssueToContext)(r,{code:i.ZodIssueCode.too_big,maximum:t.value,type:"string",inclusive:true,exact:false,message:t.message});s.dirty()}}else if(t.kind==="length"){const a=e.data.length>t.value;const o=e.data.lengthe.kind==="datetime"))}get isEmail(){return!!this._def.checks.find((e=>e.kind==="email"))}get isURL(){return!!this._def.checks.find((e=>e.kind==="url"))}get isEmoji(){return!!this._def.checks.find((e=>e.kind==="emoji"))}get isUUID(){return!!this._def.checks.find((e=>e.kind==="uuid"))}get isCUID(){return!!this._def.checks.find((e=>e.kind==="cuid"))}get isCUID2(){return!!this._def.checks.find((e=>e.kind==="cuid2"))}get isULID(){return!!this._def.checks.find((e=>e.kind==="ulid"))}get isIP(){return!!this._def.checks.find((e=>e.kind==="ip"))}get minLength(){let e=null;for(const t of this._def.checks){if(t.kind==="min"){if(e===null||t.value>e)e=t.value}}return e}get maxLength(){let e=null;for(const t of this._def.checks){if(t.kind==="max"){if(e===null||t.value{var t;return new ZodString({checks:[],typeName:y.ZodString,coerce:(t=e===null||e===void 0?void 0:e.coerce)!==null&&t!==void 0?t:false,...processCreateParams(e)})};function floatSafeRemainder(e,t){const s=(e.toString().split(".")[1]||"").length;const r=(t.toString().split(".")[1]||"").length;const a=s>r?s:r;const n=parseInt(e.toFixed(a).replace(".",""));const o=parseInt(t.toFixed(a).replace(".",""));return n%o/Math.pow(10,a)}class ZodNumber extends ZodType{constructor(){super(...arguments);this.min=this.gte;this.max=this.lte;this.step=this.multipleOf}_parse(e){if(this._def.coerce){e.data=Number(e.data)}const t=this._getType(e);if(t!==o.ZodParsedType.number){const t=this._getOrReturnCtx(e);(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.number,received:t.parsedType});return n.INVALID}let s=undefined;const r=new n.ParseStatus;for(const t of this._def.checks){if(t.kind==="int"){if(!o.util.isInteger(e.data)){s=this._getOrReturnCtx(e,s);(0,n.addIssueToContext)(s,{code:i.ZodIssueCode.invalid_type,expected:"integer",received:"float",message:t.message});r.dirty()}}else if(t.kind==="min"){const a=t.inclusive?e.datat.value:e.data>=t.value;if(a){s=this._getOrReturnCtx(e,s);(0,n.addIssueToContext)(s,{code:i.ZodIssueCode.too_big,maximum:t.value,type:"number",inclusive:t.inclusive,exact:false,message:t.message});r.dirty()}}else if(t.kind==="multipleOf"){if(floatSafeRemainder(e.data,t.value)!==0){s=this._getOrReturnCtx(e,s);(0,n.addIssueToContext)(s,{code:i.ZodIssueCode.not_multiple_of,multipleOf:t.value,message:t.message});r.dirty()}}else if(t.kind==="finite"){if(!Number.isFinite(e.data)){s=this._getOrReturnCtx(e,s);(0,n.addIssueToContext)(s,{code:i.ZodIssueCode.not_finite,message:t.message});r.dirty()}}else{o.util.assertNever(t)}}return{status:r.value,value:e.data}}gte(e,t){return this.setLimit("min",e,true,a.errorUtil.toString(t))}gt(e,t){return this.setLimit("min",e,false,a.errorUtil.toString(t))}lte(e,t){return this.setLimit("max",e,true,a.errorUtil.toString(t))}lt(e,t){return this.setLimit("max",e,false,a.errorUtil.toString(t))}setLimit(e,t,s,r){return new ZodNumber({...this._def,checks:[...this._def.checks,{kind:e,value:t,inclusive:s,message:a.errorUtil.toString(r)}]})}_addCheck(e){return new ZodNumber({...this._def,checks:[...this._def.checks,e]})}int(e){return this._addCheck({kind:"int",message:a.errorUtil.toString(e)})}positive(e){return this._addCheck({kind:"min",value:0,inclusive:false,message:a.errorUtil.toString(e)})}negative(e){return this._addCheck({kind:"max",value:0,inclusive:false,message:a.errorUtil.toString(e)})}nonpositive(e){return this._addCheck({kind:"max",value:0,inclusive:true,message:a.errorUtil.toString(e)})}nonnegative(e){return this._addCheck({kind:"min",value:0,inclusive:true,message:a.errorUtil.toString(e)})}multipleOf(e,t){return this._addCheck({kind:"multipleOf",value:e,message:a.errorUtil.toString(t)})}finite(e){return this._addCheck({kind:"finite",message:a.errorUtil.toString(e)})}safe(e){return this._addCheck({kind:"min",inclusive:true,value:Number.MIN_SAFE_INTEGER,message:a.errorUtil.toString(e)})._addCheck({kind:"max",inclusive:true,value:Number.MAX_SAFE_INTEGER,message:a.errorUtil.toString(e)})}get minValue(){let e=null;for(const t of this._def.checks){if(t.kind==="min"){if(e===null||t.value>e)e=t.value}}return e}get maxValue(){let e=null;for(const t of this._def.checks){if(t.kind==="max"){if(e===null||t.valuee.kind==="int"||e.kind==="multipleOf"&&o.util.isInteger(e.value)))}get isFinite(){let e=null,t=null;for(const s of this._def.checks){if(s.kind==="finite"||s.kind==="int"||s.kind==="multipleOf"){return true}else if(s.kind==="min"){if(t===null||s.value>t)t=s.value}else if(s.kind==="max"){if(e===null||s.valuenew ZodNumber({checks:[],typeName:y.ZodNumber,coerce:(e===null||e===void 0?void 0:e.coerce)||false,...processCreateParams(e)});class ZodBigInt extends ZodType{constructor(){super(...arguments);this.min=this.gte;this.max=this.lte}_parse(e){if(this._def.coerce){e.data=BigInt(e.data)}const t=this._getType(e);if(t!==o.ZodParsedType.bigint){const t=this._getOrReturnCtx(e);(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.bigint,received:t.parsedType});return n.INVALID}let s=undefined;const r=new n.ParseStatus;for(const t of this._def.checks){if(t.kind==="min"){const a=t.inclusive?e.datat.value:e.data>=t.value;if(a){s=this._getOrReturnCtx(e,s);(0,n.addIssueToContext)(s,{code:i.ZodIssueCode.too_big,type:"bigint",maximum:t.value,inclusive:t.inclusive,message:t.message});r.dirty()}}else if(t.kind==="multipleOf"){if(e.data%t.value!==BigInt(0)){s=this._getOrReturnCtx(e,s);(0,n.addIssueToContext)(s,{code:i.ZodIssueCode.not_multiple_of,multipleOf:t.value,message:t.message});r.dirty()}}else{o.util.assertNever(t)}}return{status:r.value,value:e.data}}gte(e,t){return this.setLimit("min",e,true,a.errorUtil.toString(t))}gt(e,t){return this.setLimit("min",e,false,a.errorUtil.toString(t))}lte(e,t){return this.setLimit("max",e,true,a.errorUtil.toString(t))}lt(e,t){return this.setLimit("max",e,false,a.errorUtil.toString(t))}setLimit(e,t,s,r){return new ZodBigInt({...this._def,checks:[...this._def.checks,{kind:e,value:t,inclusive:s,message:a.errorUtil.toString(r)}]})}_addCheck(e){return new ZodBigInt({...this._def,checks:[...this._def.checks,e]})}positive(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:false,message:a.errorUtil.toString(e)})}negative(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:false,message:a.errorUtil.toString(e)})}nonpositive(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:true,message:a.errorUtil.toString(e)})}nonnegative(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:true,message:a.errorUtil.toString(e)})}multipleOf(e,t){return this._addCheck({kind:"multipleOf",value:e,message:a.errorUtil.toString(t)})}get minValue(){let e=null;for(const t of this._def.checks){if(t.kind==="min"){if(e===null||t.value>e)e=t.value}}return e}get maxValue(){let e=null;for(const t of this._def.checks){if(t.kind==="max"){if(e===null||t.value{var t;return new ZodBigInt({checks:[],typeName:y.ZodBigInt,coerce:(t=e===null||e===void 0?void 0:e.coerce)!==null&&t!==void 0?t:false,...processCreateParams(e)})};class ZodBoolean extends ZodType{_parse(e){if(this._def.coerce){e.data=Boolean(e.data)}const t=this._getType(e);if(t!==o.ZodParsedType.boolean){const t=this._getOrReturnCtx(e);(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.boolean,received:t.parsedType});return n.INVALID}return(0,n.OK)(e.data)}}t.ZodBoolean=ZodBoolean;ZodBoolean.create=e=>new ZodBoolean({typeName:y.ZodBoolean,coerce:(e===null||e===void 0?void 0:e.coerce)||false,...processCreateParams(e)});class ZodDate extends ZodType{_parse(e){if(this._def.coerce){e.data=new Date(e.data)}const t=this._getType(e);if(t!==o.ZodParsedType.date){const t=this._getOrReturnCtx(e);(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.date,received:t.parsedType});return n.INVALID}if(isNaN(e.data.getTime())){const t=this._getOrReturnCtx(e);(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_date});return n.INVALID}const s=new n.ParseStatus;let r=undefined;for(const t of this._def.checks){if(t.kind==="min"){if(e.data.getTime()t.value){r=this._getOrReturnCtx(e,r);(0,n.addIssueToContext)(r,{code:i.ZodIssueCode.too_big,message:t.message,inclusive:true,exact:false,maximum:t.value,type:"date"});s.dirty()}}else{o.util.assertNever(t)}}return{status:s.value,value:new Date(e.data.getTime())}}_addCheck(e){return new ZodDate({...this._def,checks:[...this._def.checks,e]})}min(e,t){return this._addCheck({kind:"min",value:e.getTime(),message:a.errorUtil.toString(t)})}max(e,t){return this._addCheck({kind:"max",value:e.getTime(),message:a.errorUtil.toString(t)})}get minDate(){let e=null;for(const t of this._def.checks){if(t.kind==="min"){if(e===null||t.value>e)e=t.value}}return e!=null?new Date(e):null}get maxDate(){let e=null;for(const t of this._def.checks){if(t.kind==="max"){if(e===null||t.valuenew ZodDate({checks:[],coerce:(e===null||e===void 0?void 0:e.coerce)||false,typeName:y.ZodDate,...processCreateParams(e)});class ZodSymbol extends ZodType{_parse(e){const t=this._getType(e);if(t!==o.ZodParsedType.symbol){const t=this._getOrReturnCtx(e);(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.symbol,received:t.parsedType});return n.INVALID}return(0,n.OK)(e.data)}}t.ZodSymbol=ZodSymbol;ZodSymbol.create=e=>new ZodSymbol({typeName:y.ZodSymbol,...processCreateParams(e)});class ZodUndefined extends ZodType{_parse(e){const t=this._getType(e);if(t!==o.ZodParsedType.undefined){const t=this._getOrReturnCtx(e);(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.undefined,received:t.parsedType});return n.INVALID}return(0,n.OK)(e.data)}}t.ZodUndefined=ZodUndefined;ZodUndefined.create=e=>new ZodUndefined({typeName:y.ZodUndefined,...processCreateParams(e)});class ZodNull extends ZodType{_parse(e){const t=this._getType(e);if(t!==o.ZodParsedType.null){const t=this._getOrReturnCtx(e);(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.null,received:t.parsedType});return n.INVALID}return(0,n.OK)(e.data)}}t.ZodNull=ZodNull;ZodNull.create=e=>new ZodNull({typeName:y.ZodNull,...processCreateParams(e)});class ZodAny extends ZodType{constructor(){super(...arguments);this._any=true}_parse(e){return(0,n.OK)(e.data)}}t.ZodAny=ZodAny;ZodAny.create=e=>new ZodAny({typeName:y.ZodAny,...processCreateParams(e)});class ZodUnknown extends ZodType{constructor(){super(...arguments);this._unknown=true}_parse(e){return(0,n.OK)(e.data)}}t.ZodUnknown=ZodUnknown;ZodUnknown.create=e=>new ZodUnknown({typeName:y.ZodUnknown,...processCreateParams(e)});class ZodNever extends ZodType{_parse(e){const t=this._getOrReturnCtx(e);(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.never,received:t.parsedType});return n.INVALID}}t.ZodNever=ZodNever;ZodNever.create=e=>new ZodNever({typeName:y.ZodNever,...processCreateParams(e)});class ZodVoid extends ZodType{_parse(e){const t=this._getType(e);if(t!==o.ZodParsedType.undefined){const t=this._getOrReturnCtx(e);(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.void,received:t.parsedType});return n.INVALID}return(0,n.OK)(e.data)}}t.ZodVoid=ZodVoid;ZodVoid.create=e=>new ZodVoid({typeName:y.ZodVoid,...processCreateParams(e)});class ZodArray extends ZodType{_parse(e){const{ctx:t,status:s}=this._processInputParams(e);const r=this._def;if(t.parsedType!==o.ZodParsedType.array){(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.array,received:t.parsedType});return n.INVALID}if(r.exactLength!==null){const e=t.data.length>r.exactLength.value;const a=t.data.lengthr.maxLength.value){(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.too_big,maximum:r.maxLength.value,type:"array",inclusive:true,exact:false,message:r.maxLength.message});s.dirty()}}if(t.common.async){return Promise.all([...t.data].map(((e,s)=>r.type._parseAsync(new ParseInputLazyPath(t,e,t.path,s))))).then((e=>n.ParseStatus.mergeArray(s,e)))}const a=[...t.data].map(((e,s)=>r.type._parseSync(new ParseInputLazyPath(t,e,t.path,s))));return n.ParseStatus.mergeArray(s,a)}get element(){return this._def.type}min(e,t){return new ZodArray({...this._def,minLength:{value:e,message:a.errorUtil.toString(t)}})}max(e,t){return new ZodArray({...this._def,maxLength:{value:e,message:a.errorUtil.toString(t)}})}length(e,t){return new ZodArray({...this._def,exactLength:{value:e,message:a.errorUtil.toString(t)}})}nonempty(e){return this.min(1,e)}}t.ZodArray=ZodArray;ZodArray.create=(e,t)=>new ZodArray({type:e,minLength:null,maxLength:null,exactLength:null,typeName:y.ZodArray,...processCreateParams(t)});function deepPartialify(e){if(e instanceof ZodObject){const t={};for(const s in e.shape){const r=e.shape[s];t[s]=ZodOptional.create(deepPartialify(r))}return new ZodObject({...e._def,shape:()=>t})}else if(e instanceof ZodArray){return new ZodArray({...e._def,type:deepPartialify(e.element)})}else if(e instanceof ZodOptional){return ZodOptional.create(deepPartialify(e.unwrap()))}else if(e instanceof ZodNullable){return ZodNullable.create(deepPartialify(e.unwrap()))}else if(e instanceof ZodTuple){return ZodTuple.create(e.items.map((e=>deepPartialify(e))))}else{return e}}class ZodObject extends ZodType{constructor(){super(...arguments);this._cached=null;this.nonstrict=this.passthrough;this.augment=this.extend}_getCached(){if(this._cached!==null)return this._cached;const e=this._def.shape();const t=o.util.objectKeys(e);return this._cached={shape:e,keys:t}}_parse(e){const t=this._getType(e);if(t!==o.ZodParsedType.object){const t=this._getOrReturnCtx(e);(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.object,received:t.parsedType});return n.INVALID}const{status:s,ctx:r}=this._processInputParams(e);const{shape:a,keys:d}=this._getCached();const u=[];if(!(this._def.catchall instanceof ZodNever&&this._def.unknownKeys==="strip")){for(const e in r.data){if(!d.includes(e)){u.push(e)}}}const c=[];for(const e of d){const t=a[e];const s=r.data[e];c.push({key:{status:"valid",value:e},value:t._parse(new ParseInputLazyPath(r,s,r.path,e)),alwaysSet:e in r.data})}if(this._def.catchall instanceof ZodNever){const e=this._def.unknownKeys;if(e==="passthrough"){for(const e of u){c.push({key:{status:"valid",value:e},value:{status:"valid",value:r.data[e]}})}}else if(e==="strict"){if(u.length>0){(0,n.addIssueToContext)(r,{code:i.ZodIssueCode.unrecognized_keys,keys:u});s.dirty()}}else if(e==="strip"){}else{throw new Error(`Internal ZodObject error: invalid unknownKeys value.`)}}else{const e=this._def.catchall;for(const t of u){const s=r.data[t];c.push({key:{status:"valid",value:t},value:e._parse(new ParseInputLazyPath(r,s,r.path,t)),alwaysSet:t in r.data})}}if(r.common.async){return Promise.resolve().then((async()=>{const e=[];for(const t of c){const s=await t.key;e.push({key:s,value:await t.value,alwaysSet:t.alwaysSet})}return e})).then((e=>n.ParseStatus.mergeObjectSync(s,e)))}else{return n.ParseStatus.mergeObjectSync(s,c)}}get shape(){return this._def.shape()}strict(e){a.errorUtil.errToObj;return new ZodObject({...this._def,unknownKeys:"strict",...e!==undefined?{errorMap:(t,s)=>{var r,n,o,i;const d=(o=(n=(r=this._def).errorMap)===null||n===void 0?void 0:n.call(r,t,s).message)!==null&&o!==void 0?o:s.defaultError;if(t.code==="unrecognized_keys")return{message:(i=a.errorUtil.errToObj(e).message)!==null&&i!==void 0?i:d};return{message:d}}}:{}})}strip(){return new ZodObject({...this._def,unknownKeys:"strip"})}passthrough(){return new ZodObject({...this._def,unknownKeys:"passthrough"})}extend(e){return new ZodObject({...this._def,shape:()=>({...this._def.shape(),...e})})}merge(e){const t=new ZodObject({unknownKeys:e._def.unknownKeys,catchall:e._def.catchall,shape:()=>({...this._def.shape(),...e._def.shape()}),typeName:y.ZodObject});return t}setKey(e,t){return this.augment({[e]:t})}catchall(e){return new ZodObject({...this._def,catchall:e})}pick(e){const t={};o.util.objectKeys(e).forEach((s=>{if(e[s]&&this.shape[s]){t[s]=this.shape[s]}}));return new ZodObject({...this._def,shape:()=>t})}omit(e){const t={};o.util.objectKeys(this.shape).forEach((s=>{if(!e[s]){t[s]=this.shape[s]}}));return new ZodObject({...this._def,shape:()=>t})}deepPartial(){return deepPartialify(this)}partial(e){const t={};o.util.objectKeys(this.shape).forEach((s=>{const r=this.shape[s];if(e&&!e[s]){t[s]=r}else{t[s]=r.optional()}}));return new ZodObject({...this._def,shape:()=>t})}required(e){const t={};o.util.objectKeys(this.shape).forEach((s=>{if(e&&!e[s]){t[s]=this.shape[s]}else{const e=this.shape[s];let r=e;while(r instanceof ZodOptional){r=r._def.innerType}t[s]=r}}));return new ZodObject({...this._def,shape:()=>t})}keyof(){return createZodEnum(o.util.objectKeys(this.shape))}}t.ZodObject=ZodObject;ZodObject.create=(e,t)=>new ZodObject({shape:()=>e,unknownKeys:"strip",catchall:ZodNever.create(),typeName:y.ZodObject,...processCreateParams(t)});ZodObject.strictCreate=(e,t)=>new ZodObject({shape:()=>e,unknownKeys:"strict",catchall:ZodNever.create(),typeName:y.ZodObject,...processCreateParams(t)});ZodObject.lazycreate=(e,t)=>new ZodObject({shape:e,unknownKeys:"strip",catchall:ZodNever.create(),typeName:y.ZodObject,...processCreateParams(t)});class ZodUnion extends ZodType{_parse(e){const{ctx:t}=this._processInputParams(e);const s=this._def.options;function handleResults(e){for(const t of e){if(t.result.status==="valid"){return t.result}}for(const s of e){if(s.result.status==="dirty"){t.common.issues.push(...s.ctx.common.issues);return s.result}}const s=e.map((e=>new i.ZodError(e.ctx.common.issues)));(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_union,unionErrors:s});return n.INVALID}if(t.common.async){return Promise.all(s.map((async e=>{const s={...t,common:{...t.common,issues:[]},parent:null};return{result:await e._parseAsync({data:t.data,path:t.path,parent:s}),ctx:s}}))).then(handleResults)}else{let e=undefined;const r=[];for(const a of s){const s={...t,common:{...t.common,issues:[]},parent:null};const n=a._parseSync({data:t.data,path:t.path,parent:s});if(n.status==="valid"){return n}else if(n.status==="dirty"&&!e){e={result:n,ctx:s}}if(s.common.issues.length){r.push(s.common.issues)}}if(e){t.common.issues.push(...e.ctx.common.issues);return e.result}const a=r.map((e=>new i.ZodError(e)));(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_union,unionErrors:a});return n.INVALID}}get options(){return this._def.options}}t.ZodUnion=ZodUnion;ZodUnion.create=(e,t)=>new ZodUnion({options:e,typeName:y.ZodUnion,...processCreateParams(t)});const getDiscriminator=e=>{if(e instanceof ZodLazy){return getDiscriminator(e.schema)}else if(e instanceof ZodEffects){return getDiscriminator(e.innerType())}else if(e instanceof ZodLiteral){return[e.value]}else if(e instanceof ZodEnum){return e.options}else if(e instanceof ZodNativeEnum){return Object.keys(e.enum)}else if(e instanceof ZodDefault){return getDiscriminator(e._def.innerType)}else if(e instanceof ZodUndefined){return[undefined]}else if(e instanceof ZodNull){return[null]}else{return null}};class ZodDiscriminatedUnion extends ZodType{_parse(e){const{ctx:t}=this._processInputParams(e);if(t.parsedType!==o.ZodParsedType.object){(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.object,received:t.parsedType});return n.INVALID}const s=this.discriminator;const r=t.data[s];const a=this.optionsMap.get(r);if(!a){(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[s]});return n.INVALID}if(t.common.async){return a._parseAsync({data:t.data,path:t.path,parent:t})}else{return a._parseSync({data:t.data,path:t.path,parent:t})}}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(e,t,s){const r=new Map;for(const s of t){const t=getDiscriminator(s.shape[e]);if(!t){throw new Error(`A discriminator value for key \`${e}\` could not be extracted from all schema options`)}for(const a of t){if(r.has(a)){throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(a)}`)}r.set(a,s)}}return new ZodDiscriminatedUnion({typeName:y.ZodDiscriminatedUnion,discriminator:e,options:t,optionsMap:r,...processCreateParams(s)})}}t.ZodDiscriminatedUnion=ZodDiscriminatedUnion;function mergeValues(e,t){const s=(0,o.getParsedType)(e);const r=(0,o.getParsedType)(t);if(e===t){return{valid:true,data:e}}else if(s===o.ZodParsedType.object&&r===o.ZodParsedType.object){const s=o.util.objectKeys(t);const r=o.util.objectKeys(e).filter((e=>s.indexOf(e)!==-1));const a={...e,...t};for(const s of r){const r=mergeValues(e[s],t[s]);if(!r.valid){return{valid:false}}a[s]=r.data}return{valid:true,data:a}}else if(s===o.ZodParsedType.array&&r===o.ZodParsedType.array){if(e.length!==t.length){return{valid:false}}const s=[];for(let r=0;r{if((0,n.isAborted)(e)||(0,n.isAborted)(r)){return n.INVALID}const a=mergeValues(e.value,r.value);if(!a.valid){(0,n.addIssueToContext)(s,{code:i.ZodIssueCode.invalid_intersection_types});return n.INVALID}if((0,n.isDirty)(e)||(0,n.isDirty)(r)){t.dirty()}return{status:t.value,value:a.data}};if(s.common.async){return Promise.all([this._def.left._parseAsync({data:s.data,path:s.path,parent:s}),this._def.right._parseAsync({data:s.data,path:s.path,parent:s})]).then((([e,t])=>handleParsed(e,t)))}else{return handleParsed(this._def.left._parseSync({data:s.data,path:s.path,parent:s}),this._def.right._parseSync({data:s.data,path:s.path,parent:s}))}}}t.ZodIntersection=ZodIntersection;ZodIntersection.create=(e,t,s)=>new ZodIntersection({left:e,right:t,typeName:y.ZodIntersection,...processCreateParams(s)});class ZodTuple extends ZodType{_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==o.ZodParsedType.array){(0,n.addIssueToContext)(s,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.array,received:s.parsedType});return n.INVALID}if(s.data.lengththis._def.items.length){(0,n.addIssueToContext)(s,{code:i.ZodIssueCode.too_big,maximum:this._def.items.length,inclusive:true,exact:false,type:"array"});t.dirty()}const a=[...s.data].map(((e,t)=>{const r=this._def.items[t]||this._def.rest;if(!r)return null;return r._parse(new ParseInputLazyPath(s,e,s.path,t))})).filter((e=>!!e));if(s.common.async){return Promise.all(a).then((e=>n.ParseStatus.mergeArray(t,e)))}else{return n.ParseStatus.mergeArray(t,a)}}get items(){return this._def.items}rest(e){return new ZodTuple({...this._def,rest:e})}}t.ZodTuple=ZodTuple;ZodTuple.create=(e,t)=>{if(!Array.isArray(e)){throw new Error("You must pass an array of schemas to z.tuple([ ... ])")}return new ZodTuple({items:e,typeName:y.ZodTuple,rest:null,...processCreateParams(t)})};class ZodRecord extends ZodType{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==o.ZodParsedType.object){(0,n.addIssueToContext)(s,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.object,received:s.parsedType});return n.INVALID}const r=[];const a=this._def.keyType;const d=this._def.valueType;for(const e in s.data){r.push({key:a._parse(new ParseInputLazyPath(s,e,s.path,e)),value:d._parse(new ParseInputLazyPath(s,s.data[e],s.path,e))})}if(s.common.async){return n.ParseStatus.mergeObjectAsync(t,r)}else{return n.ParseStatus.mergeObjectSync(t,r)}}get element(){return this._def.valueType}static create(e,t,s){if(t instanceof ZodType){return new ZodRecord({keyType:e,valueType:t,typeName:y.ZodRecord,...processCreateParams(s)})}return new ZodRecord({keyType:ZodString.create(),valueType:e,typeName:y.ZodRecord,...processCreateParams(t)})}}t.ZodRecord=ZodRecord;class ZodMap extends ZodType{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==o.ZodParsedType.map){(0,n.addIssueToContext)(s,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.map,received:s.parsedType});return n.INVALID}const r=this._def.keyType;const a=this._def.valueType;const d=[...s.data.entries()].map((([e,t],n)=>({key:r._parse(new ParseInputLazyPath(s,e,s.path,[n,"key"])),value:a._parse(new ParseInputLazyPath(s,t,s.path,[n,"value"]))})));if(s.common.async){const e=new Map;return Promise.resolve().then((async()=>{for(const s of d){const r=await s.key;const a=await s.value;if(r.status==="aborted"||a.status==="aborted"){return n.INVALID}if(r.status==="dirty"||a.status==="dirty"){t.dirty()}e.set(r.value,a.value)}return{status:t.value,value:e}}))}else{const e=new Map;for(const s of d){const r=s.key;const a=s.value;if(r.status==="aborted"||a.status==="aborted"){return n.INVALID}if(r.status==="dirty"||a.status==="dirty"){t.dirty()}e.set(r.value,a.value)}return{status:t.value,value:e}}}}t.ZodMap=ZodMap;ZodMap.create=(e,t,s)=>new ZodMap({valueType:t,keyType:e,typeName:y.ZodMap,...processCreateParams(s)});class ZodSet extends ZodType{_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==o.ZodParsedType.set){(0,n.addIssueToContext)(s,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.set,received:s.parsedType});return n.INVALID}const r=this._def;if(r.minSize!==null){if(s.data.sizer.maxSize.value){(0,n.addIssueToContext)(s,{code:i.ZodIssueCode.too_big,maximum:r.maxSize.value,type:"set",inclusive:true,exact:false,message:r.maxSize.message});t.dirty()}}const a=this._def.valueType;function finalizeSet(e){const s=new Set;for(const r of e){if(r.status==="aborted")return n.INVALID;if(r.status==="dirty")t.dirty();s.add(r.value)}return{status:t.value,value:s}}const d=[...s.data.values()].map(((e,t)=>a._parse(new ParseInputLazyPath(s,e,s.path,t))));if(s.common.async){return Promise.all(d).then((e=>finalizeSet(e)))}else{return finalizeSet(d)}}min(e,t){return new ZodSet({...this._def,minSize:{value:e,message:a.errorUtil.toString(t)}})}max(e,t){return new ZodSet({...this._def,maxSize:{value:e,message:a.errorUtil.toString(t)}})}size(e,t){return this.min(e,t).max(e,t)}nonempty(e){return this.min(1,e)}}t.ZodSet=ZodSet;ZodSet.create=(e,t)=>new ZodSet({valueType:e,minSize:null,maxSize:null,typeName:y.ZodSet,...processCreateParams(t)});class ZodFunction extends ZodType{constructor(){super(...arguments);this.validate=this.implement}_parse(e){const{ctx:t}=this._processInputParams(e);if(t.parsedType!==o.ZodParsedType.function){(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.function,received:t.parsedType});return n.INVALID}function makeArgsIssue(e,s){return(0,n.makeIssue)({data:e,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,(0,r.getErrorMap)(),r.defaultErrorMap].filter((e=>!!e)),issueData:{code:i.ZodIssueCode.invalid_arguments,argumentsError:s}})}function makeReturnsIssue(e,s){return(0,n.makeIssue)({data:e,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,(0,r.getErrorMap)(),r.defaultErrorMap].filter((e=>!!e)),issueData:{code:i.ZodIssueCode.invalid_return_type,returnTypeError:s}})}const s={errorMap:t.common.contextualErrorMap};const a=t.data;if(this._def.returns instanceof ZodPromise){const e=this;return(0,n.OK)((async function(...t){const r=new i.ZodError([]);const n=await e._def.args.parseAsync(t,s).catch((e=>{r.addIssue(makeArgsIssue(t,e));throw r}));const o=await Reflect.apply(a,this,n);const d=await e._def.returns._def.type.parseAsync(o,s).catch((e=>{r.addIssue(makeReturnsIssue(o,e));throw r}));return d}))}else{const e=this;return(0,n.OK)((function(...t){const r=e._def.args.safeParse(t,s);if(!r.success){throw new i.ZodError([makeArgsIssue(t,r.error)])}const n=Reflect.apply(a,this,r.data);const o=e._def.returns.safeParse(n,s);if(!o.success){throw new i.ZodError([makeReturnsIssue(n,o.error)])}return o.data}))}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...e){return new ZodFunction({...this._def,args:ZodTuple.create(e).rest(ZodUnknown.create())})}returns(e){return new ZodFunction({...this._def,returns:e})}implement(e){const t=this.parse(e);return t}strictImplement(e){const t=this.parse(e);return t}static create(e,t,s){return new ZodFunction({args:e?e:ZodTuple.create([]).rest(ZodUnknown.create()),returns:t||ZodUnknown.create(),typeName:y.ZodFunction,...processCreateParams(s)})}}t.ZodFunction=ZodFunction;class ZodLazy extends ZodType{get schema(){return this._def.getter()}_parse(e){const{ctx:t}=this._processInputParams(e);const s=this._def.getter();return s._parse({data:t.data,path:t.path,parent:t})}}t.ZodLazy=ZodLazy;ZodLazy.create=(e,t)=>new ZodLazy({getter:e,typeName:y.ZodLazy,...processCreateParams(t)});class ZodLiteral extends ZodType{_parse(e){if(e.data!==this._def.value){const t=this._getOrReturnCtx(e);(0,n.addIssueToContext)(t,{received:t.data,code:i.ZodIssueCode.invalid_literal,expected:this._def.value});return n.INVALID}return{status:"valid",value:e.data}}get value(){return this._def.value}}t.ZodLiteral=ZodLiteral;ZodLiteral.create=(e,t)=>new ZodLiteral({value:e,typeName:y.ZodLiteral,...processCreateParams(t)});function createZodEnum(e,t){return new ZodEnum({values:e,typeName:y.ZodEnum,...processCreateParams(t)})}class ZodEnum extends ZodType{_parse(e){if(typeof e.data!=="string"){const t=this._getOrReturnCtx(e);const s=this._def.values;(0,n.addIssueToContext)(t,{expected:o.util.joinValues(s),received:t.parsedType,code:i.ZodIssueCode.invalid_type});return n.INVALID}if(this._def.values.indexOf(e.data)===-1){const t=this._getOrReturnCtx(e);const s=this._def.values;(0,n.addIssueToContext)(t,{received:t.data,code:i.ZodIssueCode.invalid_enum_value,options:s});return n.INVALID}return(0,n.OK)(e.data)}get options(){return this._def.values}get enum(){const e={};for(const t of this._def.values){e[t]=t}return e}get Values(){const e={};for(const t of this._def.values){e[t]=t}return e}get Enum(){const e={};for(const t of this._def.values){e[t]=t}return e}extract(e){return ZodEnum.create(e)}exclude(e){return ZodEnum.create(this.options.filter((t=>!e.includes(t))))}}t.ZodEnum=ZodEnum;ZodEnum.create=createZodEnum;class ZodNativeEnum extends ZodType{_parse(e){const t=o.util.getValidEnumValues(this._def.values);const s=this._getOrReturnCtx(e);if(s.parsedType!==o.ZodParsedType.string&&s.parsedType!==o.ZodParsedType.number){const e=o.util.objectValues(t);(0,n.addIssueToContext)(s,{expected:o.util.joinValues(e),received:s.parsedType,code:i.ZodIssueCode.invalid_type});return n.INVALID}if(t.indexOf(e.data)===-1){const e=o.util.objectValues(t);(0,n.addIssueToContext)(s,{received:s.data,code:i.ZodIssueCode.invalid_enum_value,options:e});return n.INVALID}return(0,n.OK)(e.data)}get enum(){return this._def.values}}t.ZodNativeEnum=ZodNativeEnum;ZodNativeEnum.create=(e,t)=>new ZodNativeEnum({values:e,typeName:y.ZodNativeEnum,...processCreateParams(t)});class ZodPromise extends ZodType{unwrap(){return this._def.type}_parse(e){const{ctx:t}=this._processInputParams(e);if(t.parsedType!==o.ZodParsedType.promise&&t.common.async===false){(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.promise,received:t.parsedType});return n.INVALID}const s=t.parsedType===o.ZodParsedType.promise?t.data:Promise.resolve(t.data);return(0,n.OK)(s.then((e=>this._def.type.parseAsync(e,{path:t.path,errorMap:t.common.contextualErrorMap}))))}}t.ZodPromise=ZodPromise;ZodPromise.create=(e,t)=>new ZodPromise({type:e,typeName:y.ZodPromise,...processCreateParams(t)});class ZodEffects extends ZodType{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===y.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(e){const{status:t,ctx:s}=this._processInputParams(e);const r=this._def.effect||null;const a={addIssue:e=>{(0,n.addIssueToContext)(s,e);if(e.fatal){t.abort()}else{t.dirty()}},get path(){return s.path}};a.addIssue=a.addIssue.bind(a);if(r.type==="preprocess"){const e=r.transform(s.data,a);if(s.common.issues.length){return{status:"dirty",value:s.data}}if(s.common.async){return Promise.resolve(e).then((e=>this._def.schema._parseAsync({data:e,path:s.path,parent:s})))}else{return this._def.schema._parseSync({data:e,path:s.path,parent:s})}}if(r.type==="refinement"){const executeRefinement=e=>{const t=r.refinement(e,a);if(s.common.async){return Promise.resolve(t)}if(t instanceof Promise){throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.")}return e};if(s.common.async===false){const e=this._def.schema._parseSync({data:s.data,path:s.path,parent:s});if(e.status==="aborted")return n.INVALID;if(e.status==="dirty")t.dirty();executeRefinement(e.value);return{status:t.value,value:e.value}}else{return this._def.schema._parseAsync({data:s.data,path:s.path,parent:s}).then((e=>{if(e.status==="aborted")return n.INVALID;if(e.status==="dirty")t.dirty();return executeRefinement(e.value).then((()=>({status:t.value,value:e.value})))}))}}if(r.type==="transform"){if(s.common.async===false){const e=this._def.schema._parseSync({data:s.data,path:s.path,parent:s});if(!(0,n.isValid)(e))return e;const o=r.transform(e.value,a);if(o instanceof Promise){throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`)}return{status:t.value,value:o}}else{return this._def.schema._parseAsync({data:s.data,path:s.path,parent:s}).then((e=>{if(!(0,n.isValid)(e))return e;return Promise.resolve(r.transform(e.value,a)).then((e=>({status:t.value,value:e})))}))}}o.util.assertNever(r)}}t.ZodEffects=ZodEffects;t.ZodTransformer=ZodEffects;ZodEffects.create=(e,t,s)=>new ZodEffects({schema:e,typeName:y.ZodEffects,effect:t,...processCreateParams(s)});ZodEffects.createWithPreprocess=(e,t,s)=>new ZodEffects({schema:t,effect:{type:"preprocess",transform:e},typeName:y.ZodEffects,...processCreateParams(s)});class ZodOptional extends ZodType{_parse(e){const t=this._getType(e);if(t===o.ZodParsedType.undefined){return(0,n.OK)(undefined)}return this._def.innerType._parse(e)}unwrap(){return this._def.innerType}}t.ZodOptional=ZodOptional;ZodOptional.create=(e,t)=>new ZodOptional({innerType:e,typeName:y.ZodOptional,...processCreateParams(t)});class ZodNullable extends ZodType{_parse(e){const t=this._getType(e);if(t===o.ZodParsedType.null){return(0,n.OK)(null)}return this._def.innerType._parse(e)}unwrap(){return this._def.innerType}}t.ZodNullable=ZodNullable;ZodNullable.create=(e,t)=>new ZodNullable({innerType:e,typeName:y.ZodNullable,...processCreateParams(t)});class ZodDefault extends ZodType{_parse(e){const{ctx:t}=this._processInputParams(e);let s=t.data;if(t.parsedType===o.ZodParsedType.undefined){s=this._def.defaultValue()}return this._def.innerType._parse({data:s,path:t.path,parent:t})}removeDefault(){return this._def.innerType}}t.ZodDefault=ZodDefault;ZodDefault.create=(e,t)=>new ZodDefault({innerType:e,typeName:y.ZodDefault,defaultValue:typeof t.default==="function"?t.default:()=>t.default,...processCreateParams(t)});class ZodCatch extends ZodType{_parse(e){const{ctx:t}=this._processInputParams(e);const s={...t,common:{...t.common,issues:[]}};const r=this._def.innerType._parse({data:s.data,path:s.path,parent:{...s}});if((0,n.isAsync)(r)){return r.then((e=>({status:"valid",value:e.status==="valid"?e.value:this._def.catchValue({get error(){return new i.ZodError(s.common.issues)},input:s.data})})))}else{return{status:"valid",value:r.status==="valid"?r.value:this._def.catchValue({get error(){return new i.ZodError(s.common.issues)},input:s.data})}}}removeCatch(){return this._def.innerType}}t.ZodCatch=ZodCatch;ZodCatch.create=(e,t)=>new ZodCatch({innerType:e,typeName:y.ZodCatch,catchValue:typeof t.catch==="function"?t.catch:()=>t.catch,...processCreateParams(t)});class ZodNaN extends ZodType{_parse(e){const t=this._getType(e);if(t!==o.ZodParsedType.nan){const t=this._getOrReturnCtx(e);(0,n.addIssueToContext)(t,{code:i.ZodIssueCode.invalid_type,expected:o.ZodParsedType.nan,received:t.parsedType});return n.INVALID}return{status:"valid",value:e.data}}}t.ZodNaN=ZodNaN;ZodNaN.create=e=>new ZodNaN({typeName:y.ZodNaN,...processCreateParams(e)});t.BRAND=Symbol("zod_brand");class ZodBranded extends ZodType{_parse(e){const{ctx:t}=this._processInputParams(e);const s=t.data;return this._def.type._parse({data:s,path:t.path,parent:t})}unwrap(){return this._def.type}}t.ZodBranded=ZodBranded;class ZodPipeline extends ZodType{_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.common.async){const handleAsync=async()=>{const e=await this._def.in._parseAsync({data:s.data,path:s.path,parent:s});if(e.status==="aborted")return n.INVALID;if(e.status==="dirty"){t.dirty();return(0,n.DIRTY)(e.value)}else{return this._def.out._parseAsync({data:e.value,path:s.path,parent:s})}};return handleAsync()}else{const e=this._def.in._parseSync({data:s.data,path:s.path,parent:s});if(e.status==="aborted")return n.INVALID;if(e.status==="dirty"){t.dirty();return{status:"dirty",value:e.value}}else{return this._def.out._parseSync({data:e.value,path:s.path,parent:s})}}}static create(e,t){return new ZodPipeline({in:e,out:t,typeName:y.ZodPipeline})}}t.ZodPipeline=ZodPipeline;class ZodReadonly extends ZodType{_parse(e){const t=this._def.innerType._parse(e);if((0,n.isValid)(t)){t.value=Object.freeze(t.value)}return t}}t.ZodReadonly=ZodReadonly;ZodReadonly.create=(e,t)=>new ZodReadonly({innerType:e,typeName:y.ZodReadonly,...processCreateParams(t)});const custom=(e,t={},s)=>{if(e)return ZodAny.create().superRefine(((r,a)=>{var n,o;if(!e(r)){const e=typeof t==="function"?t(r):typeof t==="string"?{message:t}:t;const i=(o=(n=e.fatal)!==null&&n!==void 0?n:s)!==null&&o!==void 0?o:true;const d=typeof e==="string"?{message:e}:e;a.addIssue({code:"custom",...d,fatal:i})}}));return ZodAny.create()};t.custom=custom;t.late={object:ZodObject.lazycreate};var y;(function(e){e["ZodString"]="ZodString";e["ZodNumber"]="ZodNumber";e["ZodNaN"]="ZodNaN";e["ZodBigInt"]="ZodBigInt";e["ZodBoolean"]="ZodBoolean";e["ZodDate"]="ZodDate";e["ZodSymbol"]="ZodSymbol";e["ZodUndefined"]="ZodUndefined";e["ZodNull"]="ZodNull";e["ZodAny"]="ZodAny";e["ZodUnknown"]="ZodUnknown";e["ZodNever"]="ZodNever";e["ZodVoid"]="ZodVoid";e["ZodArray"]="ZodArray";e["ZodObject"]="ZodObject";e["ZodUnion"]="ZodUnion";e["ZodDiscriminatedUnion"]="ZodDiscriminatedUnion";e["ZodIntersection"]="ZodIntersection";e["ZodTuple"]="ZodTuple";e["ZodRecord"]="ZodRecord";e["ZodMap"]="ZodMap";e["ZodSet"]="ZodSet";e["ZodFunction"]="ZodFunction";e["ZodLazy"]="ZodLazy";e["ZodLiteral"]="ZodLiteral";e["ZodEnum"]="ZodEnum";e["ZodEffects"]="ZodEffects";e["ZodNativeEnum"]="ZodNativeEnum";e["ZodOptional"]="ZodOptional";e["ZodNullable"]="ZodNullable";e["ZodDefault"]="ZodDefault";e["ZodCatch"]="ZodCatch";e["ZodPromise"]="ZodPromise";e["ZodBranded"]="ZodBranded";e["ZodPipeline"]="ZodPipeline";e["ZodReadonly"]="ZodReadonly"})(y=t.ZodFirstPartyTypeKind||(t.ZodFirstPartyTypeKind={}));class Class{constructor(...e){}}const instanceOfType=(e,s={message:`Input not instance of ${e.name}`})=>(0,t.custom)((t=>t instanceof e),s);t["instanceof"]=instanceOfType;const Z=ZodString.create;t.string=Z;const _=ZodNumber.create;t.number=_;const v=ZodNaN.create;t.nan=v;const g=ZodBigInt.create;t.bigint=g;const I=ZodBoolean.create;t.boolean=I;const T=ZodDate.create;t.date=T;const x=ZodSymbol.create;t.symbol=x;const b=ZodUndefined.create;t.undefined=b;const C=ZodNull.create;t["null"]=C;const P=ZodAny.create;t.any=P;const k=ZodUnknown.create;t.unknown=k;const w=ZodNever.create;t.never=w;const N=ZodVoid.create;t["void"]=N;const O=ZodArray.create;t.array=O;const S=ZodObject.create;t.object=S;const E=ZodObject.strictCreate;t.strictObject=E;const A=ZodUnion.create;t.union=A;const j=ZodDiscriminatedUnion.create;t.discriminatedUnion=j;const L=ZodIntersection.create;t.intersection=L;const U=ZodTuple.create;t.tuple=U;const D=ZodRecord.create;t.record=D;const R=ZodMap.create;t.map=R;const V=ZodSet.create;t.set=V;const M=ZodFunction.create;t["function"]=M;const z=ZodLazy.create;t.lazy=z;const $=ZodLiteral.create;t.literal=$;const B=ZodEnum.create;t["enum"]=B;const K=ZodNativeEnum.create;t.nativeEnum=K;const F=ZodPromise.create;t.promise=F;const q=ZodEffects.create;t.effect=q;t.transformer=q;const W=ZodOptional.create;t.optional=W;const J=ZodNullable.create;t.nullable=J;const Y=ZodEffects.createWithPreprocess;t.preprocess=Y;const H=ZodPipeline.create;t.pipeline=H;const ostring=()=>Z().optional();t.ostring=ostring;const onumber=()=>_().optional();t.onumber=onumber;const oboolean=()=>I().optional();t.oboolean=oboolean;t.coerce={string:e=>ZodString.create({...e,coerce:true}),number:e=>ZodNumber.create({...e,coerce:true}),boolean:e=>ZodBoolean.create({...e,coerce:true}),bigint:e=>ZodBigInt.create({...e,coerce:true}),date:e=>ZodDate.create({...e,coerce:true})};t.NEVER=n.INVALID}};var t={};function __nccwpck_require__(s){var r=t[s];if(r!==undefined){return r.exports}var a=t[s]={exports:{}};var n=true;try{e[s].call(a.exports,a,a.exports,__nccwpck_require__);n=false}finally{if(n)delete t[s]}return a.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var s=__nccwpck_require__(773);module.exports=s})(); \ No newline at end of file diff --git a/packages/next/src/compiled/zod/package.json b/packages/next/src/compiled/zod/package.json new file mode 100644 index 000000000000..23793495cb36 --- /dev/null +++ b/packages/next/src/compiled/zod/package.json @@ -0,0 +1 @@ +{"name":"zod","main":"index.js","author":"Colin McDonnell ","license":"MIT"} diff --git a/packages/next/src/server/config-schema.ts b/packages/next/src/server/config-schema.ts index 565bfd4d6535..0437a2fb4550 100644 --- a/packages/next/src/server/config-schema.ts +++ b/packages/next/src/server/config-schema.ts @@ -1,481 +1,345 @@ import { NextConfig } from './config' -import type { JSONSchemaType } from 'ajv' import { VALID_LOADERS } from '../shared/lib/image-config' -const configSchema = { - type: 'object', - additionalProperties: false, - properties: { - amp: { - additionalProperties: false, - properties: { - canonicalBase: { - nullable: true, - type: 'string', - }, - }, - type: 'object', - }, - analyticsId: { - type: 'string', - }, - assetPrefix: { - nullable: true, - type: 'string', - }, - basePath: { - type: 'string', - }, - cleanDistDir: { - type: 'boolean', - }, - compiler: { - additionalProperties: false, - properties: { - emotion: { - oneOf: [ - { - type: 'boolean', - }, - { - type: 'object', - additionalProperties: false, - properties: { - sourceMap: { - type: 'boolean', - }, - autoLabel: { - type: 'string', - enum: ['always', 'dev-only', 'never'], - }, - labelFormat: { - type: 'string', - minLength: 1, - }, - importMap: { - type: 'object', - }, - }, - }, - ] as any, - }, - reactRemoveProperties: { - oneOf: [ - { - type: 'boolean', - }, - { - type: 'object', - additionalProperties: false, - properties: { - properties: { - type: 'array', - items: { - type: 'string', - }, - }, - }, - }, - ] as any, - }, - relay: { - type: 'object', - }, - removeConsole: { - oneOf: [ - { - type: 'boolean', - }, - { - type: 'object', - additionalProperties: false, - properties: { - exclude: { - type: 'array', - items: { - type: 'string', - minLength: 1, - }, - }, - }, - }, - ] as any, - }, - styledComponents: { - oneOf: [ - { - type: 'boolean', - }, - { - type: 'object', - additionalProperties: false, - properties: { - displayName: { - type: 'boolean', - }, - topLevelImportPaths: { - oneOf: [ - { type: 'boolean' }, - { - type: 'array', - items: { - type: 'string', - minLength: 1, - }, - }, - ], - }, - ssr: { - type: 'boolean', - }, - fileName: { - type: 'boolean', - }, - meaninglessFileNames: { - oneOf: [ - { type: 'boolean' }, - { - type: 'array', - items: { - type: 'string', - minLength: 1, - }, - }, - ], - }, - minify: { - type: 'boolean', - }, - transpileTemplateLiterals: { - type: 'boolean', - }, - namespace: { - type: 'string', - minLength: 1, - }, - pure: { - type: 'boolean', - }, - cssProp: { - type: 'boolean', - }, - }, - }, - ] as any, - }, - }, - type: 'object', - }, - compress: { - type: 'boolean', - }, - configOrigin: { - type: 'string', - }, - crossOrigin: { - oneOf: [ - false, - { - enum: ['anonymous', 'use-credentials'], - type: 'string', - }, - ], // automatic typing does not like enum - } as any, - devIndicators: { - additionalProperties: false, - properties: { - buildActivity: { - type: 'boolean', - }, - buildActivityPosition: { - // automatic typing does not like enum - enum: ['bottom-left', 'bottom-right', 'top-left', 'top-right'] as any, - type: 'string', - }, - }, - type: 'object', - }, - distDir: { - minLength: 1, - type: 'string', - nullable: true, - }, - env: { - type: 'object', - }, - eslint: { - additionalProperties: false, - properties: { - dirs: { - items: { - minLength: 1, - type: 'string', - }, - type: 'array', - }, - ignoreDuringBuilds: { - type: 'boolean', - }, - }, - type: 'object', - }, - excludeDefaultMomentLocales: { - type: 'boolean', - }, - experimental: { - additionalProperties: false, - properties: { - appDocumentPreloading: { - type: 'boolean', - }, - adjustFontFallbacks: { - type: 'boolean', - }, - adjustFontFallbacksWithSizeAdjust: { - type: 'boolean', - }, - allowedRevalidateHeaderKeys: { - type: 'array', - }, - amp: { - additionalProperties: false, - properties: { - optimizer: { - type: 'object', - }, - skipValidation: { - type: 'boolean', - }, - validator: { - type: 'string', - }, - }, - type: 'object', - }, - clientRouterFilter: { - type: 'boolean', - }, - clientRouterFilterRedirects: { - type: 'boolean', - }, - clientRouterFilterAllowedRate: { - type: 'number', - }, - cpus: { - type: 'number', - }, - memoryBasedWorkersCount: { - type: 'boolean', - }, - craCompat: { - type: 'boolean', - }, - caseSensitiveRoutes: { - type: 'boolean', - }, - useDeploymentId: { - type: 'boolean', - }, - useDeploymentIdServerActions: { - type: 'boolean', - }, - deploymentId: { - type: 'string', - }, - disableOptimizedLoading: { - type: 'boolean', - }, - disablePostcssPresetEnv: { - type: 'boolean', - }, - esmExternals: { - oneOf: [ - { - type: 'boolean', - }, - { - const: 'loose', - }, - ] as any, - }, - serverActions: { - type: 'boolean', - }, - serverActionsBodySizeLimit: { - oneOf: [ - { - type: 'number', - }, - { - type: 'string', - }, - ] as any, - }, - extensionAlias: { - type: 'object', - }, - externalDir: { - type: 'boolean', - }, - externalMiddlewareRewritesResolve: { - type: 'boolean', - }, - fallbackNodePolyfills: { - type: 'boolean', - }, - fetchCacheKeyPrefix: { - type: 'string', - }, - forceSwcTransforms: { - type: 'boolean', - }, - fullySpecified: { - type: 'boolean', - }, - gzipSize: { - type: 'boolean', - }, - incrementalCacheHandlerPath: { - type: 'string', - }, - isrFlushToDisk: { - type: 'boolean', - }, - isrMemoryCacheSize: { - type: 'number', - }, - largePageDataBytes: { - type: 'number', - }, - manualClientBasePath: { - type: 'boolean', - }, - middlewarePrefetch: { - // automatic typing doesn't like enum - enum: ['strict', 'flexible'] as any, - type: 'string', - }, - nextScriptWorkers: { - type: 'boolean', - }, - optimizeCss: { - oneOf: [ - { - type: 'boolean', - }, - { - type: 'object', - }, - ] as any, - }, - optimisticClientCache: { - type: 'boolean', - }, - outputFileTracingRoot: { - nullable: true, - type: 'string', - }, - outputFileTracingExcludes: { - type: 'object', - }, - outputFileTracingIgnores: { - type: 'array', - }, - outputFileTracingIncludes: { - type: 'object', - }, - ppr: { - type: 'boolean', - }, - proxyTimeout: { - minimum: 0, - type: 'number', - }, - serverComponentsExternalPackages: { - items: { - type: 'string', - }, - type: 'array', - }, - scrollRestoration: { - type: 'boolean', - }, - sri: { - properties: { - algorithm: { - enum: ['sha256', 'sha384', 'sha512'] as any, - type: 'string', - }, - }, - type: 'object', - }, - strictNextHead: { - type: 'boolean', - }, - swcMinify: { - type: 'boolean', - }, - swcPlugins: { - type: 'array', - }, - swcTraceProfiling: { - type: 'boolean', - }, - urlImports: { - items: { - type: 'string', - }, - type: 'array', - }, - workerThreads: { - type: 'boolean', - }, - webVitalsAttribution: { - type: 'array', - items: { - type: 'string', - enum: ['CLS', 'FCP', 'FID', 'INP', 'LCP', 'TTFB'], - } as any, - }, - mdxRs: { - type: 'boolean', - }, - typedRoutes: { - type: 'boolean', - }, - webpackBuildWorker: { - type: 'boolean', - }, - turbo: { - type: 'object', - additionalProperties: false, - properties: { - loaders: { - type: 'object', - }, - rules: { - type: 'object', - }, - resolveAlias: { - type: 'object', - }, - }, - }, - optimizePackageImports: { - type: 'array', - }, - optimizeServerReact: { - type: 'boolean', - }, - instrumentationHook: { - type: 'boolean', - }, - turbotrace: { - type: 'object', - properties: { - logLevel: { - type: 'string', - enum: [ +import { z } from 'next/dist/compiled/zod' +import type zod from 'next/dist/compiled/zod' + +import type { SizeLimit } from '../../types' +import type { ExportPathMap, TurboLoaderItem, TurboRule } from './config-shared' +import type { + Header, + Rewrite, + RouteHas, + Redirect, +} from '../lib/load-custom-routes' + +// A custom zod schema for the SizeLimit type +const zSizeLimit = z.custom((val) => { + if (typeof val === 'number' || typeof val === 'string') { + return true + } + return false +}) + +const zExportMap: zod.ZodType = z.record( + z.string(), + z.object({ + page: z.string(), + query: z.any(), // NextParsedUrlQuery + // private optional properties + _isAppDir: z.boolean().optional(), + _isAppPrefetch: z.boolean().optional(), + _isDynamicError: z.boolean().optional(), + }) +) + +const zRouteHas: zod.ZodType = z.union([ + z.object({ + type: z.enum(['header', 'query', 'cookie']), + key: z.string(), + value: z.string().optional(), + }), + z.object({ + type: z.literal('host'), + key: z.undefined().optional(), + value: z.string(), + }), +]) + +const zRewrite: zod.ZodType = z.object({ + source: z.string(), + destination: z.string(), + basePath: z.literal(false).optional(), + locale: z.literal(false).optional(), + has: z.array(zRouteHas).optional(), + missing: z.array(zRouteHas).optional(), + internal: z.boolean().optional(), +}) + +const zRedirect: zod.ZodType = z + .object({ + source: z.string(), + destination: z.string(), + basePath: z.literal(false).optional(), + locale: z.literal(false).optional(), + has: z.array(zRouteHas).optional(), + missing: z.array(zRouteHas).optional(), + internal: z.boolean().optional(), + }) + .and( + z.union([ + z.object({ + statusCode: z.never().optional(), + permanent: z.boolean(), + }), + z.object({ + statusCode: z.number(), + permanent: z.never().optional(), + }), + ]) + ) + +const zHeader: zod.ZodType
= z.object({ + source: z.string(), + basePath: z.literal(false).optional(), + locale: z.literal(false).optional(), + headers: z.array(z.object({ key: z.string(), value: z.string() })), + has: z.array(zRouteHas).optional(), + missing: z.array(zRouteHas).optional(), + + internal: z.boolean().optional(), +}) + +const zTurboLoaderItem: zod.ZodType = z.union([ + z.string(), + z.object({ + loader: z.string(), + // Any JSON value can be used as turbo loader options, so use z.any() here + options: z.record(z.string(), z.any()), + }), +]) + +const zTurboRule: zod.ZodType = z.union([ + z.array(zTurboLoaderItem), + z.object({ + loaders: z.array(zTurboLoaderItem), + as: z.string(), + }), +]) + +export const configSchema: zod.ZodType = z.lazy(() => + z.strictObject({ + amp: z + .object({ + canonicalBase: z.string().optional(), + }) + .optional(), + analyticsId: z.string().optional(), + assetPrefix: z.string().optional(), + basePath: z.string().optional(), + cleanDistDir: z.boolean().optional(), + compiler: z + .strictObject({ + emotion: z + .union([ + z.boolean(), + z.object({ + sourceMap: z.boolean().optional(), + autoLabel: z + .union([ + z.literal('always'), + z.literal('dev-only'), + z.literal('never'), + ]) + .optional(), + labelFormat: z.string().min(1).optional(), + importMap: z + .record( + z.string(), + z.record( + z.string(), + z.object({ + canonicalImport: z + .tuple([z.string(), z.string()]) + .optional(), + styledBaseImport: z + .tuple([z.string(), z.string()]) + .optional(), + }) + ) + ) + .optional(), + }), + ]) + .optional(), + reactRemoveProperties: z + .union([ + z.boolean().optional(), + z.object({ + properties: z.array(z.string()).optional(), + }), + ]) + .optional(), + relay: z + .object({ + src: z.string(), + artifactDirectory: z.string().optional(), + language: z.enum(['javascript', 'typescript', 'flow']).optional(), + eagerEsModules: z.boolean().optional(), + }) + .optional(), + removeConsole: z + .union([ + z.boolean().optional(), + z.object({ + exclude: z.array(z.string()).min(1).optional(), + }), + ]) + .optional(), + styledComponents: z.union([ + z.boolean().optional(), + z.object({ + displayName: z.boolean().optional(), + topLevelImportPaths: z.array(z.string()).min(1).optional(), + ssr: z.boolean().optional(), + fileName: z.boolean().optional(), + meaninglessFileNames: z.array(z.string()).min(1).optional(), + minify: z.boolean().optional(), + transpileTemplateLiterals: z.boolean().optional(), + namespace: z.string().min(1).optional(), + pure: z.boolean().optional(), + cssProp: z.boolean().optional(), + }), + ]), + }) + .optional(), + compress: z.boolean().optional(), + configOrigin: z.string().optional(), + crossOrigin: z + .union([ + z.literal(false), + z.literal('anonymous'), + z.literal('use-credentials'), + ]) + .optional(), + devIndicators: z + .object({ + buildActivity: z.boolean().optional(), + buildActivityPosition: z + .union([ + z.literal('bottom-left'), + z.literal('bottom-right'), + z.literal('top-left'), + z.literal('top-right'), + ]) + .optional(), + }) + .optional(), + distDir: z.string().min(1).optional(), + env: z.record(z.string(), z.string()).optional(), + eslint: z + .strictObject({ + dirs: z.array(z.string().min(1)).optional(), + ignoreDuringBuilds: z.boolean().optional(), + }) + .optional(), + excludeDefaultMomentLocales: z.boolean().optional(), + experimental: z + .strictObject({ + appDocumentPreloading: z.boolean().optional(), + adjustFontFallbacks: z.boolean().optional(), + adjustFontFallbacksWithSizeAdjust: z.boolean().optional(), + allowedRevalidateHeaderKeys: z.array(z.string()).optional(), + amp: z + .object({ + // AMP optimizer option is unknown, use z.any() here + optimizer: z.any().optional(), + skipValidation: z.boolean().optional(), + validator: z.string().optional(), + }) + .optional(), + clientRouterFilter: z.boolean().optional(), + clientRouterFilterRedirects: z.boolean().optional(), + clientRouterFilterAllowedRate: z.number().optional(), + cpus: z.number().optional(), + memoryBasedWorkersCount: z.boolean().optional(), + craCompat: z.boolean().optional(), + caseSensitiveRoutes: z.boolean().optional(), + useDeploymentId: z.boolean().optional(), + useDeploymentIdServerActions: z.boolean().optional(), + deploymentId: z.string().optional(), + disableOptimizedLoading: z.boolean().optional(), + disablePostcssPresetEnv: z.boolean().optional(), + esmExternals: z.union([z.boolean(), z.literal('loose')]).optional(), + serverActions: z.boolean().optional(), + serverActionsBodySizeLimit: zSizeLimit.optional(), + // The original type was Record + extensionAlias: z.record(z.string(), z.any()).optional(), + externalDir: z.boolean().optional(), + externalMiddlewareRewritesResolve: z.boolean().optional(), + fallbackNodePolyfills: z.literal(false).optional(), + fetchCacheKeyPrefix: z.string().optional(), + forceSwcTransforms: z.boolean().optional(), + fullySpecified: z.boolean().optional(), + gzipSize: z.boolean().optional(), + incrementalCacheHandlerPath: z.string().optional(), + isrFlushToDisk: z.boolean().optional(), + isrMemoryCacheSize: z.number().optional(), + largePageDataBytes: z.number().optional(), + manualClientBasePath: z.boolean().optional(), + middlewarePrefetch: z.enum(['strict', 'flexible']).optional(), + nextScriptWorkers: z.boolean().optional(), + // The critter option is unknown, use z.any() here + optimizeCss: z.union([z.boolean(), z.any()]).optional(), + optimisticClientCache: z.boolean().optional(), + outputFileTracingRoot: z.string().optional(), + outputFileTracingExcludes: z + .record(z.string(), z.array(z.string())) + .optional(), + outputFileTracingIgnores: z.array(z.string()).optional(), + outputFileTracingIncludes: z + .record(z.string(), z.array(z.string())) + .optional(), + ppr: z.boolean().optional(), + proxyTimeout: z.number().gte(0).optional(), + serverComponentsExternalPackages: z.array(z.string()).optional(), + scrollRestoration: z.boolean().optional(), + sri: z + .object({ + algorithm: z.enum(['sha256', 'sha384', 'sha512']).optional(), + }) + .optional(), + strictNextHead: z.boolean().optional(), + swcMinify: z.boolean().optional(), + swcPlugins: z + // The specific swc plugin's option is unknown, use z.any() here + .array(z.tuple([z.string(), z.record(z.string(), z.any())])) + .optional(), + swcTraceProfiling: z.boolean().optional(), + // NonNullable['buildHttp'] + urlImports: z.any().optional(), + workerThreads: z.boolean().optional(), + webVitalsAttribution: z + .array( + z.union([ + z.literal('CLS'), + z.literal('FCP'), + z.literal('FID'), + z.literal('INP'), + z.literal('LCP'), + z.literal('TTFB'), + ]) + ) + .optional(), + mdxRs: z.boolean().optional(), + typedRoutes: z.boolean().optional(), + webpackBuildWorker: z.boolean().optional(), + turbo: z + .object({ + loaders: z.record(z.string(), z.array(zTurboLoaderItem)).optional(), + rules: z.record(z.string(), zTurboRule).optional(), + resolveAlias: z + .record( + z.string(), + z.union([ + z.string(), + z.array(z.string()), + z.record( + z.string(), + z.union([z.string(), z.array(z.string())]) + ), + ]) + ) + .optional(), + }) + .optional(), + optimizePackageImports: z.array(z.string()).optional(), + optimizeServerReact: z.boolean().optional(), + instrumentationHook: z.boolean().optional(), + turbotrace: z + .object({ + logLevel: z + .enum([ 'bug', 'fatal', 'error', @@ -484,341 +348,180 @@ const configSchema = { 'note', 'suggestions', 'info', - ], - } as any, - logAll: { - type: 'boolean', - }, - logDetail: { - type: 'boolean', - }, - contextDirectory: { - type: 'string', - }, - processCwd: { - type: 'string', - }, - memoryLimit: { - type: 'integer', - }, - }, - }, - logging: { - type: 'object', - properties: { - level: { - type: 'string', - }, - fullUrl: { - type: 'boolean', - }, - }, - }, - serverMinification: { - type: 'boolean', - }, - serverSourceMaps: { - type: 'boolean', - }, - bundlePagesExternals: { - type: 'boolean', - }, - }, - type: 'object', - }, - exportPathMap: { - isFunction: true, - errorMessage: 'must be a function that returns a Promise', - } as any, - generateBuildId: { - isFunction: true, - errorMessage: 'must be a function that returns a Promise', - } as any, - generateEtags: { - type: 'boolean', - }, - headers: { - isFunction: true, - errorMessage: 'must be a function that returns a Promise', - } as any, - httpAgentOptions: { - additionalProperties: false, - properties: { - keepAlive: { - type: 'boolean', - }, - }, - type: 'object', - }, - i18n: { - additionalProperties: false, - nullable: true, - properties: { - defaultLocale: { - minLength: 1, - type: 'string', - }, - domains: { - items: { - additionalProperties: false, - properties: { - defaultLocale: { - minLength: 1, - type: 'string', - }, - domain: { - minLength: 1, - type: 'string', - }, - http: { - type: 'boolean', - }, - locales: { - items: { - minLength: 1, - type: 'string', - }, - type: 'array', - }, - }, - type: 'object', - }, - type: 'array', - }, - localeDetection: { - type: 'boolean', - }, - locales: { - items: { - minLength: 1, - type: 'string', - }, - type: 'array', - }, - }, - type: 'object', - }, - images: { - additionalProperties: false, - nullable: true, - properties: { - remotePatterns: { - nullable: true, - items: { - additionalProperties: false, - properties: { - hostname: { - type: 'string', - }, - pathname: { - type: 'string', - }, - port: { - maxLength: 5, - type: 'string', - }, - protocol: { - // automatic typing doesn't like enum - enum: ['http', 'https'] as any, - type: 'string', - }, - }, - required: ['hostname'] as any, - type: 'object', - }, - maxItems: 50, - type: 'array', - }, - unoptimized: { - type: 'boolean', - }, - contentSecurityPolicy: { - type: 'string', - nullable: true, - }, - contentDispositionType: { - enum: ['inline', 'attachment'] as any, // automatic typing does not like enum - type: 'string', - nullable: true, - }, - dangerouslyAllowSVG: { - type: 'boolean', - nullable: true, - }, - deviceSizes: { - items: { - type: 'integer', - minimum: 1, - maximum: 10000, - }, - maxItems: 25, - type: 'array', - nullable: true, - }, - disableStaticImages: { - type: 'boolean', - nullable: true, - }, - domains: { - items: { - type: 'string', - }, - maxItems: 50, - type: 'array', - nullable: true, - }, - formats: { - items: { - enum: ['image/avif', 'image/webp'], // automatic typing does not like enum - type: 'string', - } as any, - maxItems: 4, - type: 'array', - nullable: true, - }, - imageSizes: { - items: { - type: 'integer', - minimum: 1, - maximum: 10000, - }, - minItems: 0, - maxItems: 25, - type: 'array', - nullable: true, - }, - loader: { - // automatic typing does not like enum - enum: VALID_LOADERS as any, - type: 'string', - nullable: true, - }, - loaderFile: { - type: 'string', - nullable: true, - }, - minimumCacheTTL: { - type: 'integer', - minimum: 0, - nullable: true, - }, - path: { - type: 'string', - nullable: true, - }, - }, - type: 'object', - }, - modularizeImports: { - type: 'object', - }, - onDemandEntries: { - additionalProperties: false, - properties: { - maxInactiveAge: { - type: 'number', - }, - pagesBufferLength: { - type: 'number', - }, - }, - type: 'object', - }, - optimizeFonts: { - type: 'boolean', - }, - output: { - // automatic typing doesn't like enum - enum: ['standalone', 'export'] as any, - type: 'string', - }, - outputFileTracing: { - type: 'boolean', - }, - pageExtensions: { - minItems: 1, - type: 'array', - }, - poweredByHeader: { - type: 'boolean', - }, - productionBrowserSourceMaps: { - type: 'boolean', - }, - publicRuntimeConfig: { - type: 'object', - }, - reactProductionProfiling: { - type: 'boolean', - }, - reactStrictMode: { - type: 'boolean', - nullable: true, - }, - redirects: { - isFunction: true, - errorMessage: 'must be a function that returns a Promise', - } as any, - rewrites: { - isFunction: true, - errorMessage: 'must be a function that returns a Promise', - } as any, - sassOptions: { - type: 'object', - }, - serverRuntimeConfig: { - type: 'object', - }, - skipMiddlewareUrlNormalize: { - type: 'boolean', - }, - skipTrailingSlashRedirect: { - type: 'boolean', - }, - staticPageGenerationTimeout: { - type: 'number', - }, - swcMinify: { - type: 'boolean', - }, - target: { - type: 'string', - }, - trailingSlash: { - type: 'boolean', - }, - transpilePackages: { - items: { - type: 'string', - }, - type: 'array', - }, - typescript: { - additionalProperties: false, - properties: { - ignoreBuildErrors: { - type: 'boolean', - }, - tsconfigPath: { - minLength: 1, - type: 'string', - }, - }, - type: 'object', - }, - useFileSystemPublicRoutes: { - type: 'boolean', - }, - webpack: { - isFunction: true, - errorMessage: - 'must be a function that returns a webpack configuration object', - } as any, - }, -} as JSONSchemaType - -// module.exports is used to get around an export bug with TypeScript -// and the Ajv automatic typing -module.exports = { - configSchema, -} + ]) + .optional(), + logAll: z.boolean().optional(), + logDetail: z.boolean().optional(), + contextDirectory: z.string().optional(), + processCwd: z.string().optional(), + memoryLimit: z.number().int().optional(), + }) + .optional(), + logging: z + .object({ + level: z.literal('verbose').optional(), + fullUrl: z.boolean().optional(), + }) + .optional(), + serverMinification: z.boolean().optional(), + serverSourceMaps: z.boolean().optional(), + bundlePagesExternals: z.boolean().optional(), + }) + .optional(), + exportPathMap: z + .function() + .args( + zExportMap, + z.object({ + dev: z.boolean(), + dir: z.string(), + outDir: z.string().nullable(), + distDir: z.string(), + buildId: z.string(), + }) + ) + .returns(z.union([zExportMap, z.promise(zExportMap)])) + .optional(), + generateBuildId: z + .function() + .args() + .returns( + z.union([ + z.string(), + z.null(), + z.promise(z.union([z.string(), z.null()])), + ]) + ) + .optional(), + generateEtags: z.boolean().optional(), + headers: z + .function() + .args() + .returns(z.promise(z.array(zHeader))) + .optional(), + httpAgentOptions: z + .strictObject({ keepAlive: z.boolean().optional() }) + .optional(), + i18n: z + .strictObject({ + defaultLocale: z.string().min(1), + domains: z + .array( + z.strictObject({ + defaultLocale: z.string().min(1), + domain: z.string().min(1), + http: z.literal(true).optional(), + locales: z.array(z.string().min(1)).optional(), + }) + ) + .optional(), + localeDetection: z.literal(false).optional(), + locales: z.array(z.string().min(1)), + }) + .nullable() + .optional(), + images: z + .strictObject({ + remotePatterns: z + .array( + z.strictObject({ + hostname: z.string(), + pathname: z.string().optional(), + port: z.string().max(5).optional(), + protocol: z.enum(['http', 'https']).optional(), + }) + ) + .max(50) + .optional(), + unoptimized: z.boolean().optional(), + contentSecurityPolicy: z.string().optional(), + contentDispositionType: z.enum(['inline', 'attachment']).optional(), + dangerouslyAllowSVG: z.boolean().optional(), + deviceSizes: z + .array(z.number().int().gte(1).lte(10000)) + .max(25) + .optional(), + disableStaticImages: z.boolean().optional(), + domains: z.array(z.string()).max(50).optional(), + formats: z + .array(z.enum(['image/avif', 'image/webp'])) + .max(4) + .optional(), + imageSizes: z + .array(z.number().int().gte(1).lte(10000)) + .min(0) + .max(25) + .optional(), + loader: z.enum(VALID_LOADERS).optional(), + loaderFile: z.string().optional(), + minimumCacheTTL: z.number().int().gte(0).optional(), + path: z.string().optional(), + }) + .optional(), + modularizeImports: z + .record( + z.string(), + z.object({ + transform: z.union([z.string(), z.record(z.string(), z.string())]), + preventFullImport: z.boolean().optional(), + skipDefaultConversion: z.boolean().optional(), + }) + ) + .optional(), + onDemandEntries: z + .strictObject({ + maxInactiveAge: z.number().optional(), + pagesBufferLength: z.number().optional(), + }) + .optional(), + optimizeFonts: z.boolean().optional(), + output: z.enum(['standalone', 'export']).optional(), + outputFileTracing: z.boolean().optional(), + pageExtensions: z.array(z.string()).min(1).optional(), + poweredByHeader: z.boolean().optional(), + productionBrowserSourceMaps: z.boolean().optional(), + publicRuntimeConfig: z.record(z.string(), z.any()).optional(), + reactProductionProfiling: z.boolean().optional(), + reactStrictMode: z.boolean().nullable().optional(), + redirects: z + .function() + .args() + .returns(z.promise(z.array(zRedirect))) + .optional(), + rewrites: z + .function() + .args() + .returns( + z.promise( + z.union([ + z.array(zRewrite), + z.object({ + beforeFiles: z.array(zRewrite), + afterFiles: z.array(zRewrite), + fallback: z.array(zRewrite), + }), + ]) + ) + ) + .optional(), + // saas option is unknown, use z.any() here + sassOptions: z.record(z.string(), z.any()).optional(), + serverRuntimeConfig: z.record(z.string(), z.any()).optional(), + skipMiddlewareUrlNormalize: z.boolean().optional(), + skipTrailingSlashRedirect: z.boolean().optional(), + staticPageGenerationTimeout: z.number().optional(), + swcMinify: z.boolean().optional(), + target: z.string().optional(), + trailingSlash: z.boolean().optional(), + transpilePackages: z.array(z.string()).optional(), + typescript: z + .strictObject({ + ignoreBuildErrors: z.boolean().optional(), + tsconfigPath: z.string().min(1).optional(), + }) + .optional(), + useFileSystemPublicRoutes: z.boolean().optional(), + // The webpack config type is unknown, use z.any() here + webpack: z.any().nullable().optional(), + }) +) diff --git a/packages/next/src/server/config-shared.ts b/packages/next/src/server/config-shared.ts index d8108f4158be..c03928b177cf 100644 --- a/packages/next/src/server/config-shared.ts +++ b/packages/next/src/server/config-shared.ts @@ -780,19 +780,3 @@ export async function normalizeConfig(phase: string, config: any) { // Support `new Promise` and `async () =>` as return values of the config export return await config } - -export function validateConfig(userConfig: NextConfig): { - errors?: Array | null -} { - if (process.env.NEXT_MINIMAL) { - return { - errors: [], - } - } else { - const configValidator = require('next/dist/next-config-validate.js') - configValidator(userConfig) - return { - errors: configValidator.errors, - } - } -} diff --git a/packages/next/src/server/config.ts b/packages/next/src/server/config.ts index 3937011f9c92..6d224c57a2d6 100644 --- a/packages/next/src/server/config.ts +++ b/packages/next/src/server/config.ts @@ -9,7 +9,6 @@ import { normalizeConfig, ExperimentalConfig, NextConfigComplete, - validateConfig, NextConfig, TurboLoaderItem, } from './config-shared' @@ -21,8 +20,88 @@ import { findRootDir } from '../lib/find-root' import { setHttpClientAndAgentOptions } from './setup-http-agent-env' import { pathHasPrefix } from '../shared/lib/router/utils/path-has-prefix' +import { ZodParsedType, util as ZodUtil } from 'next/dist/compiled/zod' +import type { ZodError, ZodIssue } from 'next/dist/compiled/zod' + export { DomainLocale, NextConfig, normalizeConfig } from './config-shared' +function processZodErrorMessage(issue: ZodIssue) { + let message = issue.message + + let path = '' + + if (issue.path.length > 0) { + if (issue.path.length === 1) { + const identifier = issue.path[0] + if (typeof identifier === 'number') { + // The first identifier inside path is a number + path = `index ${identifier}` + } else { + path = `"${identifier}"` + } + } else { + // joined path to be shown in the error message + path = `"${issue.path.reduce((acc, cur) => { + if (typeof cur === 'number') { + // array index + return `${acc}[${cur}]` + } + if (cur.includes('"')) { + // escape quotes + return `${acc}["${cur.replaceAll('"', '\\"')}"]` + } + // dot notation + const separator = acc.length === 0 ? '' : '.' + return acc + separator + cur + }, '')}"` + } + } + + if ( + issue.code === 'invalid_type' && + issue.received === ZodParsedType.undefined + ) { + // missing key in object + return `${path} is missing, expected ${issue.expected}` + } + if (issue.code === 'invalid_enum_value') { + // Remove "Invalid enum value" prefix from zod default error message + return `Expected ${ZodUtil.joinValues(issue.options)}, received '${ + issue.received + }' at ${path}` + } + + return message + (path ? ` at ${path}` : '') +} + +function normalizeZodErrors( + error: ZodError +): [errorMessages: string[], shouldExit: boolean] { + let shouldExit = false + return [ + error.issues.flatMap((issue) => { + const messages = [processZodErrorMessage(issue)] + if (issue.path[0] === 'images') { + // We exit the build when encountering an error in the images config + shouldExit = true + } + + if ('unionErrors' in issue) { + issue.unionErrors + .map(normalizeZodErrors) + .forEach(([unionMessages, unionShouldExit]) => { + messages.push(...unionMessages) + // If any of the union results shows exit the build, we exit the build + shouldExit = shouldExit || unionShouldExit + }) + } + + return messages + }), + shouldExit, + ] +} + export function warnOptionHasBeenDeprecated( config: NextConfig, nestedPropertyKey: string, @@ -875,38 +954,36 @@ export default async function loadConfig( userConfigModule.default || userConfigModule ) - const validateResult = validateConfig(userConfig) - - if (validateResult.errors) { - // Only load @segment/ajv-human-errors when invalid config is detected - const { AggregateAjvError } = - require('next/dist/compiled/@segment/ajv-human-errors') as typeof import('next/dist/compiled/@segment/ajv-human-errors') - const aggregatedAjvErrors = new AggregateAjvError(validateResult.errors, { - fieldLabels: 'js', - }) + if (!process.env.NEXT_MINIMAL) { + // We only validate the config against schema in non minimal mode + const { configSchema } = + require('./config-schema') as typeof import('./config-schema') + const state = configSchema.safeParse(userConfig) - let shouldExit = false - const messages = [`Invalid ${configFileName} options detected: `] + if (!state.success) { + // error message header + const messages = [`Invalid ${configFileName} options detected: `] - for (const error of aggregatedAjvErrors) { - messages.push(` ${error.message}`) - if (error.message.startsWith('The value at .images.')) { - shouldExit = true + const [errorMessages, shouldExit] = normalizeZodErrors(state.error) + // ident list item + for (const error of errorMessages) { + messages.push(` ${error}`) } - } - messages.push( - 'See more info here: https://nextjs.org/docs/messages/invalid-next-config' - ) + // error message footer + messages.push( + 'See more info here: https://nextjs.org/docs/messages/invalid-next-config' + ) - if (shouldExit) { - for (const message of messages) { - console.error(message) - } - await flushAndExit(1) - } else { - for (const message of messages) { - curLog.warn(message) + if (shouldExit) { + for (const message of messages) { + console.error(message) + } + await flushAndExit(1) + } else { + for (const message of messages) { + curLog.warn(message) + } } } } diff --git a/packages/next/taskfile.js b/packages/next/taskfile.js index dd6858d28958..63e40bf4e59a 100644 --- a/packages/next/taskfile.js +++ b/packages/next/taskfile.js @@ -338,55 +338,6 @@ export async function ncc_undici(task, opts) { ) } -// eslint-disable-next-line camelcase -export async function compile_config_schema(task, opts) { - const { configSchema } = require('./dist/server/config-schema') - // eslint-disable-next-line - const Ajv = require('ajv') - // eslint-disable-next-line - const standaloneCode = require('ajv/dist/standalone').default - // eslint-disable-next-line - const ajv = new Ajv({ - code: { source: true }, - allErrors: true, - verbose: true, - }) - - // errorMessage keyword will be consumed by @segment/ajv-human-errors to provide a custom error message - ajv.addKeyword('errorMessage') - - ajv.addKeyword({ - keyword: 'isFunction', - schemaType: 'boolean', - compile() { - return (data) => data == null || data instanceof Function - }, - code(ctx) { - const { data } = ctx - ctx.fail(Ajv._`!(${data} == null || ${data} instanceof Function)`) - }, - metaSchema: { - anyOf: [{ type: 'boolean' }], - }, - }) - - const compiled = ajv.compile(configSchema) - const validateCode = standaloneCode(ajv, compiled) - const preNccFilename = join(__dirname, 'dist', 'next-config-validate.js') - await fs.writeFile(preNccFilename, validateCode) - await task - .source('./dist/next-config-validate.js') - .ncc({}) - .target('dist/next-config-validate') - - await fs.unlink(preNccFilename) - await fs.rename( - join(__dirname, 'dist/next-config-validate/next-config-validate.js'), - join(__dirname, 'dist/next-config-validate.js') - ) - await fs.rmdir(join(__dirname, 'dist/next-config-validate')) -} - // eslint-disable-next-line camelcase externals['acorn'] = 'next/dist/compiled/acorn' export async function ncc_acorn(task, opts) { @@ -1150,16 +1101,6 @@ export async function ncc_async_sema(task, opts) { .ncc({ packageName: 'async-sema', externals }) .target('src/compiled/async-sema') } -// eslint-disable-next-line camelcase -export async function ncc_segment_ajv_human_errors(task, opts) { - await task - .source(relative(__dirname, require.resolve('@segment/ajv-human-errors/'))) - .ncc({ - packageName: '@segment/ajv-human-errors/', - externals, - }) - .target('src/compiled/@segment/ajv-human-errors') -} externals['postcss-plugin-stub-for-cssnano-simple'] = 'next/dist/compiled/postcss-plugin-stub-for-cssnano-simple' @@ -2035,7 +1976,7 @@ export async function ncc_unistore(task, opts) { } // eslint-disable-next-line camelcase -externals['unistore'] = 'next/dist/compiled/superstruct' +externals['superstruct'] = 'next/dist/compiled/superstruct' export async function ncc_superstruct(task, opts) { await task .source(relative(__dirname, require.resolve('superstruct'))) @@ -2043,6 +1984,14 @@ export async function ncc_superstruct(task, opts) { .target('src/compiled/superstruct') } +externals['zod'] = 'next/dist/compiled/zod' +export async function ncc_zod(task, opts) { + await task + .source(relative(__dirname, require.resolve('zod'))) + .ncc({ packageName: 'zod', externals }) + .target('src/compiled/zod') +} + // eslint-disable-next-line camelcase externals['web-vitals'] = 'next/dist/compiled/web-vitals' export async function ncc_web_vitals(task, opts) { @@ -2292,7 +2241,6 @@ export async function ncc(task, opts) { 'ncc_arg', 'ncc_async_retry', 'ncc_async_sema', - 'ncc_segment_ajv_human_errors', 'ncc_postcss_plugin_stub_for_cssnano_simple', 'ncc_assert', 'ncc_browser_zlib', @@ -2366,6 +2314,7 @@ export async function ncc(task, opts) { 'ncc_string_hash', 'ncc_strip_ansi', 'ncc_superstruct', + 'ncc_zod', 'ncc_nft', 'ncc_tar', 'ncc_terser', @@ -2664,10 +2613,7 @@ export async function trace(task, opts) { } export async function build(task, opts) { - await task.serial( - ['precompile', 'compile', 'compile_config_schema', 'generate_types'], - opts - ) + await task.serial(['precompile', 'compile', 'generate_types'], opts) } export async function generate_types(task, opts) { diff --git a/packages/next/types/misc.d.ts b/packages/next/types/misc.d.ts index 00633f5acfc7..e2bf73cc271b 100644 --- a/packages/next/types/misc.d.ts +++ b/packages/next/types/misc.d.ts @@ -388,11 +388,6 @@ declare module 'next/dist/compiled/@edge-runtime/primitives' { export = m } -declare module 'next/dist/compiled/@segment/ajv-human-errors' { - import * as m from '@segment/ajv-human-errors' - export = m -} - declare module 'next/dist/compiled/react' { import * as m from 'react' export = m @@ -480,3 +475,8 @@ declare module 'next/dist/compiled/@opentelemetry/api' { import * as m from '@opentelemetry/api' export = m } + +declare module 'next/dist/compiled/zod' { + import * as m from 'zod' + export = m +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 22bfb1ffa1aa..5237d8843b00 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -937,9 +937,6 @@ importers: '@playwright/test': specifier: ^1.35.1 version: 1.35.1 - '@segment/ajv-human-errors': - specifier: 2.1.2 - version: 2.1.2(ajv@8.11.0) '@taskr/clear': specifier: 1.1.0 version: 1.1.0 @@ -1066,9 +1063,6 @@ importers: acorn: specifier: 8.5.0 version: 8.5.0 - ajv: - specifier: 8.11.0 - version: 8.11.0 amphtml-validator: specifier: 1.0.35 version: 1.0.35 @@ -1323,7 +1317,7 @@ importers: version: 0.13.4 sass-loader: specifier: 12.4.0 - version: 12.4.0(sass@1.54.0)(webpack@5.86.0) + version: 12.4.0(webpack@5.86.0) schema-utils2: specifier: npm:schema-utils@2.7.1 version: /schema-utils@2.7.1 @@ -1426,6 +1420,9 @@ importers: ws: specifier: 8.2.3 version: 8.2.3 + zod: + specifier: 3.22.3 + version: 3.22.3 packages/next-bundle-analyzer: dependencies: @@ -6716,8 +6713,8 @@ packages: resolution: {integrity: sha512-XQr74QaLeMiqhStEhLn1im9EOMnkypp7MZOwQhGzqp2Weu5eQJbpPxWxixxlYRKWPOmJjsk6qYfYH9kq43yc2w==} dev: true - /@next/react-refresh-utils@13.5.3(react-refresh@0.12.0)(webpack@5.86.0): - resolution: {integrity: sha512-Y4wsqtdX+/QZ6W19N3y/YnuxAt/a79l/zYmRc2mwEplP0rIv6W3MBo3ePFUXOMVfmVesnOhfnZanaGiynZcFOg==} + /@next/react-refresh-utils@13.5.4(react-refresh@0.12.0)(webpack@5.86.0): + resolution: {integrity: sha512-Y2bFd17Gn5Wh1gT/P/xTlApmipdrD0JdTdMwhi8G2wD2qj8p7SZbci1kp7zp+utWVp8PFQD6kHAIBrJS9/iEQQ==} peerDependencies: react-refresh: 0.12.0 webpack: 5.86.0 @@ -7410,14 +7407,6 @@ packages: rxjs: 6.6.2 dev: true - /@segment/ajv-human-errors@2.1.2(ajv@8.11.0): - resolution: {integrity: sha512-d1uQndRFLRO01+xW1y5m+joxDgHf5SLJ70YCY2ArLoo2FJ50o6AoX2mEbuGvnKz/IdwnvDugm9Ti3mZQkW1OoA==} - peerDependencies: - ajv: ^8.0.0 - dependencies: - ajv: 8.11.0 - dev: true - /@shuding/opentype.js@1.4.0-beta.0: resolution: {integrity: sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==} engines: {node: '>= 8.0.0'} @@ -23494,7 +23483,7 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - /sass-loader@12.4.0(sass@1.54.0)(webpack@5.86.0): + /sass-loader@12.4.0(webpack@5.86.0): resolution: {integrity: sha512-7xN+8khDIzym1oL9XyS6zP6Ges+Bo2B2xbPrjdMHEYyV3AQYhd/wXeru++3ODHF0zMjYmVadblSKrPrjEkL8mg==} engines: {node: '>= 12.13.0'} peerDependencies: @@ -23512,7 +23501,6 @@ packages: dependencies: klona: 2.0.4 neo-async: 2.6.2 - sass: 1.54.0 webpack: 5.86.0(@swc/core@1.3.85) dev: true @@ -26763,6 +26751,10 @@ packages: resolution: {integrity: sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==} dev: true + /zod@3.22.3: + resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} + dev: true + /zwitch@1.0.5: resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==} dev: true @@ -26776,7 +26768,7 @@ packages: name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: - '@next/react-refresh-utils': 13.5.3(react-refresh@0.12.0)(webpack@5.86.0) + '@next/react-refresh-utils': 13.5.4(react-refresh@0.12.0)(webpack@5.86.0) '@types/node': 20.2.5 transitivePeerDependencies: - react-refresh diff --git a/test/integration/config-validation/test/index.test.ts b/test/integration/config-validation/test/index.test.ts index 6f44afe56168..74c5b8f738c1 100644 --- a/test/integration/config-validation/test/index.test.ts +++ b/test/integration/config-validation/test/index.test.ts @@ -19,9 +19,9 @@ describe('next.config.js validation', () => { } `, outputs: [ - 'The value at .images.loader must be one of', - 'The value at .rewrites must be a function that returns a Promise', - 'The value at .swcMinify must be a boolean but it was a string', + `received 'something' at "images.loader"`, + 'Expected function, received boolean at "rewrites"', + 'Expected boolean, received string at "swcMinify"', ], }, { @@ -35,8 +35,8 @@ describe('next.config.js validation', () => { } `, outputs: [ - 'The root value has an unexpected property, nonExistent,', - 'The value at .experimental has an unexpected property, anotherNonExistent', + `Unrecognized key(s) in object: 'nonExistent'`, + `Unrecognized key(s) in object: 'anotherNonExistent' at "experimental"`, ], }, ])( diff --git a/test/integration/dist-dir/test/index.test.js b/test/integration/dist-dir/test/index.test.js index d296bc652e73..9901851d56ff 100644 --- a/test/integration/dist-dir/test/index.test.js +++ b/test/integration/dist-dir/test/index.test.js @@ -83,11 +83,11 @@ describe('distDir', () => { ) }) - it('should handle null/undefined distDir', async () => { + it('should handle undefined distDir', async () => { const origNextConfig = await fs.readFile(nextConfig, 'utf8') await fs.writeFile( nextConfig, - `module.exports = { distDir: null, eslint: { ignoreDuringBuilds: true } }` + `module.exports = { distDir: undefined, eslint: { ignoreDuringBuilds: true } }` ) const { stderr } = await nextBuild(appDir, [], { stderr: true }) await fs.writeFile(nextConfig, origNextConfig) diff --git a/test/integration/image-optimizer/test/index.test.ts b/test/integration/image-optimizer/test/index.test.ts index b0209037a313..519247edcf75 100644 --- a/test/integration/image-optimizer/test/index.test.ts +++ b/test/integration/image-optimizer/test/index.test.ts @@ -43,7 +43,7 @@ describe('Image Optimizer', () => { await nextConfig.restore() expect(stderr).toContain( - 'The value at .images.domains must have 50 or fewer items but it has 51.' + 'Array must contain at most 50 element(s) at "images.domains"' ) }) @@ -70,7 +70,7 @@ describe('Image Optimizer', () => { await nextConfig.restore() expect(stderr).toContain( - 'The value at .images.remotePatterns must have 50 or fewer items but it has 51.' + 'Array must contain at most 50 element(s) at "images.remotePatterns"' ) }) @@ -95,7 +95,7 @@ describe('Image Optimizer', () => { await nextConfig.restore() expect(stderr).toContain( - 'The value at .images.remotePatterns[0] has an unexpected property, foo, which is not in the list of allowed properties (hostname, pathname, port, protocol).' + `Unrecognized key(s) in object: 'foo' at "images.remotePatterns[0]"` ) }) @@ -120,7 +120,7 @@ describe('Image Optimizer', () => { await nextConfig.restore() expect(stderr).toContain( - "The value at .images.remotePatterns[0] is missing the required field 'hostname'." + `"images.remotePatterns[0].hostname" is missing, expected string` ) }) @@ -145,7 +145,7 @@ describe('Image Optimizer', () => { await nextConfig.restore() expect(stderr).toContain( - 'The value at .images.deviceSizes must have 25 or fewer items but it has 51.' + `Array must contain at most 25 element(s) at "images.deviceSizes"` ) }) @@ -170,10 +170,10 @@ describe('Image Optimizer', () => { await nextConfig.restore() expect(stderr).toContain( - 'The value at .images.deviceSizes[0] must be equal to or greater than 1.' + 'Number must be greater than or equal to 1 at "images.deviceSizes[0]"' ) expect(stderr).toContain( - 'The value at .images.deviceSizes[1] must be equal to or less than 10000.' + 'Number must be less than or equal to 10000 at "images.deviceSizes[1]"' ) }) @@ -198,10 +198,10 @@ describe('Image Optimizer', () => { await nextConfig.restore() expect(stderr).toContain( - 'The value at .images.imageSizes[0] must be equal to or greater than 1.' + 'Number must be greater than or equal to 1 at "images.imageSizes[0]"' ) expect(stderr).toContain( - 'The value at .images.imageSizes[3] must be equal to or less than 10000.' + 'Number must be less than or equal to 10000 at "images.imageSizes[3]"' ) }) @@ -226,7 +226,7 @@ describe('Image Optimizer', () => { await nextConfig.restore() expect(stderr).toContain( - 'The value at .images.loader must be one of: "default", "imgix", "cloudinary", "akamai", or "custom".' + `Expected 'default' | 'imgix' | 'cloudinary' | 'akamai' | 'custom', received 'notreal' at "images.loader"` ) }) @@ -251,7 +251,7 @@ describe('Image Optimizer', () => { await nextConfig.restore() expect(stderr).toContain( - `The value at .images.formats[1] must be one of: "image/avif" or "image/webp".` + `Expected 'image/avif' | 'image/webp', received 'jpeg' at "images.formats[1]"` ) }) @@ -351,7 +351,7 @@ describe('Image Optimizer', () => { await nextConfig.restore() expect(stderr).toContain( - `The value at .images.dangerouslyAllowSVG must be a boolean but it was a string.` + `Expected boolean, received string at "images.dangerouslyAllowSVG"` ) }) @@ -376,7 +376,7 @@ describe('Image Optimizer', () => { await nextConfig.restore() expect(stderr).toContain( - `The value at .images.contentSecurityPolicy must be a string but it was a number.` + `Expected string, received number at "images.contentSecurityPolicy"` ) }) @@ -401,7 +401,7 @@ describe('Image Optimizer', () => { await nextConfig.restore() expect(stderr).toContain( - `The value at .images.contentDispositionType must be one of: "inline" or "attachment".` + `Expected 'inline' | 'attachment', received 'nope' at "images.contentDispositionType"` ) }) @@ -426,7 +426,7 @@ describe('Image Optimizer', () => { await nextConfig.restore() expect(stderr).toContain( - `The value at .images.minimumCacheTTL must be equal to or greater than 0.` + `Number must be greater than or equal to 0 at "images.minimumCacheTTL"` ) }) @@ -451,7 +451,7 @@ describe('Image Optimizer', () => { await nextConfig.restore() expect(stderr).toContain( - `The value at .images.unoptimized must be a boolean but it was a string.` + `Expected boolean, received string at "images.unoptimized"` ) }) }) From a44b4f85b56ef1c5cfe9ab931839a24241c10230 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 5 Oct 2023 11:45:00 -0600 Subject: [PATCH 04/15] Dev Service (#56442) This replaces the `(global as any)._nextDevHandlers` invocation with references to a specific service instance while also removing the module scoped `devInstances`. This ensures that correct types are used. This was done while changing the `match` parameter in `ensurePage` to `definition` which didn't cause a typescript error (it should have). --- .github/CODEOWNERS | 20 +-- .../next/src/server/dev/hot-reloader-types.ts | 6 +- .../src/server/dev/hot-reloader-webpack.ts | 8 +- .../next/src/server/dev/next-dev-server.ts | 48 +++---- .../src/server/dev/on-demand-entry-handler.ts | 79 +++++------- .../src/server/lib/dev-bundler-service.ts | 74 +++++++++++ packages/next/src/server/lib/render-server.ts | 2 + packages/next/src/server/lib/router-server.ts | 122 ++++-------------- .../{setup-dev.ts => setup-dev-bundler.ts} | 13 +- packages/next/src/server/next.ts | 22 +++- 10 files changed, 203 insertions(+), 191 deletions(-) create mode 100644 packages/next/src/server/lib/dev-bundler-service.ts rename packages/next/src/server/lib/router-utils/{setup-dev.ts => setup-dev-bundler.ts} (99%) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e074a6c909ac..47d7daf588ba 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -28,13 +28,13 @@ # Tooling & Telemetry -/packages/next/src/build/ @timneutkens @ijjk @shuding @huozhi @ztanner @feedthejim @vercel/web-tooling -/packages/next/src/server/lib/router-utils/setup-dev.ts @timneutkens @ijjk @shuding @huozhi @feedthejim @ztanner @wyattjoh @vercel/web-tooling -/packages/next/src/telemetry/ @timneutkens @ijjk @shuding @padmaia -/packages/next-swc/ @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling -Cargo.toml @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling -Cargo.lock @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling -/.cargo/config.toml @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling -/.config/nextest.toml @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling -/test/build-turbopack-tests-manifest.js @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling -/test/turbopack-tests-manifest.json @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling +/packages/next/src/build/ @timneutkens @ijjk @shuding @huozhi @ztanner @feedthejim @vercel/web-tooling +/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts @timneutkens @ijjk @shuding @huozhi @feedthejim @ztanner @wyattjoh @vercel/web-tooling +/packages/next/src/telemetry/ @timneutkens @ijjk @shuding @padmaia +/packages/next-swc/ @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling +Cargo.toml @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling +Cargo.lock @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling +/.cargo/config.toml @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling +/.config/nextest.toml @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling +/test/build-turbopack-tests-manifest.js @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling +/test/turbopack-tests-manifest.json @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling diff --git a/packages/next/src/server/dev/hot-reloader-types.ts b/packages/next/src/server/dev/hot-reloader-types.ts index 191e4570697d..922dc95452e0 100644 --- a/packages/next/src/server/dev/hot-reloader-types.ts +++ b/packages/next/src/server/dev/hot-reloader-types.ts @@ -3,7 +3,7 @@ import type { UrlObject } from 'url' import type { Duplex } from 'stream' import type { webpack } from 'next/dist/compiled/webpack/webpack' import type getBaseWebpackConfig from '../../build/webpack-config' -import type { RouteMatch } from '../future/route-matches/route-match' +import type { RouteDefinition } from '../future/route-definitions/route-definition' import type { Project, Update as TurbopackUpdate } from '../../build/swc' import type { VersionInfo } from './parse-version-info' @@ -134,13 +134,13 @@ export interface NextJsHotReloaderInterface { page, clientOnly, appPaths, - match, + definition, isApp, }: { page: string clientOnly: boolean appPaths?: ReadonlyArray | null isApp?: boolean - match?: RouteMatch + definition: RouteDefinition | undefined }): Promise } diff --git a/packages/next/src/server/dev/hot-reloader-webpack.ts b/packages/next/src/server/dev/hot-reloader-webpack.ts index 20fa94826f3a..48187503b399 100644 --- a/packages/next/src/server/dev/hot-reloader-webpack.ts +++ b/packages/next/src/server/dev/hot-reloader-webpack.ts @@ -4,6 +4,7 @@ import type { Duplex } from 'stream' import type { Telemetry } from '../../telemetry/storage' import type { IncomingMessage, ServerResponse } from 'http' import type { UrlObject } from 'url' +import type { RouteDefinition } from '../future/route-definitions/route-definition' import { webpack, StringXor } from 'next/dist/compiled/webpack/webpack' import { getOverlayMiddleware } from 'next/dist/compiled/@next/react-dev-overlay/dist/middleware' @@ -60,7 +61,6 @@ import ws from 'next/dist/compiled/ws' import { existsSync, promises as fs } from 'fs' import { UnwrapPromise } from '../../lib/coalesced-function' import { getRegistry } from '../../lib/helpers/get-registry' -import { RouteMatch } from '../future/route-matches/route-match' import { parseVersionInfo, VersionInfo } from './parse-version-info' import { isAPIRoute } from '../../lib/is-api-route' import { getRouteLoaderEntry } from '../../build/webpack/loaders/next-route-loader' @@ -1466,14 +1466,14 @@ export default class HotReloader implements NextJsHotReloaderInterface { page, clientOnly, appPaths, - match, + definition, isApp, }: { page: string clientOnly: boolean appPaths?: ReadonlyArray | null isApp?: boolean - match?: RouteMatch + definition?: RouteDefinition }): Promise { // Make sure we don't re-build or dispose prebuilt pages if (page !== '/_error' && BLOCKED_PAGES.indexOf(page) !== -1) { @@ -1490,7 +1490,7 @@ export default class HotReloader implements NextJsHotReloaderInterface { page, clientOnly, appPaths, - match, + definition, isApp, }) } diff --git a/packages/next/src/server/dev/next-dev-server.ts b/packages/next/src/server/dev/next-dev-server.ts index 937e303461db..561f6958ce54 100644 --- a/packages/next/src/server/dev/next-dev-server.ts +++ b/packages/next/src/server/dev/next-dev-server.ts @@ -8,12 +8,13 @@ import type { UrlWithParsedQuery } from 'url' import type { BaseNextRequest, BaseNextResponse } from '../base-http' import type { FallbackMode, MiddlewareRoutingItem } from '../base-server' import type { FunctionComponent } from 'react' -import type { RouteMatch } from '../future/route-matches/route-match' +import type { RouteDefinition } from '../future/route-definitions/route-definition' import type { RouteMatcherManager } from '../future/route-matcher-managers/route-matcher-manager' import type { NextParsedUrlQuery, NextUrlWithParsedQuery, } from '../request-meta' +import type { DevBundlerService } from '../lib/dev-bundler-service' import fs from 'fs' import { Worker } from 'next/dist/compiled/jest-worker' @@ -80,6 +81,11 @@ export interface Options extends ServerOptions { * Tells of Next.js is running from the `next dev` command */ isNextDevCommand?: boolean + + /** + * Interface to the development bundler. + */ + bundlerService: DevBundlerService } export default class DevServer extends Server { @@ -92,15 +98,12 @@ export default class DevServer extends Server { private actualInstrumentationHookFile?: string private middleware?: MiddlewareRoutingItem private originalFetch: typeof fetch + private readonly bundlerService: DevBundlerService private staticPathsCache: LRUCache< string, UnwrapPromise> > - private invokeDevMethod({ method, args }: { method: string; args: any[] }) { - return (global as any)._nextDevHandlers[method](this.dir, ...args) - } - protected staticPathsWorker?: { [key: string]: any } & { loadStaticPaths: typeof import('./static-paths-worker').loadStaticPaths } @@ -140,6 +143,7 @@ export default class DevServer extends Server { Error.stackTraceLimit = 50 } catch {} super({ ...options, dev: true }) + this.bundlerService = options.bundlerService this.originalFetch = global.fetch this.renderOpts.dev = true this.renderOpts.appDirDevErrorLogger = (err: any) => @@ -190,7 +194,7 @@ export default class DevServer extends Server { const ensurer: RouteEnsurer = { ensure: async (match) => { await this.ensurePage({ - match, + definition: match.definition, page: match.definition.page, clientOnly: false, }) @@ -487,10 +491,7 @@ export default class DevServer extends Server { err?: unknown, type?: 'unhandledRejection' | 'uncaughtException' | 'warning' | 'app-dir' ): Promise { - await this.invokeDevMethod({ - method: 'logErrorWithOriginalStack', - args: [err, type], - }) + await this.bundlerService.logErrorWithOriginalStack(err, type) } protected getPagesManifest(): PagesManifest | undefined { @@ -534,6 +535,7 @@ export default class DevServer extends Server { return this.ensurePage({ page: this.actualMiddlewareFile!, clientOnly: false, + definition: undefined, }) } @@ -543,6 +545,7 @@ export default class DevServer extends Server { (await this.ensurePage({ page: this.actualInstrumentationHookFile!, clientOnly: false, + definition: undefined, }) .then(() => true) .catch(() => false)) @@ -570,7 +573,12 @@ export default class DevServer extends Server { page: string appPaths: string[] | null }) { - return this.ensurePage({ page, appPaths, clientOnly: false }) + return this.ensurePage({ + page, + appPaths, + clientOnly: false, + definition: undefined, + }) } generateRoutes(_dev?: boolean) { @@ -723,12 +731,9 @@ export default class DevServer extends Server { page: string clientOnly: boolean appPaths?: ReadonlyArray | null - match?: RouteMatch + definition: RouteDefinition | undefined }): Promise { - await this.invokeDevMethod({ - method: 'ensurePage', - args: [opts], - }) + await this.bundlerService.ensurePage(opts) } protected async findPageComponents({ @@ -759,6 +764,7 @@ export default class DevServer extends Server { page, appPaths, clientOnly: false, + definition: undefined, }) } @@ -785,17 +791,11 @@ export default class DevServer extends Server { } protected async getFallbackErrorComponents(): Promise { - await this.invokeDevMethod({ - method: 'getFallbackErrorComponents', - args: [], - }) + await this.bundlerService.getFallbackErrorComponents() return await loadDefaultErrorComponents(this.distDir) } async getCompilationError(page: string): Promise { - return await this.invokeDevMethod({ - method: 'getCompilationError', - args: [page], - }) + return await this.bundlerService.getCompilationError(page) } } diff --git a/packages/next/src/server/dev/on-demand-entry-handler.ts b/packages/next/src/server/dev/on-demand-entry-handler.ts index c5ef3a5802ce..0529aeb9d56f 100644 --- a/packages/next/src/server/dev/on-demand-entry-handler.ts +++ b/packages/next/src/server/dev/on-demand-entry-handler.ts @@ -33,7 +33,6 @@ import { COMPILER_NAMES, RSC_MODULE_TYPES, } from '../../shared/lib/constants' -import { RouteMatch } from '../future/route-matches/route-match' import { HMR_ACTIONS_SENT_TO_BROWSER } from './hot-reloader-types' import HotReloader from './hot-reloader-webpack' import { isAppPageRouteDefinition } from '../future/route-definitions/app-page-route-definition' @@ -677,13 +676,13 @@ export function onDemandEntryHandler({ page, clientOnly, appPaths, - match, + definition, isApp, }: { page: string clientOnly: boolean appPaths: ReadonlyArray | null - match: Pick | undefined + definition: RouteDefinition | undefined isApp: boolean | undefined }): Promise { const stalledTime = 60 @@ -694,11 +693,11 @@ export function onDemandEntryHandler({ }, stalledTime * 1000) try { - let definition: Pick - if (match?.definition) { - definition = match.definition + let route: Pick + if (definition) { + route = definition } else { - definition = await findPagePathData( + route = await findPagePathData( rootDir, page, nextConfig.pageExtensions, @@ -707,18 +706,18 @@ export function onDemandEntryHandler({ ) } - const isInsideAppDir = !!appDir && definition.filename.startsWith(appDir) + const isInsideAppDir = !!appDir && route.filename.startsWith(appDir) if (typeof isApp === 'boolean' && isApp !== isInsideAppDir) { Error.stackTraceLimit = 15 throw new Error( `Ensure bailed, found path "${ - definition.page + route.page }" does not match ensure type (${isApp ? 'app' : 'pages'})` ) } - const pageBundleType = getPageBundleType(definition.bundlePath) + const pageBundleType = getPageBundleType(route.bundlePath) const addEntry = ( compilerType: CompilerNameValues ): { @@ -726,11 +725,7 @@ export function onDemandEntryHandler({ newEntry: boolean shouldInvalidate: boolean } => { - const entryKey = getEntryKey( - compilerType, - pageBundleType, - definition.page - ) + const entryKey = getEntryKey(compilerType, pageBundleType, route.page) if ( curEntries[entryKey] && // there can be an overlap in the entryKey for the instrumentation hook file and a page named the same @@ -758,9 +753,9 @@ export function onDemandEntryHandler({ curEntries[entryKey] = { type: EntryTypes.ENTRY, appPaths, - absolutePagePath: definition.filename, - request: definition.filename, - bundlePath: definition.bundlePath, + absolutePagePath: route.filename, + request: route.filename, + bundlePath: route.bundlePath, dispose: false, lastActiveTime: Date.now(), status: ADDED, @@ -774,7 +769,7 @@ export function onDemandEntryHandler({ const staticInfo = await getStaticInfoIncludingLayouts({ page, - pageFilePath: definition.filename, + pageFilePath: route.filename, isInsideAppDir, pageExtensions: nextConfig.pageExtensions, isDev: true, @@ -787,7 +782,7 @@ export function onDemandEntryHandler({ isInsideAppDir && staticInfo.rsc !== RSC_MODULE_TYPES.client runDependingOnPageType({ - page: definition.page, + page: route.page, pageRuntime: staticInfo.runtime, pageType: pageBundleType, onClient: () => { @@ -802,11 +797,11 @@ export function onDemandEntryHandler({ const edgeServerEntry = getEntryKey( COMPILER_NAMES.edgeServer, pageBundleType, - definition.page + route.page ) if ( curEntries[edgeServerEntry] && - !isInstrumentationHookFile(definition.page) + !isInstrumentationHookFile(route.page) ) { // Runtime switched from edge to server delete curEntries[edgeServerEntry] @@ -820,11 +815,11 @@ export function onDemandEntryHandler({ const serverEntry = getEntryKey( COMPILER_NAMES.server, pageBundleType, - definition.page + route.page ) if ( curEntries[serverEntry] && - !isInstrumentationHookFile(definition.page) + !isInstrumentationHookFile(route.page) ) { // Runtime switched from server to edge delete curEntries[serverEntry] @@ -839,9 +834,7 @@ export function onDemandEntryHandler({ const hasNewEntry = addedValues.some((entry) => entry.newEntry) if (hasNewEntry) { - reportTrigger( - !clientOnly && hasNewEntry ? `${definition.page}` : definition.page - ) + reportTrigger(!clientOnly && hasNewEntry ? `${route.page}` : route.page) } if (entriesThatShouldBeInvalidated.length > 0) { @@ -883,18 +876,12 @@ export function onDemandEntryHandler({ page: string clientOnly: boolean appPaths?: ReadonlyArray | null - match?: RouteMatch + definition?: RouteDefinition isApp?: boolean } // Make sure that we won't have multiple invalidations ongoing concurrently. - const batcher = Batcher.create< - Omit & { - definition?: RouteDefinition - }, - void, - string - >({ + const batcher = Batcher.create({ // The cache key here is composed of the elements that affect the // compilation, namely, the page, whether it's client only, and whether // it's an app page. This ensures that we don't have multiple compilations @@ -913,26 +900,28 @@ export function onDemandEntryHandler({ page, clientOnly, appPaths = null, - match, + definition, isApp, }: EnsurePageOptions) { // If the route is actually an app page route, then we should have access - // to the app route match, and therefore, the appPaths from it. - if ( - !appPaths && - match?.definition && - isAppPageRouteDefinition(match.definition) - ) { - appPaths = match.definition.appPaths + // to the app route definition, and therefore, the appPaths from it. + if (!appPaths && definition && isAppPageRouteDefinition(definition)) { + appPaths = definition.appPaths } // Wrap the invocation of the ensurePageImpl function in the pending // wrapper, which will ensure that we don't have multiple compilations // for the same page happening concurrently. return batcher.batch( - { page, clientOnly, appPaths, definition: match?.definition, isApp }, + { page, clientOnly, appPaths, definition, isApp }, async () => { - await ensurePageImpl({ page, clientOnly, appPaths, match, isApp }) + await ensurePageImpl({ + page, + clientOnly, + appPaths, + definition, + isApp, + }) } ) }, diff --git a/packages/next/src/server/lib/dev-bundler-service.ts b/packages/next/src/server/lib/dev-bundler-service.ts new file mode 100644 index 000000000000..99ca47415bcf --- /dev/null +++ b/packages/next/src/server/lib/dev-bundler-service.ts @@ -0,0 +1,74 @@ +import type { IncomingMessage } from 'http' +import type { DevBundler } from './router-utils/setup-dev-bundler' +import type { WorkerRequestHandler } from './types' + +import { createRequestResponseMocks } from './mock-request' + +/** + * The DevBundlerService provides an interface to perform tasks with the + * bundler while in development. + */ +export class DevBundlerService { + constructor( + private readonly bundler: DevBundler, + private readonly handler: WorkerRequestHandler + ) {} + + public ensurePage: typeof this.bundler.hotReloader.ensurePage = async ( + definition + ) => { + // TODO: remove after ensure is pulled out of server + return await this.bundler.hotReloader.ensurePage(definition) + } + + public logErrorWithOriginalStack: typeof this.bundler.logErrorWithOriginalStack = + async (...args) => { + return await this.bundler.logErrorWithOriginalStack(...args) + } + + public async getFallbackErrorComponents() { + await this.bundler.hotReloader.buildFallbackError() + // Build the error page to ensure the fallback is built too. + // TODO: See if this can be moved into hotReloader or removed. + await this.bundler.hotReloader.ensurePage({ + page: '/_error', + clientOnly: false, + definition: undefined, + }) + } + + public async getCompilationError(page: string) { + const errors = await this.bundler.hotReloader.getCompilationErrors(page) + if (!errors) return + + // Return the very first error we found. + return errors[0] + } + + public async revalidate({ + urlPath, + revalidateHeaders, + opts: revalidateOpts, + }: { + urlPath: string + revalidateHeaders: IncomingMessage['headers'] + opts: any + }) { + const mocked = createRequestResponseMocks({ + url: urlPath, + headers: revalidateHeaders, + }) + + await this.handler(mocked.req, mocked.res) + await mocked.res.hasStreamed + + if ( + mocked.res.getHeader('x-nextjs-cache') !== 'REVALIDATED' && + !(mocked.res.statusCode === 404 && revalidateOpts.unstable_onlyGenerated) + ) { + throw new Error(`Invalid response ${mocked.res.statusCode}`) + } + + return {} + } +} diff --git a/packages/next/src/server/lib/render-server.ts b/packages/next/src/server/lib/render-server.ts index 85845f774056..21c2a6ae9f6f 100644 --- a/packages/next/src/server/lib/render-server.ts +++ b/packages/next/src/server/lib/render-server.ts @@ -1,4 +1,5 @@ import type { NextServer, RequestHandler } from '../next' +import type { DevBundlerService } from './dev-bundler-service' import next from '../next' import { PropagateToWorkersField } from './router-utils/types' @@ -79,6 +80,7 @@ async function initializeImpl(opts: { experimentalHttpsServer: boolean _ipcPort?: string _ipcKey?: string + bundlerService: DevBundlerService | undefined }) { const type = process.env.__NEXT_PRIVATE_RENDER_WORKER if (type) { diff --git a/packages/next/src/server/lib/router-server.ts b/packages/next/src/server/lib/router-server.ts index b16858a50645..b1e8e7487fe2 100644 --- a/packages/next/src/server/lib/router-server.ts +++ b/packages/next/src/server/lib/router-server.ts @@ -1,7 +1,6 @@ -import type { IncomingMessage } from 'http' - // this must come first as it includes require hooks import type { WorkerRequestHandler, WorkerUpgradeHandler } from './types' +import type { DevBundler } from './router-utils/setup-dev-bundler' // This is required before other imports to ensure the require hook is setup. import '../node-polyfill-fetch' @@ -20,8 +19,6 @@ import { findPagesDir } from '../../lib/find-pages-dir' import { setupFsCheck } from './router-utils/filesystem' import { proxyRequest } from './router-utils/proxy-request' import { isAbortError, pipeReadable } from '../pipe-readable' -import { createRequestResponseMocks } from './mock-request' -import { UnwrapPromise } from '../../lib/coalesced-function' import { getResolveRoutes } from './router-utils/resolve-routes' import { NextUrlWithParsedQuery, getRequestMeta } from '../request-meta' import { pathHasPrefix } from '../../shared/lib/router/utils/path-has-prefix' @@ -35,7 +32,7 @@ import { PHASE_DEVELOPMENT_SERVER, PERMANENT_REDIRECT_STATUS, } from '../../shared/lib/constants' -import type { NextJsHotReloaderInterface } from '../dev/hot-reloader-types' +import { DevBundlerService } from './dev-bundler-service' const debug = setupDebug('next:router-server:main') @@ -48,11 +45,6 @@ export type RenderServer = Pick< | 'propagateServerField' > -const devInstances: Record< - string, - UnwrapPromise> -> = {} - export interface LazyRenderServerInstance { instance?: RenderServer } @@ -100,11 +92,9 @@ export async function initialize(opts: { const renderServer: LazyRenderServerInstance = {} - let devInstance: - | UnwrapPromise< - ReturnType - > - | undefined + let developmentBundler: DevBundler | undefined + + let devBundlerService: DevBundlerService | undefined if (opts.dev) { const telemetry = new Telemetry({ @@ -112,10 +102,10 @@ export async function initialize(opts: { }) const { pagesDir, appDir } = findPagesDir(opts.dir) - const { setupDev } = - (await require('./router-utils/setup-dev')) as typeof import('./router-utils/setup-dev') + const { setupDevBundler } = + require('./router-utils/setup-dev-bundler') as typeof import('./router-utils/setup-dev-bundler') - devInstance = await setupDev({ + developmentBundler = await setupDevBundler({ // Passed here but the initialization of this object happens below, doing the initialization before the setupDev call breaks. renderServer, appDir, @@ -128,74 +118,15 @@ export async function initialize(opts: { turbo: !!process.env.TURBOPACK, port: opts.port, }) - devInstances[opts.dir] = devInstance - ;(global as any)._nextDevHandlers = { - async ensurePage( - dir: string, - match: Parameters[0] - ) { - const curDevInstance = devInstances[dir] - // TODO: remove after ensure is pulled out of server - return await curDevInstance?.hotReloader.ensurePage(match) - }, - async logErrorWithOriginalStack(dir: string, ...args: any[]) { - const curDevInstance = devInstances[dir] - // @ts-ignore - return await curDevInstance?.logErrorWithOriginalStack(...args) - }, - async getFallbackErrorComponents(dir: string) { - const curDevInstance = devInstances[dir] - await curDevInstance.hotReloader.buildFallbackError() - // Build the error page to ensure the fallback is built too. - // TODO: See if this can be moved into hotReloader or removed. - await curDevInstance.hotReloader.ensurePage({ - page: '/_error', - clientOnly: false, - }) - }, - async getCompilationError(dir: string, page: string) { - const curDevInstance = devInstances[dir] - const errors = await curDevInstance?.hotReloader?.getCompilationErrors( - page - ) - if (!errors) return - - // Return the very first error we found. - return errors[0] - }, - async revalidate( - dir: string, - { - urlPath, - revalidateHeaders, - opts: revalidateOpts, - }: { - urlPath: string - revalidateHeaders: IncomingMessage['headers'] - opts: any - } - ) { - const mocked = createRequestResponseMocks({ - url: urlPath, - headers: revalidateHeaders, - }) - const curRequestHandler = requestHandlers[dir] - // eslint-disable-next-line @typescript-eslint/no-use-before-define - await curRequestHandler(mocked.req, mocked.res) - await mocked.res.hasStreamed - if ( - mocked.res.getHeader('x-nextjs-cache') !== 'REVALIDATED' && - !( - mocked.res.statusCode === 404 && - revalidateOpts.unstable_onlyGenerated - ) - ) { - throw new Error(`Invalid response ${mocked.res.statusCode}`) - } - return {} - }, - } as any + devBundlerService = new DevBundlerService( + developmentBundler, + // The request handler is assigned below, this allows us to create a lazy + // reference to it. + (req, res) => { + return requestHandlers[opts.dir](req, res) + } + ) } renderServer.instance = @@ -209,9 +140,10 @@ export async function initialize(opts: { dev: !!opts.dev, server: opts.server, isNodeDebugging: !!opts.isNodeDebugging, - serverFields: devInstance?.serverFields || {}, + serverFields: developmentBundler?.serverFields || {}, experimentalTestProxy: !!opts.experimentalTestProxy, experimentalHttpsServer: !!opts.experimentalHttpsServer, + bundlerService: devBundlerService, } // pre-initialize workers @@ -221,7 +153,7 @@ export async function initialize(opts: { type: 'uncaughtException' | 'unhandledRejection', err: Error | undefined ) => { - await devInstance?.logErrorWithOriginalStack(err, type) + await developmentBundler?.logErrorWithOriginalStack(err, type) } process.on('uncaughtException', logError.bind(null, 'uncaughtException')) @@ -233,7 +165,7 @@ export async function initialize(opts: { opts, renderServer.instance, renderServerOpts, - devInstance?.ensureMiddleware + developmentBundler?.ensureMiddleware ) const requestHandlerImpl: WorkerRequestHandler = async (req, res) => { @@ -328,7 +260,7 @@ export async function initialize(opts: { } // handle hot-reloader first - if (devInstance) { + if (developmentBundler) { const origUrl = req.url || '/' if (config.basePath && pathHasPrefix(origUrl, config.basePath)) { @@ -336,7 +268,7 @@ export async function initialize(opts: { } const parsedUrl = url.parse(req.url || '/') - const hotReloaderResult = await devInstance.hotReloader.run( + const hotReloaderResult = await developmentBundler.hotReloader.run( req, res, parsedUrl @@ -367,7 +299,7 @@ export async function initialize(opts: { return } - if (devInstance && matchedOutput?.type === 'devVirtualFsItem') { + if (developmentBundler && matchedOutput?.type === 'devVirtualFsItem') { const origUrl = req.url || '/' if (config.basePath && pathHasPrefix(origUrl, config.basePath)) { @@ -379,7 +311,7 @@ export async function initialize(opts: { res.setHeader(key, resHeaders[key]) } } - const result = await devInstance.requestHandler(req, res) + const result = await developmentBundler.requestHandler(req, res) if (result.finished) { return @@ -571,7 +503,7 @@ export async function initialize(opts: { } const appNotFound = opts.dev - ? devInstance?.serverFields.hasAppNotFound + ? developmentBundler?.serverFields.hasAppNotFound : await fsChecker.getItem('/_not-found') res.statusCode = 404 @@ -640,9 +572,9 @@ export async function initialize(opts: { // console.error(_err); }) - if (opts.dev && devInstance) { + if (opts.dev && developmentBundler) { if (req.url?.includes(`/_next/webpack-hmr`)) { - return devInstance.hotReloader.onHMR(req, socket, head) + return developmentBundler.hotReloader.onHMR(req, socket, head) } } diff --git a/packages/next/src/server/lib/router-utils/setup-dev.ts b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts similarity index 99% rename from packages/next/src/server/lib/router-utils/setup-dev.ts rename to packages/next/src/server/lib/router-utils/setup-dev-bundler.ts index f97e14c15178..5ba81e901a10 100644 --- a/packages/next/src/server/lib/router-utils/setup-dev.ts +++ b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts @@ -1065,6 +1065,7 @@ async function startWatcher(opts: SetupOpts) { .ensurePage({ page: decodedPagePath, clientOnly: false, + definition: undefined, }) .catch(console.error) } @@ -1166,10 +1167,10 @@ async function startWatcher(opts: SetupOpts) { // Unused parameters // clientOnly, // appPaths, - match, + definition, isApp, }) { - let page = match?.definition?.pathname ?? inputPage + let page = definition?.pathname ?? inputPage if (page === '/_error') { if (globalEntries.app) { @@ -1218,7 +1219,7 @@ async function startWatcher(opts: SetupOpts) { curEntries.get(page) ?? curEntries.get( normalizeAppPath( - normalizeMetadataRoute(match?.definition?.page ?? inputPage) + normalizeMetadataRoute(definition?.page ?? inputPage) ) ) @@ -1457,6 +1458,7 @@ async function startWatcher(opts: SetupOpts) { clientOnly: false, page: item.itemPath, isApp: item.type === 'appFile', + definition: undefined, }) } }) @@ -2236,12 +2238,13 @@ async function startWatcher(opts: SetupOpts) { return hotReloader.ensurePage({ page: serverFields.actualMiddlewareFile, clientOnly: false, + definition: undefined, }) }, } } -export async function setupDev(opts: SetupOpts) { +export async function setupDevBundler(opts: SetupOpts) { const isSrcDir = path .relative(opts.dir, opts.pagesDir || opts.appDir || '') .startsWith('src') @@ -2266,3 +2269,5 @@ export async function setupDev(opts: SetupOpts) { ) return result } + +export type DevBundler = Awaited> diff --git a/packages/next/src/server/next.ts b/packages/next/src/server/next.ts index fd987b9c8b26..061b7cfa255f 100644 --- a/packages/next/src/server/next.ts +++ b/packages/next/src/server/next.ts @@ -1,5 +1,8 @@ import type { Options as DevServerOptions } from './dev/next-dev-server' -import type { NodeRequestHandler } from './next-server' +import type { + NodeRequestHandler, + Options as ServerOptions, +} from './next-server' import type { UrlWithParsedQuery } from 'url' import type { NextConfigComplete } from './config-shared' import type { IncomingMessage, ServerResponse } from 'http' @@ -34,10 +37,15 @@ const getServerImpl = async () => { return ServerImpl } -export type NextServerOptions = Partial & { - preloadedConfig?: NextConfigComplete - internal_setStandaloneConfig?: boolean -} +export type NextServerOptions = Omit< + ServerOptions | DevServerOptions, + // This is assigned in this server abstraction. + 'conf' +> & + Partial> & { + preloadedConfig?: NextConfigComplete + internal_setStandaloneConfig?: boolean + } export interface RequestHandler { ( @@ -153,7 +161,9 @@ export class NextServer { return (server as any).close() } - private async createServer(options: DevServerOptions): Promise { + private async createServer( + options: ServerOptions | DevServerOptions + ): Promise { let ServerImplementation: typeof Server if (options.dev) { ServerImplementation = require('./dev/next-dev-server').default From 11c1d07b890e7b30ee8758cd50b53eb0559f5bc5 Mon Sep 17 00:00:00 2001 From: Leah Date: Thu, 5 Oct 2023 20:38:46 +0200 Subject: [PATCH 05/15] feat(turbopack): port next.js template loading logic (#56425) Closes WEB-1706 --- .../crates/next-core/src/middleware.rs | 29 +-- .../next-core/src/next_app/app_page_entry.rs | 81 +++---- .../next-core/src/next_app/app_route_entry.rs | 72 ++---- .../next-core/src/next_pages/page_entry.rs | 103 ++++----- .../next-swc/crates/next-core/src/util.rs | 208 +++++++++++++++++- 5 files changed, 313 insertions(+), 180 deletions(-) diff --git a/packages/next-swc/crates/next-core/src/middleware.rs b/packages/next-swc/crates/next-core/src/middleware.rs index 13ec57a4af39..ff372feabd15 100644 --- a/packages/next-swc/crates/next-core/src/middleware.rs +++ b/packages/next-swc/crates/next-core/src/middleware.rs @@ -1,13 +1,12 @@ use anyhow::Result; use indexmap::indexmap; use turbo_tasks::{Value, Vc}; -use turbo_tasks_fs::{File, FileSystemPath}; +use turbo_tasks_fs::FileSystemPath; use turbopack_binding::turbopack::core::{ - asset::AssetContent, context::AssetContext, module::Module, reference_type::ReferenceType, - virtual_source::VirtualSource, + context::AssetContext, module::Module, reference_type::ReferenceType, }; -use crate::util::{load_next_js_template, virtual_next_js_template_path}; +use crate::util::load_next_js_template; #[turbo_tasks::function] pub async fn middleware_files(page_extensions: Vc>) -> Result>> { @@ -29,23 +28,25 @@ pub async fn get_middleware_module( project_root: Vc, userland_module: Vc>, ) -> Result>> { - let template_file = "middleware.js"; + const INNER: &str = "INNER_MIDDLEWARE_MODULE"; // Load the file from the next.js codebase. - let file = load_next_js_template(project_root, template_file.to_string()).await?; - - let file = File::from(file.clone_value()); - - let template_path = virtual_next_js_template_path(project_root, template_file.to_string()); - - let virtual_source = VirtualSource::new(template_path, AssetContent::file(file.into())); + let source = load_next_js_template( + "middleware.js", + project_root, + indexmap! { + "VAR_USERLAND" => INNER.to_string(), + }, + indexmap! {}, + ) + .await?; let inner_assets = indexmap! { - "VAR_USERLAND".to_string() => userland_module + INNER.to_string() => userland_module }; let module = context.process( - Vc::upcast(virtual_source), + source, Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), ); diff --git a/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs b/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs index 1b50862bc0d6..d6d16e7dde62 100644 --- a/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs +++ b/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs @@ -1,12 +1,16 @@ use std::io::Write; use anyhow::{bail, Result}; +use indexmap::indexmap; use turbo_tasks::{TryJoinIterExt, Value, ValueToString, Vc}; use turbopack_binding::{ turbo::tasks_fs::{rope::RopeBuilder, File, FileSystemPath}, turbopack::{ core::{ - asset::AssetContent, context::AssetContext, reference_type::ReferenceType, + asset::{Asset, AssetContent}, + context::AssetContext, + reference_type::ReferenceType, + source::Source, virtual_source::VirtualSource, }, ecmascript::{chunk::EcmascriptChunkPlaceable, utils::StringifyJs}, @@ -22,7 +26,7 @@ use crate::{ next_app::{AppPage, AppPath}, next_server_component::NextServerComponentTransition, parse_segment_config_from_loader_tree, - util::{load_next_js_template, virtual_next_js_template_path, NextRuntime}, + util::{file_content_rope, load_next_js_template, NextRuntime}, }; /// Computes the entry for a Next.js app page. @@ -70,59 +74,32 @@ pub async fn get_app_page_entry( let original_name = page.to_string(); let pathname = AppPath::from(page.clone()).to_string(); - let template_file = "app-page.js"; - // Load the file from the next.js codebase. - let file = load_next_js_template(project_root, template_file.to_string()).await?; - - let mut file = file - .to_str()? - .replace( - "\"VAR_DEFINITION_PAGE\"", - &StringifyJs(&page.to_string()).to_string(), - ) - .replace( - "\"VAR_DEFINITION_PATHNAME\"", - &StringifyJs(&pathname).to_string(), - ) - .replace( - "\"VAR_ORIGINAL_PATHNAME\"", - &StringifyJs(&original_name).to_string(), - ) - // TODO(alexkirsz) Support custom global error. - .replace( - "\"VAR_MODULE_GLOBAL_ERROR\"", - &StringifyJs("next/dist/client/components/error-boundary").to_string(), - ) - .replace( - "// INJECT:tree", - format!("const tree = {};", loader_tree_code).as_str(), - ) - .replace( - "// INJECT:pages", - format!("const pages = {};", StringifyJs(&pages)).as_str(), - ) - .replace( - "// INJECT:__next_app_require__", - "const __next_app_require__ = __turbopack_require__", - ) - .replace( - "// INJECT:__next_app_load_chunk__", - "const __next_app_load_chunk__ = __turbopack_load__", - ); - - // Ensure that the last line is a newline. - if !file.ends_with('\n') { - file.push('\n'); - } - - result.push_bytes(file.as_bytes()); + let source = load_next_js_template( + "app-page.js", + project_root, + indexmap! { + "VAR_DEFINITION_PAGE" => page.to_string(), + "VAR_DEFINITION_PATHNAME" => pathname.clone(), + "VAR_ORIGINAL_PATHNAME" => original_name.clone(), + // TODO(alexkirsz) Support custom global error. + "VAR_MODULE_GLOBAL_ERROR" => "next/dist/client/components/error-boundary".to_string(), + }, + indexmap! { + "tree" => loader_tree_code, + "pages" => StringifyJs(&pages).to_string(), + "__next_app_require__" => "__turbopack_require__".to_string(), + "__next_app_load_chunk__" => " __turbopack_load__".to_string(), + }, + ) + .await?; - let file = File::from(result.build()); + let source_content = &*file_content_rope(source.content().file_content()).await?; - let template_path = virtual_next_js_template_path(project_root, template_file.to_string()); + result.concat(source_content); - let source = VirtualSource::new(template_path, AssetContent::file(file.into())); + let file = File::from(result.build()); + let source = VirtualSource::new(source.ident().path(), AssetContent::file(file.into())); let rsc_entry = context.process( Vc::upcast(source), @@ -140,7 +117,7 @@ pub async fn get_app_page_entry( }; Ok(AppEntry { - pathname: pathname.to_string(), + pathname, original_name, rsc_entry, config, diff --git a/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs b/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs index 014328c97f30..c2d682179834 100644 --- a/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs +++ b/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs @@ -23,7 +23,7 @@ use turbopack_binding::{ use crate::{ next_app::{AppEntry, AppPage, AppPath}, parse_segment_config_from_source, - util::{load_next_js_template, virtual_next_js_template_path, NextRuntime}, + util::{load_next_js_template, NextRuntime}, }; /// Computes the entry for a Next.js app route. @@ -49,62 +49,32 @@ pub async fn get_app_route_entry( nodejs_context }; - let mut result = RopeBuilder::default(); - let original_name = page.to_string(); let pathname = AppPath::from(page.clone()).to_string(); let path = source.ident().path(); - let template_file = "app-route.js"; + const INNER: &str = "INNER_APP_ROUTE"; // Load the file from the next.js codebase. - let file = load_next_js_template(project_root, template_file.to_string()).await?; - - let mut file = file - .to_str()? - .replace( - "\"VAR_DEFINITION_PAGE\"", - &StringifyJs(&original_name).to_string(), - ) - .replace( - "\"VAR_DEFINITION_PATHNAME\"", - &StringifyJs(&pathname).to_string(), - ) - .replace( - "\"VAR_DEFINITION_FILENAME\"", - &StringifyJs(&path.file_stem().await?.as_ref().unwrap().clone()).to_string(), - ) - // TODO(alexkirsz) Is this necessary? - .replace( - "\"VAR_DEFINITION_BUNDLE_PATH\"", - &StringifyJs("").to_string(), - ) - .replace( - "\"VAR_ORIGINAL_PATHNAME\"", - &StringifyJs(&original_name).to_string(), - ) - .replace( - "\"VAR_RESOLVED_PAGE_PATH\"", - &StringifyJs(&path.to_string().await?).to_string(), - ) - .replace( - "// INJECT:nextConfigOutput", - "const nextConfigOutput = \"\"", - ); - - // Ensure that the last line is a newline. - if !file.ends_with('\n') { - file.push('\n'); - } - - result.push_bytes(file.as_bytes()); - - let file = File::from(result.build()); - - let template_path = virtual_next_js_template_path(project_root, template_file.to_string()); - - let virtual_source = VirtualSource::new(template_path, AssetContent::file(file.into())); + let virtual_source = load_next_js_template( + "app-route.js", + project_root, + indexmap! { + "VAR_DEFINITION_PAGE" => page.to_string(), + "VAR_DEFINITION_PATHNAME" => pathname.clone(), + "VAR_DEFINITION_FILENAME" => path.file_stem().await?.as_ref().unwrap().clone(), + // TODO(alexkirsz) Is this necessary? + "VAR_DEFINITION_BUNDLE_PATH" => "".to_string(), + "VAR_ORIGINAL_PATHNAME" => original_name.clone(), + "VAR_RESOLVED_PAGE_PATH" => path.to_string().await?.clone_value(), + "VAR_USERLAND" => INNER.to_string(), + }, + indexmap! { + "nextConfigOutput" => "\"\"".to_string(), + }, + ) + .await?; let userland_module = context.process( source, @@ -112,7 +82,7 @@ pub async fn get_app_route_entry( ); let inner_assets = indexmap! { - "VAR_USERLAND".to_string() => userland_module + INNER.to_string() => userland_module }; let mut rsc_entry = context.process( diff --git a/packages/next-swc/crates/next-core/src/next_pages/page_entry.rs b/packages/next-swc/crates/next-core/src/next_pages/page_entry.rs index c05121a79c98..ac48b95e239c 100644 --- a/packages/next-swc/crates/next-core/src/next_pages/page_entry.rs +++ b/packages/next-swc/crates/next-core/src/next_pages/page_entry.rs @@ -11,19 +11,19 @@ use turbopack_binding::{ }, turbopack::{ core::{ - asset::AssetContent, + asset::{Asset, AssetContent}, context::AssetContext, reference_type::{EntryReferenceSubType, ReferenceType}, source::Source, virtual_source::VirtualSource, }, - ecmascript::{chunk::EcmascriptChunkPlaceable, utils::StringifyJs}, + ecmascript::chunk::EcmascriptChunkPlaceable, }, }; use crate::{ next_edge::entry::wrap_edge_entry, - util::{load_next_js_template, virtual_next_js_template_path, NextRuntime}, + util::{file_content_rope, load_next_js_template, NextRuntime}, }; #[turbo_tasks::function] @@ -36,8 +36,8 @@ pub async fn create_page_ssr_entry_module( next_original_name: Vc, runtime: NextRuntime, ) -> Result>> { - let definition_page = next_original_name.await?; - let definition_pathname = pathname.await?; + let definition_page = &*next_original_name.await?; + let definition_pathname = &*pathname.await?; let ssr_module = ssr_module_context.process(source, reference_type.clone()); @@ -59,64 +59,57 @@ pub async fn create_page_ssr_entry_module( _ => bail!("Invalid path type"), }; - // Load the file from the next.js codebase. - let file = load_next_js_template(project_root, template_file.to_string()).await?; - - let mut file = file - .to_str()? - .replace( - "\"VAR_DEFINITION_PAGE\"", - &StringifyJs(&definition_page).to_string(), - ) - .replace( - "\"VAR_DEFINITION_PATHNAME\"", - &StringifyJs(&definition_pathname).to_string(), - ); - - if reference_type == ReferenceType::Entry(EntryReferenceSubType::Page) { - file = file - .replace( - "\"VAR_MODULE_DOCUMENT\"", - &StringifyJs("@vercel/turbopack-next/pages/_document").to_string(), - ) - .replace( - "\"VAR_MODULE_APP\"", - &StringifyJs("@vercel/turbopack-next/pages/_app").to_string(), - ); - } - - // Ensure that the last line is a newline. - if !file.ends_with('\n') { - file.push('\n'); - } + const INNER: &str = "INNER_PAGE"; - let mut result = RopeBuilder::default(); - result.push_bytes(file.as_bytes()); + let mut replacements = indexmap! { + "VAR_DEFINITION_PAGE" => definition_page.clone(), + "VAR_DEFINITION_PATHNAME" => definition_pathname.clone(), + "VAR_USERLAND" => INNER.to_string(), + }; if reference_type == ReferenceType::Entry(EntryReferenceSubType::Page) { - // When we're building the instrumentation page (only when the - // instrumentation file conflicts with a page also labeled - // /instrumentation) hoist the `register` method. - if definition_page.to_string() == "/instrumentation" - || definition_page.to_string() == "/src/instrumentation" - { - writeln!( - result, - r#"export const register = hoist(userland, "register")"# - )?; - } + replacements.insert( + "VAR_MODULE_DOCUMENT", + "@vercel/turbopack-next/pages/_document".to_string(), + ); + replacements.insert( + "VAR_MODULE_APP", + "@vercel/turbopack-next/pages/_app".to_string(), + ); } - let file = File::from(result.build()); - - let template_path = virtual_next_js_template_path(project_root, template_file.to_string()); - - let source = VirtualSource::new(template_path, AssetContent::file(file.into())); + // Load the file from the next.js codebase. + let mut source = + load_next_js_template(template_file, project_root, replacements, indexmap! {}).await?; + + // When we're building the instrumentation page (only when the + // instrumentation file conflicts with a page also labeled + // /instrumentation) hoist the `register` method. + if reference_type == ReferenceType::Entry(EntryReferenceSubType::Page) + && (*definition_page == "/instrumentation" || *definition_page == "/src/instrumentation") + { + let file = &*file_content_rope(source.content().file_content()).await?; + + let mut result = RopeBuilder::default(); + result += file; + + writeln!( + result, + r#"export const register = hoist(userland, "register")"# + )?; + + let file = File::from(result.build()); + + source = Vc::upcast(VirtualSource::new( + source.ident().path(), + AssetContent::file(file.into()), + )); + } let mut ssr_module = ssr_module_context.process( - Vc::upcast(source), + source, Value::new(ReferenceType::Internal(Vc::cell(indexmap! { - "VAR_USERLAND".to_string() => ssr_module, + INNER.to_string() => ssr_module, }))), ); diff --git a/packages/next-swc/crates/next-core/src/util.rs b/packages/next-swc/crates/next-core/src/util.rs index 374d27551f76..6b1479255a09 100644 --- a/packages/next-swc/crates/next-core/src/util.rs +++ b/packages/next-swc/crates/next-core/src/util.rs @@ -1,21 +1,26 @@ -use anyhow::{bail, Result}; +use anyhow::{bail, Context, Result}; +use indexmap::{IndexMap, IndexSet}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde_json::Value as JsonValue; use swc_core::ecma::ast::Program; use turbo_tasks::{trace::TraceRawVcs, TaskInput, ValueDefault, ValueToString, Vc}; -use turbo_tasks_fs::rope::Rope; +use turbo_tasks_fs::{rope::Rope, util::join_path, File}; use turbopack_binding::{ turbo::tasks_fs::{json::parse_json_rope_with_source_context, FileContent, FileSystemPath}, turbopack::{ core::{ + asset::AssetContent, environment::{ServerAddr, ServerInfo}, ident::AssetIdent, issue::{Issue, IssueExt, IssueSeverity}, module::Module, + source::Source, + virtual_source::VirtualSource, }, ecmascript::{ analyzer::{JsValue, ObjectPart}, parse::ParseResult, + utils::StringifyJs, EcmascriptModuleAsset, }, turbopack::condition::ContextCondition, @@ -347,14 +352,202 @@ fn parse_config_from_js_value(module: Vc>, value: &JsValue) -> N config } -#[turbo_tasks::function] +/// Loads a next.js template, replaces `replacements` and `injections` and makes +/// sure there are none left over. +// TODO: should this be a turbo tasks function? +// #[turbo_tasks::function] pub async fn load_next_js_template( + path: &str, project_path: Vc, - file: String, -) -> Result> { - let file_path = virtual_next_js_template_path(project_path, file); + replacements: IndexMap<&'static str, String>, + injections: IndexMap<&'static str, String>, +) -> Result>> { + let path = virtual_next_js_template_path(project_path, path.to_string()); + + let content = &*file_content_rope(path.read()).await?; + let content = content.to_str()?.to_string(); + + let parent_path = path.parent(); + let parent_path_value = &*parent_path.await?; + + let package_root = get_next_package(project_path).parent(); + let package_root_value = &*package_root.await?; + + /// See [regex::Regex::replace_all]. + fn replace_all( + re: ®ex::Regex, + haystack: &str, + mut replacement: impl FnMut(®ex::Captures) -> Result, + ) -> Result { + let mut new = String::with_capacity(haystack.len()); + let mut last_match = 0; + for caps in re.captures_iter(haystack) { + let m = caps.get(0).unwrap(); + new.push_str(&haystack[last_match..m.start()]); + new.push_str(&replacement(&caps)?); + last_match = m.end(); + } + new.push_str(&haystack[last_match..]); + Ok(new) + } - let content = &*file_path.read().await?; + // Update the relative imports to be absolute. This will update any relative + // imports to be relative to the root of the `next` package. + let regex = lazy_regex::regex!("(?:from \"(\\..*)\"|import \"(\\..*)\")"); + + let mut count = 0; + let mut content = replace_all(regex, &content, |caps| { + let from_request = caps.get(1).map_or("", |c| c.as_str()); + let import_request = caps.get(2).map_or("", |c| c.as_str()); + + count += 1; + let is_from_request = !from_request.is_empty(); + + let imported = FileSystemPath { + fs: package_root_value.fs, + path: join_path( + &parent_path_value.path, + if is_from_request { + from_request + } else { + import_request + }, + ) + .context("path should not leave the fs")?, + }; + + let relative = package_root_value + .get_relative_path_to(&imported) + .context("path has to be relative to package root")?; + + if !relative.starts_with("./next/") { + bail!( + "Invariant: Expected relative import to start with \"./next/\", found \"{}\"", + relative + ) + } + + let relative = relative + .strip_prefix("./") + .context("should be able to strip the prefix")?; + + Ok(if is_from_request { + format!("from {}", StringifyJs(relative)) + } else { + format!("import {}", StringifyJs(relative)) + }) + }) + .context("replacing imports failed")?; + + // Verify that at least one import was replaced. It's the case today where + // every template file has at least one import to update, so this ensures that + // we don't accidentally remove the import replacement code or use the wrong + // template file. + if count == 0 { + bail!("Invariant: Expected to replace at least one import") + } + + // Replace all the template variables with the actual values. If a template + // variable is missing, throw an error. + let mut replaced = IndexSet::new(); + for (key, replacement) in &replacements { + let full = format!("\"{}\"", key); + + if content.contains(&full) { + replaced.insert(*key); + content = content.replace(&full, &StringifyJs(&replacement).to_string()); + } + } + + // Check to see if there's any remaining template variables. + let regex = lazy_regex::regex!("/VAR_[A-Z_]+"); + let matches = regex + .find_iter(&content) + .map(|m| m.as_str().to_string()) + .collect::>(); + + if !matches.is_empty() { + bail!( + "Invariant: Expected to replace all template variables, found {}", + matches.join(", "), + ) + } + + // Check to see if any template variable was provided but not used. + if replaced.len() != replacements.len() { + // Find the difference between the provided replacements and the replaced + // template variables. This will let us notify the user of any template + // variables that were not used but were provided. + let difference = replacements + .keys() + .filter(|k| !replaced.contains(*k)) + .cloned() + .collect::>(); + + bail!( + "Invariant: Expected to replace all template variables, missing {} in template", + difference.join(", "), + ) + } + + // Replace the injections. + let mut injected = IndexSet::new(); + for (key, injection) in &injections { + let full = format!("// INJECT:{}", key); + + if content.contains(&full) { + // Track all the injections to ensure that we're not missing any. + injected.insert(*key); + content = content.replace(&full, &format!("const {} = {}", key, injection)); + } + } + + // Check to see if there's any remaining injections. + let regex = lazy_regex::regex!("// INJECT:[A-Za-z0-9_]+"); + let matches = regex + .find_iter(&content) + .map(|m| m.as_str().to_string()) + .collect::>(); + + if !matches.is_empty() { + bail!( + "Invariant: Expected to inject all injections, found {}", + matches.join(", "), + ) + } + + // Check to see if any injection was provided but not used. + if injected.len() != injections.len() { + // Find the difference between the provided replacements and the replaced + // template variables. This will let us notify the user of any template + // variables that were not used but were provided. + let difference = injections + .keys() + .filter(|k| !injected.contains(*k)) + .cloned() + .collect::>(); + + bail!( + "Invariant: Expected to inject all injections, missing {} in template", + difference.join(", "), + ) + } + + // Ensure that the last line is a newline. + if !content.ends_with('\n') { + content.push('\n'); + } + + let file = File::from(content); + + let source = VirtualSource::new(path, AssetContent::file(file.into())); + + Ok(Vc::upcast(source)) +} + +#[turbo_tasks::function] +pub async fn file_content_rope(content: Vc) -> Result> { + let content = &*content.await?; let FileContent::Content(file) = content else { bail!("Expected file content for file"); @@ -363,7 +556,6 @@ pub async fn load_next_js_template( Ok(file.content().to_owned().cell()) } -#[turbo_tasks::function] pub fn virtual_next_js_template_path( project_path: Vc, file: String, From 666ce7bd8b08b9616e55f5476a677eaea8fb4e6e Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Thu, 5 Oct 2023 22:05:05 +0200 Subject: [PATCH 06/15] Chunking Refactor Step 1 (#56467) ### What? This change moves a few methods around. Module::as_chunk is moved to ChunkItem::as_chunk as temporary intermediate state. EcmascriptPlaceable::as_chunk_item is moved to ChunkableModule::as_chunk_item. This generalizes the concept of converting a Module into a ChunkItem ### Why? This is the first step of refactoring the chunking. In the end we want to avoid creating chunks from modules directly, but enforce everything going through the ChunkingContext to be chunked. This allows us to replace the existing chunking algorithm with a much more efficient one that avoid duplication between chunks in first place and doesn't require a post-chunking optimization. ### How? see https://github.com/vercel/turbo/pull/6104 Closes WEB-1715 Co-authored-by: Justin Ridgewell <112982+jridgewell@users.noreply.github.com> --- Cargo.lock | 66 +++++++++--------- Cargo.toml | 6 +- packages/next-swc/crates/next-api/src/app.rs | 2 +- .../crates/next-api/src/middleware.rs | 2 +- .../next-swc/crates/next-api/src/pages.rs | 2 +- .../crates/next-api/src/server_actions.rs | 18 +++-- .../next-build/src/next_pages/page_entries.rs | 2 +- .../next_app/app_client_references_chunks.rs | 2 +- .../with_chunking_context_scope_asset.rs | 39 +++-------- .../with_client_chunks.rs | 67 ++++++++++--------- ...cmascript_client_reference_proxy_module.rs | 61 ++++++++++------- .../src/next_dynamic/dynamic_module.rs | 2 +- .../client_reference_manifest.rs | 13 ++-- .../server_component_module.rs | 56 ++++++++++------ .../crates/next-core/src/page_loader.rs | 2 +- packages/next/package.json | 2 +- pnpm-lock.yaml | 10 +-- 17 files changed, 183 insertions(+), 169 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cbe4f11704af..9691bd382677 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -321,7 +321,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "serde", "smallvec", @@ -3515,7 +3515,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "serde", @@ -7368,7 +7368,7 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "async-trait", @@ -7400,7 +7400,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "cargo-lock", @@ -7412,7 +7412,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "bytes", @@ -7427,7 +7427,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "dotenvs", @@ -7441,7 +7441,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7458,7 +7458,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "auto-hash-map", @@ -7488,7 +7488,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "base16", "hex", @@ -7500,7 +7500,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -7514,7 +7514,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "proc-macro2", "quote", @@ -7524,7 +7524,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "mimalloc", ] @@ -7532,7 +7532,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "auto-hash-map", @@ -7557,7 +7557,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "async-recursion", @@ -7588,7 +7588,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "auto-hash-map", "mdxjs", @@ -7628,7 +7628,7 @@ dependencies = [ [[package]] name = "turbopack-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7650,7 +7650,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "clap 4.4.2", @@ -7674,7 +7674,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "async-recursion", @@ -7703,7 +7703,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "async-trait", @@ -7725,7 +7725,7 @@ dependencies = [ [[package]] name = "turbopack-dev" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7749,7 +7749,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "async-compression", @@ -7786,7 +7786,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "async-trait", @@ -7820,7 +7820,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "serde", "serde_json", @@ -7831,7 +7831,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "async-trait", @@ -7854,7 +7854,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "indoc", @@ -7871,7 +7871,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7887,7 +7887,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "base64 0.21.4", @@ -7907,7 +7907,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "serde", @@ -7922,7 +7922,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "mdxjs", @@ -7937,7 +7937,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "async-stream", @@ -7972,7 +7972,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "serde", @@ -7988,7 +7988,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "swc_core", "turbo-tasks", @@ -7999,7 +7999,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231002.1#dc1e2a7a4aa4cbd88c7144bf0bdd4fd0589373c1" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index 5d2d40a9adb0..6bd1c3e77129 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,11 +40,11 @@ swc_core = { version = "0.83.28", features = [ testing = { version = "0.34.1" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231002.1" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231005.2" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231002.1" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231005.2" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231002.1" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231005.2" } # General Deps diff --git a/packages/next-swc/crates/next-api/src/app.rs b/packages/next-swc/crates/next-api/src/app.rs index cd9ac1a0e352..05d7a0008e33 100644 --- a/packages/next-swc/crates/next-api/src/app.rs +++ b/packages/next-swc/crates/next-api/src/app.rs @@ -39,7 +39,7 @@ use turbopack_binding::{ turbopack::{ core::{ asset::{Asset, AssetContent}, - chunk::{ChunkableModule, ChunkingContext, EvaluatableAssets}, + chunk::{ChunkableModuleExt, ChunkingContext, EvaluatableAssets}, file_source::FileSource, output::{OutputAsset, OutputAssets}, virtual_output::VirtualOutputAsset, diff --git a/packages/next-swc/crates/next-api/src/middleware.rs b/packages/next-swc/crates/next-api/src/middleware.rs index b86185ccb80e..b7fedd56befb 100644 --- a/packages/next-swc/crates/next-api/src/middleware.rs +++ b/packages/next-swc/crates/next-api/src/middleware.rs @@ -13,7 +13,7 @@ use turbopack_binding::{ turbopack::{ core::{ asset::AssetContent, - chunk::{ChunkableModule, ChunkingContext}, + chunk::{ChunkableModuleExt, ChunkingContext}, context::AssetContext, module::Module, output::{OutputAsset, OutputAssets}, diff --git a/packages/next-swc/crates/next-api/src/pages.rs b/packages/next-swc/crates/next-api/src/pages.rs index b4e5ec17bc77..e198e346a3e0 100644 --- a/packages/next-swc/crates/next-api/src/pages.rs +++ b/packages/next-swc/crates/next-api/src/pages.rs @@ -37,7 +37,7 @@ use turbopack_binding::{ build::BuildChunkingContext, core::{ asset::AssetContent, - chunk::{ChunkableModule, ChunkingContext, EvaluatableAssets}, + chunk::{ChunkableModuleExt, ChunkingContext, EvaluatableAssets}, context::AssetContext, file_source::FileSource, issue::{IssueSeverity, OptionIssueSource}, diff --git a/packages/next-swc/crates/next-api/src/server_actions.rs b/packages/next-swc/crates/next-api/src/server_actions.rs index 7b0428d5ad39..3ef3583dee0b 100644 --- a/packages/next-swc/crates/next-api/src/server_actions.rs +++ b/packages/next-swc/crates/next-api/src/server_actions.rs @@ -16,13 +16,18 @@ use turbopack_binding::{ turbo::tasks_fs::{rope::RopeBuilder, File, FileSystemPath}, turbopack::{ core::{ - asset::AssetContent, chunk::EvaluatableAsset, context::AssetContext, module::Module, - output::OutputAsset, reference::primary_referenced_modules, - reference_type::ReferenceType, virtual_output::VirtualOutputAsset, + asset::AssetContent, + chunk::{ChunkItemExt, ChunkableModule, EvaluatableAsset}, + context::AssetContext, + module::Module, + output::OutputAsset, + reference::primary_referenced_modules, + reference_type::ReferenceType, + virtual_output::VirtualOutputAsset, virtual_source::VirtualSource, }, ecmascript::{ - chunk::{EcmascriptChunkItemExt, EcmascriptChunkPlaceable, EcmascriptChunkingContext}, + chunk::{EcmascriptChunkPlaceable, EcmascriptChunkingContext}, parse::ParseResult, EcmascriptModuleAsset, }, @@ -72,7 +77,10 @@ pub(crate) async fn create_server_actions_manifest( bail!("loader module must be evaluatable"); }; - let loader_id = loader.as_chunk_item(chunking_context).id().to_string(); + let loader_id = loader + .as_chunk_item(Vc::upcast(chunking_context)) + .id() + .to_string(); let manifest = build_manifest(node_root, pathname, page_name, runtime, actions, loader_id).await?; Ok((Some(evaluable), manifest)) diff --git a/packages/next-swc/crates/next-build/src/next_pages/page_entries.rs b/packages/next-swc/crates/next-build/src/next_pages/page_entries.rs index bbbe6c9ae3fc..1f024e90e1c6 100644 --- a/packages/next-swc/crates/next-build/src/next_pages/page_entries.rs +++ b/packages/next-swc/crates/next-build/src/next_pages/page_entries.rs @@ -27,7 +27,7 @@ use turbopack_binding::{ turbopack::{ build::BuildChunkingContext, core::{ - chunk::{ChunkableModule, ChunkingContext, EvaluatableAssets}, + chunk::{ChunkableModuleExt, ChunkingContext, EvaluatableAssets}, compile_time_info::CompileTimeInfo, context::AssetContext, file_source::FileSource, diff --git a/packages/next-swc/crates/next-core/src/next_app/app_client_references_chunks.rs b/packages/next-swc/crates/next-core/src/next_app/app_client_references_chunks.rs index 554b11e92e40..ea67efab3a44 100644 --- a/packages/next-swc/crates/next-core/src/next_app/app_client_references_chunks.rs +++ b/packages/next-swc/crates/next-core/src/next_app/app_client_references_chunks.rs @@ -5,7 +5,7 @@ use turbo_tasks::{debug::ValueDebugFormat, trace::TraceRawVcs, TryJoinIterExt, V use turbopack_binding::turbopack::{ build::BuildChunkingContext, core::{ - chunk::{ChunkableModule, ChunkingContext}, + chunk::{ChunkableModuleExt, ChunkingContext}, output::OutputAssets, }, ecmascript::chunk::EcmascriptChunkingContext, diff --git a/packages/next-swc/crates/next-core/src/next_client_component/with_chunking_context_scope_asset.rs b/packages/next-swc/crates/next-core/src/next_client_component/with_chunking_context_scope_asset.rs index f8cede2ba285..694db16ba4d1 100644 --- a/packages/next-swc/crates/next-core/src/next_client_component/with_chunking_context_scope_asset.rs +++ b/packages/next-swc/crates/next-core/src/next_client_component/with_chunking_context_scope_asset.rs @@ -1,17 +1,13 @@ -use anyhow::{Context, Result}; -use turbo_tasks::{Value, Vc}; +use turbo_tasks::Vc; use turbopack_binding::turbopack::{ core::{ asset::{Asset, AssetContent}, - chunk::{availability_info::AvailabilityInfo, Chunk, ChunkableModule, ChunkingContext}, + chunk::{ChunkableModule, ChunkingContext}, ident::AssetIdent, module::Module, reference::ModuleReferences, }, - ecmascript::chunk::EcmascriptChunkingContext, - turbopack::ecmascript::chunk::{ - EcmascriptChunk, EcmascriptChunkItem, EcmascriptChunkPlaceable, EcmascriptExports, - }, + turbopack::ecmascript::chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, }; #[turbo_tasks::function] @@ -49,38 +45,19 @@ impl Asset for WithChunkingContextScopeAsset { #[turbo_tasks::value_impl] impl ChunkableModule for WithChunkingContextScopeAsset { #[turbo_tasks::function] - fn as_chunk( + fn as_chunk_item( &self, - context: Vc>, - availability_info: Value, - ) -> Vc> { - Vc::upcast(EcmascriptChunk::new( - context.with_layer(self.layer.clone()), + chunking_context: Vc>, + ) -> Vc> { + Vc::upcast(ChunkableModule::as_chunk_item( self.asset, - availability_info, + chunking_context.with_layer(self.layer.clone()), )) } } #[turbo_tasks::value_impl] impl EcmascriptChunkPlaceable for WithChunkingContextScopeAsset { - #[turbo_tasks::function] - async fn as_chunk_item( - &self, - context: Vc>, - ) -> Result>> { - Ok(self.asset.as_chunk_item( - Vc::try_resolve_sidecast::>( - context.with_layer(self.layer.clone()), - ) - .await? - .context( - "ChunkingContext::with_layer should not return a different kind of chunking \ - context", - )?, - )) - } - #[turbo_tasks::function] fn get_exports(&self) -> Vc { self.asset.get_exports() diff --git a/packages/next-swc/crates/next-core/src/next_client_component/with_client_chunks.rs b/packages/next-swc/crates/next-core/src/next_client_component/with_client_chunks.rs index 87779c061e8b..d5499cc0de81 100644 --- a/packages/next-swc/crates/next-core/src/next_client_component/with_client_chunks.rs +++ b/packages/next-swc/crates/next-core/src/next_client_component/with_client_chunks.rs @@ -7,9 +7,9 @@ use turbopack_binding::{ core::{ asset::{Asset, AssetContent}, chunk::{ - availability_info::AvailabilityInfo, Chunk, ChunkData, ChunkItem, ChunkableModule, - ChunkableModuleReference, ChunkingContext, ChunkingType, ChunkingTypeOption, - ChunksData, + availability_info::AvailabilityInfo, Chunk, ChunkData, ChunkItem, ChunkItemExt, + ChunkableModule, ChunkableModuleExt, ChunkableModuleReference, ChunkingContext, + ChunkingType, ChunkingTypeOption, ChunksData, }, ident::AssetIdent, module::Module, @@ -18,7 +18,7 @@ use turbopack_binding::{ reference::{ModuleReference, ModuleReferences, SingleOutputAssetReference}, resolve::ModuleResolveResult, }, - ecmascript::chunk::{EcmascriptChunkData, EcmascriptChunkItemExt}, + ecmascript::chunk::EcmascriptChunkData, turbopack::ecmascript::{ chunk::{ EcmascriptChunk, EcmascriptChunkItem, EcmascriptChunkItemContent, @@ -68,43 +68,30 @@ impl Asset for WithClientChunksAsset { #[turbo_tasks::value_impl] impl ChunkableModule for WithClientChunksAsset { - #[turbo_tasks::function] - fn as_chunk( - self: Vc, - context: Vc>, - availability_info: Value, - ) -> Vc> { - Vc::upcast(EcmascriptChunk::new( - context.with_layer("rsc".to_string()), - Vc::upcast(self), - availability_info, - )) - } -} - -#[turbo_tasks::value_impl] -impl EcmascriptChunkPlaceable for WithClientChunksAsset { #[turbo_tasks::function] async fn as_chunk_item( self: Vc, - context: Vc>, - ) -> Result>> { + chunking_context: Vc>, + ) -> Result>> { + let context = Vc::try_resolve_sidecast::>( + chunking_context.with_layer("rsc".to_string()), + ) + .await? + .context( + "ChunkingContext::with_layer should not return a different kind of chunking context", + )?; Ok(Vc::upcast( WithClientChunksChunkItem { - context: Vc::try_resolve_sidecast::>( - context.with_layer("rsc".to_string()), - ) - .await? - .context( - "ChunkingContext::with_layer should not return a different kind of chunking \ - context", - )?, + context, inner: self, } .cell(), )) } +} +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for WithClientChunksAsset { #[turbo_tasks::function] fn get_exports(&self) -> Vc { // TODO This should be EsmExports @@ -183,7 +170,11 @@ impl EcmascriptChunkItem for WithClientChunksChunkItem { .map(|chunk_data| EcmascriptChunkData::new(chunk_data)) .collect(); - let module_id = inner.asset.as_chunk_item(this.context).id().await?; + let module_id = inner + .asset + .as_chunk_item(Vc::upcast(this.context)) + .id() + .await?; Ok(EcmascriptChunkItemContent { inner_code: formatdoc!( // We store the chunks in a binding, otherwise a new array would be created every @@ -243,6 +234,20 @@ impl ChunkItem for WithClientChunksChunkItem { } Ok(Vc::cell(references)) } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.context) + } + + #[turbo_tasks::function] + fn as_chunk(&self, availability_info: Value) -> Vc> { + Vc::upcast(EcmascriptChunk::new( + Vc::upcast(self.context.with_layer("rsc".to_string())), + Vc::upcast(self.inner), + availability_info, + )) + } } #[turbo_tasks::value] diff --git a/packages/next-swc/crates/next-core/src/next_client_reference/ecmascript_client_reference/ecmascript_client_reference_proxy_module.rs b/packages/next-swc/crates/next-core/src/next_client_reference/ecmascript_client_reference/ecmascript_client_reference_proxy_module.rs index b4adf43c325e..fe3c06999ff3 100644 --- a/packages/next-swc/crates/next-core/src/next_client_reference/ecmascript_client_reference/ecmascript_client_reference_proxy_module.rs +++ b/packages/next-swc/crates/next-core/src/next_client_reference/ecmascript_client_reference/ecmascript_client_reference_proxy_module.rs @@ -1,6 +1,6 @@ use std::{io::Write, iter::once}; -use anyhow::{bail, Result}; +use anyhow::{bail, Context, Result}; use indoc::writedoc; use turbo_tasks::{Value, ValueToString, Vc}; use turbo_tasks_fs::File; @@ -85,7 +85,7 @@ impl EcmascriptClientReferenceProxyModule { // and the $$typeof value is for rendering logic to determine if the module // is a client boundary. const {{ __esModule, $$typeof }} = proxy; - + export {{ __esModule, $$typeof }}; export default proxy; "#, @@ -164,36 +164,35 @@ impl Asset for EcmascriptClientReferenceProxyModule { #[turbo_tasks::value_impl] impl ChunkableModule for EcmascriptClientReferenceProxyModule { #[turbo_tasks::function] - fn as_chunk( + async fn as_chunk_item( self: Vc, - context: Vc>, - availability_info: Value, - ) -> Vc> { - Vc::upcast(EcmascriptChunk::new( - context, - Vc::upcast(self), - availability_info, - )) - } -} + chunking_context: Vc>, + ) -> Result>> { + let item = self.proxy_module().as_chunk_item(chunking_context); + let ecmascript_item = Vc::try_resolve_downcast::>(item) + .await? + .context("EcmascriptModuleAsset must implement EcmascriptChunkItem")?; + let chunking_context = + Vc::try_resolve_downcast::>(chunking_context) + .await? + .context( + "chunking context must impl EcmascriptChunkingContext to use \ + EcmascriptClientReferenceProxyModule", + )?; -#[turbo_tasks::value_impl] -impl EcmascriptChunkPlaceable for EcmascriptClientReferenceProxyModule { - #[turbo_tasks::function] - fn as_chunk_item( - self: Vc, - chunking_context: Vc>, - ) -> Vc> { - Vc::upcast( + Ok(Vc::upcast( ProxyModuleChunkItem { client_proxy_asset: self, - inner_proxy_module_chunk_item: self.proxy_module().as_chunk_item(chunking_context), + inner_proxy_module_chunk_item: ecmascript_item, chunking_context, } .cell(), - ) + )) } +} +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for EcmascriptClientReferenceProxyModule { #[turbo_tasks::function] fn get_exports(self: Vc) -> Vc { self.proxy_module().get_exports() @@ -232,6 +231,20 @@ impl ChunkItem for ProxyModuleChunkItem { fn references(&self) -> Vc { self.client_proxy_asset.references() } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + fn as_chunk(&self, availability_info: Value) -> Vc> { + Vc::upcast(EcmascriptChunk::new( + Vc::upcast(self.chunking_context), + Vc::upcast(self.client_proxy_asset), + availability_info, + )) + } } #[turbo_tasks::value_impl] @@ -252,6 +265,6 @@ impl EcmascriptChunkItem for ProxyModuleChunkItem { #[turbo_tasks::function] fn chunking_context(&self) -> Vc> { - self.inner_proxy_module_chunk_item.chunking_context() + EcmascriptChunkItem::chunking_context(self.inner_proxy_module_chunk_item) } } diff --git a/packages/next-swc/crates/next-core/src/next_dynamic/dynamic_module.rs b/packages/next-swc/crates/next-core/src/next_dynamic/dynamic_module.rs index b4fe032aa82d..b5cd908992b6 100644 --- a/packages/next-swc/crates/next-core/src/next_dynamic/dynamic_module.rs +++ b/packages/next-swc/crates/next-core/src/next_dynamic/dynamic_module.rs @@ -2,7 +2,7 @@ use anyhow::{bail, Result}; use turbo_tasks::Vc; use turbopack_binding::turbopack::core::{ asset::{Asset, AssetContent}, - chunk::{ChunkableModule, ChunkingContext}, + chunk::{ChunkableModule, ChunkableModuleExt, ChunkingContext}, ident::AssetIdent, module::Module, output::OutputAssets, diff --git a/packages/next-swc/crates/next-core/src/next_manifests/client_reference_manifest.rs b/packages/next-swc/crates/next-core/src/next_manifests/client_reference_manifest.rs index 527f588da1c3..f99625cec5e2 100644 --- a/packages/next-swc/crates/next-core/src/next_manifests/client_reference_manifest.rs +++ b/packages/next-swc/crates/next-core/src/next_manifests/client_reference_manifest.rs @@ -4,13 +4,12 @@ use turbo_tasks::{TryJoinIterExt, ValueToString, Vc}; use turbo_tasks_fs::{File, FileSystemPath}; use turbopack_binding::turbopack::{ core::{ - asset::AssetContent, chunk::ModuleId as TurbopackModuleId, output::OutputAsset, + asset::AssetContent, + chunk::{ChunkItemExt, ChunkableModule, ModuleId as TurbopackModuleId}, + output::OutputAsset, virtual_output::VirtualOutputAsset, }, - ecmascript::{ - chunk::{EcmascriptChunkItemExt, EcmascriptChunkPlaceable, EcmascriptChunkingContext}, - utils::StringifyJs, - }, + ecmascript::{chunk::EcmascriptChunkingContext, utils::StringifyJs}, }; use super::{ClientReferenceManifest, ManifestNode, ManifestNodeEntry, ModuleId}; @@ -117,12 +116,12 @@ impl ClientReferenceManifest { let client_module_id = ecmascript_client_reference .client_module - .as_chunk_item(client_chunking_context) + .as_chunk_item(Vc::upcast(client_chunking_context)) .id() .await?; let ssr_module_id = ecmascript_client_reference .ssr_module - .as_chunk_item(ssr_chunking_context) + .as_chunk_item(Vc::upcast(ssr_chunking_context)) .id() .await?; diff --git a/packages/next-swc/crates/next-core/src/next_server_component/server_component_module.rs b/packages/next-swc/crates/next-core/src/next_server_component/server_component_module.rs index f5253735faa9..bd89ee608195 100644 --- a/packages/next-swc/crates/next-core/src/next_server_component/server_component_module.rs +++ b/packages/next-swc/crates/next-core/src/next_server_component/server_component_module.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, Result}; +use anyhow::{bail, Context, Result}; use indoc::formatdoc; use turbo_tasks::{Value, Vc}; use turbo_tasks_fs::FileSystemPath; @@ -6,13 +6,13 @@ use turbopack_binding::turbopack::{ core::{ asset::{Asset, AssetContent}, chunk::{ - availability_info::AvailabilityInfo, Chunk, ChunkItem, ChunkableModule, ChunkingContext, + availability_info::AvailabilityInfo, Chunk, ChunkItem, ChunkItemExt, ChunkableModule, + ChunkingContext, }, ident::AssetIdent, module::Module, reference::ModuleReferences, }, - ecmascript::chunk::EcmascriptChunkItemExt, turbopack::ecmascript::{ chunk::{ EcmascriptChunk, EcmascriptChunkItem, EcmascriptChunkItemContent, @@ -73,27 +73,18 @@ impl Asset for NextServerComponentModule { #[turbo_tasks::value_impl] impl ChunkableModule for NextServerComponentModule { - #[turbo_tasks::function] - fn as_chunk( - self: Vc, - context: Vc>, - availability_info: Value, - ) -> Vc> { - Vc::upcast(EcmascriptChunk::new( - context, - Vc::upcast(self), - availability_info, - )) - } -} - -#[turbo_tasks::value_impl] -impl EcmascriptChunkPlaceable for NextServerComponentModule { #[turbo_tasks::function] async fn as_chunk_item( self: Vc, - context: Vc>, - ) -> Result>> { + chunking_context: Vc>, + ) -> Result>> { + let context = + Vc::try_resolve_downcast::>(chunking_context) + .await? + .context( + "chunking context must impl EcmascriptChunkingContext to use \ + NextServerComponentModule", + )?; Ok(Vc::upcast( BuildServerComponentChunkItem { context, @@ -102,7 +93,10 @@ impl EcmascriptChunkPlaceable for NextServerComponentModule { .cell(), )) } +} +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for NextServerComponentModule { #[turbo_tasks::function] fn get_exports(&self) -> Vc { // TODO This should be EsmExports @@ -128,7 +122,11 @@ impl EcmascriptChunkItem for BuildServerComponentChunkItem { let this = self.await?; let inner = this.inner.await?; - let module_id = inner.module.as_chunk_item(this.context).id().await?; + let module_id = inner + .module + .as_chunk_item(Vc::upcast(this.context)) + .id() + .await?; Ok(EcmascriptChunkItemContent { inner_code: formatdoc!( r#" @@ -156,4 +154,18 @@ impl ChunkItem for BuildServerComponentChunkItem { fn references(&self) -> Vc { self.inner.references() } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.context) + } + + #[turbo_tasks::function] + fn as_chunk(&self, availability_info: Value) -> Vc> { + Vc::upcast(EcmascriptChunk::new( + Vc::upcast(self.context), + Vc::upcast(self.inner), + availability_info, + )) + } } diff --git a/packages/next-swc/crates/next-core/src/page_loader.rs b/packages/next-swc/crates/next-core/src/page_loader.rs index b1f37a0d5c59..56d240b1a476 100644 --- a/packages/next-swc/crates/next-core/src/page_loader.rs +++ b/packages/next-swc/crates/next-core/src/page_loader.rs @@ -10,7 +10,7 @@ use turbopack_binding::{ core::{ asset::{Asset, AssetContent}, chunk::{ - ChunkData, ChunkableModule, ChunkingContext, ChunksData, EvaluatableAsset, + ChunkData, ChunkableModuleExt, ChunkingContext, ChunksData, EvaluatableAsset, EvaluatableAssets, }, context::AssetContext, diff --git a/packages/next/package.json b/packages/next/package.json index fc8b1aabde29..85d14ea8518d 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -191,7 +191,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.22.6", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231002.1", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231005.2", "acorn": "8.5.0", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5237d8843b00..7f6605037d31 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1058,8 +1058,8 @@ importers: specifier: 0.22.6 version: 0.22.6 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231002.1 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231002.1(react-refresh@0.12.0)(webpack@5.86.0)' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231005.2 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231005.2(react-refresh@0.12.0)(webpack@5.86.0)' acorn: specifier: 8.5.0 version: 8.5.0 @@ -26762,9 +26762,9 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231002.1(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231002.1} - id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231002.1' + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231005.2(react-refresh@0.12.0)(webpack@5.86.0)': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231005.2} + id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231005.2' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: From 35e45393048082b8aa1f4b0e2727cb8a6b55827e Mon Sep 17 00:00:00 2001 From: Will Binns-Smith Date: Thu, 5 Oct 2023 15:01:45 -0700 Subject: [PATCH 07/15] Use native node:fs in taskfile.js (#56491) This is the first in a series of PRs replacing our use of fs-extra with node's own `node:fs`. Test Plan: With clean and existing artifacts in each case, ran: - `pnpm build` - `pnpm dev` - `./node_modules/.bin/taskr ncc` Closes WEB-1717 --- .../src/compiled/babel-packages/package.json | 2 +- .../constants-browserify/package.json | 2 +- packages/next/taskfile.js | 175 ++++++++++-------- 3 files changed, 98 insertions(+), 81 deletions(-) diff --git a/packages/next/src/compiled/babel-packages/package.json b/packages/next/src/compiled/babel-packages/package.json index bd756542b973..96340f93f599 100644 --- a/packages/next/src/compiled/babel-packages/package.json +++ b/packages/next/src/compiled/babel-packages/package.json @@ -1 +1 @@ -{"name":"babel-packages","main":"./packages-bundle.js"} \ No newline at end of file +{"name":"babel-packages","main":"./packages-bundle.js"} diff --git a/packages/next/src/compiled/constants-browserify/package.json b/packages/next/src/compiled/constants-browserify/package.json index bf04940e17e9..eddc7606b465 100644 --- a/packages/next/src/compiled/constants-browserify/package.json +++ b/packages/next/src/compiled/constants-browserify/package.json @@ -1 +1 @@ -{"name":"constants-browserify","main":"./constants.json"} \ No newline at end of file +{"name":"constants-browserify","main":"./constants.json"} diff --git a/packages/next/taskfile.js b/packages/next/taskfile.js index 63e40bf4e59a..ba2614d05855 100644 --- a/packages/next/taskfile.js +++ b/packages/next/taskfile.js @@ -2,7 +2,7 @@ const { relative, basename, resolve, join, dirname } = require('path') // eslint-disable-next-line import/no-extraneous-dependencies const glob = require('glob') // eslint-disable-next-line import/no-extraneous-dependencies -const fs = require('fs-extra') +const fs = require('fs/promises') // eslint-disable-next-line import/no-extraneous-dependencies const resolveFrom = require('resolve-from') const execa = require('execa') @@ -44,7 +44,7 @@ export async function copy_styled_jsx_assets(task, opts) { // Separate type files into different folders to avoid conflicts between // dev dep `styled-jsx` and `next/dist/styled-jsx` for duplicated declare modules const typesDir = join(outputDir, 'types') - await fs.ensureDir(typesDir) + await fs.mkdir(typesDir, { recursive: true }) for (const file of typeFiles) { const content = await fs.readFile(join(styledJsxPath, file), 'utf8') @@ -118,7 +118,7 @@ export async function capsize_metrics() { 'dist/server/capsize-font-metrics.json' ) - await fs.outputJson(outputPathDist, entireMetricsCollection, { spaces: 2 }) + await writeJson(outputPathDist, entireMetricsCollection, { spaces: 2 }) } // eslint-disable-next-line camelcase @@ -135,10 +135,10 @@ export async function copy_babel_runtime(task, opts) { const inputPath = join(runtimeDir, file) const outputPath = join(outputDir, file) - if (!fs.statSync(inputPath).isFile()) { + if (!(await fs.stat(inputPath)).isFile()) { continue } - let contents = fs.readFileSync(inputPath, 'utf8') + let contents = await fs.readFile(inputPath, 'utf8') if (inputPath.endsWith('.js')) { contents = contents @@ -156,8 +156,8 @@ export async function copy_babel_runtime(task, opts) { }) } - fs.mkdirSync(dirname(outputPath), { recursive: true }) - fs.writeFileSync(outputPath, contents) + await fs.mkdir(dirname(outputPath), { recursive: true }) + await fs.writeFile(outputPath, contents) } } @@ -224,26 +224,23 @@ export async function copy_vercel_og(task, opts) { }) .target('src/compiled/@vercel/og') - await fs.writeFile( + await writeJson( join(__dirname, 'src/compiled/@vercel/og/package.json'), - JSON.stringify( - { - name: '@vercel/og', - LICENSE: 'MLP-2.0', - type: 'module', - main: './index.node.js', - exports: { - '.': { - 'edge-light': './index.edge.js', - import: './index.node.js', - node: './index.node.js', - default: './index.node.js', - }, + { + name: '@vercel/og', + LICENSE: 'MLP-2.0', + type: 'module', + main: './index.node.js', + exports: { + '.': { + 'edge-light': './index.edge.js', + import: './index.node.js', + node: './index.node.js', + default: './index.node.js', }, }, - null, - 2 - ) + }, + { spaces: 2 } ) } @@ -304,10 +301,10 @@ export async function ncc_node_platform(task, opts) { .target('src/compiled/platform') const clientFile = join(__dirname, 'src/compiled/platform/platform.js') - const content = fs.readFileSync(clientFile, 'utf8') + const content = await fs.readFile(clientFile, 'utf8') // remove AMD define branch as this forces the module to not // be treated as commonjs - fs.writeFileSync( + await fs.writeFile( clientFile, content.replace( new RegExp( @@ -354,23 +351,24 @@ export async function ncc_edge_runtime_cookies() { // `@edge-runtime/cookies` is precompiled and pre-bundled // so we vendor the package as it is. const dest = 'src/compiled/@edge-runtime/cookies' - const pkg = await fs.readJson( + const pkg = await readJson( require.resolve('@edge-runtime/cookies/package.json') ) - await fs.remove(dest) + await rmrf(dest) + await fs.mkdir(dest, { recursive: true }) - await fs.outputJson(join(dest, 'package.json'), { + await writeJson(join(dest, 'package.json'), { name: '@edge-runtime/cookies', version: pkg.version, main: './index.js', license: pkg.license, }) - await fs.copy( + await fs.cp( require.resolve('@edge-runtime/cookies/dist/index.js'), join(dest, 'index.js') ) - await fs.copy( + await fs.cp( require.resolve('@edge-runtime/cookies/dist/index.d.ts'), join(dest, 'index.d.ts') ) @@ -384,34 +382,34 @@ export async function ncc_edge_runtime_primitives() { // `@edge-runtime/primitives` is precompiled and pre-bundled // so we vendor the package as it is. const dest = 'src/compiled/@edge-runtime/primitives' - await fs.mkdirp(dest) + await fs.mkdir(dest, { recursive: true }) const primitivesPath = dirname( require.resolve('@edge-runtime/primitives/package.json') ) - const pkg = await fs.readJson( + const pkg = await readJson( require.resolve('@edge-runtime/primitives/package.json') ) - await fs.remove(dest) + await rmrf(dest) for (const file of await fs.readdir(join(primitivesPath, 'types'))) { - await fs.copy(join(primitivesPath, 'types', file), join(dest, file)) + await fs.cp(join(primitivesPath, 'types', file), join(dest, file)) } for (const file of await fs.readdir(join(primitivesPath, 'dist'))) { - await fs.copy(join(primitivesPath, 'dist', file), join(dest, file)) + await fs.cp(join(primitivesPath, 'dist', file), join(dest, file)) } - await fs.outputJson(join(dest, 'package.json'), { + await writeJson(join(dest, 'package.json'), { name: '@edge-runtime/primitives', version: pkg.version, main: './index.js', license: pkg.license, }) - await fs.copy( + await fs.cp( require.resolve('@edge-runtime/primitives'), join(dest, 'index.js') ) - await fs.copy( + await fs.cp( require.resolve('@edge-runtime/primitives/types/index.d.ts'), join(dest, 'index.d.ts') ) @@ -425,23 +423,25 @@ export async function ncc_edge_runtime_ponyfill(task, opts) { require.resolve('@edge-runtime/ponyfill/src/index.js'), 'utf8' ) - await fs.outputFile( - 'src/compiled/@edge-runtime/ponyfill/index.js', + const dest = 'src/compiled/@edge-runtime/ponyfill' + await fs.mkdir(dest, { recursive: true }) + await fs.writeFile( + join(dest, 'index.js'), indexFile.replace( `require('@edge-runtime/primitives')`, `require(${JSON.stringify(externals['@edge-runtime/primitives'])})` ) ) - await fs.copy( + await fs.cp( require.resolve('@edge-runtime/ponyfill/src/index.d.ts'), - 'src/compiled/@edge-runtime/ponyfill/index.d.ts' + join(dest, 'index.d.ts') ) - const pkg = await fs.readJson( + const pkg = await readJson( require.resolve('@edge-runtime/ponyfill/package.json') ) - await fs.outputJson('src/compiled/@edge-runtime/ponyfill/package.json', { + await writeJson(join(dest, 'package.json'), { name: '@edge-runtime/ponyfill', version: pkg.version, main: './index.js', @@ -529,10 +529,10 @@ export async function ncc_next__react_dev_overlay(task, opts) { __dirname, 'dist/compiled/@next/react-dev-overlay/dist/client.js' ) - const content = fs.readFileSync(clientFile, 'utf8') + const content = await fs.readFile(clientFile, 'utf8') // remove AMD define branch as this forces the module to not // be treated as commonjs - fs.writeFileSync( + await fs.writeFile( clientFile, content.replace( new RegExp( @@ -552,10 +552,10 @@ export async function ncc_next_font(task, opts) { // `@next/font` can be copied as is, its only dependency is already NCCed const destDir = join(__dirname, 'dist/compiled/@next/font') const pkgPath = require.resolve('@next/font/package.json') - const pkg = await fs.readJson(pkgPath) + const pkg = await readJson(pkgPath) const srcDir = dirname(pkgPath) - await fs.remove(destDir) - await fs.ensureDir(destDir) + await rmrf(destDir) + await fs.mkdir(destDir, { recursive: true }) const files = glob.sync('{dist,google,local}/**/*.{js,json,d.ts}', { cwd: srcDir, @@ -563,11 +563,11 @@ export async function ncc_next_font(task, opts) { for (const file of files) { const outputFile = join(destDir, file) - await fs.ensureDir(dirname(outputFile)) - await fs.copyFile(join(srcDir, file), outputFile) + await fs.mkdir(dirname(outputFile), { recursive: true }) + await fs.cp(join(srcDir, file), outputFile) } - await fs.outputJson(join(destDir, 'package.json'), { + await writeJson(join(destDir, 'package.json'), { name: '@next/font', license: pkg.license, types: pkg.types, @@ -580,8 +580,10 @@ externals['watchpack'] = 'watchpack' // eslint-disable-next-line camelcase externals['jest-worker'] = 'next/dist/compiled/jest-worker' export async function ncc_jest_worker(task, opts) { - await fs.remove(join(__dirname, 'src/compiled/jest-worker')) - await fs.ensureDir(join(__dirname, 'src/compiled/jest-worker/workers')) + await rmrf(join(__dirname, 'src/compiled/jest-worker')) + await fs.mkdir(join(__dirname, 'src/compiled/jest-worker/workers'), { + recursive: true, + }) const workers = ['processChild.js', 'threadChild.js'] @@ -621,22 +623,22 @@ export async function ncc_jest_worker(task, opts) { .ncc({ externals }) .target('src/compiled/jest-worker/out') - await fs.move( + await fs.rename( join(__dirname, 'src/compiled/jest-worker/out', worker + '.tmp.js'), - join(__dirname, 'src/compiled/jest-worker', worker), - { overwrite: true } + join(__dirname, 'src/compiled/jest-worker', worker) ) } - await fs.remove(join(__dirname, 'src/compiled/jest-worker/workers')) - await fs.remove(join(__dirname, 'src/compiled/jest-worker/out')) + await rmrf(join(__dirname, 'src/compiled/jest-worker/workers')) + await rmrf(join(__dirname, 'src/compiled/jest-worker/out')) } // eslint-disable-next-line camelcase export async function ncc_react_refresh_utils(task, opts) { - await fs.remove(join(__dirname, 'dist/compiled/react-refresh')) - await fs.copy( + await rmrf(join(__dirname, 'dist/compiled/react-refresh')) + await fs.cp( dirname(require.resolve('react-refresh/package.json')), - join(__dirname, 'dist/compiled/react-refresh') + join(__dirname, 'dist/compiled/react-refresh'), + { recursive: true, force: true } ) const srcDir = join( @@ -647,8 +649,8 @@ export async function ncc_react_refresh_utils(task, opts) { __dirname, 'dist/compiled/@next/react-refresh-utils/dist' ) - await fs.remove(destDir) - await fs.ensureDir(destDir) + await rmrf(destDir) + await fs.mkdir(destDir, { recursive: true }) const files = glob.sync('**/*.{js,json}', { cwd: srcDir }) @@ -658,7 +660,7 @@ export async function ncc_react_refresh_utils(task, opts) { const content = await fs.readFile(join(srcDir, file), 'utf8') const outputFile = join(destDir, file) - await fs.ensureDir(dirname(outputFile)) + await fs.mkdir(dirname(outputFile), { recursive: true }) await fs.writeFile( outputFile, content.replace( @@ -808,9 +810,9 @@ export async function copy_constants_browserify(task, opts) { await fs.mkdir(join(__dirname, 'src/compiled/constants-browserify'), { recursive: true, }) - await fs.writeFile( + await writeJson( join(__dirname, 'src/compiled/constants-browserify/package.json'), - JSON.stringify({ name: 'constants-browserify', main: './constants.json' }) + { name: 'constants-browserify', main: './constants.json' } ) await task .source(require.resolve('constants-browserify')) @@ -873,11 +875,11 @@ export async function ncc_stream_browserify(task, opts) { // reference breaking the browser polyfill const outputFile = join(__dirname, 'src/compiled/stream-browserify/index.js') - fs.writeFileSync( + await fs.writeFile( outputFile, - fs - .readFileSync(outputFile, 'utf8') - .replace(`require("stream")`, `require("events").EventEmitter`) + ( + await fs.readFile(outputFile, 'utf8') + ).replace(`require("stream")`, `require("events").EventEmitter`) ) } @@ -933,7 +935,7 @@ export async function ncc_path_browserify(task, opts) { .target('src/compiled/path-browserify') const filePath = join(__dirname, 'src/compiled/path-browserify/index.js') - const content = fs.readFileSync(filePath, 'utf8') + const content = await fs.readFile(filePath, 'utf8') // Remove process usage from path-browserify polyfill for edge-runtime await fs.writeFile(filePath, content.replace(/process\.cwd\(\)/g, '""')) @@ -1159,7 +1161,7 @@ export async function ncc_babel_bundle_packages(task, opts) { dirname(require.resolve('@babel/eslint-parser')), './parse.cjs' ) - const content = fs.readFileSync(eslintParseFile, 'utf-8') + const content = await fs.readFile(eslintParseFile, 'utf-8') // Let parser.cjs require @babel/parser directly const replacedContent = content .replace( @@ -1176,10 +1178,10 @@ export async function ncc_babel_bundle_packages(task, opts) { }) .target(`src/compiled/babel-packages`) - await fs.writeFile( - join(__dirname, 'src/compiled/babel-packages/package.json'), - JSON.stringify({ name: 'babel-packages', main: './packages-bundle.js' }) - ) + await writeJson(join(__dirname, 'src/compiled/babel-packages/package.json'), { + name: 'babel-packages', + main: './packages-bundle.js', + }) await task.source('src/bundles/babel/packages/*').target('src/compiled/babel') } @@ -1733,7 +1735,7 @@ export async function copy_vendor_react(task_) { 'unstable_server-external-runtime.js', ] for (const item of itemsToRemove) { - yield fs.remove(join(reactDomCompiledDir, item)) + yield rmrf(join(reactDomCompiledDir, item)) } // react-server-dom-webpack @@ -2856,3 +2858,18 @@ export async function next_bundle(task, opts) { opts ) } + +function writeJson(file, obj, { spaces = 0 } = {}) { + return fs.writeFile( + file, + JSON.stringify(obj, null, spaces) + (spaces === 0 ? '\n' : '') + ) +} + +function rmrf(path, options) { + return fs.rm(path, { recursive: true, force: true, ...options }) +} + +function readJson(path) { + return fs.readFile(path, 'utf8').then((content) => JSON.parse(content)) +} From 9d150b116de6aa8df2e14fa804fcccf4da477bb4 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Fri, 6 Oct 2023 01:59:22 +0200 Subject: [PATCH 08/15] Loose RSC import restrictions for 3rd party packages (#56501) When we landed #51179 it broke library like `apollo-client` as it's bundling client hooks into RSC bundle, so our RSC linter caught them and reported fatal errors. But those client hook APIs won't get executed in RSC. The original purpose of erroring on invalid hooks for server & client components was to catch bugs easier, but it might be too strict for the 3rd party libraries like `apollo-client` due to few reasons. We changed the rules only applying on user land source code. For 3rd party packages if they're not being imported correctly into proper server or client components, we're still showing runtime errors instead of fatal build errors. x-ref: https://github.com/apollographql/apollo-client/issues/10974 Closes NEXT-1673 --- .../core/src/react_server_components.rs | 19 +++++ .../fixtures/rsc-build-errors/next.config.js | 1 - .../rsc-runtime-errors/app/client/page.js | 4 + .../fixtures/rsc-runtime-errors/app/layout.js | 12 +++ .../rsc-runtime-errors/app/server/page.js | 3 + .../node_modules_bak/client-package/index.js | 6 ++ .../client-package/package.json | 4 + .../node_modules_bak/server-package/index.js | 7 ++ .../server-package/package.json | 4 + .../acceptance-app/rsc-build-errors.test.ts | 59 -------------- .../acceptance-app/rsc-runtime-errors.test.ts | 80 +++++++++++++++++++ 11 files changed, 139 insertions(+), 60 deletions(-) delete mode 100644 test/development/acceptance-app/fixtures/rsc-build-errors/next.config.js create mode 100644 test/development/acceptance-app/fixtures/rsc-runtime-errors/app/client/page.js create mode 100644 test/development/acceptance-app/fixtures/rsc-runtime-errors/app/layout.js create mode 100644 test/development/acceptance-app/fixtures/rsc-runtime-errors/app/server/page.js create mode 100644 test/development/acceptance-app/fixtures/rsc-runtime-errors/node_modules_bak/client-package/index.js create mode 100644 test/development/acceptance-app/fixtures/rsc-runtime-errors/node_modules_bak/client-package/package.json create mode 100644 test/development/acceptance-app/fixtures/rsc-runtime-errors/node_modules_bak/server-package/index.js create mode 100644 test/development/acceptance-app/fixtures/rsc-runtime-errors/node_modules_bak/server-package/package.json create mode 100644 test/development/acceptance-app/rsc-runtime-errors.test.ts diff --git a/packages/next-swc/crates/core/src/react_server_components.rs b/packages/next-swc/crates/core/src/react_server_components.rs index 8dd923dc61c7..8d136e78b09d 100644 --- a/packages/next-swc/crates/core/src/react_server_components.rs +++ b/packages/next-swc/crates/core/src/react_server_components.rs @@ -344,6 +344,10 @@ impl ReactServerComponents { } fn assert_server_graph(&self, imports: &[ModuleImports], module: &Module) { + // If the + if self.is_from_node_modules(&self.filepath) { + return; + } for import in imports { let source = import.source.0.clone(); if self.invalid_server_imports.contains(&source) { @@ -391,6 +395,9 @@ impl ReactServerComponents { } fn assert_server_filename(&self, module: &Module) { + if self.is_from_node_modules(&self.filepath) { + return; + } let is_error_file = Regex::new(r"[\\/]error\.(ts|js)x?$") .unwrap() .is_match(&self.filepath); @@ -416,6 +423,9 @@ impl ReactServerComponents { } fn assert_client_graph(&self, imports: &[ModuleImports]) { + if self.is_from_node_modules(&self.filepath) { + return; + } for import in imports { let source = import.source.0.clone(); if self.invalid_client_imports.contains(&source) { @@ -432,6 +442,9 @@ impl ReactServerComponents { } fn assert_invalid_api(&self, module: &Module, is_client_entry: bool) { + if self.is_from_node_modules(&self.filepath) { + return; + } let is_layout_or_page = Regex::new(r"[\\/](page|layout)\.(ts|js)x?$") .unwrap() .is_match(&self.filepath); @@ -562,6 +575,12 @@ impl ReactServerComponents { }, ); } + + fn is_from_node_modules(&self, filepath: &str) -> bool { + Regex::new(r"[\\/]node_modules[\\/]") + .unwrap() + .is_match(filepath) + } } pub fn server_components( diff --git a/test/development/acceptance-app/fixtures/rsc-build-errors/next.config.js b/test/development/acceptance-app/fixtures/rsc-build-errors/next.config.js deleted file mode 100644 index 4ba52ba2c8df..000000000000 --- a/test/development/acceptance-app/fixtures/rsc-build-errors/next.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = {} diff --git a/test/development/acceptance-app/fixtures/rsc-runtime-errors/app/client/page.js b/test/development/acceptance-app/fixtures/rsc-runtime-errors/app/client/page.js new file mode 100644 index 000000000000..33f94c1f46b0 --- /dev/null +++ b/test/development/acceptance-app/fixtures/rsc-runtime-errors/app/client/page.js @@ -0,0 +1,4 @@ +'use client' +export default function page() { + return 'page' +} diff --git a/test/development/acceptance-app/fixtures/rsc-runtime-errors/app/layout.js b/test/development/acceptance-app/fixtures/rsc-runtime-errors/app/layout.js new file mode 100644 index 000000000000..8525f5f8c0b2 --- /dev/null +++ b/test/development/acceptance-app/fixtures/rsc-runtime-errors/app/layout.js @@ -0,0 +1,12 @@ +export const metadata = { + title: 'Next.js', + description: 'Generated by Next.js', +} + +export default function RootLayout({ children }) { + return ( + + {children} + + ) +} diff --git a/test/development/acceptance-app/fixtures/rsc-runtime-errors/app/server/page.js b/test/development/acceptance-app/fixtures/rsc-runtime-errors/app/server/page.js new file mode 100644 index 000000000000..41c1c6b78dff --- /dev/null +++ b/test/development/acceptance-app/fixtures/rsc-runtime-errors/app/server/page.js @@ -0,0 +1,3 @@ +export default function page() { + return 'page' +} diff --git a/test/development/acceptance-app/fixtures/rsc-runtime-errors/node_modules_bak/client-package/index.js b/test/development/acceptance-app/fixtures/rsc-runtime-errors/node_modules_bak/client-package/index.js new file mode 100644 index 000000000000..6e5c0b4e8820 --- /dev/null +++ b/test/development/acceptance-app/fixtures/rsc-runtime-errors/node_modules_bak/client-package/index.js @@ -0,0 +1,6 @@ +import { useState } from 'react' + +export function callClientApi() { + // eslint-disable-next-line react-hooks/rules-of-hooks + return useState(0) +} diff --git a/test/development/acceptance-app/fixtures/rsc-runtime-errors/node_modules_bak/client-package/package.json b/test/development/acceptance-app/fixtures/rsc-runtime-errors/node_modules_bak/client-package/package.json new file mode 100644 index 000000000000..5f196b3ba2bd --- /dev/null +++ b/test/development/acceptance-app/fixtures/rsc-runtime-errors/node_modules_bak/client-package/package.json @@ -0,0 +1,4 @@ +{ + "name": "client-package", + "exports": "./index.js" +} diff --git a/test/development/acceptance-app/fixtures/rsc-runtime-errors/node_modules_bak/server-package/index.js b/test/development/acceptance-app/fixtures/rsc-runtime-errors/node_modules_bak/server-package/index.js new file mode 100644 index 000000000000..a0b959e43331 --- /dev/null +++ b/test/development/acceptance-app/fixtures/rsc-runtime-errors/node_modules_bak/server-package/index.js @@ -0,0 +1,7 @@ +'use client' + +import { cookies } from 'next/headers' + +export function callServerApi() { + return cookies() +} diff --git a/test/development/acceptance-app/fixtures/rsc-runtime-errors/node_modules_bak/server-package/package.json b/test/development/acceptance-app/fixtures/rsc-runtime-errors/node_modules_bak/server-package/package.json new file mode 100644 index 000000000000..ba9bc67edc39 --- /dev/null +++ b/test/development/acceptance-app/fixtures/rsc-runtime-errors/node_modules_bak/server-package/package.json @@ -0,0 +1,4 @@ +{ + "name": "server-package", + "exports": "./index.js" +} diff --git a/test/development/acceptance-app/rsc-build-errors.test.ts b/test/development/acceptance-app/rsc-build-errors.test.ts index 1e8bbacb26e4..f65a33bc38a4 100644 --- a/test/development/acceptance-app/rsc-build-errors.test.ts +++ b/test/development/acceptance-app/rsc-build-errors.test.ts @@ -379,63 +379,4 @@ describe('Error overlay - RSC build errors', () => { await cleanup() }) - - it('should show which import caused an error in node_modules', async () => { - const { session, cleanup } = await sandbox( - next, - new Map([ - [ - 'node_modules/client-package/module2.js', - "import { useState } from 'react'", - ], - ['node_modules/client-package/module1.js', "import './module2.js'"], - ['node_modules/client-package/index.js', "import './module1.js'"], - [ - 'node_modules/client-package/package.json', - outdent` - { - "name": "client-package", - "version": "0.0.1" - } - `, - ], - ['app/Component.js', "import 'client-package'"], - [ - 'app/page.js', - outdent` - import './Component.js' - export default function Page() { - return

Hello world

- } - `, - ], - ]) - ) - - expect(await session.hasRedbox(true)).toBe(true) - expect( - next.normalizeTestDirContent(await session.getRedboxSource()) - ).toMatchInlineSnapshot( - next.normalizeSnapshot(` - "./app/Component.js - ReactServerComponentsError: - - You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with \\"use client\\", so they're Server Components by default. - Learn more: https://nextjs.org/docs/getting-started/react-essentials - - ,-[TEST_DIR/node_modules/client-package/module2.js:1:1] - 1 | import { useState } from 'react' - : ^^^^^^^^ - \`---- - - The error was caused by importing 'client-package/index.js' in './app/Component.js'. - - Maybe one of these should be marked as a client entry with \\"use client\\": - ./app/Component.js - ./app/page.js" - `) - ) - - await cleanup() - }) }) diff --git a/test/development/acceptance-app/rsc-runtime-errors.test.ts b/test/development/acceptance-app/rsc-runtime-errors.test.ts new file mode 100644 index 000000000000..41b2688f3158 --- /dev/null +++ b/test/development/acceptance-app/rsc-runtime-errors.test.ts @@ -0,0 +1,80 @@ +import path from 'path' +import { outdent } from 'outdent' +import { FileRef, createNextDescribe } from 'e2e-utils' +import { + check, + getRedboxDescription, + hasRedbox, + shouldRunTurboDevTest, +} from 'next-test-utils' + +createNextDescribe( + 'Error overlay - RSC runtime errors', + { + files: new FileRef(path.join(__dirname, 'fixtures', 'rsc-runtime-errors')), + packageJson: { + scripts: { + setup: 'cp -r ./node_modules_bak/* ./node_modules', + build: 'yarn setup && next build', + dev: `yarn setup && next ${ + shouldRunTurboDevTest() ? 'dev --turbo' : 'dev' + }`, + start: 'next start', + }, + }, + installCommand: 'yarn', + startCommand: (global as any).isNextDev ? 'yarn dev' : 'yarn start', + }, + ({ next }) => { + it('should show runtime errors if invalid client API from node_modules is executed', async () => { + await next.patchFile( + 'app/server/page.js', + outdent` + import { callClientApi } from 'client-package' + export default function Page() { + callClientApi() + return 'page' + } + ` + ) + + const browser = await next.browser('/server') + + await check( + async () => ((await hasRedbox(browser, true)) ? 'success' : 'fail'), + /success/ + ) + const errorDescription = await getRedboxDescription(browser) + + expect(errorDescription).toContain( + `Error: useState only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/react-client-hook-in-server-component` + ) + }) + + it('should show runtime errors if invalid server API from node_modules is executed', async () => { + await next.patchFile( + 'app/client/page.js', + outdent` + 'use client' + import { callServerApi } from 'server-package' + export default function Page() { + callServerApi() + return 'page' + } + ` + ) + + const browser = await next.browser('/client') + + await check( + async () => ((await hasRedbox(browser, true)) ? 'success' : 'fail'), + /success/ + ) + const errorDescription = await getRedboxDescription(browser) + + expect(errorDescription).toContain( + `Error: Invariant: cookies() expects to have requestAsyncStorage, none available.` + ) + }) + } +) From 2af1e784c290eba505b2de76ab0e83eb110cf30e Mon Sep 17 00:00:00 2001 From: Justin Ridgewell Date: Fri, 6 Oct 2023 02:29:14 -0400 Subject: [PATCH 09/15] turbopack: Chunking Refactor Step 2 (#56504) ### What? The second step in our chunking refactoring, this removes our use of Module::as_chunk and Module::as_root_chunk. Instead, the only way to generate a chunk is directly from a root ChunkItem. ### Why? In the end we want to avoid creating chunks from modules directly, but enforce everything going through the ChunkingContext to be chunked. This allows us to replace the existing chunking algorithm with a much more efficient one that avoid duplication between chunks in first place and doesn't require a post-chunking optimization. ### How? https://github.com/vercel/turbo/pull/6120 Re: https://github.com/vercel/next.js/pull/56467 Closes WEB-1721 Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com> --- Cargo.lock | 70 +++++++++---------- Cargo.toml | 6 +- packages/next-swc/crates/next-api/src/app.rs | 14 ++-- .../crates/next-api/src/middleware.rs | 8 +-- .../next-swc/crates/next-api/src/pages.rs | 13 ++-- .../next-build/src/next_app/app_entries.rs | 16 ++++- .../next-build/src/next_pages/page_entries.rs | 9 +-- .../next_app/app_client_references_chunks.rs | 26 +++---- .../src/next_app/app_client_shared_chunks.rs | 43 ++---------- .../with_client_chunks.rs | 6 +- .../src/next_dynamic/dynamic_module.rs | 5 +- .../crates/next-core/src/page_loader.rs | 12 ++-- packages/next/package.json | 2 +- pnpm-lock.yaml | 18 ++--- 14 files changed, 103 insertions(+), 145 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9691bd382677..a321ce7d0d66 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -289,9 +289,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", @@ -321,7 +321,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "serde", "smallvec", @@ -3515,7 +3515,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "serde", @@ -7368,7 +7368,7 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "async-trait", @@ -7400,7 +7400,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "cargo-lock", @@ -7412,7 +7412,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "bytes", @@ -7427,7 +7427,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "dotenvs", @@ -7441,7 +7441,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7458,7 +7458,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "auto-hash-map", @@ -7488,7 +7488,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "base16", "hex", @@ -7500,7 +7500,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -7514,7 +7514,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "proc-macro2", "quote", @@ -7524,7 +7524,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "mimalloc", ] @@ -7532,7 +7532,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "auto-hash-map", @@ -7557,7 +7557,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "async-recursion", @@ -7588,7 +7588,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "auto-hash-map", "mdxjs", @@ -7628,7 +7628,7 @@ dependencies = [ [[package]] name = "turbopack-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7650,7 +7650,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "clap 4.4.2", @@ -7674,7 +7674,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "async-recursion", @@ -7703,7 +7703,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "async-trait", @@ -7725,7 +7725,7 @@ dependencies = [ [[package]] name = "turbopack-dev" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7749,7 +7749,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "async-compression", @@ -7786,7 +7786,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "async-trait", @@ -7820,7 +7820,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "serde", "serde_json", @@ -7831,7 +7831,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "async-trait", @@ -7854,7 +7854,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "indoc", @@ -7871,7 +7871,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7887,7 +7887,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "base64 0.21.4", @@ -7907,7 +7907,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "serde", @@ -7922,7 +7922,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "mdxjs", @@ -7937,7 +7937,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "async-stream", @@ -7972,7 +7972,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "serde", @@ -7988,7 +7988,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "swc_core", "turbo-tasks", @@ -7999,7 +7999,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231005.2#2207c3eb716b81c719385e43d25d7399f673fc11" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index 6bd1c3e77129..a895085c3971 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,11 +40,11 @@ swc_core = { version = "0.83.28", features = [ testing = { version = "0.34.1" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231005.2" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231006.1" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231005.2" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231006.1" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231005.2" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231006.1" } # General Deps diff --git a/packages/next-swc/crates/next-api/src/app.rs b/packages/next-swc/crates/next-api/src/app.rs index 05d7a0008e33..1b0684d6746d 100644 --- a/packages/next-swc/crates/next-api/src/app.rs +++ b/packages/next-swc/crates/next-api/src/app.rs @@ -39,8 +39,9 @@ use turbopack_binding::{ turbopack::{ core::{ asset::{Asset, AssetContent}, - chunk::{ChunkableModuleExt, ChunkingContext, EvaluatableAssets}, + chunk::{ChunkingContext, EvaluatableAssets}, file_source::FileSource, + module::Module, output::{OutputAsset, OutputAssets}, virtual_output::VirtualOutputAsset, }, @@ -507,7 +508,13 @@ impl AppEndpoint { let mut server_assets = vec![]; let mut client_assets = vec![]; + let app_entry = app_entry.await?; + let client_shared_chunks = get_app_client_shared_chunks( + app_entry + .rsc_entry + .ident() + .with_modifier(Vc::cell("client_shared_chunks".to_string())), this.app_project.client_runtime_entries(), this.app_project.project().client_chunking_context(), ); @@ -524,7 +531,6 @@ impl AppEndpoint { } } - let app_entry = app_entry.await?; let rsc_entry = app_entry.rsc_entry; let rsc_entry_asset = Vc::upcast(rsc_entry); @@ -707,9 +713,7 @@ impl AppEndpoint { } let files = chunking_context.evaluated_chunk_group( - app_entry - .rsc_entry - .as_root_chunk(Vc::upcast(chunking_context)), + app_entry.rsc_entry.ident(), Vc::cell(evaluatable_assets), ); server_assets.extend(files.await?.iter().copied()); diff --git a/packages/next-swc/crates/next-api/src/middleware.rs b/packages/next-swc/crates/next-api/src/middleware.rs index b7fedd56befb..ba5f17524f77 100644 --- a/packages/next-swc/crates/next-api/src/middleware.rs +++ b/packages/next-swc/crates/next-api/src/middleware.rs @@ -13,7 +13,7 @@ use turbopack_binding::{ turbopack::{ core::{ asset::AssetContent, - chunk::{ChunkableModuleExt, ChunkingContext}, + chunk::ChunkingContext, context::AssetContext, module::Module, output::{OutputAsset, OutputAssets}, @@ -88,10 +88,8 @@ impl MiddlewareEndpoint { let edge_chunking_context = self.project.edge_middleware_chunking_context(); - let edge_files = edge_chunking_context.evaluated_chunk_group( - module.as_root_chunk(Vc::upcast(edge_chunking_context)), - Vc::cell(evaluatable_assets), - ); + let edge_files = edge_chunking_context + .evaluated_chunk_group(module.ident(), Vc::cell(evaluatable_assets)); Ok(edge_files) } diff --git a/packages/next-swc/crates/next-api/src/pages.rs b/packages/next-swc/crates/next-api/src/pages.rs index e198e346a3e0..8d8f6705e8b1 100644 --- a/packages/next-swc/crates/next-api/src/pages.rs +++ b/packages/next-swc/crates/next-api/src/pages.rs @@ -37,10 +37,11 @@ use turbopack_binding::{ build::BuildChunkingContext, core::{ asset::AssetContent, - chunk::{ChunkableModuleExt, ChunkingContext, EvaluatableAssets}, + chunk::{ChunkingContext, EvaluatableAssets}, context::AssetContext, file_source::FileSource, issue::{IssueSeverity, OptionIssueSource}, + module::Module, output::{OutputAsset, OutputAssets}, reference_type::{ EcmaScriptModulesReferenceSubType, EntryReferenceSubType, ReferenceType, @@ -549,11 +550,9 @@ impl PageEndpoint { let client_chunking_context = this.pages_project.project().client_chunking_context(); - let client_entry_chunk = client_module.as_root_chunk(Vc::upcast(client_chunking_context)); - let mut client_chunks = client_chunking_context .evaluated_chunk_group( - client_entry_chunk, + client_module.ident(), this.pages_project .client_runtime_entries() .with_entry(Vc::upcast(client_main_module)) @@ -611,10 +610,8 @@ impl PageEndpoint { }; evaluatable_assets.push(evaluatable); - let edge_files = edge_chunking_context.evaluated_chunk_group( - ssr_module.as_root_chunk(Vc::upcast(edge_chunking_context)), - Vc::cell(evaluatable_assets), - ); + let edge_files = edge_chunking_context + .evaluated_chunk_group(ssr_module.ident(), Vc::cell(evaluatable_assets)); Ok(SsrChunk::Edge { files: edge_files }.cell()) } else { diff --git a/packages/next-swc/crates/next-build/src/next_app/app_entries.rs b/packages/next-swc/crates/next-build/src/next_app/app_entries.rs index 57c5143babb9..e8a05d1a8626 100644 --- a/packages/next-swc/crates/next-build/src/next_app/app_entries.rs +++ b/packages/next-swc/crates/next-build/src/next_app/app_entries.rs @@ -27,7 +27,10 @@ use turbopack_binding::{ turbopack::{ build::BuildChunkingContext, core::{ - chunk::EvaluatableAssets, compile_time_info::CompileTimeInfo, file_source::FileSource, + chunk::{ChunkingContext, EvaluatableAssets}, + compile_time_info::CompileTimeInfo, + file_source::FileSource, + ident::AssetIdent, output::OutputAsset, }, ecmascript::chunk::EcmascriptChunkingContext, @@ -256,8 +259,15 @@ pub async fn compute_app_entries_chunks( ) -> Result<()> { let client_relative_path_ref = client_relative_path.await?; - let app_client_shared_chunks = - get_app_client_shared_chunks(app_entries.client_runtime_entries, client_chunking_context); + let app_client_shared_chunks = get_app_client_shared_chunks( + AssetIdent::from_path( + client_chunking_context + .context_path() + .join("client shared chunk group".to_string()), + ), + app_entries.client_runtime_entries, + client_chunking_context, + ); let mut app_shared_client_chunks_paths = vec![]; for chunk in app_client_shared_chunks.await?.iter().copied() { diff --git a/packages/next-swc/crates/next-build/src/next_pages/page_entries.rs b/packages/next-swc/crates/next-build/src/next_pages/page_entries.rs index 1f024e90e1c6..0b183f7e535e 100644 --- a/packages/next-swc/crates/next-build/src/next_pages/page_entries.rs +++ b/packages/next-swc/crates/next-build/src/next_pages/page_entries.rs @@ -27,10 +27,11 @@ use turbopack_binding::{ turbopack::{ build::BuildChunkingContext, core::{ - chunk::{ChunkableModuleExt, ChunkingContext, EvaluatableAssets}, + chunk::{ChunkingContext, EvaluatableAssets}, compile_time_info::CompileTimeInfo, context::AssetContext, file_source::FileSource, + module::Module, output::OutputAsset, reference_type::{EntryReferenceSubType, ReferenceType}, source::Source, @@ -400,12 +401,8 @@ pub async fn compute_page_entries_chunks( .insert(pathname.clone_value(), asset_path.to_string()); } - let client_entry_chunk = page_entry - .client_module - .as_root_chunk(Vc::upcast(client_chunking_context)); - let client_chunks = client_chunking_context.evaluated_chunk_group( - client_entry_chunk, + page_entry.client_module.ident(), page_entries .client_runtime_entries .with_entry(Vc::upcast(page_entry.client_module)), diff --git a/packages/next-swc/crates/next-core/src/next_app/app_client_references_chunks.rs b/packages/next-swc/crates/next-core/src/next_app/app_client_references_chunks.rs index ea67efab3a44..83ba23239b68 100644 --- a/packages/next-swc/crates/next-core/src/next_app/app_client_references_chunks.rs +++ b/packages/next-swc/crates/next-core/src/next_app/app_client_references_chunks.rs @@ -4,10 +4,7 @@ use serde::{Deserialize, Serialize}; use turbo_tasks::{debug::ValueDebugFormat, trace::TraceRawVcs, TryJoinIterExt, Vc}; use turbopack_binding::turbopack::{ build::BuildChunkingContext, - core::{ - chunk::{ChunkableModuleExt, ChunkingContext}, - output::OutputAssets, - }, + core::{chunk::ChunkingContextExt, output::OutputAssets}, ecmascript::chunk::EcmascriptChunkingContext, }; @@ -46,24 +43,21 @@ pub async fn get_app_client_references_chunks( match client_reference_ty { ClientReferenceType::EcmascriptClientReference(ecmascript_client_reference) => { let ecmascript_client_reference_ref = ecmascript_client_reference.await?; - let client_entry_chunk = ecmascript_client_reference_ref - .client_module - .as_root_chunk(Vc::upcast(client_chunking_context)); - let ssr_entry_chunk = ecmascript_client_reference_ref - .ssr_module - .as_root_chunk(Vc::upcast(ssr_chunking_context)); ClientReferenceChunks { - client_chunks: client_chunking_context.chunk_group(client_entry_chunk), - ssr_chunks: ssr_chunking_context.chunk_group(ssr_entry_chunk), + client_chunks: client_chunking_context.root_chunk_group(Vc::upcast( + ecmascript_client_reference_ref.client_module, + )), + ssr_chunks: ssr_chunking_context.root_chunk_group(Vc::upcast( + ecmascript_client_reference_ref.ssr_module, + )), } } ClientReferenceType::CssClientReference(css_client_reference) => { let css_client_reference_ref = css_client_reference.await?; - let client_entry_chunk = css_client_reference_ref - .client_module - .as_root_chunk(Vc::upcast(client_chunking_context)); ClientReferenceChunks { - client_chunks: client_chunking_context.chunk_group(client_entry_chunk), + client_chunks: client_chunking_context.root_chunk_group(Vc::upcast( + css_client_reference_ref.client_module, + )), ssr_chunks: OutputAssets::empty(), } } diff --git a/packages/next-swc/crates/next-core/src/next_app/app_client_shared_chunks.rs b/packages/next-swc/crates/next-core/src/next_app/app_client_shared_chunks.rs index cedcd7a506a6..e7e288181690 100644 --- a/packages/next-swc/crates/next-core/src/next_app/app_client_shared_chunks.rs +++ b/packages/next-swc/crates/next-core/src/next_app/app_client_shared_chunks.rs @@ -1,41 +1,17 @@ use anyhow::Result; -use turbo_tasks::{TryJoinIterExt, Value, Vc}; +use turbo_tasks::Vc; use turbopack_binding::turbopack::{ core::{ - chunk::{availability_info::AvailabilityInfo, ChunkingContext, EvaluatableAssets}, + chunk::{ChunkingContext, EvaluatableAssets}, + ident::AssetIdent, output::OutputAssets, }, - ecmascript::chunk::{EcmascriptChunk, EcmascriptChunkPlaceable, EcmascriptChunkingContext}, + ecmascript::chunk::EcmascriptChunkingContext, }; -#[turbo_tasks::function] -pub async fn get_app_shared_client_chunk( - app_client_runtime_entries: Vc, - client_chunking_context: Vc>, -) -> Result> { - let client_runtime_entries: Vec<_> = app_client_runtime_entries - .await? - .iter() - .map(|entry| async move { - Ok(Vc::try_resolve_sidecast::>(*entry).await?) - }) - .try_join() - .await? - .into_iter() - .flatten() - .collect(); - - Ok(EcmascriptChunk::new_normalized( - client_chunking_context, - // TODO(alexkirsz) Should this accept Evaluatable instead? - Vc::cell(client_runtime_entries), - None, - Value::new(AvailabilityInfo::Untracked), - )) -} - #[turbo_tasks::function] pub async fn get_app_client_shared_chunks( + ident: Vc, app_client_runtime_entries: Vc, client_chunking_context: Vc>, ) -> Result> { @@ -43,13 +19,8 @@ pub async fn get_app_client_shared_chunks( return Ok(OutputAssets::empty()); } - let app_client_shared_chunk = - get_app_shared_client_chunk(app_client_runtime_entries, client_chunking_context); - - let app_client_shared_chunks = client_chunking_context.evaluated_chunk_group( - Vc::upcast(app_client_shared_chunk), - app_client_runtime_entries, - ); + let app_client_shared_chunks = + client_chunking_context.evaluated_chunk_group(ident, app_client_runtime_entries); Ok(app_client_shared_chunks) } diff --git a/packages/next-swc/crates/next-core/src/next_client_component/with_client_chunks.rs b/packages/next-swc/crates/next-core/src/next_client_component/with_client_chunks.rs index d5499cc0de81..9674a55f8374 100644 --- a/packages/next-swc/crates/next-core/src/next_client_component/with_client_chunks.rs +++ b/packages/next-swc/crates/next-core/src/next_client_component/with_client_chunks.rs @@ -8,7 +8,7 @@ use turbopack_binding::{ asset::{Asset, AssetContent}, chunk::{ availability_info::AvailabilityInfo, Chunk, ChunkData, ChunkItem, ChunkItemExt, - ChunkableModule, ChunkableModuleExt, ChunkableModuleReference, ChunkingContext, + ChunkableModule, ChunkableModuleReference, ChunkingContext, ChunkingContextExt, ChunkingType, ChunkingTypeOption, ChunksData, }, ident::AssetIdent, @@ -111,9 +111,7 @@ impl WithClientChunksChunkItem { async fn chunks(self: Vc) -> Result> { let this = self.await?; let inner = this.inner.await?; - Ok(this - .context - .chunk_group(inner.asset.as_root_chunk(Vc::upcast(this.context)))) + Ok(this.context.root_chunk_group(Vc::upcast(inner.asset))) } #[turbo_tasks::function] diff --git a/packages/next-swc/crates/next-core/src/next_dynamic/dynamic_module.rs b/packages/next-swc/crates/next-core/src/next_dynamic/dynamic_module.rs index b5cd908992b6..8e20f4c4dabf 100644 --- a/packages/next-swc/crates/next-core/src/next_dynamic/dynamic_module.rs +++ b/packages/next-swc/crates/next-core/src/next_dynamic/dynamic_module.rs @@ -2,7 +2,7 @@ use anyhow::{bail, Result}; use turbo_tasks::Vc; use turbopack_binding::turbopack::core::{ asset::{Asset, AssetContent}, - chunk::{ChunkableModule, ChunkableModuleExt, ChunkingContext}, + chunk::{ChunkableModule, ChunkingContext, ChunkingContextExt}, ident::AssetIdent, module::Module, output::OutputAssets, @@ -41,8 +41,7 @@ impl NextDynamicEntryModule { bail!("dynamic client asset must be chunkable"); }; - let client_entry_chunk = client_entry_module.as_root_chunk(client_chunking_context); - Ok(client_chunking_context.chunk_group(client_entry_chunk)) + Ok(client_chunking_context.root_chunk_group(client_entry_module)) } } diff --git a/packages/next-swc/crates/next-core/src/page_loader.rs b/packages/next-swc/crates/next-core/src/page_loader.rs index 56d240b1a476..7ac15c7b65a9 100644 --- a/packages/next-swc/crates/next-core/src/page_loader.rs +++ b/packages/next-swc/crates/next-core/src/page_loader.rs @@ -9,10 +9,7 @@ use turbopack_binding::{ turbopack::{ core::{ asset::{Asset, AssetContent}, - chunk::{ - ChunkData, ChunkableModuleExt, ChunkingContext, ChunksData, EvaluatableAsset, - EvaluatableAssets, - }, + chunk::{ChunkData, ChunkingContext, ChunksData, EvaluatableAsset, EvaluatableAssets}, context::AssetContext, ident::AssetIdent, module::Module, @@ -138,10 +135,9 @@ impl PageLoaderAsset { bail!("internal module must be evaluatable"); }; - Ok(this.client_chunking_context.evaluated_chunk_group( - module.as_root_chunk(this.client_chunking_context), - EvaluatableAssets::one(module), - )) + Ok(this + .client_chunking_context + .evaluated_chunk_group(module.ident(), EvaluatableAssets::one(module))) } #[turbo_tasks::function] diff --git a/packages/next/package.json b/packages/next/package.json index 85d14ea8518d..2ad7765e570a 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -191,7 +191,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.22.6", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231005.2", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.1", "acorn": "8.5.0", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7f6605037d31..dfb82e3bc636 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1058,8 +1058,8 @@ importers: specifier: 0.22.6 version: 0.22.6 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231005.2 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231005.2(react-refresh@0.12.0)(webpack@5.86.0)' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.1 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.1(react-refresh@0.12.0)(webpack@5.86.0)' acorn: specifier: 8.5.0 version: 8.5.0 @@ -9082,7 +9082,7 @@ packages: fast-deep-equal: 3.1.3 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - uri-js: 4.2.2 + uri-js: 4.4.1 dev: true /alex@9.1.0: @@ -25928,12 +25928,6 @@ packages: tslib: 2.6.2 dev: true - /uri-js@4.2.2: - resolution: {integrity: sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==} - dependencies: - punycode: 2.1.1 - dev: true - /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: @@ -26762,9 +26756,9 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231005.2(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231005.2} - id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231005.2' + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.1(react-refresh@0.12.0)(webpack@5.86.0)': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.1} + id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.1' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: From c95e4b7841bda8aebc919da261dd008619e40d88 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Fri, 6 Oct 2023 10:59:43 +0200 Subject: [PATCH 10/15] update turbopack, fix sass peer dependency (#56508) * https://github.com/vercel/turbo/pull/6076 Closes WEB-1725 --- Cargo.lock | 66 +++++++++---------- Cargo.toml | 6 +- packages/next/package.json | 2 +- packages/next/src/compiled/sass-loader/cjs.js | 2 +- pnpm-lock.yaml | 15 +++-- 5 files changed, 46 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a321ce7d0d66..a1b72d2c8712 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -321,7 +321,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "serde", "smallvec", @@ -3515,7 +3515,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "serde", @@ -7368,7 +7368,7 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "async-trait", @@ -7400,7 +7400,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "cargo-lock", @@ -7412,7 +7412,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "bytes", @@ -7427,7 +7427,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "dotenvs", @@ -7441,7 +7441,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7458,7 +7458,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "auto-hash-map", @@ -7488,7 +7488,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "base16", "hex", @@ -7500,7 +7500,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -7514,7 +7514,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "proc-macro2", "quote", @@ -7524,7 +7524,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "mimalloc", ] @@ -7532,7 +7532,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "auto-hash-map", @@ -7557,7 +7557,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "async-recursion", @@ -7588,7 +7588,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "auto-hash-map", "mdxjs", @@ -7628,7 +7628,7 @@ dependencies = [ [[package]] name = "turbopack-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7650,7 +7650,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "clap 4.4.2", @@ -7674,7 +7674,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "async-recursion", @@ -7703,7 +7703,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "async-trait", @@ -7725,7 +7725,7 @@ dependencies = [ [[package]] name = "turbopack-dev" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7749,7 +7749,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "async-compression", @@ -7786,7 +7786,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "async-trait", @@ -7820,7 +7820,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "serde", "serde_json", @@ -7831,7 +7831,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "async-trait", @@ -7854,7 +7854,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "indoc", @@ -7871,7 +7871,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7887,7 +7887,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "base64 0.21.4", @@ -7907,7 +7907,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "serde", @@ -7922,7 +7922,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "mdxjs", @@ -7937,7 +7937,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "async-stream", @@ -7972,7 +7972,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "serde", @@ -7988,7 +7988,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "swc_core", "turbo-tasks", @@ -7999,7 +7999,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.1#59ac1533324bfac62e75d759dd6cdee0f44a0b96" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231006.2#624521ff91ac654c11072581867f558c26d285ab" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index a895085c3971..0d80789e361c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,11 +40,11 @@ swc_core = { version = "0.83.28", features = [ testing = { version = "0.34.1" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231006.1" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231006.2" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231006.1" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231006.2" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231006.1" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231006.2" } # General Deps diff --git a/packages/next/package.json b/packages/next/package.json index 2ad7765e570a..b743ef8fa555 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -191,7 +191,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.22.6", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.1", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.2", "acorn": "8.5.0", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/packages/next/src/compiled/sass-loader/cjs.js b/packages/next/src/compiled/sass-loader/cjs.js index f852edbe570a..558d97da1149 100644 --- a/packages/next/src/compiled/sass-loader/cjs.js +++ b/packages/next/src/compiled/sass-loader/cjs.js @@ -1 +1 @@ -(function(){var __webpack_modules__={12:function(e,t){function set(e,t,s){if(typeof s.value==="object")s.value=klona(s.value);if(!s.enumerable||s.get||s.set||!s.configurable||!s.writable||t==="__proto__"){Object.defineProperty(e,t,s)}else e[t]=s.value}function klona(e){if(typeof e!=="object")return e;var t=0,s,r,n,o=Object.prototype.toString.call(e);if(o==="[object Object]"){n=Object.create(e.__proto__||null)}else if(o==="[object Array]"){n=Array(e.length)}else if(o==="[object Set]"){n=new Set;e.forEach((function(e){n.add(klona(e))}))}else if(o==="[object Map]"){n=new Map;e.forEach((function(e,t){n.set(klona(t),klona(e))}))}else if(o==="[object Date]"){n=new Date(+e)}else if(o==="[object RegExp]"){n=new RegExp(e.source,e.flags)}else if(o==="[object DataView]"){n=new e.constructor(klona(e.buffer))}else if(o==="[object ArrayBuffer]"){n=e.slice(0)}else if(o.slice(-6)==="Array]"){n=new e.constructor(e)}if(n){for(r=Object.getOwnPropertySymbols(e);t{if(e){if(e.file){this.addDependency(r.default.normalize(e.file))}s(new a.default(e));return}let n=t.map?JSON.parse(t.map):null;if(n&&c){n=(0,o.normalizeSourceMap)(n,this.rootContext)}t.stats.includedFiles.forEach((e=>{const t=r.default.normalize(e);if(r.default.isAbsolute(t)){this.addDependency(t)}}));s(null,t.css.toString(),n)}))}var i=loader;t["default"]=i},125:function(__unused_webpack_module,exports,__nccwpck_require__){"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.getRenderFunctionFromSassImplementation=getRenderFunctionFromSassImplementation;exports.getSassImplementation=getSassImplementation;exports.getSassOptions=getSassOptions;exports.getWebpackImporter=getWebpackImporter;exports.getWebpackResolver=getWebpackResolver;exports.isSupportedFibers=isSupportedFibers;exports.normalizeSourceMap=normalizeSourceMap;var _url=_interopRequireDefault(__nccwpck_require__(310));var _path=_interopRequireDefault(__nccwpck_require__(17));var _full=__nccwpck_require__(12);var _neoAsync=_interopRequireDefault(__nccwpck_require__(175));var _SassWarning=_interopRequireDefault(__nccwpck_require__(186));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function getDefaultSassImplementation(){let sassImplPkg="sass";try{eval("require").resolve("sass")}catch(error){try{eval("require").resolve("node-sass");sassImplPkg="node-sass"}catch(e){sassImplPkg="sass"}}return __nccwpck_require__(438)}function getSassImplementation(e,t){let s=t;if(!s){try{s=getDefaultSassImplementation()}catch(t){e.emitError(t);return}}if(typeof s==="string"){try{s=require(s)}catch(t){e.emitError(t);return}}const{info:r}=s;if(!r){e.emitError(new Error("Unknown Sass implementation."));return}const n=r.split("\t");if(n.length<2){e.emitError(new Error(`Unknown Sass implementation "${r}".`));return}const[o]=n;if(o==="dart-sass"){return s}else if(o==="node-sass"){return s}e.emitError(new Error(`Unknown Sass implementation "${o}".`))}function isProductionLikeMode(e){return e.mode==="production"||!e.mode}function proxyCustomImporters(e,t){return[].concat(e).map((e=>function proxyImporter(...s){const r={...this,webpackLoaderContext:t};return e.apply(r,s)}))}function isSupportedFibers(){const[e]=process.versions.node.split(".");return Number(e)<16}async function getSassOptions(e,t,s,r,n){const o=(0,_full.klona)(t.sassOptions?typeof t.sassOptions==="function"?t.sassOptions(e)||{}:t.sassOptions:{});const a=r.info.includes("dart-sass");if(a&&isSupportedFibers()){const e=!o.fiber&&o.fiber!==false;if(e){let e;try{e=require.resolve("fibers")}catch(e){}if(e){o.fiber=require(e)}}else if(o.fiber===false){delete o.fiber}}else{delete o.fiber}o.file=e.resourcePath;o.data=t.additionalData?typeof t.additionalData==="function"?await t.additionalData(s,e):`${t.additionalData}\n${s}`:s;if(!o.outputStyle&&isProductionLikeMode(e)){o.outputStyle="compressed"}if(n){o.sourceMap=true;o.outFile=_path.default.join(e.rootContext,"style.css.map");o.sourceMapContents=true;o.omitSourceMapUrl=true;o.sourceMapEmbed=false}const{resourcePath:i}=e;const c=_path.default.extname(i);if(c&&c.toLowerCase()===".sass"&&typeof o.indentedSyntax==="undefined"){o.indentedSyntax=true}else{o.indentedSyntax=Boolean(o.indentedSyntax)}o.importer=o.importer?proxyCustomImporters(Array.isArray(o.importer)?o.importer:[o.importer],e):[];o.includePaths=[].concat(process.cwd()).concat((o.includePaths||[]).map((e=>_path.default.isAbsolute(e)?e:_path.default.join(process.cwd(),e)))).concat(process.env.SASS_PATH?process.env.SASS_PATH.split(process.platform==="win32"?";":":"):[]);if(typeof o.charset==="undefined"){o.charset=true}if(!o.logger){const s=t.warnRuleAsWarning===true;const r=e.getLogger("sass-loader");const formatSpan=e=>`${e.url||"-"}:${e.start.line}:${e.start.column}: `;o.logger={debug(e,t){let s="";if(t.span){s=formatSpan(t.span)}s+=e;r.debug(s)},warn(t,n){let o="";if(n.deprecation){o+="Deprecation "}if(n.span&&!n.stack){o=formatSpan(n.span)}o+=t;if(n.stack){o+=`\n\n${n.stack}`}if(s){e.emitWarning(new _SassWarning.default(o,n))}else{r.warn(o)}}}}return o}const MODULE_REQUEST_REGEX=/^[^?]*~/;const IS_MODULE_IMPORT=/^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/;function getPossibleRequests(e,t=false,s=false){let r=e;if(t){if(MODULE_REQUEST_REGEX.test(e)){r=r.replace(MODULE_REQUEST_REGEX,"")}if(IS_MODULE_IMPORT.test(e)){r=r[r.length-1]==="/"?r:`${r}/`;return[...new Set([r,e])]}}const n=_path.default.extname(r).toLowerCase();if(n===".css"){return[]}const o=_path.default.dirname(r);const a=o==="."?"":`${o}/`;const i=_path.default.basename(r);const c=_path.default.basename(r,n);return[...new Set([].concat(s?[`${a}_${c}.import${n}`,`${a}${c}.import${n}`]:[]).concat([`${a}_${i}`,`${a}${i}`]).concat(t?[e]:[]))]}function promiseResolve(e){return(t,s)=>new Promise(((r,n)=>{e(t,s,((e,t)=>{if(e){n(e)}else{r(t)}}))}))}const IS_SPECIAL_MODULE_IMPORT=/^~[^/]+$/;const IS_NATIVE_WIN32_PATH=/^[a-z]:[/\\]|^\\\\/i;function getWebpackResolver(e,t,s=[]){async function startResolving(e){if(e.length===0){return Promise.reject()}const[{possibleRequests:t}]=e;if(t.length===0){return Promise.reject()}const[{resolve:s,context:r}]=e;try{return await s(r,t[0])}catch(s){const[,...r]=t;if(r.length===0){const[,...t]=e;return startResolving(t)}e[0].possibleRequests=r;return startResolving(e)}}const r=t.info.includes("dart-sass");const n=promiseResolve(e({alias:[],aliasFields:[],conditionNames:[],descriptionFiles:[],extensions:[".sass",".scss",".css"],exportsFields:[],mainFields:[],mainFiles:["_index","index"],modules:[],restrictions:[/\.((sa|sc|c)ss)$/i],preferRelative:true}));const o=promiseResolve(e({alias:[],aliasFields:[],conditionNames:[],descriptionFiles:[],extensions:[".sass",".scss",".css"],exportsFields:[],mainFields:[],mainFiles:["_index.import","_index","index.import","index"],modules:[],restrictions:[/\.((sa|sc|c)ss)$/i],preferRelative:true}));const a=promiseResolve(e({dependencyType:"sass",conditionNames:["sass","style"],mainFields:["sass","style","main","..."],mainFiles:["_index","index","..."],extensions:[".sass",".scss",".css"],restrictions:[/\.((sa|sc|c)ss)$/i],preferRelative:true}));const i=promiseResolve(e({dependencyType:"sass",conditionNames:["sass","style"],mainFields:["sass","style","main","..."],mainFiles:["_index.import","_index","index.import","index","..."],extensions:[".sass",".scss",".css"],restrictions:[/\.((sa|sc|c)ss)$/i],preferRelative:true}));return(e,t,c)=>{if(!r&&!_path.default.isAbsolute(e)){return Promise.reject()}const l=t;const u=l.slice(0,5).toLowerCase()==="file:";if(u){try{t=_url.default.fileURLToPath(l)}catch(e){t=t.slice(7)}}let p=[];const f=!IS_SPECIAL_MODULE_IMPORT.test(t)&&!u&&!l.startsWith("/")&&!IS_NATIVE_WIN32_PATH.test(l);if(s.length>0&&f){const a=getPossibleRequests(t,false,c);if(!r){p=p.concat({resolve:c?o:n,context:_path.default.dirname(e),possibleRequests:a})}p=p.concat(s.map((e=>({resolve:c?o:n,context:e,possibleRequests:a}))))}const d=getPossibleRequests(t,true,c);p=p.concat({resolve:c?i:a,context:_path.default.dirname(e),possibleRequests:d});return startResolving(p)}}const MATCH_CSS=/\.css$/i;function getWebpackImporter(e,t,s){const r=getWebpackResolver(e.getResolve,t,s);return function importer(t,s,n){const{fromImport:o}=this;r(s,t,o).then((t=>{e.addDependency(_path.default.normalize(t));n({file:t.replace(MATCH_CSS,"")})})).catch((()=>{n({file:t})}))}}let nodeSassJobQueue=null;function getRenderFunctionFromSassImplementation(e){const t=e.info.includes("dart-sass");if(t){return e.render.bind(e)}if(nodeSassJobQueue===null){const t=Number(process.env.UV_THREADPOOL_SIZE||4);nodeSassJobQueue=_neoAsync.default.queue(e.render.bind(e),t-1)}return nodeSassJobQueue.push.bind(nodeSassJobQueue)}const ABSOLUTE_SCHEME=/^[A-Za-z0-9+\-.]+:/;function getURLType(e){if(e[0]==="/"){if(e[1]==="/"){return"scheme-relative"}return"path-absolute"}if(IS_NATIVE_WIN32_PATH.test(e)){return"path-absolute"}return ABSOLUTE_SCHEME.test(e)?"absolute":"path-relative"}function normalizeSourceMap(e,t){const s=e;delete s.file;s.sourceRoot="";s.sources=s.sources.map((e=>{const s=getURLType(e);if(s==="path-relative"){return _path.default.resolve(t,_path.default.normalize(e))}return e}));return s}},175:function(e){"use strict";e.exports=require("next/dist/compiled/neo-async")},17:function(e){"use strict";e.exports=require("path")},438:function(e){"use strict";e.exports=require("sass")},310:function(e){"use strict";e.exports=require("url")},596:function(e){"use strict";e.exports=JSON.parse('{"title":"Sass Loader options","type":"object","properties":{"implementation":{"description":"The implementation of the sass to be used.","link":"https://github.com/webpack-contrib/sass-loader#implementation","anyOf":[{"type":"string"},{"type":"object"}]},"sassOptions":{"description":"Options for `node-sass` or `sass` (`Dart Sass`) implementation.","link":"https://github.com/webpack-contrib/sass-loader#sassoptions","anyOf":[{"type":"object","additionalProperties":true},{"instanceof":"Function"}]},"additionalData":{"description":"Prepends/Appends `Sass`/`SCSS` code before the actual entry file.","link":"https://github.com/webpack-contrib/sass-loader#additionaldata","anyOf":[{"type":"string"},{"instanceof":"Function"}]},"sourceMap":{"description":"Enables/Disables generation of source maps.","link":"https://github.com/webpack-contrib/sass-loader#sourcemap","type":"boolean"},"webpackImporter":{"description":"Enables/Disables default `webpack` importer.","link":"https://github.com/webpack-contrib/sass-loader#webpackimporter","type":"boolean"},"warnRuleAsWarning":{"description":"Treats the \'@warn\' rule as a webpack warning.","link":"https://github.com/webpack-contrib/sass-loader#warnruleaswarning","type":"boolean"}},"additionalProperties":false}')}};var __webpack_module_cache__={};function __nccwpck_require__(e){var t=__webpack_module_cache__[e];if(t!==undefined){return t.exports}var s=__webpack_module_cache__[e]={exports:{}};var r=true;try{__webpack_modules__[e](s,s.exports,__nccwpck_require__);r=false}finally{if(r)delete __webpack_module_cache__[e]}return s.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var __webpack_exports__=__nccwpck_require__(917);module.exports=__webpack_exports__})(); \ No newline at end of file +(function(){var __webpack_modules__={12:function(e,t){function set(e,t,s){if(typeof s.value==="object")s.value=klona(s.value);if(!s.enumerable||s.get||s.set||!s.configurable||!s.writable||t==="__proto__"){Object.defineProperty(e,t,s)}else e[t]=s.value}function klona(e){if(typeof e!=="object")return e;var t=0,s,r,n,o=Object.prototype.toString.call(e);if(o==="[object Object]"){n=Object.create(e.__proto__||null)}else if(o==="[object Array]"){n=Array(e.length)}else if(o==="[object Set]"){n=new Set;e.forEach((function(e){n.add(klona(e))}))}else if(o==="[object Map]"){n=new Map;e.forEach((function(e,t){n.set(klona(t),klona(e))}))}else if(o==="[object Date]"){n=new Date(+e)}else if(o==="[object RegExp]"){n=new RegExp(e.source,e.flags)}else if(o==="[object DataView]"){n=new e.constructor(klona(e.buffer))}else if(o==="[object ArrayBuffer]"){n=e.slice(0)}else if(o.slice(-6)==="Array]"){n=new e.constructor(e)}if(n){for(r=Object.getOwnPropertySymbols(e);t{if(e){if(e.file){this.addDependency(r.default.normalize(e.file))}s(new a.default(e));return}let n=t.map?JSON.parse(t.map):null;if(n&&c){n=(0,o.normalizeSourceMap)(n,this.rootContext)}t.stats.includedFiles.forEach((e=>{const t=r.default.normalize(e);if(r.default.isAbsolute(t)){this.addDependency(t)}}));s(null,t.css.toString(),n)}))}var i=loader;t["default"]=i},636:function(__unused_webpack_module,exports,__nccwpck_require__){"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.getRenderFunctionFromSassImplementation=getRenderFunctionFromSassImplementation;exports.getSassImplementation=getSassImplementation;exports.getSassOptions=getSassOptions;exports.getWebpackImporter=getWebpackImporter;exports.getWebpackResolver=getWebpackResolver;exports.isSupportedFibers=isSupportedFibers;exports.normalizeSourceMap=normalizeSourceMap;var _url=_interopRequireDefault(__nccwpck_require__(310));var _path=_interopRequireDefault(__nccwpck_require__(17));var _full=__nccwpck_require__(12);var _neoAsync=_interopRequireDefault(__nccwpck_require__(175));var _SassWarning=_interopRequireDefault(__nccwpck_require__(955));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function getDefaultSassImplementation(){let sassImplPkg="sass";try{eval("require").resolve("sass")}catch(error){try{eval("require").resolve("node-sass");sassImplPkg="node-sass"}catch(e){sassImplPkg="sass"}}return __nccwpck_require__(438)}function getSassImplementation(e,t){let s=t;if(!s){try{s=getDefaultSassImplementation()}catch(t){e.emitError(t);return}}if(typeof s==="string"){try{s=require(s)}catch(t){e.emitError(t);return}}const{info:r}=s;if(!r){e.emitError(new Error("Unknown Sass implementation."));return}const n=r.split("\t");if(n.length<2){e.emitError(new Error(`Unknown Sass implementation "${r}".`));return}const[o]=n;if(o==="dart-sass"){return s}else if(o==="node-sass"){return s}e.emitError(new Error(`Unknown Sass implementation "${o}".`))}function isProductionLikeMode(e){return e.mode==="production"||!e.mode}function proxyCustomImporters(e,t){return[].concat(e).map((e=>function proxyImporter(...s){const r={...this,webpackLoaderContext:t};return e.apply(r,s)}))}function isSupportedFibers(){const[e]=process.versions.node.split(".");return Number(e)<16}async function getSassOptions(e,t,s,r,n){const o=(0,_full.klona)(t.sassOptions?typeof t.sassOptions==="function"?t.sassOptions(e)||{}:t.sassOptions:{});const a=r.info.includes("dart-sass");if(a&&isSupportedFibers()){const e=!o.fiber&&o.fiber!==false;if(e){let e;try{e=require.resolve("fibers")}catch(e){}if(e){o.fiber=require(e)}}else if(o.fiber===false){delete o.fiber}}else{delete o.fiber}o.file=e.resourcePath;o.data=t.additionalData?typeof t.additionalData==="function"?await t.additionalData(s,e):`${t.additionalData}\n${s}`:s;if(!o.outputStyle&&isProductionLikeMode(e)){o.outputStyle="compressed"}if(n){o.sourceMap=true;o.outFile=_path.default.join(e.rootContext,"style.css.map");o.sourceMapContents=true;o.omitSourceMapUrl=true;o.sourceMapEmbed=false}const{resourcePath:i}=e;const c=_path.default.extname(i);if(c&&c.toLowerCase()===".sass"&&typeof o.indentedSyntax==="undefined"){o.indentedSyntax=true}else{o.indentedSyntax=Boolean(o.indentedSyntax)}o.importer=o.importer?proxyCustomImporters(Array.isArray(o.importer)?o.importer:[o.importer],e):[];o.includePaths=[].concat(process.cwd()).concat((o.includePaths||[]).map((e=>_path.default.isAbsolute(e)?e:_path.default.join(process.cwd(),e)))).concat(process.env.SASS_PATH?process.env.SASS_PATH.split(process.platform==="win32"?";":":"):[]);if(typeof o.charset==="undefined"){o.charset=true}if(!o.logger){const s=t.warnRuleAsWarning===true;const r=e.getLogger("sass-loader");const formatSpan=e=>`${e.url||"-"}:${e.start.line}:${e.start.column}: `;o.logger={debug(e,t){let s="";if(t.span){s=formatSpan(t.span)}s+=e;r.debug(s)},warn(t,n){let o="";if(n.deprecation){o+="Deprecation "}if(n.span&&!n.stack){o=formatSpan(n.span)}o+=t;if(n.stack){o+=`\n\n${n.stack}`}if(s){e.emitWarning(new _SassWarning.default(o,n))}else{r.warn(o)}}}}return o}const MODULE_REQUEST_REGEX=/^[^?]*~/;const IS_MODULE_IMPORT=/^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/;function getPossibleRequests(e,t=false,s=false){let r=e;if(t){if(MODULE_REQUEST_REGEX.test(e)){r=r.replace(MODULE_REQUEST_REGEX,"")}if(IS_MODULE_IMPORT.test(e)){r=r[r.length-1]==="/"?r:`${r}/`;return[...new Set([r,e])]}}const n=_path.default.extname(r).toLowerCase();if(n===".css"){return[]}const o=_path.default.dirname(r);const a=o==="."?"":`${o}/`;const i=_path.default.basename(r);const c=_path.default.basename(r,n);return[...new Set([].concat(s?[`${a}_${c}.import${n}`,`${a}${c}.import${n}`]:[]).concat([`${a}_${i}`,`${a}${i}`]).concat(t?[e]:[]))]}function promiseResolve(e){return(t,s)=>new Promise(((r,n)=>{e(t,s,((e,t)=>{if(e){n(e)}else{r(t)}}))}))}const IS_SPECIAL_MODULE_IMPORT=/^~[^/]+$/;const IS_NATIVE_WIN32_PATH=/^[a-z]:[/\\]|^\\\\/i;function getWebpackResolver(e,t,s=[]){async function startResolving(e){if(e.length===0){return Promise.reject()}const[{possibleRequests:t}]=e;if(t.length===0){return Promise.reject()}const[{resolve:s,context:r}]=e;try{return await s(r,t[0])}catch(s){const[,...r]=t;if(r.length===0){const[,...t]=e;return startResolving(t)}e[0].possibleRequests=r;return startResolving(e)}}const r=t.info.includes("dart-sass");const n=promiseResolve(e({alias:[],aliasFields:[],conditionNames:[],descriptionFiles:[],extensions:[".sass",".scss",".css"],exportsFields:[],mainFields:[],mainFiles:["_index","index"],modules:[],restrictions:[/\.((sa|sc|c)ss)$/i],preferRelative:true}));const o=promiseResolve(e({alias:[],aliasFields:[],conditionNames:[],descriptionFiles:[],extensions:[".sass",".scss",".css"],exportsFields:[],mainFields:[],mainFiles:["_index.import","_index","index.import","index"],modules:[],restrictions:[/\.((sa|sc|c)ss)$/i],preferRelative:true}));const a=promiseResolve(e({dependencyType:"sass",conditionNames:["sass","style"],mainFields:["sass","style","main","..."],mainFiles:["_index","index","..."],extensions:[".sass",".scss",".css"],restrictions:[/\.((sa|sc|c)ss)$/i],preferRelative:true}));const i=promiseResolve(e({dependencyType:"sass",conditionNames:["sass","style"],mainFields:["sass","style","main","..."],mainFiles:["_index.import","_index","index.import","index","..."],extensions:[".sass",".scss",".css"],restrictions:[/\.((sa|sc|c)ss)$/i],preferRelative:true}));return(e,t,c)=>{if(!r&&!_path.default.isAbsolute(e)){return Promise.reject()}const l=t;const u=l.slice(0,5).toLowerCase()==="file:";if(u){try{t=_url.default.fileURLToPath(l)}catch(e){t=t.slice(7)}}let p=[];const f=!IS_SPECIAL_MODULE_IMPORT.test(t)&&!u&&!l.startsWith("/")&&!IS_NATIVE_WIN32_PATH.test(l);if(s.length>0&&f){const a=getPossibleRequests(t,false,c);if(!r){p=p.concat({resolve:c?o:n,context:_path.default.dirname(e),possibleRequests:a})}p=p.concat(s.map((e=>({resolve:c?o:n,context:e,possibleRequests:a}))))}const d=getPossibleRequests(t,true,c);p=p.concat({resolve:c?i:a,context:_path.default.dirname(e),possibleRequests:d});return startResolving(p)}}const MATCH_CSS=/\.css$/i;function getWebpackImporter(e,t,s){const r=getWebpackResolver(e.getResolve,t,s);return function importer(t,s,n){const{fromImport:o}=this;r(s,t,o).then((t=>{e.addDependency(_path.default.normalize(t));n({file:t.replace(MATCH_CSS,"")})})).catch((()=>{n({file:t})}))}}let nodeSassJobQueue=null;function getRenderFunctionFromSassImplementation(e){const t=e.info.includes("dart-sass");if(t){return e.render.bind(e)}if(nodeSassJobQueue===null){const t=Number(process.env.UV_THREADPOOL_SIZE||4);nodeSassJobQueue=_neoAsync.default.queue(e.render.bind(e),t-1)}return nodeSassJobQueue.push.bind(nodeSassJobQueue)}const ABSOLUTE_SCHEME=/^[A-Za-z0-9+\-.]+:/;function getURLType(e){if(e[0]==="/"){if(e[1]==="/"){return"scheme-relative"}return"path-absolute"}if(IS_NATIVE_WIN32_PATH.test(e)){return"path-absolute"}return ABSOLUTE_SCHEME.test(e)?"absolute":"path-relative"}function normalizeSourceMap(e,t){const s=e;delete s.file;s.sourceRoot="";s.sources=s.sources.map((e=>{const s=getURLType(e);if(s==="path-relative"){return _path.default.resolve(t,_path.default.normalize(e))}return e}));return s}},175:function(e){"use strict";e.exports=require("next/dist/compiled/neo-async")},17:function(e){"use strict";e.exports=require("path")},438:function(e){"use strict";e.exports=require("sass")},310:function(e){"use strict";e.exports=require("url")},921:function(e){"use strict";e.exports=JSON.parse('{"title":"Sass Loader options","type":"object","properties":{"implementation":{"description":"The implementation of the sass to be used.","link":"https://github.com/webpack-contrib/sass-loader#implementation","anyOf":[{"type":"string"},{"type":"object"}]},"sassOptions":{"description":"Options for `node-sass` or `sass` (`Dart Sass`) implementation.","link":"https://github.com/webpack-contrib/sass-loader#sassoptions","anyOf":[{"type":"object","additionalProperties":true},{"instanceof":"Function"}]},"additionalData":{"description":"Prepends/Appends `Sass`/`SCSS` code before the actual entry file.","link":"https://github.com/webpack-contrib/sass-loader#additionaldata","anyOf":[{"type":"string"},{"instanceof":"Function"}]},"sourceMap":{"description":"Enables/Disables generation of source maps.","link":"https://github.com/webpack-contrib/sass-loader#sourcemap","type":"boolean"},"webpackImporter":{"description":"Enables/Disables default `webpack` importer.","link":"https://github.com/webpack-contrib/sass-loader#webpackimporter","type":"boolean"},"warnRuleAsWarning":{"description":"Treats the \'@warn\' rule as a webpack warning.","link":"https://github.com/webpack-contrib/sass-loader#warnruleaswarning","type":"boolean"}},"additionalProperties":false}')}};var __webpack_module_cache__={};function __nccwpck_require__(e){var t=__webpack_module_cache__[e];if(t!==undefined){return t.exports}var s=__webpack_module_cache__[e]={exports:{}};var r=true;try{__webpack_modules__[e](s,s.exports,__nccwpck_require__);r=false}finally{if(r)delete __webpack_module_cache__[e]}return s.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var __webpack_exports__=__nccwpck_require__(601);module.exports=__webpack_exports__})(); \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dfb82e3bc636..2fcfa9c0e1af 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1058,8 +1058,8 @@ importers: specifier: 0.22.6 version: 0.22.6 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.1 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.1(react-refresh@0.12.0)(webpack@5.86.0)' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.2 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.2(react-refresh@0.12.0)(webpack@5.86.0)' acorn: specifier: 8.5.0 version: 8.5.0 @@ -1317,7 +1317,7 @@ importers: version: 0.13.4 sass-loader: specifier: 12.4.0 - version: 12.4.0(webpack@5.86.0) + version: 12.4.0(sass@1.54.0)(webpack@5.86.0) schema-utils2: specifier: npm:schema-utils@2.7.1 version: /schema-utils@2.7.1 @@ -23483,7 +23483,7 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - /sass-loader@12.4.0(webpack@5.86.0): + /sass-loader@12.4.0(sass@1.54.0)(webpack@5.86.0): resolution: {integrity: sha512-7xN+8khDIzym1oL9XyS6zP6Ges+Bo2B2xbPrjdMHEYyV3AQYhd/wXeru++3ODHF0zMjYmVadblSKrPrjEkL8mg==} engines: {node: '>= 12.13.0'} peerDependencies: @@ -23501,6 +23501,7 @@ packages: dependencies: klona: 2.0.4 neo-async: 2.6.2 + sass: 1.54.0 webpack: 5.86.0(@swc/core@1.3.85) dev: true @@ -26756,9 +26757,9 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.1(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.1} - id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.1' + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.2(react-refresh@0.12.0)(webpack@5.86.0)': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.2} + id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231006.2' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: From 2a479316ea4f28b4e9f48c8babf5dcabae2fb164 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 6 Oct 2023 11:05:45 +0200 Subject: [PATCH 11/15] Remove app dir warning test (#56350) This test was failing in Turbopack because the option no longer exists. Fine to remove it for now. --- .../test/index.test.js | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/test/integration/config-experimental-warning/test/index.test.js b/test/integration/config-experimental-warning/test/index.test.js index 79831f282680..a4a6bed21fae 100644 --- a/test/integration/config-experimental-warning/test/index.test.js +++ b/test/integration/config-experimental-warning/test/index.test.js @@ -19,17 +19,6 @@ async function collectStdout(appDir) { return stdout } -async function collectStderr(appDir) { - let stderr = '' - const port = await findPort() - app = await launchApp(appDir, port, { - onStderr(msg) { - stderr += msg - }, - }) - return stderr -} - describe('Config Experimental Warning', () => { afterEach(() => { configFile.write('') @@ -123,19 +112,4 @@ describe('Config Experimental Warning', () => { expect(stdout).toMatch(' · workerThreads') expect(stdout).toMatch(' · scrollRestoration') }) - - it('should show warning for dropped experimental.appDir option', async () => { - configFile.write(` - module.exports = { - experimental: { - appDir: true, - } - } - `) - - const stderr = await collectStderr(appDir) - expect(stderr).toMatch( - 'App router is available by default now, `experimental.appDir` option can be safely removed.' - ) - }) }) From 5a49b88fb9a4a773703c0ab82f107d72e3f5cabe Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 6 Oct 2023 11:06:06 +0200 Subject: [PATCH 12/15] Use consistent name for App Router tests (#56352) Ensures all App Router tests have a unique name and similar reference (with `-`). --------- Co-authored-by: Jiachi Liu --- test/e2e/app-dir/app-css-pageextensions/index.test.ts | 2 +- test/e2e/app-dir/app-css/index.test.ts | 2 +- test/e2e/app-dir/app-middleware/app-middleware.test.ts | 4 ++-- test/e2e/app-dir/app-prefetch/prefetching.test.ts | 2 +- test/e2e/app-dir/app-validation/validation.test.ts | 2 +- test/e2e/app-dir/app/index.test.ts | 2 +- test/e2e/app-dir/import/import.test.ts | 2 +- test/e2e/app-dir/next-font/next-font.test.ts | 2 +- test/e2e/app-dir/next-image/next-image-https.test.ts | 2 +- test/e2e/app-dir/next-image/next-image.test.ts | 2 +- test/e2e/skip-trailing-slash-redirect/index.test.ts | 2 +- test/integration/app-dir-export/test/config.test.ts | 2 +- test/integration/app-dir-export/test/start.test.ts | 2 +- test/production/build-spinners/index.test.ts | 4 ++-- 14 files changed, 16 insertions(+), 16 deletions(-) diff --git a/test/e2e/app-dir/app-css-pageextensions/index.test.ts b/test/e2e/app-dir/app-css-pageextensions/index.test.ts index 81a13a361d05..a2cb488426ae 100644 --- a/test/e2e/app-dir/app-css-pageextensions/index.test.ts +++ b/test/e2e/app-dir/app-css-pageextensions/index.test.ts @@ -1,7 +1,7 @@ import { createNextDescribe } from 'e2e-utils' createNextDescribe( - 'app dir css with pageextensions', + 'app dir - css with pageextensions', { files: __dirname, skipDeployment: true, diff --git a/test/e2e/app-dir/app-css/index.test.ts b/test/e2e/app-dir/app-css/index.test.ts index 4b160a299c89..3d1ac7277e93 100644 --- a/test/e2e/app-dir/app-css/index.test.ts +++ b/test/e2e/app-dir/app-css/index.test.ts @@ -2,7 +2,7 @@ import { createNextDescribe } from 'e2e-utils' import { check } from 'next-test-utils' createNextDescribe( - 'app dir css', + 'app dir - css', { files: __dirname, skipDeployment: true, diff --git a/test/e2e/app-dir/app-middleware/app-middleware.test.ts b/test/e2e/app-dir/app-middleware/app-middleware.test.ts index 80f0bae676d8..661839a2aa37 100644 --- a/test/e2e/app-dir/app-middleware/app-middleware.test.ts +++ b/test/e2e/app-dir/app-middleware/app-middleware.test.ts @@ -138,7 +138,7 @@ createNextDescribe( ) createNextDescribe( - 'app dir middleware without pages dir', + 'app dir - middleware without pages dir', { files: { app: new FileRef(path.join(__dirname, 'app')), @@ -168,7 +168,7 @@ createNextDescribe( ) createNextDescribe( - 'app dir middleware with middleware in src dir', + 'app dir - middleware with middleware in src dir', { files: { 'src/app': new FileRef(path.join(__dirname, 'app')), diff --git a/test/e2e/app-dir/app-prefetch/prefetching.test.ts b/test/e2e/app-dir/app-prefetch/prefetching.test.ts index 2d9b47669089..9d14424c3c6b 100644 --- a/test/e2e/app-dir/app-prefetch/prefetching.test.ts +++ b/test/e2e/app-dir/app-prefetch/prefetching.test.ts @@ -28,7 +28,7 @@ const browserConfigWithFixedTime = { } createNextDescribe( - 'app dir prefetching', + 'app dir - prefetching', { files: __dirname, skipDeployment: true, diff --git a/test/e2e/app-dir/app-validation/validation.test.ts b/test/e2e/app-dir/app-validation/validation.test.ts index b00dde4d778e..3146ece06b95 100644 --- a/test/e2e/app-dir/app-validation/validation.test.ts +++ b/test/e2e/app-dir/app-validation/validation.test.ts @@ -1,7 +1,7 @@ import { createNextDescribe } from 'e2e-utils' createNextDescribe( - 'app dir validation', + 'app dir - validation', { files: __dirname, skipDeployment: true, diff --git a/test/e2e/app-dir/app/index.test.ts b/test/e2e/app-dir/app/index.test.ts index e082ebfe292b..c69fef660f5d 100644 --- a/test/e2e/app-dir/app/index.test.ts +++ b/test/e2e/app-dir/app/index.test.ts @@ -6,7 +6,7 @@ import { BrowserInterface } from 'test/lib/browsers/base' import { Request } from 'playwright-core' createNextDescribe( - 'app dir', + 'app dir - basic', { files: __dirname, buildCommand: process.env.NEXT_EXPERIMENTAL_COMPILE diff --git a/test/e2e/app-dir/import/import.test.ts b/test/e2e/app-dir/import/import.test.ts index 24743f773f62..55d313ba8188 100644 --- a/test/e2e/app-dir/import/import.test.ts +++ b/test/e2e/app-dir/import/import.test.ts @@ -1,7 +1,7 @@ import { createNextDescribe } from 'e2e-utils' createNextDescribe( - 'app dir imports', + 'app dir - imports', { files: __dirname, }, diff --git a/test/e2e/app-dir/next-font/next-font.test.ts b/test/e2e/app-dir/next-font/next-font.test.ts index 4320d6b556ea..77a8feeb6c7f 100644 --- a/test/e2e/app-dir/next-font/next-font.test.ts +++ b/test/e2e/app-dir/next-font/next-font.test.ts @@ -25,7 +25,7 @@ const getAttrs = (elems: Cheerio) => describe.each([['app'], ['app-old']])('%s', (fixture: string) => { createNextDescribe( - 'app dir next-font', + 'app dir - next-font', { files: { app: new FileRef(join(__dirname, fixture)), diff --git a/test/e2e/app-dir/next-image/next-image-https.test.ts b/test/e2e/app-dir/next-image/next-image-https.test.ts index fd97a867d8cb..7f45437fa791 100644 --- a/test/e2e/app-dir/next-image/next-image-https.test.ts +++ b/test/e2e/app-dir/next-image/next-image-https.test.ts @@ -1,7 +1,7 @@ import { createNextDescribe } from '../../../lib/e2e-utils' createNextDescribe( - 'app dir next-image (with https)', + 'app dir - next-image (with https)', { files: __dirname, skipDeployment: true, diff --git a/test/e2e/app-dir/next-image/next-image.test.ts b/test/e2e/app-dir/next-image/next-image.test.ts index 108dfef63edb..2640b56ed107 100644 --- a/test/e2e/app-dir/next-image/next-image.test.ts +++ b/test/e2e/app-dir/next-image/next-image.test.ts @@ -1,7 +1,7 @@ import { createNextDescribe } from 'e2e-utils' createNextDescribe( - 'app dir next-image', + 'app dir - next-image', { files: __dirname, skipDeployment: true, diff --git a/test/e2e/skip-trailing-slash-redirect/index.test.ts b/test/e2e/skip-trailing-slash-redirect/index.test.ts index d9cf1e90adbe..2b0d9ca7df64 100644 --- a/test/e2e/skip-trailing-slash-redirect/index.test.ts +++ b/test/e2e/skip-trailing-slash-redirect/index.test.ts @@ -367,7 +367,7 @@ describe('skip-trailing-slash-redirect', () => { runSharedTests('/') }) - describe('app dir', () => { + describe('app dir - skip trailing slash redirect', () => { runSharedTests('/with-app-dir/') }) }) diff --git a/test/integration/app-dir-export/test/config.test.ts b/test/integration/app-dir-export/test/config.test.ts index 79e5c8456905..1cfe54c76d3b 100644 --- a/test/integration/app-dir-export/test/config.test.ts +++ b/test/integration/app-dir-export/test/config.test.ts @@ -10,7 +10,7 @@ import { nextConfig, } from './utils' -describe('app dir with output export (next dev / next build)', () => { +describe('app dir - with output export (next dev / next build)', () => { ;(process.env.TURBOPACK ? describe.skip : describe)('production mode', () => { it('should throw when exportPathMap configured', async () => { nextConfig.replace( diff --git a/test/integration/app-dir-export/test/start.test.ts b/test/integration/app-dir-export/test/start.test.ts index b7d5241493c1..a801470efd70 100644 --- a/test/integration/app-dir-export/test/start.test.ts +++ b/test/integration/app-dir-export/test/start.test.ts @@ -17,7 +17,7 @@ const exportDir = join(appDir, 'out') const nextConfig = new File(join(appDir, 'next.config.js')) let app -describe('app dir with output export (next start)', () => { +describe('app dir - with output export (next start)', () => { ;(process.env.TURBOPACK ? describe.skip : describe)('production mode', () => { afterEach(async () => { await killApp(app) diff --git a/test/production/build-spinners/index.test.ts b/test/production/build-spinners/index.test.ts index 37114d18e7ce..6144eb6e6a05 100644 --- a/test/production/build-spinners/index.test.ts +++ b/test/production/build-spinners/index.test.ts @@ -66,9 +66,9 @@ describe('build-spinners', () => { }) it.each([ - { name: 'app dir', files: appDirFiles }, + { name: 'app dir - basic', files: appDirFiles }, { - name: 'app dir (compile workers)', + name: 'app dir - (compile workers)', files: [ ...appDirFiles, { From f95421289f3fd399f360a372c4a5bc5e2b1a0cd8 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 6 Oct 2023 11:10:12 +0200 Subject: [PATCH 13/15] Remove isTurbo check in custom-routes test (#56360) This variable wasn't used anymore. --- .../custom-routes/test/index.test.js | 104 +----------------- 1 file changed, 1 insertion(+), 103 deletions(-) diff --git a/test/integration/custom-routes/test/index.test.js b/test/integration/custom-routes/test/index.test.js index 0a77ca7db82f..0ba6ce2ffbd7 100644 --- a/test/integration/custom-routes/test/index.test.js +++ b/test/integration/custom-routes/test/index.test.js @@ -38,7 +38,7 @@ let buildId let appPort let app -const runTests = (isDev = false, isTurbo = false) => { +const runTests = (isDev = false) => { it.each([ { path: '/to-ANOTHER', @@ -78,9 +78,6 @@ const runTests = (isDev = false, isTurbo = false) => { ) it('should successfully rewrite a WebSocket request', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const messages = [] const ws = await new Promise((resolve, reject) => { let socket = new WebSocket(`ws://localhost:${appPort}/to-websocket`) @@ -104,9 +101,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should successfully rewrite a WebSocket request to a page', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const messages = [] try { const ws = await new Promise((resolve, reject) => { @@ -147,9 +141,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should handle has query encoding correctly', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - for (const expected of [ { post: 'first', @@ -192,9 +183,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should handle external beforeFiles rewrite correctly', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/overridden') const html = await res.text() @@ -213,9 +201,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should handle beforeFiles rewrite to dynamic route correctly', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/nfl') const html = await res.text() @@ -242,9 +227,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should handle beforeFiles rewrite to partly dynamic route correctly', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/nfl') const html = await res.text() @@ -282,9 +264,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should resolveHref correctly navigating through history', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const browser = await webdriver(appPort, '/') await browser.eval('window.beforeNav = 1') @@ -340,9 +319,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should not hang when proxy rewrite fails', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/to-nowhere', undefined, { timeout: 5000, }) @@ -363,9 +339,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should provide params correctly for rewrite to auto-export non-dynamic page', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const browser = await webdriver( appPort, '/rewriting-to-another-auto-export/first' @@ -391,9 +364,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should handle param like headers properly', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/my-other-header/my-path') expect(res.headers.get('x-path')).toBe('my-path') expect(res.headers.get('somemy-path')).toBe('hi') @@ -412,9 +382,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should not match dynamic route immediately after applying header', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/blog/post-321') expect(res.headers.get('x-something')).toBe('applied-everywhere') @@ -581,9 +548,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should have correct encoding for params with catchall rewrite', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const html = await renderViaHTTP( appPort, '/catchall-rewrite/hello%20world%3Fw%3D24%26focalpoint%3Dcenter?a=b' @@ -606,9 +570,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should have correct header for catchall rewrite', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/catchall-header/hello/world?a=b') const headerValue = res.headers.get('x-value') expect(headerValue).toBe('hello/world') @@ -634,9 +595,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should have correctly encoded params in query for redirect', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP( appPort, '/query-redirect/hello%20world%3Fw%3D24%26focalpoint%3Dcenter/world?a=b', @@ -744,9 +702,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should work with rewrite when only specifying href', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const browser = await webdriver(appPort, '/nav') await browser.eval('window.beforeNav = 1') await browser @@ -763,9 +718,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should work with rewrite when only specifying href and ends in dynamic route', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const browser = await webdriver(appPort, '/nav') await browser.eval('window.beforeNav = 1') await browser @@ -795,9 +747,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should match /_next file after rewrite', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - await renderViaHTTP(appPort, '/hello') const data = await renderViaHTTP( appPort, @@ -816,52 +765,34 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should apply headers for exact match', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/add-header') expect(res.headers.get('x-custom-header')).toBe('hello world') expect(res.headers.get('x-another-header')).toBe('hello again') }) it('should apply headers for multi match', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/my-headers/first') expect(res.headers.get('x-first-header')).toBe('first') expect(res.headers.get('x-second-header')).toBe('second') }) it('should apply params for header key/values', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/my-other-header/first') expect(res.headers.get('x-path')).toBe('first') expect(res.headers.get('somefirst')).toBe('hi') }) it('should support URL for header key/values', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/without-params/url') expect(res.headers.get('x-origin')).toBe('https://example.com') }) it('should apply params header key/values with URL', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/with-params/url/first') expect(res.headers.get('x-url')).toBe('https://example.com/first') }) it('should apply params header key/values with URL that has port', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/with-params/url2/first') expect(res.headers.get('x-url')).toBe( 'https://example.com:8080?hello=first' @@ -869,9 +800,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should support named pattern for header key/values', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/named-pattern/hello') expect(res.headers.get('x-something')).toBe('value=hello') expect(res.headers.get('path-hello')).toBe('end') @@ -934,9 +862,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should have correctly encoded query in location and refresh headers', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP( appPort, // Query unencoded is ?テスト=あ @@ -976,9 +901,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should handle encoded value in the pathname correctly', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP( appPort, '/redirect/me/to-about/' + encodeURI('\\google.com'), @@ -1054,9 +976,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should match missing header headers correctly', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/missing-headers-1', undefined, { headers: { 'x-my-header': 'hello world!!', @@ -1072,9 +991,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should match missing query headers correctly', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/missing-headers-2', { 'my-query': 'hellooo', }) @@ -1088,9 +1004,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should match missing cookie headers correctly', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/missing-headers-3', undefined, { headers: { cookie: 'loggedIn=true', @@ -1327,9 +1240,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should match has rewrite correctly before files', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res1 = await fetchViaHTTP(appPort, '/hello') expect(res1.status).toBe(200) const $1 = cheerio.load(await res1.text()) @@ -1497,9 +1407,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should match has header for header correctly', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/has-header-1', undefined, { headers: { 'x-my-header': 'hello world!!', @@ -1516,9 +1423,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should match has query for header correctly', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP( appPort, '/has-header-2', @@ -1539,9 +1443,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should match has cookie for header correctly', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/has-header-3', undefined, { headers: { cookie: 'loggedIn=true', @@ -1558,9 +1459,6 @@ const runTests = (isDev = false, isTurbo = false) => { }) it('should match has host for header correctly', async () => { - // TODO: remove once test failure has been fixed - if (isTurbo) return - const res = await fetchViaHTTP(appPort, '/has-header-4', undefined, { headers: { host: 'example.com', From bfdb349ebadced0346aa5b9c017851a166c493f6 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 6 Oct 2023 11:16:57 +0200 Subject: [PATCH 14/15] Remove ServerDirectiveTransformer (#56496) As discussed with @jridgewell this removes the hard error when using `"use server"` in Turbopack. --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../next-core/src/next_client/context.rs | 6 ----- .../crates/next-core/src/next_import_map.rs | 14 +++++++++++ .../next-core/src/next_server/context.rs | 23 +++++-------------- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/packages/next-swc/crates/next-core/src/next_client/context.rs b/packages/next-swc/crates/next-core/src/next_client/context.rs index fe3b43aaf156..08069da234d6 100644 --- a/packages/next-swc/crates/next-core/src/next_client/context.rs +++ b/packages/next-swc/crates/next-core/src/next_client/context.rs @@ -19,7 +19,6 @@ use turbopack_binding::{ }, dev::{react_refresh::assert_can_resolve_react_refresh, DevChunkingContext}, ecmascript::chunk::EcmascriptChunkingContext, - ecmascript_plugin::transform::directives::server::ServerDirectiveTransformer, node::execution_context::ExecutionContext, turbopack::{ condition::ContextCondition, @@ -232,11 +231,6 @@ pub async fn get_client_module_options_context( *get_emotion_transform_plugin(next_config).await?, *get_styled_components_transform_plugin(next_config).await?, *get_styled_jsx_transform_plugin().await?, - Some(Vc::cell(Box::new(ServerDirectiveTransformer::new( - // ServerDirective is not implemented yet and always reports an issue. - // We don't have to pass a valid transition name yet, but the API is prepared. - &Vc::cell("TODO".to_string()), - )) as _)), ] .into_iter() .flatten() diff --git a/packages/next-swc/crates/next-core/src/next_import_map.rs b/packages/next-swc/crates/next-core/src/next_import_map.rs index cec565798086..3d0f2b788b67 100644 --- a/packages/next-swc/crates/next-core/src/next_import_map.rs +++ b/packages/next-swc/crates/next-core/src/next_import_map.rs @@ -280,6 +280,20 @@ pub async fn get_next_server_import_map( "next/dist/build/webpack/loaders/next-flight-loader/action-proxy", ), ); + import_map.insert_exact_alias( + "private-next-rsc-action-client-wrapper", + request_to_import_mapping( + project_path, + "next/dist/build/webpack/loaders/next-flight-loader/action-client-wrapper", + ), + ); + import_map.insert_exact_alias( + "private-next-rsc-action-validate", + request_to_import_mapping( + project_path, + "next/dist/build/webpack/loaders/next-flight-loader/action-validate", + ), + ); import_map.insert_exact_alias( "next/head", request_to_import_mapping(project_path, "next/dist/client/components/noop-head"), diff --git a/packages/next-swc/crates/next-core/src/next_server/context.rs b/packages/next-swc/crates/next-core/src/next_server/context.rs index d789721362c5..02f64a86c574 100644 --- a/packages/next-swc/crates/next-core/src/next_server/context.rs +++ b/packages/next-swc/crates/next-core/src/next_server/context.rs @@ -19,9 +19,7 @@ use turbopack_binding::{ resolve::{parse::Request, pattern::Pattern}, }, ecmascript::TransformPlugin, - ecmascript_plugin::transform::directives::{ - client::ClientDirectiveTransformer, server::ServerDirectiveTransformer, - }, + ecmascript_plugin::transform::directives::client::ClientDirectiveTransformer, node::execution_context::ExecutionContext, turbopack::{ condition::ContextCondition, @@ -276,12 +274,6 @@ pub async fn get_server_module_options_context( let styled_components_transform_plugin = *get_styled_components_transform_plugin(next_config).await?; let styled_jsx_transform_plugin = *get_styled_jsx_transform_plugin().await?; - let server_directive_transform_plugin = - Some(Vc::cell(Box::new(ServerDirectiveTransformer::new( - // ServerDirective is not implemented yet and always reports an issue. - // We don't have to pass a valid transition name yet, but the API is prepared. - &Vc::cell("TODO".to_string()), - )) as _)); // ModuleOptionsContext related options let tsconfig = get_typescript_transform_options(project_path); @@ -374,7 +366,6 @@ pub async fn get_server_module_options_context( let mut base_source_transforms: Vec> = vec![ styled_components_transform_plugin, styled_jsx_transform_plugin, - server_directive_transform_plugin, ] .into_iter() .flatten() @@ -433,13 +424,11 @@ pub async fn get_server_module_options_context( ecmascript_client_reference_transition_name, .. } => { - let mut base_source_transforms: Vec> = vec![ - styled_components_transform_plugin, - server_directive_transform_plugin, - ] - .into_iter() - .flatten() - .collect(); + let mut base_source_transforms: Vec> = + vec![styled_components_transform_plugin] + .into_iter() + .flatten() + .collect(); if let Some(ecmascript_client_reference_transition_name) = ecmascript_client_reference_transition_name From 5aca71cfa6c5e46d874ec1dce3b334e6bbea65d0 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Fri, 6 Oct 2023 12:00:47 +0000 Subject: [PATCH 15/15] v13.5.5-canary.3 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index b4ff2eda07dc..73f7830deabd 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "13.5.5-canary.2" + "version": "13.5.5-canary.3" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 1ca01794a8ee..bda0b44a9471 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "13.5.5-canary.2", + "version": "13.5.5-canary.3", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index ab5cafb81e28..eb08d2c37fbb 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "13.5.5-canary.2", + "version": "13.5.5-canary.3", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "13.5.5-canary.2", + "@next/eslint-plugin-next": "13.5.5-canary.3", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.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 d37cf3822c4f..98de0667bb45 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": "13.5.5-canary.2", + "version": "13.5.5-canary.3", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index e8dac1caf89d..26ab2c54328d 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "13.5.5-canary.2", + "version": "13.5.5-canary.3", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 44ac0d40b40a..6a61ed82deca 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "13.5.5-canary.2", + "version": "13.5.5-canary.3", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 81b150a3b928..eb8b9aa8c42f 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "13.5.5-canary.2", + "version": "13.5.5-canary.3", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index e3c5a99ea548..441ce48dd794 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "13.5.5-canary.2", + "version": "13.5.5-canary.3", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 102a8ed4d33e..70af876473f6 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "13.5.5-canary.2", + "version": "13.5.5-canary.3", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index cd3dca272564..a6eefa6c8379 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "13.5.5-canary.2", + "version": "13.5.5-canary.3", "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 d498743e0287..5985e40f640d 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "13.5.5-canary.2", + "version": "13.5.5-canary.3", "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 c715e5a21092..c327aa6ecdf1 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "13.5.5-canary.2", + "version": "13.5.5-canary.3", "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 eb13e7a3d6d4..3efe409b5eba 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "13.5.5-canary.2", + "version": "13.5.5-canary.3", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index b743ef8fa555..c19051cb5c19 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "13.5.5-canary.2", + "version": "13.5.5-canary.3", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -90,7 +90,7 @@ ] }, "dependencies": { - "@next/env": "13.5.5-canary.2", + "@next/env": "13.5.5-canary.3", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -144,11 +144,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "13.5.5-canary.2", - "@next/polyfill-nomodule": "13.5.5-canary.2", - "@next/react-dev-overlay": "13.5.5-canary.2", - "@next/react-refresh-utils": "13.5.5-canary.2", - "@next/swc": "13.5.5-canary.2", + "@next/polyfill-module": "13.5.5-canary.3", + "@next/polyfill-nomodule": "13.5.5-canary.3", + "@next/react-dev-overlay": "13.5.5-canary.3", + "@next/react-refresh-utils": "13.5.5-canary.3", + "@next/swc": "13.5.5-canary.3", "@opentelemetry/api": "1.4.1", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 81edef1fd77a..69403242ad9d 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": "13.5.5-canary.2", + "version": "13.5.5-canary.3", "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 6c648bd5fc2d..0fcf62ad96dc 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": "13.5.5-canary.2", + "version": "13.5.5-canary.3", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index fbef1a4a4f25..8ab2869965ee 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "13.5.5-canary.2", + "version": "13.5.5-canary.3", "private": true, "repository": { "url": "vercel/next.js", @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "13.5.5-canary.2", + "next": "13.5.5-canary.3", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2fcfa9c0e1af..a31c55dd5bc7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -732,7 +732,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 13.5.5-canary.2 + specifier: 13.5.5-canary.3 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -793,7 +793,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 13.5.5-canary.2 + specifier: 13.5.5-canary.3 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -917,19 +917,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 13.5.5-canary.2 + specifier: 13.5.5-canary.3 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 13.5.5-canary.2 + specifier: 13.5.5-canary.3 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 13.5.5-canary.2 + specifier: 13.5.5-canary.3 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 13.5.5-canary.2 + specifier: 13.5.5-canary.3 version: link:../react-refresh-utils '@next/swc': - specifier: 13.5.5-canary.2 + specifier: 13.5.5-canary.3 version: link:../next-swc '@opentelemetry/api': specifier: 1.4.1 @@ -1583,7 +1583,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 13.5.5-canary.2 + specifier: 13.5.5-canary.3 version: link:../next outdent: specifier: 0.8.0