@vercel/routing-utils
Advanced tools
Comparing version 1.11.4-canary.0 to 1.11.4-canary.1
@@ -195,68 +195,81 @@ "use strict"; | ||
exports.collectHasSegments = collectHasSegments; | ||
const escapeSegment = (str, segmentName) => str.replace(new RegExp(`:${segmentName}`, 'g'), `__ESC_COLON_${segmentName}`); | ||
const unescapeSegments = (str) => str.replace(/__ESC_COLON_/gi, ':'); | ||
function replaceSegments(segments, hasItemSegments, destination, isRedirect) { | ||
const parsedDestination = url_1.parse(destination, true); | ||
const namedSegments = segments.filter(name => name !== UN_NAMED_SEGMENT); | ||
const canNeedReplacing = (destination.includes(':') && namedSegments.length > 0) || | ||
hasItemSegments.length > 0 || | ||
!isRedirect; | ||
if (!canNeedReplacing) { | ||
return destination; | ||
} | ||
let escapedDestination = destination; | ||
const indexes = {}; | ||
segments.forEach((name, index) => { | ||
indexes[name] = toSegmentDest(index); | ||
escapedDestination = escapeSegment(escapedDestination, name); | ||
}); | ||
// 'has' matches override 'source' matches | ||
hasItemSegments.forEach(name => { | ||
indexes[name] = '$' + name; | ||
escapedDestination = escapeSegment(escapedDestination, name); | ||
}); | ||
const parsedDestination = url_1.parse(escapedDestination, true); | ||
delete parsedDestination.href; | ||
delete parsedDestination.path; | ||
delete parsedDestination.search; | ||
delete parsedDestination.host; | ||
// eslint-disable-next-line prefer-const | ||
let { pathname, hash, query, ...rest } = parsedDestination; | ||
pathname = pathname || ''; | ||
hash = hash || ''; | ||
const namedSegments = segments.filter(name => name !== UN_NAMED_SEGMENT); | ||
if (namedSegments.length > 0 || hasItemSegments.length > 0) { | ||
const indexes = {}; | ||
segments.forEach((name, index) => { | ||
indexes[name] = toSegmentDest(index); | ||
}); | ||
// 'has' matches override 'source' matches | ||
hasItemSegments.forEach(name => { | ||
indexes[name] = '$' + name; | ||
}); | ||
let destParams = new Set(); | ||
if (destination.includes(':')) { | ||
const pathnameKeys = []; | ||
const hashKeys = []; | ||
try { | ||
path_to_regexp_1.pathToRegexp(pathname, pathnameKeys); | ||
path_to_regexp_1.pathToRegexp(hash || '', hashKeys); | ||
} | ||
catch (_) { | ||
// this is not fatal so don't error when failing to parse the | ||
// params from the destination | ||
} | ||
destParams = new Set([...pathnameKeys, ...hashKeys] | ||
.map(key => key.name) | ||
.filter(val => typeof val === 'string')); | ||
pathname = safelyCompile(pathname, indexes, true); | ||
hash = hash ? safelyCompile(hash, indexes, true) : null; | ||
for (const [key, strOrArray] of Object.entries(query)) { | ||
if (Array.isArray(strOrArray)) { | ||
query[key] = strOrArray.map(str => safelyCompile(str, indexes, true)); | ||
} | ||
else { | ||
query[key] = safelyCompile(strOrArray, indexes, true); | ||
} | ||
} | ||
let { pathname, hash, query, hostname, ...rest } = parsedDestination; | ||
pathname = unescapeSegments(pathname || ''); | ||
hash = unescapeSegments(hash || ''); | ||
hostname = unescapeSegments(hostname || ''); | ||
let destParams = new Set(); | ||
const pathnameKeys = []; | ||
const hashKeys = []; | ||
const hostnameKeys = []; | ||
try { | ||
path_to_regexp_1.pathToRegexp(pathname, pathnameKeys); | ||
path_to_regexp_1.pathToRegexp(hash || '', hashKeys); | ||
path_to_regexp_1.pathToRegexp(hostname || '', hostnameKeys); | ||
} | ||
catch (_) { | ||
// this is not fatal so don't error when failing to parse the | ||
// params from the destination | ||
} | ||
destParams = new Set([...pathnameKeys, ...hashKeys, ...hostnameKeys] | ||
.map(key => key.name) | ||
.filter(val => typeof val === 'string')); | ||
pathname = safelyCompile(pathname, indexes, true); | ||
hash = hash ? safelyCompile(hash, indexes, true) : null; | ||
hostname = hostname ? safelyCompile(hostname, indexes, true) : null; | ||
for (const [key, strOrArray] of Object.entries(query)) { | ||
if (Array.isArray(strOrArray)) { | ||
query[key] = strOrArray.map(str => safelyCompile(unescapeSegments(str), indexes, true)); | ||
} | ||
// We only add path segments to redirect queries if manually | ||
// specified and only automatically add them for rewrites if one | ||
// or more params aren't already used in the destination's path | ||
const paramKeys = Object.keys(indexes); | ||
if (!isRedirect && !paramKeys.some(param => destParams.has(param))) { | ||
for (const param of paramKeys) { | ||
if (!(param in query) && param !== UN_NAMED_SEGMENT) { | ||
query[param] = indexes[param]; | ||
} | ||
else { | ||
query[key] = safelyCompile(unescapeSegments(strOrArray), indexes, true); | ||
} | ||
} | ||
// We only add path segments to redirect queries if manually | ||
// specified and only automatically add them for rewrites if one | ||
// or more params aren't already used in the destination's path | ||
const paramKeys = Object.keys(indexes); | ||
const needsQueryUpdating = !isRedirect && !paramKeys.some(param => destParams.has(param)); | ||
if (needsQueryUpdating) { | ||
for (const param of paramKeys) { | ||
if (!(param in query) && param !== UN_NAMED_SEGMENT) { | ||
query[param] = indexes[param]; | ||
} | ||
} | ||
destination = url_1.format({ | ||
...rest, | ||
pathname, | ||
query, | ||
hash, | ||
}); | ||
// url.format() escapes the dollar sign but it must be preserved for now-proxy | ||
destination = destination.replace(/%24/g, '$'); | ||
} | ||
return destination; | ||
destination = url_1.format({ | ||
...rest, | ||
hostname, | ||
pathname, | ||
query, | ||
hash, | ||
}); | ||
// url.format() escapes the dollar sign but it must be preserved for now-proxy | ||
return destination.replace(/%24/g, '$'); | ||
} | ||
@@ -263,0 +276,0 @@ function safelyCompile(value, indexes, attemptDirectCompile) { |
{ | ||
"name": "@vercel/routing-utils", | ||
"version": "1.11.4-canary.0", | ||
"version": "1.11.4-canary.1", | ||
"description": "Vercel routing utilities", | ||
@@ -33,3 +33,3 @@ "main": "./dist/index.js", | ||
}, | ||
"gitHead": "e8fec4b69c60739204334cfb910572776ef25fcd" | ||
"gitHead": "bfbd92732080d9cf944205f17273504cc06cbf07" | ||
} |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
76644
1622
0