UNPKG

next

Version:

The React Framework

196 lines (195 loc) • 7.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); 0 && (module.exports = { PARAMETER_PATTERN: null, getDynamicParam: null, interpolateParallelRouteParams: null, parseMatchedParameter: null, parseParameter: null }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { PARAMETER_PATTERN: function() { return PARAMETER_PATTERN; }, getDynamicParam: function() { return getDynamicParam; }, interpolateParallelRouteParams: function() { return interpolateParallelRouteParams; }, parseMatchedParameter: function() { return parseMatchedParameter; }, parseParameter: function() { return parseParameter; } }); const _invarianterror = require("../../invariant-error"); const _parseloadertree = require("./parse-loader-tree"); const _getsegmentparam = require("./get-segment-param"); /** * Gets the value of a param from the params object. This correctly handles the * case where the param is a fallback route param and encodes the resulting * value. * * @param interpolatedParams - The params object. * @param segmentKey - The key of the segment. * @param fallbackRouteParams - The fallback route params. * @returns The value of the param. */ function getParamValue(interpolatedParams, segmentKey, fallbackRouteParams) { let value = interpolatedParams[segmentKey]; if (fallbackRouteParams?.has(segmentKey)) { // We know that the fallback route params has the segment key because we // checked that above. const [searchValue] = fallbackRouteParams.get(segmentKey); value = searchValue; } else if (Array.isArray(value)) { value = value.map((i)=>encodeURIComponent(i)); } else if (typeof value === 'string') { value = encodeURIComponent(value); } return value; } function interpolateParallelRouteParams(loaderTree, params, pagePath, fallbackRouteParams) { const interpolated = structuredClone(params); // Stack-based traversal with depth tracking const stack = [ { tree: loaderTree, depth: 0 } ]; // Derive value from pagePath based on depth and parameter type const pathSegments = pagePath.split('/').slice(1) // Remove first empty string ; while(stack.length > 0){ const { tree, depth } = stack.pop(); const { segment, parallelRoutes } = (0, _parseloadertree.parseLoaderTree)(tree); // Check if current segment contains a parameter const segmentParam = (0, _getsegmentparam.getSegmentParam)(segment); if (segmentParam && !interpolated.hasOwnProperty(segmentParam.param) && // If the param is in the fallback route params, we don't need to // interpolate it because it's already marked as being unknown. !fallbackRouteParams?.has(segmentParam.param)) { switch(segmentParam.type){ case 'catchall': case 'optional-catchall': case 'catchall-intercepted-(..)(..)': case 'catchall-intercepted-(.)': case 'catchall-intercepted-(..)': case 'catchall-intercepted-(...)': // For catchall parameters, take all remaining segments from this depth const remainingSegments = pathSegments.slice(depth); // Process each segment to handle any dynamic params const processedSegments = remainingSegments.flatMap((pathSegment)=>{ const param = (0, _getsegmentparam.getSegmentParam)(pathSegment); // If the segment matches a param, return the param value otherwise, // it's a static segment, so just return that. We don't use the // `getParamValue` function here because we don't want the values to // be encoded, that's handled on get by the `getDynamicParam` // function. return param ? interpolated[param.param] : pathSegment; }).filter((s)=>s !== undefined); if (processedSegments.length > 0) { interpolated[segmentParam.param] = processedSegments; } break; case 'dynamic': case 'dynamic-intercepted-(..)(..)': case 'dynamic-intercepted-(.)': case 'dynamic-intercepted-(..)': case 'dynamic-intercepted-(...)': // For regular dynamic parameters, take the segment at this depth if (depth < pathSegments.length) { const pathSegment = pathSegments[depth]; const param = (0, _getsegmentparam.getSegmentParam)(pathSegment); interpolated[segmentParam.param] = param ? interpolated[param.param] : pathSegment; } break; default: segmentParam.type; } } // Calculate next depth - increment if this is not a route group and not empty let nextDepth = depth; const isRouteGroup = segment.startsWith('(') && segment.endsWith(')'); if (!isRouteGroup && segment !== '') { nextDepth++; } // Add all parallel routes to the stack for processing for (const route of Object.values(parallelRoutes)){ stack.push({ tree: route, depth: nextDepth }); } } return interpolated; } function getDynamicParam(interpolatedParams, segmentKey, dynamicParamType, fallbackRouteParams) { let value = getParamValue(interpolatedParams, segmentKey, fallbackRouteParams); // handle the case where an optional catchall does not have a value, // e.g. `/dashboard/[[...slug]]` when requesting `/dashboard` if (!value || value.length === 0) { if (dynamicParamType === 'oc') { return { param: segmentKey, value: null, type: dynamicParamType, treeSegment: [ segmentKey, '', dynamicParamType ] }; } throw Object.defineProperty(new _invarianterror.InvariantError(`Missing value for segment key: "${segmentKey}" with dynamic param type: ${dynamicParamType}`), "__NEXT_ERROR_CODE", { value: "E864", enumerable: false, configurable: true }); } return { param: segmentKey, // The value that is passed to user code. value, // The value that is rendered in the router tree. treeSegment: [ segmentKey, Array.isArray(value) ? value.join('/') : value, dynamicParamType ], type: dynamicParamType }; } const PARAMETER_PATTERN = /^([^[]*)\[((?:\[[^\]]*\])|[^\]]+)\](.*)$/; function parseParameter(param) { const match = param.match(PARAMETER_PATTERN); if (!match) { return parseMatchedParameter(param); } return parseMatchedParameter(match[2]); } function parseMatchedParameter(param) { const optional = param.startsWith('[') && param.endsWith(']'); if (optional) { param = param.slice(1, -1); } const repeat = param.startsWith('...'); if (repeat) { param = param.slice(3); } return { key: param, repeat, optional }; } //# sourceMappingURL=get-dynamic-param.js.map