mirror of
https://github.com/simstudioai/sim.git
synced 2026-02-11 07:04:58 -05:00
feat(trigger-docs): new trigger docs, function block rce imports fix (#1462)
* fix(sidebar): draggable cursor on sidebar when switching workflows (#1276) * remove inline css for edge labels * fix remote code execution imports for javascript * add docs for new triggers * fix * fix draggable link --------- Co-authored-by: Waleed Latif <walif6@gmail.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: Adam Gough <77861281+aadamgough@users.noreply.github.com> Co-authored-by: Adam Gough <adamgough@Mac.attlocal.net> Co-authored-by: Siddharth Ganesan <33737564+Sg312@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
d1f5c69e6b
commit
0e65a8a31d
@@ -39,6 +39,89 @@ function createSecureFetch(requestId: string) {
|
||||
const E2B_JS_WRAPPER_LINES = 3 // Lines before user code: ';(async () => {', ' try {', ' const __sim_result = await (async () => {'
|
||||
const E2B_PYTHON_WRAPPER_LINES = 1 // Lines before user code: 'def __sim_main__():'
|
||||
|
||||
type TypeScriptModule = typeof import('typescript')
|
||||
|
||||
let typescriptModulePromise: Promise<TypeScriptModule> | null = null
|
||||
|
||||
async function loadTypeScriptModule(): Promise<TypeScriptModule> {
|
||||
if (!typescriptModulePromise) {
|
||||
typescriptModulePromise = import('typescript').then((mod) => {
|
||||
const tsModule = (mod?.default ?? mod) as TypeScriptModule
|
||||
return tsModule
|
||||
})
|
||||
}
|
||||
|
||||
return typescriptModulePromise
|
||||
}
|
||||
|
||||
async function extractJavaScriptImports(
|
||||
code: string
|
||||
): Promise<{ imports: string; remainingCode: string; importLineCount: number }> {
|
||||
try {
|
||||
const tsModule = await loadTypeScriptModule()
|
||||
|
||||
const sourceFile = tsModule.createSourceFile(
|
||||
'user-code.js',
|
||||
code,
|
||||
tsModule.ScriptTarget.Latest,
|
||||
true,
|
||||
tsModule.ScriptKind.JS
|
||||
)
|
||||
|
||||
const importSegments: Array<{ text: string; start: number; end: number }> = []
|
||||
|
||||
sourceFile.statements.forEach((statement) => {
|
||||
if (
|
||||
tsModule.isImportDeclaration(statement) ||
|
||||
tsModule.isImportEqualsDeclaration(statement)
|
||||
) {
|
||||
importSegments.push({
|
||||
text: statement.getFullText(sourceFile).trim(),
|
||||
start: statement.getFullStart(),
|
||||
end: statement.getEnd(),
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (importSegments.length === 0) {
|
||||
return { imports: '', remainingCode: code, importLineCount: 0 }
|
||||
}
|
||||
|
||||
importSegments.sort((a, b) => a.start - b.start)
|
||||
|
||||
const imports = importSegments.map((segment) => segment.text).join('\n')
|
||||
|
||||
let cursor = 0
|
||||
const parts: string[] = []
|
||||
let importLineCount = 0
|
||||
|
||||
for (const segment of importSegments) {
|
||||
if (segment.start > cursor) {
|
||||
parts.push(code.slice(cursor, segment.start))
|
||||
}
|
||||
|
||||
const removedSegment = code.slice(segment.start, segment.end)
|
||||
importLineCount += removedSegment.split('\n').length - 1
|
||||
|
||||
const newlinePlaceholder = removedSegment.replace(/[^\n]/g, '')
|
||||
parts.push(newlinePlaceholder)
|
||||
|
||||
cursor = segment.end
|
||||
}
|
||||
|
||||
if (cursor < code.length) {
|
||||
parts.push(code.slice(cursor))
|
||||
}
|
||||
|
||||
const remainingCode = parts.join('')
|
||||
|
||||
return { imports, remainingCode, importLineCount: Math.max(importLineCount, 0) }
|
||||
} catch (error) {
|
||||
logger.error('Failed to extract JavaScript imports', { error })
|
||||
return { imports: '', remainingCode: code, importLineCount: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhanced error information interface
|
||||
*/
|
||||
@@ -624,6 +707,15 @@ export async function POST(req: NextRequest) {
|
||||
if (lang === CodeLanguage.JavaScript) {
|
||||
// Track prologue lines for error adjustment
|
||||
let prologueLineCount = 0
|
||||
|
||||
const { imports, remainingCode } = await extractJavaScriptImports(resolvedCode)
|
||||
|
||||
const importSection: string = imports ? `${imports}\n` : ''
|
||||
const importLineCount = imports ? imports.split('\n').length : 0
|
||||
|
||||
const codeBody = remainingCode
|
||||
resolvedCode = importSection ? `${imports}\n\n${codeBody}` : codeBody
|
||||
|
||||
prologue += `const params = JSON.parse(${JSON.stringify(JSON.stringify(executionParams))});\n`
|
||||
prologueLineCount++
|
||||
prologue += `const environmentVariables = JSON.parse(${JSON.stringify(JSON.stringify(envVars))});\n`
|
||||
@@ -632,11 +724,12 @@ export async function POST(req: NextRequest) {
|
||||
prologue += `const ${k} = JSON.parse(${JSON.stringify(JSON.stringify(v))});\n`
|
||||
prologueLineCount++
|
||||
}
|
||||
|
||||
const wrapped = [
|
||||
';(async () => {',
|
||||
' try {',
|
||||
' const __sim_result = await (async () => {',
|
||||
` ${resolvedCode.split('\n').join('\n ')}`,
|
||||
` ${codeBody.split('\n').join('\n ')}`,
|
||||
' })();',
|
||||
" console.log('__SIM_RESULT__=' + JSON.stringify(__sim_result));",
|
||||
' } catch (error) {',
|
||||
@@ -645,7 +738,7 @@ export async function POST(req: NextRequest) {
|
||||
' }',
|
||||
'})();',
|
||||
].join('\n')
|
||||
const codeForE2B = prologue + wrapped + epilogue
|
||||
const codeForE2B = importSection + prologue + wrapped + epilogue
|
||||
|
||||
const execStart = Date.now()
|
||||
const {
|
||||
@@ -674,7 +767,7 @@ export async function POST(req: NextRequest) {
|
||||
e2bStdout,
|
||||
lang,
|
||||
resolvedCode,
|
||||
prologueLineCount
|
||||
prologueLineCount + importLineCount
|
||||
)
|
||||
return NextResponse.json(
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user