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>
1 line
No EOL
12 KiB
Text
1 line
No EOL
12 KiB
Text
{"version":3,"sources":["../../../../../src/shared/lib/router/utils/get-dynamic-param.ts"],"sourcesContent":["import type { DynamicParam } from '../../../../server/app-render/app-render'\nimport type { LoaderTree } from '../../../../server/lib/app-dir-module'\nimport type { OpaqueFallbackRouteParams } from '../../../../server/request/fallback-params'\nimport type { Params } from '../../../../server/request/params'\nimport type { DynamicParamTypesShort } from '../../app-router-types'\nimport { InvariantError } from '../../invariant-error'\nimport { parseLoaderTree } from './parse-loader-tree'\nimport { getSegmentParam } from './get-segment-param'\n\n/**\n * Gets the value of a param from the params object. This correctly handles the\n * case where the param is a fallback route param and encodes the resulting\n * value.\n *\n * @param interpolatedParams - The params object.\n * @param segmentKey - The key of the segment.\n * @param fallbackRouteParams - The fallback route params.\n * @returns The value of the param.\n */\nfunction getParamValue(\n interpolatedParams: Params,\n segmentKey: string,\n fallbackRouteParams: OpaqueFallbackRouteParams | null\n) {\n let value = interpolatedParams[segmentKey]\n\n if (fallbackRouteParams?.has(segmentKey)) {\n // We know that the fallback route params has the segment key because we\n // checked that above.\n const [searchValue] = fallbackRouteParams.get(segmentKey)!\n value = searchValue\n } else if (Array.isArray(value)) {\n value = value.map((i) => encodeURIComponent(i))\n } else if (typeof value === 'string') {\n value = encodeURIComponent(value)\n }\n\n return value\n}\n\nexport function interpolateParallelRouteParams(\n loaderTree: LoaderTree,\n params: Params,\n pagePath: string,\n fallbackRouteParams: OpaqueFallbackRouteParams | null\n) {\n const interpolated = structuredClone(params)\n\n // Stack-based traversal with depth tracking\n const stack: Array<{ tree: LoaderTree; depth: number }> = [\n { tree: loaderTree, depth: 0 },\n ]\n\n // Derive value from pagePath based on depth and parameter type\n const pathSegments = pagePath.split('/').slice(1) // Remove first empty string\n\n while (stack.length > 0) {\n const { tree, depth } = stack.pop()!\n const { segment, parallelRoutes } = parseLoaderTree(tree)\n\n // Check if current segment contains a parameter\n const segmentParam = getSegmentParam(segment)\n if (\n segmentParam &&\n !interpolated.hasOwnProperty(segmentParam.param) &&\n // If the param is in the fallback route params, we don't need to\n // interpolate it because it's already marked as being unknown.\n !fallbackRouteParams?.has(segmentParam.param)\n ) {\n switch (segmentParam.type) {\n case 'catchall':\n case 'optional-catchall':\n case 'catchall-intercepted':\n // For catchall parameters, take all remaining segments from this depth\n const remainingSegments = pathSegments.slice(depth)\n\n // Process each segment to handle any dynamic params\n const processedSegments = remainingSegments\n .flatMap((pathSegment) => {\n const param = getSegmentParam(pathSegment)\n // If the segment matches a param, return the param value otherwise,\n // it's a static segment, so just return that. We don't use the\n // `getParamValue` function here because we don't want the values to\n // be encoded, that's handled on get by the `getDynamicParam`\n // function.\n return param ? interpolated[param.param] : pathSegment\n })\n .filter((s) => s !== undefined)\n\n if (processedSegments.length > 0) {\n interpolated[segmentParam.param] = processedSegments\n }\n break\n case 'dynamic':\n case 'dynamic-intercepted':\n // For regular dynamic parameters, take the segment at this depth\n if (depth < pathSegments.length) {\n const pathSegment = pathSegments[depth]\n const param = getSegmentParam(pathSegment)\n\n interpolated[segmentParam.param] = param\n ? interpolated[param.param]\n : pathSegment\n }\n break\n default:\n segmentParam.type satisfies never\n }\n }\n\n // Calculate next depth - increment if this is not a route group and not empty\n let nextDepth = depth\n const isRouteGroup = segment.startsWith('(') && segment.endsWith(')')\n if (!isRouteGroup && segment !== '') {\n nextDepth++\n }\n\n // Add all parallel routes to the stack for processing\n for (const route of Object.values(parallelRoutes)) {\n stack.push({ tree: route, depth: nextDepth })\n }\n }\n\n return interpolated\n}\n\n/**\n *\n * Shared logic on client and server for creating a dynamic param value.\n *\n * This code needs to be shared with the client so it can extract dynamic route\n * params from the URL without a server request.\n *\n * Because everything in this module is sent to the client, we should aim to\n * keep this code as simple as possible. The special case handling for catchall\n * and optional is, alas, unfortunate.\n */\nexport function getDynamicParam(\n interpolatedParams: Params,\n segmentKey: string,\n dynamicParamType: DynamicParamTypesShort,\n fallbackRouteParams: OpaqueFallbackRouteParams | null\n): DynamicParam {\n let value: string | string[] | undefined = getParamValue(\n interpolatedParams,\n segmentKey,\n fallbackRouteParams\n )\n\n // handle the case where an optional catchall does not have a value,\n // e.g. `/dashboard/[[...slug]]` when requesting `/dashboard`\n if (!value || value.length === 0) {\n if (dynamicParamType === 'oc') {\n return {\n param: segmentKey,\n value: null,\n type: dynamicParamType,\n treeSegment: [segmentKey, '', dynamicParamType],\n }\n }\n\n throw new InvariantError(\n `Missing value for segment key: \"${segmentKey}\" with dynamic param type: ${dynamicParamType}`\n )\n }\n\n return {\n param: segmentKey,\n // The value that is passed to user code.\n value,\n // The value that is rendered in the router tree.\n treeSegment: [\n segmentKey,\n Array.isArray(value) ? value.join('/') : value,\n dynamicParamType,\n ],\n type: dynamicParamType,\n }\n}\n\n/**\n * Regular expression pattern used to match route parameters.\n * Matches both single parameters and parameter groups.\n * Examples:\n * - `[[...slug]]` matches parameter group with key 'slug', repeat: true, optional: true\n * - `[...slug]` matches parameter group with key 'slug', repeat: true, optional: false\n * - `[[foo]]` matches parameter with key 'foo', repeat: false, optional: true\n * - `[bar]` matches parameter with key 'bar', repeat: false, optional: false\n */\nexport const PARAMETER_PATTERN = /^([^[]*)\\[((?:\\[[^\\]]*\\])|[^\\]]+)\\](.*)$/\n\n/**\n * Parses a given parameter from a route to a data structure that can be used\n * to generate the parametrized route.\n * Examples:\n * - `[[...slug]]` -> `{ key: 'slug', repeat: true, optional: true }`\n * - `[...slug]` -> `{ key: 'slug', repeat: true, optional: false }`\n * - `[[foo]]` -> `{ key: 'foo', repeat: false, optional: true }`\n * - `[bar]` -> `{ key: 'bar', repeat: false, optional: false }`\n * - `fizz` -> `{ key: 'fizz', repeat: false, optional: false }`\n * @param param - The parameter to parse.\n * @returns The parsed parameter as a data structure.\n */\nexport function parseParameter(param: string) {\n const match = param.match(PARAMETER_PATTERN)\n\n if (!match) {\n return parseMatchedParameter(param)\n }\n\n return parseMatchedParameter(match[2])\n}\n\n/**\n * Parses a matched parameter from the PARAMETER_PATTERN regex to a data structure that can be used\n * to generate the parametrized route.\n * Examples:\n * - `[...slug]` -> `{ key: 'slug', repeat: true, optional: true }`\n * - `...slug` -> `{ key: 'slug', repeat: true, optional: false }`\n * - `[foo]` -> `{ key: 'foo', repeat: false, optional: true }`\n * - `bar` -> `{ key: 'bar', repeat: false, optional: false }`\n * @param param - The matched parameter to parse.\n * @returns The parsed parameter as a data structure.\n */\nexport function parseMatchedParameter(param: string) {\n const optional = param.startsWith('[') && param.endsWith(']')\n if (optional) {\n param = param.slice(1, -1)\n }\n const repeat = param.startsWith('...')\n if (repeat) {\n param = param.slice(3)\n }\n return { key: param, repeat, optional }\n}\n"],"names":["InvariantError","parseLoaderTree","getSegmentParam","getParamValue","interpolatedParams","segmentKey","fallbackRouteParams","value","has","searchValue","get","Array","isArray","map","i","encodeURIComponent","interpolateParallelRouteParams","loaderTree","params","pagePath","interpolated","structuredClone","stack","tree","depth","pathSegments","split","slice","length","pop","segment","parallelRoutes","segmentParam","hasOwnProperty","param","type","remainingSegments","processedSegments","flatMap","pathSegment","filter","s","undefined","nextDepth","isRouteGroup","startsWith","endsWith","route","Object","values","push","getDynamicParam","dynamicParamType","treeSegment","join","PARAMETER_PATTERN","parseParameter","match","parseMatchedParameter","optional","repeat","key"],"mappings":"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","ignoreList":[0]} |