From 6ab37a60fcc9c054dc278b2115399939b945e541 Mon Sep 17 00:00:00 2001 From: Aditya kumar singh <143548997+Adityakk9031@users.noreply.github.com> Date: Sun, 12 Jul 2026 16:59:40 +0530 Subject: [PATCH 1/3] fix(convert): resolve directory pruning failure on Windows due to path separator mismatches --- packages/leadtype/src/convert/convert.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/leadtype/src/convert/convert.ts b/packages/leadtype/src/convert/convert.ts index ff33e4a4..242ec05c 100644 --- a/packages/leadtype/src/convert/convert.ts +++ b/packages/leadtype/src/convert/convert.ts @@ -1272,7 +1272,9 @@ 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 = new Set( + orphans.map((filePath) => resolve(dirname(filePath))) + ); for (let dir of parents) { while (dir !== resolvedOutDir && dir.startsWith(resolvedOutDir + sep)) { try { @@ -1280,7 +1282,7 @@ async function pruneOrphanedOutputs( } catch { break; } - dir = dirname(dir); + dir = resolve(dirname(dir)); } } From ea63aa0263523e5dbd09c60491c93c88870d9260 Mon Sep 17 00:00:00 2001 From: Aditya kumar singh <143548997+Adityakk9031@users.noreply.github.com> Date: Sun, 12 Jul 2026 18:30:51 +0530 Subject: [PATCH 2/3] refactor(convert): remove redundant resolve call in directory prune loop --- packages/leadtype/src/convert/convert.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/leadtype/src/convert/convert.ts b/packages/leadtype/src/convert/convert.ts index 242ec05c..bd1196f6 100644 --- a/packages/leadtype/src/convert/convert.ts +++ b/packages/leadtype/src/convert/convert.ts @@ -1282,7 +1282,7 @@ async function pruneOrphanedOutputs( } catch { break; } - dir = resolve(dirname(dir)); + dir = dirname(dir); } } From 3311f2563bb1469e9313b3c8feee8c48cf5ac075 Mon Sep 17 00:00:00 2001 From: Kaylee <65376239+KayleeWilliams@users.noreply.github.com> Date: Wed, 15 Jul 2026 11:05:01 +0100 Subject: [PATCH 3/3] test(convert): cover Windows prune paths --- .changeset/fuzzy-dodos-prune.md | 5 +++++ packages/leadtype/src/convert/convert.test.ts | 13 +++++++++++++ packages/leadtype/src/convert/convert.ts | 19 ++++++++++++++++--- 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 .changeset/fuzzy-dodos-prune.md 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 bd1196f6..7fb9078a 100644 --- a/packages/leadtype/src/convert/convert.ts +++ b/packages/leadtype/src/convert/convert.ts @@ -1272,9 +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) => resolve(dirname(filePath))) - ); + const parents = resolvePruneParentDirectories(orphans); for (let dir of parents) { while (dir !== resolvedOutDir && dir.startsWith(resolvedOutDir + sep)) { try { @@ -1289,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).