| Server IP : 13.235.167.51 / Your IP : 216.73.217.116 Web Server : Apache System : Linux machinox-server 6.17.0-1013-aws #13~24.04.1-Ubuntu SMP Fri Apr 24 21:36:58 UTC 2026 aarch64 User : root ( 0) PHP Version : 8.2.29 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/control.machinox.in/node_modules/next/dist/esm/build/ |
Upload File : |
{"version":3,"sources":["../../../src/build/validate-app-paths.ts"],"sourcesContent":["import {\n getParamProperties,\n type SegmentParam,\n} from '../shared/lib/router/utils/get-segment-param'\nimport {\n isInterceptionAppRoute,\n parseAppRoute,\n type NormalizedAppRoute,\n type NormalizedAppRouteSegment,\n} from '../shared/lib/router/routes/app'\n\n/**\n * Validates segment parameters for common syntax errors.\n * Based on validation logic from sorted-routes.ts\n */\nfunction validateSegmentParam(param: SegmentParam, pathname: string): void {\n // Check for empty parameter names\n if (param.paramName.length === 0) {\n throw new Error(`Parameter names cannot be empty in route \"${pathname}\".`)\n }\n\n // Check for three-dot character (…) instead of ...\n if (param.paramName.includes('…')) {\n throw new Error(\n `Detected a three-dot character ('…') in parameter \"${param.paramName}\" in route \"${pathname}\". Did you mean ('...')?`\n )\n }\n\n // Check for optional non-catch-all segments (not yet supported)\n if (\n param.paramType !== 'optional-catchall' &&\n param.paramName.startsWith('[') &&\n param.paramName.endsWith(']')\n ) {\n throw new Error(\n `Optional route parameters are not yet supported (\"[${param.paramName}]\") in route \"${pathname}\".`\n )\n }\n\n // Check for extra brackets\n if (param.paramName.startsWith('[') || param.paramName.endsWith(']')) {\n throw new Error(\n `Segment names may not start or end with extra brackets ('${param.paramName}') in route \"${pathname}\".`\n )\n }\n\n // Check for erroneous periods\n if (param.paramName.startsWith('.')) {\n throw new Error(\n `Segment names may not start with erroneous periods ('${param.paramName}') in route \"${pathname}\".`\n )\n }\n}\n\n/**\n * Validates a Route object for internal consistency.\n * Checks for duplicate slugs, invalid catch-all placement, and other route errors.\n * For interception routes, validates both the intercepting and intercepted routes separately.\n * Returns the validated segment parameters.\n */\nfunction validateAppRoute(route: NormalizedAppRoute): void {\n // For interception routes, validate the intercepting and intercepted routes separately\n // This allows the same parameter name to appear in both parts\n if (isInterceptionAppRoute(route)) {\n validateAppRoute(route.interceptingRoute)\n validateAppRoute(route.interceptedRoute)\n return\n }\n\n // Then validate semantic constraints (duplicates, normalization, positioning)\n const slugNames = new Set<string>()\n const normalizedSegments = new Set<string>()\n let hasCatchAll = false\n let hasOptionalCatchAllInPath = false\n let catchAllPosition = -1\n\n for (let i = 0; i < route.segments.length; i++) {\n const segment = route.segments[i]\n\n // Type narrowing - only process dynamic segments\n if (segment.type === 'dynamic') {\n // First, validate syntax\n validateSegmentParam(segment.param, route.pathname)\n\n const properties = getParamProperties(segment.param.paramType)\n\n if (properties.repeat) {\n if (properties.optional) {\n hasOptionalCatchAllInPath = true\n } else {\n hasCatchAll = true\n }\n\n catchAllPosition = i\n }\n\n // Check to see if the parameter name is already in use.\n if (slugNames.has(segment.param.paramName)) {\n throw new Error(\n `You cannot have the same slug name \"${segment.param.paramName}\" repeat within a single dynamic path in route \"${route.pathname}\".`\n )\n }\n\n // Normalize parameter name for comparison by removing all non-word\n // characters.\n const normalizedSegment = segment.param.paramName.replace(/\\W/g, '')\n if (normalizedSegments.has(normalizedSegment)) {\n const existing = Array.from(slugNames).find((s) => {\n return s.replace(/\\W/g, '') === normalizedSegment\n })\n throw new Error(\n `You cannot have the slug names \"${existing}\" and \"${segment.param.paramName}\" differ only by non-word symbols within a single dynamic path in route \"${route.pathname}\".`\n )\n }\n\n slugNames.add(segment.param.paramName)\n normalizedSegments.add(normalizedSegment)\n }\n\n // Check if catch-all is not at the end\n if (hasCatchAll && i > catchAllPosition) {\n throw new Error(\n `Catch-all must be the last part of the URL in route \"${route.pathname}\".`\n )\n }\n if (hasOptionalCatchAllInPath && i > catchAllPosition) {\n throw new Error(\n `Optional catch-all must be the last part of the URL in route \"${route.pathname}\".`\n )\n }\n }\n\n // Check for both required and optional catch-all\n if (hasCatchAll && hasOptionalCatchAllInPath) {\n throw new Error(\n `You cannot use both a required and optional catch-all route at the same level in route \"${route.pathname}\".`\n )\n }\n}\n\n/**\n * Validates a single path for internal consistency and returns its segment parameters.\n */\nfunction parseAndValidateAppPath(path: string): NormalizedAppRoute {\n // Fast parse the route information. We're expecting this to be a normalized\n // route, so we pass `true` to the `parseAppRoute` function.\n const route = parseAppRoute(path, true)\n\n // Slow walk the data from the route in order to validate it.\n validateAppRoute(route)\n\n return route\n}\n\n/**\n * Normalizes segments by replacing dynamic segment names with placeholders.\n * This allows us to compare routes for structural equivalence.\n * Preserves interception markers so that routes with different markers are not considered ambiguous.\n *\n * Examples:\n * - [slug] -> [*]\n * - [modalSlug] -> [*]\n * - [...slug] -> [...*]\n * - [[...slug]] -> [[...*]]\n * - (..)test -> (..)test\n * - (..)[slug] -> (..)[*]\n */\nfunction normalizeSegments(\n segments: readonly NormalizedAppRouteSegment[]\n): string {\n return (\n '/' +\n segments\n .map((segment) => {\n if (segment.type === 'static') {\n return segment.name\n }\n\n // Dynamic segment - normalize the parameter name by replacing the\n // parameter name with a wildcard. The interception marker is already\n // included in the segment name, so no special handling is needed.\n return segment.name.replace(segment.param.paramName, '*')\n })\n .join('/')\n )\n}\n\n/**\n * Validates that app paths don't create ambiguous routes.\n *\n * NOTE: The paths passed to this function should already have been normalized by normalizeAppPath,\n * which means parallel route segments (@modal, @sidebar, etc.) have been removed.\n *\n * This function performs two types of validation:\n * 1. Individual path validation (syntax, slug names, catch-all placement, etc.)\n * 2. Cross-path validation (ambiguous routes, conflicting patterns)\n *\n * @param appPaths - Array of normalized app router paths to validate\n * @returns Array of validated routes\n * @throws Error if validation fails\n */\nexport function validateAppPaths(\n appPaths: readonly string[]\n): NormalizedAppRoute[] {\n // First, validate each path individually\n const paramsByPath = new Map<string, NormalizedAppRoute>()\n for (const path of appPaths) {\n paramsByPath.set(path, parseAndValidateAppPath(path))\n }\n\n // Group paths by their normalized structure for ambiguity detection\n const structureMap = new Map<string, string[]>()\n\n for (const [path, route] of paramsByPath) {\n // Check if the last segment is an optional catch-all and check to see if\n // there is a route with the same specificity that conflicts with it.\n const lastSegment = route.segments[route.segments.length - 1]\n if (\n lastSegment?.type === 'dynamic' &&\n lastSegment.param.paramType === 'optional-catchall'\n ) {\n const prefixSegments = route.segments.slice(0, -1)\n const normalizedPrefix = normalizeSegments(prefixSegments)\n\n for (const [appPath, appRoute] of paramsByPath) {\n const normalizedAppPath = normalizeSegments(appRoute.segments)\n\n // Special case: root-level optional catch-all\n // /[[...slug]] has prefix '' which should match '/'\n if (prefixSegments.length === 0 && appPath === '/') {\n throw new Error(\n `You cannot define a route with the same specificity as an optional catch-all route (\"${appPath}\" and \"/[[...${lastSegment.param.paramName}]]\").`\n )\n }\n\n // General case: compare normalized structures\n if (normalizedAppPath === normalizedPrefix) {\n throw new Error(\n `You cannot define a route with the same specificity as an optional catch-all route (\"${appPath}\" and \"${normalizedPrefix}/[[...${lastSegment.param.paramName}]]\").`\n )\n }\n }\n }\n\n // Normalize the route to get its structure\n const structure = normalizeSegments(route.segments)\n\n // Track which paths map to this structure\n const existingPaths = structureMap.get(structure) ?? []\n existingPaths.push(path)\n structureMap.set(structure, existingPaths)\n }\n\n // Check for ambiguous routes (different slug names, same structure)\n const conflicts: Array<{ paths: string[]; normalizedPath: string }> = []\n\n for (const [structure, paths] of structureMap) {\n if (paths.length > 1) {\n // Multiple paths map to the same structure - this is ambiguous\n conflicts.push({\n paths,\n normalizedPath: structure,\n })\n }\n }\n\n if (conflicts.length > 0) {\n const errorMessages = conflicts.map(({ paths, normalizedPath }) => {\n const pathsList = paths.map((p) => ` - ${p}`).join('\\n')\n return `Ambiguous route pattern \"${normalizedPath}\" matches multiple routes:\\n${pathsList}`\n })\n\n throw new Error(\n `Ambiguous app routes detected:\\n\\n${errorMessages.join('\\n\\n')}\\n\\n` +\n `These routes cannot be distinguished from each other when matching URLs. ` +\n `Please ensure that dynamic segments have unique patterns or use different static segments.`\n )\n }\n\n return Array.from(paramsByPath.values())\n}\n"],"names":["getParamProperties","isInterceptionAppRoute","parseAppRoute","validateSegmentParam","param","pathname","paramName","length","Error","includes","paramType","startsWith","endsWith","validateAppRoute","route","interceptingRoute","interceptedRoute","slugNames","Set","normalizedSegments","hasCatchAll","hasOptionalCatchAllInPath","catchAllPosition","i","segments","segment","type","properties","repeat","optional","has","normalizedSegment","replace","existing","Array","from","find","s","add","parseAndValidateAppPath","path","normalizeSegments","map","name","join","validateAppPaths","appPaths","paramsByPath","Map","set","structureMap","lastSegment","prefixSegments","slice","normalizedPrefix","appPath","appRoute","normalizedAppPath","structure","existingPaths","get","push","conflicts","paths","normalizedPath","errorMessages","pathsList","p","values"],"mappings":"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","ignoreList":[0]}