Skip to content

Commit f4a3c94

Browse files
committed
consolidate more code
1 parent 9ec0c8f commit f4a3c94

File tree

5 files changed

+124
-132
lines changed

5 files changed

+124
-132
lines changed

apps/sim/blocks/blocks/fireflies.ts

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,15 @@
11
import { FirefliesIcon } from '@/components/icons'
2+
import { resolveHttpsUrlFromFileInput } from '@/lib/uploads/utils/file-utils'
23
import type { BlockConfig } from '@/blocks/types'
34
import { AuthMode } from '@/blocks/types'
45
import type { FirefliesResponse } from '@/tools/fireflies/types'
56
import { getTrigger } from '@/triggers'
67

7-
const resolveHttpsUrlFromFileInput = (fileInput: unknown): string | null => {
8-
if (!fileInput || typeof fileInput !== 'object') {
9-
return null
10-
}
11-
12-
const record = fileInput as Record<string, unknown>
13-
const url =
14-
typeof record.url === 'string'
15-
? record.url.trim()
16-
: typeof record.path === 'string'
17-
? record.path.trim()
18-
: ''
19-
20-
if (!url || !url.startsWith('https://')) {
21-
return null
22-
}
23-
24-
return url
25-
}
26-
278
export const FirefliesBlock: BlockConfig<FirefliesResponse> = {
289
type: 'fireflies',
29-
name: 'Fireflies',
10+
name: 'Fireflies (Legacy)',
3011
description: 'Interact with Fireflies.ai meeting transcripts and recordings',
12+
hideFromToolbar: true,
3113
authMode: AuthMode.ApiKey,
3214
triggerAllowed: true,
3315
longDescription:
@@ -618,9 +600,9 @@ const firefliesV2Inputs = FirefliesBlock.inputs
618600
export const FirefliesV2Block: BlockConfig<FirefliesResponse> = {
619601
...FirefliesBlock,
620602
type: 'fireflies_v2',
621-
name: 'Fireflies (File Only)',
603+
name: 'Fireflies',
622604
description: 'Interact with Fireflies.ai meeting transcripts and recordings',
623-
hideFromToolbar: true,
605+
hideFromToolbar: false,
624606
subBlocks: firefliesV2SubBlocks,
625607
tools: {
626608
...FirefliesBlock.tools,

apps/sim/blocks/blocks/google_slides.ts

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,14 @@
11
import { GoogleSlidesIcon } from '@/components/icons'
2+
import { resolveHttpsUrlFromFileInput } from '@/lib/uploads/utils/file-utils'
23
import type { BlockConfig } from '@/blocks/types'
34
import { AuthMode } from '@/blocks/types'
45
import type { GoogleSlidesResponse } from '@/tools/google_slides/types'
56

6-
const resolveHttpsUrlFromFileInput = (fileInput: unknown): string | null => {
7-
if (!fileInput || typeof fileInput !== 'object') {
8-
return null
9-
}
10-
11-
const record = fileInput as Record<string, unknown>
12-
const url =
13-
typeof record.url === 'string'
14-
? record.url.trim()
15-
: typeof record.path === 'string'
16-
? record.path.trim()
17-
: ''
18-
19-
if (!url || !url.startsWith('https://')) {
20-
return null
21-
}
22-
23-
return url
24-
}
25-
267
export const GoogleSlidesBlock: BlockConfig<GoogleSlidesResponse> = {
278
type: 'google_slides',
28-
name: 'Google Slides',
9+
name: 'Google Slides (Legacy)',
2910
description: 'Read, write, and create presentations',
11+
hideFromToolbar: true,
3012
authMode: AuthMode.OAuth,
3113
longDescription:
3214
'Integrate Google Slides into the workflow. Can read, write, create presentations, replace text, add slides, add images, get thumbnails, get page details, delete objects, duplicate objects, reorder slides, create tables, create shapes, and insert text.',
@@ -963,9 +945,9 @@ const googleSlidesV2Inputs = GoogleSlidesBlock.inputs
963945
export const GoogleSlidesV2Block: BlockConfig<GoogleSlidesResponse> = {
964946
...GoogleSlidesBlock,
965947
type: 'google_slides_v2',
966-
name: 'Google Slides (File Only)',
948+
name: 'Google Slides',
967949
description: 'Read, write, and create presentations',
968-
hideFromToolbar: true,
950+
hideFromToolbar: false,
969951
subBlocks: googleSlidesV2SubBlocks,
970952
tools: {
971953
...GoogleSlidesBlock.tools,

apps/sim/blocks/blocks/stt.ts

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -388,21 +388,36 @@ export const SttV2Block: BlockConfig<SttBlockResponse> = {
388388
suffix: '_v2',
389389
fallbackToolId: 'stt_whisper_v2',
390390
}),
391-
params: (params) => ({
392-
provider: params.provider,
393-
apiKey: params.apiKey,
394-
model: params.model,
395-
audioFile: params.audioFile,
396-
audioFileReference: params.audioFileReference,
397-
language: params.language,
398-
timestamps: params.timestamps,
399-
diarization: params.diarization,
400-
translateToEnglish: params.translateToEnglish,
401-
sentiment: params.sentiment,
402-
entityDetection: params.entityDetection,
403-
piiRedaction: params.piiRedaction,
404-
summarization: params.summarization,
405-
}),
391+
params: (params) => {
392+
let audioInput = params.audioFile || params.audioFileReference
393+
if (audioInput && typeof audioInput === 'string') {
394+
try {
395+
audioInput = JSON.parse(audioInput)
396+
} catch {
397+
throw new Error('Audio file must be a valid file reference')
398+
}
399+
}
400+
if (audioInput && Array.isArray(audioInput)) {
401+
throw new Error(
402+
'File reference must be a single file, not an array. Use <block.files[0]> to select one file.'
403+
)
404+
}
405+
return {
406+
provider: params.provider,
407+
apiKey: params.apiKey,
408+
model: params.model,
409+
audioFile: audioInput,
410+
audioFileReference: undefined,
411+
language: params.language,
412+
timestamps: params.timestamps,
413+
diarization: params.diarization,
414+
translateToEnglish: params.translateToEnglish,
415+
sentiment: params.sentiment,
416+
entityDetection: params.entityDetection,
417+
piiRedaction: params.piiRedaction,
418+
summarization: params.summarization,
419+
}
420+
},
406421
},
407422
},
408423
inputs: sttV2Inputs,

apps/sim/blocks/blocks/vision.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,26 @@ export const VisionV2Block: BlockConfig<VisionResponse> = {
116116
suffix: '_v2',
117117
fallbackToolId: 'vision_tool_v2',
118118
}),
119+
params: (params) => {
120+
let imageInput = params.imageFile || params.imageFileReference
121+
if (imageInput && typeof imageInput === 'string') {
122+
try {
123+
imageInput = JSON.parse(imageInput)
124+
} catch {
125+
throw new Error('Image file must be a valid file reference')
126+
}
127+
}
128+
if (imageInput && Array.isArray(imageInput)) {
129+
throw new Error(
130+
'File reference must be a single file, not an array. Use <block.files[0]> to select one file.'
131+
)
132+
}
133+
return {
134+
...params,
135+
imageFile: imageInput,
136+
imageFileReference: undefined,
137+
}
138+
},
119139
},
120140
},
121141
subBlocks: [

apps/sim/lib/uploads/utils/file-utils.ts

Lines changed: 64 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -451,16 +451,38 @@ function isCompleteUserFile(file: RawFileInput): file is UserFile {
451451
typeof file.url === 'string' &&
452452
typeof file.size === 'number' &&
453453
typeof file.type === 'string' &&
454-
typeof file.key === 'string' &&
455-
typeof file.uploadedAt === 'string' &&
456-
typeof file.expiresAt === 'string'
454+
typeof file.key === 'string'
457455
)
458456
}
459457

