fix: roll back failed inline script seeding

This commit is contained in:
centdix
2026-04-16 17:48:16 +02:00
parent 2f98f54527
commit dc62cd0e32
2 changed files with 84 additions and 31 deletions
@@ -65,6 +65,42 @@ describe('applyFlowJsonUpdate', () => {
applyFlowJsonUpdate(flow as any, inlineScriptSession, {
modules: [makeRawScriptModule('validate_data', 'inline_script.other_module')]
})
).toThrow('Unresolved inline script references: other_module')
})
it('rolls back seeded inline scripts after a failed update so retries still warn', () => {
const flow = {
value: {
modules: [makeRawScriptModule('process_data', 'existing code')]
}
}
const inlineScriptSession = createInlineScriptSession()
inlineScriptSession.set('process_data', 'existing code')
expect(() =>
applyFlowJsonUpdate(flow as any, inlineScriptSession, {
modules: [
makeRawScriptModule('validate_data', 'inline_script.validate_data'),
makeRawScriptModule('save_results', 'inline_script.other_module')
]
})
).toThrow('Unresolved inline script references: other_module')
expect(inlineScriptSession.getAll()).toEqual({
process_data: 'existing code'
})
expect((flow.value.modules as Array<FlowModule & { value: any }>)[0]?.value.content).toBe(
'existing code'
)
const result = applyFlowJsonUpdate(flow as any, inlineScriptSession, {
modules: [
makeRawScriptModule('process_data', 'inline_script.process_data'),
makeRawScriptModule('validate_data', 'inline_script.validate_data')
]
})
expect(result.emptyInlineScriptModuleIds).toEqual(['validate_data'])
expect(inlineScriptSession.get('validate_data')).toBe('')
})
})
@@ -65,43 +65,60 @@ export function applyFlowJsonUpdate(
inlineScriptSession: InlineScriptSession,
{ modules, schema, preprocessorModule, failureModule }: FlowJsonUpdate
): FlowJsonUpdateResult {
const previousModules = flow.value.modules
const previousSchema = flow.schema
const previousPreprocessorModule = flow.value.preprocessor_module
const previousFailureModule = flow.value.failure_module
const previousInlineScripts = inlineScriptSession.getAll()
const emptyInlineScriptModuleIds = new Set<string>()
if (modules !== undefined) {
seedMissingInlineScripts(modules, inlineScriptSession).forEach((id) =>
emptyInlineScriptModuleIds.add(id)
)
flow.value.modules = restoreFlowModules(modules, inlineScriptSession)
}
try {
if (modules !== undefined) {
seedMissingInlineScripts(modules, inlineScriptSession).forEach((id) =>
emptyInlineScriptModuleIds.add(id)
)
flow.value.modules = restoreFlowModules(modules, inlineScriptSession)
}
if (schema !== undefined) {
flow.schema = schema ?? undefined
}
if (schema !== undefined) {
flow.schema = schema ?? undefined
}
if (preprocessorModule !== undefined) {
flow.value.preprocessor_module =
preprocessorModule === null
? undefined
: restoreFlowModuleWithSeededInlineScripts(
preprocessorModule,
inlineScriptSession,
emptyInlineScriptModuleIds
)
}
if (preprocessorModule !== undefined) {
flow.value.preprocessor_module =
preprocessorModule === null
? undefined
: restoreFlowModuleWithSeededInlineScripts(
preprocessorModule,
inlineScriptSession,
emptyInlineScriptModuleIds
)
}
if (failureModule !== undefined) {
flow.value.failure_module =
failureModule === null
? undefined
: restoreFlowModuleWithSeededInlineScripts(
failureModule,
inlineScriptSession,
emptyInlineScriptModuleIds
)
}
if (failureModule !== undefined) {
flow.value.failure_module =
failureModule === null
? undefined
: restoreFlowModuleWithSeededInlineScripts(
failureModule,
inlineScriptSession,
emptyInlineScriptModuleIds
)
}
return {
emptyInlineScriptModuleIds: Array.from(emptyInlineScriptModuleIds)
return {
emptyInlineScriptModuleIds: Array.from(emptyInlineScriptModuleIds)
}
} catch (error) {
flow.value.modules = previousModules
flow.schema = previousSchema
flow.value.preprocessor_module = previousPreprocessorModule
flow.value.failure_module = previousFailureModule
inlineScriptSession.clear()
for (const [moduleId, content] of Object.entries(previousInlineScripts)) {
inlineScriptSession.set(moduleId, content)
}
throw error
}
}