@signalwire/docusaurus-plugin-llms-txt
Version:
Generate Markdown versions of Docusaurus HTML pages and an llms.txt index file
107 lines (106 loc) • 3.89 kB
JavaScript
/**
* Comprehensive path utilities for directory setup and cross-platform operations
* Consolidates path handling logic from multiple modules for better maintainability
*/
import path from 'path';
import { normalizeUrl } from '@docusaurus/utils';
import { MD_EXTENSION } from '../constants';
/**
* Path management service that consolidates common path operations
* @internal
*/
export class PathManager {
constructor(siteDir, config, outDir) {
this.directories = setupDirectories(siteDir, config, outDir);
}
/** Get normalized relative HTML path */
getRelativeHtmlPath(fullHtmlPath) {
const relativePath = path.relative(this.directories.docsDir, fullHtmlPath);
return normalizeCrossPlatformPath(relativePath);
}
/** Get normalized relative markdown path */
getRelativeMarkdownPath(mdPath) {
const relativePath = path.relative(this.directories.mdOutDir, mdPath);
return normalizeCrossPlatformPath(relativePath);
}
}
/**
* Setup directory paths based on plugin configuration
* Simplified to use outDir directly without docsRoot/outputDir customization
* @internal
*
* @param siteDir - Site root directory
* @param config - Plugin configuration
* @param outDir - Build output directory (must be provided from Docusaurus)
* @returns Directory configuration object
*/
export function setupDirectories(siteDir, _config, outDir) {
// Use provided outDir from Docusaurus, no need to calculate from buildDir
if (!outDir) {
throw new Error(`outDir must be provided - this should come from Docusaurus postBuild context. ` +
`Received: siteDir="${siteDir}", outDir="${outDir}"`);
}
// Simplified: use outDir directly as both docsDir and mdOutDir
const docsDir = outDir;
const mdOutDir = outDir;
return {
siteDir,
outDir,
docsDir,
mdOutDir,
};
}
/**
* Build site URL from site configuration using Docusaurus normalizeUrl utility
* Centralizes the repeated site URL building pattern
* @internal
*
* @param siteConfig - Docusaurus site configuration
* @returns Complete site URL
*/
export function buildSiteUrl({ url, baseUrl, }) {
// Use Docusaurus's normalizeUrl for proper URL construction
return normalizeUrl([url, baseUrl]);
}
// === CROSS-PLATFORM PATH NORMALIZATION ===
// Consolidated from path-normalization.ts for better organization
/**
* Normalize path separators for cross-platform compatibility
* Replaces Windows backslashes with forward slashes
* @internal
*
* @param filePath - Path to normalize
* @returns Path with forward slashes
*/
export function normalizeCrossPlatformPath(filePath) {
return filePath.replace(/\\/g, '/');
}
// === HTML TO MARKDOWN PATH CONVERSION ===
// Consolidated from fs/path.ts
/**
* Convert a relative HTML path to its corresponding Markdown file path
* Uses Docusaurus-style path conversion logic
* @internal
*
* Examples:
* index.html → index.md
* blog/index.html → blog.md
* api/reference.html → api/reference.md
*/
export function htmlPathToMdPath(relHtmlPath, mdOutDir) {
// Handle index.html files - convert to directory name
const indexMatch = relHtmlPath.match(/^(.*)\/index\.html?$/i);
if (indexMatch) {
const dirPath = indexMatch[1] ?? '';
// For root index.html, use 'index.md', for others use 'dirname.md'
const mdFileName = dirPath === '' ? 'index' + MD_EXTENSION : dirPath + MD_EXTENSION;
return path.join(mdOutDir, mdFileName);
}
// Handle root index.html case (just "index.html")
if (relHtmlPath === 'index.html') {
return path.join(mdOutDir, 'index' + MD_EXTENSION);
}
// Handle regular HTML files - replace extension
const withoutExt = relHtmlPath.replace(/\.html?$/i, '');
return path.join(mdOutDir, withoutExt + MD_EXTENSION);
}