···11+import Foundation
22+33+/// Helper to decode arbitrary JSON values into `Any` for pass-through storage.
44+/// Used by XRPC outputs that carry opaque record values through to callers.
55+struct AnyDecodable: Decodable {
66+ let value: Any
77+88+ init(from decoder: Decoder) throws {
99+ let c = try decoder.singleValueContainer()
1010+ if c.decodeNil() {
1111+ value = NSNull()
1212+ } else if let b = try? c.decode(Bool.self) {
1313+ value = b
1414+ } else if let i = try? c.decode(Int64.self) {
1515+ value = i
1616+ } else if let d = try? c.decode(Double.self) {
1717+ value = d
1818+ } else if let s = try? c.decode(String.self) {
1919+ value = s
2020+ } else if let arr = try? c.decode([AnyDecodable].self) {
2121+ value = arr.map(\.value)
2222+ } else if let dict = try? c.decode([String: AnyDecodable].self) {
2323+ value = dict.mapValues(\.value)
2424+ } else {
2525+ throw DecodingError.dataCorruptedError(in: c, debugDescription: "Unsupported JSON value")
2626+ }
2727+ }
2828+}
···11+import Foundation
22+33+public struct DescribeRepoOutput: Decodable, Sendable, Equatable {
44+ public let handle: String
55+ public let did: String
66+ public let collections: [String]
77+ public let handleIsCorrect: Bool?
88+99+ // didDoc is JSON-any; keep it as a raw Data blob so callers can parse only
1010+ // the pieces they need (avoids modelling the entire DID-core schema).
1111+ public let didDoc: Data?
1212+1313+ enum CodingKeys: String, CodingKey {
1414+ case handle, did, collections, handleIsCorrect, didDoc
1515+ }
1616+1717+ public init(from decoder: Decoder) throws {
1818+ let c = try decoder.container(keyedBy: CodingKeys.self)
1919+ handle = try c.decode(String.self, forKey: .handle)
2020+ did = try c.decode(String.self, forKey: .did)
2121+ collections = try c.decode([String].self, forKey: .collections)
2222+ handleIsCorrect = try c.decodeIfPresent(Bool.self, forKey: .handleIsCorrect)
2323+ if c.contains(.didDoc) {
2424+ let any = try c.decode(AnyDecodable.self, forKey: .didDoc)
2525+ didDoc = try JSONSerialization.data(withJSONObject: any.value)
2626+ } else {
2727+ didDoc = nil
2828+ }
2929+ }
3030+}