diff --git a/.changeset/fuzzy-dodos-prune.md b/.changeset/fuzzy-dodos-prune.md new file mode 100644 index 00000000..0cd376b0 --- /dev/null +++ b/.changeset/fuzzy-dodos-prune.md @@ -0,0 +1,5 @@ +--- +"leadtype": patch +--- + +Fix `convertAllMdx()` directory pruning on Windows by normalizing globbed paths before comparing them with the output directory. diff --git a/packages/leadtype/src/convert/convert.test.ts b/packages/leadtype/src/convert/convert.test.ts index 76065a15..2a057989 100644 --- a/packages/leadtype/src/convert/convert.test.ts +++ b/packages/leadtype/src/convert/convert.test.ts @@ -22,6 +22,7 @@ import { convertAllMdx, convertMdxFile, resolveMdxFrontmatter, + resolvePruneParentDirectories, } from "./convert"; const execFileAsync = promisify(execFile); @@ -82,6 +83,18 @@ afterEach(async () => { }); describe("convertAllMdx", () => { + it("normalizes glob paths before pruning directories on Windows", () => { + const parents = resolvePruneParentDirectories( + [ + "C:/repo/public/guides/orphan.md", + "C:\\repo\\public\\guides\\another-orphan.md", + ], + path.win32 + ); + + expect([...parents]).toEqual(["C:\\repo\\public\\guides"]); + }); + it("defaults to the framework-neutral docs directory", async () => { const projectDir = await createTempProject(); const previousCwd = process.cwd(); diff --git a/packages/leadtype/src/convert/convert.ts b/packages/leadtype/src/convert/convert.ts index ff33e4a4..7fb9078a 100644 --- a/packages/leadtype/src/convert/convert.ts +++ b/packages/leadtype/src/convert/convert.ts @@ -1272,7 +1272,7 @@ async function pruneOrphanedOutputs( // Deleting the last page of a section leaves an empty directory behind; // sweep upward until a non-empty parent (or outDir) stops the walk. const resolvedOutDir = resolve(outDir); - const parents = new Set(orphans.map((filePath) => dirname(filePath))); + const parents = resolvePruneParentDirectories(orphans); for (let dir of parents) { while (dir !== resolvedOutDir && dir.startsWith(resolvedOutDir + sep)) { try { @@ -1287,6 +1287,21 @@ async function pruneOrphanedOutputs( return orphans; } +interface PrunePathApi { + dirname: (filePath: string) => string; + resolve: (...paths: string[]) => string; +} + +/** Normalize glob output before comparing it with native filesystem paths. */ +export function resolvePruneParentDirectories( + filePaths: readonly string[], + pathApi: PrunePathApi = { dirname, resolve } +): Set { + return new Set( + filePaths.map((filePath) => pathApi.resolve(pathApi.dirname(filePath))) + ); +} + /** * Convert every .mdx file under srcDir to .md under outDir (preserving the * relative directory structure).