Skip to content

Commit bdf7289

Browse files
committed
fix edge cases
1 parent aca7005 commit bdf7289

File tree

3 files changed

+85
-72
lines changed

3 files changed

+85
-72
lines changed

apps/sim/app/api/function/execute/route.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ function resolveTagVariables(
480480
const undefinedLiteral = language === 'python' ? 'None' : 'undefined'
481481

482482
const tagPattern = new RegExp(
483-
`${REFERENCE.START}([a-zA-Z_][a-zA-Z0-9_${REFERENCE.PATH_DELIMITER}]*[a-zA-Z0-9_])${REFERENCE.END}`,
483+
`${REFERENCE.START}([a-zA-Z_](?:[a-zA-Z0-9_${REFERENCE.PATH_DELIMITER}]*[a-zA-Z0-9_])?)${REFERENCE.END}`,
484484
'g'
485485
)
486486
const tagMatches = resolvedCode.match(tagPattern) || []
@@ -508,19 +508,18 @@ function resolveTagVariables(
508508
continue
509509
}
510510

511-
if (
512-
typeof tagValue === 'string' &&
513-
tagValue.length > 100 &&
514-
(tagValue.startsWith('{') || tagValue.startsWith('['))
515-
) {
516-
try {
517-
tagValue = JSON.parse(tagValue)
518-
} catch {
519-
// Keep as-is
511+
if (typeof tagValue === 'string') {
512+
const trimmed = tagValue.trimStart()
513+
if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
514+
try {
515+
tagValue = JSON.parse(tagValue)
516+
} catch {
517+
// Keep as string if not valid JSON
518+
}
520519
}
521520
}
522521

523-
const safeVarName = `__tag_${tagName.replace(/[^a-zA-Z0-9_]/g, '_')}`
522+
const safeVarName = `__tag_${tagName.replace(/_/g, '_1').replace(/\./g, '_0')}`
524523
contextVariables[safeVarName] = tagValue
525524
resolvedCode = resolvedCode.replace(new RegExp(escapeRegExp(match), 'g'), safeVarName)
526525
}

apps/sim/executor/utils/block-data.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ export function collectBlockData(ctx: ExecutionContext): BlockDataCollection {
2626
blockNameMapping[normalizeName(workflowBlock.metadata.name)] = id
2727
}
2828

29-
// Build output schema from block type and params
3029
const blockType = workflowBlock.metadata?.id
3130
if (blockType) {
3231
const params = workflowBlock.config?.params as Record<string, unknown> | undefined

apps/sim/executor/utils/block-reference.ts

Lines changed: 75 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,53 @@ export class InvalidFieldError extends Error {
2828
}
2929
}
3030

31+
const FILE_PROPERTIES = ['name', 'type', 'size', 'url', 'base64', 'mimeType'] as const
32+
33+
function isFileType(value: unknown): boolean {
34+
if (typeof value !== 'object' || value === null) return false
35+
const typed = value as { type?: string }
36+
return typed.type === 'file[]' || typed.type === 'files'
37+
}
38+
39+
function isArrayType(value: unknown): value is { type: 'array'; items?: unknown } {
40+
if (typeof value !== 'object' || value === null) return false
41+
return (value as { type?: string }).type === 'array'
42+
}
43+
44+
function getArrayItems(schema: unknown): unknown {
45+
if (typeof schema !== 'object' || schema === null) return undefined
46+
return (schema as { items?: unknown }).items
47+
}
48+
49+
function getProperties(schema: unknown): Record<string, unknown> | undefined {
50+
if (typeof schema !== 'object' || schema === null) return undefined
51+
const props = (schema as { properties?: unknown }).properties
52+
return typeof props === 'object' && props !== null
53+
? (props as Record<string, unknown>)
54+
: undefined
55+
}
56+
57+
function lookupField(schema: unknown, fieldName: string): unknown | undefined {
58+
if (typeof schema !== 'object' || schema === null) return undefined
59+
const typed = schema as Record<string, unknown>
60+
61+
if (fieldName in typed) {
62+
return typed[fieldName]
63+
}
64+
65+
const props = getProperties(schema)
66+
if (props && fieldName in props) {
67+
return props[fieldName]
68+
}
69+
70+
return undefined
71+
}
72+
3173
function isPathInSchema(schema: OutputSchema | undefined, pathParts: string[]): boolean {
3274
if (!schema || pathParts.length === 0) {
3375
return true
3476
}
3577

36-
const FILE_PROPERTIES = ['name', 'type', 'size', 'url', 'base64', 'mimeType']
37-
const isFileType = (value: unknown): boolean => {
38-
if (typeof value !== 'object' || value === null) return false
39-
const typed = value as { type?: string }
40-
return typed.type === 'file[]' || typed.type === 'files'
41-
}
42-
4378
let current: unknown = schema
4479

4580
for (let i = 0; i < pathParts.length; i++) {
@@ -50,78 +85,58 @@ function isPathInSchema(schema: OutputSchema | undefined, pathParts: string[]):
5085
}
5186

5287
if (/^\d+$/.test(part)) {
53-
if (isFileType(current) && i + 1 < pathParts.length) {
54-
return FILE_PROPERTIES.includes(pathParts[i + 1])
88+
if (isFileType(current)) {
89+
const nextPart = pathParts[i + 1]
90+
return !nextPart || FILE_PROPERTIES.includes(nextPart as (typeof FILE_PROPERTIES)[number])
91+
}
92+
if (isArrayType(current)) {
93+
current = getArrayItems(current)
5594
}
5695
continue
5796
}
5897

5998
const arrayMatch = part.match(/^([^[]+)\[(\d+)\]$/)
6099
if (arrayMatch) {
61100
const [, prop] = arrayMatch
62-
const typed = current as Record<string, unknown>
101+
const fieldDef = lookupField(current, prop)
102+
if (!fieldDef) return false
63103

64-
if (prop in typed) {
65-
const fieldDef = typed[prop]
66-
if (isFileType(fieldDef) && i + 1 < pathParts.length) {
67-
return FILE_PROPERTIES.includes(pathParts[i + 1])
68-
}
69-
current = fieldDef
70-
continue
104+
if (isFileType(fieldDef)) {
105+
const nextPart = pathParts[i + 1]
106+
return !nextPart || FILE_PROPERTIES.includes(nextPart as (typeof FILE_PROPERTIES)[number])
71107
}
72-
return false
73-
}
74108

75-
const typed = current as Record<string, unknown>
76-
77-
if (part in typed) {
78-
const nextValue = typed[part]
79-
if (isFileType(nextValue) && i + 1 < pathParts.length) {
80-
if (/^\d+$/.test(pathParts[i + 1]) && i + 2 < pathParts.length) {
81-
return FILE_PROPERTIES.includes(pathParts[i + 2])
82-
}
83-
return FILE_PROPERTIES.includes(pathParts[i + 1])
84-
}
85-
current = nextValue
109+
current = isArrayType(fieldDef) ? getArrayItems(fieldDef) : fieldDef
86110
continue
87111
}
88112

89-
if (typed.properties && typeof typed.properties === 'object') {
90-
const props = typed.properties as Record<string, unknown>
91-
if (part in props) {
92-
current = props[part]
93-
continue
94-
}
113+
if (isFileType(current) && FILE_PROPERTIES.includes(part as (typeof FILE_PROPERTIES)[number])) {
114+
return true
95115
}
96116

97-
if (typed.type === 'array' && typed.items && typeof typed.items === 'object') {
98-
const items = typed.items as Record<string, unknown>
99-
if (items.properties && typeof items.properties === 'object') {
100-
const itemProps = items.properties as Record<string, unknown>
101-
if (part in itemProps) {
102-
current = itemProps[part]
103-
continue
117+
const fieldDef = lookupField(current, part)
118+
if (fieldDef !== undefined) {
119+
if (isFileType(fieldDef)) {
120+
const nextPart = pathParts[i + 1]
121+
if (!nextPart) return true
122+
if (/^\d+$/.test(nextPart)) {
123+
const afterIndex = pathParts[i + 2]
124+
return (
125+
!afterIndex || FILE_PROPERTIES.includes(afterIndex as (typeof FILE_PROPERTIES)[number])
126+
)
104127
}
128+
return FILE_PROPERTIES.includes(nextPart as (typeof FILE_PROPERTIES)[number])
105129
}
106-
if (part in items) {
107-
current = items[part]
108-
continue
109-
}
110-
}
111-
112-
if (isFileType(current) && FILE_PROPERTIES.includes(part)) {
113-
return true
130+
current = fieldDef
131+
continue
114132
}
115133

116-
if (
117-
typeof current === 'object' &&
118-
current !== null &&
119-
'type' in current &&
120-
typeof (current as { type: unknown }).type === 'string'
121-
) {
122-
const typedCurrent = current as { type: string; properties?: unknown; items?: unknown }
123-
if (!typedCurrent.properties && !typedCurrent.items) {
124-
return false
134+
if (isArrayType(current)) {
135+
const items = getArrayItems(current)
136+
const itemField = lookupField(items, part)
137+
if (itemField !== undefined) {
138+
current = itemField
139+
continue
125140
}
126141
}
127142

0 commit comments

Comments
 (0)