Skip to content

Part 2 - applying File URL or Path improvements #17091

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

Merged
merged 53 commits into from
Jun 17, 2025
Merged

Part 2 - applying File URL or Path improvements #17091

merged 53 commits into from
Jun 17, 2025

Conversation

GTFalcao
Copy link
Collaborator

@GTFalcao GTFalcao commented Jun 12, 2025

Partially addresses #16977

This branch was created off the first one (#16979 ), and will be merged only after that one is merged.

The 30 components changed in this branch are:

autodesk: upload-file

cradl_ai:

  • parse-document
  • parse-document-human-in-loop

docsbot_ai: upload-source-file

egnyte: upload-file

flippingbook:

  • create-flipbook
  • update-flipbook

google_drive:

  • upload-file
  • update-file

happy_scribe: submit-file

ilovepdf: process-files

imagga:

  • analyze-image
  • process-batch

lokalise: upload-file

podio: upload-file

zoho_crm: upload-attachment

openai:

  • analyze-image-content
  • chat
  • create-batch
  • create-transcription
  • upload-file

airparser: upload-document-parse

alttext_ai: generate-alt-text

azure_storage: upload-blob

boldsign: send-document-template

canva:

  • create-design-import-job
  • upload-asset

claid_ai:

  • correct-color-lighting
  • remove-background
  • upscale-image

Summary by CodeRabbit

  • New Features

    • Many components now support accepting either a file URL or a local file path (e.g., in /tmp) for file inputs, making file uploads and processing more flexible and convenient.
  • Bug Fixes

    • Improved reliability and compatibility of file uploads by standardizing file stream and metadata handling across actions.
  • Refactor

    • File handling was unified to use a consistent, asynchronous approach for reading files and obtaining metadata, replacing previous synchronous and manual file system operations.
    • Deprecated or removed support for direct file URL uploads in some components, consolidating input methods for clarity and maintainability.
    • Updated property labels and descriptions throughout to clearly indicate support for both file URLs and local paths.
  • Chores

    • Updated package versions and dependencies to ensure compatibility and leverage the latest platform features.
    • Removed unnecessary dependencies and legacy utility code related to file handling.

@GTFalcao
Copy link
Collaborator Author

@vunguyenhung

  • lokalise-upload-file: according to the docs linked in the prop, PDF is not a supported format;

  • stannp-create-campaign: your test succeeded on the previous PR and the code for this component was not changed. Perhaps it is a business rule error, e.g. certain campaign types do not work with the PDF format? (it seems each test was made with a different campaign type)

  • openai-chat: I fixed the issue with the audio; as for the image, the prop accepts raw base64 content or a file URL; to keep the current functionality we would have to create a separate prop (one for raw base64 input, and another for file path or url). Do you think that should be done?

  • akeneo-create-a-new-product-media-file: as we related, since this error is unrelated to file handling and happens in the live component, we'll skip this and open a new issue to investigate it, in order not to hold off on all other components due to this one

@GTFalcao GTFalcao marked this pull request as ready for review June 17, 2025 00:54
@GTFalcao GTFalcao moved this from Changes Required to Ready for QA in Component (Source and Action) Backlog Jun 17, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 30

🔭 Outside diff range comments (6)
components/microsoft_onedrive/actions/upload-file/upload-file.mjs (1)

43-53: Ensure filename fallback & propagate content-type

If neither the optional filename prop nor metadata.name is set (e.g. when the URL lacks a terminating filename), OneDrive will receive an empty name and will reject the request.
Additionally, you’re not forwarding metadata.contentType, so uploads may be stored with a generic MIME type.

-const name = filename || metadata.name;
+const name = filename || metadata.name;
+if (!name) {
+  throw new ConfigurationError("Unable to determine a filename – provide the *Name* prop or use a URL/path that contains one.");
+}

and pass the MIME type:

-    const response = await this.onedrive.uploadFile({
+    const response = await this.onedrive.uploadFile({
       uploadFolderId,
       name,
       data: stream,
+      contentType: metadata.contentType,
       $,
     });

This keeps failures explicit and preserves the original file’s MIME information.

components/docsbot_ai/actions/upload-source-file/upload-source-file.mjs (1)

35-57: $summary may print “undefined” when metadata lacks name

You already fallback to filePath.split("/").pop() when building the upload URL, but the success summary always uses metadata.name, which can be undefined (e.g. when uploading from a public URL that lacks a filename header).

-    $.export("$summary", `Successfully uploaded "${metadata.name}"`);
+    const fileName = metadata.name || filePath.split("/").pop();
+    $.export("$summary", `Successfully uploaded "${fileName}"`);

This keeps the summary meaningful in all scenarios.

components/onlyoffice_docspace/onlyoffice_docspace.app.mjs (1)

71-75: getHeaders is executed twice – drop the inner call to prevent redundant work

_makeRequest() already expands headers with this.getHeaders(headers) before passing it to getConfig().
Inside getConfig(), this.getHeaders(headers) is invoked again, duplicating default header enrichment and risking key overwrites.

Remove one layer:

-const config = await this.getConfig({
-  url: this.getUrl(path),
-  headers: this.getHeaders(headers),
-  ...args,
-});
+const config = await this.getConfig({
+  url: this.getUrl(path),
+  headers,          // already normalized
+  ...args,
+});

Less work, same result.

components/pandadoc/actions/create-document-attachment/create-document-attachment.mjs (1)

55-62: Leverage FormData’s own headers instead of private _boundary

Using the non-public property data._boundary may break with future form-data versions.
formData.getHeaders() already populates the correct Content-Type with the boundary.

-      headers: {
-        "Content-Type": `multipart/form-data; boundary=${data._boundary}`,
-      },
+      headers: data.getHeaders(),
components/boldsign/actions/send-document-template/send-document-template.mjs (1)

260-273: JSON.parse(message) inside catch block can throw and mask root errors

If BoldSign returns plain-text, the secondary exception hides the original. Wrap the parse in a try/catch.

-      const parsedMessage = JSON.parse(message);
+      let parsedMessage = {};
+      try {
+        parsedMessage = JSON.parse(message);
+      } catch { /* non-JSON message */ }
components/onlyoffice_docspace/actions/upload-file/upload-file.mjs (1)

12-19: folderId prop incorrectly re-uses the “file” prop definition

propDefinition: [ app, "file" ] will inject the file property schema where a folder ID is expected, breaking the UI and runtime validation. This looks like a copy/paste slip.

-    folderId: {
-      label: "Folder ID",
-      description: "The ID of the folder where you want the file to be uploaded.",
-      propDefinition: [
-        app,
-        "file",
-      ],
-    },
+    folderId: {
+      propDefinition: [
+        app,
+        "folderId",           // assuming the app already exposes this
+      ],
+    },
🧹 Nitpick comments (39)
components/mistral_ai/package.json (1)

3-3: Confirm semver compliance for version bump.
You've bumped @pipedream/mistral_ai from 0.1.0 to 0.2.0, which indicates minor, backward-compatible changes. Ensure the CHANGELOG and release notes are updated to document the new file URL/path support and any behavioral changes.

components/google_drive/package.json (1)

3-3: Major version bump—review for breaking changes.
Releasing @pipedream/google_drive as 1.0.0 signals potential breaking changes. Ensure downstream workflows, documentation, and CHANGELOG entries reflect any API alterations introduced by the refactor.

components/cradl_ai/package.json (1)

3-3: Update minor version for new features.
Bumping @pipedream/cradl_ai from 0.1.0 to 0.2.0 covers the new file handling improvements. Don’t forget to update your CHANGELOG or release notes with details of the async file stream support.

components/alttext_ai/package.json (1)

3-3: Document version bump in CHANGELOG.
You’ve increased @pipedream/alttext_ai from 0.1.0 to 0.2.0. Make sure to log the new file URL/path handling feature in the component’s release notes.

components/ocrspace/actions/process-pdf/process-pdf.mjs (1)

8-8: Increment action version.
The action version was bumped from 0.0.1 to 0.1.0. Ensure that this change is mirrored in your CHANGELOG and that any consumers reference the correct version.

components/imagga/package.json (1)

3-3: Confirm semantic versioning for the major release
Bumping version to 1.0.0 signals a major release with potential breaking changes. Ensure CHANGELOG, migration guides, and documentation clearly outline any API or behavior changes for consumers.

components/box/package.json (1)

3-3: Confirm semantic versioning for the minor bump
Updating version from 0.3.0 to 0.4.0 indicates non-breaking enhancements. Ensure CHANGELOG reflects updated file-stream handling workflows.

components/openai/package.json (1)

3-3: Confirm major version bump to 1.0.0
The jump from 0.x to 1.0.0 indicates breaking changes across OpenAI components. Ensure this is documented in CHANGELOG/release notes and that downstream consumers are aware of any migration steps.

components/onlinecheckwriter/package.json (1)

3-3: Document version bump to 0.2.0
The minor version increase reflects added file-URL/path support. Please update CHANGELOG and any release notes to highlight the new capability.

components/askyourpdf/package.json (1)

3-3: Update package version to 0.2.0
Reflects async refactors and file-input enhancements. Ensure release notes capture the switch to asynchronous utilities and any required user-facing changes.

components/autodesk/package.json (1)

3-3: Bump version to 0.2.0
Indicates the upload-file action now supports file URLs and uses the new streaming utility. Add a CHANGELOG entry to note the enhanced file-input flexibility.

components/ilovepdf/package.json (1)

3-3: Major version bump to 1.0.0
Switching from 0.x to 1.0.0 signals significant changes (URL/path handling, drop of fileUrls). Make sure upgrade instructions are clearly communicated since this is likely a breaking release.

components/claid_ai/claid_ai.app.mjs (1)

9-11: Description now mirrors new behaviour but drops the original docs link

The clearer label/description is great, but removing the link to the ClaiD API docs slightly reduces discoverability for users. Consider re-adding the link at the end of the description for quick reference.

components/imagga/imagga.app.mjs (1)

34-36: Example extension doesn’t match the “image” context

The description example points to /tmp/myFile.txt, which suggests a text file.
Using an image-specific extension (e.g., .jpg or .png) avoids confusing users about the expected MIME type.

- (for example, `/tmp/myFile.txt`)
+ (for example, `/tmp/myImage.jpg`)
components/flippingbook/flippingbook.app.mjs (1)

37-41: Property name no longer reflects behaviour

filePath now accepts URLs as well, but the identifier still contains “Path”.
Consider renaming to file (mirroring other components) to keep the code self-documenting, or at minimum add an inline comment acknowledging the broadened scope.

components/claid_ai/actions/remove-background/remove-background.mjs (1)

99-108: Redundant urlExists round-trip

getFileStreamAndMetadata already handles both local paths and HTTP(S) URLs.
You could remove the extra HEAD request and simply attempt getFileStreamAndMetadata; fall back to the editImage branch only when the call throws for non-local URLs.

This avoids an additional network hop and simplifies control flow.

components/canva/actions/upload-asset/upload-asset.mjs (1)

32-46: Prefer actual MIME & omit unknown length

metadata.size may be absent for remote URLs, and hard-setting Content-Length with undefined produces an invalid header. Also, using the real MIME type helps Canva classify the asset.

-const { stream, metadata } = await getFileStreamAndMetadata(this.filePath);
+const { stream, metadata } = await getFileStreamAndMetadata(this.filePath);

 ...

-"Content-Length": metadata.size,
-"Content-Type": "application/octet-stream",
+...(Number.isFinite(metadata.size) && { "Content-Length": metadata.size }),
+"Content-Type": metadata.contentType || "application/octet-stream",
 ...
-data: stream,
+data: stream,

This keeps the request compliant and improves downstream processing accuracy.

components/ocrspace/actions/common/process-base.mjs (1)

48-51: Variable naming now misleading after util refactor

getUrlOrFile() now returns a base-64 string, not a { url, file } object.
Storing it in a variable called file can confuse future readers and static-analysis tools.

-    const file = await getUrlOrFile(this.file);
+    const base64Image = await getUrlOrFile(this.file);
+    const file = base64Image;          // preserve old semantic if callers rely on `file`

Renaming clarifies intent with zero runtime impact.

components/box/actions/upload-file-version/upload-file-version.mjs (1)

56-65: Missing parentId prop – may always be undefined

parentId is destructured from this and forwarded to getFileUploadBody, yet no parentId prop exists.
If getFileUploadBody doesn’t require it, drop the argument to avoid confusion; otherwise expose the prop.

-      file, fileId, createdAt, modifiedAt, fileName, parentId,
+      file, fileId, createdAt, modifiedAt, fileName,

(or add a parentId prop mirroring folderId).

Tiny cleanup but prevents dead-code drift.

components/_2markdown/actions/pdf-to-markdown/pdf-to-markdown.mjs (1)

30-37: Wrap stream acquisition in a try / catch to surface user-friendly errors

A missing or inaccessible file/URL will currently bubble an unhandled rejection and surface as “Internal error”. Catch it early and throw a meaningful ConfigurationError.

-const {
-  stream, metadata,
-} = await getFileStreamAndMetadata(this.filePath);
+let stream, metadata;
+try {
+  ({ stream, metadata } = await getFileStreamAndMetadata(this.filePath));
+} catch (err) {
+  throw new Error(`Unable to fetch file "${ this.filePath }": ${ err.message }`);
+}
components/_2markdown/actions/html-file-to-markdown/html-file-to-markdown.mjs (1)

23-30: Add defensive error handling around getFileStreamAndMetadata

Same rationale as in the PDF action – shield users from opaque stack traces.

-const {
-  stream, metadata,
-} = await getFileStreamAndMetadata(this.filePath);
+let stream, metadata;
+try {
+  ({ stream, metadata } = await getFileStreamAndMetadata(this.filePath));
+} catch (err) {
+  throw new Error(`Unable to fetch file "${ this.filePath }": ${ err.message }`);
+}
components/onlyoffice_docspace/onlyoffice_docspace.app.mjs (1)

49-55: Avoid the terse boolean-chain for clarity & potential precedence pitfalls

The data assignment combines && and || in a single expression. While functionally correct, the mixed short-circuit logic is harder to scan and easy to mis-read, especially once await is added.

-const data = hasMultipartHeader && await utils.getFormData(preData) || preData;
+const data = hasMultipartHeader
+  ? await utils.getFormData(preData)
+  : preData;

The explicit ternary improves readability and eliminates precedence ambiguity.

components/akeneo/actions/create-a-new-product-media-file/create-a-new-product-media-file.mjs (1)

34-37: Prop name now mismatches behaviour

The prop is still called filename but it expects a path or URL. To avoid confusion and to stay in line with other components, rename the prop (and references) to filePath or file.

components/mistral_ai/actions/upload-file/upload-file.mjs (1)

15-17: Clarify example extension in description

The property description now says “for example, /tmp/myFile.txt”.
Mistral only accepts specific formats (JSON, CSV, etc.). Consider replacing the .txt example with an actually supported extension to prevent user confusion.

components/autodesk/actions/upload-file/upload-file.mjs (1)

3-4: Import grouping nit

axios and getFileStreamAndMetadata come from different logical domains (HTTP vs. file util). Consider separate import lines for readability.

components/openai/actions/create-batch/create-batch.mjs (1)

33-36: Example file extension is misleading

The description references /tmp/myFile.jpg, but the OpenAI batch endpoint requires a .jsonl file. Recommend updating the example to avoid accidental misuse.

components/ocrspace/common/utils.mjs (1)

16-21: checkTmp() appears to be dead code

checkTmp() is no longer referenced after the refactor. Keeping unused helpers adds noise and can confuse future maintainers.

-export const checkTmp = (filename) => {
-  if (filename.indexOf("/tmp") === -1) {
-    return `/tmp/${filename}`;
-  }
-  return filename;
-};

If no other module imports this function, please remove it (and any tests) to keep the surface area minimal.

components/airparser/actions/upload-document-parse/upload-document-parse.mjs (1)

20-23: Prop name & description drift

filePath still implies “path”, but the label/description now mentions URLs as well. Consider renaming the prop to file or filePathOrUrl to avoid misleading users.

components/onlyoffice_docspace/common/utils.mjs (1)

5-9: Serial await in deep recursion could be slow

for…of / await processes nested objects sequentially. When many files are nested, building the form may be noticeably slower. Consider collecting promises and await Promise.all(...) where order is irrelevant.

components/askyourpdf/askyourpdf.app.mjs (1)

35-36: Use a ternary for clarity

The short-circuit expression mixes await, &&, and ||, which is easy to mis-read.

-const data = hasMultipartHeader && await utils.getFormData(preData) || preData;
+const data = hasMultipartHeader
+  ? await utils.getFormData(preData)
+  : preData;
components/boldsign/actions/send-document-template/send-document-template.mjs (2)

191-204: Inefficient in-memory buffering & missing content-type fallback

Reading each file into memory can exhaust RAM for large PDFs. Consider:

  1. Streaming directly to a base64 encoder (or chunked upload if BoldSign API supports multipart).
  2. Defaulting contentType to "application/octet-stream" when metadata.contentType is falsy.

At minimum, document the memory limitation.


208-237: Duplicate reminderSettings causes needless overwrites

reminderSettings is built twice – once in additionalData and once inline – then the spread operator overwrites the first instance. Drop the inline copy to avoid confusion.

-          reminderSettings: {
-            enableAutoReminder: this.enableAutoReminder,
-            reminderDays: this.reminderDays,
-            reminderCount: this.reminderCount,
-          },
...
-          ...additionalData,
+          ...additionalData,
components/ilovepdf/actions/process-files/process-files.mjs (1)

64-71: Same knownLength concern as other components

See earlier PandaDoc comment – omit knownLength when it is undefined.

components/nyckel/common/common-image.mjs (1)

15-24: Behaviour change: URLs are now downloaded instead of passed as JSON

Downloading remote images server-side may increase latency and bandwidth costs but yields a consistent interface – good trade-off.
Consider retaining the original “pass-through URL” optimisation for large public images via a prop toggle.

components/openai/actions/chat/chat.mjs (1)

49-54: Removal of model/audio compatibility check may surface late-stage API errors

Previously the action failed fast when audio was supplied with a non-audio model. Now the request will reach OpenAI and return a 400, which is a poorer DX.

Re-introduce a lightweight guard:

+if (this.audio && !this.modelId.includes("gpt-4o-audio-preview")) {
+  throw new Error("Audio input is only supported with the gpt-4o-audio-preview model");
+}

This keeps users from incurring an unnecessary API call.

components/flippingbook/actions/update-flipbook/update-flipbook.mjs (1)

50-57: Minor duplication: consider extracting getFileData into a shared util

Both create- and update-flipbook actions expose identical getFileData logic through createFlipbook.methods. A small shared helper under components/flippingbook/common/file-utils.mjs would keep cross-action behaviour in sync and simplify future fixes.

components/imagga/common/utils.mjs (1)

42-49: Optional: drop knownLength when unavailable

metadata.size may be undefined for remote URLs, which causes some servers to reject the upload. Consider omitting knownLength when the value is falsy.

-  formData.append("image", stream, {
-    contentType: metadata.contentType,
-    knownLength: metadata.size,
-    filename: metadata.name,
-  });
+  formData.append("image", stream, {
+    contentType: metadata.contentType,
+    ...(metadata.size && { knownLength: metadata.size }),
+    filename: metadata.name,
+  });
components/openai/actions/analyze-image-content/analyze-image-content.mjs (1)

62-69: Dead code — imageUrl prop was removed but the branch remains

this.imageUrl is always undefined, so this block will never run and only confuses future readers.

-    if (this.imageUrl) {
-      data.thread.messages[0].content.push({
-        type: "image_url",
-        image_url: {
-          url: this.imageUrl,
-        },
-      });
-    }
components/alttext_ai/actions/generate-alt-text/generate-alt-text.mjs (1)

69-82: Reading entire file into memory can blow up large workflows

For very large images the chunks -> Buffer.concat pattern will hold the whole file in memory.
Consider streaming to base64 on-the-fly or enforcing a reasonable size limit to avoid OOM crashes.

If the API actually accepts multipart files, you could avoid base64 altogether and pipe the stream.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ac56587 and a0bc8d7.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (107)
  • components/_2markdown/_2markdown.app.mjs (1 hunks)
  • components/_2markdown/actions/html-file-to-markdown/html-file-to-markdown.mjs (2 hunks)
  • components/_2markdown/actions/pdf-to-markdown/pdf-to-markdown.mjs (3 hunks)
  • components/_2markdown/package.json (2 hunks)
  • components/airparser/actions/upload-document-parse/upload-document-parse.mjs (3 hunks)
  • components/airparser/package.json (2 hunks)
  • components/akeneo/actions/create-a-new-product-media-file/create-a-new-product-media-file.mjs (3 hunks)
  • components/akeneo/package.json (2 hunks)
  • components/alttext_ai/actions/generate-alt-text/generate-alt-text.mjs (2 hunks)
  • components/alttext_ai/package.json (2 hunks)
  • components/askyourpdf/actions/add-document-via-file-upload/add-document-via-file-upload.mjs (1 hunks)
  • components/askyourpdf/askyourpdf.app.mjs (2 hunks)
  • components/askyourpdf/common/utils.mjs (1 hunks)
  • components/askyourpdf/package.json (2 hunks)
  • components/autodesk/actions/upload-file/upload-file.mjs (3 hunks)
  • components/autodesk/package.json (2 hunks)
  • components/azure_storage/actions/upload-blob/upload-blob.mjs (4 hunks)
  • components/azure_storage/common/utils.mjs (0 hunks)
  • components/azure_storage/package.json (2 hunks)
  • components/boldsign/actions/send-document-template/send-document-template.mjs (3 hunks)
  • components/boldsign/package.json (2 hunks)
  • components/box/actions/upload-file-version/upload-file-version.mjs (2 hunks)
  • components/box/actions/upload-file/upload-file.mjs (2 hunks)
  • components/box/box.app.mjs (1 hunks)
  • components/box/common/common-file-upload.mjs (2 hunks)
  • components/box/common/utils.mjs (1 hunks)
  • components/box/package.json (2 hunks)
  • components/canva/actions/create-design-import-job/create-design-import-job.mjs (2 hunks)
  • components/canva/actions/upload-asset/upload-asset.mjs (2 hunks)
  • components/canva/canva.app.mjs (1 hunks)
  • components/canva/package.json (2 hunks)
  • components/claid_ai/actions/correct-color-lighting/correct-color-lighting.mjs (2 hunks)
  • components/claid_ai/actions/remove-background/remove-background.mjs (2 hunks)
  • components/claid_ai/actions/upscale-image/upscale-image.mjs (2 hunks)
  • components/claid_ai/claid_ai.app.mjs (1 hunks)
  • components/claid_ai/package.json (2 hunks)
  • components/cradl_ai/actions/common/common.mjs (2 hunks)
  • components/cradl_ai/actions/parse-document-human-in-loop/parse-document-human-in-loop.mjs (1 hunks)
  • components/cradl_ai/actions/parse-document/parse-document.mjs (1 hunks)
  • components/cradl_ai/package.json (2 hunks)
  • components/docsbot_ai/actions/upload-source-file/upload-source-file.mjs (3 hunks)
  • components/docsbot_ai/docsbot_ai.app.mjs (1 hunks)
  • components/docsbot_ai/package.json (2 hunks)
  • components/egnyte/actions/upload-file/upload-file.mjs (2 hunks)
  • components/egnyte/package.json (2 hunks)
  • components/fileforge/actions/generate-pdf/generate-pdf.mjs (3 hunks)
  • components/fileforge/common/utils.mjs (0 hunks)
  • components/fileforge/package.json (2 hunks)
  • components/flippingbook/actions/create-flipbook/create-flipbook.mjs (2 hunks)
  • components/flippingbook/actions/update-flipbook/update-flipbook.mjs (2 hunks)
  • components/flippingbook/flippingbook.app.mjs (1 hunks)
  • components/flippingbook/package.json (2 hunks)
  • components/google_drive/actions/update-file/update-file.mjs (3 hunks)
  • components/google_drive/actions/upload-file/upload-file.mjs (3 hunks)
  • components/google_drive/common/filePathOrUrl.mjs (0 hunks)
  • components/google_drive/common/utils.mjs (1 hunks)
  • components/google_drive/google_drive.app.mjs (1 hunks)
  • components/google_drive/package.json (1 hunks)
  • components/happy_scribe/actions/submit-file/submit-file.mjs (2 hunks)
  • components/happy_scribe/package.json (2 hunks)
  • components/ilovepdf/actions/process-files/process-files.mjs (3 hunks)
  • components/ilovepdf/ilovepdf.app.mjs (1 hunks)
  • components/ilovepdf/package.json (2 hunks)
  • components/imagga/actions/analyze-image/analyze-image.mjs (1 hunks)
  • components/imagga/actions/process-batch/process-batch.mjs (1 hunks)
  • components/imagga/common/utils.mjs (1 hunks)
  • components/imagga/imagga.app.mjs (1 hunks)
  • components/imagga/package.json (2 hunks)
  • components/leaddyno/leaddyno.app.mjs (1 hunks)
  • components/llmwhisperer/actions/extract-text/extract-text.mjs (4 hunks)
  • components/llmwhisperer/package.json (2 hunks)
  • components/lokalise/actions/upload-file/upload-file.mjs (3 hunks)
  • components/lokalise/package.json (2 hunks)
  • components/mapbox/actions/create-tileset/create-tileset.mjs (4 hunks)
  • components/mapbox/package.json (2 hunks)
  • components/microsoft_onedrive/actions/upload-file/upload-file.mjs (3 hunks)
  • components/microsoft_onedrive/package.json (2 hunks)
  • components/mistral_ai/actions/upload-file/upload-file.mjs (2 hunks)
  • components/mistral_ai/package.json (2 hunks)
  • components/monday/actions/update-column-values/update-column-values.mjs (4 hunks)
  • components/monday/package.json (2 hunks)
  • components/nyckel/actions/classify-image/classify-image.mjs (2 hunks)
  • components/nyckel/actions/extract-text-from-image/extract-text-from-image.mjs (2 hunks)
  • components/nyckel/common/common-image.mjs (2 hunks)
  • components/nyckel/nyckel.app.mjs (1 hunks)
  • components/nyckel/package.json (2 hunks)
  • components/ocrspace/actions/common/process-base.mjs (1 hunks)
  • components/ocrspace/actions/process-image/process-image.mjs (1 hunks)
  • components/ocrspace/actions/process-pdf/process-pdf.mjs (1 hunks)
  • components/ocrspace/common/utils.mjs (2 hunks)
  • components/ocrspace/ocrspace.app.mjs (1 hunks)
  • components/ocrspace/package.json (2 hunks)
  • components/onlinecheckwriter/actions/mail-pdf-document/mail-pdf-document.mjs (3 hunks)
  • components/onlinecheckwriter/package.json (2 hunks)
  • components/onlyoffice_docspace/actions/upload-file/upload-file.mjs (2 hunks)
  • components/onlyoffice_docspace/common/utils.mjs (1 hunks)
  • components/onlyoffice_docspace/onlyoffice_docspace.app.mjs (2 hunks)
  • components/onlyoffice_docspace/package.json (2 hunks)
  • components/openai/actions/analyze-image-content/analyze-image-content.mjs (3 hunks)
  • components/openai/actions/chat/chat.mjs (3 hunks)
  • components/openai/actions/common/common.mjs (5 hunks)
  • components/openai/actions/create-batch/create-batch.mjs (3 hunks)
  • components/openai/actions/create-transcription/create-transcription.mjs (2 hunks)
  • components/openai/actions/upload-file/upload-file.mjs (2 hunks)
  • components/openai/openai.app.mjs (1 hunks)
  • components/openai/package.json (2 hunks)
  • components/pandadoc/actions/create-document-attachment/create-document-attachment.mjs (3 hunks)
⛔ Files not processed due to max files limit (27)
  • components/pandadoc/actions/create-document-from-file/create-document-from-file.mjs
  • components/pandadoc/package.json
  • components/pandadoc/pandadoc.app.mjs
  • components/pdf4me/actions/compress-pdf/compress-pdf.mjs
  • components/pdf4me/actions/convert-to-pdf/convert-to-pdf.mjs
  • components/pdf4me/actions/merge-pdfs/merge-pdfs.mjs
  • components/pdf4me/common/utils.mjs
  • components/pdf4me/package.json
  • components/pdf4me/pdf4me.app.mjs
  • components/podio/actions/upload-file/upload-file.mjs
  • components/podio/package.json
  • components/slack/actions/upload-file/upload-file.mjs
  • components/slack/package.json
  • components/slack/slack.app.mjs
  • components/stannp/actions/create-campaign/create-campaign.mjs
  • components/stannp/common/utils.mjs
  • components/stannp/package.json
  • components/zamzar/actions/start-job-from-file/start-job-from-file.mjs
  • components/zamzar/common/utils.mjs
  • components/zamzar/package.json
  • components/zamzar/zamzar.app.mjs
  • components/zoho_crm/actions/upload-attachment/upload-attachment.mjs
  • components/zoho_crm/package.json
  • components/zoho_desk/actions/add-ticket-attachment/add-ticket-attachment.mjs
  • components/zoho_desk/common/utils.mjs
  • components/zoho_desk/package.json
  • components/zoho_desk/zoho_desk.app.mjs
💤 Files with no reviewable changes (3)
  • components/fileforge/common/utils.mjs
  • components/azure_storage/common/utils.mjs
  • components/google_drive/common/filePathOrUrl.mjs
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: pnpm publish
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Lint Code Base
  • GitHub Check: Verify TypeScript components
🔇 Additional comments (90)
components/leaddyno/leaddyno.app.mjs (1)

11-11: Trivial change
Added a trailing newline at end of file; no functional impact.

components/mistral_ai/package.json (1)

16-16: Verify platform dependency update compatibility.
Upgrading @pipedream/platform to ^3.1.0 is required for getFileStreamAndMetadata. Please confirm there are no unintended breaking changes in v3.1.0 that impact this component’s functionality.

components/cradl_ai/package.json (1)

16-16: Confirm platform SDK upgrade.
Moving to @pipedream/platform@^3.1.0 is necessary for the new file utilities. Verify that all existing actions in this component remain compatible with the updated SDK.

components/alttext_ai/package.json (1)

16-16: Validate platform dependency update.
Upgrading to @pipedream/platform@^3.1.0 unlocks the new streaming API. Confirm there are no regressions with other actions in this component.

components/claid_ai/package.json (2)

3-3: Bump package version to 0.2.0
Aligns with the coordinated versioning across components in this PR.


16-16: ```shell
#!/bin/bash

Re-verify that no direct fs imports or requires remain in the claid_ai component

rg -n "require(['"]fs['"])" components/claid_ai
rg -n "import fs" components/claid_ai


</details>
<details>
<summary>components/azure_storage/package.json (2)</summary>

`3-3`: **Bump package version to 0.2.0**  
Consistent with the Azure Storage component’s update cycle.

---

`16-16`: Let’s re-run the search without the invalid `-R` flag to verify there are truly no lingering imports:


```shell
#!/bin/bash
# Correctly check for any references to common/utils.mjs in the azure_storage component
rg -n "common/utils\.mjs" components/azure_storage

This will confirm whether any stray imports remain.

components/microsoft_onedrive/package.json (2)

3-3: Bump package version to 1.7.0
Keeps parity with other components handling file URLs/paths improvements.


13-13: ```shell
#!/bin/bash

Check for any remaining file-type imports in the OneDrive component

rg -n "require(['"]file-type['"]]|import .*\bfile-type\b" components/microsoft_onedrive

Verify file-type is not listed as a dependency in package.json

grep -R '"file-type"' components/microsoft_onedrive/package.json || true


</details>
<details>
<summary>components/mapbox/package.json (2)</summary>

`3-3`: **Bump package version to 0.2.0**  
Aligns with the standard release cadence for Mapbox components.

---

`16-16`: **Upgrade @pipedream/platform to ^3.1.0**  
Enables use of the latest file‐stream utilities; no additional changes needed here.

</details>
<details>
<summary>components/cradl_ai/actions/parse-document-human-in-loop/parse-document-human-in-loop.mjs (1)</summary>

`8-8`: **Bump action version to 0.1.0**  
Matches the new minor release for the human-in-loop parsing action; functionality remains unchanged.

</details>
<details>
<summary>components/imagga/package.json (1)</summary>

`16-16`: **Validate compatibility with @pipedream/platform v3.1.0**  
Upgrading the dependency to `^3.1.0` should support all new file utilities (e.g., `getFileStreamAndMetadata`). Run integration tests to confirm no missing exports or breaking changes in the platform SDK.

</details>
<details>
<summary>components/llmwhisperer/package.json (2)</summary>

`3-3`: **Approve minor version bump to 0.2.0**  
Incrementing from `0.1.0` to `0.2.0` is a backward-compatible change. Versioning aligns with non-breaking enhancements in file handling.

---

`16-16`: **Verify removal of direct fs dependency and upgrade to @pipedream/platform v3.1.0**  
Ensure no residual `fs` imports remain and that all file operations now use platform utilities.  

```shell
#!/bin/bash
# Check for lingering fs imports in llmwhisperer
rg -n "require\(['\"]fs['\"]\)|import .*fs" -l components/llmwhisperer
components/box/package.json (1)

13-13: Validate @pipedream/platform v3.1.0 upgrade
The dependency has been updated to ^3.1.0. Verify that Box actions using getFileUploadBody and related async utilities work correctly with this SDK version.

components/boldsign/package.json (2)

3-3: Approve version bump to 0.2.0
Moving from 0.1.0 to 0.2.0 is aligned with the non-breaking refactor to platform file utilities.


16-16: Validate compatibility with @pipedream/platform v3.1.0
Confirm that getFileStreamAndMetadata is fully supported in v3.1.0 and that no legacy fs calls remain in the BoldSign actions.

components/fileforge/package.json (2)

3-3: Approve version bump to 0.2.0
Increment from 0.1.0 to 0.2.0 indicates backward-compatible enhancements for fileforge’s PDF generation workflows.


16-16: Validate @pipedream/platform v3.1.0 upgrade
Ensure that getFileStreamAndMetadata properly replaces prior fs-based logic in both generate-pdf and utils.mjs. Run end-to-end tests in a sandbox.

components/ocrspace/actions/process-image/process-image.mjs (1)

8-8: Bump action version
Updated the action version from 0.0.1 to 0.1.0 to reflect the standardized file input handling changes.

components/canva/package.json (2)

3-3: Bump package version
Incremented version to 0.3.0 following internal file handling refactor.


16-16: Upgrade platform dependency
Updated @pipedream/platform to ^3.1.0 to leverage the new file streaming utilities.

components/flippingbook/package.json (2)

3-3: Major version bump
Raised version to 1.0.0—ensure the breaking change (removal of fileUrl property and consolidation to filePath) is documented in the CHANGELOG and upgrade guides.


16-16: Upgrade platform dependency
Bumped @pipedream/platform to ^3.1.0 to align with standardized async file handling utilities.

components/onlyoffice_docspace/package.json (2)

3-3: Bump package version
Version updated to 0.2.0 to reflect async form data and file handling enhancements.


16-16: Upgrade platform dependency
Updated @pipedream/platform to ^3.1.0 for getFileStreamAndMetadata support.

components/lokalise/package.json (2)

3-3: Bump package version
Incremented to 0.2.0 following migration to async streaming with getFileStream.


16-16: Upgrade platform dependency
Updated @pipedream/platform to ^3.1.0 to standardize file URL and path handling.

components/akeneo/package.json (2)

3-3: Bump component version to 0.1.0
Aligns with the new action version for file URL/path improvements.


13-13: Upgrade @pipedream/platform dependency to ^3.1.0
Matches the PR-wide migration to v3 utilities for async file handling.

components/monday/package.json (2)

3-3: Bump component version to 0.8.0
Reflects the new release containing file URL/path enhancements.


17-17: Upgrade @pipedream/platform dependency to ^3.1.0
Ensures access to the updated getFileStreamAndMetadata utilities.

components/ocrspace/package.json (2)

3-3: Bump component version to 0.2.0
Prepares OCRSpace component for the file handling improvements release.


16-16: Upgrade @pipedream/platform dependency to ^3.1.0
Brings in the latest async file utilities across components.

components/airparser/package.json (2)

3-3: Bump component version to 0.2.0
Marks Airparser release with platform v3 compatibility.


16-16: Upgrade @pipedream/platform dependency to ^3.1.0
Aligns Airparser with the new file-stream utilities.

components/happy_scribe/package.json (2)

3-3: Bump component version to 0.2.0
Signals Happy Scribe component update for async file input support.


16-16: Upgrade @pipedream/platform dependency to ^3.1.0
Ensures availability of getFileStream for base64, URL, and path inputs.

components/docsbot_ai/package.json (2)

3-3: Semantic version bump
Version updated from 0.1.0 to 0.2.0 to reflect the file URL/path enhancements.


16-16: Upgrade @pipedream/platform to ^3.1.0
This aligns with the platform utility refactor (getFileStreamAndMetadata). Ensure no breaking changes in the new version.

components/cradl_ai/actions/parse-document/parse-document.mjs (1)

8-8: Bump action version
Updated version to "0.1.0" consistent with other component revisions. Confirm corresponding release notes or changelog updates.

components/nyckel/package.json (2)

3-3: Semantic version bump
Version bumped from 0.1.0 to 0.2.0 to capture the file handling improvements.


16-16: Upgrade platform dependency
Updated @pipedream/platform to ^3.1.0, matching the standardized file input utilities.

components/_2markdown/package.json (2)

3-3: Version increment
Updated component version to 0.2.0 following the bulk refactor.


16-16: Platform dependency update
Upgraded @pipedream/platform to ^3.1.0 for consistent use of file streaming utilities.

components/egnyte/package.json (2)

3-3: Package version bump
Incremented version to 0.2.0 in alignment with other packages.


16-16: Upgrade @pipedream/platform
Upgraded to ^3.1.0 to leverage the new file input utilities.

components/openai/package.json (1)

17-17: Verify platform dependency upgrade to ^3.1.0
Upgrading @pipedream/platform to ^3.1.0 aligns with the new getFileStreamAndMetadata API, but please confirm there are no unresolved peer dependency conflicts and all imports remain compatible.

components/onlinecheckwriter/package.json (1)

16-16: Upgrade @pipedream/platform to ^3.1.0
This change is required for the getFileStreamAndMetadata utility. Verify that all components build correctly against platform v3.1.0 and that no legacy code still references removed APIs.

components/askyourpdf/package.json (1)

13-14: Dependencies bumped: platform → ^3.1.0, form-data → ^4.0.0
Aligns with the use of getFileStreamAndMetadata and multipart form-data improvements. Confirm that the async getFormData workflow in askyourpdf.app.mjs functions as expected with these versions.

components/autodesk/package.json (1)

16-16: Upgrade @pipedream/platform dependency to ^3.1.0
Needed for the new getFileStreamAndMetadata API in the upload-file action. Please validate that the action imports and error handling remain correct under v3.1.0.

components/ilovepdf/package.json (1)

16-17: Dependencies updated: platform → ^3.1.0, form-data → ^4.0.0
Ensures compatibility with getFileStreamAndMetadata and improved multipart handling. Run a full integration test to confirm process-files action behavior is unaffected.

components/nyckel/actions/extract-text-from-image/extract-text-from-image.mjs (2)

9-9: Version bump looks correct

Minor‐version increment from 0.0.10.1.0 matches the behavioural change (async file handling).


31-31: Good catch turning getImageData() into an awaited call

Awaiting the promise prevents a possible race condition where an unresolved promise would be spread into the request object. 👍

components/box/box.app.mjs (1)

16-18: Property description updated—check consistency with downstream validation

Down-stream helpers (e.g. common/utils.mjs -> getFileData) now accept both URLs and /tmp paths, so this UI text is aligned. Make sure any older validations that assumed a local path (e.g. regex checks) have been removed; otherwise users could hit confusing “invalid path” errors.

components/_2markdown/_2markdown.app.mjs (1)

9-10: Label/description update LGTM

Wording is now consistent with the cross-component file-URL standard.

components/claid_ai/actions/remove-background/remove-background.mjs (1)

4-4: 👍 Switched to getFileStreamAndMetadata

Great move—eliminates manual fs handling and guarantees metadata is present.

components/openai/actions/upload-file/upload-file.mjs (1)

31-39: Good adoption of unified file helper

Transition to getFileStreamAndMetadata improves reliability and preserves filename metadata—LGTM.

components/nyckel/actions/classify-image/classify-image.mjs (1)

49-49: Awaiting getImageData fixes race condition

Waiting for the promise before spreading the object prevents undefined payloads—nice catch.

components/askyourpdf/actions/add-document-via-file-upload/add-document-via-file-upload.mjs (1)

9-16: Prop docs updated – looks good

Label/description now matches the new cross-component convention (URL or /tmp path). No further issues spotted.

components/box/actions/upload-file/upload-file.mjs (1)

50-56: Nice catch making getFileUploadBody awaitable

The added await aligns with the now-async helper and prevents the request from being sent with an unresolved Promise.
No additional concerns.

components/google_drive/google_drive.app.mjs (1)

158-162: Change looks good – property description matches the new cross-component convention

Only the label/description were updated; type and behaviour stay unchanged. No further action needed.

components/nyckel/nyckel.app.mjs (1)

30-34: Consistent wording – looks good

Label/description now match the platform-wide “File Path or URL” wording.

components/google_drive/common/utils.mjs (1)

261-273: Let’s inspect the imports and usage of getFileStream in the Google Drive update action:

#!/bin/bash
# Show import statements in update-file.mjs
grep -n "import" components/google_drive/actions/update-file/update-file.mjs

# Show lines around getFileStream usage
grep -n -C3 "getFileStream" components/google_drive/actions/update-file/update-file.mjs
components/imagga/actions/analyze-image/analyze-image.mjs (1)

9-18: Change looks good – single source of truth for the image input

Switching to a single imageFile prop simplifies the interface and aligns with the
new unified file-handling utility. No issues spotted here.

components/_2markdown/actions/pdf-to-markdown/pdf-to-markdown.mjs (1)

2-2: Use of getFileStreamAndMetadata looks good

Switching from fs to the platform helper keeps the action compatible with both URLs and /tmp paths and removes the sync I/O.

components/cradl_ai/actions/common/common.mjs (2)

3-3: 👍 Replacing synchronous fs.readFileSync with streaming helper

The import aligns this module with the new file-handling convention and removes blocking I/O.


49-58: Confirm the API accepts a stream – it previously received a Buffer

getFileStream() returns a Readable stream whereas the prior implementation sent a Buffer.
Most axios back-ends handle both, but if the endpoint expects Content-Length or random access it may break.

Please re-run the integration tests for large (>5 MB) files and, if necessary, compute and set the Content-Length header:

-const fileData = await getFileStream(this.filePath);
+const { stream, metadata } = await getFileStream(this.filePath);
+
+// axios will set transfer-encoding: chunked; add length if the API demands it
+const headers = {
+  "Content-Type": this.contentType,
+  ...(metadata.size && { "Content-Length": metadata.size }),
+};
components/_2markdown/actions/html-file-to-markdown/html-file-to-markdown.mjs (1)

2-2: Consistent helper import — good move

Keeps the two 2Markdown actions in sync with the new pattern.

components/ilovepdf/ilovepdf.app.mjs (1)

9-11: Making filePaths mandatory could be a breaking change

optional: true was removed. Existing workflows that dynamically build the list may now fail validation.

Recommend retaining optionality or bumping the major version of the app to signal a breaking contract.

-  type: "string[]",
-  label: "File Paths or URLs",
-  description: "...",
+  type: "string[]",
+  label: "File Paths or URLs",
+  description: "...",
+  optional: true,
components/box/common/common-file-upload.mjs (1)

30-33: Good addition of contentType and explicit filename

These headers help Box detect the MIME type and preserve the original name.

components/canva/canva.app.mjs (1)

42-44: Label & description update looks good

The new wording clearly states that either a URL or /tmp path is accepted. No further action needed.

components/ocrspace/ocrspace.app.mjs (1)

14-16: Documentation tweak acknowledged

Consistent phrasing with the rest of the repo – thanks for the alignment.

components/google_drive/actions/upload-file/upload-file.mjs (1)

38-43: Prop name aligns but keep an eye on cross-file usages

filePath is now sourced from the app definition. Make sure all downstream actions/tests referring to the old file prop are migrated; otherwise callers will get a validation error at runtime.

components/openai/actions/create-batch/create-batch.mjs (1)

54-61: Optional size header

Similar to the Autodesk upload, metadata.size can be undefined, yet it is passed as knownLength. While FormData tolerates undefined, some runtimes mis-handle it. You may want to conditionally supply knownLength only when it is a finite number.

components/monday/actions/update-column-values/update-column-values.mjs (1)

67-76: Verify knownLength reliability

For files coming from a URL without a Content-Length header, metadata.size may be undefined, yet it is forwarded to FormData as knownLength. Monday’s API can reject uploads without a valid size. Please confirm this edge case or conditionally omit the option.

components/ilovepdf/actions/process-files/process-files.mjs (1)

78-83: Headers are correctly derived – nice!

components/happy_scribe/actions/submit-file/submit-file.mjs (1)

24-29: Verify Happy Scribe API accepts a stream

Previously a Buffer was sent; switching to a stream may change Content-Length handling. Please confirm with the API or wrap the stream in FormData if a multipart upload is required.

components/askyourpdf/common/utils.mjs (1)

5-9: 👍 Async traversal fix looks good

Switching from forEach with an async callback to an awaited for … of loop guarantees sequential execution and proper error bubbling.

components/openai/actions/chat/chat.mjs (1)

147-148: Awaiting _getChatArgs requires it to be truly async

Good catch changing the invocation to await. Verify that common._getChatArgs now returns a Promise in every code path; otherwise this will wrap a non-promise value and may mask sync exceptions.

components/openai/actions/common/common.mjs (1)

121-168: New async signature may break callers – double-check every run() that invokes _getChatArgs()

_getChatArgs is now async and returns a Promise. Every consumer must await it:

-const chatArgs = this._getChatArgs();
+const chatArgs = await this._getChatArgs();

Search all OpenAI actions in the repo to ensure none call it without await; otherwise they will pass a Promise to the OpenAI SDK and fail at runtime.

components/onlyoffice_docspace/actions/upload-file/upload-file.mjs (1)

43-50: Double-check multipart handling for the file field

You pass a plain string to the File field and set MULTIPART_FORM_DATA_HEADERS manually.
If this.app.post() no longer wraps the payload with FormData (since the utils were refactored to be async), the request will send JSON instead of multipart.

Please verify that app.post():

  1. Detects data.File values that are paths/URLs and converts them to a stream via getFileStreamAndMetadata.
  2. Re-creates the Content-Type: multipart/form-data header with the correct boundary.
    Manually providing Content-Type often leads to incorrect boundaries.

If either of these assumptions is false, the upload will fail. Consider preparing the FormData here instead of relying on hidden magic.

components/google_drive/actions/update-file/update-file.mjs (1)

117-118: ```shell
#!/bin/bash
set -eux

Show imports in the target file to identify where getFileStream is coming from

sed -n '1,50p' components/google_drive/actions/update-file/update-file.mjs

Search for getFileStream definition across the repo

rg -n "export (async )?function getFileStream" -C 3 --glob "*.{js,ts,mjs}"

Search for getFileStreamAndMetadata definition across the repo

rg -n "export (async )?function getFileStreamAndMetadata" -C 3 --glob "*.{js,ts,mjs}"


</details>
<details>
<summary>components/imagga/actions/process-batch/process-batch.mjs (1)</summary>

`17-21`: **LGTM – clearer property label**

The new label and description make the accepted input explicit.

</details>
<details>
<summary>components/openai/openai.app.mjs (1)</summary>

`257-260`: **Label/description update looks good**

Consistent wording across components improves UX.

</details>
<details>
<summary>components/llmwhisperer/actions/extract-text/extract-text.mjs (1)</summary>

`30-35`: **Typos in prop names / docs leak into query-string**

`pageSeperator` & `page_seperator` are misspelled (“Separator”).  
Unless the backend intentionally uses the typo, this will silently break the feature. Same for the description typo “stratergy”.

Confirm the expected spelling on the API side; if it’s a typo, fix both the prop key and the query-param to avoid hard-to-trace errors.  
  


Also applies to: 41-41, 140-144

</details>
<details>
<summary>components/openai/actions/analyze-image-content/analyze-image-content.mjs (1)</summary>

`80-88`: **Guard against unknown content-type**

`getFileStreamAndMetadata` can return `metadata.contentType === undefined` when downloading from certain URLs.  
OpenAI rejects uploads without a valid `Content-Type`.

```diff
-      fileData.append("file", stream, {
-        contentType: metadata.contentType,
+      fileData.append("file", stream, {
+        contentType: metadata.contentType ?? "application/octet-stream",
components/alttext_ai/actions/generate-alt-text/generate-alt-text.mjs (1)

16-21: Great usability touch with the alert prop

The clarifying alert avoids common mis-configuration errors—nice!

Comment on lines +125 to 127
label: "File Path or URL",
description: "The file to upload. Provide either a file URL or a path to a file in the `/tmp` directory (for example, `/tmp/myFile.txt`)",
},
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Name collision may confuse users (file vs filePath)

The app now exposes:
file – “Source File Path” (path only)
filePath – “File Path or URL” (path or URL)

Because both ultimately represent a file, consider unifying them (or clearly deprecating one) to avoid users picking the wrong prop when building flows.

🤖 Prompt for AI Agents
In components/docsbot_ai/docsbot_ai.app.mjs around lines 125 to 127, there is a
naming collision between the properties `file` and `filePath`, both representing
file locations but with different scopes. To fix this, unify these properties
into a single clear and descriptive name that covers both use cases or clearly
deprecate one of them with appropriate warnings and documentation updates to
prevent user confusion when selecting properties for flows.

Comment on lines 34 to 36
alertType: "info",
content: "Please provide exactly one of File URL or File Path.",
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

“Info” alert is now misleading after URL/Path consolidation

Since the dedicated File URL prop was removed, users can no longer provide “exactly one of URL or Path.”
Keeping this alert will confuse them.

Either (a) drop the alert entirely, or (b) re-phrase to clarify that the single field accepts both formats.

-    info: {
-      type: "alert",
-      alertType: "info",
-      content: "Please provide exactly one of File URL or File Path.",
-    },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
alertType: "info",
content: "Please provide exactly one of File URL or File Path.",
},
🤖 Prompt for AI Agents
In components/flippingbook/flippingbook.app.mjs around lines 34 to 36, the alert
message still refers to providing exactly one of File URL or File Path, which is
misleading since the File URL prop was removed and the single field now accepts
both formats. Update the alert message to clarify that the single input field
accepts either a URL or a file path, or remove the alert entirely if it is no
longer necessary.

Comment on lines 92 to +101
const data = new FormData();
const content = fs.createReadStream(file.includes("tmp/")
? file
: `/tmp/${file}`);
const {
stream, metadata,
} = await getFileStreamAndMetadata(file);

data.append("file", content);
data.append("file", stream, {
contentType: metadata.contentType,
knownLength: metadata.size,
filename: metadata.name,
});
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Guard against missing metadata & send MIME safely

metadata.size and metadata.contentType may be undefined for some URLs (e.g. when the server omits Content-Length or Content-Type). Passing undefined to FormData as knownLength/contentType triggers runtime errors in Node.

-const { stream, metadata } = await getFileStreamAndMetadata(file);
-
-data.append("file", stream, {
-  contentType: metadata.contentType,
-  knownLength: metadata.size,
-  filename: metadata.name,
-});
+const { stream, metadata } = await getFileStreamAndMetadata(file);
+const options = {
+  filename: metadata.name,
+};
+if (metadata.contentType) options.contentType = metadata.contentType;
+if (Number.isFinite(metadata.size)) options.knownLength = metadata.size;
+
+data.append("file", stream, options);

This avoids unexpected ERR_STREAM_PREMATURE_CLOSE / FormData length calculation errors.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const data = new FormData();
const content = fs.createReadStream(file.includes("tmp/")
? file
: `/tmp/${file}`);
const {
stream, metadata,
} = await getFileStreamAndMetadata(file);
data.append("file", content);
data.append("file", stream, {
contentType: metadata.contentType,
knownLength: metadata.size,
filename: metadata.name,
});
const data = new FormData();
const { stream, metadata } = await getFileStreamAndMetadata(file);
const options = {
filename: metadata.name,
};
if (metadata.contentType) options.contentType = metadata.contentType;
if (Number.isFinite(metadata.size)) options.knownLength = metadata.size;
data.append("file", stream, options);
🤖 Prompt for AI Agents
In components/openai/actions/create-transcription/create-transcription.mjs
around lines 92 to 101, the code uses metadata.size and metadata.contentType
directly when appending to FormData, which can be undefined and cause runtime
errors. To fix this, add checks to ensure metadata.size and metadata.contentType
are defined before passing them to FormData; if they are undefined, omit those
properties or provide safe defaults to prevent errors like
ERR_STREAM_PREMATURE_CLOSE.

Comment on lines +59 to +67
const {
stream, metadata,
} = await getFileStreamAndMetadata(this.image);
const formData = new FormData();
formData.append("file", fs.createReadStream(checkTmp(this.image)));
formData.append("file", stream, {
contentType: metadata.contentType,
knownLength: metadata.size,
filename: metadata.name,
});
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Header metadata could be incomplete & redundant local variable

  1. metadata.contentType, metadata.size, metadata.name are passed blindly.
    contentType or size may be undefined when the source is a URL and the remote
    server does not provide those headers – many do not. form-data will then serialise
    undefined and the request may be rejected by the API.
  2. imageUrl (defined at line 41) is never mutated, so you can drop the alias and just
    use this.image.
-      const {
-        stream, metadata,
-      } = await getFileStreamAndMetadata(this.image);
+      const { stream, metadata } =
+        await getFileStreamAndMetadata(this.image);

       const formData = new FormData();
-      formData.append("file", stream, {
-        contentType: metadata.contentType,
-        knownLength: metadata.size,
-        filename: metadata.name,
-      });
+      const fileOptions = {
+        filename: metadata?.name ?? "upload",
+      };
+      if (metadata?.contentType)   fileOptions.contentType = metadata.contentType;
+      if (metadata?.size != null)  fileOptions.knownLength = metadata.size;
+      formData.append("file", stream, fileOptions);

This keeps the request robust when metadata is unavailable and eliminates the extra variable.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const {
stream, metadata,
} = await getFileStreamAndMetadata(this.image);
const formData = new FormData();
formData.append("file", fs.createReadStream(checkTmp(this.image)));
formData.append("file", stream, {
contentType: metadata.contentType,
knownLength: metadata.size,
filename: metadata.name,
});
const { stream, metadata } =
await getFileStreamAndMetadata(this.image);
const formData = new FormData();
const fileOptions = {
filename: metadata?.name ?? "upload",
};
if (metadata?.contentType) fileOptions.contentType = metadata.contentType;
if (metadata?.size != null) fileOptions.knownLength = metadata.size;
formData.append("file", stream, fileOptions);
🤖 Prompt for AI Agents
In components/claid_ai/actions/upscale-image/upscale-image.mjs around lines 59
to 67, the metadata fields contentType, size, and name are used directly without
checking if they are undefined, which can cause issues if the source is a URL
lacking these headers. Update the code to conditionally include these fields
only if they are defined to prevent sending undefined values in the form data.
Also, remove the unused imageUrl alias declared at line 41 and use this.image
directly to simplify the code.

Comment on lines +33 to 47
const {
stream, metadata,
} = await getFileStreamAndMetadata(this.filePath);

let response = await this.canva.importDesign({
$,
headers: {
"Import-Metadata": JSON.stringify({
"title_base64": titleBase64,
}),
"Content-Length": fs.statSync(filePath).size,
"Content-Length": metadata.size,
"Content-Type": "application/octet-stream",
},
data: fs.createReadStream(filePath),
data: stream,
});
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Content-Length may be undefined & wrong content-type hard-coded

metadata.size is only guaranteed for local /tmp files; for remote URLs it can be
undefined. Supplying an undefined Content-Length header breaks the request.

In addition, you already receive metadata.contentType, yet you always send
application/octet-stream. Let’s only include the header when present and use the
correct MIME type.

-        "Content-Length": metadata.size,
-        "Content-Type": "application/octet-stream",
+        ...(metadata.size != null && { "Content-Length": metadata.size }),
+        "Content-Type": metadata.contentType ?? "application/octet-stream",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const {
stream, metadata,
} = await getFileStreamAndMetadata(this.filePath);
let response = await this.canva.importDesign({
$,
headers: {
"Import-Metadata": JSON.stringify({
"title_base64": titleBase64,
}),
"Content-Length": fs.statSync(filePath).size,
"Content-Length": metadata.size,
"Content-Type": "application/octet-stream",
},
data: fs.createReadStream(filePath),
data: stream,
});
const {
stream, metadata,
} = await getFileStreamAndMetadata(this.filePath);
let response = await this.canva.importDesign({
$,
headers: {
"Import-Metadata": JSON.stringify({
"title_base64": titleBase64,
}),
...(metadata.size != null && { "Content-Length": metadata.size }),
"Content-Type": metadata.contentType ?? "application/octet-stream",
},
data: stream,
});
🤖 Prompt for AI Agents
In
components/canva/actions/create-design-import-job/create-design-import-job.mjs
around lines 33 to 47, the Content-Length header is set using metadata.size
which can be undefined for remote files, causing request failures. Also, the
Content-Type header is hardcoded to application/octet-stream instead of using
the actual metadata.contentType. Fix this by conditionally including the
Content-Length header only if metadata.size is defined, and set the Content-Type
header to metadata.contentType if available, otherwise omit it or use a sensible
default.

Comment on lines +5 to 24
async getFileData(filePath) {
const {
stream, metadata,
} = await getFileStreamAndMetadata(filePath);
return {
attributes: {
content_created_at: new Date(stats.ctimeMs).toISOString()
.split(".")[0] + "Z",
content_modified_at: new Date(stats.mtimeMs).toISOString()
.split(".")[0] + "Z",
name: path.basename(filePath),
parent: {
id: 0,
fileContent: stream,
fileMeta: {
attributes: {
content_created_at: new Date(metadata.lastModified).toISOString()
.split(".")[0] + "Z",
content_modified_at: new Date(metadata.lastModified).toISOString()
.split(".")[0] + "Z",
name: metadata.name,
parent: {
id: 0,
},
},
size: metadata.size,
contentType: metadata.contentType,
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

metadata.lastModified can be undefined – guard to prevent Invalid Date exceptions

new Date(undefined).toISOString() throws, breaking every upload where the upstream server doesn’t send a Last-Modified header (common for signed URLs).

-          content_created_at: new Date(metadata.lastModified).toISOString()
+          content_created_at: metadata.lastModified
+            ? new Date(metadata.lastModified).toISOString()
+            : new Date().toISOString()

Apply the same guard to content_modified_at.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In components/box/common/utils.mjs between lines 5 and 24, the code uses new
Date(metadata.lastModified).toISOString() without checking if
metadata.lastModified is defined, which can cause Invalid Date exceptions if
lastModified is undefined. To fix this, add a guard to check if
metadata.lastModified exists before converting it to a date string for both
content_created_at and content_modified_at. If lastModified is undefined, set
these fields to null or an appropriate default value to prevent errors.

Comment on lines +7 to +18
const imageList = await imageFile.reduce(async (acc, cur) => {
await delay(1000);
const uploadId = await uploadFile({
imageFile: cur,
imagga,
});

return [
...await acc,
uploadId,
];
}, []);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Asynchronous Array.reduce causes race conditions and wastes the 1 s delay

Array.reduce does not await earlier iterations; all uploads start concurrently, defeating the sequential delay and potentially hitting rate limits.

Refactor to a simple for…of loop:

-  const imageList = await imageFile.reduce(async (acc, cur) => {
-    await delay(1000);
-    const uploadId = await uploadFile({ imageFile: cur, imagga });
-    return [
-      ...await acc,
-      uploadId,
-    ];
-  }, []);
+  const imageList = [];
+  for (const file of imageFile) {
+    await delay(1000);
+    const uploadId = await uploadFile({ imageFile: file, imagga });
+    imageList.push(uploadId);
+  }

This guarantees one-second spacing between requests and preserves order.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const imageList = await imageFile.reduce(async (acc, cur) => {
await delay(1000);
const uploadId = await uploadFile({
imageFile: cur,
imagga,
});
return [
...await acc,
uploadId,
];
}, []);
const imageList = [];
for (const file of imageFile) {
await delay(1000);
const uploadId = await uploadFile({ imageFile: file, imagga });
imageList.push(uploadId);
}
🤖 Prompt for AI Agents
In components/imagga/common/utils.mjs between lines 7 and 18, the use of
asynchronous Array.reduce causes all uploads to start concurrently, ignoring the
intended 1-second delay between each. Replace the reduce with a for...of loop
that awaits each upload and delay sequentially to ensure uploads happen one
after another with a 1-second gap, preserving order and preventing rate limit
issues.

@vunguyenhung
Copy link
Collaborator

Hi @GTFalcao,

For OpenAI chat:

  1. For Audio, I still see the existing error. Could you try to reproduce on your side and let me know the result?
  2. For Image, I think we can improve the existing prop to add support for file path, such as we can do a simple regex to detect the file path, file url or base64, then handle each case accordingly. For me, having 2 separate props for image might confuse the end user 🙏

@vunguyenhung vunguyenhung moved this from Ready for QA to Changes Required in Component (Source and Action) Backlog Jun 17, 2025
@vunguyenhung
Copy link
Collaborator

Hello everyone, I have tested this PR and there're some test cases failed or needed improvement.

Please check the test report below for more information
https://vunguyenhung.notion.site/Part-2-applying-File-URL-or-Path-improvements-210bf548bb5e8132b254c9b32cecd14f

@GTFalcao
Copy link
Collaborator Author

For the record, base64 image input was already not supported in the code, despite the prop description saying so. I've changed the prop to standard file path/url input as well.

@GTFalcao GTFalcao moved this from Changes Required to Ready for QA in Component (Source and Action) Backlog Jun 17, 2025
@vunguyenhung vunguyenhung moved this from Ready for QA to In QA in Component (Source and Action) Backlog Jun 17, 2025
@vunguyenhung vunguyenhung moved this from In QA to Changes Required in Component (Source and Action) Backlog Jun 17, 2025
@vunguyenhung
Copy link
Collaborator

Hello everyone, I have tested this PR and there're some test cases failed or needed improvement.

Please check the test report below for more information
https://vunguyenhung.notion.site/Part-2-applying-File-URL-or-Path-improvements-210bf548bb5e8132b254c9b32cecd14f

@GTFalcao
Copy link
Collaborator Author

I've adjusted the image to always be an "image_url" instead of an "input_image", creating the URL from the base64 content.

I also found and fixed the issue with the audio input: it was detecting the extension via a regexp which failed when there were query parameters (which was the case in your input, but not mine). I've adjusted this to use the extension from the file metadata instead.

@GTFalcao GTFalcao moved this from Changes Required to Ready for QA in Component (Source and Action) Backlog Jun 17, 2025
@vunguyenhung vunguyenhung moved this from Ready for QA to Ready for Release in Component (Source and Action) Backlog Jun 17, 2025
@vunguyenhung
Copy link
Collaborator

Hi everyone, all test cases are passed! Ready for release!

Test report
https://vunguyenhung.notion.site/Part-2-applying-File-URL-or-Path-improvements-210bf548bb5e8132b254c9b32cecd14f

@GTFalcao
Copy link
Collaborator Author

/approve

luancazarine

This comment was marked as duplicate.

@GTFalcao GTFalcao merged commit 3741b91 into master Jun 17, 2025
10 of 11 checks passed
@GTFalcao GTFalcao deleted the 16977-part-2 branch June 17, 2025 18:39
@github-project-automation github-project-automation bot moved this from Ready for Release to Done in Component (Source and Action) Backlog Jun 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants