summaryrefslogtreecommitdiff
path: root/Hutch/Networking/GraphQLRequest.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-03-17 23:19:43 -0500
committerChristian Cleberg <[email protected]>2026-03-17 23:19:43 -0500
commit32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5 (patch)
treeee36d421d704e508d5617d803b4c8cbdb4804fe1 /Hutch/Networking/GraphQLRequest.swift
parent8f2057c53e9009c2529c9c4849c914666c0e4b40 (diff)
downloadhutch-32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5.tar.gz
hutch-32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5.tar.bz2
hutch-32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5.zip
v1.0
Diffstat (limited to 'Hutch/Networking/GraphQLRequest.swift')
-rw-r--r--Hutch/Networking/GraphQLRequest.swift45
1 files changed, 45 insertions, 0 deletions
diff --git a/Hutch/Networking/GraphQLRequest.swift b/Hutch/Networking/GraphQLRequest.swift
new file mode 100644
index 0000000..bce7b40
--- /dev/null
+++ b/Hutch/Networking/GraphQLRequest.swift
@@ -0,0 +1,45 @@
+import Foundation
+
+/// The JSON body sent with every GraphQL request.
+struct GraphQLRequestBody: Encodable, Sendable {
+ let query: String
+ let variables: [String: AnyCodable]?
+}
+
+/// The top-level shape of every GraphQL response.
+struct GraphQLResponse<T: Decodable>: Decodable {
+ let data: T?
+ let errors: [GraphQLError]?
+}
+
+// MARK: - AnyCodable
+
+/// A type-erased `Codable` wrapper so callers can pass `[String: Any]` variables
+/// without losing type information at the encoding boundary.
+struct AnyCodable: Sendable, Encodable {
+ let value: any Sendable
+
+ init(_ value: any Sendable) {
+ self.value = value
+ }
+
+ func encode(to encoder: any Encoder) throws {
+ var container = encoder.singleValueContainer()
+ switch value {
+ case let v as String:
+ try container.encode(v)
+ case let v as Int:
+ try container.encode(v)
+ case let v as Double:
+ try container.encode(v)
+ case let v as Bool:
+ try container.encode(v)
+ case let v as [any Sendable]:
+ try container.encode(v.map { AnyCodable($0) })
+ case let v as [String: any Sendable]:
+ try container.encode(v.mapValues { AnyCodable($0) })
+ default:
+ try container.encodeNil()
+ }
+ }
+}