UNPKG

@entro314labs/starlight-document-converter

Version:

A comprehensive document converter for Astro Starlight that transforms various document formats into Starlight-compatible Markdown with proper frontmatter

175 lines (174 loc) 6.54 kB
import { boxes, createResultsTable, status } from "./chunk-RI3FHBT3.js"; // src/utils/cli-commands.ts import { readdir, readFile, writeFile } from "fs/promises"; import { dirname, join } from "path"; import { spinner } from "@clack/prompts"; import pc from "picocolors"; async function repairSingleFile(filePath, options) { const { FrontmatterRepair } = await import("./frontmatter-repair-JNEPELNZ.js"); const { LinkImageProcessor } = await import("./link-image-processor-5LK3OBO7.js"); const { TocGenerator } = await import("./toc-generator-XJPRHRCH.js"); const repairer = new FrontmatterRepair(); const linkProcessor = new LinkImageProcessor( dirname(filePath), options.output || dirname(filePath) ); const tocGenerator = new TocGenerator(); const content = await readFile(filePath, "utf-8"); const repairResult = repairer.repairFrontmatter(content, filePath); let processedContent = repairResult.repairedContent; let wasRepaired = repairResult.fixed; const issues = [...repairResult.issues]; if (options.fixLinks || options.processImages) { const { content: linkProcessedContent } = await linkProcessor.processContent( processedContent, filePath, filePath ); if (linkProcessedContent !== processedContent) { processedContent = linkProcessedContent; wasRepaired = true; issues.push("Processed links and images"); } } if (options.generateToc && !tocGenerator.hasExistingToc(processedContent)) { const tocContent = tocGenerator.insertTocIntoContent(processedContent); if (tocContent !== processedContent) { processedContent = tocContent; wasRepaired = true; issues.push("Added table of contents"); } } if (!options.dryRun && processedContent !== content) { await writeFile(filePath, processedContent, "utf-8"); } return { repaired: wasRepaired, issues }; } async function repairDirectory(inputPath, options) { const files = await readdir(inputPath, { recursive: true }); let totalRepaired = 0; let totalIssues = 0; let filesProcessed = 0; for (const file of files) { if (typeof file === "string" && (file.endsWith(".md") || file.endsWith(".mdx"))) { const filePath = join(inputPath, file); try { const result = await repairSingleFile(filePath, options); if (result.repaired) { totalRepaired++; totalIssues += result.issues.length; if (options.verbose) { console.log(` ${pc.cyan(file)}:`); result.issues.forEach((issue) => console.log(` \u2022 ${issue}`)); } } filesProcessed++; } catch (error) { console.warn(`Failed to process ${file}:`, error); } } } return { totalRepaired, totalIssues, filesProcessed }; } async function validateSingleFile(filePath, options) { const { FrontmatterRepair } = await import("./frontmatter-repair-JNEPELNZ.js"); const validator = new FrontmatterRepair(); const content = await readFile(filePath, "utf-8"); const validation = validator.validateContent(content, filePath); return { valid: validation.valid, validation }; } async function validateDirectory(inputPath, options) { const files = await readdir(inputPath, { recursive: true }); let totalFiles = 0; let validFiles = 0; let issueCount = 0; const allIssues = []; for (const file of files) { if (typeof file === "string" && (file.endsWith(".md") || file.endsWith(".mdx"))) { const filePath = join(inputPath, file); try { const result = await validateSingleFile(filePath, options); totalFiles++; if (result.valid) { validFiles++; } else { issueCount += result.validation.issues.filter((i) => i.type === "error").length; allIssues.push({ file, validation: result.validation }); } if (options.showDetails || !result.valid) { console.log( ` ${pc.cyan(file)}: ${result.valid ? pc.green("\u2705 Valid") : pc.red("\u274C Issues")}` ); if (result.validation.score) { const scoreColor = result.validation.score.overall === "good" ? pc.green : result.validation.score.overall === "fair" ? pc.yellow : pc.red; console.log(` Quality: ${scoreColor(result.validation.score.overall.toUpperCase())}`); } if (!result.valid && options.verbose) { result.validation.issues.forEach((issue) => { const icon = issue.type === "error" ? "\u274C" : issue.type === "warning" ? "\u26A0\uFE0F" : "\u2139\uFE0F"; console.log(` ${icon} ${issue.message}`); }); } } } catch (error) { console.warn(`Failed to validate ${file}:`, error); } } } return { totalFiles, validFiles, issueCount, allIssues }; } function showRepairResults(stats, options) { const table = createResultsTable({ filesProcessed: stats.filesProcessed, totalRepaired: stats.totalRepaired, totalIssues: stats.totalIssues }); const title = options.dryRun ? "Repair Analysis (Dry Run)" : "Repair Results"; const isDryRun = options.dryRun; const header = isDryRun ? boxes.warning( `${status.info("Analysis completed without making changes")} ${table.toString()}`, title ) : boxes.success(`${status.success("Files successfully repaired")} ${table.toString()}`, title); return header; } function showValidationResults(stats) { const successRate = stats.totalFiles > 0 ? Math.round(stats.validFiles / stats.totalFiles * 100) : 100; const table = createResultsTable({ totalFiles: stats.totalFiles, validFiles: stats.validFiles, issueCount: stats.issueCount }); const title = "Validation Results"; const header = successRate >= 90 ? boxes.success(`${status.success("Excellent content quality!")} ${table.toString()}`, title) : successRate >= 70 ? boxes.warning(`${status.warning("Some issues found")} ${table.toString()}`, title) : boxes.error( `${status.error("Multiple issues need attention")} ${table.toString()}`, title ); return header; } function createSpinner(message, dryRun = false) { const s = spinner(); const styledMessage = dryRun ? status.warning(`Analyzing: ${message}`) : status.processing(message); s.start(styledMessage); return s; } export { createSpinner, repairDirectory, repairSingleFile, showRepairResults, showValidationResults, validateDirectory, validateSingleFile }; //# sourceMappingURL=cli-commands-IAGYE2JW.js.map