diff --git a/lib/src/robot/client.dart b/lib/src/robot/client.dart index 71fbbfa5147..a0d04b02c82 100644 --- a/lib/src/robot/client.dart +++ b/lib/src/robot/client.dart @@ -83,7 +83,7 @@ class Discovery { return Discovery( subtype: proto.query.subtype, model: proto.query.model, - results: proto.results.toMap(), + results: proto.results.toMap().unwrap(), ); } diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 5527458fcc8..db72afa8882 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -39,6 +39,70 @@ extension StructUtils on Struct { } } +// Deeply unwraps a nested proto map structure by removing wrappers and converting all nested values to their primitive types. +extension UnwrapProtoMapUtils on Map { + Map unwrap() { + final result = {}; + + dynamic unwrapValue(dynamic value) { + if (value is Map) { + final mapValue = Map.from(value); + + // Remove `Kind` wrapper + if (mapValue.containsKey('Kind')) { + final kindValue = mapValue['Kind']; + if (kindValue is Map) { + final kindMap = Map.from(kindValue); + + // Directly convert value types + if (kindMap.containsKey('StringValue')) return kindMap['StringValue']; + if (kindMap.containsKey('NumberValue')) return kindMap['NumberValue']; + if (kindMap.containsKey('BoolValue')) return kindMap['BoolValue']; + if (kindMap.containsKey('NullValue')) return null; + + // Special handling for more non-value types + if (kindMap.containsKey('ListValue')) { + final listValue = kindMap['ListValue']; + if (listValue is Map && listValue.containsKey('values')) { + return (listValue['values'] as List).map(unwrapValue).toList(); + } + return []; + } + + if (kindMap.containsKey('StructValue')) { + final structValue = kindMap['StructValue']; + if (structValue is Map && structValue.containsKey('fields')) { + return Map.from(structValue['fields']).unwrap(); + } + } + } + return value; + } + + // Remove `fields` wrapper + if (mapValue.containsKey('fields')) { + return Map.from(mapValue['fields']).unwrap(); + } + + // Continue unwrapping (recursive) + return mapValue.map((key, val) => MapEntry(key, unwrapValue(val))); + } + + if (value is List) { + return value.map(unwrapValue).toList(); + } + + return value; + } + + forEach((key, value) { + result[key] = unwrapValue(value); + }); + + return result; + } +} + extension ListValueUtils on List { Value toValue() { final values = map((e) {