utils.js 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.unique = unique;
  6. exports.difference = difference;
  7. exports.computeFromManifest = computeFromManifest;
  8. exports.isMiddlewareFilename = isMiddlewareFilename;
  9. exports.printTreeView = printTreeView;
  10. exports.printCustomRoutes = printCustomRoutes;
  11. exports.getJsPageSizeInKb = getJsPageSizeInKb;
  12. exports.buildStaticPaths = buildStaticPaths;
  13. exports.buildAppStaticPaths = buildAppStaticPaths;
  14. exports.isPageStatic = isPageStatic;
  15. exports.hasCustomGetInitialProps = hasCustomGetInitialProps;
  16. exports.getNamedExports = getNamedExports;
  17. exports.detectConflictingPaths = detectConflictingPaths;
  18. exports.copyTracedFiles = copyTracedFiles;
  19. exports.isReservedPage = isReservedPage;
  20. exports.isCustomErrorPage = isCustomErrorPage;
  21. exports.isMiddlewareFile = isMiddlewareFile;
  22. exports.getPossibleMiddlewareFilenames = getPossibleMiddlewareFilenames;
  23. exports.collectGenerateParams = void 0;
  24. require("../server/node-polyfill-fetch");
  25. var _requireHook = _interopRequireDefault(require("../build/webpack/require-hook"));
  26. var _chalk = _interopRequireDefault(require("next/dist/compiled/chalk"));
  27. var _gzipSize = _interopRequireDefault(require("next/dist/compiled/gzip-size"));
  28. var _textTable = _interopRequireDefault(require("next/dist/compiled/text-table"));
  29. var _path = _interopRequireDefault(require("path"));
  30. var _fs = require("fs");
  31. var _reactIs = require("next/dist/compiled/react-is");
  32. var _stripAnsi = _interopRequireDefault(require("next/dist/compiled/strip-ansi"));
  33. var _constants = require("../lib/constants");
  34. var _prettyBytes = _interopRequireDefault(require("../lib/pretty-bytes"));
  35. var _routeRegex = require("../shared/lib/router/utils/route-regex");
  36. var _routeMatcher = require("../shared/lib/router/utils/route-matcher");
  37. var _isDynamic = require("../shared/lib/router/utils/is-dynamic");
  38. var _escapePathDelimiters = _interopRequireDefault(require("../shared/lib/router/utils/escape-path-delimiters"));
  39. var _findPageFile = require("../server/lib/find-page-file");
  40. var _removeTrailingSlash = require("../shared/lib/router/utils/remove-trailing-slash");
  41. var _normalizeLocalePath = require("../shared/lib/i18n/normalize-locale-path");
  42. var Log = _interopRequireWildcard(require("./output/log"));
  43. var _loadComponents = require("../server/load-components");
  44. var _trace = require("../trace");
  45. var _config = require("../server/config");
  46. var _recursiveDelete = require("../lib/recursive-delete");
  47. var _asyncSema = require("next/dist/compiled/async-sema");
  48. var _denormalizePagePath = require("../shared/lib/page-path/denormalize-page-path");
  49. var _normalizePagePath = require("../shared/lib/page-path/normalize-page-path");
  50. var _sandbox = require("../server/web/sandbox");
  51. function _interopRequireDefault(obj) {
  52. return obj && obj.__esModule ? obj : {
  53. default: obj
  54. };
  55. }
  56. function _getRequireWildcardCache() {
  57. if (typeof WeakMap !== "function") return null;
  58. var cache = new WeakMap();
  59. _getRequireWildcardCache = function() {
  60. return cache;
  61. };
  62. return cache;
  63. }
  64. function _interopRequireWildcard(obj) {
  65. if (obj && obj.__esModule) {
  66. return obj;
  67. }
  68. if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
  69. return {
  70. default: obj
  71. };
  72. }
  73. var cache = _getRequireWildcardCache();
  74. if (cache && cache.has(obj)) {
  75. return cache.get(obj);
  76. }
  77. var newObj = {};
  78. var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
  79. for(var key in obj){
  80. if (Object.prototype.hasOwnProperty.call(obj, key)) {
  81. var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
  82. if (desc && (desc.get || desc.set)) {
  83. Object.defineProperty(newObj, key, desc);
  84. } else {
  85. newObj[key] = obj[key];
  86. }
  87. }
  88. }
  89. newObj.default = obj;
  90. if (cache) {
  91. cache.set(obj, newObj);
  92. }
  93. return newObj;
  94. }
  95. const RESERVED_PAGE = /^\/(_app|_error|_document|api(\/|$))/;
  96. const fileGzipStats = {};
  97. const fsStatGzip = (file)=>{
  98. const cached = fileGzipStats[file];
  99. if (cached) return cached;
  100. return fileGzipStats[file] = _gzipSize.default.file(file);
  101. };
  102. const fileSize = async (file)=>(await _fs.promises.stat(file)).size;
  103. const fileStats = {};
  104. const fsStat = (file)=>{
  105. const cached = fileStats[file];
  106. if (cached) return cached;
  107. return fileStats[file] = fileSize(file);
  108. };
  109. (0, _requireHook).default();
  110. function unique(main, sub) {
  111. return [
  112. ...new Set([
  113. ...main,
  114. ...sub
  115. ])
  116. ];
  117. }
  118. function difference(main, sub) {
  119. const a = new Set(main);
  120. const b = new Set(sub);
  121. return [
  122. ...a
  123. ].filter((x)=>!b.has(x));
  124. }
  125. /**
  126. * Return an array of the items shared by both arrays.
  127. */ function intersect(main, sub) {
  128. const a = new Set(main);
  129. const b = new Set(sub);
  130. return [
  131. ...new Set([
  132. ...a
  133. ].filter((x)=>b.has(x)))
  134. ];
  135. }
  136. function sum(a) {
  137. return a.reduce((size, stat)=>size + stat, 0);
  138. }
  139. function denormalizeAppPagePath(page) {
  140. return page + "/page";
  141. }
  142. let cachedBuildManifest;
  143. let cachedAppBuildManifest;
  144. let lastCompute;
  145. let lastComputePageInfo;
  146. async function computeFromManifest(manifests, distPath, gzipSize = true, pageInfos) {
  147. var ref, ref1;
  148. if (Object.is(cachedBuildManifest, manifests.build) && lastComputePageInfo === !!pageInfos && Object.is(cachedAppBuildManifest, manifests.app)) {
  149. return lastCompute;
  150. }
  151. // Determine the files that are in pages and app and count them, this will
  152. // tell us if they are unique or common.
  153. const countBuildFiles = (map, key, manifest)=>{
  154. for (const file of manifest[key]){
  155. if (key === "/_app") {
  156. map.set(file, Infinity);
  157. } else if (map.has(file)) {
  158. map.set(file, map.get(file) + 1);
  159. } else {
  160. map.set(file, 1);
  161. }
  162. }
  163. };
  164. const files = {
  165. pages: {
  166. each: new Map(),
  167. expected: 0
  168. }
  169. };
  170. for(const key1 in manifests.build.pages){
  171. if (pageInfos) {
  172. const pageInfo = pageInfos.get(key1);
  173. // don't include AMP pages since they don't rely on shared bundles
  174. // AMP First pages are not under the pageInfos key
  175. if (pageInfo == null ? void 0 : pageInfo.isHybridAmp) {
  176. continue;
  177. }
  178. }
  179. files.pages.expected++;
  180. countBuildFiles(files.pages.each, key1, manifests.build.pages);
  181. }
  182. // Collect the build files form the app manifest.
  183. if ((ref = manifests.app) == null ? void 0 : ref.pages) {
  184. files.app = {
  185. each: new Map(),
  186. expected: 0
  187. };
  188. for(const key in manifests.app.pages){
  189. files.app.expected++;
  190. countBuildFiles(files.app.each, key, manifests.app.pages);
  191. }
  192. }
  193. const getSize = gzipSize ? fsStatGzip : fsStat;
  194. const stats = new Map();
  195. var ref2;
  196. // For all of the files in the pages and app manifests, compute the file size
  197. // at once.
  198. await Promise.all([
  199. ...new Set([
  200. ...files.pages.each.keys(),
  201. ...(ref2 = (ref1 = files.app) == null ? void 0 : ref1.each.keys()) != null ? ref2 : [],
  202. ]),
  203. ].map(async (f)=>{
  204. try {
  205. // Add the file size to the stats.
  206. stats.set(f, await getSize(_path.default.join(distPath, f)));
  207. } catch {}
  208. }));
  209. const groupFiles = async (listing)=>{
  210. const entries = [
  211. ...listing.each.entries()
  212. ];
  213. const shapeGroup = (group)=>group.reduce((acc, [f])=>{
  214. acc.files.push(f);
  215. const size = stats.get(f);
  216. if (typeof size === "number") {
  217. acc.size.total += size;
  218. }
  219. return acc;
  220. }, {
  221. files: [],
  222. size: {
  223. total: 0
  224. }
  225. });
  226. return {
  227. unique: shapeGroup(entries.filter(([, len])=>len === 1)),
  228. common: shapeGroup(entries.filter(([, len])=>len === listing.expected || len === Infinity))
  229. };
  230. };
  231. lastCompute = {
  232. router: {
  233. pages: await groupFiles(files.pages),
  234. app: files.app ? await groupFiles(files.app) : undefined
  235. },
  236. sizes: stats
  237. };
  238. cachedBuildManifest = manifests.build;
  239. cachedAppBuildManifest = manifests.app;
  240. lastComputePageInfo = !!pageInfos;
  241. return lastCompute;
  242. }
  243. function isMiddlewareFilename(file) {
  244. return file === _constants.MIDDLEWARE_FILENAME || file === `src/${_constants.MIDDLEWARE_FILENAME}`;
  245. }
  246. async function printTreeView(lists, pageInfos, serverless, { distPath , buildId , pagesDir , pageExtensions , buildManifest , appBuildManifest , middlewareManifest , useStatic404 , gzipSize =true }) {
  247. var ref6;
  248. const getPrettySize = (_size)=>{
  249. const size = (0, _prettyBytes).default(_size);
  250. // green for 0-130kb
  251. if (_size < 130 * 1000) return _chalk.default.green(size);
  252. // yellow for 130-170kb
  253. if (_size < 170 * 1000) return _chalk.default.yellow(size);
  254. // red for >= 170kb
  255. return _chalk.default.red.bold(size);
  256. };
  257. const MIN_DURATION = 300;
  258. const getPrettyDuration = (_duration)=>{
  259. const duration = `${_duration} ms`;
  260. // green for 300-1000ms
  261. if (_duration < 1000) return _chalk.default.green(duration);
  262. // yellow for 1000-2000ms
  263. if (_duration < 2000) return _chalk.default.yellow(duration);
  264. // red for >= 2000ms
  265. return _chalk.default.red.bold(duration);
  266. };
  267. const getCleanName = (fileName)=>fileName// Trim off `static/`
  268. .replace(/^static\//, "")// Re-add `static/` for root files
  269. .replace(/^<buildId>/, "static")// Remove file hash
  270. .replace(/(?:^|[.-])([0-9a-z]{6})[0-9a-z]{14}(?=\.)/, ".$1");
  271. // Check if we have a custom app.
  272. const hasCustomApp = pagesDir && await (0, _findPageFile).findPageFile(pagesDir, "/_app", pageExtensions, false);
  273. const filterAndSortList = (list)=>list.slice().filter((e)=>!(e === "/_document" || e === "/_error" || !hasCustomApp && e === "/_app")).sort((a, b)=>a.localeCompare(b));
  274. // Collect all the symbols we use so we can print the icons out.
  275. const usedSymbols = new Set();
  276. const messages = [];
  277. const stats = await computeFromManifest({
  278. build: buildManifest,
  279. app: appBuildManifest
  280. }, distPath, gzipSize, pageInfos);
  281. const printFileTree = async ({ list , routerType })=>{
  282. var ref7, ref3;
  283. messages.push([
  284. routerType === "app" ? "Route (app)" : "Route (pages)",
  285. "Size",
  286. "First Load JS",
  287. ].map((entry)=>_chalk.default.underline(entry)));
  288. filterAndSortList(list).forEach((item, i, arr)=>{
  289. var ref8, ref4, ref5;
  290. const border = i === 0 ? arr.length === 1 ? "\u2500" : "\u250C" : i === arr.length - 1 ? "\u2514" : "\u251C";
  291. const pageInfo = pageInfos.get(item);
  292. const ampFirst = buildManifest.ampFirstPages.includes(item);
  293. const totalDuration = ((pageInfo == null ? void 0 : pageInfo.pageDuration) || 0) + ((pageInfo == null ? void 0 : (ref8 = pageInfo.ssgPageDurations) == null ? void 0 : ref8.reduce((a, b)=>a + (b || 0), 0)) || 0);
  294. const symbol = routerType === "app" || item === "/_app" || item === "/_app.server" ? " " : (pageInfo == null ? void 0 : pageInfo.static) ? "\u25CB" : (pageInfo == null ? void 0 : pageInfo.isSsg) ? "\u25CF" : (pageInfo == null ? void 0 : pageInfo.runtime) === _constants.SERVER_RUNTIME.edge ? "\u2107" : "\u03BB";
  295. usedSymbols.add(symbol);
  296. if (pageInfo == null ? void 0 : pageInfo.initialRevalidateSeconds) usedSymbols.add("ISR");
  297. messages.push([
  298. `${border} ${routerType === "pages" ? `${symbol} ` : ""}${(pageInfo == null ? void 0 : pageInfo.initialRevalidateSeconds) ? `${item} (ISR: ${pageInfo == null ? void 0 : pageInfo.initialRevalidateSeconds} Seconds)` : item}${totalDuration > MIN_DURATION ? ` (${getPrettyDuration(totalDuration)})` : ""}`,
  299. pageInfo ? ampFirst ? _chalk.default.cyan("AMP") : pageInfo.size >= 0 ? (0, _prettyBytes).default(pageInfo.size) : "" : "",
  300. pageInfo ? ampFirst ? _chalk.default.cyan("AMP") : pageInfo.size >= 0 ? getPrettySize(pageInfo.totalSize) : "" : "",
  301. ]);
  302. const uniqueCssFiles = ((ref4 = buildManifest.pages[item]) == null ? void 0 : ref4.filter((file)=>{
  303. var ref;
  304. return file.endsWith(".css") && ((ref = stats.router[routerType]) == null ? void 0 : ref.unique.files.includes(file));
  305. })) || [];
  306. if (uniqueCssFiles.length > 0) {
  307. const contSymbol = i === arr.length - 1 ? " " : "\u251C";
  308. uniqueCssFiles.forEach((file, index, { length })=>{
  309. const innerSymbol = index === length - 1 ? "\u2514" : "\u251C";
  310. const size = stats.sizes.get(file);
  311. messages.push([
  312. `${contSymbol} ${innerSymbol} ${getCleanName(file)}`,
  313. typeof size === "number" ? (0, _prettyBytes).default(size) : "",
  314. "",
  315. ]);
  316. });
  317. }
  318. if (pageInfo == null ? void 0 : (ref5 = pageInfo.ssgPageRoutes) == null ? void 0 : ref5.length) {
  319. const totalRoutes = pageInfo.ssgPageRoutes.length;
  320. const contSymbol = i === arr.length - 1 ? " " : "\u251C";
  321. let routes;
  322. if (pageInfo.ssgPageDurations && pageInfo.ssgPageDurations.some((d)=>d > MIN_DURATION)) {
  323. const previewPages = totalRoutes === 8 ? 8 : Math.min(totalRoutes, 7);
  324. const routesWithDuration = pageInfo.ssgPageRoutes.map((route, idx)=>({
  325. route,
  326. duration: pageInfo.ssgPageDurations[idx] || 0
  327. })).sort(({ duration: a }, { duration: b })=>// Sort by duration
  328. // keep too small durations in original order at the end
  329. a <= MIN_DURATION && b <= MIN_DURATION ? 0 : b - a);
  330. routes = routesWithDuration.slice(0, previewPages);
  331. const remainingRoutes = routesWithDuration.slice(previewPages);
  332. if (remainingRoutes.length) {
  333. const remaining = remainingRoutes.length;
  334. const avgDuration = Math.round(remainingRoutes.reduce((total, { duration })=>total + duration, 0) / remainingRoutes.length);
  335. routes.push({
  336. route: `[+${remaining} more paths]`,
  337. duration: 0,
  338. avgDuration
  339. });
  340. }
  341. } else {
  342. const previewPages = totalRoutes === 4 ? 4 : Math.min(totalRoutes, 3);
  343. routes = pageInfo.ssgPageRoutes.slice(0, previewPages).map((route)=>({
  344. route,
  345. duration: 0
  346. }));
  347. if (totalRoutes > previewPages) {
  348. const remaining = totalRoutes - previewPages;
  349. routes.push({
  350. route: `[+${remaining} more paths]`,
  351. duration: 0
  352. });
  353. }
  354. }
  355. routes.forEach(({ route , duration , avgDuration }, index, { length })=>{
  356. const innerSymbol = index === length - 1 ? "\u2514" : "\u251C";
  357. messages.push([
  358. `${contSymbol} ${innerSymbol} ${route}${duration > MIN_DURATION ? ` (${getPrettyDuration(duration)})` : ""}${avgDuration && avgDuration > MIN_DURATION ? ` (avg ${getPrettyDuration(avgDuration)})` : ""}`,
  359. "",
  360. "",
  361. ]);
  362. });
  363. }
  364. });
  365. const sharedFilesSize = (ref7 = stats.router[routerType]) == null ? void 0 : ref7.common.size.total;
  366. var _files;
  367. const sharedFiles = (_files = (ref3 = stats.router[routerType]) == null ? void 0 : ref3.common.files) != null ? _files : [];
  368. messages.push([
  369. "+ First Load JS shared by all",
  370. typeof sharedFilesSize === "number" ? getPrettySize(sharedFilesSize) : "",
  371. "",
  372. ]);
  373. const sharedCssFiles = [];
  374. [
  375. ...sharedFiles.filter((file)=>{
  376. if (file.endsWith(".css")) {
  377. sharedCssFiles.push(file);
  378. return false;
  379. }
  380. return true;
  381. }).map((e)=>e.replace(buildId, "<buildId>")).sort(),
  382. ...sharedCssFiles.map((e)=>e.replace(buildId, "<buildId>")).sort(),
  383. ].forEach((fileName, index, { length })=>{
  384. const innerSymbol = index === length - 1 ? "\u2514" : "\u251C";
  385. const originalName = fileName.replace("<buildId>", buildId);
  386. const cleanName = getCleanName(fileName);
  387. const size = stats.sizes.get(originalName);
  388. messages.push([
  389. ` ${innerSymbol} ${cleanName}`,
  390. typeof size === "number" ? (0, _prettyBytes).default(size) : "",
  391. "",
  392. ]);
  393. });
  394. };
  395. // If enabled, then print the tree for the app directory.
  396. if (lists.app && stats.router.app) {
  397. await printFileTree({
  398. routerType: "app",
  399. list: lists.app
  400. });
  401. messages.push([
  402. "",
  403. "",
  404. ""
  405. ]);
  406. }
  407. pageInfos.set("/404", {
  408. ...pageInfos.get("/404") || pageInfos.get("/_error"),
  409. static: useStatic404
  410. });
  411. if (!lists.pages.includes("/404")) {
  412. lists.pages = [
  413. ...lists.pages,
  414. "/404"
  415. ];
  416. }
  417. // Print the tree view for the pages directory.
  418. await printFileTree({
  419. routerType: "pages",
  420. list: lists.pages
  421. });
  422. const middlewareInfo = (ref6 = middlewareManifest.middleware) == null ? void 0 : ref6["/"];
  423. if ((middlewareInfo == null ? void 0 : middlewareInfo.files.length) > 0) {
  424. const middlewareSizes = await Promise.all(middlewareInfo.files.map((dep)=>`${distPath}/${dep}`).map(gzipSize ? fsStatGzip : fsStat));
  425. messages.push([
  426. "",
  427. "",
  428. ""
  429. ]);
  430. messages.push([
  431. "\u0192 Middleware",
  432. getPrettySize(sum(middlewareSizes)),
  433. ""
  434. ]);
  435. }
  436. console.log((0, _textTable).default(messages, {
  437. align: [
  438. "l",
  439. "l",
  440. "r"
  441. ],
  442. stringLength: (str)=>(0, _stripAnsi).default(str).length
  443. }));
  444. console.log();
  445. console.log((0, _textTable).default([
  446. usedSymbols.has("\u2107") && [
  447. "\u2107",
  448. "(Streaming)",
  449. `server-side renders with streaming (uses React 18 SSR streaming or Server Components)`,
  450. ],
  451. usedSymbols.has("\u03BB") && [
  452. "\u03BB",
  453. serverless ? "(Lambda)" : "(Server)",
  454. `server-side renders at runtime (uses ${_chalk.default.cyan("getInitialProps")} or ${_chalk.default.cyan("getServerSideProps")})`,
  455. ],
  456. usedSymbols.has("\u25CB") && [
  457. "\u25CB",
  458. "(Static)",
  459. "automatically rendered as static HTML (uses no initial props)",
  460. ],
  461. usedSymbols.has("\u25CF") && [
  462. "\u25CF",
  463. "(SSG)",
  464. `automatically generated as static HTML + JSON (uses ${_chalk.default.cyan("getStaticProps")})`,
  465. ],
  466. usedSymbols.has("ISR") && [
  467. "",
  468. "(ISR)",
  469. `incremental static regeneration (uses revalidate in ${_chalk.default.cyan("getStaticProps")})`,
  470. ],
  471. ].filter((x)=>x), {
  472. align: [
  473. "l",
  474. "l",
  475. "l"
  476. ],
  477. stringLength: (str)=>(0, _stripAnsi).default(str).length
  478. }));
  479. console.log();
  480. }
  481. function printCustomRoutes({ redirects , rewrites , headers }) {
  482. const printRoutes = (routes, type)=>{
  483. const isRedirects = type === "Redirects";
  484. const isHeaders = type === "Headers";
  485. console.log(_chalk.default.underline(type));
  486. console.log();
  487. /*
  488. ┌ source
  489. ├ permanent/statusCode
  490. └ destination
  491. */ const routesStr = routes.map((route)=>{
  492. let routeStr = `┌ source: ${route.source}\n`;
  493. if (!isHeaders) {
  494. const r = route;
  495. routeStr += `${isRedirects ? "\u251C" : "\u2514"} destination: ${r.destination}\n`;
  496. }
  497. if (isRedirects) {
  498. const r = route;
  499. routeStr += `└ ${r.statusCode ? `status: ${r.statusCode}` : `permanent: ${r.permanent}`}\n`;
  500. }
  501. if (isHeaders) {
  502. const r = route;
  503. routeStr += `└ headers:\n`;
  504. for(let i = 0; i < r.headers.length; i++){
  505. const header = r.headers[i];
  506. const last = i === headers.length - 1;
  507. routeStr += ` ${last ? "\u2514" : "\u251C"} ${header.key}: ${header.value}\n`;
  508. }
  509. }
  510. return routeStr;
  511. }).join("\n");
  512. console.log(routesStr, "\n");
  513. };
  514. if (redirects.length) {
  515. printRoutes(redirects, "Redirects");
  516. }
  517. if (headers.length) {
  518. printRoutes(headers, "Headers");
  519. }
  520. const combinedRewrites = [
  521. ...rewrites.beforeFiles,
  522. ...rewrites.afterFiles,
  523. ...rewrites.fallback,
  524. ];
  525. if (combinedRewrites.length) {
  526. printRoutes(combinedRewrites, "Rewrites");
  527. }
  528. }
  529. async function getJsPageSizeInKb(routerType, page, distPath, buildManifest, appBuildManifest, gzipSize = true, cachedStats) {
  530. const pageManifest = routerType === "pages" ? buildManifest : appBuildManifest;
  531. if (!pageManifest) {
  532. throw new Error('expected appBuildManifest with an "app" pageType');
  533. }
  534. // If stats was not provided, then compute it again.
  535. const stats = cachedStats != null ? cachedStats : await computeFromManifest({
  536. build: buildManifest,
  537. app: appBuildManifest
  538. }, distPath, gzipSize);
  539. const pageData = stats.router[routerType];
  540. if (!pageData) {
  541. // This error shouldn't happen and represents an error in Next.js.
  542. throw new Error('expected "app" manifest data with an "app" pageType');
  543. }
  544. const pagePath = routerType === "pages" ? (0, _denormalizePagePath).denormalizePagePath(page) : denormalizeAppPagePath(page);
  545. const fnFilterJs = (entry)=>entry.endsWith(".js");
  546. var _pagePath;
  547. const pageFiles = ((_pagePath = pageManifest.pages[pagePath]) != null ? _pagePath : []).filter(fnFilterJs);
  548. var ref;
  549. const appFiles = ((ref = pageManifest.pages["/_app"]) != null ? ref : []).filter(fnFilterJs);
  550. const fnMapRealPath = (dep)=>`${distPath}/${dep}`;
  551. const allFilesReal = unique(pageFiles, appFiles).map(fnMapRealPath);
  552. const selfFilesReal = difference(// Find the files shared by the pages files and the unique files...
  553. intersect(pageFiles, pageData.unique.files), // but without the common files.
  554. pageData.common.files).map(fnMapRealPath);
  555. const getSize = gzipSize ? fsStatGzip : fsStat;
  556. // Try to get the file size from the page data if available, otherwise do a
  557. // raw compute.
  558. const getCachedSize = async (file)=>{
  559. const key = file.slice(distPath.length + 1);
  560. const size = stats.sizes.get(key);
  561. // If the size wasn't in the stats bundle, then get it from the file
  562. // directly.
  563. if (typeof size !== "number") {
  564. return getSize(file);
  565. }
  566. return size;
  567. };
  568. try {
  569. // Doesn't use `Promise.all`, as we'd double compute duplicate files. This
  570. // function is memoized, so the second one will instantly resolve.
  571. const allFilesSize = sum(await Promise.all(allFilesReal.map(getCachedSize)));
  572. const selfFilesSize = sum(await Promise.all(selfFilesReal.map(getCachedSize)));
  573. return [
  574. selfFilesSize,
  575. allFilesSize
  576. ];
  577. } catch {}
  578. return [
  579. -1,
  580. -1
  581. ];
  582. }
  583. async function buildStaticPaths({ page , getStaticPaths , staticPathsResult , configFileName , locales , defaultLocale }) {
  584. const prerenderPaths = new Set();
  585. const encodedPrerenderPaths = new Set();
  586. const _routeRegex1 = (0, _routeRegex).getRouteRegex(page);
  587. const _routeMatcher1 = (0, _routeMatcher).getRouteMatcher(_routeRegex1);
  588. // Get the default list of allowed params.
  589. const _validParamKeys = Object.keys(_routeMatcher1(page));
  590. if (!staticPathsResult) {
  591. if (getStaticPaths) {
  592. staticPathsResult = await getStaticPaths({
  593. locales,
  594. defaultLocale
  595. });
  596. } else {
  597. throw new Error(`invariant: attempted to buildStaticPaths without "staticPathsResult" or "getStaticPaths" ${page}`);
  598. }
  599. }
  600. const expectedReturnVal = `Expected: { paths: [], fallback: boolean }\n` + `See here for more info: https://nextjs.org/docs/messages/invalid-getstaticpaths-value`;
  601. if (!staticPathsResult || typeof staticPathsResult !== "object" || Array.isArray(staticPathsResult)) {
  602. throw new Error(`Invalid value returned from getStaticPaths in ${page}. Received ${typeof staticPathsResult} ${expectedReturnVal}`);
  603. }
  604. const invalidStaticPathKeys = Object.keys(staticPathsResult).filter((key)=>!(key === "paths" || key === "fallback"));
  605. if (invalidStaticPathKeys.length > 0) {
  606. throw new Error(`Extra keys returned from getStaticPaths in ${page} (${invalidStaticPathKeys.join(", ")}) ${expectedReturnVal}`);
  607. }
  608. if (!(typeof staticPathsResult.fallback === "boolean" || staticPathsResult.fallback === "blocking")) {
  609. throw new Error(`The \`fallback\` key must be returned from getStaticPaths in ${page}.\n` + expectedReturnVal);
  610. }
  611. const toPrerender = staticPathsResult.paths;
  612. if (!Array.isArray(toPrerender)) {
  613. 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 }`);
  614. }
  615. toPrerender.forEach((entry)=>{
  616. // For a string-provided path, we must make sure it matches the dynamic
  617. // route.
  618. if (typeof entry === "string") {
  619. entry = (0, _removeTrailingSlash).removeTrailingSlash(entry);
  620. const localePathResult = (0, _normalizeLocalePath).normalizeLocalePath(entry, locales);
  621. let cleanedEntry = entry;
  622. if (localePathResult.detectedLocale) {
  623. cleanedEntry = entry.slice(localePathResult.detectedLocale.length + 1);
  624. } else if (defaultLocale) {
  625. entry = `/${defaultLocale}${entry}`;
  626. }
  627. const result = _routeMatcher1(cleanedEntry);
  628. if (!result) {
  629. throw new Error(`The provided path \`${cleanedEntry}\` does not match the page: \`${page}\`.`);
  630. }
  631. // If leveraging the string paths variant the entry should already be
  632. // encoded so we decode the segments ensuring we only escape path
  633. // delimiters
  634. prerenderPaths.add(entry.split("/").map((segment)=>(0, _escapePathDelimiters).default(decodeURIComponent(segment), true)).join("/"));
  635. encodedPrerenderPaths.add(entry);
  636. } else {
  637. const invalidKeys = Object.keys(entry).filter((key)=>key !== "params" && key !== "locale");
  638. if (invalidKeys.length) {
  639. 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}: ...`).join(", ")} } }` + `\n\nKeys that need to be moved: ${invalidKeys.join(", ")}.\n`);
  640. }
  641. const { params ={} } = entry;
  642. let builtPage = page;
  643. let encodedBuiltPage = page;
  644. _validParamKeys.forEach((validParamKey)=>{
  645. const { repeat , optional } = _routeRegex1.groups[validParamKey];
  646. let paramValue = params[validParamKey];
  647. if (optional && params.hasOwnProperty(validParamKey) && (paramValue === null || paramValue === undefined || paramValue === false)) {
  648. paramValue = [];
  649. }
  650. if (repeat && !Array.isArray(paramValue) || !repeat && typeof paramValue !== "string") {
  651. throw new Error(`A required parameter (${validParamKey}) was not provided as ${repeat ? "an array" : "a string"} in getStaticPaths for ${page}`);
  652. }
  653. let replaced = `[${repeat ? "..." : ""}${validParamKey}]`;
  654. if (optional) {
  655. replaced = `[${replaced}]`;
  656. }
  657. builtPage = builtPage.replace(replaced, repeat ? paramValue.map((segment)=>(0, _escapePathDelimiters).default(segment, true)).join("/") : (0, _escapePathDelimiters).default(paramValue, true)).replace(/(?!^)\/$/, "");
  658. encodedBuiltPage = encodedBuiltPage.replace(replaced, repeat ? paramValue.map(encodeURIComponent).join("/") : encodeURIComponent(paramValue)).replace(/(?!^)\/$/, "");
  659. });
  660. if (entry.locale && !(locales == null ? void 0 : locales.includes(entry.locale))) {
  661. throw new Error(`Invalid locale returned from getStaticPaths for ${page}, the locale ${entry.locale} is not specified in ${configFileName}`);
  662. }
  663. const curLocale = entry.locale || defaultLocale || "";
  664. prerenderPaths.add(`${curLocale ? `/${curLocale}` : ""}${curLocale && builtPage === "/" ? "" : builtPage}`);
  665. encodedPrerenderPaths.add(`${curLocale ? `/${curLocale}` : ""}${curLocale && encodedBuiltPage === "/" ? "" : encodedBuiltPage}`);
  666. }
  667. });
  668. return {
  669. paths: [
  670. ...prerenderPaths
  671. ],
  672. fallback: staticPathsResult.fallback,
  673. encodedPaths: [
  674. ...encodedPrerenderPaths
  675. ]
  676. };
  677. }
  678. const collectGenerateParams = (segment, parentSegments = [], generateParams = [])=>{
  679. var ref, ref9, ref10, ref11;
  680. if (!Array.isArray(segment)) return generateParams;
  681. const isLayout = !!((ref = segment[2]) == null ? void 0 : ref.layout);
  682. const mod = isLayout ? (ref9 = segment[2]) == null ? void 0 : ref9.layout == null ? void 0 : ref9.layout() : (ref10 = segment[2]) == null ? void 0 : ref10.page == null ? void 0 : ref10.page();
  683. const result = {
  684. isLayout,
  685. segmentPath: `/${parentSegments.join("/")}${segment[0] && parentSegments.length > 0 ? "/" : ""}${segment[0]}`,
  686. config: mod == null ? void 0 : mod.config,
  687. getStaticPaths: mod == null ? void 0 : mod.getStaticPaths,
  688. generateStaticParams: mod == null ? void 0 : mod.generateStaticParams
  689. };
  690. if (segment[0]) {
  691. parentSegments.push(segment[0]);
  692. }
  693. if (result.config || result.generateStaticParams || result.getStaticPaths) {
  694. generateParams.push(result);
  695. }
  696. return collectGenerateParams((ref11 = segment[1]) == null ? void 0 : ref11.children, parentSegments, generateParams);
  697. };
  698. exports.collectGenerateParams = collectGenerateParams;
  699. async function buildAppStaticPaths({ page , configFileName , generateParams }) {
  700. const pageEntry = generateParams[generateParams.length - 1];
  701. // if the page has legacy getStaticPaths we call it like normal
  702. if (typeof (pageEntry == null ? void 0 : pageEntry.getStaticPaths) === "function") {
  703. return buildStaticPaths({
  704. page,
  705. configFileName,
  706. getStaticPaths: pageEntry.getStaticPaths
  707. });
  708. } else {
  709. let hadGenerateParams = false;
  710. const buildParams = async (paramsItems = [
  711. {}
  712. ], idx = 0)=>{
  713. const curGenerate = generateParams[idx];
  714. if (idx === generateParams.length) {
  715. return paramsItems;
  716. }
  717. if (typeof curGenerate.generateStaticParams !== "function" && idx < generateParams.length) {
  718. return buildParams(paramsItems, idx + 1);
  719. }
  720. hadGenerateParams = true;
  721. const newParams = [];
  722. for (const params of paramsItems){
  723. const result = await curGenerate.generateStaticParams({
  724. params
  725. });
  726. // TODO: validate the result is valid here or wait for
  727. // buildStaticPaths to validate?
  728. for (const item of result.params){
  729. newParams.push({
  730. ...params,
  731. ...item
  732. });
  733. }
  734. }
  735. if (idx < generateParams.length) {
  736. return buildParams(newParams, idx + 1);
  737. }
  738. return newParams;
  739. };
  740. const builtParams = await buildParams();
  741. const fallback = !generateParams.some(// TODO: check complementary configs that can impact
  742. // dynamicParams behavior
  743. (generate)=>{
  744. var ref;
  745. return ((ref = generate.config) == null ? void 0 : ref.dynamicParams) === false;
  746. });
  747. if (!hadGenerateParams) {
  748. return {
  749. paths: undefined,
  750. fallback: undefined,
  751. encodedPaths: undefined
  752. };
  753. }
  754. return buildStaticPaths({
  755. staticPathsResult: {
  756. fallback,
  757. paths: builtParams.map((params)=>({
  758. params
  759. }))
  760. },
  761. page,
  762. configFileName
  763. });
  764. }
  765. }
  766. async function isPageStatic({ page , distDir , serverless , configFileName , runtimeEnvConfig , httpAgentOptions , locales , defaultLocale , parentId , pageRuntime , edgeInfo , pageType , hasServerComponents , originalAppPath }) {
  767. const isPageStaticSpan = (0, _trace).trace("is-page-static-utils", parentId);
  768. return isPageStaticSpan.traceAsyncFn(async ()=>{
  769. require("../shared/lib/runtime-config").setConfig(runtimeEnvConfig);
  770. (0, _config).setHttpAgentOptions(httpAgentOptions);
  771. let componentsResult;
  772. let prerenderRoutes;
  773. let encodedPrerenderRoutes;
  774. let prerenderFallback;
  775. let appConfig = {};
  776. if (pageRuntime === _constants.SERVER_RUNTIME.edge) {
  777. const runtime = await (0, _sandbox).getRuntimeContext({
  778. paths: edgeInfo.files.map((file)=>_path.default.join(distDir, file)),
  779. env: edgeInfo.env,
  780. edgeFunctionEntry: edgeInfo,
  781. name: edgeInfo.name,
  782. useCache: true,
  783. distDir
  784. });
  785. const mod = runtime.context._ENTRIES[`middleware_${edgeInfo.name}`].ComponentMod;
  786. componentsResult = {
  787. Component: mod.default,
  788. ComponentMod: mod,
  789. pageConfig: mod.config || {},
  790. // @ts-expect-error this is not needed during require
  791. buildManifest: {},
  792. reactLoadableManifest: {},
  793. getServerSideProps: mod.getServerSideProps,
  794. getStaticPaths: mod.getStaticPaths,
  795. getStaticProps: mod.getStaticProps
  796. };
  797. } else {
  798. componentsResult = await (0, _loadComponents).loadComponents({
  799. distDir,
  800. pathname: originalAppPath || page,
  801. serverless,
  802. hasServerComponents: !!hasServerComponents,
  803. isAppPath: pageType === "app"
  804. });
  805. }
  806. const Comp = componentsResult.Component || {};
  807. let staticPathsResult;
  808. if (pageType === "app") {
  809. const tree = componentsResult.ComponentMod.tree;
  810. const generateParams = collectGenerateParams(tree);
  811. appConfig = generateParams.reduce((builtConfig, curGenParams)=>{
  812. const { dynamic , fetchCache , preferredRegion , revalidate: curRevalidate , } = (curGenParams == null ? void 0 : curGenParams.config) || {};
  813. // TODO: should conflicting configs here throw an error
  814. // e.g. if layout defines one region but page defines another
  815. if (typeof builtConfig.preferredRegion === "undefined") {
  816. builtConfig.preferredRegion = preferredRegion;
  817. }
  818. if (typeof builtConfig.dynamic === "undefined") {
  819. builtConfig.dynamic = dynamic;
  820. }
  821. if (typeof builtConfig.fetchCache === "undefined") {
  822. builtConfig.fetchCache = fetchCache;
  823. }
  824. // any revalidate number overrides false
  825. // shorter revalidate overrides longer (initially)
  826. if (typeof builtConfig.revalidate === "undefined") {
  827. builtConfig.revalidate = curRevalidate;
  828. }
  829. if (typeof curRevalidate === "number" && (typeof builtConfig.revalidate !== "number" || curRevalidate < builtConfig.revalidate)) {
  830. builtConfig.revalidate = curRevalidate;
  831. }
  832. return builtConfig;
  833. }, {});
  834. if ((0, _isDynamic).isDynamicRoute(page)) {
  835. ({ paths: prerenderRoutes , fallback: prerenderFallback , encodedPaths: encodedPrerenderRoutes , } = await buildAppStaticPaths({
  836. page,
  837. configFileName,
  838. generateParams
  839. }));
  840. }
  841. } else {
  842. if (!Comp || !(0, _reactIs).isValidElementType(Comp) || typeof Comp === "string") {
  843. throw new Error("INVALID_DEFAULT_EXPORT");
  844. }
  845. }
  846. const hasGetInitialProps = !!Comp.getInitialProps;
  847. const hasStaticProps = !!componentsResult.getStaticProps;
  848. const hasStaticPaths = !!componentsResult.getStaticPaths;
  849. const hasServerProps = !!componentsResult.getServerSideProps;
  850. const hasLegacyServerProps = !!await componentsResult.ComponentMod.unstable_getServerProps;
  851. const hasLegacyStaticProps = !!await componentsResult.ComponentMod.unstable_getStaticProps;
  852. const hasLegacyStaticPaths = !!await componentsResult.ComponentMod.unstable_getStaticPaths;
  853. const hasLegacyStaticParams = !!await componentsResult.ComponentMod.unstable_getStaticParams;
  854. if (hasLegacyStaticParams) {
  855. throw new Error(`unstable_getStaticParams was replaced with getStaticPaths. Please update your code.`);
  856. }
  857. if (hasLegacyStaticPaths) {
  858. throw new Error(`unstable_getStaticPaths was replaced with getStaticPaths. Please update your code.`);
  859. }
  860. if (hasLegacyStaticProps) {
  861. throw new Error(`unstable_getStaticProps was replaced with getStaticProps. Please update your code.`);
  862. }
  863. if (hasLegacyServerProps) {
  864. throw new Error(`unstable_getServerProps was replaced with getServerSideProps. Please update your code.`);
  865. }
  866. // A page cannot be prerendered _and_ define a data requirement. That's
  867. // contradictory!
  868. if (hasGetInitialProps && hasStaticProps) {
  869. throw new Error(_constants.SSG_GET_INITIAL_PROPS_CONFLICT);
  870. }
  871. if (hasGetInitialProps && hasServerProps) {
  872. throw new Error(_constants.SERVER_PROPS_GET_INIT_PROPS_CONFLICT);
  873. }
  874. if (hasStaticProps && hasServerProps) {
  875. throw new Error(_constants.SERVER_PROPS_SSG_CONFLICT);
  876. }
  877. const pageIsDynamic = (0, _isDynamic).isDynamicRoute(page);
  878. // A page cannot have static parameters if it is not a dynamic page.
  879. if (hasStaticProps && hasStaticPaths && !pageIsDynamic) {
  880. throw new Error(`getStaticPaths can only be used with dynamic pages, not '${page}'.` + `\nLearn more: https://nextjs.org/docs/routing/dynamic-routes`);
  881. }
  882. if (hasStaticProps && pageIsDynamic && !hasStaticPaths) {
  883. 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`);
  884. }
  885. if (hasStaticProps && hasStaticPaths || staticPathsResult) {
  886. ({ paths: prerenderRoutes , fallback: prerenderFallback , encodedPaths: encodedPrerenderRoutes , } = await buildStaticPaths({
  887. page,
  888. locales,
  889. defaultLocale,
  890. configFileName,
  891. staticPathsResult,
  892. getStaticPaths: componentsResult.getStaticPaths
  893. }));
  894. }
  895. const isNextImageImported = global.__NEXT_IMAGE_IMPORTED;
  896. const config = componentsResult.pageConfig;
  897. return {
  898. isStatic: !hasStaticProps && !hasGetInitialProps && !hasServerProps,
  899. isHybridAmp: config.amp === "hybrid",
  900. isAmpOnly: config.amp === true,
  901. prerenderRoutes,
  902. prerenderFallback,
  903. encodedPrerenderRoutes,
  904. hasStaticProps,
  905. hasServerProps,
  906. isNextImageImported,
  907. traceIncludes: config.unstable_includeFiles || [],
  908. traceExcludes: config.unstable_excludeFiles || [],
  909. appConfig
  910. };
  911. }).catch((err)=>{
  912. if (err.message === "INVALID_DEFAULT_EXPORT") {
  913. throw err;
  914. }
  915. console.error(err);
  916. throw new Error(`Failed to collect page data for ${page}`);
  917. });
  918. }
  919. async function hasCustomGetInitialProps(page, distDir, isLikeServerless, runtimeEnvConfig, checkingApp) {
  920. require("../shared/lib/runtime-config").setConfig(runtimeEnvConfig);
  921. const components = await (0, _loadComponents).loadComponents({
  922. distDir,
  923. pathname: page,
  924. serverless: isLikeServerless,
  925. hasServerComponents: false,
  926. isAppPath: false
  927. });
  928. let mod = components.ComponentMod;
  929. if (checkingApp) {
  930. mod = await mod._app || mod.default || mod;
  931. } else {
  932. mod = mod.default || mod;
  933. }
  934. mod = await mod;
  935. return mod.getInitialProps !== mod.origGetInitialProps;
  936. }
  937. async function getNamedExports(page, distDir, isLikeServerless, runtimeEnvConfig) {
  938. require("../shared/lib/runtime-config").setConfig(runtimeEnvConfig);
  939. const components = await (0, _loadComponents).loadComponents({
  940. distDir,
  941. pathname: page,
  942. serverless: isLikeServerless,
  943. hasServerComponents: false,
  944. isAppPath: false
  945. });
  946. let mod = components.ComponentMod;
  947. return Object.keys(mod);
  948. }
  949. function detectConflictingPaths(combinedPages, ssgPages, additionalSsgPaths) {
  950. const conflictingPaths = new Map();
  951. const dynamicSsgPages = [
  952. ...ssgPages
  953. ].filter((page)=>(0, _isDynamic).isDynamicRoute(page));
  954. additionalSsgPaths.forEach((paths, pathsPage)=>{
  955. paths.forEach((curPath)=>{
  956. const lowerPath = curPath.toLowerCase();
  957. let conflictingPage = combinedPages.find((page)=>page.toLowerCase() === lowerPath);
  958. if (conflictingPage) {
  959. conflictingPaths.set(lowerPath, [
  960. {
  961. path: curPath,
  962. page: pathsPage
  963. },
  964. {
  965. path: conflictingPage,
  966. page: conflictingPage
  967. },
  968. ]);
  969. } else {
  970. let conflictingPath;
  971. conflictingPage = dynamicSsgPages.find((page)=>{
  972. var ref;
  973. if (page === pathsPage) return false;
  974. conflictingPath = (ref = additionalSsgPaths.get(page)) == null ? void 0 : ref.find((compPath)=>compPath.toLowerCase() === lowerPath);
  975. return conflictingPath;
  976. });
  977. if (conflictingPage && conflictingPath) {
  978. conflictingPaths.set(lowerPath, [
  979. {
  980. path: curPath,
  981. page: pathsPage
  982. },
  983. {
  984. path: conflictingPath,
  985. page: conflictingPage
  986. },
  987. ]);
  988. }
  989. }
  990. });
  991. });
  992. if (conflictingPaths.size > 0) {
  993. let conflictingPathsOutput = "";
  994. conflictingPaths.forEach((pathItems)=>{
  995. pathItems.forEach((pathItem, idx)=>{
  996. const isDynamic = pathItem.page !== pathItem.path;
  997. if (idx > 0) {
  998. conflictingPathsOutput += "conflicts with ";
  999. }
  1000. conflictingPathsOutput += `path: "${pathItem.path}"${isDynamic ? ` from page: "${pathItem.page}" ` : " "}`;
  1001. });
  1002. conflictingPathsOutput += "\n";
  1003. });
  1004. 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);
  1005. process.exit(1);
  1006. }
  1007. }
  1008. async function copyTracedFiles(dir, distDir, pageKeys, tracingRoot, serverConfig, middlewareManifest) {
  1009. const outputPath = _path.default.join(distDir, "standalone");
  1010. const copiedFiles = new Set();
  1011. await (0, _recursiveDelete).recursiveDelete(outputPath);
  1012. async function handleTraceFiles(traceFilePath) {
  1013. const traceData = JSON.parse(await _fs.promises.readFile(traceFilePath, "utf8"));
  1014. const copySema = new _asyncSema.Sema(10, {
  1015. capacity: traceData.files.length
  1016. });
  1017. const traceFileDir = _path.default.dirname(traceFilePath);
  1018. await Promise.all(traceData.files.map(async (relativeFile)=>{
  1019. await copySema.acquire();
  1020. const tracedFilePath = _path.default.join(traceFileDir, relativeFile);
  1021. const fileOutputPath = _path.default.join(outputPath, _path.default.relative(tracingRoot, tracedFilePath));
  1022. if (!copiedFiles.has(fileOutputPath)) {
  1023. copiedFiles.add(fileOutputPath);
  1024. await _fs.promises.mkdir(_path.default.dirname(fileOutputPath), {
  1025. recursive: true
  1026. });
  1027. const symlink = await _fs.promises.readlink(tracedFilePath).catch(()=>null);
  1028. if (symlink) {
  1029. try {
  1030. await _fs.promises.symlink(symlink, fileOutputPath);
  1031. } catch (e) {
  1032. if (e.code !== "EEXIST") {
  1033. throw e;
  1034. }
  1035. }
  1036. } else {
  1037. await _fs.promises.copyFile(tracedFilePath, fileOutputPath);
  1038. }
  1039. }
  1040. await copySema.release();
  1041. }));
  1042. }
  1043. for (const middleware of Object.values(middlewareManifest.middleware) || []){
  1044. if (isMiddlewareFilename(middleware.name)) {
  1045. for (const file of middleware.files){
  1046. const originalPath = _path.default.join(distDir, file);
  1047. const fileOutputPath = _path.default.join(outputPath, _path.default.relative(tracingRoot, distDir), file);
  1048. await _fs.promises.mkdir(_path.default.dirname(fileOutputPath), {
  1049. recursive: true
  1050. });
  1051. await _fs.promises.copyFile(originalPath, fileOutputPath);
  1052. }
  1053. }
  1054. }
  1055. for (const page of pageKeys){
  1056. const pageFile = _path.default.join(distDir, "server", "pages", `${(0, _normalizePagePath).normalizePagePath(page)}.js`);
  1057. const pageTraceFile = `${pageFile}.nft.json`;
  1058. await handleTraceFiles(pageTraceFile);
  1059. }
  1060. await handleTraceFiles(_path.default.join(distDir, "next-server.js.nft.json"));
  1061. const serverOutputPath = _path.default.join(outputPath, _path.default.relative(tracingRoot, dir), "server.js");
  1062. await _fs.promises.writeFile(serverOutputPath, `
  1063. process.env.NODE_ENV = 'production'
  1064. process.chdir(__dirname)
  1065. const NextServer = require('next/dist/server/next-server').default
  1066. const http = require('http')
  1067. const path = require('path')
  1068. // Make sure commands gracefully respect termination signals (e.g. from Docker)
  1069. // Allow the graceful termination to be manually configurable
  1070. if (!process.env.NEXT_MANUAL_SIG_HANDLE) {
  1071. process.on('SIGTERM', () => process.exit(0))
  1072. process.on('SIGINT', () => process.exit(0))
  1073. }
  1074. let handler
  1075. const server = http.createServer(async (req, res) => {
  1076. try {
  1077. await handler(req, res)
  1078. } catch (err) {
  1079. console.error(err);
  1080. res.statusCode = 500
  1081. res.end('internal server error')
  1082. }
  1083. })
  1084. const currentPort = parseInt(process.env.PORT, 10) || 3000
  1085. server.listen(currentPort, (err) => {
  1086. if (err) {
  1087. console.error("Failed to start server", err)
  1088. process.exit(1)
  1089. }
  1090. const nextServer = new NextServer({
  1091. hostname: 'localhost',
  1092. port: currentPort,
  1093. dir: path.join(__dirname),
  1094. dev: false,
  1095. customServer: false,
  1096. conf: ${JSON.stringify({
  1097. ...serverConfig,
  1098. distDir: `./${_path.default.relative(dir, distDir)}`
  1099. })},
  1100. })
  1101. handler = nextServer.getRequestHandler()
  1102. console.log("Listening on port", currentPort)
  1103. })
  1104. `);
  1105. }
  1106. function isReservedPage(page) {
  1107. return RESERVED_PAGE.test(page);
  1108. }
  1109. function isCustomErrorPage(page) {
  1110. return page === "/404" || page === "/500";
  1111. }
  1112. function isMiddlewareFile(file) {
  1113. return file === `/${_constants.MIDDLEWARE_FILENAME}` || file === `/src/${_constants.MIDDLEWARE_FILENAME}`;
  1114. }
  1115. function getPossibleMiddlewareFilenames(folder, extensions) {
  1116. return extensions.map((extension)=>_path.default.join(folder, `${_constants.MIDDLEWARE_FILENAME}.${extension}`));
  1117. }
  1118. class MiddlewareInServerlessTargetError extends Error {
  1119. constructor(){
  1120. super("Next.js Middleware is not supported in the deprecated serverless target.\n" + 'Please remove `target: "serverless" from your next.config.js to use Middleware.');
  1121. this.name = "MiddlewareInServerlessTargetError";
  1122. }
  1123. }
  1124. exports.MiddlewareInServerlessTargetError = MiddlewareInServerlessTargetError;
  1125. class NestedMiddlewareError extends Error {
  1126. constructor(nestedFileNames, mainDir, pagesDir){
  1127. super(`Nested Middleware is not allowed, found:\n` + `${nestedFileNames.map((file)=>`pages${file}`).join("\n")}\n` + `Please move your code to a single file at ${_path.default.join(_path.default.posix.sep, _path.default.relative(mainDir, _path.default.resolve(pagesDir, "..")), "middleware")} instead.\n` + `Read More - https://nextjs.org/docs/messages/nested-middleware`);
  1128. }
  1129. }
  1130. exports.NestedMiddlewareError = NestedMiddlewareError;
  1131. //# sourceMappingURL=utils.js.map