@netlify/plugin-nextjs 4.37.1 → 4.37.2

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.
package/lib/constants.js CHANGED
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.DIVIDER = exports.LAMBDA_MAX_SIZE = exports.LAMBDA_WARNING_SIZE = exports.MINIMUM_REVALIDATE_SECONDS = exports.DYNAMIC_PARAMETER_REGEX = exports.OPTIONAL_CATCH_ALL_REGEX = exports.CATCH_ALL_REGEX = exports.DEFAULT_FUNCTIONS_SRC = exports.HANDLER_FUNCTION_PATH = exports.ODB_FUNCTION_PATH = exports.HIDDEN_PATHS = exports.IMAGE_FUNCTION_TITLE = exports.ODB_FUNCTION_TITLE = exports.HANDLER_FUNCTION_TITLE = exports.NEXT_PLUGIN = exports.NEXT_PLUGIN_NAME = exports.IMAGE_FUNCTION_NAME = exports.ODB_FUNCTION_NAME = exports.HANDLER_FUNCTION_NAME = void 0;
7
+ const destr_1 = __importDefault(require("destr"));
4
8
  exports.HANDLER_FUNCTION_NAME = '___netlify-handler';
5
9
  exports.ODB_FUNCTION_NAME = '___netlify-odb-handler';
6
10
  exports.IMAGE_FUNCTION_NAME = '_ipx';
@@ -10,18 +14,29 @@ exports.HANDLER_FUNCTION_TITLE = 'Next.js SSR handler';
10
14
  exports.ODB_FUNCTION_TITLE = 'Next.js ISR handler';
11
15
  exports.IMAGE_FUNCTION_TITLE = 'next/image handler';
12
16
  // These are paths in .next that shouldn't be publicly accessible
13
- exports.HIDDEN_PATHS = [
14
- '/cache/*',
15
- '/server/*',
16
- '/serverless/*',
17
- '/trace',
18
- '/traces',
19
- '/routes-manifest.json',
20
- '/build-manifest.json',
21
- '/prerender-manifest.json',
22
- '/react-loadable-manifest.json',
23
- '/BUILD_ID',
24
- ];
17
+ exports.HIDDEN_PATHS = (0, destr_1.default)(process.env.NEXT_KEEP_METADATA_FILES)
18
+ ? []
19
+ : [
20
+ '/cache',
21
+ '/server',
22
+ '/serverless',
23
+ '/trace',
24
+ '/traces',
25
+ '/routes-manifest.json',
26
+ '/build-manifest.json',
27
+ '/prerender-manifest.json',
28
+ '/react-loadable-manifest.json',
29
+ '/BUILD_ID',
30
+ '/app-build-manifest.json',
31
+ '/app-path-routes-manifest.json',
32
+ '/export-marker.json',
33
+ '/images-manifest.json',
34
+ '/next-server.js.nft.json',
35
+ '/package.json',
36
+ '/prerender-manifest.js',
37
+ '/required-server-files.json',
38
+ '/static-manifest.json',
39
+ ];
25
40
  exports.ODB_FUNCTION_PATH = `/.netlify/builders/${exports.ODB_FUNCTION_NAME}`;
26
41
  exports.HANDLER_FUNCTION_PATH = `/.netlify/functions/${exports.HANDLER_FUNCTION_NAME}`;
27
42
  exports.DEFAULT_FUNCTIONS_SRC = 'netlify/functions';
@@ -9,7 +9,6 @@ const fs_extra_1 = require("fs-extra");
9
9
  const pathe_1 = require("pathe");
10
10
  const slash_1 = __importDefault(require("slash"));
11
11
  const constants_1 = require("../constants");
12
- const flags_1 = require("./flags");
13
12
  const utils_1 = require("./utils");
14
13
  const ROUTES_MANIFEST_FILE = 'routes-manifest.json';
