Next.js website for Rocky Mountain Vending company featuring: - Product catalog with Stripe integration - Service areas and parts pages - Admin dashboard with Clerk authentication - SEO optimized pages with JSON-LD structured data Co-authored-by: Cursor <cursoragent@cursor.com>
103 lines
No EOL
5.5 KiB
Text
103 lines
No EOL
5.5 KiB
Text
import { collectFallbackRouteParams } from '../../build/segment-config/app/app-segments';
|
|
import { InvariantError } from '../../shared/lib/invariant-error';
|
|
import { getRouteMatcher } from '../../shared/lib/router/utils/route-matcher';
|
|
import { getRouteRegex } from '../../shared/lib/router/utils/route-regex';
|
|
import { dynamicParamTypes } from '../app-render/get-short-dynamic-param-type';
|
|
function getParamKeys(page) {
|
|
const pattern = getRouteRegex(page);
|
|
const matcher = getRouteMatcher(pattern);
|
|
// Get the default list of allowed params.
|
|
return Object.keys(matcher(page));
|
|
}
|
|
/**
|
|
* Creates an opaque fallback route params object from the fallback route params.
|
|
*
|
|
* @param fallbackRouteParams the fallback route params
|
|
* @returns the opaque fallback route params
|
|
*/ export function createOpaqueFallbackRouteParams(fallbackRouteParams) {
|
|
// If there are no fallback route params, we can return early.
|
|
if (fallbackRouteParams.length === 0) return null;
|
|
// As we're creating unique keys for each of the dynamic route params, we only
|
|
// need to generate a unique ID once per request because each of the keys will
|
|
// be also be unique.
|
|
const uniqueID = Math.random().toString(16).slice(2);
|
|
const keys = new Map();
|
|
// Generate a unique key for the fallback route param, if this key is found
|
|
// in the static output, it represents a bug in cache components.
|
|
for (const { paramName, paramType } of fallbackRouteParams){
|
|
keys.set(paramName, [
|
|
`%%drp:${paramName}:${uniqueID}%%`,
|
|
dynamicParamTypes[paramType]
|
|
]);
|
|
}
|
|
return keys;
|
|
}
|
|
/**
|
|
* Gets the fallback route params for a given page. This is an expensive
|
|
* operation because it requires parsing the loader tree to extract the fallback
|
|
* route params.
|
|
*
|
|
* @param page the page
|
|
* @param routeModule the route module
|
|
* @returns the opaque fallback route params
|
|
*/ export function getFallbackRouteParams(page, routeModule) {
|
|
// First, get the fallback route params based on the provided page.
|
|
const unknownParamKeys = new Set(getParamKeys(page));
|
|
// Needed when processing fallback route params for catchall routes in
|
|
// parallel segments, derive from pathname. This is similar to
|
|
// getDynamicParam's pagePath parsing logic.
|
|
const pathSegments = page.split('/').filter(Boolean);
|
|
const collected = collectFallbackRouteParams(routeModule);
|
|
// Then, we have to get the fallback route params from the segments that are
|
|
// associated with parallel route segments.
|
|
const fallbackRouteParams = [];
|
|
for (const fallbackRouteParam of collected){
|
|
if (fallbackRouteParam.isParallelRouteParam) {
|
|
// Try to see if we can resolve this parameter from the page that was
|
|
// passed in.
|
|
if (unknownParamKeys.has(fallbackRouteParam.paramName)) {
|
|
continue;
|
|
}
|
|
if (fallbackRouteParam.paramType === 'optional-catchall' || fallbackRouteParam.paramType === 'catchall') {
|
|
// If there are any fallback route segments then we can't use the
|
|
// pathname to derive the value because it's not complete. We can
|
|
// make this assumption because the routes are always resolved left
|
|
// to right and the catchall is always the last segment, so any
|
|
// route parameters that are unknown will always contribute to the
|
|
// pathname and therefore the catchall param too.
|
|
if (collected.some((param)=>!param.isParallelRouteParam && unknownParamKeys.has(param.paramName))) {
|
|
fallbackRouteParams.push(fallbackRouteParam);
|
|
continue;
|
|
}
|
|
if (pathSegments.length === 0 && fallbackRouteParam.paramType !== 'optional-catchall') {
|
|
// We shouldn't be able to match a catchall segment without any path
|
|
// segments if it's not an optional catchall.
|
|
throw Object.defineProperty(new InvariantError(`Unexpected empty path segments match for a pathname "${page}" with param "${fallbackRouteParam.paramName}" of type "${fallbackRouteParam.paramType}"`), "__NEXT_ERROR_CODE", {
|
|
value: "E792",
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
}
|
|
// The path segments are not empty, and the segments didn't contain any
|
|
// unknown params, so we know that this particular fallback route param
|
|
// route param is not actually unknown, and is known. We can skip adding
|
|
// it to the fallback route params.
|
|
} else {
|
|
// This is some other type of route param that shouldn't get resolved
|
|
// statically.
|
|
throw Object.defineProperty(new InvariantError(`Unexpected match for a pathname "${page}" with a param "${fallbackRouteParam.paramName}" of type "${fallbackRouteParam.paramType}"`), "__NEXT_ERROR_CODE", {
|
|
value: "E791",
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
}
|
|
} else if (unknownParamKeys.has(fallbackRouteParam.paramName)) {
|
|
// As this is a non-parallel route segment, and it exists in the unknown
|
|
// param keys, we know it's a fallback route param.
|
|
fallbackRouteParams.push(fallbackRouteParam);
|
|
}
|
|
}
|
|
return createOpaqueFallbackRouteParams(fallbackRouteParams);
|
|
}
|
|
|
|
//# sourceMappingURL=fallback-params.js.map |