-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New Components - pdf4me #16174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New Components - pdf4me #16174
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 3 Skipped Deployments
|
WalkthroughThis pull request introduces new modules for the pdf4me component that handle PDF conversion, merging, and compression. Additionally, it adds a set of utility functions for file path normalization, extension checking, and temporary file downloading. The pdf4me app has been enhanced with new properties and methods to support these PDF operations, and the package configuration has been updated to include a new dependency and version bump. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ActionModule
participant Utils
participant App
User->>ActionModule: Trigger PDF Action (compress/convert/merge)
ActionModule->>Utils: Check file extension & normalize file path
ActionModule->>App: Call corresponding PDF API method
App->>App: Process API request (_makeRequest)
App-->>ActionModule: Return processed PDF data
ActionModule->>Utils: Download file to temporary location
ActionModule-->>User: Return summary message and file data
Assessment against linked issues
Suggested labels
Suggested reviewers
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
components/pdf4me/common/utils.mjsOops! Something went wrong! :( ESLint: 8.57.1 Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs 📜 Recent review detailsConfiguration used: CodeRabbit UI ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms (3)
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Nitpick comments (10)
components/pdf4me/actions/merge-pdfs/merge-pdfs.mjs (2)
32-40: Add validation for the response from the API.The code doesn't validate the response from the mergePdfs API call before attempting to save it.
const response = await this.pdf4me.mergePdfs({ $, data: { docContent: fileContents, docName: filename, }, responseType: "arraybuffer", }); + if (!response || response.length === 0) { + throw new Error("Received empty response from PDF4me API"); + }
41-45: Consider adding more detailed success information.The current success message is generic. Consider enhancing it with information about the number of files merged and the output file size.
const filedata = utils.downloadToTmp(response, filename); - $.export("$summary", "Successfully merged PDF files"); + $.export("$summary", `Successfully merged ${this.filePaths.length} PDF files into ${filename} (${response.length} bytes)`); return filedata;components/pdf4me/actions/convert-to-pdf/convert-to-pdf.mjs (2)
33-42: Add validation for the API response.The code should validate the response from the convertToPdf API call.
const response = await this.pdf4me.convertToPdf({ $, data: { docContent: fileContent, docName: this.filename, }, responseType: "arraybuffer", }); + if (!response || response.length === 0) { + throw new Error("Received empty response from PDF4me API"); + }
43-46: Enhance success message with file details.The current success message is generic. Consider enhancing it with information about the converted file.
const filedata = utils.downloadToTmp(response, this.filename); - $.export("$summary", "Successfully converted file to PDF"); + $.export("$summary", `Successfully converted ${this.filePath} to PDF (${response.length} bytes)`); return filedata;components/pdf4me/common/utils.mjs (2)
3-7: Improve path normalization logic.The current implementation assumes any path containing "tmp/" is already properly normalized, which may not be true for paths like "example/tmp/file.pdf".
function normalizeFilePath(path) { - return path.includes("tmp/") + return path.startsWith("/tmp/") || path.startsWith("tmp/") ? path : `/tmp/${path}`; }
9-13: Enhance extension checking logic.The current implementation doesn't handle cases where a filename might contain multiple dots or extensions.
function checkForExtension(filename, ext = "pdf") { - return filename.includes(`.${ext}`) + return filename.toLowerCase().endsWith(`.${ext.toLowerCase()}`) ? filename : `${filename}.${ext}`; }components/pdf4me/actions/compress-pdf/compress-pdf.mjs (2)
42-48: Consider using asynchronous file operationsUsing
fs.readFileSyncfor potentially large PDFs could block the Node.js event loop and cause performance issues.- const fileContent = fs.readFileSync(filePath, { - encoding: "base64", - }); + const fileContent = await fs.promises.readFile(filePath, { + encoding: "base64", + });
61-63: Add file size information to the summaryTo provide more value to users, consider adding the original and compressed file sizes to the summary message.
- $.export("$summary", "Successfully compressed PDF file"); + const originalSize = fs.statSync(filePath).size; + const compressedSize = fs.statSync(filedata.path).size; + const reductionPercent = ((originalSize - compressedSize) / originalSize * 100).toFixed(2); + $.export("$summary", `Successfully compressed PDF file from ${(originalSize/1024).toFixed(2)}KB to ${(compressedSize/1024).toFixed(2)}KB (${reductionPercent}% reduction)`);components/pdf4me/pdf4me.app.mjs (2)
19-21: Consider versioning the base URLBest practice is to include API version in the base URL method to make future version changes easier.
_baseUrl() { - return "https://api.pdf4me.com/api/v2"; + const API_VERSION = "v2"; + return `https://api.pdf4me.com/api/${API_VERSION}`; }
35-55: Implement consistent documentation for API wrapper methodsThe API methods would benefit from JSDoc comments to explain their parameters and return values.
+ /** + * Converts a document to PDF format + * @param {Object} opts - The options for the conversion + * @param {Object} opts.data - The data for the conversion + * @param {string} opts.data.docContent - The base64-encoded document content + * @param {string} opts.data.docName - The name of the document + * @returns {Promise<Object>} The API response + */ convertToPdf(opts = {}) { return this._makeRequest({ method: "POST", path: "/ConvertToPdf", ...opts, }); },Add similar documentation for the other methods.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (6)
components/pdf4me/actions/compress-pdf/compress-pdf.mjs(1 hunks)components/pdf4me/actions/convert-to-pdf/convert-to-pdf.mjs(1 hunks)components/pdf4me/actions/merge-pdfs/merge-pdfs.mjs(1 hunks)components/pdf4me/common/utils.mjs(1 hunks)components/pdf4me/package.json(2 hunks)components/pdf4me/pdf4me.app.mjs(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: Verify TypeScript components
- GitHub Check: pnpm publish
- GitHub Check: Publish TypeScript components
🔇 Additional comments (7)
components/pdf4me/package.json (2)
3-3: Version bumped appropriately for new features.The version update from 0.0.1 to 0.1.0 follows semantic versioning principles correctly for the addition of new functionalities.
14-17: Dependencies section added correctly.The addition of the @pipedream/platform dependency is appropriate for the new functionality being introduced. The version constraint is also reasonable.
components/pdf4me/actions/merge-pdfs/merge-pdfs.mjs (1)
5-24: Component definition looks good.The component metadata and properties are well-defined with clear descriptions and appropriate types. The documentation links provide useful references for users.
components/pdf4me/actions/convert-to-pdf/convert-to-pdf.mjs (1)
5-26: Component definition is well structured.The component properties and metadata are clearly defined with appropriate documentation references.
components/pdf4me/common/utils.mjs (1)
27-31: Utility exports look good.The module exports all the utility functions properly.
components/pdf4me/actions/compress-pdf/compress-pdf.mjs (1)
19-34: Look good: Comprehensive optimize profile optionsThe optimize profile offers various compression types which gives users flexibility in how they want to compress their PDFs.
components/pdf4me/pdf4me.app.mjs (1)
6-17: Good implementation of propDefinitionsThe propDefinitions for filePath and filename are well-documented with clear descriptions and proper types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
components/pdf4me/actions/compress-pdf/compress-pdf.mjs (2)
42-48: Consider using asynchronous file operations.The code currently uses
fs.readFileSync()which blocks the event loop. In a Node.js environment, it's generally better to use asynchronous alternatives.- const fileContent = fs.readFileSync(filePath, { - encoding: "base64", - }); + const fileContent = await fs.promises.readFile(filePath, { + encoding: "base64", + });
59-63: Enhance the success message with compression details.The current success message is generic. Consider enhancing it with information about the original and compressed file sizes to give users more insight into the effectiveness of the compression.
- $.export("$summary", "Successfully compressed PDF file"); + const originalSize = fs.statSync(filePath).size; + const compressedSize = fs.statSync(filedata).size; + const compressionRatio = ((originalSize - compressedSize) / originalSize * 100).toFixed(2); + $.export("$summary", `Successfully compressed PDF from ${(originalSize/1024).toFixed(2)}KB to ${(compressedSize/1024).toFixed(2)}KB (${compressionRatio}% reduction)`);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
components/pdf4me/actions/compress-pdf/compress-pdf.mjs(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: Verify TypeScript components
- GitHub Check: pnpm publish
- GitHub Check: Publish TypeScript components
🔇 Additional comments (4)
components/pdf4me/actions/compress-pdf/compress-pdf.mjs (4)
1-4: LGTM! Import statements are well organized.The imports look appropriate for the functionality of this component, including the pdf4me app, utility functions, and filesystem module.
5-10: Component metadata is well-defined.The metadata includes an appropriate key, descriptive name, helpful documentation link, initial version (0.0.1), and correct component type.
11-41: Props are well-structured with comprehensive options.The props definition is clear and well-organized, with appropriate references to shared prop definitions and a well-defined set of compression options.
49-58: Add error handling for API callsThe API call lacks error handling. If the PDF4me API returns an error, the action will fail without a clear error message.
- const response = await this.pdf4me.compressPdf({ - $, - data: { - docContent: fileContent, - docName: filename, - optimizeProfile: this.optimizeProfile, - }, - responseType: "arraybuffer", - }); + try { + const response = await this.pdf4me.compressPdf({ + $, + data: { + docContent: fileContent, + docName: filename, + optimizeProfile: this.optimizeProfile, + }, + responseType: "arraybuffer", + }); + } catch (error) { + $.export("$summary", `Error compressing PDF: ${error.message}`); + throw error; + }
jcortes
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @michelle0927 I've added just one minor observation other than that lgtm! Ready for QA!
Co-authored-by: Jorge Cortes <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (2)
components/pdf4me/common/utils.mjs (1)
16-26: Add error handling to file download function.The downloadToTmp function should handle potential file system errors and validate inputs.
function downloadToTmp(response, filename) { + if (!response) { + throw new Error("Cannot download empty response"); + } + + if (!filename || typeof filename !== "string") { + throw new Error("Invalid filename provided"); + } const rawcontent = response.toString("base64"); const buffer = Buffer.from(rawcontent, "base64"); const filePath = normalizeFilePath(filename); - fs.writeFileSync(filePath, buffer); + + try { + fs.writeFileSync(filePath, buffer); + } catch (error) { + throw new Error(`Failed to write file to ${filePath}: ${error.message}`); + } return [ filename, filePath, ]; }components/pdf4me/pdf4me.app.mjs (1)
32-34:⚠️ Potential issueUse Basic Authentication for PDF4me.
According to the PDF4me documentation, the
Authorizationheader should containBasic <APIKey>rather than the raw key. This ensures compatibility with their API.Apply this diff to fix the header:
-headers: { - authorization: this.$auth.api_key, -}, +headers: { + Authorization: `Basic ${this.$auth.api_key}`, + "Content-Type": "application/json", +},
🧹 Nitpick comments (1)
components/pdf4me/pdf4me.app.mjs (1)
36-38: Ensure error details are surfaced.
utils.handleErrorMessage(error);may abstract or suppress some error context. Consider passing the HTTP status and response body to the thrown error for clarity, as previously suggested in past reviews.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
components/pdf4me/common/utils.mjs(1 hunks)components/pdf4me/pdf4me.app.mjs(1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
components/pdf4me/common/utils.mjs
[error] 30-30: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: pnpm publish
🔇 Additional comments (4)
components/pdf4me/pdf4me.app.mjs (4)
1-2: Imports look good.No issues detected with the new imports from
@pipedream/platformand your local utilities file.
7-18: Properties are well-defined.The new
filePathandfilenameproperties correctly guide users to store files under/tmp. This aligns with typical usage in Pipedream. No concerns here regarding naming or data types.
20-22:❓ Verification inconclusive
Verify API version usage.
You're targeting
https://api.pdf4me.com/api/v2. Please confirm thatv2endpoints support all methods (/ConvertToPdf,/Merge,/Optimize) you plan to call.
🏁 Script executed:
#!/bin/bash # Description: Check for presence and validity of v2 endpoints. # Expect: references to ConvertToPdf, Merge, Optimize under v2 in PDF4me documentation. echo "Please verify with official docs or run a test request to confirm availability of these endpoints on v2."Length of output: 218
Attention: Verify API Version Endpoints
The base URL in
components/pdf4me/pdf4me.app.mjsis set to use the v2 API, but the current verification script only echoes a reminder. Please confirm—via the official PDF4me documentation or a test request—that the v2 endpoints (/ConvertToPdf,/Merge, and/Optimize) are indeed supported.
40-59:✅ Verification successful
POST methods look consistent.
convertToPdf,mergePdfs, andcompressPdfproperly pass their options to_makeRequest. Ensure the request bodies align with PDF4me-specific requirements (e.g., references to files, parameters).
🏁 Script executed:
#!/bin/bash # Description: Check method usage references in action files fd convert-to-pdf.mjs | xargs cat fd merge-pdfs.mjs | xargs cat fd compress-pdf.mjs | xargs cat # Inspect how you're constructing the body for these calls # Expect properly formed JSON with PDFs or relevant fields # as required by PDF4me documentation.Length of output: 7572
Action: PDF4me POST Request Bodies are Conforming
The PDF4me integration methods in
components/pdf4me/pdf4me.app.mjsare correctly constructing POST requests. Verification across the related action files confirms the following:
- convertToPdf: Reads the file from the specified path (encoding it in base64) and sends a request with
docContentanddocName.- mergePdfs: Constructs an array of base64-encoded file contents passed as
docContentalong with the document name (docName).- compressPdf: Includes the additional
optimizeProfilefield along withdocContentanddocNameas required.All request bodies align with PDF4me’s API expectations, and the file references/parameters are accurately provided.
|
/approve |
Resolves #16099
Summary by CodeRabbit
New Features
Chores