You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			304 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
			
		
		
	
	
			304 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
| "use strict";
 | |
| Object.defineProperty(exports, "__esModule", {
 | |
|     value: true
 | |
| });
 | |
| 0 && (module.exports = {
 | |
|     normalizeVercelUrl: null,
 | |
|     interpolateDynamicPath: null,
 | |
|     normalizeDynamicRouteParams: null,
 | |
|     getUtils: null
 | |
| });
 | |
| function _export(target, all) {
 | |
|     for(var name in all)Object.defineProperty(target, name, {
 | |
|         enumerable: true,
 | |
|         get: all[name]
 | |
|     });
 | |
| }
 | |
| _export(exports, {
 | |
|     normalizeVercelUrl: function() {
 | |
|         return normalizeVercelUrl;
 | |
|     },
 | |
|     interpolateDynamicPath: function() {
 | |
|         return interpolateDynamicPath;
 | |
|     },
 | |
|     normalizeDynamicRouteParams: function() {
 | |
|         return normalizeDynamicRouteParams;
 | |
|     },
 | |
|     getUtils: function() {
 | |
|         return getUtils;
 | |
|     }
 | |
| });
 | |
| const _url = require("url");
 | |
| const _normalizelocalepath = require("../shared/lib/i18n/normalize-locale-path");
 | |
| const _pathmatch = require("../shared/lib/router/utils/path-match");
 | |
| const _routeregex = require("../shared/lib/router/utils/route-regex");
 | |
| const _routematcher = require("../shared/lib/router/utils/route-matcher");
 | |
| const _preparedestination = require("../shared/lib/router/utils/prepare-destination");
 | |
| const _removetrailingslash = require("../shared/lib/router/utils/remove-trailing-slash");
 | |
| const _apppaths = require("../shared/lib/router/utils/app-paths");
 | |
| const _constants = require("../lib/constants");
 | |
| function normalizeVercelUrl(req, trustQuery, paramKeys, pageIsDynamic, defaultRouteRegex) {
 | |
|     // make sure to normalize req.url on Vercel to strip dynamic params
 | |
|     // from the query which are added during routing
 | |
|     if (pageIsDynamic && trustQuery && defaultRouteRegex) {
 | |
|         const _parsedUrl = (0, _url.parse)(req.url, true);
 | |
|         delete _parsedUrl.search;
 | |
|         for (const key of Object.keys(_parsedUrl.query)){
 | |
|             if (key !== _constants.NEXT_QUERY_PARAM_PREFIX && key.startsWith(_constants.NEXT_QUERY_PARAM_PREFIX) || (paramKeys || Object.keys(defaultRouteRegex.groups)).includes(key)) {
 | |
|                 delete _parsedUrl.query[key];
 | |
|             }
 | |
|         }
 | |
|         req.url = (0, _url.format)(_parsedUrl);
 | |
|     }
 | |
| }
 | |
| function interpolateDynamicPath(pathname, params, defaultRouteRegex) {
 | |
|     if (!defaultRouteRegex) return pathname;
 | |
|     for (const param of Object.keys(defaultRouteRegex.groups)){
 | |
|         const { optional, repeat } = defaultRouteRegex.groups[param];
 | |
|         let builtParam = `[${repeat ? "..." : ""}${param}]`;
 | |
|         if (optional) {
 | |
|             builtParam = `[${builtParam}]`;
 | |
|         }
 | |
|         const paramIdx = pathname.indexOf(builtParam);
 | |
|         if (paramIdx > -1) {
 | |
|             let paramValue;
 | |
|             const value = params[param];
 | |
|             if (Array.isArray(value)) {
 | |
|                 paramValue = value.map((v)=>v && encodeURIComponent(v)).join("/");
 | |
|             } else if (value) {
 | |
|                 paramValue = encodeURIComponent(value);
 | |
|             } else {
 | |
|                 paramValue = "";
 | |
|             }
 | |
|             pathname = pathname.slice(0, paramIdx) + paramValue + pathname.slice(paramIdx + builtParam.length);
 | |
|         }
 | |
|     }
 | |
|     return pathname;
 | |
| }
 | |
