@@ -735,99 +735,11 @@ fn extract_all_languages(data: &Value) -> Value {
735735}
736736
737737/// Extract all services across all projects
738+ /// In a monorepo, projects ARE services - so we return projects data
738739fn extract_all_services ( data : & Value ) -> Value {
739- let mut services = Vec :: new ( ) ;
740-
741- // Helper to extract compact service info from a ServiceAnalysis
742- let compact_service = |svc : & Value , project_name : Option < & str > | -> Value {
743- let mut svc_info = serde_json:: Map :: new ( ) ;
744-
745- // Add project name if from monorepo
746- if let Some ( proj) = project_name {
747- svc_info. insert ( "project" . to_string ( ) , Value :: String ( proj. to_string ( ) ) ) ;
748- }
749-
750- // Core fields
751- if let Some ( v) = svc. get ( "name" ) {
752- svc_info. insert ( "name" . to_string ( ) , v. clone ( ) ) ;
753- }
754- if let Some ( v) = svc. get ( "path" ) {
755- svc_info. insert ( "path" . to_string ( ) , v. clone ( ) ) ;
756- }
757- if let Some ( v) = svc. get ( "service_type" ) {
758- svc_info. insert ( "service_type" . to_string ( ) , v. clone ( ) ) ;
759- }
760-
761- // Extract language names (compact)
762- if let Some ( langs) = svc. get ( "languages" ) . and_then ( |l| l. as_array ( ) ) {
763- let lang_names: Vec < Value > = langs
764- . iter ( )
765- . filter_map ( |l| l. get ( "name" ) . and_then ( |n| n. as_str ( ) ) )
766- . map ( |n| Value :: String ( n. to_string ( ) ) )
767- . collect ( ) ;
768- if !lang_names. is_empty ( ) {
769- svc_info. insert ( "languages" . to_string ( ) , Value :: Array ( lang_names) ) ;
770- }
771- }
772-
773- // Extract technology names (compact)
774- if let Some ( techs) = svc. get ( "technologies" ) . and_then ( |t| t. as_array ( ) ) {
775- let tech_names: Vec < Value > = techs
776- . iter ( )
777- . filter_map ( |t| t. get ( "name" ) . and_then ( |n| n. as_str ( ) ) )
778- . map ( |n| Value :: String ( n. to_string ( ) ) )
779- . collect ( ) ;
780- if !tech_names. is_empty ( ) {
781- svc_info. insert ( "technologies" . to_string ( ) , Value :: Array ( tech_names) ) ;
782- }
783- }
784-
785- // Extract ports
786- if let Some ( ports) = svc. get ( "ports" ) . and_then ( |p| p. as_array ( ) ) {
787- let port_list: Vec < Value > = ports
788- . iter ( )
789- . filter_map ( |p| p. get ( "port" ) . and_then ( |n| n. as_u64 ( ) ) )
790- . map ( |n| Value :: Number ( n. into ( ) ) )
791- . collect ( ) ;
792- if !port_list. is_empty ( ) {
793- svc_info. insert ( "ports" . to_string ( ) , Value :: Array ( port_list) ) ;
794- }
795- }
796-
797- Value :: Object ( svc_info)
798- } ;
799-
800- // Handle ProjectAnalysis flat structure (services at top level)
801- if let Some ( svcs) = data. get ( "services" ) . and_then ( |s| s. as_array ( ) ) {
802- for svc in svcs {
803- services. push ( compact_service ( svc, None ) ) ;
804- }
805- }
806-
807- // Handle MonorepoAnalysis structure (services nested in projects)
808- if let Some ( projects) = data. get ( "projects" ) . and_then ( |v| v. as_array ( ) ) {
809- for project in projects {
810- let proj_name = project
811- . get ( "name" )
812- . and_then ( |n| n. as_str ( ) )
813- . unwrap_or ( "unknown" ) ;
814-
815- if let Some ( svcs) = project
816- . get ( "analysis" )
817- . and_then ( |a| a. get ( "services" ) )
818- . and_then ( |s| s. as_array ( ) )
819- {
820- for svc in svcs {
821- services. push ( compact_service ( svc, Some ( proj_name) ) ) ;
822- }
823- }
824- }
825- }
826-
827- serde_json:: json!( {
828- "total_services" : services. len( ) ,
829- "services" : services
830- } )
740+ // In monorepos, projects = services. Return projects list as services.
741+ // This is because the `services` field in ProjectAnalysis was never implemented.
742+ extract_projects_list ( data)
831743}
832744
833745/// Compact entire analyze_project output (strip file arrays)
0 commit comments