@vercel/next 3.0.1-canary.0 → 3.0.2-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,23 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EDGE_FUNCTION_USER_SCRIPT_SIZE_LIMIT = void 0;
3
+ exports.EDGE_FUNCTION_SIZE_LIMIT = void 0;
4
4
  const KIB = 1024;
5
5
  const MIB = 1024 * KIB;
6
6
  /**
7
- * The limit after compression. it has to be kibibyte instead of kilobyte
8
- * See https://github.com/cloudflare/wrangler/blob/8907b12add3d70ee21ac597b69cd66f6807571f4/src/wranglerjs/output.rs#L44
7
+ * The maximum size of a *compressed* edge function.
9
8
  */
10
- const EDGE_FUNCTION_SCRIPT_SIZE_LIMIT = MIB;
11
- /**
12
- * This safety buffer must cover the size of our whole runtime layer compressed
13
- * plus some extra space to allow it to grow in the future. At the time of
14
- * writing this comment the compressed size size is ~7KiB so 20KiB should
15
- * be more than enough.
16
- */
17
- const EDGE_FUNCTION_SCRIPT_SIZE_BUFFER = 20 * KIB;
18
- /**
19
- * The max size we allow for compressed user code is the compressed script
20
- * limit minus the compressed safety buffer. We must check this limit after
21
- * compressing the user code.
22
- */
23
- exports.EDGE_FUNCTION_USER_SCRIPT_SIZE_LIMIT = EDGE_FUNCTION_SCRIPT_SIZE_LIMIT - EDGE_FUNCTION_SCRIPT_SIZE_BUFFER;
9
+ exports.EDGE_FUNCTION_SIZE_LIMIT = MIB;
@@ -66,7 +66,7 @@ function getWasmImportStatements(wasm = []) {
66
66
  }
67
67
  async function validateScript(content) {
68
68
  const gzipped = await gzip(content);
69
- if (gzipped.length > constants_1.EDGE_FUNCTION_USER_SCRIPT_SIZE_LIMIT) {
70
- throw new Error(`Exceeds maximum edge function script size: ${(0, pretty_bytes_1.default)(gzipped.length)} / ${(0, pretty_bytes_1.default)(constants_1.EDGE_FUNCTION_USER_SCRIPT_SIZE_LIMIT)}`);
69
+ if (gzipped.length > constants_1.EDGE_FUNCTION_SIZE_LIMIT) {
70
+ throw new Error(`Exceeds maximum edge function script size: ${(0, pretty_bytes_1.default)(gzipped.length)} / ${(0, pretty_bytes_1.default)(constants_1.EDGE_FUNCTION_SIZE_LIMIT)}`);
71
71
  }
72
72
  }
package/dist/index.js CHANGED
@@ -44725,27 +44725,13 @@ exports.default = createServerlessConfig;
44725
44725
  "use strict";
44726
44726
 
44727
44727
  Object.defineProperty(exports, "__esModule", ({ value: true }));
44728
- exports.EDGE_FUNCTION_USER_SCRIPT_SIZE_LIMIT = void 0;
44728
+ exports.EDGE_FUNCTION_SIZE_LIMIT = void 0;
44729
44729
  const KIB = 1024;
44730
44730
  const MIB = 1024 * KIB;
44731
44731
  /**
44732
- * The limit after compression. it has to be kibibyte instead of kilobyte
44733
- * See https://github.com/cloudflare/wrangler/blob/8907b12add3d70ee21ac597b69cd66f6807571f4/src/wranglerjs/output.rs#L44
44732
+ * The maximum size of a *compressed* edge function.
44734
44733
  */
44735
- const EDGE_FUNCTION_SCRIPT_SIZE_LIMIT = MIB;
44736
- /**
44737
- * This safety buffer must cover the size of our whole runtime layer compressed
44738
- * plus some extra space to allow it to grow in the future. At the time of
44739
- * writing this comment the compressed size size is ~7KiB so 20KiB should
44740
- * be more than enough.
44741
- */
44742
- const EDGE_FUNCTION_SCRIPT_SIZE_BUFFER = 20 * KIB;
44743
- /**
44744
- * The max size we allow for compressed user code is the compressed script
44745
- * limit minus the compressed safety buffer. We must check this limit after
44746
- * compressing the user code.
44747
- */
44748
- exports.EDGE_FUNCTION_USER_SCRIPT_SIZE_LIMIT = EDGE_FUNCTION_SCRIPT_SIZE_LIMIT - EDGE_FUNCTION_SCRIPT_SIZE_BUFFER;
44734
+ exports.EDGE_FUNCTION_SIZE_LIMIT = MIB;
44749
44735
 
44750
44736
 
44751
44737
  /***/ }),
@@ -44822,8 +44808,8 @@ function getWasmImportStatements(wasm = []) {
44822
44808
  }
