@@ -143,13 +143,17 @@ describe('Workflow with Optional Outputs and Skipped Nodes', () => {
143143 }
144144
145145 const [ lastNodeResult , allResults ] = await runExample ( )
146-
146+
147147 // Verify last node result (evenHandler1)
148148 expect ( lastNodeResult . state ) . to . equal ( 'completed' )
149149 expect ( lastNodeResult . output ) . to . deep . equal ( { doubled : 8 } )
150-
150+
151151 // Verify all node results
152- expect ( allResults ) . to . have . all . keys ( 'processor1' , 'evenHandler1' , 'oddHandler1' )
152+ expect ( allResults ) . to . have . all . keys (
153+ 'processor1' ,
154+ 'evenHandler1' ,
155+ 'oddHandler1'
156+ )
153157 expect ( allResults . processor1 . state ) . to . equal ( 'completed' )
154158 expect ( allResults . processor1 . output ) . to . deep . equal ( { even : 4 } )
155159 expect ( allResults . evenHandler1 . state ) . to . equal ( 'completed' )
@@ -284,7 +288,11 @@ describe('Workflow with Optional Outputs and Skipped Nodes', () => {
284288 expect ( lastNodeResult . output ) . to . deep . equal ( { doubled : 10 } )
285289
286290 // Verify all node results
287- expect ( allResults ) . to . have . all . keys ( 'if1' , 'trueHandler1' , 'falseHandler1' )
291+ expect ( allResults ) . to . have . all . keys (
292+ 'if1' ,
293+ 'trueHandler1' ,
294+ 'falseHandler1'
295+ )
288296 expect ( allResults . if1 . state ) . to . equal ( 'completed' )
289297 expect ( allResults . if1 . output ) . to . deep . equal ( { true : 5 } )
290298 expect ( allResults . trueHandler1 . state ) . to . equal ( 'completed' )
@@ -396,4 +404,98 @@ describe('Workflow with Optional Outputs and Skipped Nodes', () => {
396404 expect ( allResults . divide . state ) . to . equal ( 'completed' )
397405 expect ( allResults . divide . output ) . to . deep . equal ( { result : 5 } )
398406 } )
407+
408+ it ( 'should handle dynamic input/output schemas based on node config' , async ( ) => {
409+ // Define node types with dynamic schemas
410+ type EvalInput = { value : number | string }
411+ type EvalOutput = { result : unknown }
412+
413+ const evalNode : NodeDefinition < EvalInput , EvalOutput > = {
414+ inputSchema : ( node : WorkflowNode ) => {
415+ // Dynamic input schema based on node config
416+ const inputType = node . config ?. inputType || 'number'
417+ return z . object ( {
418+ value : inputType === 'string' ? z . string ( ) : z . number ( )
419+ } )
420+ } ,
421+ outputSchema : ( node : WorkflowNode ) => {
422+ // Dynamic output schema based on node config
423+ const outputType = node . config ?. outputType || 'number'
424+ return {
425+ result : outputType === 'string' ? z . string ( ) : z . number ( )
426+ }
427+ } ,
428+ run : async ( input : EvalInput ) => {
429+ // Simple evaluation for demonstration
430+ const result = input . value . toString ( )
431+ return { result }
432+ }
433+ }
434+
435+ // Create and configure workflow
436+ const factory = createNodeFactory ( )
437+ factory . registerNode ( 'eval' , evalNode )
438+
439+ const workflow : WorkflowNode [ ] = [
440+ {
441+ id : 'eval1' ,
442+ type : 'eval' ,
443+ dependencies : [ ] ,
444+ config : {
445+ inputType : 'number' ,
446+ outputType : 'string'
447+ }
448+ }
449+ ]
450+
451+ const initialContext : NodeContext = {
452+ variables : {
453+ value : 42
454+ } ,
455+ metadata : { }
456+ }
457+
458+ const [ lastNodeResult , allResults ] = await executeWorkflow (
459+ workflow ,
460+ factory ,
461+ initialContext ,
462+ {
463+ maxRetries : 2 ,
464+ maxParallel : 2
465+ }
466+ )
467+
468+ // Verify results
469+ expect ( lastNodeResult . state ) . to . equal ( 'completed' )
470+ expect ( lastNodeResult . output ) . to . deep . equal ( { result : '42' } )
471+ expect ( allResults . eval1 . state ) . to . equal ( 'completed' )
472+ expect ( allResults . eval1 . output ) . to . deep . equal ( { result : '42' } )
473+
474+ // Test with invalid input type
475+ const invalidWorkflow : WorkflowNode [ ] = [
476+ {
477+ id : 'eval2' ,
478+ type : 'eval' ,
479+ dependencies : [ ] ,
480+ config : {
481+ inputType : 'string' ,
482+ outputType : 'number'
483+ }
484+ }
485+ ]
486+
487+ const [ invalidLastResult , invalidResults ] = await executeWorkflow (
488+ invalidWorkflow ,
489+ factory ,
490+ initialContext ,
491+ {
492+ maxRetries : 2 ,
493+ maxParallel : 2
494+ }
495+ )
496+
497+ // Verify validation failure
498+ expect ( invalidLastResult . state ) . to . equal ( 'failed' )
499+ expect ( invalidResults . eval2 . state ) . to . equal ( 'failed' )
500+ } )
399501} )
0 commit comments