feat: add middleware for Accept: text/markdown content negotiation#37
Conversation
302-redirects GET/HEAD requests with Accept: text/markdown to {path}.md.
Passes through for other methods, paths with file extensions, or missing
text/markdown Accept header. Preserves query strings. Root path redirects
to /index.md.
Branch preview🔗 https://feat-markdown-content-negoti.chinmina.pages.dev (direct commit link) |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughAdds a request middleware and tests: for GET/HEAD requests whose Accept header includes text/markdown, the middleware redirects to a corresponding .md path (stripping trailing slashes and mapping empty path to /index) and preserves the original query string; other requests are passed through. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Middleware as onRequest (Middleware)
participant Handler as context.next (Handler)
Client->>Middleware: HTTP Request
activate Middleware
alt Method not GET/HEAD OR Accept missing/doesn't include text/markdown OR path has extension
Middleware->>Handler: context.next()
activate Handler
Handler-->>Middleware: Response
deactivate Handler
Middleware-->>Client: Response (passthrough)
else GET/HEAD and Accept includes text/markdown and path has no extension
Middleware-->>Client: 302 Redirect to <rgba(0,128,0,0.5)>path.md</rgba> (preserve query)
end
deactivate Middleware
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly Related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
functions/_middleware.test.ts (1)
16-116: Good test coverage of the core requirements.The test suite thoroughly covers:
- GET/HEAD redirect behavior
- Root path normalization to
/index.md- Query string preservation
- Pass-through for non-matching methods, Accept headers, and file extensions
Consider adding tests for edge cases:
- Trailing slash paths (e.g.,
/about/) — relates to the malformed redirect issue- Paths with dots in directory segments (e.g.,
/v1.0/docs) to confirm only the final segment is checked📝 Suggested additional test cases
it("handles trailing slash paths", async () => { const context = createContext("https://example.com/about/", { headers: { Accept: "text/markdown" }, }) const response = await onRequest(context) expect(response.status).toBe(302) expect(response.headers.get("Location")).toBe("/about.md") }) it("redirects paths with dots in directory names", async () => { const context = createContext("https://example.com/v1.0/docs", { headers: { Accept: "text/markdown" }, }) const response = await onRequest(context) expect(response.status).toBe(302) expect(response.headers.get("Location")).toBe("/v1.0/docs.md") })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@functions/_middleware.test.ts` around lines 16 - 116, Add tests for trailing-slash and dotted-directory edge cases to ensure onRequest redirects produce well-formed .md locations: add a test invoking createContext with "https://example.com/about/" and Accept: "text/markdown" and assert onRequest returns 302 with Location "/about.md" (not "/about/.md"), and another test with "https://example.com/v1.0/docs" and Accept: "text/markdown" asserting 302 and Location "/v1.0/docs.md"; place these alongside the existing tests so they exercise the same onRequest middleware and confirm query-preservation and behavior for final path segment only.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@functions/_middleware.ts`:
- Around line 13-17: Normalize the request pathname by stripping any trailing
slashes before inspecting or using it: compute a normalizedPath (derived from
new URL(request.url).pathname with trailing slashes removed, defaulting to "/"
if empty), then derive lastSegment from normalizedPath.split("/").pop() and use
normalizedPath for any redirect construction instead of the raw url.pathname;
update the logic around the lastSegment variable and any redirect code in
functions/_middleware.ts so trailing-slash paths like "/about/" produce
"/about.md" rather than "/about/.md".
---
Nitpick comments:
In `@functions/_middleware.test.ts`:
- Around line 16-116: Add tests for trailing-slash and dotted-directory edge
cases to ensure onRequest redirects produce well-formed .md locations: add a
test invoking createContext with "https://example.com/about/" and Accept:
"text/markdown" and assert onRequest returns 302 with Location "/about.md" (not
"/about/.md"), and another test with "https://example.com/v1.0/docs" and Accept:
"text/markdown" asserting 302 and Location "/v1.0/docs.md"; place these
alongside the existing tests so they exercise the same onRequest middleware and
confirm query-preservation and behavior for final path segment only.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ba862ed0-8069-4f62-8767-2d98ea6f74ce
📒 Files selected for processing (2)
functions/_middleware.test.tsfunctions/_middleware.ts
Accept: text/markdown content negotiation
Paths like /about/ produced /about/.md instead of /about.md. Strip trailing slashes before inspecting or constructing the redirect URL. Also reorders checks to parse the URL only after confirming the Accept header matches.
Purpose
Completes HTTP content negotiation support for markdown content, building on the flattened markdown output from #36. Clients can now request documentation as raw markdown using the standard
Accept: text/markdownheader rather than needing to know the site's.mdURL convention. This supports LLM tooling and programmatic consumers that prefer markdown over HTML.Context
{slug}.mdpattern that makes the redirect URL deterministicfunctions/_middleware.ts) — no Astro adapter or SSR needed, the site stays fully staticSummary by CodeRabbit
New Features
Tests