Skip to content

fix(core): strip trailing slash before .md check in toMarkdownPath#79

Merged
thepushkaraj merged 1 commit into
dodopayments:mainfrom
abhay-codes07:fix/tomarkdownpath-trailing-slash
Jul 23, 2026
Merged

fix(core): strip trailing slash before .md check in toMarkdownPath#79
thepushkaraj merged 1 commit into
dodopayments:mainfrom
abhay-codes07:fix/tomarkdownpath-trailing-slash

Conversation

@abhay-codes07

@abhay-codes07 abhay-codes07 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

toMarkdownPath ran its .md idempotency check before stripping trailing slashes, so a markdown path with a trailing slash (e.g. /blog/post.md/) came out as /blog/post.md.md and would 404. This strips trailing slashes first.

Closes #78.

Changes

  • packages/core/src/paths.ts: strip trailing slashes before the .md check, so an already-.md path maps back to itself with or without a trailing slash. This also fixes toMarkdownUrl, which delegates to toMarkdownPath.
  • Added a regression test for /a.md/ and /blog/post.md/.

Other cases (root to /index.md, trailing-slash stripping, deep nesting, query/hash preservation) are unchanged.

Type

  • Bug fix (non-breaking)
  • New feature (non-breaking)
  • Breaking change
  • Spec change (requires bump in AEO_SPEC_VERSION)
  • Docs / examples / tooling only

Verification

  • bun run build passes
  • bun run test passes (core: 181 tests)
  • bun run typecheck passes
  • If touching examples: ran dualmark verify (no examples touched)
  • If touching /spec/: ran sync-spec (no spec files touched)

Changeset

  • Added a changeset (patch for @dualmark/core)

cc @thepushkaraj @aagarwal1012.

The idempotency guard ran before trailing slashes were stripped, so a
markdown path with a trailing slash (e.g. /blog/post.md/) was given a
doubled extension (/blog/post.md.md) and would 404. Strip trailing slashes
first so an already-.md path maps back to itself.
Copilot AI review requested due to automatic review settings July 1, 2026 02:35
@vercel

vercel Bot commented Jul 1, 2026

Copy link
Copy Markdown

@abhay-codes07 is attempting to deploy a commit to the Dodo Payments Team on Vercel.

A member of the Team first needs to authorize it.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes an edge case in @dualmark/core markdown-twin path mapping where a .md pathname with a trailing slash (e.g. /blog/post.md/) would incorrectly become /blog/post.md.md, causing 404s. The update normalizes trailing slashes before performing the .md idempotency check, and adds a regression test to lock in the behavior.

Changes:

  • Normalize trailing slashes before checking for an existing .md extension in toMarkdownPath (which also fixes toMarkdownUrl).
  • Add regression tests ensuring .md/ inputs do not get a doubled extension.
  • Add a patch changeset for @dualmark/core.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
packages/core/src/paths.ts Reorders normalization to strip trailing slashes before .md idempotency detection to avoid .md.md outputs.
packages/core/test/paths.test.ts Adds regression coverage for .md paths that include a trailing slash.
.changeset/tomarkdownpath-trailing-slash.md Records a patch changeset describing the bug fix and its impact.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +21 to +23
// Strip trailing slashes before the `.md` check, otherwise a markdown path
// with a trailing slash (e.g. "/blog/post.md/") defeats the idempotency
// guard and gets a doubled extension ("/blog/post.md.md").

@dodo-squirrels dodo-squirrels Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: fix(core): strip trailing slash before .md check in toMarkdownPath

Verdict: LGTM — approving.

Reviewed end-to-end and exercised the change locally.

Bug reproduction (confirmed on main)

On main, toMarkdownPath ran the .md idempotency guard before trimming trailing slashes:

if (pathname.endsWith(".md")) return pathname;   // "/blog/post.md/" doesn't end with ".md"
const trimmed = pathname.replace(/\/+$/, "");    // -> "/blog/post.md"
return trimmed + ".md";                          // -> "/blog/post.md.md"  ✗

So toMarkdownPath("/blog/post.md/") returned /blog/post.md.md (and toMarkdownUrl produced the same doubled path), which 404s. Verified this reproduces on main.

Fix verification

Checked out the branch and ran the edge cases directly:

Input Output
/blog/post.md/ /blog/post.md
/a.md/ /a.md
/blog/post/ /blog/post.md
/ and "" /index.md
/blog/x.md /blog/x.md (idempotent)
/blog// /blog.md
toMarkdownUrl("https://x.com/blog/post.md/") https://x.com/blog/post.md

Ordering is now correct: trim trailing slashes → empty check → .md idempotency check → append. All other cases are unchanged, and this aligns with content-negotiation spec §6 (trailing slash stripped, .md twins are equivalent representations).

Tests

  • Added paths.test.ts cases for .md + trailing slash cover the exact regression.
  • Full @dualmark/core suite passes locally: 181/181.

Clean, minimal, well-commented, changeset included. No concerns.

@thepushkaraj
thepushkaraj merged commit f513326 into dodopayments:main Jul 23, 2026
1 check failed

@thepushkaraj thepushkaraj left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @abhay-codes07!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

toMarkdownPath doubles the extension for a .md path with a trailing slash

3 participants