UNPKG

38.6 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", {
3 value: true
4});
5exports.collectPages = collectPages;
6exports.printTreeView = printTreeView;
7exports.printCustomRoutes = printCustomRoutes;
8exports.computeFromManifest = computeFromManifest;
9exports.difference = difference;
10exports.getJsPageSizeInKb = getJsPageSizeInKb;
11exports.buildStaticPaths = buildStaticPaths;
12exports.isPageStatic = isPageStatic;
13exports.hasCustomGetInitialProps = hasCustomGetInitialProps;
14exports.getNamedExports = getNamedExports;
15exports.detectConflictingPaths = detectConflictingPaths;
16exports.getRawPageExtensions = getRawPageExtensions;
17exports.isFlightPage = isFlightPage;
18exports.getUnresolvedModuleFromError = getUnresolvedModuleFromError;
19exports.copyTracedFiles = copyTracedFiles;
20exports.isReservedPage = isReservedPage;
21exports.isCustomErrorPage = isCustomErrorPage;
22require("../server/node-polyfill-fetch");
23var _chalk = _interopRequireDefault(require("next/dist/compiled/chalk"));
24var _gzipSize = _interopRequireDefault(require("next/dist/compiled/gzip-size"));
25var _textTable = _interopRequireDefault(require("next/dist/compiled/text-table"));
26var _path = _interopRequireDefault(require("path"));
27var _fs = require("fs");
28var _reactIs = require("next/dist/compiled/react-is");
29var _stripAnsi = _interopRequireDefault(require("next/dist/compiled/strip-ansi"));
30var _constants = require("../lib/constants");
31var _prettyBytes = _interopRequireDefault(require("../lib/pretty-bytes"));
32var _recursiveReaddir = require("../lib/recursive-readdir");
33var _utils = require("../shared/lib/router/utils");
34var _isDynamic = require("../shared/lib/router/utils/is-dynamic");
35var _escapePathDelimiters = _interopRequireDefault(require("../shared/lib/router/utils/escape-path-delimiters"));
36var _findPageFile = require("../server/lib/find-page-file");
37var _normalizePagePath = require("../server/normalize-page-path");
38var _normalizeTrailingSlash = require("../client/normalize-trailing-slash");
39var _normalizeLocalePath = require("../shared/lib/i18n/normalize-locale-path");
40var Log = _interopRequireWildcard(require("./output/log"));
41var _loadComponents = require("../server/load-components");
42var _trace = require("../trace");
43var _config = require("../server/config");
44var _isError = _interopRequireDefault(require("../lib/is-error"));
45var _recursiveDelete = require("../lib/recursive-delete");
46var _asyncSema = require("next/dist/compiled/async-sema");
47function _interopRequireDefault(obj) {
48 return obj && obj.__esModule ? obj : {
49 default: obj
50 };
51}
52function _interopRequireWildcard(obj) {
53 if (obj && obj.__esModule) {
54 return obj;
55 } else {
56 var newObj = {};
57 if (obj != null) {
58 for(var key in obj){
59 if (Object.prototype.hasOwnProperty.call(obj, key)) {
60 var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};
61 if (desc.get || desc.set) {
62 Object.defineProperty(newObj, key, desc);
63 } else {
64 newObj[key] = obj[key];
65 }
66 }
67 }
68 }
69 newObj.default = obj;
70 return newObj;
71 }
72}
73const { builtinModules } = require('module');
74const RESERVED_PAGE = /^\/(_app|_error|_document|api(\/|$))/;
75const fileGzipStats = {};
76const fsStatGzip = (file)=>{
77 const cached = fileGzipStats[file];
78 if (cached) return cached;
79 return fileGzipStats[file] = _gzipSize.default.file(file);
80};
81const fileSize = async (file)=>(await _fs.promises.stat(file)).size
82;
83const fileStats = {};
84const fsStat = (file)=>{
85 const cached = fileStats[file];
86 if (cached) return cached;
87 return fileStats[file] = fileSize(file);
88};
89function collectPages(directory, pageExtensions) {
90 return (0, _recursiveReaddir).recursiveReadDir(directory, new RegExp(`\\.(?:${pageExtensions.join('|')})$`));
91}
92async function printTreeView(list, pageInfos, serverless, { distPath , buildId , pagesDir , pageExtensions , buildManifest , useStatic404 , gzipSize =true }) {
93 const getPrettySize = (_size)=>{
94 const size = (0, _prettyBytes).default(_size);
95 // green for 0-130kb
96 if (_size < 130 * 1000) return _chalk.default.green(size);
97 // yellow for 130-170kb
98 if (_size < 170 * 1000) return _chalk.default.yellow(size);
99 // red for >= 170kb
100 return _chalk.default.red.bold(size);
101 };
102 const MIN_DURATION = 300;
103 const getPrettyDuration = (_duration)=>{
104 const duration = `${_duration} ms`;
105 // green for 300-1000ms
106 if (_duration < 1000) return _chalk.default.green(duration);
107 // yellow for 1000-2000ms
108 if (_duration < 2000) return _chalk.default.yellow(duration);
109 // red for >= 2000ms
110 return _chalk.default.red.bold(duration);
111 };
112 const getCleanName = (fileName)=>fileName// Trim off `static/`
113 .replace(/^static\//, '')// Re-add `static/` for root files
114 .replace(/^<buildId>/, 'static')// Remove file hash
115 .replace(/(?:^|[.-])([0-9a-z]{6})[0-9a-z]{14}(?=\.)/, '.$1')
116 ;
117 const messages = [
118 [
119 'Page',
120 'Size',
121 'First Load JS'
122 ].map((entry)=>_chalk.default.underline(entry)
123 ),
124 ];
125 const hasCustomApp = await (0, _findPageFile).findPageFile(pagesDir, '/_app', pageExtensions);
126 pageInfos.set('/404', {
127 ...pageInfos.get('/404') || pageInfos.get('/_error'),
128 static: useStatic404
129 });
130 if (!list.includes('/404')) {
131 list = [
132 ...list,
133 '/404'
134 ];
135 }
136 const sizeData = await computeFromManifest(buildManifest, distPath, gzipSize, pageInfos);
137 const usedSymbols = new Set();
138 const pageList = list.slice().filter((e)=>!(e === '/_document' || e === '/_error' || !hasCustomApp && e === '/_app')
139 ).sort((a, b)=>a.localeCompare(b)
140 );
141 pageList.forEach((item, i, arr)=>{
142 var ref, ref1, ref2;
143 const border = i === 0 ? arr.length === 1 ? '─' : '┌' : i === arr.length - 1 ? '└' : '├';
144 const pageInfo = pageInfos.get(item);
145 const ampFirst = buildManifest.ampFirstPages.includes(item);
146 const totalDuration = ((pageInfo === null || pageInfo === void 0 ? void 0 : pageInfo.pageDuration) || 0) + ((pageInfo === null || pageInfo === void 0 ? void 0 : (ref = pageInfo.ssgPageDurations) === null || ref === void 0 ? void 0 : ref.reduce((a, b)=>a + (b || 0)
147 , 0)) || 0);
148 const symbol = item === '/_app' ? ' ' : item.endsWith('/_middleware') ? 'ƒ' : (pageInfo === null || pageInfo === void 0 ? void 0 : pageInfo.static) ? '○' : (pageInfo === null || pageInfo === void 0 ? void 0 : pageInfo.isSsg) ? '●' : (pageInfo === null || pageInfo === void 0 ? void 0 : pageInfo.runtime) === 'edge' ? 'ℇ' : 'λ';
149 usedSymbols.add(symbol);
150 if (pageInfo === null || pageInfo === void 0 ? void 0 : pageInfo.initialRevalidateSeconds) usedSymbols.add('ISR');
151 messages.push([
152 `${border} ${symbol} ${(pageInfo === null || pageInfo === void 0 ? void 0 : pageInfo.initialRevalidateSeconds) ? `${item} (ISR: ${pageInfo === null || pageInfo === void 0 ? void 0 : pageInfo.initialRevalidateSeconds} Seconds)` : item}${totalDuration > MIN_DURATION ? ` (${getPrettyDuration(totalDuration)})` : ''}`,
153 pageInfo ? ampFirst ? _chalk.default.cyan('AMP') : pageInfo.size >= 0 ? (0, _prettyBytes).default(pageInfo.size) : '' : '',
154 pageInfo ? ampFirst ? _chalk.default.cyan('AMP') : pageInfo.size >= 0 ? getPrettySize(pageInfo.totalSize) : '' : '',
155 ]);
156 const uniqueCssFiles = ((ref1 = buildManifest.pages[item]) === null || ref1 === void 0 ? void 0 : ref1.filter((file)=>file.endsWith('.css') && sizeData.uniqueFiles.includes(file)
157 )) || [];
158 if (uniqueCssFiles.length > 0) {
159 const contSymbol = i === arr.length - 1 ? ' ' : '├';
160 uniqueCssFiles.forEach((file, index, { length })=>{
161 const innerSymbol = index === length - 1 ? '└' : '├';
162 messages.push([
163 `${contSymbol} ${innerSymbol} ${getCleanName(file)}`,
164 (0, _prettyBytes).default(sizeData.sizeUniqueFiles[file]),
165 '',
166 ]);
167 });
168 }
169 if (pageInfo === null || pageInfo === void 0 ? void 0 : (ref2 = pageInfo.ssgPageRoutes) === null || ref2 === void 0 ? void 0 : ref2.length) {
170 const totalRoutes = pageInfo.ssgPageRoutes.length;
171 const contSymbol = i === arr.length - 1 ? ' ' : '├';
172 let routes;
173 if (pageInfo.ssgPageDurations && pageInfo.ssgPageDurations.some((d)=>d > MIN_DURATION
174 )) {
175 const previewPages = totalRoutes === 8 ? 8 : Math.min(totalRoutes, 7);
176 const routesWithDuration = pageInfo.ssgPageRoutes.map((route, idx)=>({
177 route,
178 duration: pageInfo.ssgPageDurations[idx] || 0
179 })
180 ).sort(({ duration: a }, { duration: b })=>// Sort by duration
181 // keep too small durations in original order at the end
182 a <= MIN_DURATION && b <= MIN_DURATION ? 0 : b - a
183 );
184 routes = routesWithDuration.slice(0, previewPages);
185 const remainingRoutes = routesWithDuration.slice(previewPages);
186 if (remainingRoutes.length) {
187 const remaining = remainingRoutes.length;
188 const avgDuration = Math.round(remainingRoutes.reduce((total, { duration })=>total + duration
189 , 0) / remainingRoutes.length);
190 routes.push({
191 route: `[+${remaining} more paths]`,
192 duration: 0,
193 avgDuration
194 });
195 }
196 } else {
197 const previewPages = totalRoutes === 4 ? 4 : Math.min(totalRoutes, 3);
198 routes = pageInfo.ssgPageRoutes.slice(0, previewPages).map((route)=>({
199 route,
200 duration: 0
201 })
202 );
203 if (totalRoutes > previewPages) {
204 const remaining = totalRoutes - previewPages;
205 routes.push({
206 route: `[+${remaining} more paths]`,
207 duration: 0
208 });
209 }
210 }
211 routes.forEach(({ route , duration , avgDuration }, index, { length })=>{
212 const innerSymbol = index === length - 1 ? '└' : '├';
213 messages.push([
214 `${contSymbol} ${innerSymbol} ${route}${duration > MIN_DURATION ? ` (${getPrettyDuration(duration)})` : ''}${avgDuration && avgDuration > MIN_DURATION ? ` (avg ${getPrettyDuration(avgDuration)})` : ''}`,
215 '',
216 '',
217 ]);
218 });
219 }
220 });
221 const sharedFilesSize = sizeData.sizeCommonFiles;
222 const sharedFiles = sizeData.sizeCommonFile;
223 messages.push([
224 '+ First Load JS shared by all',
225 getPrettySize(sharedFilesSize),
226 '',
227 ]);
228 const sharedFileKeys = Object.keys(sharedFiles);
229 const sharedCssFiles = [];
230 [
231 ...sharedFileKeys.filter((file)=>{
232 if (file.endsWith('.css')) {
233 sharedCssFiles.push(file);
234 return false;
235 }
236 return true;
237 }).map((e)=>e.replace(buildId, '<buildId>')
238 ).sort(),
239 ...sharedCssFiles.map((e)=>e.replace(buildId, '<buildId>')
240 ).sort(),
241 ].forEach((fileName, index, { length })=>{
242 const innerSymbol = index === length - 1 ? '└' : '├';
243 const originalName = fileName.replace('<buildId>', buildId);
244 const cleanName = getCleanName(fileName);
245 messages.push([
246 ` ${innerSymbol} ${cleanName}`,
247 (0, _prettyBytes).default(sharedFiles[originalName]),
248 '',
249 ]);
250 });
251 console.log((0, _textTable).default(messages, {
252 align: [
253 'l',
254 'l',
255 'r'
256 ],
257 stringLength: (str)=>(0, _stripAnsi).default(str).length
258 }));
259 console.log();
260 console.log((0, _textTable).default([
261 usedSymbols.has('ƒ') && [
262 'ƒ',
263 '(Middleware)',
264 `intercepts requests (uses ${_chalk.default.cyan('_middleware')})`,
265 ],
266 usedSymbols.has('ℇ') && [
267 'ℇ',
268 '(Streaming)',
269 `server-side renders with streaming (uses React 18 SSR streaming or Server Components)`,
270 ],
271 usedSymbols.has('λ') && [
272 'λ',
273 serverless ? '(Lambda)' : '(Server)',
274 `server-side renders at runtime (uses ${_chalk.default.cyan('getInitialProps')} or ${_chalk.default.cyan('getServerSideProps')})`,
275 ],
276 usedSymbols.has('○') && [
277 '○',
278 '(Static)',
279 'automatically rendered as static HTML (uses no initial props)',
280 ],
281 usedSymbols.has('●') && [
282 '●',
283 '(SSG)',
284 `automatically generated as static HTML + JSON (uses ${_chalk.default.cyan('getStaticProps')})`,
285 ],
286 usedSymbols.has('ISR') && [
287 '',
288 '(ISR)',
289 `incremental static regeneration (uses revalidate in ${_chalk.default.cyan('getStaticProps')})`,
290 ],
291 ].filter((x)=>x
292 ), {
293 align: [
294 'l',
295 'l',
296 'l'
297 ],
298 stringLength: (str)=>(0, _stripAnsi).default(str).length
299 }));
300 console.log();
301}
302function printCustomRoutes({ redirects , rewrites , headers }) {
303 const printRoutes = (routes, type)=>{
304 const isRedirects = type === 'Redirects';
305 const isHeaders = type === 'Headers';
306 console.log(_chalk.default.underline(type));
307 console.log();
308 /*
309 ┌ source
310 ├ permanent/statusCode
311 └ destination
312 */ const routesStr = routes.map((route)=>{
313 let routeStr = `┌ source: ${route.source}\n`;
314 if (!isHeaders) {
315 const r = route;
316 routeStr += `${isRedirects ? '├' : '└'} destination: ${r.destination}\n`;
317 }
318 if (isRedirects) {
319 const r = route;
320 routeStr += `└ ${r.statusCode ? `status: ${r.statusCode}` : `permanent: ${r.permanent}`}\n`;
321 }
322 if (isHeaders) {
323 const r = route;
324 routeStr += `└ headers:\n`;
325 for(let i = 0; i < r.headers.length; i++){
326 const header = r.headers[i];
327 const last = i === headers.length - 1;
328 routeStr += ` ${last ? '└' : '├'} ${header.key}: ${header.value}\n`;
329 }
330 }
331 return routeStr;
332 }).join('\n');
333 console.log(routesStr, '\n');
334 };
335 if (redirects.length) {
336 printRoutes(redirects, 'Redirects');
337 }
338 if (headers.length) {
339 printRoutes(headers, 'Headers');
340 }
341 const combinedRewrites = [
342 ...rewrites.beforeFiles,
343 ...rewrites.afterFiles,
344 ...rewrites.fallback,
345 ];
346 if (combinedRewrites.length) {
347 printRoutes(combinedRewrites, 'Rewrites');
348 }
349}
350let cachedBuildManifest;
351let lastCompute;
352let lastComputePageInfo;
353async function computeFromManifest(manifest, distPath, gzipSize = true, pageInfos) {
354 if (Object.is(cachedBuildManifest, manifest) && lastComputePageInfo === !!pageInfos) {
355 return lastCompute;
356 }
357 let expected = 0;
358 const files = new Map();
359 Object.keys(manifest.pages).forEach((key)=>{
360 if (pageInfos) {
361 const pageInfo = pageInfos.get(key);
362 // don't include AMP pages since they don't rely on shared bundles
363 // AMP First pages are not under the pageInfos key
364 if (pageInfo === null || pageInfo === void 0 ? void 0 : pageInfo.isHybridAmp) {
365 return;
366 }
367 }
368 ++expected;
369 manifest.pages[key].forEach((file)=>{
370 if (key === '/_app') {
371 files.set(file, Infinity);
372 } else if (files.has(file)) {
373 files.set(file, files.get(file) + 1);
374 } else {
375 files.set(file, 1);
376 }
377 });
378 });
379 const getSize = gzipSize ? fsStatGzip : fsStat;
380 const commonFiles = [
381 ...files.entries()
382 ].filter(([, len])=>len === expected || len === Infinity
383 ).map(([f])=>f
384 );
385 const uniqueFiles = [
386 ...files.entries()
387 ].filter(([, len])=>len === 1
388 ).map(([f])=>f
389 );
390 let stats;
391 try {
392 stats = await Promise.all(commonFiles.map(async (f)=>[
393 f,
394 await getSize(_path.default.join(distPath, f))
395 ]
396 ));
397 } catch (_) {
398 stats = [];
399 }
400 let uniqueStats;
401 try {
402 uniqueStats = await Promise.all(uniqueFiles.map(async (f)=>[
403 f,
404 await getSize(_path.default.join(distPath, f))
405 ]
406 ));
407 } catch (_1) {
408 uniqueStats = [];
409 }
410 lastCompute = {
411 commonFiles,
412 uniqueFiles,
413 sizeUniqueFiles: uniqueStats.reduce((obj, n)=>Object.assign(obj, {
414 [n[0]]: n[1]
415 })
416 , {}),
417 sizeCommonFile: stats.reduce((obj, n)=>Object.assign(obj, {
418 [n[0]]: n[1]
419 })
420 , {}),
421 sizeCommonFiles: stats.reduce((size, [f, stat])=>{
422 if (f.endsWith('.css')) return size;
423 return size + stat;
424 }, 0)
425 };
426 cachedBuildManifest = manifest;
427 lastComputePageInfo = !!pageInfos;
428 return lastCompute;
429}
430function difference(main, sub) {
431 const a = new Set(main);
432 const b = new Set(sub);
433 return [
434 ...a
435 ].filter((x)=>!b.has(x)
436 );
437}
438function intersect(main, sub) {
439 const a = new Set(main);
440 const b = new Set(sub);
441 return [
442 ...new Set([
443 ...a
444 ].filter((x)=>b.has(x)
445 ))
446 ];
447}
448function sum(a) {
449 return a.reduce((size, stat)=>size + stat
450 , 0);
451}
452async function getJsPageSizeInKb(page, distPath, buildManifest, gzipSize = true, computedManifestData) {
453 const data = computedManifestData || await computeFromManifest(buildManifest, distPath, gzipSize);
454 const fnFilterJs = (entry)=>entry.endsWith('.js')
455 ;
456 const pageFiles = (buildManifest.pages[(0, _normalizePagePath).denormalizePagePath(page)] || []).filter(fnFilterJs);
457 const appFiles = (buildManifest.pages['/_app'] || []).filter(fnFilterJs);
458 const fnMapRealPath = (dep)=>`${distPath}/${dep}`
459 ;
460 const allFilesReal = [
461 ...new Set([
462 ...pageFiles,
463 ...appFiles
464 ])
465 ].map(fnMapRealPath);
466 const selfFilesReal = difference(intersect(pageFiles, data.uniqueFiles), data.commonFiles).map(fnMapRealPath);
467 const getSize = gzipSize ? fsStatGzip : fsStat;
468 try {
469 // Doesn't use `Promise.all`, as we'd double compute duplicate files. This
470 // function is memoized, so the second one will instantly resolve.
471 const allFilesSize = sum(await Promise.all(allFilesReal.map(getSize)));
472 const selfFilesSize = sum(await Promise.all(selfFilesReal.map(getSize)));
473 return [
474 selfFilesSize,
475 allFilesSize
476 ];
477 } catch (_) {}
478 return [
479 -1,
480 -1
481 ];
482}
483async function buildStaticPaths(page, getStaticPaths, configFileName, locales, defaultLocale) {
484 const prerenderPaths = new Set();
485 const encodedPrerenderPaths = new Set();
486 const _routeRegex = (0, _utils).getRouteRegex(page);
487 const _routeMatcher = (0, _utils).getRouteMatcher(_routeRegex);
488 // Get the default list of allowed params.
489 const _validParamKeys = Object.keys(_routeMatcher(page));
490 const staticPathsResult = await getStaticPaths({
491 locales,
492 defaultLocale
493 });
494 const expectedReturnVal = `Expected: { paths: [], fallback: boolean }\n` + `See here for more info: https://nextjs.org/docs/messages/invalid-getstaticpaths-value`;
495 if (!staticPathsResult || typeof staticPathsResult !== 'object' || Array.isArray(staticPathsResult)) {
496 throw new Error(`Invalid value returned from getStaticPaths in ${page}. Received ${typeof staticPathsResult} ${expectedReturnVal}`);
497 }
498 const invalidStaticPathKeys = Object.keys(staticPathsResult).filter((key)=>!(key === 'paths' || key === 'fallback')
499 );
500 if (invalidStaticPathKeys.length > 0) {
501 throw new Error(`Extra keys returned from getStaticPaths in ${page} (${invalidStaticPathKeys.join(', ')}) ${expectedReturnVal}`);
502 }
503 if (!(typeof staticPathsResult.fallback === 'boolean' || staticPathsResult.fallback === 'blocking')) {
504 throw new Error(`The \`fallback\` key must be returned from getStaticPaths in ${page}.\n` + expectedReturnVal);
505 }
506 const toPrerender = staticPathsResult.paths;
507 if (!Array.isArray(toPrerender)) {
508 throw new Error(`Invalid \`paths\` value returned from getStaticPaths in ${page}.\n` + `\`paths\` must be an array of strings or objects of shape { params: [key: string]: string }`);
509 }
510 toPrerender.forEach((entry)=>{
511 // For a string-provided path, we must make sure it matches the dynamic
512 // route.
513 if (typeof entry === 'string') {
514 entry = (0, _normalizeTrailingSlash).removePathTrailingSlash(entry);
515 const localePathResult = (0, _normalizeLocalePath).normalizeLocalePath(entry, locales);
516 let cleanedEntry = entry;
517 if (localePathResult.detectedLocale) {
518 cleanedEntry = entry.slice(localePathResult.detectedLocale.length + 1);
519 } else if (defaultLocale) {
520 entry = `/${defaultLocale}${entry}`;
521 }
522 const result = _routeMatcher(cleanedEntry);
523 if (!result) {
524 throw new Error(`The provided path \`${cleanedEntry}\` does not match the page: \`${page}\`.`);
525 }
526 // If leveraging the string paths variant the entry should already be
527 // encoded so we decode the segments ensuring we only escape path
528 // delimiters
529 prerenderPaths.add(entry.split('/').map((segment)=>(0, _escapePathDelimiters).default(decodeURIComponent(segment), true)
530 ).join('/'));
531 encodedPrerenderPaths.add(entry);
532 } else {
533 const invalidKeys = Object.keys(entry).filter((key)=>key !== 'params' && key !== 'locale'
534 );
535 if (invalidKeys.length) {
536 throw new Error(`Additional keys were returned from \`getStaticPaths\` in page "${page}". ` + `URL Parameters intended for this dynamic route must be nested under the \`params\` key, i.e.:` + `\n\n\treturn { params: { ${_validParamKeys.map((k)=>`${k}: ...`
537 ).join(', ')} } }` + `\n\nKeys that need to be moved: ${invalidKeys.join(', ')}.\n`);
538 }
539 const { params ={} } = entry;
540 let builtPage = page;
541 let encodedBuiltPage = page;
542 _validParamKeys.forEach((validParamKey)=>{
543 const { repeat , optional } = _routeRegex.groups[validParamKey];
544 let paramValue = params[validParamKey];
545 if (optional && params.hasOwnProperty(validParamKey) && (paramValue === null || paramValue === undefined || paramValue === false)) {
546 paramValue = [];
547 }
548 if (repeat && !Array.isArray(paramValue) || !repeat && typeof paramValue !== 'string') {
549 throw new Error(`A required parameter (${validParamKey}) was not provided as ${repeat ? 'an array' : 'a string'} in getStaticPaths for ${page}`);
550 }
551 let replaced = `[${repeat ? '...' : ''}${validParamKey}]`;
552 if (optional) {
553 replaced = `[${replaced}]`;
554 }
555 builtPage = builtPage.replace(replaced, repeat ? paramValue.map((segment)=>(0, _escapePathDelimiters).default(segment, true)
556 ).join('/') : (0, _escapePathDelimiters).default(paramValue, true)).replace(/(?!^)\/$/, '');
557 encodedBuiltPage = encodedBuiltPage.replace(replaced, repeat ? paramValue.map(encodeURIComponent).join('/') : encodeURIComponent(paramValue)).replace(/(?!^)\/$/, '');
558 });
559 if (entry.locale && !(locales === null || locales === void 0 ? void 0 : locales.includes(entry.locale))) {
560 throw new Error(`Invalid locale returned from getStaticPaths for ${page}, the locale ${entry.locale} is not specified in ${configFileName}`);
561 }
562 const curLocale = entry.locale || defaultLocale || '';
563 prerenderPaths.add(`${curLocale ? `/${curLocale}` : ''}${curLocale && builtPage === '/' ? '' : builtPage}`);
564 encodedPrerenderPaths.add(`${curLocale ? `/${curLocale}` : ''}${curLocale && encodedBuiltPage === '/' ? '' : encodedBuiltPage}`);
565 }
566 });
567 return {
568 paths: [
569 ...prerenderPaths
570 ],
571 fallback: staticPathsResult.fallback,
572 encodedPaths: [
573 ...encodedPrerenderPaths
574 ]
575 };
576}
577async function isPageStatic(page, distDir, serverless, configFileName, runtimeEnvConfig, httpAgentOptions, locales, defaultLocale, parentId) {
578 const isPageStaticSpan = (0, _trace).trace('is-page-static-utils', parentId);
579 return isPageStaticSpan.traceAsyncFn(async ()=>{
580 try {
581 require('../shared/lib/runtime-config').setConfig(runtimeEnvConfig);
582 (0, _config).setHttpAgentOptions(httpAgentOptions);
583 const mod = await (0, _loadComponents).loadComponents(distDir, page, serverless);
584 const Comp = mod.Component;
585 if (!Comp || !(0, _reactIs).isValidElementType(Comp) || typeof Comp === 'string') {
586 throw new Error('INVALID_DEFAULT_EXPORT');
587 }
588 const hasFlightData = !!mod.__next_rsc__;
589 const hasGetInitialProps = !!Comp.getInitialProps;
590 const hasStaticProps = !!mod.getStaticProps;
591 const hasStaticPaths = !!mod.getStaticPaths;
592 const hasServerProps = !!mod.getServerSideProps;
593 const hasLegacyServerProps = !!await mod.ComponentMod.unstable_getServerProps;
594 const hasLegacyStaticProps = !!await mod.ComponentMod.unstable_getStaticProps;
595 const hasLegacyStaticPaths = !!await mod.ComponentMod.unstable_getStaticPaths;
596 const hasLegacyStaticParams = !!await mod.ComponentMod.unstable_getStaticParams;
597 if (hasLegacyStaticParams) {
598 throw new Error(`unstable_getStaticParams was replaced with getStaticPaths. Please update your code.`);
599 }
600 if (hasLegacyStaticPaths) {
601 throw new Error(`unstable_getStaticPaths was replaced with getStaticPaths. Please update your code.`);
602 }
603 if (hasLegacyStaticProps) {
604 throw new Error(`unstable_getStaticProps was replaced with getStaticProps. Please update your code.`);
605 }
606 if (hasLegacyServerProps) {
607 throw new Error(`unstable_getServerProps was replaced with getServerSideProps. Please update your code.`);
608 }
609 // A page cannot be prerendered _and_ define a data requirement. That's
610 // contradictory!
611 if (hasGetInitialProps && hasStaticProps) {
612 throw new Error(_constants.SSG_GET_INITIAL_PROPS_CONFLICT);
613 }
614 if (hasGetInitialProps && hasServerProps) {
615 throw new Error(_constants.SERVER_PROPS_GET_INIT_PROPS_CONFLICT);
616 }
617 if (hasStaticProps && hasServerProps) {
618 throw new Error(_constants.SERVER_PROPS_SSG_CONFLICT);
619 }
620 const pageIsDynamic = (0, _isDynamic).isDynamicRoute(page);
621 // A page cannot have static parameters if it is not a dynamic page.
622 if (hasStaticProps && hasStaticPaths && !pageIsDynamic) {
623 throw new Error(`getStaticPaths can only be used with dynamic pages, not '${page}'.` + `\nLearn more: https://nextjs.org/docs/routing/dynamic-routes`);
624 }
625 if (hasStaticProps && pageIsDynamic && !hasStaticPaths) {
626 throw new Error(`getStaticPaths is required for dynamic SSG pages and is missing for '${page}'.` + `\nRead more: https://nextjs.org/docs/messages/invalid-getstaticpaths-value`);
627 }
628 let prerenderRoutes;
629 let encodedPrerenderRoutes;
630 let prerenderFallback;
631 if (hasStaticProps && hasStaticPaths) {
632 ({ paths: prerenderRoutes , fallback: prerenderFallback , encodedPaths: encodedPrerenderRoutes , } = await buildStaticPaths(page, mod.getStaticPaths, configFileName, locales, defaultLocale));
633 }
634 const isNextImageImported = global.__NEXT_IMAGE_IMPORTED;
635 const config = mod.pageConfig;
636 return {
637 isStatic: !hasStaticProps && !hasGetInitialProps && !hasServerProps && !hasFlightData,
638 isHybridAmp: config.amp === 'hybrid',
639 isAmpOnly: config.amp === true,
640 prerenderRoutes,
641 prerenderFallback,
642 encodedPrerenderRoutes,
643 hasStaticProps,
644 hasServerProps,
645 hasFlightData,
646 isNextImageImported,
647 traceIncludes: config.unstable_includeFiles || [],
648 traceExcludes: config.unstable_excludeFiles || []
649 };
650 } catch (err) {
651 if ((0, _isError).default(err) && err.code === 'MODULE_NOT_FOUND') return {};
652 throw err;
653 }
654 });
655}
656async function hasCustomGetInitialProps(page, distDir, isLikeServerless, runtimeEnvConfig, checkingApp) {
657 require('../shared/lib/runtime-config').setConfig(runtimeEnvConfig);
658 const components = await (0, _loadComponents).loadComponents(distDir, page, isLikeServerless);
659 let mod = components.ComponentMod;
660 if (checkingApp) {
661 mod = await mod._app || mod.default || mod;
662 } else {
663 mod = mod.default || mod;
664 }
665 mod = await mod;
666 return mod.getInitialProps !== mod.origGetInitialProps;
667}
668async function getNamedExports(page, distDir, isLikeServerless, runtimeEnvConfig) {
669 require('../shared/lib/runtime-config').setConfig(runtimeEnvConfig);
670 const components = await (0, _loadComponents).loadComponents(distDir, page, isLikeServerless);
671 let mod = components.ComponentMod;
672 return Object.keys(mod);
673}
674function detectConflictingPaths(combinedPages, ssgPages, additionalSsgPaths) {
675 const conflictingPaths = new Map();
676 const dynamicSsgPages = [
677 ...ssgPages
678 ].filter((page)=>(0, _isDynamic).isDynamicRoute(page)
679 );
680 additionalSsgPaths.forEach((paths, pathsPage)=>{
681 paths.forEach((curPath)=>{
682 const lowerPath = curPath.toLowerCase();
683 let conflictingPage = combinedPages.find((page)=>page.toLowerCase() === lowerPath
684 );
685 if (conflictingPage) {
686 conflictingPaths.set(lowerPath, [
687 {
688 path: curPath,
689 page: pathsPage
690 },
691 {
692 path: conflictingPage,
693 page: conflictingPage
694 },
695 ]);
696 } else {
697 let conflictingPath;
698 conflictingPage = dynamicSsgPages.find((page)=>{
699 var ref;
700 if (page === pathsPage) return false;
701 conflictingPath = (ref = additionalSsgPaths.get(page)) === null || ref === void 0 ? void 0 : ref.find((compPath)=>compPath.toLowerCase() === lowerPath
702 );
703 return conflictingPath;
704 });
705 if (conflictingPage && conflictingPath) {
706 conflictingPaths.set(lowerPath, [
707 {
708 path: curPath,
709 page: pathsPage
710 },
711 {
712 path: conflictingPath,
713 page: conflictingPage
714 },
715 ]);
716 }
717 }
718 });
719 });
720 if (conflictingPaths.size > 0) {
721 let conflictingPathsOutput = '';
722 conflictingPaths.forEach((pathItems)=>{
723 pathItems.forEach((pathItem, idx)=>{
724 const isDynamic = pathItem.page !== pathItem.path;
725 if (idx > 0) {
726 conflictingPathsOutput += 'conflicts with ';
727 }
728 conflictingPathsOutput += `path: "${pathItem.path}"${isDynamic ? ` from page: "${pathItem.page}" ` : ' '}`;
729 });
730 conflictingPathsOutput += '\n';
731 });
732 Log.error('Conflicting paths returned from getStaticPaths, paths must be unique per page.\n' + 'See more info here: https://nextjs.org/docs/messages/conflicting-ssg-paths\n\n' + conflictingPathsOutput);
733 process.exit(1);
734 }
735}
736function getRawPageExtensions(pageExtensions) {
737 return pageExtensions.filter((ext)=>!ext.startsWith('client.') && !ext.startsWith('server.')
738 );
739}
740function isFlightPage(nextConfig, filePath) {
741 if (!nextConfig.experimental.serverComponents) {
742 return false;
743 }
744 const rawPageExtensions = getRawPageExtensions(nextConfig.pageExtensions || []);
745 return rawPageExtensions.some((ext)=>{
746 return filePath.endsWith(`.server.${ext}`);
747 });
748}
749function getUnresolvedModuleFromError(error) {
750 const moduleErrorRegex = new RegExp(`Module not found: Can't resolve '(\\w+)'`);
751 const [, moduleName] = error.match(moduleErrorRegex) || [];
752 return builtinModules.find((item)=>item === moduleName
753 );
754}
755async function copyTracedFiles(dir, distDir, pageKeys, tracingRoot, serverConfig, middlewareManifest) {
756 const outputPath = _path.default.join(distDir, 'standalone');
757 const copiedFiles = new Set();
758 await (0, _recursiveDelete).recursiveDelete(outputPath);
759 async function handleTraceFiles(traceFilePath) {
760 const traceData = JSON.parse(await _fs.promises.readFile(traceFilePath, 'utf8'));
761 const copySema = new _asyncSema.Sema(10, {
762 capacity: traceData.files.length
763 });
764 const traceFileDir = _path.default.dirname(traceFilePath);
765 await Promise.all(traceData.files.map(async (relativeFile)=>{
766 await copySema.acquire();
767 const tracedFilePath = _path.default.join(traceFileDir, relativeFile);
768 const fileOutputPath = _path.default.join(outputPath, _path.default.relative(tracingRoot, tracedFilePath));
769 if (!copiedFiles.has(fileOutputPath)) {
770 copiedFiles.add(fileOutputPath);
771 await _fs.promises.mkdir(_path.default.dirname(fileOutputPath), {
772 recursive: true
773 });
774 const symlink = await _fs.promises.readlink(tracedFilePath).catch(()=>null
775 );
776 if (symlink) {
777 console.log('symlink', _path.default.relative(tracingRoot, symlink));
778 await _fs.promises.symlink(_path.default.relative(tracingRoot, symlink), fileOutputPath);
779 } else {
780 await _fs.promises.copyFile(tracedFilePath, fileOutputPath);
781 }
782 }
783 await copySema.release();
784 }));
785 }
786 for (const page of pageKeys){
787 if (_constants.MIDDLEWARE_ROUTE.test(page)) {
788 const { files } = middlewareManifest.middleware[page.replace(/\/_middleware$/, '') || '/'];
789 for (const file of files){
790 const originalPath = _path.default.join(distDir, file);
791 const fileOutputPath = _path.default.join(outputPath, _path.default.relative(tracingRoot, distDir), file);
792 await _fs.promises.mkdir(_path.default.dirname(fileOutputPath), {
793 recursive: true
794 });
795 await _fs.promises.copyFile(originalPath, fileOutputPath);
796 }
797 continue;
798 }
799 const pageFile = _path.default.join(distDir, 'server', 'pages', `${(0, _normalizePagePath).normalizePagePath(page)}.js`);
800 const pageTraceFile = `${pageFile}.nft.json`;
801 await handleTraceFiles(pageTraceFile);
802 }
803 await handleTraceFiles(_path.default.join(distDir, 'next-server.js.nft.json'));
804 const serverOutputPath = _path.default.join(outputPath, _path.default.relative(tracingRoot, dir), 'server.js');
805 await _fs.promises.writeFile(serverOutputPath, `
806process.env.NODE_ENV = 'production'
807process.chdir(__dirname)
808const NextServer = require('next/dist/server/next-server').default
809const http = require('http')
810const path = require('path')
811
812// Make sure commands gracefully respect termination signals (e.g. from Docker)
813process.on('SIGTERM', () => process.exit(0))
814process.on('SIGINT', () => process.exit(0))
815
816let handler
817
818const server = http.createServer(async (req, res) => {
819 try {
820 await handler(req, res)
821 } catch (err) {
822 console.error(err);
823 res.statusCode = 500
824 res.end('internal server error')
825 }
826})
827const currentPort = parseInt(process.env.PORT, 10) || 3000
828
829server.listen(currentPort, (err) => {
830 if (err) {
831 console.error("Failed to start server", err)
832 process.exit(1)
833 }
834 const addr = server.address()
835 const nextServer = new NextServer({
836 hostname: 'localhost',
837 port: currentPort,
838 dir: path.join(__dirname),
839 dev: false,
840 conf: ${JSON.stringify({
841 ...serverConfig,
842 distDir: `./${_path.default.relative(dir, distDir)}`
843 })},
844 })
845 handler = nextServer.getRequestHandler()
846
847 console.log("Listening on port", currentPort)
848})
849 `);
850}
851function isReservedPage(page) {
852 return RESERVED_PAGE.test(page);
853}
854function isCustomErrorPage(page) {
855 return page === '/404' || page === '/500';
856}
857
858//# sourceMappingURL=utils.js.map
\No newline at end of file