From 47c9604577a35a8fdcc80c838b803dacf7608fd4 Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Tue, 3 Feb 2026 12:09:55 -0800 Subject: [PATCH] update single file blocks --- apps/sim/blocks/blocks/confluence.ts | 2 +- apps/sim/blocks/blocks/dropbox.ts | 2 +- apps/sim/blocks/blocks/fireflies.ts | 8 +++--- apps/sim/blocks/blocks/google_drive.ts | 2 +- apps/sim/blocks/blocks/linear.ts | 6 ++--- apps/sim/blocks/blocks/onedrive.ts | 2 +- apps/sim/blocks/blocks/s3.ts | 2 +- apps/sim/blocks/blocks/spotify.ts | 2 +- apps/sim/blocks/blocks/stt.ts | 10 ++++--- apps/sim/blocks/blocks/supabase.ts | 4 ++- apps/sim/blocks/blocks/telegram.ts | 32 ++++++++++++++--------- apps/sim/blocks/blocks/textract.ts | 9 ++++--- apps/sim/blocks/blocks/video_generator.ts | 2 +- apps/sim/blocks/blocks/vision.ts | 7 ++--- apps/sim/blocks/blocks/wordpress.ts | 2 +- apps/sim/blocks/utils.ts | 30 +++++++++++++++------ 16 files changed, 75 insertions(+), 47 deletions(-) diff --git a/apps/sim/blocks/blocks/confluence.ts b/apps/sim/blocks/blocks/confluence.ts index 0fb46836c..5bdb21e5e 100644 --- a/apps/sim/blocks/blocks/confluence.ts +++ b/apps/sim/blocks/blocks/confluence.ts @@ -652,7 +652,7 @@ export const ConfluenceV2Block: BlockConfig = { if (operation === 'upload_attachment') { const fileInput = attachmentFileUpload || attachmentFileReference || attachmentFile - const normalizedFile = normalizeFileInput(fileInput) + const normalizedFile = normalizeFileInput(fileInput, { single: true }) if (!normalizedFile) { throw new Error('File is required for upload attachment operation.') } diff --git a/apps/sim/blocks/blocks/dropbox.ts b/apps/sim/blocks/blocks/dropbox.ts index 8fbbb8cb3..044625cc6 100644 --- a/apps/sim/blocks/blocks/dropbox.ts +++ b/apps/sim/blocks/blocks/dropbox.ts @@ -320,7 +320,7 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, // Normalize file input for upload operation // normalizeFileInput handles JSON stringified values from advanced mode if (params.fileContent) { - params.fileContent = normalizeFileInput(params.fileContent) + params.fileContent = normalizeFileInput(params.fileContent, { single: true }) } switch (params.operation) { diff --git a/apps/sim/blocks/blocks/fireflies.ts b/apps/sim/blocks/blocks/fireflies.ts index d9d919da5..b67a256ca 100644 --- a/apps/sim/blocks/blocks/fireflies.ts +++ b/apps/sim/blocks/blocks/fireflies.ts @@ -620,12 +620,12 @@ export const FirefliesV2Block: BlockConfig = { } if (params.operation === 'fireflies_upload_audio') { - const audioFiles = - normalizeFileInput(params.audioFile) || normalizeFileInput(params.audioFileReference) - if (!audioFiles || audioFiles.length === 0) { + const audioFile = + normalizeFileInput(params.audioFile, { single: true }) || + normalizeFileInput(params.audioFileReference, { single: true }) + if (!audioFile) { throw new Error('Audio file is required.') } - const audioFile = audioFiles[0] const audioUrl = resolveHttpsUrlFromFileInput(audioFile) if (!audioUrl) { throw new Error('Audio file must include a https URL.') diff --git a/apps/sim/blocks/blocks/google_drive.ts b/apps/sim/blocks/blocks/google_drive.ts index 841934731..d14168d5a 100644 --- a/apps/sim/blocks/blocks/google_drive.ts +++ b/apps/sim/blocks/blocks/google_drive.ts @@ -793,7 +793,7 @@ Return ONLY the message text - no subject line, no greetings/signatures, no extr } = params // Normalize file input - handles both basic (file-upload) and advanced (short-input) modes - const normalizedFile = normalizeFileInput(file ?? fileUpload) + const normalizedFile = normalizeFileInput(file ?? fileUpload, { single: true }) // Use folderSelector if provided, otherwise use manualFolderId const effectiveFolderId = (folderSelector || manualFolderId || '').trim() diff --git a/apps/sim/blocks/blocks/linear.ts b/apps/sim/blocks/blocks/linear.ts index 58f336700..d7c245a85 100644 --- a/apps/sim/blocks/blocks/linear.ts +++ b/apps/sim/blocks/blocks/linear.ts @@ -1775,10 +1775,10 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n throw new Error('Issue ID is required.') } // Normalize file inputs - handles JSON stringified values from advanced mode - const normalizedUpload = normalizeFileInput(params.attachmentFileUpload) - const normalizedFile = normalizeFileInput(params.file) // Take the first file from whichever input has data (Linear only accepts single file) - const attachmentFile = normalizedUpload?.[0] || normalizedFile?.[0] + const attachmentFile = + normalizeFileInput(params.attachmentFileUpload, { single: true }) || + normalizeFileInput(params.file, { single: true }) // Check for multiple files if ( (normalizedUpload && normalizedUpload.length > 1) || diff --git a/apps/sim/blocks/blocks/onedrive.ts b/apps/sim/blocks/blocks/onedrive.ts index 605c90ca3..e2e3545fb 100644 --- a/apps/sim/blocks/blocks/onedrive.ts +++ b/apps/sim/blocks/blocks/onedrive.ts @@ -371,7 +371,7 @@ export const OneDriveBlock: BlockConfig = { } // Normalize file input from both basic (file-upload) and advanced (short-input) modes - const normalizedFile = normalizeFileInput(file || fileReference) + const normalizedFile = normalizeFileInput(file || fileReference, { single: true }) return { credential, diff --git a/apps/sim/blocks/blocks/s3.ts b/apps/sim/blocks/blocks/s3.ts index 5681984fd..9c8c537a1 100644 --- a/apps/sim/blocks/blocks/s3.ts +++ b/apps/sim/blocks/blocks/s3.ts @@ -273,7 +273,7 @@ export const S3Block: BlockConfig = { } // Use file from uploadFile if in basic mode, otherwise use file reference // normalizeFileInput handles JSON stringified values from advanced mode - const fileParam = normalizeFileInput(params.uploadFile || params.file) + const fileParam = normalizeFileInput(params.uploadFile || params.file, { single: true }) return { accessKeyId: params.accessKeyId, diff --git a/apps/sim/blocks/blocks/spotify.ts b/apps/sim/blocks/blocks/spotify.ts index 57e75639e..c152b3a56 100644 --- a/apps/sim/blocks/blocks/spotify.ts +++ b/apps/sim/blocks/blocks/spotify.ts @@ -788,7 +788,7 @@ export const SpotifyBlock: BlockConfig = { } // Normalize file input for cover image if (params.coverImage !== undefined) { - params.coverImage = normalizeFileInput(params.coverImage) + params.coverImage = normalizeFileInput(params.coverImage, { single: true }) } return params.operation || 'spotify_search' }, diff --git a/apps/sim/blocks/blocks/stt.ts b/apps/sim/blocks/blocks/stt.ts index 8896f1b61..4dbf80999 100644 --- a/apps/sim/blocks/blocks/stt.ts +++ b/apps/sim/blocks/blocks/stt.ts @@ -260,8 +260,9 @@ export const SttBlock: BlockConfig = { }, params: (params) => { // Normalize file input from basic (file-upload) or advanced (short-input) mode - const normalizedFiles = normalizeFileInput(params.audioFile || params.audioFileReference) - const audioFile = normalizedFiles?.[0] + const audioFile = normalizeFileInput(params.audioFile || params.audioFileReference, { + single: true, + }) return { provider: params.provider, @@ -393,8 +394,9 @@ export const SttV2Block: BlockConfig = { }), params: (params) => { // Normalize file input from basic (file-upload) or advanced (short-input) mode - const normalizedFiles = normalizeFileInput(params.audioFile || params.audioFileReference) - const audioFile = normalizedFiles?.[0] + const audioFile = normalizeFileInput(params.audioFile || params.audioFileReference, { + single: true, + }) return { provider: params.provider, diff --git a/apps/sim/blocks/blocks/supabase.ts b/apps/sim/blocks/blocks/supabase.ts index 07d3a4bae..78256c5be 100644 --- a/apps/sim/blocks/blocks/supabase.ts +++ b/apps/sim/blocks/blocks/supabase.ts @@ -982,7 +982,9 @@ Return ONLY the PostgREST filter expression - no explanations, no markdown, no e // Normalize file input for storage_upload operation // normalizeFileInput handles JSON stringified values from advanced mode - const normalizedFileData = normalizeFileInput(file || fileContent || fileData) + const normalizedFileData = normalizeFileInput(file || fileContent || fileData, { + single: true, + }) // Parse JSON data if it's a string let parsedData diff --git a/apps/sim/blocks/blocks/telegram.ts b/apps/sim/blocks/blocks/telegram.ts index bda5b617b..2be6eb546 100644 --- a/apps/sim/blocks/blocks/telegram.ts +++ b/apps/sim/blocks/blocks/telegram.ts @@ -269,46 +269,54 @@ export const TelegramBlock: BlockConfig = { messageId: params.messageId, } case 'telegram_send_photo': { - const photoSource = normalizeFileInput(params.photoFile || params.photo) - if (!photoSource || photoSource.length === 0) { + const photoSource = normalizeFileInput(params.photoFile || params.photo, { + single: true, + }) + if (!photoSource) { throw new Error('Photo is required.') } return { ...commonParams, - photo: photoSource[0], + photo: photoSource, caption: params.caption, } } case 'telegram_send_video': { - const videoSource = normalizeFileInput(params.videoFile || params.video) - if (!videoSource || videoSource.length === 0) { + const videoSource = normalizeFileInput(params.videoFile || params.video, { + single: true, + }) + if (!videoSource) { throw new Error('Video is required.') } return { ...commonParams, - video: videoSource[0], + video: videoSource, caption: params.caption, } } case 'telegram_send_audio': { - const audioSource = normalizeFileInput(params.audioFile || params.audio) - if (!audioSource || audioSource.length === 0) { + const audioSource = normalizeFileInput(params.audioFile || params.audio, { + single: true, + }) + if (!audioSource) { throw new Error('Audio is required.') } return { ...commonParams, - audio: audioSource[0], + audio: audioSource, caption: params.caption, } } case 'telegram_send_animation': { - const animationSource = normalizeFileInput(params.animationFile || params.animation) - if (!animationSource || animationSource.length === 0) { + const animationSource = normalizeFileInput(params.animationFile || params.animation, { + single: true, + }) + if (!animationSource) { throw new Error('Animation is required.') } return { ...commonParams, - animation: animationSource[0], + animation: animationSource, caption: params.caption, } } diff --git a/apps/sim/blocks/blocks/textract.ts b/apps/sim/blocks/blocks/textract.ts index b59055c21..10f5a1113 100644 --- a/apps/sim/blocks/blocks/textract.ts +++ b/apps/sim/blocks/blocks/textract.ts @@ -265,13 +265,14 @@ export const TextractV2Block: BlockConfig = { } parameters.s3Uri = params.s3Uri.trim() } else { - const files = normalizeFileInput( - params.fileUpload || params.fileReference || params.document + const file = normalizeFileInput( + params.fileUpload || params.fileReference || params.document, + { single: true } ) - if (!files || files.length === 0) { + if (!file) { throw new Error('Document file is required') } - parameters.file = files[0] + parameters.file = file } const featureTypes: string[] = [] diff --git a/apps/sim/blocks/blocks/video_generator.ts b/apps/sim/blocks/blocks/video_generator.ts index cd874c6de..ae31eb951 100644 --- a/apps/sim/blocks/blocks/video_generator.ts +++ b/apps/sim/blocks/blocks/video_generator.ts @@ -746,7 +746,7 @@ export const VideoGeneratorV2Block: BlockConfig = { duration: params.duration ? Number(params.duration) : undefined, aspectRatio: params.aspectRatio, resolution: params.resolution, - visualReference: normalizeFileInput(visualRef), + visualReference: normalizeFileInput(visualRef, { single: true }), consistencyMode: params.consistencyMode, stylePreset: params.stylePreset, promptOptimizer: params.promptOptimizer, diff --git a/apps/sim/blocks/blocks/vision.ts b/apps/sim/blocks/blocks/vision.ts index 244c4126b..a367b0c58 100644 --- a/apps/sim/blocks/blocks/vision.ts +++ b/apps/sim/blocks/blocks/vision.ts @@ -118,9 +118,10 @@ export const VisionV2Block: BlockConfig = { }), params: (params) => { // normalizeFileInput handles JSON stringified values from advanced mode - const normalizedFiles = normalizeFileInput(params.imageFile || params.imageFileReference) - // Vision expects a single file, take the first from the normalized array - const imageFile = normalizedFiles?.[0] + // Vision expects a single file + const imageFile = normalizeFileInput(params.imageFile || params.imageFileReference, { + single: true, + }) return { ...params, imageFile, diff --git a/apps/sim/blocks/blocks/wordpress.ts b/apps/sim/blocks/blocks/wordpress.ts index bcc7eba50..e0b206ce5 100644 --- a/apps/sim/blocks/blocks/wordpress.ts +++ b/apps/sim/blocks/blocks/wordpress.ts @@ -770,7 +770,7 @@ export const WordPressBlock: BlockConfig = { case 'wordpress_upload_media': return { ...baseParams, - file: normalizeFileInput(params.fileUpload || params.file), + file: normalizeFileInput(params.fileUpload || params.file, { single: true }), filename: params.filename, title: params.mediaTitle, caption: params.caption, diff --git a/apps/sim/blocks/utils.ts b/apps/sim/blocks/utils.ts index cb7d5b418..9c800d50f 100644 --- a/apps/sim/blocks/utils.ts +++ b/apps/sim/blocks/utils.ts @@ -251,7 +251,7 @@ export function createVersionedToolSelector> } /** - * Normalizes file input from block params. + * Normalizes file input from block params to a consistent format. * Handles the case where template resolution JSON.stringify's arrays/objects * when they're placed in short-input fields (advanced mode). * @@ -260,9 +260,21 @@ export function createVersionedToolSelector> * - An array of file objects (basic mode or properly resolved) * - A single file object * - A JSON string of file(s) (from advanced mode template resolution) - * @returns Normalized array of file objects, or undefined if no files + * @param options.single - If true, returns only the first file object instead of an array + * @returns Normalized file(s), or undefined if no files */ -export function normalizeFileInput(fileParam: unknown): object[] | undefined { +export function normalizeFileInput( + fileParam: unknown, + options: { single: true } +): object | undefined +export function normalizeFileInput( + fileParam: unknown, + options?: { single?: false } +): object[] | undefined +export function normalizeFileInput( + fileParam: unknown, + options?: { single?: boolean } +): object | object[] | undefined { if (!fileParam) return undefined if (typeof fileParam === 'string') { @@ -273,13 +285,15 @@ export function normalizeFileInput(fileParam: unknown): object[] | undefined { } } + let files: object[] | undefined + if (Array.isArray(fileParam)) { - return fileParam.length > 0 ? fileParam : undefined + files = fileParam.length > 0 ? fileParam : undefined + } else if (typeof fileParam === 'object' && fileParam !== null) { + files = [fileParam] } - if (typeof fileParam === 'object' && fileParam !== null) { - return [fileParam] - } + if (!files) return undefined - return undefined + return options?.single ? files[0] : files }