44823
44809
  async function validateScript(content) {
44824
44810
  const gzipped = await gzip(content);
44825
- if (gzipped.length > constants_1.EDGE_FUNCTION_USER_SCRIPT_SIZE_LIMIT) {
44826
- throw new Error(`Exceeds maximum edge function script size: ${(0, pretty_bytes_1.default)(gzipped.length)} / ${(0, pretty_bytes_1.default)(constants_1.EDGE_FUNCTION_USER_SCRIPT_SIZE_LIMIT)}`);
44811
+ if (gzipped.length > constants_1.EDGE_FUNCTION_SIZE_LIMIT) {
44812
+ throw new Error(`Exceeds maximum edge function script size: ${(0, pretty_bytes_1.default)(gzipped.length)} / ${(0, pretty_bytes_1.default)(constants_1.EDGE_FUNCTION_SIZE_LIMIT)}`);
44827
44813
  }
44828
44814
  }
44829
44815
 
@@ -44857,6 +44843,7 @@ const create_serverless_config_1 = __importDefault(__webpack_require__(9892));
44857
44843
  const legacy_versions_1 = __importDefault(__webpack_require__(1207));
44858
44844
  const server_build_1 = __webpack_require__(5840);
44859
44845
  const utils_1 = __webpack_require__(4411);
44846
+ const assert_1 = __importDefault(__webpack_require__(2357));
44860
44847
  exports.version = 2;
44861
44848
  exports.htmlContentType = 'text/html; charset=utf-8';
44862
44849
  const SERVER_BUILD_MINIMUM_NEXT_VERSION = 'v10.0.9-canary.4';
@@ -45532,7 +45519,11 @@ const build = async ({ files, workPath, repoRootPath, entrypoint, config = {}, m
45532
45519
  nextFiles['next.config.js'] = filesAfterBuild['next.config.js'];
45533
45520
  }
45534
45521
  const pagesDir = path_1.default.join(entryPath, outputDirectory, 'server', 'static', buildId, 'pages');
45535
- const pages = await (0, build_utils_1.glob)('**/!(_middleware).js', pagesDir);
45522
+ const pages = await getServerlessPages({
45523
+ pagesDir,
45524
+ entryPath,
45525
+ outputDirectory,
45526
+ });
45536
45527
  const launcherPath = path_1.default.join(__dirname, 'legacy-launcher.js');
45537
45528
  const launcherData = await (0, fs_extra_1.readFile)(launcherPath, 'utf8');
45538
45529
  await Promise.all(Object.keys(pages).map(async (page) => {
@@ -45578,7 +45569,11 @@ const build = async ({ files, workPath, repoRootPath, entrypoint, config = {}, m
45578
45569
  else {
45579
45570
  (0, build_utils_1.debug)('Preparing serverless function files...');
45580
45571
  const pagesDir = path_1.default.join(entryPath, outputDirectory, isServerMode ? 'server' : 'serverless', 'pages');
45581
- const pages = await (0, build_utils_1.glob)('**/!(_middleware).js', pagesDir);
45572
+ const pages = await getServerlessPages({
45573
+ pagesDir,
45574
+ entryPath,
45575
+ outputDirectory,
45576
+ });
45582
45577
  const isApiPage = (page) => page
45583
45578
  .replace(/\\/g, '/')
45584
45579
  .match(/(serverless|server)\/pages\/api(\/|\.js$)/);
@@ -45729,6 +45724,7 @@ const build = async ({ files, workPath, repoRootPath, entrypoint, config = {}, m
45729
45724
  entryPath,
45730
45725
  baseDir,
45731
45726
  dataRoutes,
45727
+ buildId,
45732
45728
  escapedBuildId,
45733
45729
  outputDirectory,
45734
45730
  trailingSlashRedirects,
@@ -46637,6 +46633,23 @@ const prepareCache = async ({ workPath, repoRootPath, entrypoint, config = {}, }
46637
46633
  return cache;
46638
46634
  };
46639
46635
  exports.prepareCache = prepareCache;
46636
+ async function getServerlessPages(params) {
46637
+ const [pages, middlewareManifest] = await Promise.all([
46638
+ (0, build_utils_1.glob)('**/!(_middleware).js', params.pagesDir),
46639
+ (0, utils_1.getMiddlewareManifest)(params.entryPath, params.outputDirectory),
46640
+ ]);
46641
+ // Edge Functions do not consider as Serverless Functions
46642
+ for (const edgeFunctionFile of Object.keys(middlewareManifest?.functions ?? {})) {
46643
+ // `getStaticProps` are expecting `Prerender` output which is a Serverless function
46644
+ // and not an Edge Function. Therefore we only remove API endpoints for now, as they
46645
+ // don't have `getStaticProps`.
46646
+ //
46647
+ // Context: https://github.com/vercel/vercel/pull/7905#discussion_r890213165
46648
+ (0, assert_1.default)(edgeFunctionFile.startsWith('/api/'), `Only API endpoints are currently supported for Edge endpoints.`);
46649
+ delete pages[edgeFunctionFile.slice(1) + '.js'];
46650
+ }
46651
+ return pages;
46652
+ }
46640
46653
 
46641
46654
 
46642
46655
  /***/ }),
@@ -47011,7 +47024,8 @@ const pretty_bytes_1 = __importDefault(__webpack_require__(539));
47011
47024
  // related PR: https://github.com/vercel/next.js/pull/30046
47012
47025
  const CORRECT_NOT_FOUND_ROUTES_VERSION = 'v12.0.1';
47013
47026
  const CORRECT_MIDDLEWARE_ORDER_VERSION = 'v12.1.7-canary.29';
47014
- async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs, baseDir, workPath, entryPath, nodeVersion, escapedBuildId, dynamicPrefix, entryDirectory, outputDirectory, redirects, beforeFilesRewrites, afterFilesRewrites, fallbackRewrites, headers, dataRoutes, hasIsr404Page, imagesManifest, wildcardConfig, routesManifest, staticPages, lambdaPages, nextVersion, canUsePreviewMode, prerenderManifest, omittedPrerenderRoutes, trailingSlashRedirects, isCorrectLocaleAPIRoutes, lambdaCompressedByteLimit, requiredServerFilesManifest, }) {
47027
+ const NEXT_DATA_MIDDLEWARE_RESOLVING_VERSION = 'v12.1.7-canary.33';
47028
+ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs, baseDir, workPath, entryPath, nodeVersion, buildId, escapedBuildId, dynamicPrefix, entryDirectory, outputDirectory, redirects, beforeFilesRewrites, afterFilesRewrites, fallbackRewrites, headers, dataRoutes, hasIsr404Page, imagesManifest, wildcardConfig, routesManifest, staticPages, lambdaPages, nextVersion, canUsePreviewMode, prerenderManifest, omittedPrerenderRoutes, trailingSlashRedirects, isCorrectLocaleAPIRoutes, lambdaCompressedByteLimit, requiredServerFilesManifest, }) {
47015
47029
  const lambdas = {};
47016
47030
  const prerenders = {};
47017
47031
  const lambdaPageKeys = Object.keys(lambdaPages);
@@ -47410,6 +47424,8 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
47410
47424
  routesManifest,
47411
47425
  isCorrectMiddlewareOrder,
47412
47426
  });
47427
+ const isNextDataServerResolving = middleware.staticRoutes.length > 0 &&
47428
+ semver_1.default.gte(nextVersion, NEXT_DATA_MIDDLEWARE_RESOLVING_VERSION);
47413
47429
  const dynamicRoutes = await (0, utils_1.getDynamicRoutes)(entryPath, entryDirectory, dynamicPages, false, routesManifest, omittedPrerenderRoutes, canUsePreviewMode, prerenderManifest.bypassToken || '', true, middleware.dynamicRouteMap).then(arr => (0, utils_1.localizeDynamicRoutes)(arr, dynamicPrefix, entryDirectory, staticPages, prerenderManifest, routesManifest, true, isCorrectLocaleAPIRoutes));
47414
47430
  const { staticFiles, publicDirectoryFiles, staticDirectoryFiles } = await (0, utils_1.getStaticFiles)(entryPath, entryDirectory, outputDirectory);
47415
47431
  const notFoundPreviewRoutes = [];
@@ -47452,6 +47468,39 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
47452
47468
  }
47453
47469
  }
47454
47470
  }
47471
+ const normalizeNextDataRoute = isNextDataServerResolving
47472
+ ? [
47473
+ // strip _next/data prefix for resolving
47474
+ {
47475
+ src: `^${path_1.default.join('/', entryDirectory, '/_next/data/', escapedBuildId, '/(.*).json')}`,
47476
+ dest: `${path_1.default.join('/', entryDirectory, '/$1')}`,
47477
+ continue: true,
47478
+ override: true,
47479
+ has: [
47480
+ {
47481
+ type: 'header',
47482
+ key: 'x-nextjs-data',
47483
+ },
47484
+ ],
47485
+ },
47486
+ ]
47487
+ : [];
47488
+ const denormalizeNextDataRoute = isNextDataServerResolving
47489
+ ? [
47490
+ {
47491
+ src: '/(.*)',
47492
+ has: [
47493
+ {
47494
+ type: 'header',
47495
+ key: 'x-nextjs-data',
47496
+ },
47497
+ ],
47498
+ dest: `${path_1.default.join('/', entryDirectory, '/_next/data/', buildId, '/$1.json')}`,
47499
+ continue: true,
47500
+ override: true,
47501
+ },
47502
+ ]
47503
+ : [];
47455
47504
  return {
47456
47505
  wildcard: wildcardConfig,
47457
47506
  images: imagesManifest?.images?.loader === 'default'
@@ -47475,6 +47524,15 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
47475
47524
  ...staticDirectoryFiles,
47476
47525
  ...privateOutputs.files,
47477
47526
  ...middleware.edgeFunctions,
47527
+ ...(isNextDataServerResolving
47528
+ ? {
47529
+ __next_data_catchall: new build_utils_1.FileBlob({
47530
+ contentType: 'application/json',
47531
+ mode: 0o644,
47532
+ data: '{}',
47533
+ }),
47534
+ }
47535
+ : {}),
47478
47536
  },
47479
47537
  routes: [
47480
47538
  /*
@@ -47492,6 +47550,8 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
47492
47550
  // trailing slash
47493
47551
  ...trailingSlashRedirects,
47494
47552
  ...privateOutputs.routes,
47553
+ // normalize _next/data URL before processing redirects
47554
+ ...normalizeNextDataRoute,
47495
47555
  ...(i18n
47496
47556
  ? [
47497
47557
  // Handle auto-adding current default locale to path based on
@@ -47617,6 +47677,8 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
47617
47677
  continue: true,
47618
47678
  },
47619
47679
  ]),
47680
+ // we need to undo _next/data normalize before checking filesystem
47681
+ ...denormalizeNextDataRoute,
47620
47682
  // while middleware was in beta the order came right before
47621
47683
  // handle: 'filesystem' we maintain this for older versions
47622
47684
  // to prevent a local/deploy mismatch
@@ -47635,13 +47697,19 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
47635
47697
  },
47636
47698
  ]
47637
47699
  : []),
47638
- // No-op _next/data rewrite to trigger handle: 'rewrites' and then 404
47639
- // if no match to prevent rewriting _next/data unexpectedly
47640
- {
47641
- src: path_1.default.join('/', entryDirectory, '_next/data/(.*)'),
47642
- dest: path_1.default.join('/', entryDirectory, '_next/data/$1'),
47643
- check: true,
47644
- },
47700
+ // normalize _next/data URL before processing rewrites
47701
+ ...normalizeNextDataRoute,
47702
+ ...(!isNextDataServerResolving
47703
+ ? [
47704
+ // No-op _next/data rewrite to trigger handle: 'rewrites' and then 404
47705
+ // if no match to prevent rewriting _next/data unexpectedly
47706
+ {
47707
+ src: path_1.default.join('/', entryDirectory, '_next/data/(.*)'),
47708
+ dest: path_1.default.join('/', entryDirectory, '_next/data/$1'),
47709
+ check: true,
47710
+ },
47711
+ ]
47712
+ : []),
47645
47713
  // These need to come before handle: miss or else they are grouped
47646
47714
  // with that routing section
47647
47715
  ...afterFilesRewrites,
@@ -47687,18 +47755,34 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
47687
47755
  // routes that are called after each rewrite or after routes
47688
47756
  // if there no rewrites
47689
47757
  { handle: 'rewrite' },
47758
+ // re-build /_next/data URL after resolving
47759
+ ...denormalizeNextDataRoute,
47690
47760
  // /_next/data routes for getServerProps/getStaticProps pages
47691
47761
  ...dataRoutes,
47692
- // ensure we 404 for non-existent _next/data routes before
47693
- // trying page dynamic routes
47694
- {
47695
- src: path_1.default.join('/', entryDirectory, '_next/data/(.*)'),
47696
- dest: path_1.default.join('/', entryDirectory, '404'),
47697
- status: 404,
47698
- },
47762
+ ...(!isNextDataServerResolving
47763
+ ? [
47764
+ // ensure we 404 for non-existent _next/data routes before
47765
+ // trying page dynamic routes
47766
+ {
47767
+ src: path_1.default.join('/', entryDirectory, '_next/data/(.*)'),
47768
+ dest: path_1.default.join('/', entryDirectory, '404'),
47769
+ status: 404,
47770
+ },
47771
+ ]
47772
+ : []),
47699
47773
  // Dynamic routes (must come after dataRoutes as dataRoutes are more
47700
47774
  // specific)
47701
47775
  ...dynamicRoutes,
47776
+ ...(isNextDataServerResolving
47777
+ ? [
47778
+ // add a catch-all data route so we don't 404 when getting
47779
+ // middleware effects
47780
+ {
47781
+ src: `^${path_1.default.join('/', entryDirectory, '/_next/data/', escapedBuildId, '/(.*).json')}`,
47782
+ dest: '__next_data_catchall',
47783
+ },
47784
+ ]
47785
+ : []),
47702
47786
  // routes to call after a file has been matched
47703
47787
  { handle: 'hit' },
47704
47788
  // Before we handle static files we need to set proper caching headers
@@ -47920,7 +48004,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
47920
48004
  return (mod && mod.__esModule) ? mod : { "default": mod };
47921
48005
  };
47922
48006
  Object.defineProperty(exports, "__esModule", ({ value: true }));
47923
- exports.getMiddlewareBundle = exports.getSourceFilePathFromPage = exports.isDynamicRoute = exports.normalizePage = exports.getNextConfig = exports.normalizePackageJson = exports.validateEntrypoint = exports.excludeFiles = exports.getPrivateOutputs = exports.updateRouteSrc = exports.getNextServerPath = exports.normalizeIndexOutput = exports.getStaticFiles = exports.onPrerenderRoute = exports.onPrerenderRouteInitial = exports.detectLambdaLimitExceeding = exports.outputFunctionFileSizeInfo = exports.getPageLambdaGroups = exports.MAX_UNCOMPRESSED_LAMBDA_SIZE = exports.addLocaleOrDefault = exports.normalizeLocalePath = exports.getPrerenderManifest = exports.getRequiredServerFilesManifest = exports.getExportStatus = exports.getExportIntent = exports.createLambdaFromPseudoLayers = exports.createPseudoLayer = exports.ExperimentalTraceVersion = exports.collectTracedFiles = exports.getFilesMapFromReasons = exports.filterStaticPages = exports.getImagesManifest = exports.localizeDynamicRoutes = exports.getDynamicRoutes = exports.getRoutesManifest = void 0;
48007
+ exports.getMiddlewareManifest = exports.getMiddlewareBundle = exports.getSourceFilePathFromPage = exports.isDynamicRoute = exports.normalizePage = exports.getNextConfig = exports.normalizePackageJson = exports.validateEntrypoint = exports.excludeFiles = exports.getPrivateOutputs = exports.updateRouteSrc = exports.getNextServerPath = exports.normalizeIndexOutput = exports.getStaticFiles = exports.onPrerenderRoute = exports.onPrerenderRouteInitial = exports.detectLambdaLimitExceeding = exports.outputFunctionFileSizeInfo = exports.getPageLambdaGroups = exports.MAX_UNCOMPRESSED_LAMBDA_SIZE = exports.addLocaleOrDefault = exports.normalizeLocalePath = exports.getPrerenderManifest = exports.getRequiredServerFilesManifest = exports.getExportStatus = exports.getExportIntent = exports.createLambdaFromPseudoLayers = exports.createPseudoLayer = exports.ExperimentalTraceVersion = exports.collectTracedFiles = exports.getFilesMapFromReasons = exports.filterStaticPages = exports.getImagesManifest = exports.localizeDynamicRoutes = exports.getDynamicRoutes = exports.getRoutesManifest = void 0;
47924
48008
  const build_utils_1 = __webpack_require__(3445);
47925
48009
  const async_sema_1 = __webpack_require__(7916);
47926
48010
  const buffer_crc32_1 = __importDefault(__webpack_require__(360));
@@ -49234,25 +49318,41 @@ async function getPrivateOutputs(dir, entries) {
49234
49318
  exports.getPrivateOutputs = getPrivateOutputs;
49235
49319
  async function getMiddlewareBundle({ entryPath, outputDirectory, routesManifest, isCorrectMiddlewareOrder, }) {
49236
49320
  const middlewareManifest = await getMiddlewareManifest(entryPath, outputDirectory);
49237
- if (middlewareManifest && middlewareManifest?.sortedMiddleware.length > 0) {
49238
- const workerConfigs = await Promise.all(middlewareManifest.sortedMiddleware.map(async (key) => {
49239
- const middleware = middlewareManifest.middleware[key];
49321
+ const sortedFunctions = [
49322
+ ...(!middlewareManifest
49323
+ ? []
49324
+ : middlewareManifest.sortedMiddleware.map(key => ({
49325
+ key,
49326
+ edgeFunction: middlewareManifest?.middleware[key],
49327
+ type: 'middleware',
49328
+ }))),
49329
+ ...Object.entries(middlewareManifest?.functions ?? {}).map(([key, edgeFunction]) => {
49330
+ return {
49331
+ key,
49332
+ edgeFunction,
49333
+ type: 'function',
49334
+ };
49335
+ }),
49336
+ ];
49337
+ if (middlewareManifest && sortedFunctions.length > 0) {
49338
+ const workerConfigs = await Promise.all(sortedFunctions.map(async ({ key, edgeFunction, type }) => {
49240
49339
  try {
49241
- const wrappedModuleSource = await (0, get_edge_function_source_1.getNextjsEdgeFunctionSource)(middleware.files, {
49242
- name: middleware.name,
49340
+ const wrappedModuleSource = await (0, get_edge_function_source_1.getNextjsEdgeFunctionSource)(edgeFunction.files, {
49341
+ name: edgeFunction.name,
49243
49342
  staticRoutes: routesManifest.staticRoutes,
49244
49343
  dynamicRoutes: routesManifest.dynamicRoutes.filter(r => !('isMiddleware' in r)),
49245
49344
  nextConfig: {
49246
49345
  basePath: routesManifest.basePath,
49247
49346
  i18n: routesManifest.i18n,
49248
49347
  },
49249
- }, path_1.default.resolve(entryPath, outputDirectory), middleware.wasm);
49348
+ }, path_1.default.resolve(entryPath, outputDirectory), edgeFunction.wasm);
49250
49349
  return {
49251
- page: middlewareManifest.middleware[key].page,
49350
+ type,
49351
+ page: edgeFunction.page,
49252
49352
  edgeFunction: (() => {
49253
49353
  const { source, map } = wrappedModuleSource.sourceAndMap();
49254
49354
  const transformedMap = (0, sourcemapped_1.stringifySourceMap)(transformSourceMap(map));
49255
- const wasmFiles = (middleware.wasm ?? []).reduce((acc, { filePath, name }) => {
49355
+ const wasmFiles = (edgeFunction.wasm ?? []).reduce((acc, { filePath, name }) => {
49256
49356
  const fullFilePath = path_1.default.join(entryPath, outputDirectory, filePath);
49257
49357
  acc[`wasm/${name}.wasm`] = new build_utils_1.FileFsRef({
49258
49358
  mode: 0o644,
@@ -49263,7 +49363,7 @@ async function getMiddlewareBundle({ entryPath, outputDirectory, routesManifest,
49263
49363
  }, {});
49264
49364
  return new build_utils_1.EdgeFunction({
49265
49365
  deploymentTarget: 'v8-worker',
49266
- name: middleware.name,
49366
+ name: edgeFunction.name,
49267
49367
  files: {
49268
49368
  'index.js': new build_utils_1.FileBlob({
49269
49369
  data: source,
@@ -49280,10 +49380,10 @@ async function getMiddlewareBundle({ entryPath, outputDirectory, routesManifest,
49280
49380
  ...wasmFiles,
49281
49381
  },
49282
49382
  entrypoint: 'index.js',
49283
- envVarsInUse: middleware.env,
49383
+ envVarsInUse: edgeFunction.env,
49284
49384
  });
49285
49385
  })(),
49286
- routeSrc: getRouteSrc(middlewareManifest.middleware[key], routesManifest),
49386
+ routeSrc: getRouteSrc(edgeFunction, routesManifest),
49287
49387
  };
49288
49388
  }
49289
49389
  catch (e) {
@@ -49298,15 +49398,21 @@ async function getMiddlewareBundle({ entryPath, outputDirectory, routesManifest,
49298
49398
  };
49299
49399
  for (const worker of workerConfigs.values()) {
49300
49400
  const edgeFile = worker.edgeFunction.name;
49301
- worker.edgeFunction.name = edgeFile.replace(/^pages\//, '');
49302
- source.edgeFunctions[edgeFile] = worker.edgeFunction;
49401
+ const shortPath = edgeFile.replace(/^pages\//, '');
49402
+ worker.edgeFunction.name = shortPath;
49403
+ source.edgeFunctions[shortPath] = worker.edgeFunction;
49303
49404
  const route = {
49304
49405
  continue: true,
49305
- middlewarePath: edgeFile,
49306
49406
  src: worker.routeSrc,
49307
49407
  };
49308
- if (isCorrectMiddlewareOrder) {
49309
- route.override = true;
49408
+ if (worker.type === 'function') {
49409
+ route.dest = shortPath;
49410
+ }
49411
+ else {
49412
+ route.middlewarePath = shortPath;
49413
+ if (isCorrectMiddlewareOrder) {
49414
+ route.override = true;
49415
+ }
49310
49416
  }
49311
49417
  if (routesManifest.version > 3 && isDynamicRoute(worker.page)) {
49312
49418
  source.dynamicRouteMap.set(worker.page, route);
@@ -49340,6 +49446,7 @@ async function getMiddlewareManifest(entryPath, outputDirectory) {
49340
49446
  }
49341
49447
  return fs_extra_1.default.readJSON(middlewareManifestPath);
49342
49448
  }
49449
+ exports.getMiddlewareManifest = getMiddlewareManifest;
49343
49450
  /**
49344
49451
  * For an object containing middleware info and a routes manifest this will
49345
49452
  * generate a string with the route that will activate the middleware on
@@ -18,7 +18,8 @@ const pretty_bytes_1 = __importDefault(require("pretty-bytes"));
18
18
  // related PR: https://github.com/vercel/next.js/pull/30046
19
19
  const CORRECT_NOT_FOUND_ROUTES_VERSION = 'v12.0.1';
20
20
  const CORRECT_MIDDLEWARE_ORDER_VERSION = 'v12.1.7-canary.29';
21
- async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs, baseDir, workPath, entryPath, nodeVersion, escapedBuildId, dynamicPrefix, entryDirectory, outputDirectory, redirects, beforeFilesRewrites, afterFilesRewrites, fallbackRewrites, headers, dataRoutes, hasIsr404Page, imagesManifest, wildcardConfig, routesManifest, staticPages, lambdaPages, nextVersion, canUsePreviewMode, prerenderManifest, omittedPrerenderRoutes, trailingSlashRedirects, isCorrectLocaleAPIRoutes, lambdaCompressedByteLimit, requiredServerFilesManifest, }) {
21
+ const NEXT_DATA_MIDDLEWARE_RESOLVING_VERSION = 'v12.1.7-canary.33';
22
+ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs, baseDir, workPath, entryPath, nodeVersion, buildId, escapedBuildId, dynamicPrefix, entryDirectory, outputDirectory, redirects, beforeFilesRewrites, afterFilesRewrites, fallbackRewrites, headers, dataRoutes, hasIsr404Page, imagesManifest, wildcardConfig, routesManifest, staticPages, lambdaPages, nextVersion, canUsePreviewMode, prerenderManifest, omittedPrerenderRoutes, trailingSlashRedirects, isCorrectLocaleAPIRoutes, lambdaCompressedByteLimit, requiredServerFilesManifest, }) {
22
23
  const lambdas = {};
23
24
  const prerenders = {};
24
25
  const lambdaPageKeys = Object.keys(lambdaPages);
@@ -417,6 +418,8 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
417
418
  routesManifest,
418
419
  isCorrectMiddlewareOrder,
419
420
  });
421
+ const isNextDataServerResolving = middleware.staticRoutes.length > 0 &&
422
+ semver_1.default.gte(nextVersion, NEXT_DATA_MIDDLEWARE_RESOLVING_VERSION);
420
423
  const dynamicRoutes = await (0, utils_1.getDynamicRoutes)(entryPath, entryDirectory, dynamicPages, false, routesManifest, omittedPrerenderRoutes, canUsePreviewMode, prerenderManifest.bypassToken || '', true, middleware.dynamicRouteMap).then(arr => (0, utils_1.localizeDynamicRoutes)(arr, dynamicPrefix, entryDirectory, staticPages, prerenderManifest, routesManifest, true, isCorrectLocaleAPIRoutes));
421
424
  const { staticFiles, publicDirectoryFiles, staticDirectoryFiles } = await (0, utils_1.getStaticFiles)(entryPath, entryDirectory, outputDirectory);
422
425
  const notFoundPreviewRoutes = [];
@@ -459,6 +462,39 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
459
462
  }
460
463
  }
461
464
  }
465
+ const normalizeNextDataRoute = isNextDataServerResolving
466
+ ? [
467
+ // strip _next/data prefix for resolving
468
+ {
469
+ src: `^${path_1.default.join('/', entryDirectory, '/_next/data/', escapedBuildId, '/(.*).json')}`,
470
+ dest: `${path_1.default.join('/', entryDirectory, '/$1')}`,
471
+ continue: true,
472
+ override: true,
473
+ has: [
474
+ {
475
+ type: 'header',
476
+ key: 'x-nextjs-data',
477
+ },
478
+ ],
479
+ },
480
+ ]
481
+ : [];
482
+ const denormalizeNextDataRoute = isNextDataServerResolving
483
+ ? [
484
+ {
485
+ src: '/(.*)',
486
+ has: [
487
+ {
488
+ type: 'header',
489
+ key: 'x-nextjs-data',
490
+ },
491
+ ],
492
+ dest: `${path_1.default.join('/', entryDirectory, '/_next/data/', buildId, '/$1.json')}`,
493
+ continue: true,
494
+ override: true,
495
+ },
496
+ ]
497
+ : [];
462
498
  return {
463
499
  wildcard: wildcardConfig,
464
500
  images: imagesManifest?.images?.loader === 'default'
@@ -482,6 +518,15 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
482
518
  ...staticDirectoryFiles,
483
519
  ...privateOutputs.files,
484
520
  ...middleware.edgeFunctions,
521
+ ...(isNextDataServerResolving
522
+ ? {
523
+ __next_data_catchall: new build_utils_1.FileBlob({
524
+ contentType: 'application/json',
525
+ mode: 0o644,
526
+ data: '{}',
527
+ }),
528
+ }
529
+ : {}),
485
530
  },
486
531
  routes: [
487
532
  /*
@@ -499,6 +544,8 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
499
544
  // trailing slash
500
545
  ...trailingSlashRedirects,
501
546
  ...privateOutputs.routes,
547
+ // normalize _next/data URL before processing redirects
548
+ ...normalizeNextDataRoute,
502
549
  ...(i18n
503
550
  ? [
504
551
  // Handle auto-adding current default locale to path based on
@@ -624,6 +671,8 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
624
671
  continue: true,
625
672
  },
626
673
  ]),
674
+ // we need to undo _next/data normalize before checking filesystem
675
+ ...denormalizeNextDataRoute,
627
676
  // while middleware was in beta the order came right before
628
677
  // handle: 'filesystem' we maintain this for older versions
629
678
  // to prevent a local/deploy mismatch
@@ -642,13 +691,19 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
642
691
  },
643
692
  ]
644
693
  : []),
645
- // No-op _next/data rewrite to trigger handle: 'rewrites' and then 404
646
- // if no match to prevent rewriting _next/data unexpectedly
647
- {
648
- src: path_1.default.join('/', entryDirectory, '_next/data/(.*)'),
649
- dest: path_1.default.join('/', entryDirectory, '_next/data/$1'),
650
- check: true,
651
- },
694
+ // normalize _next/data URL before processing rewrites
695
+ ...normalizeNextDataRoute,
696
+ ...(!isNextDataServerResolving
697
+ ? [
698
+ // No-op _next/data rewrite to trigger handle: 'rewrites' and then 404
699
+ // if no match to prevent rewriting _next/data unexpectedly
700
+ {
701
+ src: path_1.default.join('/', entryDirectory, '_next/data/(.*)'),
702
+ dest: path_1.default.join('/', entryDirectory, '_next/data/$1'),
703
+ check: true,
704
+ },
705
+ ]
706
+ : []),
652
707
  // These need to come before handle: miss or else they are grouped
653
708
  // with that routing section
654
709
  ...afterFilesRewrites,
@@ -694,18 +749,34 @@ async function serverBuild({ dynamicPages, pagesDir, config = {}, privateOutputs
694
749
  // routes that are called after each rewrite or after routes
695
750
  // if there no rewrites
696
751
  { handle: 'rewrite' },
752
+ // re-build /_next/data URL after resolving
753
+ ...denormalizeNextDataRoute,
697
754
  // /_next/data routes for getServerProps/getStaticProps pages
698
755
  ...dataRoutes,
699
- // ensure we 404 for non-existent _next/data routes before
700
- // trying page dynamic routes
701
- {
702
- src: path_1.default.join('/', entryDirectory, '_next/data/(.*)'),
703
- dest: path_1.default.join('/', entryDirectory, '404'),
704
- status: 404,
705
- },
756
+ ...(!isNextDataServerResolving
757
+ ? [
758
+ // ensure we 404 for non-existent _next/data routes before
759
+ // trying page dynamic routes
760
+ {
761
+ src: path_1.default.join('/', entryDirectory, '_next/data/(.*)'),
762
+ dest: path_1.default.join('/', entryDirectory, '404'),
763
+ status: 404,
764
+ },
765
+ ]
766
+ : []),
706
767
  // Dynamic routes (must come after dataRoutes as dataRoutes are more
707
768
  // specific)
708
769
  ...dynamicRoutes,
770
+ ...(isNextDataServerResolving
771
+ ? [
772
+ // add a catch-all data route so we don't 404 when getting
773
+ // middleware effects
774
+ {
775
+ src: `^${path_1.default.join('/', entryDirectory, '/_next/data/', escapedBuildId, '/(.*).json')}`,
776
+ dest: '__next_data_catchall',
777
+ },
778
+ ]
779
+ : []),
709
780
  // routes to call after a file has been matched
710
781
  { handle: 'hit' },
711
782
  // Before we handle static files we need to set proper caching headers
package/dist/utils.js CHANGED
@@ -22,7 +22,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
22
22
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
23
  };
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.getMiddlewareBundle = exports.getSourceFilePathFromPage = exports.isDynamicRoute = exports.normalizePage = exports.getNextConfig = exports.normalizePackageJson = exports.validateEntrypoint = exports.excludeFiles = exports.getPrivateOutputs = exports.updateRouteSrc = exports.getNextServerPath = exports.normalizeIndexOutput = exports.getStaticFiles = exports.onPrerenderRoute = exports.onPrerenderRouteInitial = exports.detectLambdaLimitExceeding = exports.outputFunctionFileSizeInfo = exports.getPageLambdaGroups = exports.MAX_UNCOMPRESSED_LAMBDA_SIZE = exports.addLocaleOrDefault = exports.normalizeLocalePath = exports.getPrerenderManifest = exports.getRequiredServerFilesManifest = exports.getExportStatus = exports.getExportIntent = exports.createLambdaFromPseudoLayers = exports.createPseudoLayer = exports.ExperimentalTraceVersion = exports.collectTracedFiles = exports.getFilesMapFromReasons = exports.filterStaticPages = exports.getImagesManifest = exports.localizeDynamicRoutes = exports.getDynamicRoutes = exports.getRoutesManifest = void 0;
25
+ exports.getMiddlewareManifest = exports.getMiddlewareBundle = exports.getSourceFilePathFromPage = exports.isDynamicRoute = exports.normalizePage = exports.getNextConfig = exports.normalizePackageJson = exports.validateEntrypoint = exports.excludeFiles = exports.getPrivateOutputs = exports.updateRouteSrc = exports.getNextServerPath = exports.normalizeIndexOutput = exports.getStaticFiles = exports.onPrerenderRoute = exports.onPrerenderRouteInitial = exports.detectLambdaLimitExceeding = exports.outputFunctionFileSizeInfo = exports.getPageLambdaGroups = exports.MAX_UNCOMPRESSED_LAMBDA_SIZE = exports.addLocaleOrDefault = exports.normalizeLocalePath = exports.getPrerenderManifest = exports.getRequiredServerFilesManifest = exports.getExportStatus = exports.getExportIntent = exports.createLambdaFromPseudoLayers = exports.createPseudoLayer = exports.ExperimentalTraceVersion = exports.collectTracedFiles = exports.getFilesMapFromReasons = exports.filterStaticPages = exports.getImagesManifest = exports.localizeDynamicRoutes = exports.getDynamicRoutes = exports.getRoutesManifest = void 0;
26
26
  const build_utils_1 = require("@vercel/build-utils");
27
27
  const async_sema_1 = require("async-sema");
28
28
  const buffer_crc32_1 = __importDefault(require("buffer-crc32"));
@@ -1336,25 +1336,41 @@ async function getPrivateOutputs(dir, entries) {
1336
1336
  exports.getPrivateOutputs = getPrivateOutputs;
1337
1337
  async function getMiddlewareBundle({ entryPath, outputDirectory, routesManifest, isCorrectMiddlewareOrder, }) {
1338
1338
  const middlewareManifest = await getMiddlewareManifest(entryPath, outputDirectory);
1339
- if (middlewareManifest && middlewareManifest?.sortedMiddleware.length > 0) {
1340
- const workerConfigs = await Promise.all(middlewareManifest.sortedMiddleware.map(async (key) => {
1341
- const middleware = middlewareManifest.middleware[key];
1339
+ const sortedFunctions = [
1340
+ ...(!middlewareManifest
1341
+ ? []
1342
+ : middlewareManifest.sortedMiddleware.map(key => ({
1343
+ key,
1344
+ edgeFunction: middlewareManifest?.middleware[key],
1345
+ type: 'middleware',
1346
+ }))),
1347
+ ...Object.entries(middlewareManifest?.functions ?? {}).map(([key, edgeFunction]) => {
1348
+ return {
1349
+ key,
1350
+ edgeFunction,
1351
+ type: 'function',
1352
+ };
1353
+ }),
1354
+ ];
1355
+ if (middlewareManifest && sortedFunctions.length > 0) {
1356
+ const workerConfigs = await Promise.all(sortedFunctions.map(async ({ key, edgeFunction, type }) => {
1342
1357
  try {
1343
- const wrappedModuleSource = await (0, get_edge_function_source_1.getNextjsEdgeFunctionSource)(middleware.files, {
1344
- name: middleware.name,
1358
+ const wrappedModuleSource = await (0, get_edge_function_source_1.getNextjsEdgeFunctionSource)(edgeFunction.files, {
1359
+ name: edgeFunction.name,
1345
1360
  staticRoutes: routesManifest.staticRoutes,
1346
1361
  dynamicRoutes: routesManifest.dynamicRoutes.filter(r => !('isMiddleware' in r)),
1347
1362
  nextConfig: {
1348
1363
  basePath: routesManifest.basePath,
1349
1364
  i18n: routesManifest.i18n,
1350
1365
  },
1351
- }, path_1.default.resolve(entryPath, outputDirectory), middleware.wasm);
1366
+ }, path_1.default.resolve(entryPath, outputDirectory), edgeFunction.wasm);
1352
1367
  return {
1353
- page: middlewareManifest.middleware[key].page,
1368
+ type,
1369
+ page: edgeFunction.page,
1354
1370
  edgeFunction: (() => {
1355
1371
  const { source, map } = wrappedModuleSource.sourceAndMap();
1356
1372
  const transformedMap = (0, sourcemapped_1.stringifySourceMap)(transformSourceMap(map));
1357
- const wasmFiles = (middleware.wasm ?? []).reduce((acc, { filePath, name }) => {
1373
+ const wasmFiles = (edgeFunction.wasm ?? []).reduce((acc, { filePath, name }) => {
1358
1374
  const fullFilePath = path_1.default.join(entryPath, outputDirectory, filePath);
1359
1375
  acc[`wasm/${name}.wasm`] = new build_utils_1.FileFsRef({
1360
1376
  mode: 0o644,
@@ -1365,7 +1381,7 @@ async function getMiddlewareBundle({ entryPath, outputDirectory, routesManifest,
1365
1381
  }, {});
1366
1382
  return new build_utils_1.EdgeFunction({
1367
1383
  deploymentTarget: 'v8-worker',
1368
- name: middleware.name,
1384
+ name: edgeFunction.name,
1369
1385
  files: {
1370
1386
  'index.js': new build_utils_1.FileBlob({
1371
1387
  data: source,
@@ -1382,10 +1398,10 @@ async function getMiddlewareBundle({ entryPath, outputDirectory, routesManifest,
1382
1398
  ...wasmFiles,
1383
1399
  },
1384
1400
  entrypoint: 'index.js',
1385
- envVarsInUse: middleware.env,
1401
+ envVarsInUse: edgeFunction.env,
1386
1402
  });
1387
1403
  })(),
1388
- routeSrc: getRouteSrc(middlewareManifest.middleware[key], routesManifest),
1404
+ routeSrc: getRouteSrc(edgeFunction, routesManifest),
1389
1405
  };
1390
1406
  }
1391
1407
  catch (e) {
@@ -1400,15 +1416,21 @@ async function getMiddlewareBundle({ entryPath, outputDirectory, routesManifest,
1400
1416
  };
1401
1417
  for (const worker of workerConfigs.values()) {
1402
1418
  const edgeFile = worker.edgeFunction.name;
1403
- worker.edgeFunction.name = edgeFile.replace(/^pages\//, '');
1404
- source.edgeFunctions[edgeFile] = worker.edgeFunction;
1419
+ const shortPath = edgeFile.replace(/^pages\//, '');
1420
+ worker.edgeFunction.name = shortPath;
1421
+ source.edgeFunctions[shortPath] = worker.edgeFunction;
1405
1422
  const route = {
1406
1423
  continue: true,
1407
- middlewarePath: edgeFile,
1408
1424
  src: worker.routeSrc,
1409
1425
  };
1410
- if (isCorrectMiddlewareOrder) {
1411
- route.override = true;
1426
+ if (worker.type === 'function') {
1427
+ route.dest = shortPath;
1428
+ }
1429
+ else {
1430
+ route.middlewarePath = shortPath;
1431
+ if (isCorrectMiddlewareOrder) {
1432
+ route.override = true;
1433
+ }
1412
1434
  }
1413
1435
  if (routesManifest.version > 3 && isDynamicRoute(worker.page)) {
1414
1436
  source.dynamicRouteMap.set(worker.page, route);
@@ -1442,6 +1464,7 @@ async function getMiddlewareManifest(entryPath, outputDirectory) {
1442
1464
  }
1443
1465
  return fs_extra_1.default.readJSON(middlewareManifestPath);
1444
1466
  }
1467
+ exports.getMiddlewareManifest = getMiddlewareManifest;
1445
1468
  /**
1446
1469
  * For an object containing middleware info and a routes manifest this will
1447
1470
  * generate a string with the route that will activate the middleware on
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/next",
3
- "version": "3.0.1-canary.0",
3
+ "version": "3.0.2-canary.0",
4
4
  "license": "MIT",
5
5
  "main": "./dist/index",
6
6
  "homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
@@ -45,7 +45,7 @@
45
45
  "@types/semver": "6.0.0",
46
46
  "@types/text-table": "0.2.1",
47
47
  "@types/webpack-sources": "3.2.0",
48
- "@vercel/build-utils": "4.0.1-canary.0",
48
+ "@vercel/build-utils": "4.1.1-canary.0",
49
49
  "@vercel/nft": "0.19.1",
50
50
  "@vercel/routing-utils": "1.13.4",
51
51
  "async-sema": "3.0.1",
@@ -70,5 +70,5 @@
70
70
  "typescript": "4.5.2",
71
71
  "webpack-sources": "3.2.3"
72
72
  },
73
- "gitHead": "39f758662131ec37c467ebba5d5b618cba0c753f"
73
+ "gitHead": "4bf6295d7a1d6544f195d76a2a4aedb476fa7dc1"
74
74
  }