| function normalizeDynamicRouteParams(params, ignoreOptional, defaultRouteRegex, defaultRouteMatches) {
 | |
|     let hasValidParams = true;
 | |
|     if (!defaultRouteRegex) return {
 | |
|         params,
 | |
|         hasValidParams: false
 | |
|     };
 | |
|     params = Object.keys(defaultRouteRegex.groups).reduce((prev, key)=>{
 | |
|         let value = params[key];
 | |
|         if (typeof value === "string") {
 | |
|             value = (0, _apppaths.normalizeRscURL)(value);
 | |
|         }
 | |
|         if (Array.isArray(value)) {
 | |
|             value = value.map((val)=>{
 | |
|                 if (typeof val === "string") {
 | |
|                     val = (0, _apppaths.normalizeRscURL)(val);
 | |
|                 }
 | |
|                 return val;
 | |
|             });
 | |
|         }
 | |
|         // if the value matches the default value we can't rely
 | |
|         // on the parsed params, this is used to signal if we need
 | |
|         // to parse x-now-route-matches or not
 | |
|         const defaultValue = defaultRouteMatches[key];
 | |
|         const isOptional = defaultRouteRegex.groups[key].optional;
 | |
|         const isDefaultValue = Array.isArray(defaultValue) ? defaultValue.some((defaultVal)=>{
 | |
|             return Array.isArray(value) ? value.some((val)=>val.includes(defaultVal)) : value == null ? void 0 : value.includes(defaultVal);
 | |
|         }) : value == null ? void 0 : value.includes(defaultValue);
 | |
|         if (isDefaultValue || typeof value === "undefined" && !(isOptional && ignoreOptional)) {
 | |
|             hasValidParams = false;
 | |
|         }
 | |
|         // non-provided optional values should be undefined so normalize
 | |
|         // them to undefined
 | |
|         if (isOptional && (!value || Array.isArray(value) && value.length === 1 && // fallback optional catch-all SSG pages have
 | |
|         // [[...paramName]] for the root path on Vercel
 | |
|         (value[0] === "index" || value[0] === `[[...${key}]]`))) {
 | |
|             value = undefined;
 | |
|             delete params[key];
 | |
|         }
 | |
|         // query values from the proxy aren't already split into arrays
 | |
|         // so make sure to normalize catch-all values
 | |
|         if (value && typeof value === "string" && defaultRouteRegex.groups[key].repeat) {
 | |
|             value = value.split("/");
 | |
|         }
 | |
|         if (value) {
 | |
|             prev[key] = value;
 | |
|         }
 | |
|         return prev;
 | |
|     }, {});
 | |
|     return {
 | |
|         params,
 | |
|         hasValidParams
 | |
|     };
 | |
| }
 | |
