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.
		
		
		
		
		
			
		
			
	
	
		
			504 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			JavaScript
		
	
		
		
			
		
	
	
			504 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			JavaScript
		
	
| 
											9 months ago
										 | "use strict"; | ||
|  | Object.defineProperty(exports, "__esModule", { | ||
|  |     value: true | ||
|  | }); | ||
|  | 0 && (module.exports = { | ||
|  |     normalizeRouteRegex: null, | ||
|  |     checkCustomRoutes: null, | ||
|  |     default: null | ||
|  | }); | ||
|  | function _export(target, all) { | ||
|  |     for(var name in all)Object.defineProperty(target, name, { | ||
|  |         enumerable: true, | ||
|  |         get: all[name] | ||
|  |     }); | ||
|  | } | ||
|  | _export(exports, { | ||
|  |     normalizeRouteRegex: function() { | ||
|  |         return normalizeRouteRegex; | ||
|  |     }, | ||
|  |     checkCustomRoutes: function() { | ||
|  |         return checkCustomRoutes; | ||
|  |     }, | ||
|  |     default: function() { | ||
|  |         return loadCustomRoutes; | ||
|  |     } | ||
|  | }); | ||
|  | const _picocolors = require("./picocolors"); | ||
|  | const _escaperegexp = require("../shared/lib/escape-regexp"); | ||
|  | const _trytoparsepath = require("./try-to-parse-path"); | ||
|  | const _redirectstatus = require("./redirect-status"); | ||
|  | const allowedHasTypes = new Set([ | ||
|  |     "header", | ||
|  |     "cookie", | ||
|  |     "query", | ||
|  |     "host" | ||
|  | ]); | ||
|  | const namedGroupsRegex = /\(\?<([a-zA-Z][a-zA-Z0-9]*)>/g; | ||
|  | function normalizeRouteRegex(regex) { | ||
|  |     // clean up un-necessary escaping from regex.source which turns / into \\/
 | ||
|  |     return regex.replace(/\\\//g, "/"); | ||
|  | } | ||
|  | function checkRedirect(route) { | ||
|  |     const invalidParts = []; | ||
|  |     let hadInvalidStatus = false; | ||
|  |     if (route.statusCode && !_redirectstatus.allowedStatusCodes.has(route["statusCode"])) { | ||
|  |         hadInvalidStatus = true; | ||
|  |         invalidParts.push(`\`statusCode\` is not undefined or valid statusCode`); | ||
|  |     } | ||
|  |     if (typeof route.permanent !== "boolean" && !route["statusCode"]) { | ||
|  |         invalidParts.push(`\`permanent\` is not set to \`true\` or \`false\``); | ||
|  |     } | ||
|  |     return { | ||
|  |         invalidParts, | ||
|  |         hadInvalidStatus | ||
|  |     }; | ||
|  | } | ||
|  | function checkHeader(route) { | ||
|  |     const invalidParts = []; | ||
|  |     if (!Array.isArray(route.headers)) { | ||
|  |         invalidParts.push("`headers` field must be an array"); | ||
|  |     } else if (route.headers.length === 0) { | ||
|  |         invalidParts.push("`headers` field cannot be empty"); | ||
|  |     } else { | ||
|  |         for (const header of route.headers){ | ||
|  |             if (!header || typeof header !== "object") { | ||
|  |                 invalidParts.push("`headers` items must be object with { key: '', value: '' }"); | ||
|  |                 break; | ||
|  |             } | ||
|  |             if (typeof header.key !== "string") { | ||
|  |                 invalidParts.push("`key` in header item must be string"); | ||
|  |                 break; | ||
|  |             } | ||
|  |             if (typeof header.value !== "string") { | ||
|  |                 invalidParts.push("`value` in header item must be string"); | ||
|  |                 break; | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  |     return invalidParts; | ||
|  | } | ||
|  | function checkCustomRoutes(routes, type) { | ||
|  |     if (!Array.isArray(routes)) { | ||
|  |         console.error(`Error: ${type}s must return an array, received ${typeof routes}.\n` + `See here for more info: https://nextjs.org/docs/messages/routes-must-be-array`); | ||
|  |         process.exit(1); | ||
|  |     } | ||
|  |     let numInvalidRoutes = 0; | ||
|  |     let hadInvalidStatus = false; | ||
|  |     let hadInvalidHas = false; | ||
|  |     let hadInvalidMissing = false; | ||
|  |     const allowedKeys = new Set([ | ||
|  |         "source", | ||
|  |         "locale", | ||
|  |         "has", | ||
|  |         "missing" | ||
|  |     ]); | ||
|  |     if (type === "rewrite") { | ||
|  |         allowedKeys.add("basePath"); | ||
|  |         allowedKeys.add("destination"); | ||
|  |     } | ||
|  |     if (type === "redirect") { | ||
|  |         allowedKeys.add("basePath"); | ||
|  |         allowedKeys.add("statusCode"); | ||
|  |         allowedKeys.add("permanent"); | ||
|  |         allowedKeys.add("destination"); | ||
|  |     } | ||
|  |     if (type === "header") { | ||
|  |         allowedKeys.add("basePath"); | ||
|  |         allowedKeys.add("headers"); | ||
|  |     } | ||
|  |     for (const route of routes){ | ||
|  |         if (!route || typeof route !== "object") { | ||
|  |             console.error(`The route ${JSON.stringify(route)} is not a valid object with \`source\`${type !== "middleware" ? ` and \`${type === "header" ? "headers" : "destination"}\`` : ""}`); | ||
|  |             numInvalidRoutes++; | ||
|  |             continue; | ||
|  |         } | ||
|  |         if (type === "rewrite" && route.basePath === false && !(route.destination.startsWith("http://") || route.destination.startsWith("https://"))) { | ||
|  |             console.error(`The route ${route.source} rewrites urls outside of the basePath. Please use a destination that starts with \`http://\` or \`https://\` https://nextjs.org/docs/messages/invalid-external-rewrite`); | ||
|  |             numInvalidRoutes++; | ||
|  |             continue; | ||
|  |         } | ||
|  |         const keys = Object.keys(route); | ||
|  |         const invalidKeys = keys.filter((key)=>!allowedKeys.has(key)); | ||
|  |         const invalidParts = []; | ||
|  |         if ("basePath" in route && typeof route.basePath !== "undefined" && route.basePath !== false) { | ||
|  |             invalidParts.push("`basePath` must be undefined or false"); | ||
|  |         } | ||
|  |         if (typeof route.locale !== "undefined" && route.locale !== false) { | ||
|  |             invalidParts.push("`locale` must be undefined or false"); | ||
|  |         } | ||
|  |         const checkInvalidHasMissing = (items, fieldName)=>{ | ||
|  |             let hadInvalidItem = false; | ||
|  |             if (typeof items !== "undefined" && !Array.isArray(items)) { | ||
|  |                 invalidParts.push(`\`${fieldName}\` must be undefined or valid has object`); | ||
|  |                 hadInvalidItem = true; | ||
|  |             } else if (items) { | ||
|  |                 const invalidHasItems = []; | ||
|  |                 for (const hasItem of items){ | ||
|  |                     let invalidHasParts = []; | ||
|  |                     if (!allowedHasTypes.has(hasItem.type)) { | ||
|  |                         invalidHasParts.push(`invalid type "${hasItem.type}"`); | ||
|  |                     } | ||
|  |                     if (typeof hasItem.key !== "string" && hasItem.type !== "host") { | ||
|  |                         invalidHasParts.push(`invalid key "${hasItem.key}"`); | ||
|  |                     } | ||
|  |                     if (typeof hasItem.value !== "undefined" && typeof hasItem.value !== "string") { | ||
|  |                         invalidHasParts.push(`invalid value "${hasItem.value}"`); | ||
|  |                     } | ||
|  |                     if (typeof hasItem.value === "undefined" && hasItem.type === "host") { | ||
|  |                         invalidHasParts.push(`value is required for "host" type`); | ||
|  |                     } | ||
|  |                     if (invalidHasParts.length > 0) { | ||
|  |                         invalidHasItems.push(`${invalidHasParts.join(", ")} for ${JSON.stringify(hasItem)}`); | ||
|  |                     } | ||
|  |                 } | ||
|  |                 if (invalidHasItems.length > 0) { | ||
|  |                     hadInvalidItem = true; | ||
|  |                     const itemStr = `item${invalidHasItems.length === 1 ? "" : "s"}`; | ||
|  |                     console.error(`Invalid \`${fieldName}\` ${itemStr}:\n` + invalidHasItems.join("\n")); | ||
|  |                     console.error(); | ||
|  |                     invalidParts.push(`invalid \`${fieldName}\` ${itemStr} found`); | ||
|  |                 } | ||
|  |             } | ||
|  |             return hadInvalidItem; | ||
|  |         }; | ||
|  |         if (checkInvalidHasMissing(route.has, "has")) { | ||
|  |             hadInvalidHas = true; | ||
|  |         } | ||
|  |         if (checkInvalidHasMissing(route.missing, "missing")) { | ||
|  |             hadInvalidMissing = true; | ||
|  |         } | ||
|  |         if (!route.source) { | ||
|  |             invalidParts.push("`source` is missing"); | ||
|  |         } else if (typeof route.source !== "string") { | ||
|  |             invalidParts.push("`source` is not a string"); | ||
|  |         } else if (!route.source.startsWith("/")) { | ||
|  |             invalidParts.push("`source` does not start with /"); | ||
|  |         } | ||
|  |         if (type === "header") { | ||
|  |             invalidParts.push(...checkHeader(route)); | ||
|  |         } else if (type !== "middleware") { | ||
|  |             let _route = route; | ||
|  |             if (!_route.destination) { | ||
|  |                 invalidParts.push("`destination` is missing"); | ||
|  |             } else if (typeof _route.destination !== "string") { | ||
|  |                 invalidParts.push("`destination` is not a string"); | ||
|  |             } else if (type === "rewrite" && !_route.destination.match(/^(\/|https:\/\/|http:\/\/)/)) { | ||
|  |                 invalidParts.push("`destination` does not start with `/`, `http://`, or `https://`"); | ||
|  |             } | ||
|  |         } | ||
|  |         if (type === "redirect") { | ||
|  |             const result = checkRedirect(route); | ||
|  |             hadInvalidStatus = hadInvalidStatus || result.hadInvalidStatus; | ||
|  |             invalidParts.push(...result.invalidParts); | ||
|  |         } | ||
|  |         let sourceTokens; | ||
|  |         if (typeof route.source === "string" && route.source.startsWith("/")) { | ||
|  |             // only show parse error if we didn't already show error
 | ||
|  |             // for not being a string
 | ||
|  |             const { tokens, error, regexStr } = (0, _trytoparsepath.tryToParsePath)(route.source); | ||
|  |             if (error) { | ||
|  |                 invalidParts.push("`source` parse failed"); | ||
|  |             } | ||
|  |             if (regexStr && regexStr.length > 4096) { | ||
|  |                 invalidParts.push("`source` exceeds max built length of 4096"); | ||
|  |             } | ||
|  |             sourceTokens = tokens; | ||
|  |         } | ||
|  |         const hasSegments = new Set(); | ||
|  |         if (route.has) { | ||
|  |             for (const hasItem of route.has){ | ||
|  |                 if (!hasItem.value && hasItem.key) { | ||
|  |                     hasSegments.add(hasItem.key); | ||
|  |                 } | ||
|  |                 if (hasItem.value) { | ||
|  |                     for (const match of hasItem.value.matchAll(namedGroupsRegex)){ | ||
|  |                         if (match[1]) { | ||
|  |                             hasSegments.add(match[1]); | ||
|  |                         } | ||
|  |                     } | ||
|  |                     if (hasItem.type === "host") { | ||
|  |                         hasSegments.add("host"); | ||
|  |                     } | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |         // make sure no unnamed patterns are attempted to be used in the
 | ||
|  |         // destination as this can cause confusion and is not allowed
 | ||
|  |         if (typeof route.destination === "string") { | ||
|  |             if (route.destination.startsWith("/") && Array.isArray(sourceTokens)) { | ||
|  |                 const unnamedInDest = new Set(); | ||
|  |                 for (const token of sourceTokens){ | ||
|  |                     if (typeof token === "object" && typeof token.name === "number") { | ||
|  |                         const unnamedIndex = new RegExp(`:${token.name}(?!\\d)`); | ||
|  |                         if (route.destination.match(unnamedIndex)) { | ||
|  |                             unnamedInDest.add(`:${token.name}`); | ||
|  |                         } | ||
|  |                     } | ||
|  |                 } | ||
|  |                 if (unnamedInDest.size > 0) { | ||
|  |                     invalidParts.push(`\`destination\` has unnamed params ${[ | ||
|  |                         ...unnamedInDest | ||
|  |                     ].join(", ")}`);
 | ||
|  |                 } else { | ||
|  |                     const { tokens: destTokens, regexStr: destRegexStr, error: destinationParseFailed } = (0, _trytoparsepath.tryToParsePath)(route.destination, { | ||
|  |                         handleUrl: true | ||
|  |                     }); | ||
|  |                     if (destRegexStr && destRegexStr.length > 4096) { | ||
|  |                         invalidParts.push("`destination` exceeds max built length of 4096"); | ||
|  |                     } | ||
|  |                     if (destinationParseFailed) { | ||
|  |                         invalidParts.push("`destination` parse failed"); | ||
|  |                     } else { | ||
|  |                         const sourceSegments = new Set(sourceTokens.map((item)=>typeof item === "object" && item.name).filter(Boolean)); | ||
|  |                         const invalidDestSegments = new Set(); | ||
|  |                         for (const token of destTokens){ | ||
|  |                             if (typeof token === "object" && !sourceSegments.has(token.name) && !hasSegments.has(token.name)) { | ||
|  |                                 invalidDestSegments.add(token.name); | ||
|  |                             } | ||
|  |                         } | ||
|  |                         if (invalidDestSegments.size) { | ||
|  |                             invalidParts.push(`\`destination\` has segments not in \`source\` or \`has\` (${[ | ||
|  |                                 ...invalidDestSegments | ||
|  |                             ].join(", ")})`);
 | ||
|  |                         } | ||
|  |                     } | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |         const hasInvalidKeys = invalidKeys.length > 0; | ||
|  |         const hasInvalidParts = invalidParts.length > 0; | ||
|  |         if (hasInvalidKeys || hasInvalidParts) { | ||
|  |             console.error(`${invalidParts.join(", ")}${invalidKeys.length ? (hasInvalidParts ? "," : "") + ` invalid field${invalidKeys.length === 1 ? "" : "s"}: ` + invalidKeys.join(",") : ""} for route ${JSON.stringify(route)}`); | ||
|  |             console.error(); | ||
|  |             numInvalidRoutes++; | ||
|  |         } | ||
|  |     } | ||
|  |     if (numInvalidRoutes > 0) { | ||
|  |         if (hadInvalidStatus) { | ||
|  |             console.error(`\nValid redirect statusCode values are ${[ | ||
|  |                 ..._redirectstatus.allowedStatusCodes | ||
|  |             ].join(", ")}`);
 | ||
|  |         } | ||
|  |         if (hadInvalidHas) { | ||
|  |             console.error(`\nValid \`has\` object shape is ${JSON.stringify({ | ||
|  |                 type: [ | ||
|  |                     ...allowedHasTypes | ||
|  |                 ].join(", "), | ||
|  |                 key: "the key to check for", | ||
|  |                 value: "undefined or a value string to match against" | ||
|  |             }, null, 2)}`);
 | ||
|  |         } | ||
|  |         if (hadInvalidMissing) { | ||
|  |             console.error(`\nValid \`missing\` object shape is ${JSON.stringify({ | ||
|  |                 type: [ | ||
|  |                     ...allowedHasTypes | ||
|  |                 ].join(", "), | ||
|  |                 key: "the key to check for", | ||
|  |                 value: "undefined or a value string to match against" | ||
|  |             }, null, 2)}`);
 | ||
|  |         } | ||
|  |         console.error(); | ||
|  |         console.error(`Error: Invalid ${type}${numInvalidRoutes === 1 ? "" : "s"} found`); | ||
|  |         process.exit(1); | ||
|  |     } | ||
|  | } | ||
|  | function processRoutes(routes, config, type) { | ||
|  |     const _routes = routes; | ||
|  |     const newRoutes = []; | ||
|  |     const defaultLocales = []; | ||
|  |     if (config.i18n && type === "redirect") { | ||
|  |         var _config_i18n; | ||
|  |         for (const item of ((_config_i18n = config.i18n) == null ? void 0 : _config_i18n.domains) || []){ | ||
|  |             defaultLocales.push({ | ||
|  |                 locale: item.defaultLocale, | ||
|  |                 base: `http${item.http ? "" : "s"}://${item.domain}` | ||
|  |             }); | ||
|  |         } | ||
|  |         defaultLocales.push({ | ||
|  |             locale: config.i18n.defaultLocale, | ||
|  |             base: "" | ||
|  |         }); | ||
|  |     } | ||
|  |     for (const r of _routes){ | ||
|  |         var _r_destination; | ||
|  |         const srcBasePath = config.basePath && r.basePath !== false ? config.basePath : ""; | ||
|  |         const isExternal = !((_r_destination = r.destination) == null ? void 0 : _r_destination.startsWith("/")); | ||
|  |         const destBasePath = srcBasePath && !isExternal ? srcBasePath : ""; | ||
|  |         if (config.i18n && r.locale !== false) { | ||
|  |             var _r_destination1; | ||
|  |             if (!isExternal) { | ||
|  |                 defaultLocales.forEach((item)=>{ | ||
|  |                     let destination; | ||
|  |                     if (r.destination) { | ||
|  |                         destination = item.base ? `${item.base}${destBasePath}${r.destination}` : `${destBasePath}${r.destination}`; | ||
|  |                     } | ||
|  |                     newRoutes.push({ | ||
|  |                         ...r, | ||
|  |                         destination, | ||
|  |                         source: `${srcBasePath}/${item.locale}${r.source === "/" && !config.trailingSlash ? "" : r.source}` | ||
|  |                     }); | ||
|  |                 }); | ||
|  |             } | ||
|  |             r.source = `/:nextInternalLocale(${config.i18n.locales.map((locale)=>(0, _escaperegexp.escapeStringRegexp)(locale)).join("|")})${r.source === "/" && !config.trailingSlash ? "" : r.source}`; | ||
|  |             if (r.destination && ((_r_destination1 = r.destination) == null ? void 0 : _r_destination1.startsWith("/"))) { | ||
|  |                 r.destination = `/:nextInternalLocale${r.destination === "/" && !config.trailingSlash ? "" : r.destination}`; | ||
|  |             } | ||
|  |         } | ||
|  |         r.source = `${srcBasePath}${r.source === "/" && srcBasePath ? "" : r.source}`; | ||
|  |         if (r.destination) { | ||
|  |             r.destination = `${destBasePath}${r.destination === "/" && destBasePath ? "" : r.destination}`; | ||
|  |         } | ||
|  |         newRoutes.push(r); | ||
|  |     } | ||
|  |     return newRoutes; | ||
|  | } | ||
|  | async function loadRedirects(config) { | ||
|  |     if (typeof config.redirects !== "function") { | ||
|  |         return []; | ||
|  |     } | ||
|  |     let redirects = await config.redirects(); | ||
|  |     // check before we process the routes and after to ensure
 | ||
|  |     // they are still valid
 | ||
|  |     checkCustomRoutes(redirects, "redirect"); | ||
|  |     // save original redirects before transforms
 | ||
|  |     if (Array.isArray(redirects)) { | ||
|  |         config._originalRedirects = redirects.map((r)=>({ | ||
|  |                 ...r | ||
|  |             })); | ||
|  |     } | ||
|  |     redirects = processRoutes(redirects, config, "redirect"); | ||
|  |     checkCustomRoutes(redirects, "redirect"); | ||
|  |     return redirects; | ||
|  | } | ||
|  | async function loadRewrites(config) { | ||
|  |     if (typeof config.rewrites !== "function") { | ||
|  |         return { | ||
|  |             beforeFiles: [], | ||
|  |             afterFiles: [], | ||
|  |             fallback: [] | ||
|  |         }; | ||
|  |     } | ||
|  |     const _rewrites = await config.rewrites(); | ||
|  |     let beforeFiles = []; | ||
|  |     let afterFiles = []; | ||
|  |     let fallback = []; | ||
|  |     if (!Array.isArray(_rewrites) && typeof _rewrites === "object" && Object.keys(_rewrites).every((key)=>key === "beforeFiles" || key === "afterFiles" || key === "fallback")) { | ||
|  |         beforeFiles = _rewrites.beforeFiles || []; | ||
|  |         afterFiles = _rewrites.afterFiles || []; | ||
|  |         fallback = _rewrites.fallback || []; | ||
|  |     } else { | ||
|  |         afterFiles = _rewrites; | ||
|  |     } | ||
|  |     // check before we process the routes and after to ensure
 | ||
|  |     // they are still valid
 | ||
|  |     checkCustomRoutes(beforeFiles, "rewrite"); | ||
|  |     checkCustomRoutes(afterFiles, "rewrite"); | ||
|  |     checkCustomRoutes(fallback, "rewrite"); | ||
|  |     // save original rewrites before transforms
 | ||
|  |     config._originalRewrites = { | ||
|  |         beforeFiles: beforeFiles.map((r)=>({ | ||
|  |                 ...r | ||
|  |             })), | ||
|  |         afterFiles: afterFiles.map((r)=>({ | ||
|  |                 ...r | ||
|  |             })), | ||
|  |         fallback: fallback.map((r)=>({ | ||
|  |                 ...r | ||
|  |             })) | ||
|  |     }; | ||
|  |     beforeFiles = processRoutes(beforeFiles, config, "rewrite"); | ||
|  |     afterFiles = processRoutes(afterFiles, config, "rewrite"); | ||
|  |     fallback = processRoutes(fallback, config, "rewrite"); | ||
|  |     checkCustomRoutes(beforeFiles, "rewrite"); | ||
|  |     checkCustomRoutes(afterFiles, "rewrite"); | ||
|  |     checkCustomRoutes(fallback, "rewrite"); | ||
|  |     return { | ||
|  |         beforeFiles, | ||
|  |         afterFiles, | ||
|  |         fallback | ||
|  |     }; | ||
|  | } | ||
|  | async function loadHeaders(config) { | ||
|  |     if (typeof config.headers !== "function") { | ||
|  |         return []; | ||
|  |     } | ||
|  |     let headers = await config.headers(); | ||
|  |     // check before we process the routes and after to ensure
 | ||
|  |     // they are still valid
 | ||
|  |     checkCustomRoutes(headers, "header"); | ||
|  |     headers = processRoutes(headers, config, "header"); | ||
|  |     checkCustomRoutes(headers, "header"); | ||
|  |     return headers; | ||
|  | } | ||
|  | async function loadCustomRoutes(config) { | ||
|  |     const [headers, rewrites, redirects] = await Promise.all([ | ||
|  |         loadHeaders(config), | ||
|  |         loadRewrites(config), | ||
|  |         loadRedirects(config) | ||
|  |     ]); | ||
|  |     const totalRewrites = rewrites.beforeFiles.length + rewrites.afterFiles.length + rewrites.fallback.length; | ||
|  |     const totalRoutes = headers.length + redirects.length + totalRewrites; | ||
|  |     if (totalRoutes > 1000) { | ||
|  |         console.warn((0, _picocolors.bold)((0, _picocolors.yellow)(`Warning: `)) + `total number of custom routes exceeds 1000, this can reduce performance. Route counts:\n` + `headers: ${headers.length}\n` + `rewrites: ${totalRewrites}\n` + `redirects: ${redirects.length}\n` + `See more info: https://nextjs.org/docs/messages/max-custom-routes-reached`); | ||
|  |     } | ||
|  |     if (!config.skipTrailingSlashRedirect) { | ||
|  |         if (config.trailingSlash) { | ||
|  |             redirects.unshift({ | ||
|  |                 source: "/:file((?!\\.well-known(?:/.*)?)(?:[^/]+/)*[^/]+\\.\\w+)/", | ||
|  |                 destination: "/:file", | ||
|  |                 permanent: true, | ||
|  |                 locale: config.i18n ? false : undefined, | ||
|  |                 internal: true, | ||
|  |                 // don't run this redirect for _next/data requests
 | ||
|  |                 missing: [ | ||
|  |                     { | ||
|  |                         type: "header", | ||
|  |                         key: "x-nextjs-data" | ||
|  |                     } | ||
|  |                 ] | ||
|  |             }, { | ||
|  |                 source: "/:notfile((?!\\.well-known(?:/.*)?)(?:[^/]+/)*[^/\\.]+)", | ||
|  |                 destination: "/:notfile/", | ||
|  |                 permanent: true, | ||
|  |                 locale: config.i18n ? false : undefined, | ||
|  |                 internal: true | ||
|  |             }); | ||
|  |             if (config.basePath) { | ||
|  |                 redirects.unshift({ | ||
|  |                     source: config.basePath, | ||
|  |                     destination: config.basePath + "/", | ||
|  |                     permanent: true, | ||
|  |                     basePath: false, | ||
|  |                     locale: config.i18n ? false : undefined, | ||
|  |                     internal: true | ||
|  |                 }); | ||
|  |             } | ||
|  |         } else { | ||
|  |             redirects.unshift({ | ||
|  |                 source: "/:path+/", | ||
|  |                 destination: "/:path+", | ||
|  |                 permanent: true, | ||
|  |                 locale: config.i18n ? false : undefined, | ||
|  |                 internal: true | ||
|  |             }); | ||
|  |             if (config.basePath) { | ||
|  |                 redirects.unshift({ | ||
|  |                     source: config.basePath + "/", | ||
|  |                     destination: config.basePath, | ||
|  |                     permanent: true, | ||
|  |                     basePath: false, | ||
|  |                     locale: config.i18n ? false : undefined, | ||
|  |                     internal: true | ||
|  |                 }); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  |     return { | ||
|  |         headers, | ||
|  |         rewrites, | ||
|  |         redirects | ||
|  |     }; | ||
|  | } | ||
|  | 
 | ||
|  | //# sourceMappingURL=load-custom-routes.js.map
 |