460458
function isUrlLike(value: string): boolean {
461459
return value.startsWith('http://') || value.startsWith('https://') || value.startsWith('/')
462460
}
463461

462+
/**
463+
* Extracts HTTPS URL from a file input object (UserFile or RawFileInput)
464+
* Returns null if no valid HTTPS URL is found
465+
*/
466+
export function resolveHttpsUrlFromFileInput(fileInput: unknown): string | null {
467+
if (!fileInput || typeof fileInput !== 'object') {
468+
return null
469+
}
470+
471+
const record = fileInput as Record<string, unknown>
472+
const url =
473+
typeof record.url === 'string'
474+
? record.url.trim()
475+
: typeof record.path === 'string'
476+
? record.path.trim()
477+
: ''
478+
479+
if (!url || !url.startsWith('https://')) {
480+
return null
481+
}
482+
483+
return url
484+
}
485+
464486
function resolveStorageKeyFromRawFile(file: RawFileInput): string | null {
465487
if (file.key) {
466488
return file.key
@@ -484,45 +506,26 @@ function resolveInternalFileUrl(file: RawFileInput): string {
484506
if (file.url && isInternalFileUrl(file.url)) {
485507
return file.url
486508
}
487-
488509
if (file.path && isInternalFileUrl(file.path)) {
489510
return file.path
490511
}
491-
492512
return ''
493513
}
494514

495515
/**
496-
* Converts a single raw file object to UserFile format
497-
* @param file - Raw file object (must be a single file, not an array)
498-
* @param requestId - Request ID for logging
499-
* @param logger - Logger instance
500-
* @returns UserFile object
501-
* @throws Error if file is an array or has no storage key
516+
* Core conversion logic from RawFileInput to UserFile
502517
*/
503-
export function processSingleFileToUserFile(
504-
file: RawFileInput,
505-
requestId: string,
506-
logger: Logger
507-
): UserFile {
508-
if (Array.isArray(file)) {
509-
const errorMsg = `Expected a single file but received an array with ${file.length} file(s). Use a file input that accepts multiple files, or select a specific file from the array (e.g., {{block.files[0]}}).`
510-
logger.error(`[${requestId}] ${errorMsg}`)
511-
throw new Error(errorMsg)
512-
}
513-
518+
function convertToUserFile(file: RawFileInput, requestId: string, logger: Logger): UserFile | null {
514519
if (isCompleteUserFile(file)) {
515520
return {
516521
...file,
517-
url: resolveInternalFileUrl(file),
522+
url: resolveInternalFileUrl(file) || file.url,
518523
}
519524
}
520525

521526
const storageKey = resolveStorageKeyFromRawFile(file)
522-
523527
if (!storageKey) {
524-
logger.warn(`[${requestId}] File has no storage key: ${file.name || 'unknown'}`)
525-
throw new Error(`File has no storage key: ${file.name || 'unknown'}`)
528+
return null
526529
}
527530

528531
const userFile: UserFile = {
@@ -541,12 +544,32 @@ export function processSingleFileToUserFile(
541544
}
542545

543546
/**
544-
* Converts raw file objects (from file-upload or variable references) to UserFile format
545-
* Accepts either a single file or an array of files and normalizes to array output
546-
* @param files - Single file or array of raw file objects
547-
* @param requestId - Request ID for logging
548-
* @param logger - Logger instance
549-
* @returns Array of UserFile objects
547+
* Converts a single raw file object to UserFile format
548+
* @throws Error if file is an array or has no storage key
549+
*/
550+
export function processSingleFileToUserFile(
551+
file: RawFileInput,
552+
requestId: string,
553+
logger: Logger
554+
): UserFile {
555+
if (Array.isArray(file)) {
556+
const errorMsg = `Expected a single file but received an array with ${file.length} file(s). Use a file input that accepts multiple files, or select a specific file from the array (e.g., {{block.files[0]}}).`
557+
logger.error(`[${requestId}] ${errorMsg}`)
558+
throw new Error(errorMsg)
559+
}
560+
561+
const userFile = convertToUserFile(file, requestId, logger)
562+
if (!userFile) {
563+
const errorMsg = `File has no storage key: ${file.name || 'unknown'}`
564+
logger.warn(`[${requestId}] ${errorMsg}`)
565+
throw new Error(errorMsg)
566+
}
567+
568+
return userFile
569+
}
570+
571+
/**
572+
* Converts raw file objects to UserFile format, accepting single or array input
550573
*/
551574
export function processFilesToUserFiles(
552575
files: RawFileInput | RawFileInput[],
@@ -557,46 +580,16 @@ export function processFilesToUserFiles(
557580
const userFiles: UserFile[] = []
558581

559582
for (const file of filesArray) {
560-
try {
561-
if (Array.isArray(file)) {
562-
logger.warn(`[${requestId}] Skipping nested array in file input`)
563-
continue
564-
}
565-
566-
if (isCompleteUserFile(file)) {
567-
userFiles.push({
568-
...file,
569-
url: resolveInternalFileUrl(file),
570-
})
571-
continue
572-
}
573-
574-
const storageKey = resolveStorageKeyFromRawFile(file)
575-
576-
if (!storageKey) {
577-
logger.warn(`[${requestId}] Skipping file without storage key: ${file.name || 'unknown'}`)
578-
continue
579-
}
580-
581-
const userFile: UserFile = {
582-
id: file.id || `file-${Date.now()}`,
583-
name: file.name,
584-
url: resolveInternalFileUrl(file),
585-
size: file.size,
586-
type: file.type || 'application/octet-stream',
587-
key: storageKey,
588-
context: file.context,
589-
base64: file.base64,
590-
}
591-
592-
logger.info(
593-
`[${requestId}] Converted file to UserFile: ${userFile.name} (key: ${userFile.key})`
594-
)
583+
if (Array.isArray(file)) {
584+
logger.warn(`[${requestId}] Skipping nested array in file input`)
585+
continue
586+
}
587+
588+
const userFile = convertToUserFile(file, requestId, logger)
589+
if (userFile) {
595590
userFiles.push(userFile)
596-
} catch (error) {
597-
logger.warn(
598-
`[${requestId}] Skipping file: ${error instanceof Error ? error.message : 'Unknown error'}`
599-
)
591+
} else {
592+
logger.warn(`[${requestId}] Skipping file without storage key: ${file.name || 'unknown'}`)
600593
}
601594
}
602595

0 commit comments

Comments
 (0)