| function getUtils({ page, i18n, basePath, rewrites, pageIsDynamic, trailingSlash, caseSensitive }) {
 | |
|     let defaultRouteRegex;
 | |
|     let dynamicRouteMatcher;
 | |
|     let defaultRouteMatches;
 | |
|     if (pageIsDynamic) {
 | |
|         defaultRouteRegex = (0, _routeregex.getNamedRouteRegex)(page, false);
 | |
|         dynamicRouteMatcher = (0, _routematcher.getRouteMatcher)(defaultRouteRegex);
 | |
|         defaultRouteMatches = dynamicRouteMatcher(page);
 | |
|     }
 | |
|     function handleRewrites(req, parsedUrl) {
 | |
|         const rewriteParams = {};
 | |
|         let fsPathname = parsedUrl.pathname;
 | |
|         const matchesPage = ()=>{
 | |
|             const fsPathnameNoSlash = (0, _removetrailingslash.removeTrailingSlash)(fsPathname || "");
 | |
|             return fsPathnameNoSlash === (0, _removetrailingslash.removeTrailingSlash)(page) || (dynamicRouteMatcher == null ? void 0 : dynamicRouteMatcher(fsPathnameNoSlash));
 | |
|         };
 | |
|         const checkRewrite = (rewrite)=>{
 | |
|             const matcher = (0, _pathmatch.getPathMatch)(rewrite.source + (trailingSlash ? "(/)?" : ""), {
 | |
|                 removeUnnamedParams: true,
 | |
|                 strict: true,
 | |
|                 sensitive: !!caseSensitive
 | |
|             });
 | |
|             let params = matcher(parsedUrl.pathname);
 | |
|             if ((rewrite.has || rewrite.missing) && params) {
 | |
|                 const hasParams = (0, _preparedestination.matchHas)(req, parsedUrl.query, rewrite.has, rewrite.missing);
 | |
|                 if (hasParams) {
 | |
|                     Object.assign(params, hasParams);
 | |
|                 } else {
 | |
|                     params = false;
 | |
|                 }
 | |
|             }
 | |
|             if (params) {
 | |
|                 const { parsedDestination, destQuery } = (0, _preparedestination.prepareDestination)({
 | |
|                     appendParamsToQuery: true,
 | |
|                     destination: rewrite.destination,
 | |
|                     params: params,
 | |
|                     query: parsedUrl.query
 | |
|                 });
 | |
|                 // if the rewrite destination is external break rewrite chain
 | |
|                 if (parsedDestination.protocol) {
 | |
|                     return true;
 | |
|                 }
 | |
|                 Object.assign(rewriteParams, destQuery, params);
 | |
|                 Object.assign(parsedUrl.query, parsedDestination.query);
 | |
|                 delete parsedDestination.query;
 | |
|                 Object.assign(parsedUrl, parsedDestination);
 | |
|                 fsPathname = parsedUrl.pathname;
 | |
|                 if (basePath) {
 | |
|                     fsPathname = fsPathname.replace(new RegExp(`^${basePath}`), "") || "/";
 | |
|                 }
 | |
|                 if (i18n) {
 | |
|                     const destLocalePathResult = (0, _normalizelocalepath.normalizeLocalePath)(fsPathname, i18n.locales);
 | |
|                     fsPathname = destLocalePathResult.pathname;
 | |
|                     parsedUrl.query.nextInternalLocale = destLocalePathResult.detectedLocale || params.nextInternalLocale;
 | |
|                 }
 | |
|                 if (fsPathname === page) {
 | |
|                     return true;
 | |
|                 }
 | |
|                 if (pageIsDynamic && dynamicRouteMatcher) {
 | |
|                     const dynamicParams = dynamicRouteMatcher(fsPathname);
 | |
|                     if (dynamicParams) {
 | |
|                         parsedUrl.query = {
 | |
|                             ...parsedUrl.query,
 | |
|                             ...dynamicParams
 | |
|                         };
 | |
|                         return true;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             return false;
 | |
|         };
 | |
|         for (const rewrite of rewrites.beforeFiles || []){
 | |
|             checkRewrite(rewrite);
 | |
|         }
 | |
|         if (fsPathname !== page) {
 | |
|             let finished = false;
 | |
|             for (const rewrite of rewrites.afterFiles || []){
 | |
|                 finished = checkRewrite(rewrite);
 | |
|                 if (finished) break;
 | |
|             }
 | |
|             if (!finished && !matchesPage()) {
 | |
|                 for (const rewrite of rewrites.fallback || []){
 | |
|                     finished = checkRewrite(rewrite);
 | |
|                     if (finished) break;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         return rewriteParams;
 | |
|     }
 | |
|     function getParamsFromRouteMatches(req, renderOpts, detectedLocale) {
 | |
|         return (0, _routematcher.getRouteMatcher)(function() {
 | |
|             const { groups, routeKeys } = defaultRouteRegex;
 | |
|             return {
 | |
|                 re: {
 | |
|                     // Simulate a RegExp match from the \`req.url\` input
 | |
|                     exec: (str)=>{
 | |
|                         const obj = Object.fromEntries(new URLSearchParams(str));
 | |
|                         const matchesHasLocale = i18n && detectedLocale && obj["1"] === detectedLocale;
 | |
|                         for (const key of Object.keys(obj)){
 | |
|                             const value = obj[key];
 | |
|                             if (key !== _constants.NEXT_QUERY_PARAM_PREFIX && key.startsWith(_constants.NEXT_QUERY_PARAM_PREFIX)) {
 | |
|                                 const normalizedKey = key.substring(_constants.NEXT_QUERY_PARAM_PREFIX.length);
 | |
|                                 obj[normalizedKey] = value;
 | |
|                                 delete obj[key];
 | |
|                             }
 | |
|                         }
 | |
|                         // favor named matches if available
 | |
|                         const routeKeyNames = Object.keys(routeKeys || {});
 | |
|                         const filterLocaleItem = (val)=>{
 | |
|                             if (i18n) {
 | |
|                                 // locale items can be included in route-matches
 | |
|                                 // for fallback SSG pages so ensure they are
 | |
|                                 // filtered
 | |
|                                 const isCatchAll = Array.isArray(val);
 | |
|                                 const _val = isCatchAll ? val[0] : val;
 | |
|                                 if (typeof _val === "string" && i18n.locales.some((item)=>{
 | |
|                                     if (item.toLowerCase() === _val.toLowerCase()) {
 | |
|                                         detectedLocale = item;
 | |
|                                         renderOpts.locale = detectedLocale;
 | |
|                                         return true;
 | |
|                                     }
 | |
|                                     return false;
 | |
|                                 })) {
 | |
|                                     // remove the locale item from the match
 | |
|                                     if (isCatchAll) {
 | |
|                                         val.splice(0, 1);
 | |
|                                     }
 | |
|                                     // the value is only a locale item and
 | |
|                                     // shouldn't be added
 | |
|                                     return isCatchAll ? val.length === 0 : true;
 | |
|                                 }
 | |
|                             }
 | |
|                             return false;
 | |
|                         };
 | |
|                         if (routeKeyNames.every((name)=>obj[name])) {
 | |
|                             return routeKeyNames.reduce((prev, keyName)=>{
 | |
|                                 const paramName = routeKeys == null ? void 0 : routeKeys[keyName];
 | |
|                                 if (paramName && !filterLocaleItem(obj[keyName])) {
 | |
|                                     prev[groups[paramName].pos] = obj[keyName];
 | |
|                                 }
 | |
|                                 return prev;
 | |
|                             }, {});
 | |
|                         }
 | |
|                         return Object.keys(obj).reduce((prev, key)=>{
 | |
|                             if (!filterLocaleItem(obj[key])) {
 | |
|                                 let normalizedKey = key;
 | |
|                                 if (matchesHasLocale) {
 | |
|                                     normalizedKey = parseInt(key, 10) - 1 + "";
 | |
|                                 }
 | |
|                                 return Object.assign(prev, {
 | |
|                                     [normalizedKey]: obj[key]
 | |
|                                 });
 | |
|                             }
 | |
|                             return prev;
 | |
|                         }, {});
 | |
|                     }
 | |
|                 },
 | |
|                 groups
 | |
|             };
 | |
|         }())(req.headers["x-now-route-matches"]);
 | |
|     }
 | |
|     return {
 | |
|         handleRewrites,
 | |
|         defaultRouteRegex,
 | |
|         dynamicRouteMatcher,
 | |
|         defaultRouteMatches,
 | |
|         getParamsFromRouteMatches,
 | |
|         normalizeDynamicRouteParams: (params, ignoreOptional)=>normalizeDynamicRouteParams(params, ignoreOptional, defaultRouteRegex, defaultRouteMatches),
 | |
|         normalizeVercelUrl: (req, trustQuery, paramKeys)=>normalizeVercelUrl(req, trustQuery, paramKeys, pageIsDynamic, defaultRouteRegex),
 | |
|         interpolateDynamicPath: (pathname, params)=>interpolateDynamicPath(pathname, params, defaultRouteRegex)
 | |
|     };
 | |
| }
 | |
| 
 | |
| //# sourceMappingURL=server-utils.js.map
 |