UNPKG

next

Version:

The React Framework

176 lines (174 loc) • 8.26 kB
"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