import Foundation /// `POST /v{n}/users/authenticate/` struct AuthRequest: Encodable { let email: String let password: String } /// A successful login replies `{"status":"success"}` with no `data` (dev guide /// §Response format). We don't depend on a payload — auth state lives in /// cookies — so `AuthResponse` is empty-representable and captures `data` raw /// only when a build happens to include it. struct AuthResponse: Decodable, EmptyRepresentable { let raw: JSONValue init(from decoder: Decoder) throws { raw = try JSONValue(from: decoder) } private init(raw: JSONValue) { self.raw = raw } static var emptyValue: AuthResponse { AuthResponse(raw: .null) } var email: String? { raw["email"]?.stringValue ?? raw["User"]?["email"]?.stringValue } } /// `GET /v{n}/ponmgr/version/` — attribute set describing the install. /// Exact keys vary; surface a best-effort display string and keep raw. struct VersionInfo: Decodable { let raw: JSONValue init(from decoder: Decoder) throws { raw = try JSONValue(from: decoder) } var displayVersion: String? { raw["version"]?.stringValue ?? raw["Version"]?.stringValue ?? raw["ponmgr"]?["version"]?.stringValue } } // `PUT /v{n}/databases/selection/` takes the database id as a bare string under // the data envelope — `{ "data": "" }` (dev guide §Request Format). It is // sent by passing the id String straight to `client.send(wrapInData: true)`, so // no wrapper struct is needed here.