@@ -3444,11 +3444,86 @@ pub fn resolve_document_node_type(identifier: &str) -> Option<&DocumentNodeDefin
3444
3444
}
3445
3445
3446
3446
pub fn collect_node_types ( ) -> Vec < FrontendNodeType > {
3447
- DOCUMENT_NODE_TYPES
3447
+ // Create a mapping from registry ID to document node identifier
3448
+ let id_to_identifier_map: HashMap < String , & ' static str > = DOCUMENT_NODE_TYPES
3449
+ . iter ( )
3450
+ . filter_map ( |definition| {
3451
+ if let DocumentNodeImplementation :: ProtoNode ( ProtoNodeIdentifier { name } ) = & definition. node_template . document_node . implementation {
3452
+ Some ( ( name. to_string ( ) , definition. identifier ) )
3453
+ } else {
3454
+ None
3455
+ }
3456
+ } )
3457
+ . collect ( ) ;
3458
+ let mut extracted_node_types = Vec :: new ( ) ;
3459
+
3460
+ let node_registry = graphene_core:: registry:: NODE_REGISTRY . lock ( ) . unwrap ( ) ;
3461
+ let node_metadata = graphene_core:: registry:: NODE_METADATA . lock ( ) . unwrap ( ) ;
3462
+ for ( id, metadata) in node_metadata. iter ( ) {
3463
+ if let Some ( implementations) = node_registry. get ( id) {
3464
+ let identifier = match id_to_identifier_map. get ( id) {
3465
+ Some ( & id) => id. to_string ( ) ,
3466
+ None => continue ,
3467
+ } ;
3468
+
3469
+ // Extract category from metadata (already creates an owned String)
3470
+ let category = metadata. category . unwrap_or_default ( ) . to_string ( ) ;
3471
+
3472
+ // Extract input types (already creates owned Strings)
3473
+ let input_types = implementations
3474
+ . iter ( )
3475
+ . flat_map ( |( _, node_io) | node_io. inputs . iter ( ) . map ( |ty| ty. clone ( ) . nested_type ( ) . to_string ( ) ) )
3476
+ . collect :: < HashSet < String > > ( )
3477
+ . into_iter ( )
3478
+ . collect :: < Vec < String > > ( ) ;
3479
+
3480
+ // Create a FrontendNodeType
3481
+ let node_type = FrontendNodeType :: with_owned_strings_and_input_types ( identifier, category, input_types) ;
3482
+
3483
+ // Store the created node_type
3484
+ extracted_node_types. push ( node_type) ;
3485
+ }
3486
+ }
3487
+
3488
+ let node_types: Vec < FrontendNodeType > = DOCUMENT_NODE_TYPES
3448
3489
. iter ( )
3449
3490
. filter ( |definition| !definition. category . is_empty ( ) )
3450
- . map ( |definition| FrontendNodeType :: new ( definition. identifier , definition. category ) )
3451
- . collect ( )
3491
+ . map ( |definition| {
3492
+ let input_types = definition
3493
+ . node_template
3494
+ . document_node
3495
+ . inputs
3496
+ . iter ( )
3497
+ . filter_map ( |node_input| node_input. as_value ( ) . map ( |node_value| node_value. ty ( ) . nested_type ( ) . to_string ( ) ) )
3498
+ . collect :: < Vec < String > > ( ) ;
3499
+
3500
+ FrontendNodeType :: with_input_types ( definition. identifier , definition. category , input_types)
3501
+ } )
3502
+ . collect ( ) ;
3503
+
3504
+ // Update categories in extracted_node_types from node_types
3505
+ for extracted_node in & mut extracted_node_types {
3506
+ if extracted_node. category . is_empty ( ) {
3507
+ // Find matching node in node_types and update category if found
3508
+ if let Some ( matching_node) = node_types. iter ( ) . find ( |node_type| node_type. name == extracted_node. name ) {
3509
+ extracted_node. category = matching_node. category . clone ( ) ;
3510
+ }
3511
+ }
3512
+ }
3513
+ let missing_nodes: Vec < FrontendNodeType > = node_types
3514
+ . iter ( )
3515
+ . filter ( |node| !extracted_node_types. iter ( ) . any ( |extracted| extracted. name == node. name ) )
3516
+ . cloned ( )
3517
+ . collect ( ) ;
3518
+
3519
+ // Add the missing nodes to extracted_node_types
3520
+ for node in missing_nodes {
3521
+ extracted_node_types. push ( node) ;
3522
+ }
3523
+ // Remove entries with empty categories
3524
+ extracted_node_types. retain ( |node| !node. category . is_empty ( ) ) ;
3525
+
3526
+ extracted_node_types
3452
3527
}
3453
3528
3454
3529
pub fn collect_node_descriptions ( ) -> Vec < ( String , String ) > {
0 commit comments