Skip to content

feat(files): add Markdown PDF download - #6511

Open
BillLeoutsakosvl346 wants to merge 14 commits into
stagingfrom
feat/markdown-pdf-download
Open

feat(files): add Markdown PDF download#6511
BillLeoutsakosvl346 wants to merge 14 commits into
stagingfrom
feat/markdown-pdf-download

Conversation

@BillLeoutsakosvl346

@BillLeoutsakosvl346 BillLeoutsakosvl346 commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a Markdown-only Download PDF action to the Files header. It downloads a server-generated PDF directly, without opening print preview.

PDF reuses the existing file export route's authentication and file-access checks, the browser download helper, filename handling, error toast, audit event, and authorized workspace image resolution. It intentionally exports the latest durable stored revision, matching ordinary Markdown Download; neither action forces or waits for a collaborative save.

The optional format=pdf query enters an isolated PDF-only branch. When format is absent, the original non-Markdown redirect, raw Markdown response, image-ID ZIP creation and rewriting, filename rules, size limits, telemetry, client fetch behavior, Markdown eligibility rules, and preview behavior remain unchanged—including their existing quirks.

The PDF renderer invokes the Files editor's existing Markdown parser directly. Its small lazy jsdom setup is private to the PDF renderer; the existing collaboration converter is byte-for-byte identical to staging, and no shared parser abstraction, collaboration change, or realtime behavior is introduced.

The renderer supports headings, paragraphs, marks, lists/task lists, blockquotes, code, tables, links, rules, and authorized embedded images on light A4 pages. PDF-only byte, image-pixel, normalized-image, document-node, and request-rate limits bound server work. Fallback fonts preserve supported multilingual text; unsupported emoji use readable code-point labels.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Other

Testing

  • Biome passed on the PDF renderer
  • Focused Vitest: PDF renderer, export route, and existing collaboration converter — 3 files / 30 tests passed
  • Sim TypeScript: bun run type-check passed
  • Strict API-contract validation passed
  • git diff --check passed
  • Confirmed converter.ts has no diff from origin/staging
  • Confirmed no shared server-Markdown adapter or PDF-specific collaboration/realtime changes remain
  • Regression coverage confirms absent-format raw Markdown, image-ID ZIP rewriting/telemetry, and non-Markdown redirects never enter PDF logic

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement

Screenshots/Videos

No new screenshot is attached in this update because no controllable localhost browser session was available. The action remains the existing Markdown-only Download PDF header action and downloads directly without print preview.

@BillLeoutsakosvl346
BillLeoutsakosvl346 requested a review from a team as a code owner August 11, 2026 00:15
@vercel

vercel Bot commented Aug 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Aug 11, 2026 7:27pm

Request Review

@cursor

cursor Bot commented Aug 11, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
New server-side PDF generation is CPU/memory-heavy (Sharp, React PDF, fonts) and adds export surface area with auth checks; byte/rate limits mitigate abuse, but production load and Docker font bundling are worth watching.

Overview
Adds Download PDF for Markdown files in the workspace Files UI and a format=pdf branch on the existing file export API. Ordinary download, ZIP bundling, and non-Markdown redirects stay on the default path when format is omitted.

The PDF path rate-limits exports, reads stored Markdown and authorized embedded images under tighter byte caps than ZIP export, and returns a direct application/pdf attachment with audit/telemetry. A new server renderer (markdown-pdf.tsx) parses Markdown with the editor’s TipTap pipeline (JSDOM on demand), lays out GFM blocks with @react-pdf/renderer, normalizes images via Sharp with pixel/byte limits, and uses Geist plus Noto/Unifont fallbacks for multilingual text (unsupported emoji as code-point labels).

The client download helper and fileExportContract accept optional format=pdf. Docker and Next config copy @fontsource packages and trace jsdom for export routes. Dependencies add @react-pdf/renderer, fontkit, and font packages.

Reviewed by Cursor Bugbot for commit 2b17c81. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps

greptile-apps Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds direct server-generated PDF downloads for stored Markdown files while preserving the existing export behavior for other requests.

  • Introduces a Markdown-to-PDF renderer with multilingual fonts, authorized embedded images, pagination, and resource ceilings.
  • Adds the authenticated, rate-limited format=pdf export path and a Markdown-only Files header action.
  • Updates the binary API contract, standalone deployment assets, dependencies, and focused tests.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the prior production font-path and component-props findings are resolved in the current code.

Important Files Changed

Filename Overview
apps/sim/app/api/files/export/[id]/markdown-pdf.tsx Adds the bounded Markdown PDF renderer, font fallback selection, image normalization, and document layout.
apps/sim/app/api/files/export/[id]/route.ts Adds an isolated authenticated and rate-limited PDF branch without changing ordinary export behavior.
apps/sim/app/workspace/[workspaceId]/files/files.tsx Adds the Markdown-only Download PDF action with duplicate-request suppression and existing error handling.
apps/sim/lib/uploads/client/download.ts Extends the download helper to request and save PDF exports through the binary route contract.
docker/app.Dockerfile Copies runtime fallback-font packages required by standalone PDF rendering.

Sequence Diagram

sequenceDiagram
  participant U as Files UI
  participant E as Export API
  participant S as Object Storage
  participant R as PDF Renderer
  U->>E: "GET /api/files/export/:id?format=pdf"
  E->>E: Authenticate, authorize, rate-limit
  E->>S: Read stored Markdown
  E->>S: Resolve and read authorized images
  E->>R: Render Markdown and images
  R-->>E: PDF buffer
  E-->>U: PDF attachment
Loading

Reviews (2): Last reviewed commit: "fix(files): preserve PDF image links and..." | Re-trigger Greptile

Comment thread apps/sim/app/api/files/export/[id]/markdown-pdf.tsx Outdated
Comment thread apps/sim/app/api/files/export/[id]/markdown-pdf.tsx Outdated
Comment thread apps/sim/app/api/files/export/[id]/markdown-pdf.tsx Outdated
Comment thread apps/sim/app/api/files/export/[id]/markdown-pdf.tsx Outdated
Comment thread apps/sim/app/api/files/export/[id]/markdown-pdf.tsx
Comment thread apps/realtime/src/handlers/file-doc.ts Outdated
Comment thread apps/sim/app/workspace/[workspaceId]/files/files.tsx
Comment thread apps/sim/app/api/files/export/[id]/markdown-pdf.tsx

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 46ecbf4. Configure here.

Comment thread apps/sim/app/api/files/export/[id]/markdown-pdf.tsx
Comment thread apps/sim/app/api/files/export/[id]/markdown-pdf.tsx
@BillLeoutsakosvl346

Copy link
Copy Markdown
Contributor Author

@greptile

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.

1 participant