176 lines
8.1 KiB
JavaScript
Executable File
176 lines
8.1 KiB
JavaScript
Executable File
"use strict";
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
0 && (module.exports = {
|
|
doesStaticSegmentAppearInURL: null,
|
|
getCacheKeyForDynamicParam: null,
|
|
getParamValueFromCacheKey: null,
|
|
getRenderedPathname: null,
|
|
getRenderedSearch: null,
|
|
parseDynamicParamFromURLPart: null,
|
|
urlToUrlWithoutFlightMarker: null
|
|
});
|
|
function _export(target, all) {
|
|
for(var name in all)Object.defineProperty(target, name, {
|
|
enumerable: true,
|
|
get: all[name]
|
|
});
|
|
}
|
|
_export(exports, {
|
|
doesStaticSegmentAppearInURL: function() {
|
|
return doesStaticSegmentAppearInURL;
|
|
},
|
|
getCacheKeyForDynamicParam: function() {
|
|
return getCacheKeyForDynamicParam;
|
|
},
|
|
getParamValueFromCacheKey: function() {
|
|
return getParamValueFromCacheKey;
|
|
},
|
|
getRenderedPathname: function() {
|
|
return getRenderedPathname;
|
|
},
|
|
getRenderedSearch: function() {
|
|
return getRenderedSearch;
|
|
},
|
|
parseDynamicParamFromURLPart: function() {
|
|
return parseDynamicParamFromURLPart;
|
|
},
|
|
urlToUrlWithoutFlightMarker: function() {
|
|
return urlToUrlWithoutFlightMarker;
|
|
}
|
|
});
|
|
const _segment = require("../shared/lib/segment");
|
|
const _segmentvalueencoding = require("../shared/lib/segment-cache/segment-value-encoding");
|
|
const _approuterheaders = require("./components/app-router-headers");
|
|
function getRenderedSearch(response) {
|
|
// If the server performed a rewrite, the search params used to render the
|
|
// page will be different from the params in the request URL. In this case,
|
|
// the response will include a header that gives the rewritten search query.
|
|
const rewrittenQuery = response.headers.get(_approuterheaders.NEXT_REWRITTEN_QUERY_HEADER);
|
|
if (rewrittenQuery !== null) {
|
|
return rewrittenQuery === '' ? '' : '?' + rewrittenQuery;
|
|
}
|
|
// If the header is not present, there was no rewrite, so we use the search
|
|
// query of the response URL.
|
|
return urlToUrlWithoutFlightMarker(new URL(response.url)).search;
|
|
}
|
|
function getRenderedPathname(response) {
|
|
// If the server performed a rewrite, the pathname used to render the
|
|
// page will be different from the pathname in the request URL. In this case,
|
|
// the response will include a header that gives the rewritten pathname.
|
|
const rewrittenPath = response.headers.get(_approuterheaders.NEXT_REWRITTEN_PATH_HEADER);
|
|
return rewrittenPath != null ? rewrittenPath : urlToUrlWithoutFlightMarker(new URL(response.url)).pathname;
|
|
}
|
|
function parseDynamicParamFromURLPart(paramType, pathnameParts, partIndex) {
|
|
// This needs to match the behavior in get-dynamic-param.ts.
|
|
switch(paramType){
|
|
// Catchalls
|
|
case 'c':
|
|
case 'ci':
|
|
{
|
|
// Catchalls receive all the remaining URL parts. If there are no
|
|
// remaining pathname parts, return an empty array.
|
|
return partIndex < pathnameParts.length ? pathnameParts.slice(partIndex).map((s)=>encodeURIComponent(s)) : [];
|
|
}
|
|
// Optional catchalls
|
|
case 'oc':
|
|
{
|
|
// Optional catchalls receive all the remaining URL parts, unless this is
|
|
// the end of the pathname, in which case they return null.
|
|
return partIndex < pathnameParts.length ? pathnameParts.slice(partIndex).map((s)=>encodeURIComponent(s)) : null;
|
|
}
|
|
// Dynamic
|
|
case 'd':
|
|
case 'di':
|
|
{
|
|
if (partIndex >= pathnameParts.length) {
|
|
// The route tree expected there to be more parts in the URL than there
|
|
// actually are. This could happen if the x-nextjs-rewritten-path header
|
|
// is incorrectly set, or potentially due to bug in Next.js. TODO:
|
|
// Should this be a hard error? During a prefetch, we can just abort.
|
|
// During a client navigation, we could trigger a hard refresh. But if
|
|
// it happens during initial render, we don't really have any
|
|
// recovery options.
|
|
return '';
|
|
}
|
|
return encodeURIComponent(pathnameParts[partIndex]);
|
|
}
|
|
default:
|
|
paramType;
|
|
return '';
|
|
}
|
|
}
|
|
function doesStaticSegmentAppearInURL(segment) {
|
|
// This is not a parameterized segment; however, we need to determine
|
|
// whether or not this segment appears in the URL. For example, this route
|
|
// groups do not appear in the URL, so they should be skipped. Any other
|
|
// special cases must be handled here.
|
|
// TODO: Consider encoding this directly into the router tree instead of
|
|
// inferring it on the client based on the segment type. Something like
|
|
// a `doesAppearInURL` flag in FlightRouterState.
|
|
if (segment === _segmentvalueencoding.ROOT_SEGMENT_REQUEST_KEY || // For some reason, the loader tree sometimes includes extra __PAGE__
|
|
// "layouts" when part of a parallel route. But it's not a leaf node.
|
|
// Otherwise, we wouldn't need this special case because pages are
|
|
// always leaf nodes.
|
|
// TODO: Investigate why the loader produces these fake page segments.
|
|
segment.startsWith(_segment.PAGE_SEGMENT_KEY) || // Route groups.
|
|
segment[0] === '(' && segment.endsWith(')') || segment === _segment.DEFAULT_SEGMENT_KEY || segment === '/_not-found') {
|
|
return false;
|
|
} else {
|
|
// All other segment types appear in the URL
|
|
return true;
|
|
}
|
|
}
|
|
function getCacheKeyForDynamicParam(paramValue, renderedSearch) {
|
|
// This needs to match the logic in get-dynamic-param.ts, until we're able to
|
|
// unify the various implementations so that these are always computed on
|
|
// the client.
|
|
if (typeof paramValue === 'string') {
|
|
// TODO: Refactor or remove this helper function to accept a string rather
|
|
// than the whole segment type. Also we can probably just append the
|
|
// search string instead of turning it into JSON.
|
|
const pageSegmentWithSearchParams = (0, _segment.addSearchParamsIfPageSegment)(paramValue, Object.fromEntries(new URLSearchParams(renderedSearch)));
|
|
return pageSegmentWithSearchParams;
|
|
} else if (paramValue === null) {
|
|
return '';
|
|
} else {
|
|
return paramValue.join('/');
|
|
}
|
|
}
|
|
function urlToUrlWithoutFlightMarker(url) {
|
|
const urlWithoutFlightParameters = new URL(url);
|
|
urlWithoutFlightParameters.searchParams.delete(_approuterheaders.NEXT_RSC_UNION_QUERY);
|
|
if (process.env.NODE_ENV === 'production') {
|
|
if (process.env.__NEXT_CONFIG_OUTPUT === 'export' && urlWithoutFlightParameters.pathname.endsWith('.txt')) {
|
|
const { pathname } = urlWithoutFlightParameters;
|
|
const length = pathname.endsWith('/index.txt') ? 10 : 4;
|
|
// Slice off `/index.txt` or `.txt` from the end of the pathname
|
|
urlWithoutFlightParameters.pathname = pathname.slice(0, -length);
|
|
}
|
|
}
|
|
return urlWithoutFlightParameters;
|
|
}
|
|
function getParamValueFromCacheKey(paramCacheKey, paramType) {
|
|
// Turn the cache key string sent by the server (as part of FlightRouterState)
|
|
// into a value that can be passed to `useParams` and client components.
|
|
const isCatchAll = paramType === 'c' || paramType === 'oc';
|
|
if (isCatchAll) {
|
|
// Catch-all param keys are a concatenation of the path segments.
|
|
// See equivalent logic in `getSelectedParams`.
|
|
// TODO: We should just pass the array directly, rather than concatenate
|
|
// it to a string and then split it back to an array. It needs to be an
|
|
// array in some places, like when passing a key React, but we can convert
|
|
// it at runtime in those places.
|
|
return paramCacheKey.split('/');
|
|
}
|
|
return paramCacheKey;
|
|
}
|
|
|
|
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
|
|
Object.defineProperty(exports.default, '__esModule', { value: true });
|
|
Object.assign(exports.default, exports);
|
|
module.exports = exports.default;
|
|
}
|
|
|
|
//# sourceMappingURL=route-params.js.map
|