UNPKG

@mui/internal-docs-infra

Version:

MUI Infra - internal documentation creation tools.

101 lines (87 loc) 4.11 kB
import { createSyntheticDirectories, buildPath } from "./pathUtils.mjs"; export function calculateMainFilePath(url, maxBackNav, maxSourceBackNav, metadataPrefix, fileName) { // Handle optional parameters with defaults const actualMaxSourceBackNav = maxSourceBackNav ?? maxBackNav; const actualMetadataPrefix = metadataPrefix ?? ''; // Handle empty URL if (!url) { return ''; } // Extract URL parts and filename let urlSegments; let filename; let hasTrailingSlash = false; try { // Try to parse as URL first const urlObj = new URL(url); hasTrailingSlash = urlObj.pathname.endsWith('/'); const pathSegments = urlObj.pathname.split('/').filter(Boolean); let baseFilename; if (hasTrailingSlash) { // If URL ends with /, there's no filename - all segments are path segments baseFilename = ''; urlSegments = pathSegments; } else { // Normal case - last segment is the filename baseFilename = pathSegments.pop() || ''; urlSegments = pathSegments; } // Use provided fileName or preserve query and hash from URL if (fileName !== undefined) { filename = fileName; } else { filename = baseFilename + urlObj.search + urlObj.hash; if (hasTrailingSlash && !baseFilename) { filename = `${filename}/`; } } } catch { // Fallback to simple string parsing for relative paths hasTrailingSlash = url.endsWith('/'); const urlParts = url.split('/'); let baseFilename; if (hasTrailingSlash) { // If URL ends with /, there's no filename - all segments are path segments baseFilename = urlParts.pop() || ''; // Remove the empty string after trailing slash urlSegments = urlParts.filter(part => part !== ''); // Remove empty segments } else { // Normal case - last segment is the filename baseFilename = urlParts.pop() || ''; urlSegments = urlParts.filter(part => part !== ''); // Remove empty segments } // Use provided fileName or fallback to extracted baseFilename if (fileName !== undefined) { filename = fileName; } else { filename = baseFilename; if (hasTrailingSlash && !baseFilename) { filename = `${filename}/`; } } } // Work with a copy of URL segments to avoid mutations const remainingUrlSegments = [...urlSegments]; // Take actualMaxSourceBackNav items from the end for sourcePath const sourcePath = remainingUrlSegments.splice(-actualMaxSourceBackNav, actualMaxSourceBackNav); // Calculate unhandledBackNav, accounting for missing sourcePath segments let unhandledBackNav = maxBackNav - actualMaxSourceBackNav; // Add any missing sourcePath segments to unhandledBackNav const missingSourcePathSegments = actualMaxSourceBackNav - sourcePath.length; unhandledBackNav += missingSourcePathSegments; // Split actualMetadataPrefix and subtract that count from unhandledBackNav const metadataPrefixSegments = actualMetadataPrefix.split('/').filter(part => part !== ''); unhandledBackNav -= metadataPrefixSegments.length; // Calculate metadataPath from remaining URL segments (what's left after sourcePath) const metadataSegmentsNeeded = Math.max(0, unhandledBackNav); const metadataSegmentsAvailable = Math.min(metadataSegmentsNeeded, remainingUrlSegments.length); const metadataPath = remainingUrlSegments.splice(-metadataSegmentsAvailable, metadataSegmentsAvailable); // Update unhandledBackNav with segments we couldn't fulfill from URL unhandledBackNav = metadataSegmentsNeeded - metadataSegmentsAvailable; // Create synthetic directories for any remaining unhandledBackNav const syntheticDirs = createSyntheticDirectories(unhandledBackNav); // Combine all parts to create the final path using buildPath utility // Order: [synthetic directories] + [metadataPath] + [metadataPrefix] + [sourcePath] + [filename] const path = buildPath(syntheticDirs, metadataPath, metadataPrefixSegments, sourcePath, filename); // Return as file:// URL unless the result is empty return path ? `file:///${path}` : path; }