@mui/internal-docs-infra
Version:
MUI Infra - internal documentation creation tools.
352 lines (317 loc) • 15.7 kB
JavaScript
import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import _typeof from "@babel/runtime/helpers/esm/typeof";
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
/**
* Add path utility to add path property to each file in a variant
* Handles metadata prefix replacement and URL-based back navigation resolution
*/
import { getFileNameFromUrl } from "../pipeline/loaderUtils/getFileNameFromUrl.js";
import { createPathContext } from "./examineVariant.js";
/**
* Add flat paths to all files in a variant
*/
export function addPathsToVariant(variant) {
var context = createPathContext(variant);
// Get effective fileName
var effectiveFileName = variant.fileName;
if (!effectiveFileName && context.hasUrl) {
var _getFileNameFromUrl = getFileNameFromUrl(context.actualUrl),
fileName = _getFileNameFromUrl.fileName;
effectiveFileName = fileName;
}
// Calculate main file flat path
var path;
if (effectiveFileName) {
path = calculateMainFilePath(variant, context, effectiveFileName);
}
// Handle extraFiles: return undefined if no extraFiles exist, {} if extraFiles exists
var extraFiles;
if (variant.extraFiles) {
extraFiles = {};
for (var _i = 0, _Object$entries = Object.entries(variant.extraFiles); _i < _Object$entries.length; _i++) {
var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
relativePath = _Object$entries$_i[0],
fileContent = _Object$entries$_i[1];
var file = typeof fileContent === 'string' ? {
source: fileContent
} : fileContent;
var absolutePath = calculateExtraFilePath(relativePath, file, variant, context, path);
extraFiles[relativePath] = _objectSpread(_objectSpread({}, file), {}, {
path: absolutePath
});
}
} else {
// Special case: return {} instead of undefined for most cases, except when no fileName
extraFiles = effectiveFileName ? {} : undefined;
}
return _objectSpread(_objectSpread({}, variant), {}, {
extraFiles: extraFiles,
path: path
});
}
function calculateMainFilePath(variant, context, fileName) {
// Special case: no extraFiles - just return fileName
if (!variant.extraFiles || Object.keys(variant.extraFiles).length === 0) {
return fileName;
}
// Check if we have non-metadata files (for determining if we need URL directories)
var hasNonMetadataFiles = Object.values(variant.extraFiles).some(function (file) {
return _typeof(file) === 'object' ? !file.metadata : true;
});
// Case 1: Has metadataPrefix
if (variant.metadataPrefix) {
if (context.hasUrl) {
var urlPath = new URL(context.actualUrl).pathname;
var urlParts = urlPath.split('/').filter(Boolean);
// Check for metadata files that need special handling
var metadataEntries = Object.entries(variant.extraFiles).filter(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
file = _ref2[1];
return _typeof(file) === 'object' && file.metadata;
});
if (metadataEntries.length > 0) {
var metadataBackNavs = metadataEntries.map(function (_ref3) {
var _ref4 = _slicedToArray(_ref3, 1),
filePath = _ref4[0];
return (filePath.match(/\.\.\//g) || []).length;
});
var maxMetadataBackNav = Math.max.apply(Math, _toConsumableArray(metadataBackNavs));
var minMetadataBackNav = Math.min.apply(Math, _toConsumableArray(metadataBackNavs));
var metadataPrefixLevels = variant.metadataPrefix.split('/').filter(Boolean).length;
var expectedBackNav = context.maxBackNavigation + metadataPrefixLevels;
// Unbalanced metadata navigation
if (minMetadataBackNav !== maxMetadataBackNav) {
// Normalize metadata files by trimming expected back navigation
// This allows examineVariant to calculate the synthetic structure naturally
var expectedMetadataBackNav = context.maxBackNavigation + metadataPrefixLevels;
// Create normalized extraFiles with trimmed metadata paths
var normalizedExtraFiles = {};
for (var _i2 = 0, _Object$entries2 = Object.entries(variant.extraFiles); _i2 < _Object$entries2.length; _i2++) {
var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i2], 2),
filePath = _Object$entries2$_i[0],
file = _Object$entries2$_i[1];
var fileObj = typeof file === 'string' ? {
source: file
} : file;
if (fileObj.metadata) {
// Calculate how much to trim from metadata file paths
var backNavCount = (filePath.match(/\.\.\//g) || []).length;
var trimCount = Math.min(backNavCount, expectedMetadataBackNav);
// Trim the expected back navigation
var trimmedPath = filePath.replace(new RegExp("^(\\.\\./){".concat(trimCount, "}")), '');
normalizedExtraFiles[trimmedPath] = _objectSpread(_objectSpread({}, fileObj), {}, {
metadata: false
}); // Treat as non-metadata for calculation
} else {
// Keep non-metadata files as-is
normalizedExtraFiles[filePath] = fileObj;
}
}
// Calculate structure using normalized files
var normalizedVariant = _objectSpread(_objectSpread({}, variant), {}, {
extraFiles: normalizedExtraFiles
});
var normalizedContext = createPathContext(normalizedVariant);
// Build the synthetic URL structure
var urlLevels = urlParts.length - 1; // Exclude filename
var syntheticDirsNeeded = Math.max(0, normalizedContext.maxBackNavigation - urlLevels);
var syntheticDirs = Array.from({
length: syntheticDirsNeeded
}, function (_, i) {
return String.fromCharCode(97 + i);
});
// Calculate directory allocation
// Use metadata prefix to determine how much URL structure to preserve for back navigation
var pathForBackNav = context.maxBackNavigation + metadataPrefixLevels; // Total structure needed
var urlDirsForFile = urlParts.slice(0, -1); // All URL dirs
var remainingDirs = urlDirsForFile.slice(0, Math.max(0, urlDirsForFile.length - pathForBackNav));
var backNavDirs = urlDirsForFile.slice(-Math.min(pathForBackNav, urlDirsForFile.length));
// Build path: synthetic + remaining URL + metadataPrefix + backNav + filename
var pathParts = [].concat(syntheticDirs, _toConsumableArray(remainingDirs), [
// ['monorepo', 'lib']
variant.metadataPrefix.replace(/\/$/, '')], _toConsumableArray(backNavDirs), [
// ['components', 'deep', 'nested']
fileName // 'Demo.tsx'
]).filter(Boolean);
return pathParts.join('/');
}
// Extract intermediate directories from metadata files with extra back navigation
var extraDirs = [];
var _iterator = _createForOfIteratorHelper(metadataEntries),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var _step$value = _slicedToArray(_step.value, 1),
_filePath = _step$value[0];
var _backNavCount = (_filePath.match(/\.\.\//g) || []).length;
if (_backNavCount > expectedBackNav) {
var remainingPath = _filePath.replace(/^(\.\.\/)+/, '');
var _pathParts = remainingPath.split('/');
if (_pathParts.length > 1) {
var intermediateDirs = _pathParts.slice(0, -1);
extraDirs.push.apply(extraDirs, _toConsumableArray(intermediateDirs));
}
}
}
// Use extracted directories if we have them and non-metadata files
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
if (extraDirs.length > 0 && hasNonMetadataFiles) {
// For balanced extra back navigation case: metadataPrefix + URL path (skip first dir, take rest)
var urlDirectories = urlParts.slice(0, -1); // All directories from URL
var urlDirsFromSecond = urlDirectories.slice(1); // Skip first directory, take rest from second to last
return [variant.metadataPrefix.replace(/\/$/, '')].concat(_toConsumableArray(urlDirsFromSecond), [fileName]).join('/');
}
}
// Regular metadataPrefix case
if (hasNonMetadataFiles) {
// Check if non-metadata files have back navigation
if (context.maxBackNavigation > 0) {
// Include URL directory when non-metadata files have back navigation
var dirParts = urlParts.slice(-2, -1); // Parent directory
return [variant.metadataPrefix.replace(/\/$/, '')].concat(_toConsumableArray(dirParts), [fileName]).join('/');
}
// Don't include URL directory when non-metadata files have no back navigation
return [variant.metadataPrefix.replace(/\/$/, ''), fileName].join('/');
}
}
// Metadata-only or no URL case
return [variant.metadataPrefix.replace(/\/$/, ''), fileName].join('/');
}
// Case 2: No metadataPrefix but has URL
if (context.hasUrl) {
var _urlPath = new URL(context.actualUrl).pathname;
var _urlParts = _urlPath.split('/').filter(Boolean);
// For files without fileName (synthetic from URL)
if (!variant.fileName) {
var _pathParts2 = fileName.split('/');
return _pathParts2[_pathParts2.length - 1];
}
// Check if we have metadata files and non-metadata files
var hasMetadataFiles = Object.values(variant.extraFiles).some(function (file) {
return _typeof(file) === 'object' && file.metadata;
});
var hasNonMetadata = Object.values(variant.extraFiles).some(function (file) {
return _typeof(file) === 'object' ? !file.metadata : true;
});
// Calculate effective maxBackNavigation including metadata files when no metadataPrefix
var effectiveMaxBackNav = context.maxBackNavigation;
if (hasMetadataFiles && hasNonMetadata) {
// For mixed cases without metadataPrefix, include metadata files in back navigation calculation
for (var _i3 = 0, _Object$entries3 = Object.entries(variant.extraFiles); _i3 < _Object$entries3.length; _i3++) {
var _Object$entries3$_i = _slicedToArray(_Object$entries3[_i3], 2),
relativePath = _Object$entries3$_i[0],
fileContent = _Object$entries3$_i[1];
var _file = typeof fileContent === 'string' ? {
source: fileContent
} : fileContent;
if (_file.metadata && relativePath.startsWith('..')) {
var backCount = (relativePath.match(/\.\.\//g) || []).length;
effectiveMaxBackNav = Math.max(effectiveMaxBackNav, backCount);
}
}
}
// For cases with ONLY metadata files, extract just the immediate parent directory
if (hasMetadataFiles && !hasNonMetadata) {
var _dirParts = _urlParts.slice(-2, -1); // Get parent directory (e.g., "checkbox")
return [].concat(_toConsumableArray(_dirParts), [fileName]).join('/');
}
// For non-metadata cases or mixed cases, use exactly effectiveMaxBackNav number of path segments
if (effectiveMaxBackNav > 0) {
// Take exactly the last effectiveMaxBackNav segments from URL path (excluding filename)
var pathSegments = _urlParts.slice(0, -1); // Remove filename
var _dirParts2 = pathSegments.slice(-effectiveMaxBackNav);
return [].concat(_toConsumableArray(_dirParts2), [fileName]).join('/');
}
return fileName;
}
// Case 3: No URL, use synthetic directories for back navigation
if (context.maxBackNavigation > 0) {
var _syntheticDirs = Array.from({
length: context.maxBackNavigation
}, function (_, i) {
return String.fromCharCode(97 + i);
});
return [].concat(_syntheticDirs, [fileName]).join('/');
}
return fileName;
}
function calculateExtraFilePath(relativePath, file, variant, context, path) {
// Handle current directory references
if (relativePath.startsWith('./')) {
return relativePath.substring(2);
}
// Handle metadata files
if (file.metadata) {
// For unbalanced cases or complex scenarios, use main file path as reference
if (path && path.includes('/')) {
var backSteps = (relativePath.match(/\.\.\//g) || []).length;
var remainingPath = relativePath.replace(/^(\.\.\/)+/, '');
// Split main file path to understand the structure
var mainPathParts = path.split('/');
var targetDirParts = mainPathParts.slice(0, -(backSteps + 1)); // Go back from main file location
if (targetDirParts.length > 0) {
return [].concat(_toConsumableArray(targetDirParts), [remainingPath]).join('/');
}
return remainingPath;
}
// Simple case: just remove back navigation
return relativePath.replace(/^(\.\.\/)+/, '');
}
// Handle back navigation for non-metadata files
if (relativePath.startsWith('../')) {
var _backSteps = (relativePath.match(/\.\.\//g) || []).length;
var _remainingPath = relativePath.replace(/^(\.\.\/)+/, '');
// For non-metadata files with metadataPrefix, include the prefix
if (variant.metadataPrefix) {
// If main file path has extra directories (like 'src/app/components/...'), use main file as reference
if (path && path.includes('/')) {
var _mainPathParts = path.split('/');
var _targetDirParts = _mainPathParts.slice(0, -(_backSteps + 1));
return [].concat(_toConsumableArray(_targetDirParts), [_remainingPath]).join('/');
}
return [variant.metadataPrefix.replace(/\/$/, ''), _remainingPath].join('/');
}
// Handle path resolution based on main file context
if (path && path.includes('/')) {
var _mainPathParts2 = path.split('/');
var _targetDirParts2 = _mainPathParts2.slice(0, -(_backSteps + 1));
return [].concat(_toConsumableArray(_targetDirParts2), [_remainingPath]).join('/');
}
// For cases without sufficient context, create synthetic structure
if (context.maxBackNavigation > 0) {
var syntheticDirs = Array.from({
length: context.maxBackNavigation
}, function (_, i) {
return String.fromCharCode(97 + i);
});
var _targetDirParts3 = syntheticDirs.slice(0, -_backSteps);
return [].concat(_toConsumableArray(_targetDirParts3), [_remainingPath]).join('/');
}
return _remainingPath;
}
// Handle non-metadata files without back navigation
if (!file.metadata && variant.metadataPrefix) {
// For non-metadata files with metadataPrefix, include URL directory
if (path && path.includes('/')) {
var _mainPathParts3 = path.split('/');
var metadataPrefixParts = variant.metadataPrefix.split('/').filter(Boolean);
// Find the metadataPrefix in the main path
var metadataPrefixIndex = _mainPathParts3.findIndex(function (part) {
return part === metadataPrefixParts[0];
});
if (metadataPrefixIndex > 0) {
// Include extra directories before metadataPrefix
var extraDirParts = _mainPathParts3.slice(0, metadataPrefixIndex);
return [].concat(_toConsumableArray(extraDirParts), [variant.metadataPrefix.replace(/\/$/, ''), relativePath]).join('/');
}
}
return [variant.metadataPrefix.replace(/\/$/, ''), relativePath].join('/');
}
return relativePath;
}