15
14
  const defaultFailBuild = (message, { error }) => {
@@ -65,7 +64,7 @@ const hasManuallyAddedModule = ({ netlifyConfig, moduleName, }) =>
65
64
  Object.values(netlifyConfig.functions).some(({ included_files = [] }) => included_files.some((inc) => inc.includes(`node_modules/${moduleName}`)));
66
65
  exports.hasManuallyAddedModule = hasManuallyAddedModule;
67
66
  /* eslint-enable camelcase */
68
- const configureHandlerFunctions = async ({ netlifyConfig, publish, ignore = [], apiLambdas, featureFlags, }) => {
67
+ const configureHandlerFunctions = async ({ netlifyConfig, publish, ignore = [], apiLambdas, splitApiRoutes, }) => {
69
68
  var _a, _b, _c;
70
69
  const config = await (0, exports.getRequiredServerFiles)(publish);
71
70
  const files = config.files || [];
@@ -95,7 +94,7 @@ const configureHandlerFunctions = async ({ netlifyConfig, publish, ignore = [],
95
94
  };
96
95
  configureFunction(constants_1.HANDLER_FUNCTION_NAME);
97
96
  configureFunction(constants_1.ODB_FUNCTION_NAME);
98
- if ((0, flags_1.splitApiRoutes)(featureFlags)) {
97
+ if (splitApiRoutes) {
99
98
  for (const apiLambda of apiLambdas) {
100
99
  const { functionName, includedFiles } = apiLambda;
101
100
  (_b = netlifyConfig.functions)[functionName] || (_b[functionName] = { included_files: [] });
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.movePublicFiles = exports.unpatchNextFiles = exports.unpatchFile = exports.patchNextFiles = exports.getDependenciesOfFile = exports.getSourceFileForPage = exports.getServerFile = exports.moveStaticPages = exports.getMiddleware = exports.matchesRewrite = exports.matchesRedirect = exports.matchMiddleware = exports.stripLocale = exports.isDynamicRoute = void 0;
6
+ exports.removeMetadataFiles = exports.movePublicFiles = exports.unpatchNextFiles = exports.unpatchFile = exports.patchNextFiles = exports.getDependenciesOfFile = exports.getSourceFileForPage = exports.getServerFile = exports.moveStaticPages = exports.getMiddleware = exports.matchesRewrite = exports.matchesRedirect = exports.matchMiddleware = exports.stripLocale = exports.isDynamicRoute = void 0;
7
7
  const os_1 = require("os");
8
8
  const chalk_1 = require("chalk");
9
9
  const fs_extra_1 = require("fs-extra");
@@ -112,8 +112,8 @@ const moveStaticPages = async ({ netlifyConfig, target, i18n, basePath, }) => {
112
112
  console.warn('Error moving file', source, error);
113
113
  }
114
114
  };
115
- // Move all static files, except error documents and nft manifests
116
- const pages = await (0, globby_1.default)(['{app,pages}/**/*.{html,json,rsc}', '!**/(500|404|*.js.nft).{html,json}'], {
115
+ // Move all static files, except nft manifests
116
+ const pages = await (0, globby_1.default)(['{app,pages}/**/*.{html,json,rsc}', '!**/*.js.nft.{html,json}'], {
117
117
  cwd: outputDir,
118
118
  dot: true,
119
119
  });
@@ -392,3 +392,13 @@ const movePublicFiles = async ({ appDir, outdir, publish, basePath, }) => {
392
392
  }
393
393
  };
394
394
  exports.movePublicFiles = movePublicFiles;
395
+ const removeMetadataFiles = async (publish) => {
396
+ // Limit concurrent deletions to number of cpus or 2 if there is only 1
397
+ const limit = (0, p_limit_1.default)(Math.max(2, (0, os_1.cpus)().length));
398
+ const removePromises = constants_1.HIDDEN_PATHS.map((HIDDEN_PATH) => {
399
+ const pathToDelete = (0, pathe_1.join)(publish, HIDDEN_PATH);
400
+ return limit(() => (0, fs_extra_1.remove)(pathToDelete));
401
+ });
402
+ await Promise.all(removePromises);
403
+ };
404
+ exports.removeMetadataFiles = removeMetadataFiles;
@@ -5,6 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.splitApiRoutes = void 0;
7
7
  const destr_1 = __importDefault(require("destr"));
8
+ const fs_extra_1 = require("fs-extra");
9
+ const pathe_1 = require("pathe");
8
10
  /**
9
11
  * If this flag is enabled, we generate individual Lambda functions for API Routes.
10
12
  * They're packed together in 50mb chunks to avoid hitting the Lambda size limit.
@@ -16,7 +18,17 @@ const destr_1 = __importDefault(require("destr"));
16
18
  * If disabled, we bundle all API Routes into a single function.
17
19
  * This is can lead to large bundle sizes.
18
20
  *
21
+ * Relies on `next-server.js.nft.json`, which is only supported in Next.js 12+.
22
+ *
19
23
  * Disabled by default. Can be overriden using the NEXT_SPLIT_API_ROUTES env var.
20
24
  */
21
- const splitApiRoutes = (featureFlags) => { var _a, _b; return (_b = (_a = (0, destr_1.default)(process.env.NEXT_SPLIT_API_ROUTES)) !== null && _a !== void 0 ? _a : featureFlags.next_split_api_routes) !== null && _b !== void 0 ? _b : false; };
25
+ const splitApiRoutes = (featureFlags, publish) => {
26
+ var _a, _b;
27
+ const isEnabled = (_b = (_a = (0, destr_1.default)(process.env.NEXT_SPLIT_API_ROUTES)) !== null && _a !== void 0 ? _a : featureFlags.next_split_api_routes) !== null && _b !== void 0 ? _b : false;
28
+ if (isEnabled && !(0, fs_extra_1.existsSync)((0, pathe_1.join)(publish, 'next-server.js.nft.json'))) {
29
+ console.warn('Trace-based bundling not possible on this version of Next.js. Speed up your builds significantly by upgrading to Next.js v12 or newer.');
30
+ return false;
31
+ }
32
+ return isEnabled;
33
+ };
22
34
  exports.splitApiRoutes = splitApiRoutes;
@@ -179,7 +179,7 @@ const traceNextServer = async (publish) => {
179
179
  };
180
180
  const traceNPMPackage = async (packageName, publish) => {
181
181
  try {
182
- return await (0, tiny_glob_1.default)((0, pathe_1.join)((0, pathe_1.dirname)(require.resolve(packageName, { paths: [publish] })), '**', '*'), {
182
+ return await (0, tiny_glob_1.default)((0, pathe_1.join)((0, pathe_1.dirname)(require.resolve(packageName, { paths: [__dirname, publish] })), '**', '*'), {
183
183
  absolute: true,
184
184
  });
185
185
  }
@@ -14,12 +14,6 @@ const edge_1 = require("./edge");
14
14
  const files_1 = require("./files");
15
15
  const utils_1 = require("./utils");
16
16
  const matchesMiddleware = (middleware, route) => middleware.some((middlewarePath) => route.startsWith(middlewarePath));
17
- const generateHiddenPathRedirects = ({ basePath }) => constants_1.HIDDEN_PATHS.map((path) => ({
18
- from: `${basePath}${path}`,
19
- to: '/404.html',
20
- status: 404,
21
- force: true,
22
- }));
23
17
  const generateLocaleRedirects = ({ i18n, basePath, trailingSlash, }) => {
24
18
  const redirects = [];
25
19
  // If the cookie is set, we need to redirect at the origin
@@ -187,7 +181,6 @@ exports.generateDynamicRewrites = generateDynamicRewrites;
187
181
  const generateRedirects = async ({ netlifyConfig, nextConfig: { i18n, basePath, trailingSlash, appDir }, buildId, apiLambdas, }) => {
188
182
  const { dynamicRoutes: prerenderedDynamicRoutes, routes: prerenderedStaticRoutes } = await (0, fs_extra_1.readJSON)((0, pathe_1.join)(netlifyConfig.build.publish, 'prerender-manifest.json'));
189
183
  const { dynamicRoutes, staticRoutes } = await (0, fs_extra_1.readJSON)((0, pathe_1.join)(netlifyConfig.build.publish, 'routes-manifest.json'));
190
- netlifyConfig.redirects.push(...generateHiddenPathRedirects({ basePath }));
191
184
  if (i18n && i18n.localeDetection !== false) {
192
185
  netlifyConfig.redirects.push(...generateLocaleRedirects({ i18n, basePath, trailingSlash }));
193
186
  }
@@ -93,7 +93,7 @@ const redirectsForNextRoute = ({ route, buildId, basePath, to, i18n, status = 20
93
93
  exports.redirectsForNextRoute = redirectsForNextRoute;
94
94
  const redirectsForNext404Route = ({ route, buildId, basePath, i18n, force = false, }) => netlifyRoutesForNextRoute({ route, buildId, i18n }).map(({ redirect, locale }) => ({
95
95
  from: `${basePath}${redirect}`,
96
- to: locale ? `${basePath}/server/pages/${locale}/404.html` : `${basePath}/server/pages/404.html`,
96
+ to: locale ? `${basePath}/${locale}/404.html` : `${basePath}/404.html`,
97
97
  status: 404,
98
98
  force,
99
99
  }));
package/lib/index.js CHANGED
@@ -92,7 +92,7 @@ const plugin = {
92
92
  }
93
93
  }
94
94
  const buildId = (0, fs_extra_1.readFileSync)((0, path_1.join)(publish, 'BUILD_ID'), 'utf8').trim();
95
- const apiLambdas = (0, flags_1.splitApiRoutes)(featureFlags)
95
+ const apiLambdas = (0, flags_1.splitApiRoutes)(featureFlags, publish)
96
96
  ? await (0, functions_1.getAPILambdas)(publish, appDir, pageExtensions)
97
97
  : await (0, functions_1.getExtendedApiRouteConfigs)(publish, appDir, pageExtensions).then((extendedRoutes) => extendedRoutes.map(functions_1.packSingleFunction));
98
98
  await (0, functions_1.generateFunctions)(constants, appDir, apiLambdas);
@@ -102,7 +102,7 @@ const plugin = {
102
102
  ignore,
103
103
  publish: (0, path_1.relative)(process.cwd(), publish),
104
104
  apiLambdas,
105
- featureFlags,
105
+ splitApiRoutes: (0, flags_1.splitApiRoutes)(featureFlags, publish),
106
106
  });
107
107
  await (0, files_1.movePublicFiles)({ appDir, outdir, publish, basePath });
108
108
  await (0, files_1.patchNextFiles)(appDir);
@@ -148,6 +148,10 @@ const plugin = {
148
148
  (0, verification_1.warnForProblematicUserRewrites)({ basePath, redirects });
149
149
  (0, verification_1.warnForRootRedirects)({ appDir });
150
150
  await (0, functions_1.warnOnApiRoutes)({ FUNCTIONS_DIST });
151
+ // we are removing metadata files from Publish directory
152
+ // we have to do this after functions were bundled as bundling still
153
+ // require those files, but we don't want to publish them
154
+ await (0, files_1.removeMetadataFiles)(publish);
151
155
  if (experimental === null || experimental === void 0 ? void 0 : experimental.appDir) {
152
156
  console.log('🧪 Thank you for testing "appDir" support on Netlify. For known issues and to give feedback, visit https://ntl.fyi/next-13-feedback');
153
157
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/plugin-nextjs",
3
- "version": "4.37.1",
3
+ "version": "4.37.2",
4
4
  "description": "Run Next.js seamlessly on Netlify",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -58,6 +58,8 @@ export const addMiddlewareHeaders = async (
58
58
  }
59
59
 
60
60
  interface ResponseCookies {
61
+ // This is non-standard that Next.js adds.
62
+ // See github.com/vercel/next.js/blob/de08f8b3d31ef45131dad97a7d0e95fa01001167/packages/next/src/compiled/@edge-runtime/cookies/index.js#L158
61
63
  readonly _headers: Headers
62
64
  }
63
65
 
@@ -191,7 +193,8 @@ export const buildResponse = async ({
191
193
  }
192
194
 
193
195
  // NextResponse doesn't set cookies onto the originResponse, so we need to copy them over
194
- if (response.cookies._headers.has('set-cookie')) {
196
+ // In some cases, it's possible there are no headers set. See https://github.com/netlify/pod-ecosystem-frameworks/issues/475
197
+ if (response.cookies._headers?.has('set-cookie')) {
195
198
  response.originResponse.headers.set('set-cookie', response.cookies._headers.get('set-cookie')!)
196
199
  }
197
200