Skip to content

Commit 12239a0

Browse files
committed
consolidate literal gen
1 parent c264481 commit 12239a0

File tree

3 files changed

+53
-46
lines changed

3 files changed

+53
-46
lines changed

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

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { executeInIsolatedVM } from '@/lib/execution/isolated-vm'
88
import { CodeLanguage, DEFAULT_CODE_LANGUAGE, isValidCodeLanguage } from '@/lib/execution/languages'
99
import { escapeRegExp, normalizeName, REFERENCE } from '@/executor/constants'
1010
import { type OutputSchema, resolveBlockReference } from '@/executor/utils/block-reference'
11+
import { formatLiteralForCode } from '@/executor/utils/code-formatting'
1112
import {
1213
createEnvVarPattern,
1314
createWorkflowVariablePattern,
@@ -692,15 +693,7 @@ export async function POST(req: NextRequest) {
692693
prologue += `const environmentVariables = JSON.parse(${JSON.stringify(JSON.stringify(envVars))});\n`
693694
prologueLineCount++
694695
for (const [k, v] of Object.entries(contextVariables)) {
695-
if (v === undefined) {
696-
prologue += `const ${k} = undefined;\n`
697-
} else if (v === null) {
698-
prologue += `const ${k} = null;\n`
699-
} else if (typeof v === 'boolean' || typeof v === 'number') {
700-
prologue += `const ${k} = ${v};\n`
701-
} else {
702-
prologue += `const ${k} = JSON.parse(${JSON.stringify(JSON.stringify(v))});\n`
703-
}
696+
prologue += `const ${k} = ${formatLiteralForCode(v, 'javascript')};\n`
704697
prologueLineCount++
705698
}
706699

@@ -771,25 +764,7 @@ export async function POST(req: NextRequest) {
771764
prologue += `environmentVariables = json.loads(${JSON.stringify(JSON.stringify(envVars))})\n`
772765
prologueLineCount++
773766
for (const [k, v] of Object.entries(contextVariables)) {
774-
if (v === undefined) {
775-
prologue += `${k} = None\n`
776-
} else if (v === null) {
777-
prologue += `${k} = None\n`
778-
} else if (typeof v === 'boolean') {
779-
prologue += `${k} = ${v ? 'True' : 'False'}\n`
780-
} else if (typeof v === 'number') {
781-
if (Number.isNaN(v)) {
782-
prologue += `${k} = float('nan')\n`
783-
} else if (v === Number.POSITIVE_INFINITY) {
784-
prologue += `${k} = float('inf')\n`
785-
} else if (v === Number.NEGATIVE_INFINITY) {
786-
prologue += `${k} = float('-inf')\n`
787-
} else {
788-
prologue += `${k} = ${v}\n`
789-
}
790-
} else {
791-
prologue += `${k} = json.loads(${JSON.stringify(JSON.stringify(v))})\n`
792-
}
767+
prologue += `${k} = ${formatLiteralForCode(v, 'python')}\n`
793768
prologueLineCount++
794769
}
795770
const wrapped = [
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Formats a JavaScript/TypeScript value as a code literal for the target language.
3+
* Handles special cases like null, undefined, booleans, and Python-specific number representations.
4+
*
5+
* @param value - The value to format
6+
* @param language - Target language ('javascript' or 'python')
7+
* @returns A string literal representation valid in the target language
8+
*
9+
* @example
10+
* formatLiteralForCode(null, 'python') // => 'None'
11+
* formatLiteralForCode(true, 'python') // => 'True'
12+
* formatLiteralForCode(NaN, 'python') // => "float('nan')"
13+
* formatLiteralForCode("hello", 'javascript') // => '"hello"'
14+
* formatLiteralForCode({a: 1}, 'python') // => "json.loads('{\"a\":1}')"
15+
*/
16+
export function formatLiteralForCode(value: unknown, language: 'javascript' | 'python'): string {
17+
const isPython = language === 'python'
18+
19+
if (value === undefined) {
20+
return isPython ? 'None' : 'undefined'
21+
}
22+
if (value === null) {
23+
return isPython ? 'None' : 'null'
24+
}
25+
if (typeof value === 'boolean') {
26+
return isPython ? (value ? 'True' : 'False') : String(value)
27+
}
28+
if (typeof value === 'number') {
29+
if (Number.isNaN(value)) {
30+
return isPython ? "float('nan')" : 'NaN'
31+
}
32+
if (value === Number.POSITIVE_INFINITY) {
33+
return isPython ? "float('inf')" : 'Infinity'
34+
}
35+
if (value === Number.NEGATIVE_INFINITY) {
36+
return isPython ? "float('-inf')" : '-Infinity'
37+
}
38+
return String(value)
39+
}
40+
if (typeof value === 'string') {
41+
return JSON.stringify(value)
42+
}
43+
// Objects and arrays - Python needs json.loads() because JSON true/false/null aren't valid Python
44+
if (isPython) {
45+
return `json.loads(${JSON.stringify(JSON.stringify(value))})`
46+
}
47+
return JSON.stringify(value)
48+
}

apps/sim/executor/variables/resolvers/block.ts

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
type OutputSchema,
1111
resolveBlockReference,
1212
} from '@/executor/utils/block-reference'
13+
import { formatLiteralForCode } from '@/executor/utils/code-formatting'
1314
import {
1415
navigatePath,
1516
type ResolutionContext,
@@ -207,23 +208,6 @@ export class BlockResolver implements Resolver {
207208
}
208209

209210
private formatValueForCodeContext(value: any, language?: string): string {
210-
const isPython = language === 'python'
211-
212-
if (typeof value === 'string') {
213-
return JSON.stringify(value)
214-
}
215-
if (typeof value === 'object' && value !== null) {
216-
return JSON.stringify(value)
217-
}
218-
if (value === undefined) {
219-
return isPython ? 'None' : 'undefined'
220-
}
221-
if (value === null) {
222-
return isPython ? 'None' : 'null'
223-
}
224-
if (typeof value === 'boolean') {
225-
return isPython ? (value ? 'True' : 'False') : String(value)
226-
}
227-
return String(value)
211+
return formatLiteralForCode(value, language === 'python' ? 'python' : 'javascript')
228212
}
229213
}

0 commit comments

Comments
 (0)