123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.matchHas = matchHas;
- exports.compileNonPath = compileNonPath;
- exports.prepareDestination = prepareDestination;
- var _extends = require("@swc/helpers/lib/_extends.js").default;
- var _pathToRegexp = require("next/dist/compiled/path-to-regexp");
- var _escapeRegexp = require("../../escape-regexp");
- var _parseUrl = require("./parse-url");
- /**
- * Ensure only a-zA-Z are used for param names for proper interpolating
- * with path-to-regexp
- */ function getSafeParamName(paramName) {
- let newParamName = '';
- for(let i = 0; i < paramName.length; i++){
- const charCode = paramName.charCodeAt(i);
- if (charCode > 64 && charCode < 91 || charCode > 96 && charCode < 123 // a-z
- ) {
- newParamName += paramName[i];
- }
- }
- return newParamName;
- }
- function escapeSegment(str, segmentName) {
- return str.replace(new RegExp(`:${(0, _escapeRegexp).escapeStringRegexp(segmentName)}`, 'g'), `__ESC_COLON_${segmentName}`);
- }
- function unescapeSegments(str) {
- return str.replace(/__ESC_COLON_/gi, ':');
- }
- function matchHas(req, query, has = [], missing = []) {
- const params = {};
- const hasMatch = (hasItem)=>{
- let value;
- let key = hasItem.key;
- switch(hasItem.type){
- case 'header':
- {
- key = key.toLowerCase();
- value = req.headers[key];
- break;
- }
- case 'cookie':
- {
- value = req.cookies[hasItem.key];
- break;
- }
- case 'query':
- {
- value = query[key];
- break;
- }
- case 'host':
- {
- const { host } = (req == null ? void 0 : req.headers) || {};
- // remove port from host if present
- const hostname = host == null ? void 0 : host.split(':')[0].toLowerCase();
- value = hostname;
- break;
- }
- default:
- {
- break;
- }
- }
- if (!hasItem.value && value) {
- params[getSafeParamName(key)] = value;
- return true;
- } else if (value) {
- const matcher = new RegExp(`^${hasItem.value}$`);
- const matches = Array.isArray(value) ? value.slice(-1)[0].match(matcher) : value.match(matcher);
- if (matches) {
- if (Array.isArray(matches)) {
- if (matches.groups) {
- Object.keys(matches.groups).forEach((groupKey)=>{
- params[groupKey] = matches.groups[groupKey];
- });
- } else if (hasItem.type === 'host' && matches[0]) {
- params.host = matches[0];
- }
- }
- return true;
- }
- }
- return false;
- };
- const allMatch = has.every((item)=>hasMatch(item)) && !missing.some((item)=>hasMatch(item));
- if (allMatch) {
- return params;
- }
- return false;
- }
- function compileNonPath(value, params) {
- if (!value.includes(':')) {
- return value;
- }
- for (const key of Object.keys(params)){
- if (value.includes(`:${key}`)) {
- value = value.replace(new RegExp(`:${key}\\*`, 'g'), `:${key}--ESCAPED_PARAM_ASTERISKS`).replace(new RegExp(`:${key}\\?`, 'g'), `:${key}--ESCAPED_PARAM_QUESTION`).replace(new RegExp(`:${key}\\+`, 'g'), `:${key}--ESCAPED_PARAM_PLUS`).replace(new RegExp(`:${key}(?!\\w)`, 'g'), `--ESCAPED_PARAM_COLON${key}`);
- }
- }
- value = value.replace(/(:|\*|\?|\+|\(|\)|\{|\})/g, '\\$1').replace(/--ESCAPED_PARAM_PLUS/g, '+').replace(/--ESCAPED_PARAM_COLON/g, ':').replace(/--ESCAPED_PARAM_QUESTION/g, '?').replace(/--ESCAPED_PARAM_ASTERISKS/g, '*');
- // the value needs to start with a forward-slash to be compiled
- // correctly
- return (0, _pathToRegexp).compile(`/${value}`, {
- validate: false
- })(params).slice(1);
- }
- function prepareDestination(args) {
- const query = Object.assign({}, args.query);
- delete query.__nextLocale;
- delete query.__nextDefaultLocale;
- delete query.__nextDataReq;
- let escapedDestination = args.destination;
- for (const param of Object.keys(_extends({}, args.params, query))){
- escapedDestination = escapeSegment(escapedDestination, param);
- }
- const parsedDestination = (0, _parseUrl).parseUrl(escapedDestination);
- const destQuery = parsedDestination.query;
- const destPath = unescapeSegments(`${parsedDestination.pathname}${parsedDestination.hash || ''}`);
- const destHostname = unescapeSegments(parsedDestination.hostname || '');
- const destPathParamKeys = [];
- const destHostnameParamKeys = [];
- (0, _pathToRegexp).pathToRegexp(destPath, destPathParamKeys);
- (0, _pathToRegexp).pathToRegexp(destHostname, destHostnameParamKeys);
- const destParams = [];
- destPathParamKeys.forEach((key)=>destParams.push(key.name));
- destHostnameParamKeys.forEach((key)=>destParams.push(key.name));
- const destPathCompiler = (0, _pathToRegexp).compile(destPath, // we don't validate while compiling the destination since we should
- // have already validated before we got to this point and validating
- // breaks compiling destinations with named pattern params from the source
- // e.g. /something:hello(.*) -> /another/:hello is broken with validation
- // since compile validation is meant for reversing and not for inserting
- // params from a separate path-regex into another
- {
- validate: false
- });
- const destHostnameCompiler = (0, _pathToRegexp).compile(destHostname, {
- validate: false
- });
- // update any params in query values
- for (const [key1, strOrArray] of Object.entries(destQuery)){
- // the value needs to start with a forward-slash to be compiled
- // correctly
- if (Array.isArray(strOrArray)) {
- destQuery[key1] = strOrArray.map((value)=>compileNonPath(unescapeSegments(value), args.params));
- } else {
- destQuery[key1] = compileNonPath(unescapeSegments(strOrArray), args.params);
- }
- }
- // add path params to query if it's not a redirect and not
- // already defined in destination query or path
- let paramKeys = Object.keys(args.params).filter((name)=>name !== 'nextInternalLocale');
- if (args.appendParamsToQuery && !paramKeys.some((key)=>destParams.includes(key))) {
- for (const key of paramKeys){
- if (!(key in destQuery)) {
- destQuery[key] = args.params[key];
- }
- }
- }
- let newUrl;
- try {
- newUrl = destPathCompiler(args.params);
- const [pathname, hash] = newUrl.split('#');
- parsedDestination.hostname = destHostnameCompiler(args.params);
- parsedDestination.pathname = pathname;
- parsedDestination.hash = `${hash ? '#' : ''}${hash || ''}`;
- delete parsedDestination.search;
- } catch (err) {
- if (err.message.match(/Expected .*? to not repeat, but got an array/)) {
- throw new Error(`To use a multi-match in the destination you must add \`*\` at the end of the param name to signify it should repeat. https://nextjs.org/docs/messages/invalid-multi-match`);
- }
- throw err;
- }
- // Query merge order lowest priority to highest
- // 1. initial URL query values
- // 2. path segment values
- // 3. destination specified query values
- parsedDestination.query = _extends({}, query, parsedDestination.query);
- return {
- newUrl,
- destQuery,
- parsedDestination
- };
- }
- //# sourceMappingURL=prepare-destination.js.map
|