feat(build): add lightweight libreoffice build extension#3164
feat(build): add lightweight libreoffice build extension#3164CuboYe wants to merge 1 commit intotriggerdotdev:mainfrom
Conversation
…iggerdotdev#1361) - Add `packages/build/src/extensions/libreoffice.ts`: installs libreoffice-writer and libreoffice-impress (configurable) via apt with --no-install-recommends so no X11/desktop packages are pulled in. Includes fonts-liberation and fonts-dejavu-core for accurate document rendering. Sets LIBREOFFICE_PATH env var. - Register `@trigger.dev/build/extensions/libreoffice` export in package.json. - Add `references/libreoffice/` reference project demonstrating headless docx/pptx to PDF conversion using execFile + LibreOffice --headless --norestore. - Update docs to reference the dedicated extension instead of the generic aptGet. - Add patch changeset for @trigger.dev/build. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: a0a263a The changes in this PR will be included in the next version bump. This PR includes changesets to release 28 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Hi @CuboYe, thanks for your interest in contributing! This project requires that pull request authors are vouched, and you are not in the list of vouched users. This PR will be closed automatically. See https://github.com/triggerdotdev/trigger.dev/blob/main/CONTRIBUTING.md for more details. |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review infoConfiguration used: Repository UI Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (4)
📒 Files selected for processing (4)
WalkthroughThis pull request introduces a new LibreOffice build extension for the Trigger.dev build system. The changes include: a changeset file declaring the patch release, a new TypeScript extension implementation that handles automated LibreOffice installation with customizable components and fonts, updates to the package.json to export the new extension with proper type declarations, and documentation updates demonstrating how to use the extension for DOCX/PPTX to PDF conversion in headless environments. Estimated code review effort🎯 3 (Moderate) | ⏱️ ~23 minutes ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). 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 |
|
|
||
| // Derive a safe input filename from the URL. | ||
| const urlPath = new URL(documentUrl).pathname; | ||
| const ext = urlPath.split(".").pop() ?? "docx"; |
There was a problem hiding this comment.
🔴 URL extension extraction produces invalid file path when URL has no file extension
When the documentUrl has no dot-separated file extension in its pathname (e.g., https://api.example.com/documents/report or a signed URL like https://storage.example.com/abc123), the extension extraction at line 33 produces a broken path that causes a runtime crash.
Root Cause
The expression urlPath.split(".").pop() always returns a non-empty string (the last element of the split array), so the ?? "docx" fallback never triggers for URLs without a file extension.
For example, given documentUrl = "https://api.example.com/documents/report":
urlPath="/documents/report"urlPath.split(".")=["/documents/report"].pop()="/documents/report"— a truthy string, notnull/undefinedext="/documents/report"inputPath=join(workDir, "input./documents/report")→ e.g./tmp/lo-123/input./documents/report
The resulting inputPath contains intermediate directory components (/documents/) that don't exist, so writeFileSync(inputPath, ...) at line 45 throws ENOENT. Even URLs with dots in non-extension positions (e.g. https://api.v2.example.com/file) would extract garbage like "com/file" containing a /.
Impact: The task crashes for any URL whose pathname doesn't end with a recognizable .ext suffix. Since many document-serving APIs and signed URLs lack file extensions, this is a common real-world scenario. Users are likely to copy this reference project as a template.
| const ext = urlPath.split(".").pop() ?? "docx"; | |
| const lastSegment = urlPath.split("/").pop() ?? ""; | |
| const ext = lastSegment.includes(".") ? lastSegment.split(".").pop()! : "docx"; |
Was this helpful? React with 👍 or 👎 to provide feedback.
| @@ -0,0 +1,13 @@ | |||
| import { defineConfig } from "@trigger.dev/sdk/v3"; | |||
There was a problem hiding this comment.
🚩 Reference config uses deprecated @trigger.dev/sdk/v3 import path
At references/libreoffice/trigger.config.ts:1, the import uses @trigger.dev/sdk/v3 which is noted as a deprecated path alias in CLAUDE.md and packages/trigger-sdk/CLAUDE.md ("Never use @trigger.dev/sdk/v3"). While this still works as an alias, other reference projects and the docs example (docs/guides/examples/libreoffice-pdf-conversion.mdx:21) correctly use @trigger.dev/sdk. This inconsistency could confuse users who use this reference as a template.
Was this helpful? React with 👍 or 👎 to provide feedback.
Fixes #1361
/claim #1361
What changed
libreoffice()build extension at@trigger.dev/build/extensions/libreoffice--no-install-recommends(headless-oriented, no X11)LIBREOFFICE_PATHdeploy env varreferences/libreofficereference project showing docx/pptx -> pdf conversion@trigger.dev/buildValidation