@@ -825,4 +825,78 @@ describe("Schema", () => {
825825 ) . toBe ( true ) ;
826826 } ) ;
827827
828+ it ( 'offers a nested nullable object property as a ReferenceValue path suggestion for a plain TEXT parameter' , ( ) => {
829+ // Node 1: custom::text::nested_nullable_object(): {test?: {bla?: TEXT | null} | null}
830+ // — no parameters, returns an object whose `test` property is an optional,
831+ // nullable object which itself holds an optional, nullable `bla` property.
832+ // Node 2: std::text::split(value: TEXT, delimiter: TEXT): LIST<TEXT>
833+ //
834+ // The `value` parameter is declared as plain TEXT (string). Node 1's `test.bla`
835+ // property has type string | null | undefined behind a nullable `test` object.
836+ // Strict assignability would reject it, but the editor must still offer node 1's
837+ // `test.bla` property as a ReferenceValue suggestion with referencePath
838+ // [{path: "test"}, {path: "bla"}]: the nullish parts along the reference chain
839+ // should be ignored for suggestion scoping.
840+ const NESTED_NULLABLE_OBJECT_FN : FunctionDefinition = {
841+ id : "gid://sagittarius/FunctionDefinition/9003" ,
842+ identifier : "custom::text::nested_nullable_object" ,
843+ signature : "(): {test?: {bla?: TEXT | null} | null}" ,
844+ } ;
845+
846+ const flow : Flow = {
847+ id : "gid://sagittarius/Flow/1" ,
848+ startingNodeId : "gid://sagittarius/NodeFunction/1" ,
849+ signature : "(): void" ,
850+ nodes : {
851+ nodes : [
852+ {
853+ id : "gid://sagittarius/NodeFunction/1" ,
854+ functionDefinition : { identifier : "custom::text::nested_nullable_object" } ,
855+ nextNodeId : "gid://sagittarius/NodeFunction/2" ,
856+ parameters : {
857+ nodes : [ ] ,
858+ } ,
859+ } ,
860+ {
861+ id : "gid://sagittarius/NodeFunction/2" ,
862+ functionDefinition : { identifier : "std::text::split" } ,
863+ parameters : {
864+ nodes : [
865+ { value : null } ,
866+ { value : { __typename : "LiteralValue" , value : "," } } ,
867+ ] ,
868+ } ,
869+ } ,
870+ ] ,
871+ } ,
872+ } ;
873+
874+ const [ valueSchema ] = getSignatureSchema (
875+ flow ,
876+ DATA_TYPES ,
877+ [ ...FUNCTION_SIGNATURES , NESTED_NULLABLE_OBJECT_FN ] ,
878+ "gid://sagittarius/NodeFunction/2" ,
879+ ) ;
880+
881+ // value: TEXT → free-form text input.
882+ expect ( valueSchema . schema . input ) . toBe ( "text" ) ;
883+
884+ // Node 1's `test.bla` property is TEXT | null | undefined nested inside the
885+ // nullable `test` object; stripping the nullish parts leaves TEXT, which is
886+ // assignable to the TEXT parameter → node 1 must be offered with
887+ // referencePath [{path: "test"}, {path: "bla"}].
888+ const suggestions = ( valueSchema . schema . suggestions ?? [ ] ) as any [ ] ;
889+ expect (
890+ suggestions . some (
891+ ( s ) =>
892+ s . __typename === "ReferenceValue" &&
893+ s . nodeFunctionId === "gid://sagittarius/NodeFunction/1" &&
894+ Array . isArray ( s . referencePath ) &&
895+ s . referencePath . length === 2 &&
896+ s . referencePath [ 0 ] . path === "test" &&
897+ s . referencePath [ 1 ] . path === "bla" ,
898+ ) ,
899+ ) . toBe ( true ) ;
900+ } ) ;
901+
828902} )
0 commit comments