// Code generated by tools/generate.py; DO NOT EDIT. import Foundation public typealias JSONObject = [String: String] public let schemaSHA256 = "a86cbdaf2cfb884e3d98467968007e731ca55c6f6eb6dbd5cd6b95e062a9b058" public let currentWireVersion = "1" public let nMinus1WireVersion = "0" public let nMinus2WireVersion = "-1" public struct ContractValidationError: Error, Equatable { public let field: String; public let code: String } private struct AnyCodingKey: CodingKey { let stringValue: String; let intValue: Int?; init?(stringValue: String) { self.stringValue = stringValue; self.intValue = nil }; init?(intValue: Int) { self.stringValue = String(intValue); self.intValue = intValue } } private func validBase64URL(_ value: String) -> Bool { guard !value.isEmpty, value.utf8.allSatisfy({ byte in (byte >= 65 && byte <= 90) || (byte >= 97 && byte <= 122) || (byte >= 48 && byte <= 57) || byte == 45 || byte == 95 }) else { return false } let padding = String(repeating: "=", count: (4 - value.utf8.count % 4) % 4) let standard = value.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/") + padding guard let decoded = Data(base64Encoded: standard) else { return false } return decoded.base64EncodedString().replacingOccurrences(of: "+", with: "-").replacingOccurrences(of: "/", with: "_").replacingOccurrences(of: "=", with: "") == value } public struct AllocationPolicy: Codable, Equatable { public let minimumKbps: Int64 public let targetKbps: Int64 public let maximumKbps: Int64 public let tier: String public let audience: String public let protocolValue: String public let protocolVersion: Int64 public let grantTtlSeconds: Int64 public let reservationLeaseSeconds: Int64 enum CodingKeys: String, CodingKey { case minimumKbps = "minimum_kbps" case targetKbps = "target_kbps" case maximumKbps = "maximum_kbps" case tier = "tier" case audience = "audience" case protocolValue = "protocol" case protocolVersion = "protocol_version" case grantTtlSeconds = "grant_ttl_seconds" case reservationLeaseSeconds = "reservation_lease_seconds" } public init(minimumKbps: Int64, targetKbps: Int64, maximumKbps: Int64, tier: String, audience: String, protocolValue: String, protocolVersion: Int64, grantTtlSeconds: Int64, reservationLeaseSeconds: Int64) throws { self.minimumKbps = minimumKbps self.targetKbps = targetKbps self.maximumKbps = maximumKbps self.tier = tier self.audience = audience self.protocolValue = protocolValue self.protocolVersion = protocolVersion self.grantTtlSeconds = grantTtlSeconds self.reservationLeaseSeconds = reservationLeaseSeconds try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(minimumKbps: try c.decode(Int64.self, forKey: .minimumKbps), targetKbps: try c.decode(Int64.self, forKey: .targetKbps), maximumKbps: try c.decode(Int64.self, forKey: .maximumKbps), tier: try c.decode(String.self, forKey: .tier), audience: try c.decode(String.self, forKey: .audience), protocolValue: try c.decode(String.self, forKey: .protocolValue), protocolVersion: try c.decode(Int64.self, forKey: .protocolVersion), grantTtlSeconds: try c.decode(Int64.self, forKey: .grantTtlSeconds), reservationLeaseSeconds: try c.decode(Int64.self, forKey: .reservationLeaseSeconds)) } public func validate() throws { if self.minimumKbps < 1 { throw ContractValidationError(field: "minimum_kbps", code: "minimum") } if self.minimumKbps > 100000000 { throw ContractValidationError(field: "minimum_kbps", code: "maximum") } if self.targetKbps < 1 { throw ContractValidationError(field: "target_kbps", code: "minimum") } if self.targetKbps > 100000000 { throw ContractValidationError(field: "target_kbps", code: "maximum") } if self.maximumKbps < 1 { throw ContractValidationError(field: "maximum_kbps", code: "minimum") } if self.maximumKbps > 100000000 { throw ContractValidationError(field: "maximum_kbps", code: "maximum") } if !["standard", "priority", "premium"].contains(self.tier) { throw ContractValidationError(field: "tier", code: "invalid_value") } if self.audience.isEmpty { throw ContractValidationError(field: "audience", code: "required") } if !self.audience.isEmpty && self.audience.utf8.count < 1 { throw ContractValidationError(field: "audience", code: "min_length") } if self.audience.utf8.count > 256 { throw ContractValidationError(field: "audience", code: "max_length") } if self.protocolValue.isEmpty { throw ContractValidationError(field: "protocol", code: "required") } if !self.protocolValue.isEmpty && self.protocolValue.utf8.count < 1 { throw ContractValidationError(field: "protocol", code: "min_length") } if self.protocolValue.utf8.count > 64 { throw ContractValidationError(field: "protocol", code: "max_length") } if self.protocolVersion < 1 { throw ContractValidationError(field: "protocol_version", code: "minimum") } if self.protocolVersion > 100 { throw ContractValidationError(field: "protocol_version", code: "maximum") } if self.grantTtlSeconds < 5 { throw ContractValidationError(field: "grant_ttl_seconds", code: "minimum") } if self.grantTtlSeconds > 300 { throw ContractValidationError(field: "grant_ttl_seconds", code: "maximum") } if self.reservationLeaseSeconds < 5 { throw ContractValidationError(field: "reservation_lease_seconds", code: "minimum") } if self.reservationLeaseSeconds > 3600 { throw ContractValidationError(field: "reservation_lease_seconds", code: "maximum") } if minimumKbps > targetKbps || targetKbps > maximumKbps { throw ContractValidationError(field: "bounds", code: "invalid_order") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct AssignedDesktop: Codable, Equatable { public let assignmentId: String public let poolId: String public let name: String public let availability: String enum CodingKeys: String, CodingKey { case assignmentId = "assignment_id" case poolId = "pool_id" case name = "name" case availability = "availability" } public init(assignmentId: String, poolId: String, name: String, availability: String) throws { self.assignmentId = assignmentId self.poolId = poolId self.name = name self.availability = availability try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(assignmentId: try c.decode(String.self, forKey: .assignmentId), poolId: try c.decode(String.self, forKey: .poolId), name: try c.decode(String.self, forKey: .name), availability: try c.decode(String.self, forKey: .availability)) } public func validate() throws { if self.assignmentId.isEmpty { throw ContractValidationError(field: "assignment_id", code: "required") } if !self.assignmentId.isEmpty && self.assignmentId.utf8.count < 1 { throw ContractValidationError(field: "assignment_id", code: "min_length") } if self.assignmentId.utf8.count > 128 { throw ContractValidationError(field: "assignment_id", code: "max_length") } if self.poolId.isEmpty { throw ContractValidationError(field: "pool_id", code: "required") } if !self.poolId.isEmpty && self.poolId.utf8.count < 1 { throw ContractValidationError(field: "pool_id", code: "min_length") } if self.poolId.utf8.count > 128 { throw ContractValidationError(field: "pool_id", code: "max_length") } if self.name.isEmpty { throw ContractValidationError(field: "name", code: "required") } if !self.name.isEmpty && self.name.utf8.count < 1 { throw ContractValidationError(field: "name", code: "min_length") } if self.name.utf8.count > 256 { throw ContractValidationError(field: "name", code: "max_length") } if self.availability.isEmpty { throw ContractValidationError(field: "availability", code: "required") } if !self.availability.isEmpty && self.availability.utf8.count < 1 { throw ContractValidationError(field: "availability", code: "min_length") } if self.availability.utf8.count > 64 { throw ContractValidationError(field: "availability", code: "max_length") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct BrokerSession: Codable, Equatable { public let id: String public let principalId: String public let poolId: String public let assignmentId: String? public let state: String public let policySnapshot: AllocationPolicy public let reconnectDeadline: String? public let outcome: String? public let failureCode: String? public let cleanupState: String public let idempotencyKey: String public let correlationId: String public let requestedAt: String public let endedAt: String? public let version: Int64 enum CodingKeys: String, CodingKey { case id = "id" case principalId = "principal_id" case poolId = "pool_id" case assignmentId = "assignment_id" case state = "state" case policySnapshot = "policy_snapshot" case reconnectDeadline = "reconnect_deadline" case outcome = "outcome" case failureCode = "failure_code" case cleanupState = "cleanup_state" case idempotencyKey = "idempotency_key" case correlationId = "correlation_id" case requestedAt = "requested_at" case endedAt = "ended_at" case version = "version" } public init(id: String, principalId: String, poolId: String, assignmentId: String?, state: String, policySnapshot: AllocationPolicy, reconnectDeadline: String?, outcome: String?, failureCode: String?, cleanupState: String, idempotencyKey: String, correlationId: String, requestedAt: String, endedAt: String?, version: Int64) throws { self.id = id self.principalId = principalId self.poolId = poolId self.assignmentId = assignmentId self.state = state self.policySnapshot = policySnapshot self.reconnectDeadline = reconnectDeadline self.outcome = outcome self.failureCode = failureCode self.cleanupState = cleanupState self.idempotencyKey = idempotencyKey self.correlationId = correlationId self.requestedAt = requestedAt self.endedAt = endedAt self.version = version try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(id: try c.decode(String.self, forKey: .id), principalId: try c.decode(String.self, forKey: .principalId), poolId: try c.decode(String.self, forKey: .poolId), assignmentId: try c.decodeIfPresent(String.self, forKey: .assignmentId), state: try c.decode(String.self, forKey: .state), policySnapshot: try c.decode(AllocationPolicy.self, forKey: .policySnapshot), reconnectDeadline: try c.decodeIfPresent(String.self, forKey: .reconnectDeadline), outcome: try c.decodeIfPresent(String.self, forKey: .outcome), failureCode: try c.decodeIfPresent(String.self, forKey: .failureCode), cleanupState: try c.decode(String.self, forKey: .cleanupState), idempotencyKey: try c.decode(String.self, forKey: .idempotencyKey), correlationId: try c.decode(String.self, forKey: .correlationId), requestedAt: try c.decode(String.self, forKey: .requestedAt), endedAt: try c.decodeIfPresent(String.self, forKey: .endedAt), version: try c.decode(Int64.self, forKey: .version)) } public func validate() throws { if self.id.isEmpty { throw ContractValidationError(field: "id", code: "required") } if !self.id.isEmpty && self.id.utf8.count < 1 { throw ContractValidationError(field: "id", code: "min_length") } if self.id.utf8.count > 128 { throw ContractValidationError(field: "id", code: "max_length") } if self.principalId.isEmpty { throw ContractValidationError(field: "principal_id", code: "required") } if !self.principalId.isEmpty && self.principalId.utf8.count < 1 { throw ContractValidationError(field: "principal_id", code: "min_length") } if self.principalId.utf8.count > 128 { throw ContractValidationError(field: "principal_id", code: "max_length") } if self.poolId.isEmpty { throw ContractValidationError(field: "pool_id", code: "required") } if !self.poolId.isEmpty && self.poolId.utf8.count < 1 { throw ContractValidationError(field: "pool_id", code: "min_length") } if self.poolId.utf8.count > 128 { throw ContractValidationError(field: "pool_id", code: "max_length") } if let value = self.assignmentId { if value.utf8.count > 128 { throw ContractValidationError(field: "assignment_id", code: "max_length") } } if self.state.isEmpty { throw ContractValidationError(field: "state", code: "required") } if !self.state.isEmpty && self.state.utf8.count < 1 { throw ContractValidationError(field: "state", code: "min_length") } if self.state.utf8.count > 64 { throw ContractValidationError(field: "state", code: "max_length") } try self.policySnapshot.validate() if let value = self.reconnectDeadline { if value.utf8.count > 64 { throw ContractValidationError(field: "reconnect_deadline", code: "max_length") } if ISO8601DateFormatter().date(from: value) == nil { throw ContractValidationError(field: "reconnect_deadline", code: "invalid_time") } } if let value = self.outcome { if value.utf8.count > 64 { throw ContractValidationError(field: "outcome", code: "max_length") } } if let value = self.failureCode { if value.utf8.count > 128 { throw ContractValidationError(field: "failure_code", code: "max_length") } } if self.cleanupState.isEmpty { throw ContractValidationError(field: "cleanup_state", code: "required") } if !self.cleanupState.isEmpty && self.cleanupState.utf8.count < 1 { throw ContractValidationError(field: "cleanup_state", code: "min_length") } if self.cleanupState.utf8.count > 64 { throw ContractValidationError(field: "cleanup_state", code: "max_length") } if self.idempotencyKey.isEmpty { throw ContractValidationError(field: "idempotency_key", code: "required") } if !self.idempotencyKey.isEmpty && self.idempotencyKey.utf8.count < 1 { throw ContractValidationError(field: "idempotency_key", code: "min_length") } if self.idempotencyKey.utf8.count > 256 { throw ContractValidationError(field: "idempotency_key", code: "max_length") } if self.correlationId.isEmpty { throw ContractValidationError(field: "correlation_id", code: "required") } if !self.correlationId.isEmpty && self.correlationId.utf8.count < 1 { throw ContractValidationError(field: "correlation_id", code: "min_length") } if self.correlationId.utf8.count > 128 { throw ContractValidationError(field: "correlation_id", code: "max_length") } if self.requestedAt.utf8.count > 64 { throw ContractValidationError(field: "requested_at", code: "max_length") } if ISO8601DateFormatter().date(from: self.requestedAt) == nil { throw ContractValidationError(field: "requested_at", code: "invalid_time") } if let value = self.endedAt { if value.utf8.count > 64 { throw ContractValidationError(field: "ended_at", code: "max_length") } if ISO8601DateFormatter().date(from: value) == nil { throw ContractValidationError(field: "ended_at", code: "invalid_time") } } if self.version < 1 { throw ContractValidationError(field: "version", code: "minimum") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct CapabilityProfile: Codable, Equatable { public let transport: String public let framing: String public let media: String public let audio: String public let sourceRateControl: String public let clientDecode: [String] enum CodingKeys: String, CodingKey { case transport = "transport" case framing = "framing" case media = "media" case audio = "audio" case sourceRateControl = "source_rate_control" case clientDecode = "client_decode" } public init(transport: String, framing: String, media: String, audio: String, sourceRateControl: String, clientDecode: [String]) throws { self.transport = transport self.framing = framing self.media = media self.audio = audio self.sourceRateControl = sourceRateControl self.clientDecode = clientDecode try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(transport: try c.decode(String.self, forKey: .transport), framing: try c.decode(String.self, forKey: .framing), media: try c.decode(String.self, forKey: .media), audio: try c.decode(String.self, forKey: .audio), sourceRateControl: try c.decode(String.self, forKey: .sourceRateControl), clientDecode: try c.decode([String].self, forKey: .clientDecode)) } public func validate() throws { if self.transport.isEmpty { throw ContractValidationError(field: "transport", code: "required") } if !self.transport.isEmpty && self.transport.utf8.count < 1 { throw ContractValidationError(field: "transport", code: "min_length") } if self.transport.utf8.count > 64 { throw ContractValidationError(field: "transport", code: "max_length") } if !["datagram-v1", "datagram-v2"].contains(self.framing) { throw ContractValidationError(field: "framing", code: "invalid_value") } if self.media.isEmpty { throw ContractValidationError(field: "media", code: "required") } if !self.media.isEmpty && self.media.utf8.count < 1 { throw ContractValidationError(field: "media", code: "min_length") } if self.media.utf8.count > 64 { throw ContractValidationError(field: "media", code: "max_length") } if self.audio.isEmpty { throw ContractValidationError(field: "audio", code: "required") } if !self.audio.isEmpty && self.audio.utf8.count < 1 { throw ContractValidationError(field: "audio", code: "min_length") } if self.audio.utf8.count > 64 { throw ContractValidationError(field: "audio", code: "max_length") } if self.sourceRateControl.isEmpty { throw ContractValidationError(field: "source_rate_control", code: "required") } if !self.sourceRateControl.isEmpty && self.sourceRateControl.utf8.count < 1 { throw ContractValidationError(field: "source_rate_control", code: "min_length") } if self.sourceRateControl.utf8.count > 64 { throw ContractValidationError(field: "source_rate_control", code: "max_length") } if self.clientDecode.count < 1 { throw ContractValidationError(field: "client_decode", code: "min_items") } if self.clientDecode.count > 2 { throw ContractValidationError(field: "client_decode", code: "max_items") } for item in self.clientDecode where !["h264-opus", "hevc-opus"].contains(item) { throw ContractValidationError(field: "client_decode", code: "invalid_item") } if Set(self.clientDecode).count != self.clientDecode.count { throw ContractValidationError(field: "client_decode", code: "duplicate_item") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ChannelFrame: Codable, Equatable { public let version: String public let flowId: String public let sequence: Int64 public let flags: Int64 public let fragmentIndex: Int64 public let fragmentCount: Int64 public let timestampMs: Int64 public let payload: String enum CodingKeys: String, CodingKey { case version = "version" case flowId = "flow_id" case sequence = "sequence" case flags = "flags" case fragmentIndex = "fragment_index" case fragmentCount = "fragment_count" case timestampMs = "timestamp_ms" case payload = "payload" } public init(version: String, flowId: String, sequence: Int64, flags: Int64, fragmentIndex: Int64, fragmentCount: Int64, timestampMs: Int64, payload: String) throws { self.version = version self.flowId = flowId self.sequence = sequence self.flags = flags self.fragmentIndex = fragmentIndex self.fragmentCount = fragmentCount self.timestampMs = timestampMs self.payload = payload try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(version: try c.decode(String.self, forKey: .version), flowId: try c.decode(String.self, forKey: .flowId), sequence: try c.decode(Int64.self, forKey: .sequence), flags: try c.decode(Int64.self, forKey: .flags), fragmentIndex: try c.decode(Int64.self, forKey: .fragmentIndex), fragmentCount: try c.decode(Int64.self, forKey: .fragmentCount), timestampMs: try c.decode(Int64.self, forKey: .timestampMs), payload: try c.decode(String.self, forKey: .payload)) } public func validate() throws { if self.version != "1" { throw ContractValidationError(field: "version", code: "invalid_value") } if self.flowId.isEmpty { throw ContractValidationError(field: "flow_id", code: "required") } if !self.flowId.isEmpty && self.flowId.utf8.count < 1 { throw ContractValidationError(field: "flow_id", code: "min_length") } if self.flowId.utf8.count > 64 { throw ContractValidationError(field: "flow_id", code: "max_length") } if self.sequence < 0 { throw ContractValidationError(field: "sequence", code: "minimum") } if self.flags < 0 { throw ContractValidationError(field: "flags", code: "minimum") } if self.flags > 255 { throw ContractValidationError(field: "flags", code: "maximum") } if self.fragmentIndex < 0 { throw ContractValidationError(field: "fragment_index", code: "minimum") } if self.fragmentIndex > 15 { throw ContractValidationError(field: "fragment_index", code: "maximum") } if self.fragmentCount < 1 { throw ContractValidationError(field: "fragment_count", code: "minimum") } if self.fragmentCount > 16 { throw ContractValidationError(field: "fragment_count", code: "maximum") } if self.timestampMs < 0 { throw ContractValidationError(field: "timestamp_ms", code: "minimum") } if self.payload.utf8.count > 87384 { throw ContractValidationError(field: "payload", code: "max_length") } if self.payload.utf8.count > 65536 { throw ContractValidationError(field: "payload", code: "max_bytes") } if fragmentIndex >= fragmentCount { throw ContractValidationError(field: "fragment_index", code: "invalid_order") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ClipboardPolicy: Codable, Equatable { public let clientToProviderEnabled: Bool public let providerToClientEnabled: Bool public let maxTextBytes: Int64 public let maxUpdatesPerMinute: Int64 enum CodingKeys: String, CodingKey { case clientToProviderEnabled = "client_to_provider_enabled" case providerToClientEnabled = "provider_to_client_enabled" case maxTextBytes = "max_text_bytes" case maxUpdatesPerMinute = "max_updates_per_minute" } public init(clientToProviderEnabled: Bool, providerToClientEnabled: Bool, maxTextBytes: Int64, maxUpdatesPerMinute: Int64) throws { self.clientToProviderEnabled = clientToProviderEnabled self.providerToClientEnabled = providerToClientEnabled self.maxTextBytes = maxTextBytes self.maxUpdatesPerMinute = maxUpdatesPerMinute try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(clientToProviderEnabled: try c.decode(Bool.self, forKey: .clientToProviderEnabled), providerToClientEnabled: try c.decode(Bool.self, forKey: .providerToClientEnabled), maxTextBytes: try c.decode(Int64.self, forKey: .maxTextBytes), maxUpdatesPerMinute: try c.decode(Int64.self, forKey: .maxUpdatesPerMinute)) } public func validate() throws { if self.maxTextBytes < 1 { throw ContractValidationError(field: "max_text_bytes", code: "minimum") } if self.maxTextBytes > 65536 { throw ContractValidationError(field: "max_text_bytes", code: "maximum") } if self.maxUpdatesPerMinute < 1 { throw ContractValidationError(field: "max_updates_per_minute", code: "minimum") } if self.maxUpdatesPerMinute > 120 { throw ContractValidationError(field: "max_updates_per_minute", code: "maximum") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ClipboardText: Codable, Equatable { public let text: String public let encoding: String enum CodingKeys: String, CodingKey { case text = "text" case encoding = "encoding" } public init(text: String, encoding: String) throws { self.text = text self.encoding = encoding try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(text: try c.decode(String.self, forKey: .text), encoding: try c.decode(String.self, forKey: .encoding)) } public func validate() throws { if self.text.utf8.count > 65536 { throw ContractValidationError(field: "text", code: "max_length") } if self.encoding != "utf-8" { throw ContractValidationError(field: "encoding", code: "invalid_value") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ConnectionManifest: Codable, Equatable { public let version: String public let purpose: String public let sessionId: String public let reconnectSequence: Int64 public let gateway: ManifestGateway public let tunnel: ManifestTunnel public let profile: ManifestProfile public let grant: GrantReference public let correlationId: String enum CodingKeys: String, CodingKey { case version = "version" case purpose = "purpose" case sessionId = "session_id" case reconnectSequence = "reconnect_sequence" case gateway = "gateway" case tunnel = "tunnel" case profile = "profile" case grant = "grant" case correlationId = "correlation_id" } public init(version: String, purpose: String, sessionId: String, reconnectSequence: Int64, gateway: ManifestGateway, tunnel: ManifestTunnel, profile: ManifestProfile, grant: GrantReference, correlationId: String) throws { self.version = version self.purpose = purpose self.sessionId = sessionId self.reconnectSequence = reconnectSequence self.gateway = gateway self.tunnel = tunnel self.profile = profile self.grant = grant self.correlationId = correlationId try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(version: try c.decode(String.self, forKey: .version), purpose: try c.decode(String.self, forKey: .purpose), sessionId: try c.decode(String.self, forKey: .sessionId), reconnectSequence: try c.decode(Int64.self, forKey: .reconnectSequence), gateway: try c.decode(ManifestGateway.self, forKey: .gateway), tunnel: try c.decode(ManifestTunnel.self, forKey: .tunnel), profile: try c.decode(ManifestProfile.self, forKey: .profile), grant: try c.decode(GrantReference.self, forKey: .grant), correlationId: try c.decode(String.self, forKey: .correlationId)) } public func validate() throws { if self.version != "1" { throw ContractValidationError(field: "version", code: "invalid_value") } if !["launch", "reconnect"].contains(self.purpose) { throw ContractValidationError(field: "purpose", code: "invalid_value") } if self.sessionId.isEmpty { throw ContractValidationError(field: "session_id", code: "required") } if !self.sessionId.isEmpty && self.sessionId.utf8.count < 1 { throw ContractValidationError(field: "session_id", code: "min_length") } if self.sessionId.utf8.count > 128 { throw ContractValidationError(field: "session_id", code: "max_length") } if self.reconnectSequence < 0 { throw ContractValidationError(field: "reconnect_sequence", code: "minimum") } try self.gateway.validate() try self.tunnel.validate() try self.profile.validate() try self.grant.validate() if self.correlationId.isEmpty { throw ContractValidationError(field: "correlation_id", code: "required") } if !self.correlationId.isEmpty && self.correlationId.utf8.count < 1 { throw ContractValidationError(field: "correlation_id", code: "min_length") } if self.correlationId.utf8.count > 128 { throw ContractValidationError(field: "correlation_id", code: "max_length") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct DeviceChallenge: Codable, Equatable { public let deviceId: String public let serverId: String public let principalId: String public let challenge: String public let expiresAt: String public let algorithm: String public let signatureFormat: String enum CodingKeys: String, CodingKey { case deviceId = "device_id" case serverId = "server_id" case principalId = "principal_id" case challenge = "challenge" case expiresAt = "expires_at" case algorithm = "algorithm" case signatureFormat = "signature_format" } public init(deviceId: String, serverId: String, principalId: String, challenge: String, expiresAt: String, algorithm: String, signatureFormat: String) throws { self.deviceId = deviceId self.serverId = serverId self.principalId = principalId self.challenge = challenge self.expiresAt = expiresAt self.algorithm = algorithm self.signatureFormat = signatureFormat try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(deviceId: try c.decode(String.self, forKey: .deviceId), serverId: try c.decode(String.self, forKey: .serverId), principalId: try c.decode(String.self, forKey: .principalId), challenge: try c.decode(String.self, forKey: .challenge), expiresAt: try c.decode(String.self, forKey: .expiresAt), algorithm: try c.decode(String.self, forKey: .algorithm), signatureFormat: try c.decode(String.self, forKey: .signatureFormat)) } public func validate() throws { if self.deviceId.isEmpty { throw ContractValidationError(field: "device_id", code: "required") } if !self.deviceId.isEmpty && self.deviceId.utf8.count < 1 { throw ContractValidationError(field: "device_id", code: "min_length") } if self.deviceId.utf8.count > 128 { throw ContractValidationError(field: "device_id", code: "max_length") } if self.serverId.isEmpty { throw ContractValidationError(field: "server_id", code: "required") } if !self.serverId.isEmpty && self.serverId.utf8.count < 1 { throw ContractValidationError(field: "server_id", code: "min_length") } if self.serverId.utf8.count > 128 { throw ContractValidationError(field: "server_id", code: "max_length") } if self.principalId.isEmpty { throw ContractValidationError(field: "principal_id", code: "required") } if !self.principalId.isEmpty && self.principalId.utf8.count < 1 { throw ContractValidationError(field: "principal_id", code: "min_length") } if self.principalId.utf8.count > 128 { throw ContractValidationError(field: "principal_id", code: "max_length") } if self.challenge.isEmpty { throw ContractValidationError(field: "challenge", code: "required") } if !self.challenge.isEmpty && self.challenge.utf8.count < 1 { throw ContractValidationError(field: "challenge", code: "min_length") } if self.challenge.utf8.count > 256 { throw ContractValidationError(field: "challenge", code: "max_length") } if self.expiresAt.utf8.count > 64 { throw ContractValidationError(field: "expires_at", code: "max_length") } if ISO8601DateFormatter().date(from: self.expiresAt) == nil { throw ContractValidationError(field: "expires_at", code: "invalid_time") } if self.algorithm != "ed25519" { throw ContractValidationError(field: "algorithm", code: "invalid_value") } if self.signatureFormat != "ed25519-domain-separated-v1" { throw ContractValidationError(field: "signature_format", code: "invalid_value") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct DeviceProofRequest: Codable, Equatable { public let challenge: String public let signature: String enum CodingKeys: String, CodingKey { case challenge = "challenge" case signature = "signature" } public init(challenge: String, signature: String) throws { self.challenge = challenge self.signature = signature try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(challenge: try c.decode(String.self, forKey: .challenge), signature: try c.decode(String.self, forKey: .signature)) } public func validate() throws { if self.challenge.isEmpty { throw ContractValidationError(field: "challenge", code: "required") } if !self.challenge.isEmpty && self.challenge.utf8.count < 1 { throw ContractValidationError(field: "challenge", code: "min_length") } if self.challenge.utf8.count > 256 { throw ContractValidationError(field: "challenge", code: "max_length") } if self.signature.isEmpty { throw ContractValidationError(field: "signature", code: "required") } if !self.signature.isEmpty && self.signature.utf8.count < 1 { throw ContractValidationError(field: "signature", code: "min_length") } if self.signature.utf8.count > 256 { throw ContractValidationError(field: "signature", code: "max_length") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct DeviceRegistrationRequest: Codable, Equatable { public let name: String public let platform: String public let deviceSubject: String public let algorithm: String public let publicKey: String enum CodingKeys: String, CodingKey { case name = "name" case platform = "platform" case deviceSubject = "device_subject" case algorithm = "algorithm" case publicKey = "public_key" } public init(name: String, platform: String, deviceSubject: String, algorithm: String, publicKey: String) throws { self.name = name self.platform = platform self.deviceSubject = deviceSubject self.algorithm = algorithm self.publicKey = publicKey try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(name: try c.decode(String.self, forKey: .name), platform: try c.decode(String.self, forKey: .platform), deviceSubject: try c.decode(String.self, forKey: .deviceSubject), algorithm: try c.decode(String.self, forKey: .algorithm), publicKey: try c.decode(String.self, forKey: .publicKey)) } public func validate() throws { if self.name.isEmpty { throw ContractValidationError(field: "name", code: "required") } if !self.name.isEmpty && self.name.utf8.count < 1 { throw ContractValidationError(field: "name", code: "min_length") } if self.name.utf8.count > 128 { throw ContractValidationError(field: "name", code: "max_length") } if self.platform.isEmpty { throw ContractValidationError(field: "platform", code: "required") } if !self.platform.isEmpty && self.platform.utf8.count < 1 { throw ContractValidationError(field: "platform", code: "min_length") } if self.platform.utf8.count > 64 { throw ContractValidationError(field: "platform", code: "max_length") } if self.deviceSubject.isEmpty { throw ContractValidationError(field: "device_subject", code: "required") } if !self.deviceSubject.isEmpty && self.deviceSubject.utf8.count < 1 { throw ContractValidationError(field: "device_subject", code: "min_length") } if self.deviceSubject.utf8.count > 256 { throw ContractValidationError(field: "device_subject", code: "max_length") } if self.algorithm != "ed25519" { throw ContractValidationError(field: "algorithm", code: "invalid_value") } if self.publicKey.isEmpty { throw ContractValidationError(field: "public_key", code: "required") } if !self.publicKey.isEmpty && self.publicKey.utf8.count < 1 { throw ContractValidationError(field: "public_key", code: "min_length") } if self.publicKey.utf8.count > 256 { throw ContractValidationError(field: "public_key", code: "max_length") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct EntitledPool: Codable, Equatable { public let poolId: String public let name: String public let assignmentState: String enum CodingKeys: String, CodingKey { case poolId = "pool_id" case name = "name" case assignmentState = "assignment_state" } public init(poolId: String, name: String, assignmentState: String) throws { self.poolId = poolId self.name = name self.assignmentState = assignmentState try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(poolId: try c.decode(String.self, forKey: .poolId), name: try c.decode(String.self, forKey: .name), assignmentState: try c.decode(String.self, forKey: .assignmentState)) } public func validate() throws { if self.poolId.isEmpty { throw ContractValidationError(field: "pool_id", code: "required") } if !self.poolId.isEmpty && self.poolId.utf8.count < 1 { throw ContractValidationError(field: "pool_id", code: "min_length") } if self.poolId.utf8.count > 128 { throw ContractValidationError(field: "pool_id", code: "max_length") } if self.name.isEmpty { throw ContractValidationError(field: "name", code: "required") } if !self.name.isEmpty && self.name.utf8.count < 1 { throw ContractValidationError(field: "name", code: "min_length") } if self.name.utf8.count > 256 { throw ContractValidationError(field: "name", code: "max_length") } if self.assignmentState.isEmpty { throw ContractValidationError(field: "assignment_state", code: "required") } if !self.assignmentState.isEmpty && self.assignmentState.utf8.count < 1 { throw ContractValidationError(field: "assignment_state", code: "min_length") } if self.assignmentState.utf8.count > 64 { throw ContractValidationError(field: "assignment_state", code: "max_length") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ErrorEnvelope: Codable, Equatable { public let status: Bool public let error: String public let code: String public let message: String public let resolution: String public let requestId: String public let violations: [FieldViolation] enum CodingKeys: String, CodingKey { case status = "status" case error = "error" case code = "code" case message = "message" case resolution = "resolution" case requestId = "request_id" case violations = "violations" } public init(status: Bool, error: String, code: String, message: String, resolution: String, requestId: String, violations: [FieldViolation]) throws { self.status = status self.error = error self.code = code self.message = message self.resolution = resolution self.requestId = requestId self.violations = violations try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(status: try c.decode(Bool.self, forKey: .status), error: try c.decode(String.self, forKey: .error), code: try c.decode(String.self, forKey: .code), message: try c.decode(String.self, forKey: .message), resolution: try c.decode(String.self, forKey: .resolution), requestId: try c.decode(String.self, forKey: .requestId), violations: try c.decode([FieldViolation].self, forKey: .violations)) } public func validate() throws { if self.error.isEmpty { throw ContractValidationError(field: "error", code: "required") } if !self.error.isEmpty && self.error.utf8.count < 1 { throw ContractValidationError(field: "error", code: "min_length") } if self.error.utf8.count > 512 { throw ContractValidationError(field: "error", code: "max_length") } if self.code.isEmpty { throw ContractValidationError(field: "code", code: "required") } if !self.code.isEmpty && self.code.utf8.count < 1 { throw ContractValidationError(field: "code", code: "min_length") } if self.code.utf8.count > 128 { throw ContractValidationError(field: "code", code: "max_length") } if self.message.isEmpty { throw ContractValidationError(field: "message", code: "required") } if !self.message.isEmpty && self.message.utf8.count < 1 { throw ContractValidationError(field: "message", code: "min_length") } if self.message.utf8.count > 512 { throw ContractValidationError(field: "message", code: "max_length") } if self.resolution.isEmpty { throw ContractValidationError(field: "resolution", code: "required") } if !self.resolution.isEmpty && self.resolution.utf8.count < 1 { throw ContractValidationError(field: "resolution", code: "min_length") } if self.resolution.utf8.count > 128 { throw ContractValidationError(field: "resolution", code: "max_length") } if self.requestId.isEmpty { throw ContractValidationError(field: "request_id", code: "required") } if !self.requestId.isEmpty && self.requestId.utf8.count < 1 { throw ContractValidationError(field: "request_id", code: "min_length") } if self.requestId.utf8.count > 128 { throw ContractValidationError(field: "request_id", code: "max_length") } if self.violations.count > 16 { throw ContractValidationError(field: "violations", code: "max_items") } for item in self.violations { try item.validate() } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct EventEnvelope: Codable, Equatable { public let eventId: String public let sequence: Int64 public let type: String public let version: Int64 public let resource: ResourceLink public let occurredAt: String public let correlationId: String public let payload: JSONObject enum CodingKeys: String, CodingKey { case eventId = "event_id" case sequence = "sequence" case type = "type" case version = "version" case resource = "resource" case occurredAt = "occurred_at" case correlationId = "correlation_id" case payload = "payload" } public init(eventId: String, sequence: Int64, type: String, version: Int64, resource: ResourceLink, occurredAt: String, correlationId: String, payload: JSONObject) throws { self.eventId = eventId self.sequence = sequence self.type = type self.version = version self.resource = resource self.occurredAt = occurredAt self.correlationId = correlationId self.payload = payload try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(eventId: try c.decode(String.self, forKey: .eventId), sequence: try c.decode(Int64.self, forKey: .sequence), type: try c.decode(String.self, forKey: .type), version: try c.decode(Int64.self, forKey: .version), resource: try c.decode(ResourceLink.self, forKey: .resource), occurredAt: try c.decode(String.self, forKey: .occurredAt), correlationId: try c.decode(String.self, forKey: .correlationId), payload: try c.decode(JSONObject.self, forKey: .payload)) } public func validate() throws { if self.eventId.isEmpty { throw ContractValidationError(field: "event_id", code: "required") } if !self.eventId.isEmpty && self.eventId.utf8.count < 1 { throw ContractValidationError(field: "event_id", code: "min_length") } if self.eventId.utf8.count > 128 { throw ContractValidationError(field: "event_id", code: "max_length") } if self.sequence < 1 { throw ContractValidationError(field: "sequence", code: "minimum") } if self.type.isEmpty { throw ContractValidationError(field: "type", code: "required") } if !self.type.isEmpty && self.type.utf8.count < 1 { throw ContractValidationError(field: "type", code: "min_length") } if self.type.utf8.count > 128 { throw ContractValidationError(field: "type", code: "max_length") } if self.version < 1 { throw ContractValidationError(field: "version", code: "minimum") } try self.resource.validate() if self.occurredAt.utf8.count > 64 { throw ContractValidationError(field: "occurred_at", code: "max_length") } if ISO8601DateFormatter().date(from: self.occurredAt) == nil { throw ContractValidationError(field: "occurred_at", code: "invalid_time") } if self.correlationId.isEmpty { throw ContractValidationError(field: "correlation_id", code: "required") } if !self.correlationId.isEmpty && self.correlationId.utf8.count < 1 { throw ContractValidationError(field: "correlation_id", code: "min_length") } if self.correlationId.utf8.count > 128 { throw ContractValidationError(field: "correlation_id", code: "max_length") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct EventResume: Codable, Equatable { public let cursor: String public let lastSequence: Int64 enum CodingKeys: String, CodingKey { case cursor = "cursor" case lastSequence = "last_sequence" } public init(cursor: String, lastSequence: Int64) throws { self.cursor = cursor self.lastSequence = lastSequence try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(cursor: try c.decode(String.self, forKey: .cursor), lastSequence: try c.decode(Int64.self, forKey: .lastSequence)) } public func validate() throws { if self.cursor.utf8.count > 512 { throw ContractValidationError(field: "cursor", code: "max_length") } if self.lastSequence < 0 { throw ContractValidationError(field: "last_sequence", code: "minimum") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct FieldViolation: Codable, Equatable { public let field: String public let code: String enum CodingKeys: String, CodingKey { case field = "field" case code = "code" } public init(field: String, code: String) throws { self.field = field self.code = code try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(field: try c.decode(String.self, forKey: .field), code: try c.decode(String.self, forKey: .code)) } public func validate() throws { if self.field.isEmpty { throw ContractValidationError(field: "field", code: "required") } if !self.field.isEmpty && self.field.utf8.count < 1 { throw ContractValidationError(field: "field", code: "min_length") } if self.field.utf8.count > 128 { throw ContractValidationError(field: "field", code: "max_length") } if self.code.isEmpty { throw ContractValidationError(field: "code", code: "required") } if !self.code.isEmpty && self.code.utf8.count < 1 { throw ContractValidationError(field: "code", code: "min_length") } if self.code.utf8.count > 64 { throw ContractValidationError(field: "code", code: "max_length") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct GatewayClipboardAudit: Codable, Equatable { public let version: String public let sessionId: String public let direction: String public let outcome: String public let textBytes: Int64 public let reason: String enum CodingKeys: String, CodingKey { case version = "version" case sessionId = "session_id" case direction = "direction" case outcome = "outcome" case textBytes = "text_bytes" case reason = "reason" } public init(version: String, sessionId: String, direction: String, outcome: String, textBytes: Int64, reason: String) throws { self.version = version self.sessionId = sessionId self.direction = direction self.outcome = outcome self.textBytes = textBytes self.reason = reason try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(version: try c.decode(String.self, forKey: .version), sessionId: try c.decode(String.self, forKey: .sessionId), direction: try c.decode(String.self, forKey: .direction), outcome: try c.decode(String.self, forKey: .outcome), textBytes: try c.decode(Int64.self, forKey: .textBytes), reason: try c.decode(String.self, forKey: .reason)) } public func validate() throws { if self.version != "1" { throw ContractValidationError(field: "version", code: "invalid_value") } if self.sessionId.isEmpty { throw ContractValidationError(field: "session_id", code: "required") } if !self.sessionId.isEmpty && self.sessionId.utf8.count < 1 { throw ContractValidationError(field: "session_id", code: "min_length") } if self.sessionId.utf8.count > 128 { throw ContractValidationError(field: "session_id", code: "max_length") } if !["client_to_provider", "provider_to_client"].contains(self.direction) { throw ContractValidationError(field: "direction", code: "invalid_value") } if !["forwarded", "suppressed", "rejected"].contains(self.outcome) { throw ContractValidationError(field: "outcome", code: "invalid_value") } if self.textBytes < 0 { throw ContractValidationError(field: "text_bytes", code: "minimum") } if self.textBytes > 65536 { throw ContractValidationError(field: "text_bytes", code: "maximum") } if !["forwarded", "loop", "policy", "rate", "provider", "malformed"].contains(self.reason) { throw ContractValidationError(field: "reason", code: "invalid_value") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct GatewayClipboardText: Codable, Equatable { public let direction: String public let text: String public let encoding: String public let loopToken: String enum CodingKeys: String, CodingKey { case direction = "direction" case text = "text" case encoding = "encoding" case loopToken = "loop_token" } public init(direction: String, text: String, encoding: String, loopToken: String) throws { self.direction = direction self.text = text self.encoding = encoding self.loopToken = loopToken try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(direction: try c.decode(String.self, forKey: .direction), text: try c.decode(String.self, forKey: .text), encoding: try c.decode(String.self, forKey: .encoding), loopToken: try c.decode(String.self, forKey: .loopToken)) } public func validate() throws { if !["client_to_provider", "provider_to_client"].contains(self.direction) { throw ContractValidationError(field: "direction", code: "invalid_value") } if self.text.utf8.count > 65536 { throw ContractValidationError(field: "text", code: "max_length") } if self.text.utf8.count > 65536 { throw ContractValidationError(field: "text", code: "max_bytes") } if self.encoding != "utf-8" { throw ContractValidationError(field: "encoding", code: "invalid_value") } if self.loopToken.isEmpty { throw ContractValidationError(field: "loop_token", code: "required") } if !self.loopToken.isEmpty && self.loopToken.utf8.count < 16 { throw ContractValidationError(field: "loop_token", code: "min_length") } if self.loopToken.utf8.count > 128 { throw ContractValidationError(field: "loop_token", code: "max_length") } if !validBase64URL(self.loopToken) { throw ContractValidationError(field: "loop_token", code: "invalid_format") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct GatewayDrain: Codable, Equatable { public let version: String public let gatewayId: String public let sequence: Int64 public let reason: String public let deadline: String enum CodingKeys: String, CodingKey { case version = "version" case gatewayId = "gateway_id" case sequence = "sequence" case reason = "reason" case deadline = "deadline" } public init(version: String, gatewayId: String, sequence: Int64, reason: String, deadline: String) throws { self.version = version self.gatewayId = gatewayId self.sequence = sequence self.reason = reason self.deadline = deadline try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(version: try c.decode(String.self, forKey: .version), gatewayId: try c.decode(String.self, forKey: .gatewayId), sequence: try c.decode(Int64.self, forKey: .sequence), reason: try c.decode(String.self, forKey: .reason), deadline: try c.decode(String.self, forKey: .deadline)) } public func validate() throws { if self.version != "1" { throw ContractValidationError(field: "version", code: "invalid_value") } if self.gatewayId.isEmpty { throw ContractValidationError(field: "gateway_id", code: "required") } if !self.gatewayId.isEmpty && self.gatewayId.utf8.count < 1 { throw ContractValidationError(field: "gateway_id", code: "min_length") } if self.gatewayId.utf8.count > 128 { throw ContractValidationError(field: "gateway_id", code: "max_length") } if self.sequence < 1 { throw ContractValidationError(field: "sequence", code: "minimum") } if self.reason.isEmpty { throw ContractValidationError(field: "reason", code: "required") } if !self.reason.isEmpty && self.reason.utf8.count < 1 { throw ContractValidationError(field: "reason", code: "min_length") } if self.reason.utf8.count > 256 { throw ContractValidationError(field: "reason", code: "max_length") } if self.deadline.utf8.count > 64 { throw ContractValidationError(field: "deadline", code: "max_length") } if ISO8601DateFormatter().date(from: self.deadline) == nil { throw ContractValidationError(field: "deadline", code: "invalid_time") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct GatewayHeartbeat: Codable, Equatable { public let version: String public let gatewayId: String public let sequence: Int64 public let observedAt: String public let activeConnections: Int64 public let egressKbps: Int64 public let state: String public let telemetry: GatewayTelemetry enum CodingKeys: String, CodingKey { case version = "version" case gatewayId = "gateway_id" case sequence = "sequence" case observedAt = "observed_at" case activeConnections = "active_connections" case egressKbps = "egress_kbps" case state = "state" case telemetry = "telemetry" } public init(version: String, gatewayId: String, sequence: Int64, observedAt: String, activeConnections: Int64, egressKbps: Int64, state: String, telemetry: GatewayTelemetry) throws { self.version = version self.gatewayId = gatewayId self.sequence = sequence self.observedAt = observedAt self.activeConnections = activeConnections self.egressKbps = egressKbps self.state = state self.telemetry = telemetry try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(version: try c.decode(String.self, forKey: .version), gatewayId: try c.decode(String.self, forKey: .gatewayId), sequence: try c.decode(Int64.self, forKey: .sequence), observedAt: try c.decode(String.self, forKey: .observedAt), activeConnections: try c.decode(Int64.self, forKey: .activeConnections), egressKbps: try c.decode(Int64.self, forKey: .egressKbps), state: try c.decode(String.self, forKey: .state), telemetry: try c.decode(GatewayTelemetry.self, forKey: .telemetry)) } public func validate() throws { if self.version != "1" { throw ContractValidationError(field: "version", code: "invalid_value") } if self.gatewayId.isEmpty { throw ContractValidationError(field: "gateway_id", code: "required") } if !self.gatewayId.isEmpty && self.gatewayId.utf8.count < 1 { throw ContractValidationError(field: "gateway_id", code: "min_length") } if self.gatewayId.utf8.count > 128 { throw ContractValidationError(field: "gateway_id", code: "max_length") } if self.sequence < 1 { throw ContractValidationError(field: "sequence", code: "minimum") } if self.observedAt.utf8.count > 64 { throw ContractValidationError(field: "observed_at", code: "max_length") } if ISO8601DateFormatter().date(from: self.observedAt) == nil { throw ContractValidationError(field: "observed_at", code: "invalid_time") } if self.activeConnections < 0 { throw ContractValidationError(field: "active_connections", code: "minimum") } if self.activeConnections > 1000000 { throw ContractValidationError(field: "active_connections", code: "maximum") } if self.egressKbps < 0 { throw ContractValidationError(field: "egress_kbps", code: "minimum") } if self.egressKbps > 1000000000 { throw ContractValidationError(field: "egress_kbps", code: "maximum") } if !["ready", "draining", "offline"].contains(self.state) { throw ContractValidationError(field: "state", code: "invalid_value") } try self.telemetry.validate() } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct GatewayRegistration: Codable, Equatable { public let version: String public let gatewayId: String public let instanceIdentity: String public let certificateIdentity: String public let publicIdentity: String public let address: String public let providerIdentity: String public let protocolMinVersion: Int64 public let protocolMaxVersion: Int64 public let connectionCapacity: Int64 public let bandwidthCapacityKbps: Int64 public let features: [String] public let capabilities: CapabilityProfile enum CodingKeys: String, CodingKey { case version = "version" case gatewayId = "gateway_id" case instanceIdentity = "instance_identity" case certificateIdentity = "certificate_identity" case publicIdentity = "public_identity" case address = "address" case providerIdentity = "provider_identity" case protocolMinVersion = "protocol_min_version" case protocolMaxVersion = "protocol_max_version" case connectionCapacity = "connection_capacity" case bandwidthCapacityKbps = "bandwidth_capacity_kbps" case features = "features" case capabilities = "capabilities" } public init(version: String, gatewayId: String, instanceIdentity: String, certificateIdentity: String, publicIdentity: String, address: String, providerIdentity: String, protocolMinVersion: Int64, protocolMaxVersion: Int64, connectionCapacity: Int64, bandwidthCapacityKbps: Int64, features: [String], capabilities: CapabilityProfile) throws { self.version = version self.gatewayId = gatewayId self.instanceIdentity = instanceIdentity self.certificateIdentity = certificateIdentity self.publicIdentity = publicIdentity self.address = address self.providerIdentity = providerIdentity self.protocolMinVersion = protocolMinVersion self.protocolMaxVersion = protocolMaxVersion self.connectionCapacity = connectionCapacity self.bandwidthCapacityKbps = bandwidthCapacityKbps self.features = features self.capabilities = capabilities try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(version: try c.decode(String.self, forKey: .version), gatewayId: try c.decode(String.self, forKey: .gatewayId), instanceIdentity: try c.decode(String.self, forKey: .instanceIdentity), certificateIdentity: try c.decode(String.self, forKey: .certificateIdentity), publicIdentity: try c.decode(String.self, forKey: .publicIdentity), address: try c.decode(String.self, forKey: .address), providerIdentity: try c.decode(String.self, forKey: .providerIdentity), protocolMinVersion: try c.decode(Int64.self, forKey: .protocolMinVersion), protocolMaxVersion: try c.decode(Int64.self, forKey: .protocolMaxVersion), connectionCapacity: try c.decode(Int64.self, forKey: .connectionCapacity), bandwidthCapacityKbps: try c.decode(Int64.self, forKey: .bandwidthCapacityKbps), features: try c.decode([String].self, forKey: .features), capabilities: try c.decode(CapabilityProfile.self, forKey: .capabilities)) } public func validate() throws { if self.version != "1" { throw ContractValidationError(field: "version", code: "invalid_value") } if self.gatewayId.isEmpty { throw ContractValidationError(field: "gateway_id", code: "required") } if !self.gatewayId.isEmpty && self.gatewayId.utf8.count < 1 { throw ContractValidationError(field: "gateway_id", code: "min_length") } if self.gatewayId.utf8.count > 128 { throw ContractValidationError(field: "gateway_id", code: "max_length") } if self.instanceIdentity.isEmpty { throw ContractValidationError(field: "instance_identity", code: "required") } if !self.instanceIdentity.isEmpty && self.instanceIdentity.utf8.count < 1 { throw ContractValidationError(field: "instance_identity", code: "min_length") } if self.instanceIdentity.utf8.count > 512 { throw ContractValidationError(field: "instance_identity", code: "max_length") } if self.certificateIdentity.isEmpty { throw ContractValidationError(field: "certificate_identity", code: "required") } if !self.certificateIdentity.isEmpty && self.certificateIdentity.utf8.count < 1 { throw ContractValidationError(field: "certificate_identity", code: "min_length") } if self.certificateIdentity.utf8.count > 512 { throw ContractValidationError(field: "certificate_identity", code: "max_length") } if self.publicIdentity.isEmpty { throw ContractValidationError(field: "public_identity", code: "required") } if !self.publicIdentity.isEmpty && self.publicIdentity.utf8.count < 1 { throw ContractValidationError(field: "public_identity", code: "min_length") } if self.publicIdentity.utf8.count > 256 { throw ContractValidationError(field: "public_identity", code: "max_length") } if self.address.isEmpty { throw ContractValidationError(field: "address", code: "required") } if !self.address.isEmpty && self.address.utf8.count < 1 { throw ContractValidationError(field: "address", code: "min_length") } if self.address.utf8.count > 256 { throw ContractValidationError(field: "address", code: "max_length") } if self.providerIdentity.isEmpty { throw ContractValidationError(field: "provider_identity", code: "required") } if !self.providerIdentity.isEmpty && self.providerIdentity.utf8.count < 1 { throw ContractValidationError(field: "provider_identity", code: "min_length") } if self.providerIdentity.utf8.count > 256 { throw ContractValidationError(field: "provider_identity", code: "max_length") } if self.protocolMinVersion < 1 { throw ContractValidationError(field: "protocol_min_version", code: "minimum") } if self.protocolMinVersion > 100 { throw ContractValidationError(field: "protocol_min_version", code: "maximum") } if self.protocolMaxVersion < 1 { throw ContractValidationError(field: "protocol_max_version", code: "minimum") } if self.protocolMaxVersion > 100 { throw ContractValidationError(field: "protocol_max_version", code: "maximum") } if self.connectionCapacity < 1 { throw ContractValidationError(field: "connection_capacity", code: "minimum") } if self.connectionCapacity > 1000000 { throw ContractValidationError(field: "connection_capacity", code: "maximum") } if self.bandwidthCapacityKbps < 1 { throw ContractValidationError(field: "bandwidth_capacity_kbps", code: "minimum") } if self.bandwidthCapacityKbps > 1000000000 { throw ContractValidationError(field: "bandwidth_capacity_kbps", code: "maximum") } if self.features.count > 64 { throw ContractValidationError(field: "features", code: "max_items") } try self.capabilities.validate() if protocolMinVersion > protocolMaxVersion { throw ContractValidationError(field: "protocol_version", code: "invalid_order") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct GatewayTelemetry: Codable, Equatable { public let admittedSessions: Int64 public let admissionRejects: Int64 public let reconnects: Int64 public let drainTransitions: Int64 public let mediaDrops: Int64 public let mediaPackets: Int64 public let mediaBytes: Int64 public let queueDelayMicros: Int64 public let processingDelayMicros: Int64 public let processingSamples: Int64 public let pacingDelayMicros: Int64 public let providerErrors: Int64 public let inputRejected: Int64 public let controlRttMicros: Int64 public let controlJitterMicros: Int64 public let controlLossPpm: Int64 public let pendingReliable: Int64 public let providerState: String enum CodingKeys: String, CodingKey { case admittedSessions = "admitted_sessions" case admissionRejects = "admission_rejects" case reconnects = "reconnects" case drainTransitions = "drain_transitions" case mediaDrops = "media_drops" case mediaPackets = "media_packets" case mediaBytes = "media_bytes" case queueDelayMicros = "queue_delay_micros" case processingDelayMicros = "processing_delay_micros" case processingSamples = "processing_samples" case pacingDelayMicros = "pacing_delay_micros" case providerErrors = "provider_errors" case inputRejected = "input_rejected" case controlRttMicros = "control_rtt_micros" case controlJitterMicros = "control_jitter_micros" case controlLossPpm = "control_loss_ppm" case pendingReliable = "pending_reliable" case providerState = "provider_state" } public init(admittedSessions: Int64, admissionRejects: Int64, reconnects: Int64, drainTransitions: Int64, mediaDrops: Int64, mediaPackets: Int64, mediaBytes: Int64, queueDelayMicros: Int64, processingDelayMicros: Int64, processingSamples: Int64, pacingDelayMicros: Int64, providerErrors: Int64, inputRejected: Int64, controlRttMicros: Int64, controlJitterMicros: Int64, controlLossPpm: Int64, pendingReliable: Int64, providerState: String) throws { self.admittedSessions = admittedSessions self.admissionRejects = admissionRejects self.reconnects = reconnects self.drainTransitions = drainTransitions self.mediaDrops = mediaDrops self.mediaPackets = mediaPackets self.mediaBytes = mediaBytes self.queueDelayMicros = queueDelayMicros self.processingDelayMicros = processingDelayMicros self.processingSamples = processingSamples self.pacingDelayMicros = pacingDelayMicros self.providerErrors = providerErrors self.inputRejected = inputRejected self.controlRttMicros = controlRttMicros self.controlJitterMicros = controlJitterMicros self.controlLossPpm = controlLossPpm self.pendingReliable = pendingReliable self.providerState = providerState try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(admittedSessions: try c.decode(Int64.self, forKey: .admittedSessions), admissionRejects: try c.decode(Int64.self, forKey: .admissionRejects), reconnects: try c.decode(Int64.self, forKey: .reconnects), drainTransitions: try c.decode(Int64.self, forKey: .drainTransitions), mediaDrops: try c.decode(Int64.self, forKey: .mediaDrops), mediaPackets: try c.decode(Int64.self, forKey: .mediaPackets), mediaBytes: try c.decode(Int64.self, forKey: .mediaBytes), queueDelayMicros: try c.decode(Int64.self, forKey: .queueDelayMicros), processingDelayMicros: try c.decode(Int64.self, forKey: .processingDelayMicros), processingSamples: try c.decode(Int64.self, forKey: .processingSamples), pacingDelayMicros: try c.decode(Int64.self, forKey: .pacingDelayMicros), providerErrors: try c.decode(Int64.self, forKey: .providerErrors), inputRejected: try c.decode(Int64.self, forKey: .inputRejected), controlRttMicros: try c.decode(Int64.self, forKey: .controlRttMicros), controlJitterMicros: try c.decode(Int64.self, forKey: .controlJitterMicros), controlLossPpm: try c.decode(Int64.self, forKey: .controlLossPpm), pendingReliable: try c.decode(Int64.self, forKey: .pendingReliable), providerState: try c.decode(String.self, forKey: .providerState)) } public func validate() throws { if self.admittedSessions < 0 { throw ContractValidationError(field: "admitted_sessions", code: "minimum") } if self.admittedSessions > 9223372036854775807 { throw ContractValidationError(field: "admitted_sessions", code: "maximum") } if self.admissionRejects < 0 { throw ContractValidationError(field: "admission_rejects", code: "minimum") } if self.admissionRejects > 9223372036854775807 { throw ContractValidationError(field: "admission_rejects", code: "maximum") } if self.reconnects < 0 { throw ContractValidationError(field: "reconnects", code: "minimum") } if self.reconnects > 9223372036854775807 { throw ContractValidationError(field: "reconnects", code: "maximum") } if self.drainTransitions < 0 { throw ContractValidationError(field: "drain_transitions", code: "minimum") } if self.drainTransitions > 9223372036854775807 { throw ContractValidationError(field: "drain_transitions", code: "maximum") } if self.mediaDrops < 0 { throw ContractValidationError(field: "media_drops", code: "minimum") } if self.mediaDrops > 9223372036854775807 { throw ContractValidationError(field: "media_drops", code: "maximum") } if self.mediaPackets < 0 { throw ContractValidationError(field: "media_packets", code: "minimum") } if self.mediaPackets > 9223372036854775807 { throw ContractValidationError(field: "media_packets", code: "maximum") } if self.mediaBytes < 0 { throw ContractValidationError(field: "media_bytes", code: "minimum") } if self.mediaBytes > 9223372036854775807 { throw ContractValidationError(field: "media_bytes", code: "maximum") } if self.queueDelayMicros < 0 { throw ContractValidationError(field: "queue_delay_micros", code: "minimum") } if self.queueDelayMicros > 9223372036854775807 { throw ContractValidationError(field: "queue_delay_micros", code: "maximum") } if self.processingDelayMicros < 0 { throw ContractValidationError(field: "processing_delay_micros", code: "minimum") } if self.processingDelayMicros > 9223372036854775807 { throw ContractValidationError(field: "processing_delay_micros", code: "maximum") } if self.processingSamples < 0 { throw ContractValidationError(field: "processing_samples", code: "minimum") } if self.processingSamples > 9223372036854775807 { throw ContractValidationError(field: "processing_samples", code: "maximum") } if self.pacingDelayMicros < 0 { throw ContractValidationError(field: "pacing_delay_micros", code: "minimum") } if self.pacingDelayMicros > 9223372036854775807 { throw ContractValidationError(field: "pacing_delay_micros", code: "maximum") } if self.providerErrors < 0 { throw ContractValidationError(field: "provider_errors", code: "minimum") } if self.providerErrors > 9223372036854775807 { throw ContractValidationError(field: "provider_errors", code: "maximum") } if self.inputRejected < 0 { throw ContractValidationError(field: "input_rejected", code: "minimum") } if self.inputRejected > 9223372036854775807 { throw ContractValidationError(field: "input_rejected", code: "maximum") } if self.controlRttMicros < 0 { throw ContractValidationError(field: "control_rtt_micros", code: "minimum") } if self.controlRttMicros > 9223372036854775807 { throw ContractValidationError(field: "control_rtt_micros", code: "maximum") } if self.controlJitterMicros < 0 { throw ContractValidationError(field: "control_jitter_micros", code: "minimum") } if self.controlJitterMicros > 9223372036854775807 { throw ContractValidationError(field: "control_jitter_micros", code: "maximum") } if self.controlLossPpm < 0 { throw ContractValidationError(field: "control_loss_ppm", code: "minimum") } if self.controlLossPpm > 1000000 { throw ContractValidationError(field: "control_loss_ppm", code: "maximum") } if self.pendingReliable < 0 { throw ContractValidationError(field: "pending_reliable", code: "minimum") } if self.pendingReliable > 9223372036854775807 { throw ContractValidationError(field: "pending_reliable", code: "maximum") } if !["unknown", "starting", "ready", "disconnected", "terminating", "terminated", "cleanup_pending", "failed"].contains(self.providerState) { throw ContractValidationError(field: "provider_state", code: "invalid_value") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct GrantReference: Codable, Equatable { public let opaqueValue: String public let expiresAt: String public let audience: String enum CodingKeys: String, CodingKey { case opaqueValue = "opaque_value" case expiresAt = "expires_at" case audience = "audience" } public init(opaqueValue: String, expiresAt: String, audience: String) throws { self.opaqueValue = opaqueValue self.expiresAt = expiresAt self.audience = audience try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(opaqueValue: try c.decode(String.self, forKey: .opaqueValue), expiresAt: try c.decode(String.self, forKey: .expiresAt), audience: try c.decode(String.self, forKey: .audience)) } public func validate() throws { if self.opaqueValue.isEmpty { throw ContractValidationError(field: "opaque_value", code: "required") } if !self.opaqueValue.isEmpty && self.opaqueValue.utf8.count < 43 { throw ContractValidationError(field: "opaque_value", code: "min_length") } if self.opaqueValue.utf8.count > 256 { throw ContractValidationError(field: "opaque_value", code: "max_length") } if self.expiresAt.utf8.count > 64 { throw ContractValidationError(field: "expires_at", code: "max_length") } if ISO8601DateFormatter().date(from: self.expiresAt) == nil { throw ContractValidationError(field: "expires_at", code: "invalid_time") } if self.audience.isEmpty { throw ContractValidationError(field: "audience", code: "required") } if !self.audience.isEmpty && self.audience.utf8.count < 1 { throw ContractValidationError(field: "audience", code: "min_length") } if self.audience.utf8.count > 128 { throw ContractValidationError(field: "audience", code: "max_length") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct LoginRequest: Codable, Equatable { public let provider: String? public let username: String public let password: String enum CodingKeys: String, CodingKey { case provider = "provider" case username = "username" case password = "password" } public init(provider: String?, username: String, password: String) throws { self.provider = provider self.username = username self.password = password try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(provider: try c.decodeIfPresent(String.self, forKey: .provider), username: try c.decode(String.self, forKey: .username), password: try c.decode(String.self, forKey: .password)) } public func validate() throws { if let value = self.provider { if !["ldap", "local"].contains(value) { throw ContractValidationError(field: "provider", code: "invalid_value") } } if self.username.isEmpty { throw ContractValidationError(field: "username", code: "required") } if !self.username.isEmpty && self.username.utf8.count < 1 { throw ContractValidationError(field: "username", code: "min_length") } if self.username.utf8.count > 256 { throw ContractValidationError(field: "username", code: "max_length") } if self.password.isEmpty { throw ContractValidationError(field: "password", code: "required") } if !self.password.isEmpty && self.password.utf8.count < 1 { throw ContractValidationError(field: "password", code: "min_length") } if self.password.utf8.count > 1024 { throw ContractValidationError(field: "password", code: "max_length") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ManifestBounds: Codable, Equatable { public let minimumKbps: Int64 public let targetKbps: Int64 public let maximumKbps: Int64 enum CodingKeys: String, CodingKey { case minimumKbps = "minimum_kbps" case targetKbps = "target_kbps" case maximumKbps = "maximum_kbps" } public init(minimumKbps: Int64, targetKbps: Int64, maximumKbps: Int64) throws { self.minimumKbps = minimumKbps self.targetKbps = targetKbps self.maximumKbps = maximumKbps try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(minimumKbps: try c.decode(Int64.self, forKey: .minimumKbps), targetKbps: try c.decode(Int64.self, forKey: .targetKbps), maximumKbps: try c.decode(Int64.self, forKey: .maximumKbps)) } public func validate() throws { if self.minimumKbps < 1 { throw ContractValidationError(field: "minimum_kbps", code: "minimum") } if self.minimumKbps > 100000000 { throw ContractValidationError(field: "minimum_kbps", code: "maximum") } if self.targetKbps < 1 { throw ContractValidationError(field: "target_kbps", code: "minimum") } if self.targetKbps > 100000000 { throw ContractValidationError(field: "target_kbps", code: "maximum") } if self.maximumKbps < 1 { throw ContractValidationError(field: "maximum_kbps", code: "minimum") } if self.maximumKbps > 100000000 { throw ContractValidationError(field: "maximum_kbps", code: "maximum") } if minimumKbps > targetKbps || targetKbps > maximumKbps { throw ContractValidationError(field: "bounds", code: "invalid_order") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ManifestGateway: Codable, Equatable { public let id: String public let addresses: [String] public let publicIdentity: String enum CodingKeys: String, CodingKey { case id = "id" case addresses = "addresses" case publicIdentity = "public_identity" } public init(id: String, addresses: [String], publicIdentity: String) throws { self.id = id self.addresses = addresses self.publicIdentity = publicIdentity try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(id: try c.decode(String.self, forKey: .id), addresses: try c.decode([String].self, forKey: .addresses), publicIdentity: try c.decode(String.self, forKey: .publicIdentity)) } public func validate() throws { if self.id.isEmpty { throw ContractValidationError(field: "id", code: "required") } if !self.id.isEmpty && self.id.utf8.count < 1 { throw ContractValidationError(field: "id", code: "min_length") } if self.id.utf8.count > 128 { throw ContractValidationError(field: "id", code: "max_length") } if self.addresses.count < 1 { throw ContractValidationError(field: "addresses", code: "min_items") } if self.addresses.count > 4 { throw ContractValidationError(field: "addresses", code: "max_items") } if self.publicIdentity.isEmpty { throw ContractValidationError(field: "public_identity", code: "required") } if !self.publicIdentity.isEmpty && self.publicIdentity.utf8.count < 1 { throw ContractValidationError(field: "public_identity", code: "min_length") } if self.publicIdentity.utf8.count > 256 { throw ContractValidationError(field: "public_identity", code: "max_length") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ManifestProfile: Codable, Equatable { public let id: String public let bounds: ManifestBounds enum CodingKeys: String, CodingKey { case id = "id" case bounds = "bounds" } public init(id: String, bounds: ManifestBounds) throws { self.id = id self.bounds = bounds try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(id: try c.decode(String.self, forKey: .id), bounds: try c.decode(ManifestBounds.self, forKey: .bounds)) } public func validate() throws { if self.id.isEmpty { throw ContractValidationError(field: "id", code: "required") } if !self.id.isEmpty && self.id.utf8.count < 1 { throw ContractValidationError(field: "id", code: "min_length") } if self.id.utf8.count > 128 { throw ContractValidationError(field: "id", code: "max_length") } try self.bounds.validate() } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ManifestTunnel: Codable, Equatable { public let versions: [String] public let features: [String] enum CodingKeys: String, CodingKey { case versions = "versions" case features = "features" } public init(versions: [String], features: [String]) throws { self.versions = versions self.features = features try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(versions: try c.decode([String].self, forKey: .versions), features: try c.decode([String].self, forKey: .features)) } public func validate() throws { if self.versions.count < 1 { throw ContractValidationError(field: "versions", code: "min_items") } if self.versions.count > 4 { throw ContractValidationError(field: "versions", code: "max_items") } if self.features.count > 32 { throw ContractValidationError(field: "features", code: "max_items") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct NativeCredential: Codable, Equatable { public let deviceId: String? public let familyId: String public let accessToken: String public let refreshToken: String public let expiresAt: String public let refreshExpiresAt: String? enum CodingKeys: String, CodingKey { case deviceId = "device_id" case familyId = "family_id" case accessToken = "access_token" case refreshToken = "refresh_token" case expiresAt = "expires_at" case refreshExpiresAt = "refresh_expires_at" } public init(deviceId: String?, familyId: String, accessToken: String, refreshToken: String, expiresAt: String, refreshExpiresAt: String?) throws { self.deviceId = deviceId self.familyId = familyId self.accessToken = accessToken self.refreshToken = refreshToken self.expiresAt = expiresAt self.refreshExpiresAt = refreshExpiresAt try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(deviceId: try c.decodeIfPresent(String.self, forKey: .deviceId), familyId: try c.decode(String.self, forKey: .familyId), accessToken: try c.decode(String.self, forKey: .accessToken), refreshToken: try c.decode(String.self, forKey: .refreshToken), expiresAt: try c.decode(String.self, forKey: .expiresAt), refreshExpiresAt: try c.decodeIfPresent(String.self, forKey: .refreshExpiresAt)) } public func validate() throws { if let value = self.deviceId { if value.utf8.count > 128 { throw ContractValidationError(field: "device_id", code: "max_length") } } if self.familyId.isEmpty { throw ContractValidationError(field: "family_id", code: "required") } if !self.familyId.isEmpty && self.familyId.utf8.count < 1 { throw ContractValidationError(field: "family_id", code: "min_length") } if self.familyId.utf8.count > 128 { throw ContractValidationError(field: "family_id", code: "max_length") } if self.accessToken.isEmpty { throw ContractValidationError(field: "access_token", code: "required") } if !self.accessToken.isEmpty && self.accessToken.utf8.count < 1 { throw ContractValidationError(field: "access_token", code: "min_length") } if self.accessToken.utf8.count > 256 { throw ContractValidationError(field: "access_token", code: "max_length") } if self.refreshToken.isEmpty { throw ContractValidationError(field: "refresh_token", code: "required") } if !self.refreshToken.isEmpty && self.refreshToken.utf8.count < 1 { throw ContractValidationError(field: "refresh_token", code: "min_length") } if self.refreshToken.utf8.count > 256 { throw ContractValidationError(field: "refresh_token", code: "max_length") } if self.expiresAt.utf8.count > 64 { throw ContractValidationError(field: "expires_at", code: "max_length") } if ISO8601DateFormatter().date(from: self.expiresAt) == nil { throw ContractValidationError(field: "expires_at", code: "invalid_time") } if let value = self.refreshExpiresAt { if value.utf8.count > 64 { throw ContractValidationError(field: "refresh_expires_at", code: "max_length") } if ISO8601DateFormatter().date(from: value) == nil { throw ContractValidationError(field: "refresh_expires_at", code: "invalid_time") } } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct PageInfo: Codable, Equatable { public let limit: Int64 public let nextCursor: String enum CodingKeys: String, CodingKey { case limit = "limit" case nextCursor = "next_cursor" } public init(limit: Int64, nextCursor: String) throws { self.limit = limit self.nextCursor = nextCursor try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(limit: try c.decode(Int64.self, forKey: .limit), nextCursor: try c.decode(String.self, forKey: .nextCursor)) } public func validate() throws { if self.limit < 1 { throw ContractValidationError(field: "limit", code: "minimum") } if self.limit > 100 { throw ContractValidationError(field: "limit", code: "maximum") } if self.nextCursor.utf8.count > 512 { throw ContractValidationError(field: "next_cursor", code: "max_length") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ProviderSessionWork: Codable, Equatable { public let version: String public let sessionId: String public let gatewayId: String public let reconnectSequence: Int64 public let expiresAt: String public let providerProfile: String public let providerIdentity: String public let policyVersionId: String public let streamPolicy: ProviderStreamPolicy public let applicationId: String public let clientId: String public let managementHost: String public let managementPort: Int64 public let streamHost: String public let streamPort: Int64 public let clientCertificatePem: String public let clientPrivateKeyPem: String public let serverCertificatePem: String public let clipboardPolicy: ClipboardPolicy public let providerApplicationTerminationAllowed: Bool enum CodingKeys: String, CodingKey { case version = "version" case sessionId = "session_id" case gatewayId = "gateway_id" case reconnectSequence = "reconnect_sequence" case expiresAt = "expires_at" case providerProfile = "provider_profile" case providerIdentity = "provider_identity" case policyVersionId = "policy_version_id" case streamPolicy = "stream_policy" case applicationId = "application_id" case clientId = "client_id" case managementHost = "management_host" case managementPort = "management_port" case streamHost = "stream_host" case streamPort = "stream_port" case clientCertificatePem = "client_certificate_pem" case clientPrivateKeyPem = "client_private_key_pem" case serverCertificatePem = "server_certificate_pem" case clipboardPolicy = "clipboard_policy" case providerApplicationTerminationAllowed = "provider_application_termination_allowed" } public init(version: String, sessionId: String, gatewayId: String, reconnectSequence: Int64, expiresAt: String, providerProfile: String, providerIdentity: String, policyVersionId: String, streamPolicy: ProviderStreamPolicy, applicationId: String, clientId: String, managementHost: String, managementPort: Int64, streamHost: String, streamPort: Int64, clientCertificatePem: String, clientPrivateKeyPem: String, serverCertificatePem: String, clipboardPolicy: ClipboardPolicy, providerApplicationTerminationAllowed: Bool) throws { self.version = version self.sessionId = sessionId self.gatewayId = gatewayId self.reconnectSequence = reconnectSequence self.expiresAt = expiresAt self.providerProfile = providerProfile self.providerIdentity = providerIdentity self.policyVersionId = policyVersionId self.streamPolicy = streamPolicy self.applicationId = applicationId self.clientId = clientId self.managementHost = managementHost self.managementPort = managementPort self.streamHost = streamHost self.streamPort = streamPort self.clientCertificatePem = clientCertificatePem self.clientPrivateKeyPem = clientPrivateKeyPem self.serverCertificatePem = serverCertificatePem self.clipboardPolicy = clipboardPolicy self.providerApplicationTerminationAllowed = providerApplicationTerminationAllowed try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(version: try c.decode(String.self, forKey: .version), sessionId: try c.decode(String.self, forKey: .sessionId), gatewayId: try c.decode(String.self, forKey: .gatewayId), reconnectSequence: try c.decode(Int64.self, forKey: .reconnectSequence), expiresAt: try c.decode(String.self, forKey: .expiresAt), providerProfile: try c.decode(String.self, forKey: .providerProfile), providerIdentity: try c.decode(String.self, forKey: .providerIdentity), policyVersionId: try c.decode(String.self, forKey: .policyVersionId), streamPolicy: try c.decode(ProviderStreamPolicy.self, forKey: .streamPolicy), applicationId: try c.decode(String.self, forKey: .applicationId), clientId: try c.decode(String.self, forKey: .clientId), managementHost: try c.decode(String.self, forKey: .managementHost), managementPort: try c.decode(Int64.self, forKey: .managementPort), streamHost: try c.decode(String.self, forKey: .streamHost), streamPort: try c.decode(Int64.self, forKey: .streamPort), clientCertificatePem: try c.decode(String.self, forKey: .clientCertificatePem), clientPrivateKeyPem: try c.decode(String.self, forKey: .clientPrivateKeyPem), serverCertificatePem: try c.decode(String.self, forKey: .serverCertificatePem), clipboardPolicy: try c.decode(ClipboardPolicy.self, forKey: .clipboardPolicy), providerApplicationTerminationAllowed: try c.decode(Bool.self, forKey: .providerApplicationTerminationAllowed)) } public func validate() throws { if self.version != "1" { throw ContractValidationError(field: "version", code: "invalid_value") } if self.sessionId.isEmpty { throw ContractValidationError(field: "session_id", code: "required") } if !self.sessionId.isEmpty && self.sessionId.utf8.count < 1 { throw ContractValidationError(field: "session_id", code: "min_length") } if self.sessionId.utf8.count > 128 { throw ContractValidationError(field: "session_id", code: "max_length") } if self.gatewayId.isEmpty { throw ContractValidationError(field: "gateway_id", code: "required") } if !self.gatewayId.isEmpty && self.gatewayId.utf8.count < 1 { throw ContractValidationError(field: "gateway_id", code: "min_length") } if self.gatewayId.utf8.count > 128 { throw ContractValidationError(field: "gateway_id", code: "max_length") } if self.reconnectSequence < 0 { throw ContractValidationError(field: "reconnect_sequence", code: "minimum") } if self.expiresAt.utf8.count > 64 { throw ContractValidationError(field: "expires_at", code: "max_length") } if ISO8601DateFormatter().date(from: self.expiresAt) == nil { throw ContractValidationError(field: "expires_at", code: "invalid_time") } if self.providerProfile != "apollo" { throw ContractValidationError(field: "provider_profile", code: "invalid_value") } if self.providerIdentity.isEmpty { throw ContractValidationError(field: "provider_identity", code: "required") } if !self.providerIdentity.isEmpty && self.providerIdentity.utf8.count < 1 { throw ContractValidationError(field: "provider_identity", code: "min_length") } if self.providerIdentity.utf8.count > 256 { throw ContractValidationError(field: "provider_identity", code: "max_length") } if self.policyVersionId.isEmpty { throw ContractValidationError(field: "policy_version_id", code: "required") } if !self.policyVersionId.isEmpty && self.policyVersionId.utf8.count < 1 { throw ContractValidationError(field: "policy_version_id", code: "min_length") } if self.policyVersionId.utf8.count > 128 { throw ContractValidationError(field: "policy_version_id", code: "max_length") } try self.streamPolicy.validate() if self.applicationId.isEmpty { throw ContractValidationError(field: "application_id", code: "required") } if !self.applicationId.isEmpty && self.applicationId.utf8.count < 1 { throw ContractValidationError(field: "application_id", code: "min_length") } if self.applicationId.utf8.count > 128 { throw ContractValidationError(field: "application_id", code: "max_length") } if self.clientId.isEmpty { throw ContractValidationError(field: "client_id", code: "required") } if !self.clientId.isEmpty && self.clientId.utf8.count < 1 { throw ContractValidationError(field: "client_id", code: "min_length") } if self.clientId.utf8.count > 128 { throw ContractValidationError(field: "client_id", code: "max_length") } if self.managementHost.isEmpty { throw ContractValidationError(field: "management_host", code: "required") } if !self.managementHost.isEmpty && self.managementHost.utf8.count < 1 { throw ContractValidationError(field: "management_host", code: "min_length") } if self.managementHost.utf8.count > 256 { throw ContractValidationError(field: "management_host", code: "max_length") } if self.managementPort < 1 { throw ContractValidationError(field: "management_port", code: "minimum") } if self.managementPort > 65535 { throw ContractValidationError(field: "management_port", code: "maximum") } if self.streamHost.isEmpty { throw ContractValidationError(field: "stream_host", code: "required") } if !self.streamHost.isEmpty && self.streamHost.utf8.count < 1 { throw ContractValidationError(field: "stream_host", code: "min_length") } if self.streamHost.utf8.count > 256 { throw ContractValidationError(field: "stream_host", code: "max_length") } if self.streamPort < 1 { throw ContractValidationError(field: "stream_port", code: "minimum") } if self.streamPort > 65535 { throw ContractValidationError(field: "stream_port", code: "maximum") } if self.clientCertificatePem.isEmpty { throw ContractValidationError(field: "client_certificate_pem", code: "required") } if !self.clientCertificatePem.isEmpty && self.clientCertificatePem.utf8.count < 1 { throw ContractValidationError(field: "client_certificate_pem", code: "min_length") } if self.clientCertificatePem.utf8.count > 32768 { throw ContractValidationError(field: "client_certificate_pem", code: "max_length") } if self.clientPrivateKeyPem.isEmpty { throw ContractValidationError(field: "client_private_key_pem", code: "required") } if !self.clientPrivateKeyPem.isEmpty && self.clientPrivateKeyPem.utf8.count < 1 { throw ContractValidationError(field: "client_private_key_pem", code: "min_length") } if self.clientPrivateKeyPem.utf8.count > 32768 { throw ContractValidationError(field: "client_private_key_pem", code: "max_length") } if self.serverCertificatePem.isEmpty { throw ContractValidationError(field: "server_certificate_pem", code: "required") } if !self.serverCertificatePem.isEmpty && self.serverCertificatePem.utf8.count < 1 { throw ContractValidationError(field: "server_certificate_pem", code: "min_length") } if self.serverCertificatePem.utf8.count > 32768 { throw ContractValidationError(field: "server_certificate_pem", code: "max_length") } try self.clipboardPolicy.validate() } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ProviderState: Codable, Equatable { public let version: String public let sessionId: String public let state: String public let cleanupPending: Bool public let channels: [String] enum CodingKeys: String, CodingKey { case version = "version" case sessionId = "session_id" case state = "state" case cleanupPending = "cleanup_pending" case channels = "channels" } public init(version: String, sessionId: String, state: String, cleanupPending: Bool, channels: [String]) throws { self.version = version self.sessionId = sessionId self.state = state self.cleanupPending = cleanupPending self.channels = channels try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(version: try c.decode(String.self, forKey: .version), sessionId: try c.decode(String.self, forKey: .sessionId), state: try c.decode(String.self, forKey: .state), cleanupPending: try c.decode(Bool.self, forKey: .cleanupPending), channels: try c.decode([String].self, forKey: .channels)) } public func validate() throws { if self.version != "1" { throw ContractValidationError(field: "version", code: "invalid_value") } if self.sessionId.isEmpty { throw ContractValidationError(field: "session_id", code: "required") } if !self.sessionId.isEmpty && self.sessionId.utf8.count < 1 { throw ContractValidationError(field: "session_id", code: "min_length") } if self.sessionId.utf8.count > 128 { throw ContractValidationError(field: "session_id", code: "max_length") } if !["starting", "ready", "disconnected", "terminating", "terminated", "cleanup_pending", "failed"].contains(self.state) { throw ContractValidationError(field: "state", code: "invalid_value") } if self.channels.count > 8 { throw ContractValidationError(field: "channels", code: "max_items") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ProviderStreamPolicy: Codable, Equatable { public let resolutionWidth: Int64 public let resolutionHeight: Int64 public let fps: Int64 public let codec: String public let bitrateKbps: Int64 public let audioEnabled: Bool enum CodingKeys: String, CodingKey { case resolutionWidth = "resolution_width" case resolutionHeight = "resolution_height" case fps = "fps" case codec = "codec" case bitrateKbps = "bitrate_kbps" case audioEnabled = "audio_enabled" } public init(resolutionWidth: Int64, resolutionHeight: Int64, fps: Int64, codec: String, bitrateKbps: Int64, audioEnabled: Bool) throws { self.resolutionWidth = resolutionWidth self.resolutionHeight = resolutionHeight self.fps = fps self.codec = codec self.bitrateKbps = bitrateKbps self.audioEnabled = audioEnabled try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(resolutionWidth: try c.decode(Int64.self, forKey: .resolutionWidth), resolutionHeight: try c.decode(Int64.self, forKey: .resolutionHeight), fps: try c.decode(Int64.self, forKey: .fps), codec: try c.decode(String.self, forKey: .codec), bitrateKbps: try c.decode(Int64.self, forKey: .bitrateKbps), audioEnabled: try c.decode(Bool.self, forKey: .audioEnabled)) } public func validate() throws { if self.resolutionWidth < 320 { throw ContractValidationError(field: "resolution_width", code: "minimum") } if self.resolutionWidth > 16384 { throw ContractValidationError(field: "resolution_width", code: "maximum") } if self.resolutionHeight < 200 { throw ContractValidationError(field: "resolution_height", code: "minimum") } if self.resolutionHeight > 8640 { throw ContractValidationError(field: "resolution_height", code: "maximum") } if self.fps < 1 { throw ContractValidationError(field: "fps", code: "minimum") } if self.fps > 240 { throw ContractValidationError(field: "fps", code: "maximum") } if !["H264", "HEVC", "AV1"].contains(self.codec) { throw ContractValidationError(field: "codec", code: "invalid_value") } if self.bitrateKbps < 100 { throw ContractValidationError(field: "bitrate_kbps", code: "minimum") } if self.bitrateKbps > 1000000 { throw ContractValidationError(field: "bitrate_kbps", code: "maximum") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ReauthGrant: Codable, Equatable { public let token: String public let purpose: String public let expiresAt: String enum CodingKeys: String, CodingKey { case token = "token" case purpose = "purpose" case expiresAt = "expires_at" } public init(token: String, purpose: String, expiresAt: String) throws { self.token = token self.purpose = purpose self.expiresAt = expiresAt try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(token: try c.decode(String.self, forKey: .token), purpose: try c.decode(String.self, forKey: .purpose), expiresAt: try c.decode(String.self, forKey: .expiresAt)) } public func validate() throws { if self.token.isEmpty { throw ContractValidationError(field: "token", code: "required") } if !self.token.isEmpty && self.token.utf8.count < 1 { throw ContractValidationError(field: "token", code: "min_length") } if self.token.utf8.count > 256 { throw ContractValidationError(field: "token", code: "max_length") } if self.purpose.isEmpty { throw ContractValidationError(field: "purpose", code: "required") } if !self.purpose.isEmpty && self.purpose.utf8.count < 1 { throw ContractValidationError(field: "purpose", code: "min_length") } if self.purpose.utf8.count > 64 { throw ContractValidationError(field: "purpose", code: "max_length") } if self.expiresAt.utf8.count > 64 { throw ContractValidationError(field: "expires_at", code: "max_length") } if ISO8601DateFormatter().date(from: self.expiresAt) == nil { throw ContractValidationError(field: "expires_at", code: "invalid_time") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ReauthRequest: Codable, Equatable { public let password: String public let purpose: String enum CodingKeys: String, CodingKey { case password = "password" case purpose = "purpose" } public init(password: String, purpose: String) throws { self.password = password self.purpose = purpose try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(password: try c.decode(String.self, forKey: .password), purpose: try c.decode(String.self, forKey: .purpose)) } public func validate() throws { if self.password.isEmpty { throw ContractValidationError(field: "password", code: "required") } if !self.password.isEmpty && self.password.utf8.count < 1 { throw ContractValidationError(field: "password", code: "min_length") } if self.password.utf8.count > 1024 { throw ContractValidationError(field: "password", code: "max_length") } if !["identity_change", "key_change", "backup_enable", "external_database_tls_disabled", "assignment_change"].contains(self.purpose) { throw ContractValidationError(field: "purpose", code: "invalid_value") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ReconnectRequest: Codable, Equatable { public let clientDeviceId: String public let deviceKeyId: String public let expectedVersion: Int64 enum CodingKeys: String, CodingKey { case clientDeviceId = "client_device_id" case deviceKeyId = "device_key_id" case expectedVersion = "expected_version" } public init(clientDeviceId: String, deviceKeyId: String, expectedVersion: Int64) throws { self.clientDeviceId = clientDeviceId self.deviceKeyId = deviceKeyId self.expectedVersion = expectedVersion try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(clientDeviceId: try c.decode(String.self, forKey: .clientDeviceId), deviceKeyId: try c.decode(String.self, forKey: .deviceKeyId), expectedVersion: try c.decode(Int64.self, forKey: .expectedVersion)) } public func validate() throws { if self.clientDeviceId.isEmpty { throw ContractValidationError(field: "client_device_id", code: "required") } if !self.clientDeviceId.isEmpty && self.clientDeviceId.utf8.count < 1 { throw ContractValidationError(field: "client_device_id", code: "min_length") } if self.clientDeviceId.utf8.count > 128 { throw ContractValidationError(field: "client_device_id", code: "max_length") } if self.deviceKeyId.isEmpty { throw ContractValidationError(field: "device_key_id", code: "required") } if !self.deviceKeyId.isEmpty && self.deviceKeyId.utf8.count < 1 { throw ContractValidationError(field: "device_key_id", code: "min_length") } if self.deviceKeyId.utf8.count > 128 { throw ContractValidationError(field: "device_key_id", code: "max_length") } if self.expectedVersion < 1 { throw ContractValidationError(field: "expected_version", code: "minimum") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct RefreshRequest: Codable, Equatable { public let familyId: String public let refreshToken: String enum CodingKeys: String, CodingKey { case familyId = "family_id" case refreshToken = "refresh_token" } public init(familyId: String, refreshToken: String) throws { self.familyId = familyId self.refreshToken = refreshToken try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(familyId: try c.decode(String.self, forKey: .familyId), refreshToken: try c.decode(String.self, forKey: .refreshToken)) } public func validate() throws { if self.familyId.isEmpty { throw ContractValidationError(field: "family_id", code: "required") } if !self.familyId.isEmpty && self.familyId.utf8.count < 1 { throw ContractValidationError(field: "family_id", code: "min_length") } if self.familyId.utf8.count > 128 { throw ContractValidationError(field: "family_id", code: "max_length") } if self.refreshToken.isEmpty { throw ContractValidationError(field: "refresh_token", code: "required") } if !self.refreshToken.isEmpty && self.refreshToken.utf8.count < 1 { throw ContractValidationError(field: "refresh_token", code: "min_length") } if self.refreshToken.utf8.count > 256 { throw ContractValidationError(field: "refresh_token", code: "max_length") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct Resource: Codable, Equatable { public let id: String public let kind: String public let name: String public let state: String public let assignmentState: String? public let version: Int64 public let links: [ResourceLink] enum CodingKeys: String, CodingKey { case id = "id" case kind = "kind" case name = "name" case state = "state" case assignmentState = "assignment_state" case version = "version" case links = "links" } public init(id: String, kind: String, name: String, state: String, assignmentState: String?, version: Int64, links: [ResourceLink]) throws { self.id = id self.kind = kind self.name = name self.state = state self.assignmentState = assignmentState self.version = version self.links = links try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(id: try c.decode(String.self, forKey: .id), kind: try c.decode(String.self, forKey: .kind), name: try c.decode(String.self, forKey: .name), state: try c.decode(String.self, forKey: .state), assignmentState: try c.decodeIfPresent(String.self, forKey: .assignmentState), version: try c.decode(Int64.self, forKey: .version), links: try c.decode([ResourceLink].self, forKey: .links)) } public func validate() throws { if self.id.isEmpty { throw ContractValidationError(field: "id", code: "required") } if !self.id.isEmpty && self.id.utf8.count < 1 { throw ContractValidationError(field: "id", code: "min_length") } if self.id.utf8.count > 128 { throw ContractValidationError(field: "id", code: "max_length") } if self.kind.isEmpty { throw ContractValidationError(field: "kind", code: "required") } if !self.kind.isEmpty && self.kind.utf8.count < 1 { throw ContractValidationError(field: "kind", code: "min_length") } if self.kind.utf8.count > 64 { throw ContractValidationError(field: "kind", code: "max_length") } if self.name.isEmpty { throw ContractValidationError(field: "name", code: "required") } if !self.name.isEmpty && self.name.utf8.count < 1 { throw ContractValidationError(field: "name", code: "min_length") } if self.name.utf8.count > 256 { throw ContractValidationError(field: "name", code: "max_length") } if self.state.isEmpty { throw ContractValidationError(field: "state", code: "required") } if !self.state.isEmpty && self.state.utf8.count < 1 { throw ContractValidationError(field: "state", code: "min_length") } if self.state.utf8.count > 64 { throw ContractValidationError(field: "state", code: "max_length") } if let value = self.assignmentState { if value.utf8.count > 64 { throw ContractValidationError(field: "assignment_state", code: "max_length") } } if self.version < 1 { throw ContractValidationError(field: "version", code: "minimum") } if self.links.count > 16 { throw ContractValidationError(field: "links", code: "max_items") } for item in self.links { try item.validate() } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ResourceLink: Codable, Equatable { public let type: String public let id: String public let version: Int64 enum CodingKeys: String, CodingKey { case type = "type" case id = "id" case version = "version" } public init(type: String, id: String, version: Int64) throws { self.type = type self.id = id self.version = version try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(type: try c.decode(String.self, forKey: .type), id: try c.decode(String.self, forKey: .id), version: try c.decode(Int64.self, forKey: .version)) } public func validate() throws { if self.type.isEmpty { throw ContractValidationError(field: "type", code: "required") } if !self.type.isEmpty && self.type.utf8.count < 1 { throw ContractValidationError(field: "type", code: "min_length") } if self.type.utf8.count > 64 { throw ContractValidationError(field: "type", code: "max_length") } if self.id.isEmpty { throw ContractValidationError(field: "id", code: "required") } if !self.id.isEmpty && self.id.utf8.count < 1 { throw ContractValidationError(field: "id", code: "min_length") } if self.id.utf8.count > 128 { throw ContractValidationError(field: "id", code: "max_length") } if self.version < 1 { throw ContractValidationError(field: "version", code: "minimum") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct ResourceList: Codable, Equatable { public let assignedDesktops: [AssignedDesktop] public let entitledPools: [EntitledPool] public let page: PageInfo enum CodingKeys: String, CodingKey { case assignedDesktops = "assigned_desktops" case entitledPools = "entitled_pools" case page = "page" } public init(assignedDesktops: [AssignedDesktop], entitledPools: [EntitledPool], page: PageInfo) throws { self.assignedDesktops = assignedDesktops self.entitledPools = entitledPools self.page = page try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(assignedDesktops: try c.decode([AssignedDesktop].self, forKey: .assignedDesktops), entitledPools: try c.decode([EntitledPool].self, forKey: .entitledPools), page: try c.decode(PageInfo.self, forKey: .page)) } public func validate() throws { if self.assignedDesktops.count > 100 { throw ContractValidationError(field: "assigned_desktops", code: "max_items") } for item in self.assignedDesktops { try item.validate() } if self.entitledPools.count > 100 { throw ContractValidationError(field: "entitled_pools", code: "max_items") } for item in self.entitledPools { try item.validate() } try self.page.validate() } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct SessionAuthority: Codable, Equatable { public let version: String public let sessionId: String public let gatewayId: String public let audience: String public let reconnectSequence: Int64 public let expiresAt: String public let capabilities: CapabilityProfile public let providerProfile: String public let providerIdentity: String enum CodingKeys: String, CodingKey { case version = "version" case sessionId = "session_id" case gatewayId = "gateway_id" case audience = "audience" case reconnectSequence = "reconnect_sequence" case expiresAt = "expires_at" case capabilities = "capabilities" case providerProfile = "provider_profile" case providerIdentity = "provider_identity" } public init(version: String, sessionId: String, gatewayId: String, audience: String, reconnectSequence: Int64, expiresAt: String, capabilities: CapabilityProfile, providerProfile: String, providerIdentity: String) throws { self.version = version self.sessionId = sessionId self.gatewayId = gatewayId self.audience = audience self.reconnectSequence = reconnectSequence self.expiresAt = expiresAt self.capabilities = capabilities self.providerProfile = providerProfile self.providerIdentity = providerIdentity try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(version: try c.decode(String.self, forKey: .version), sessionId: try c.decode(String.self, forKey: .sessionId), gatewayId: try c.decode(String.self, forKey: .gatewayId), audience: try c.decode(String.self, forKey: .audience), reconnectSequence: try c.decode(Int64.self, forKey: .reconnectSequence), expiresAt: try c.decode(String.self, forKey: .expiresAt), capabilities: try c.decode(CapabilityProfile.self, forKey: .capabilities), providerProfile: try c.decode(String.self, forKey: .providerProfile), providerIdentity: try c.decode(String.self, forKey: .providerIdentity)) } public func validate() throws { if self.version != "1" { throw ContractValidationError(field: "version", code: "invalid_value") } if self.sessionId.isEmpty { throw ContractValidationError(field: "session_id", code: "required") } if !self.sessionId.isEmpty && self.sessionId.utf8.count < 1 { throw ContractValidationError(field: "session_id", code: "min_length") } if self.sessionId.utf8.count > 128 { throw ContractValidationError(field: "session_id", code: "max_length") } if self.gatewayId.isEmpty { throw ContractValidationError(field: "gateway_id", code: "required") } if !self.gatewayId.isEmpty && self.gatewayId.utf8.count < 1 { throw ContractValidationError(field: "gateway_id", code: "min_length") } if self.gatewayId.utf8.count > 128 { throw ContractValidationError(field: "gateway_id", code: "max_length") } if self.audience.isEmpty { throw ContractValidationError(field: "audience", code: "required") } if !self.audience.isEmpty && self.audience.utf8.count < 1 { throw ContractValidationError(field: "audience", code: "min_length") } if self.audience.utf8.count > 256 { throw ContractValidationError(field: "audience", code: "max_length") } if self.reconnectSequence < 0 { throw ContractValidationError(field: "reconnect_sequence", code: "minimum") } if self.expiresAt.utf8.count > 64 { throw ContractValidationError(field: "expires_at", code: "max_length") } if ISO8601DateFormatter().date(from: self.expiresAt) == nil { throw ContractValidationError(field: "expires_at", code: "invalid_time") } try self.capabilities.validate() if !["apollo"].contains(self.providerProfile) { throw ContractValidationError(field: "provider_profile", code: "invalid_value") } if self.providerIdentity.isEmpty { throw ContractValidationError(field: "provider_identity", code: "required") } if !self.providerIdentity.isEmpty && self.providerIdentity.utf8.count < 1 { throw ContractValidationError(field: "provider_identity", code: "min_length") } if self.providerIdentity.utf8.count > 256 { throw ContractValidationError(field: "provider_identity", code: "max_length") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct SessionRequest: Codable, Equatable { public let clientDeviceId: String public let deviceKeyId: String public let poolId: String public let idempotencyKey: String public let policySnapshot: AllocationPolicy enum CodingKeys: String, CodingKey { case clientDeviceId = "client_device_id" case deviceKeyId = "device_key_id" case poolId = "pool_id" case idempotencyKey = "idempotency_key" case policySnapshot = "policy_snapshot" } public init(clientDeviceId: String, deviceKeyId: String, poolId: String, idempotencyKey: String, policySnapshot: AllocationPolicy) throws { self.clientDeviceId = clientDeviceId self.deviceKeyId = deviceKeyId self.poolId = poolId self.idempotencyKey = idempotencyKey self.policySnapshot = policySnapshot try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(clientDeviceId: try c.decode(String.self, forKey: .clientDeviceId), deviceKeyId: try c.decode(String.self, forKey: .deviceKeyId), poolId: try c.decode(String.self, forKey: .poolId), idempotencyKey: try c.decode(String.self, forKey: .idempotencyKey), policySnapshot: try c.decode(AllocationPolicy.self, forKey: .policySnapshot)) } public func validate() throws { if self.clientDeviceId.isEmpty { throw ContractValidationError(field: "client_device_id", code: "required") } if !self.clientDeviceId.isEmpty && self.clientDeviceId.utf8.count < 1 { throw ContractValidationError(field: "client_device_id", code: "min_length") } if self.clientDeviceId.utf8.count > 128 { throw ContractValidationError(field: "client_device_id", code: "max_length") } if self.deviceKeyId.isEmpty { throw ContractValidationError(field: "device_key_id", code: "required") } if !self.deviceKeyId.isEmpty && self.deviceKeyId.utf8.count < 1 { throw ContractValidationError(field: "device_key_id", code: "min_length") } if self.deviceKeyId.utf8.count > 128 { throw ContractValidationError(field: "device_key_id", code: "max_length") } if self.poolId.isEmpty { throw ContractValidationError(field: "pool_id", code: "required") } if !self.poolId.isEmpty && self.poolId.utf8.count < 1 { throw ContractValidationError(field: "pool_id", code: "min_length") } if self.poolId.utf8.count > 128 { throw ContractValidationError(field: "pool_id", code: "max_length") } if self.idempotencyKey.isEmpty { throw ContractValidationError(field: "idempotency_key", code: "required") } if !self.idempotencyKey.isEmpty && self.idempotencyKey.utf8.count < 1 { throw ContractValidationError(field: "idempotency_key", code: "min_length") } if self.idempotencyKey.utf8.count > 256 { throw ContractValidationError(field: "idempotency_key", code: "max_length") } try self.policySnapshot.validate() } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct StableError: Codable, Equatable { public let version: String public let code: String public let message: String public let retryable: Bool enum CodingKeys: String, CodingKey { case version = "version" case code = "code" case message = "message" case retryable = "retryable" } public init(version: String, code: String, message: String, retryable: Bool) throws { self.version = version self.code = code self.message = message self.retryable = retryable try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(version: try c.decode(String.self, forKey: .version), code: try c.decode(String.self, forKey: .code), message: try c.decode(String.self, forKey: .message), retryable: try c.decode(Bool.self, forKey: .retryable)) } public func validate() throws { if self.version != "1" { throw ContractValidationError(field: "version", code: "invalid_value") } if self.code.isEmpty { throw ContractValidationError(field: "code", code: "required") } if !self.code.isEmpty && self.code.utf8.count < 1 { throw ContractValidationError(field: "code", code: "min_length") } if self.code.utf8.count > 128 { throw ContractValidationError(field: "code", code: "max_length") } if self.message.isEmpty { throw ContractValidationError(field: "message", code: "required") } if !self.message.isEmpty && self.message.utf8.count < 1 { throw ContractValidationError(field: "message", code: "min_length") } if self.message.utf8.count > 512 { throw ContractValidationError(field: "message", code: "max_length") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct TunnelAdmissionRequest: Codable, Equatable { public let version: String public let sessionId: String public let gatewayId: String public let audience: String public let grant: String public let reconnectSequence: Int64 public let clientNonce: String public let deviceSignature: String public let capabilities: CapabilityProfile enum CodingKeys: String, CodingKey { case version = "version" case sessionId = "session_id" case gatewayId = "gateway_id" case audience = "audience" case grant = "grant" case reconnectSequence = "reconnect_sequence" case clientNonce = "client_nonce" case deviceSignature = "device_signature" case capabilities = "capabilities" } public init(version: String, sessionId: String, gatewayId: String, audience: String, grant: String, reconnectSequence: Int64, clientNonce: String, deviceSignature: String, capabilities: CapabilityProfile) throws { self.version = version self.sessionId = sessionId self.gatewayId = gatewayId self.audience = audience self.grant = grant self.reconnectSequence = reconnectSequence self.clientNonce = clientNonce self.deviceSignature = deviceSignature self.capabilities = capabilities try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(version: try c.decode(String.self, forKey: .version), sessionId: try c.decode(String.self, forKey: .sessionId), gatewayId: try c.decode(String.self, forKey: .gatewayId), audience: try c.decode(String.self, forKey: .audience), grant: try c.decode(String.self, forKey: .grant), reconnectSequence: try c.decode(Int64.self, forKey: .reconnectSequence), clientNonce: try c.decode(String.self, forKey: .clientNonce), deviceSignature: try c.decode(String.self, forKey: .deviceSignature), capabilities: try c.decode(CapabilityProfile.self, forKey: .capabilities)) } public func validate() throws { if self.version != "1" { throw ContractValidationError(field: "version", code: "invalid_value") } if self.sessionId.isEmpty { throw ContractValidationError(field: "session_id", code: "required") } if !self.sessionId.isEmpty && self.sessionId.utf8.count < 1 { throw ContractValidationError(field: "session_id", code: "min_length") } if self.sessionId.utf8.count > 128 { throw ContractValidationError(field: "session_id", code: "max_length") } if self.gatewayId.isEmpty { throw ContractValidationError(field: "gateway_id", code: "required") } if !self.gatewayId.isEmpty && self.gatewayId.utf8.count < 1 { throw ContractValidationError(field: "gateway_id", code: "min_length") } if self.gatewayId.utf8.count > 128 { throw ContractValidationError(field: "gateway_id", code: "max_length") } if self.audience.isEmpty { throw ContractValidationError(field: "audience", code: "required") } if !self.audience.isEmpty && self.audience.utf8.count < 1 { throw ContractValidationError(field: "audience", code: "min_length") } if self.audience.utf8.count > 256 { throw ContractValidationError(field: "audience", code: "max_length") } if self.grant.isEmpty { throw ContractValidationError(field: "grant", code: "required") } if !self.grant.isEmpty && self.grant.utf8.count < 43 { throw ContractValidationError(field: "grant", code: "min_length") } if self.grant.utf8.count > 256 { throw ContractValidationError(field: "grant", code: "max_length") } if self.reconnectSequence < 0 { throw ContractValidationError(field: "reconnect_sequence", code: "minimum") } if self.clientNonce.isEmpty { throw ContractValidationError(field: "client_nonce", code: "required") } if !self.clientNonce.isEmpty && self.clientNonce.utf8.count < 16 { throw ContractValidationError(field: "client_nonce", code: "min_length") } if self.clientNonce.utf8.count > 128 { throw ContractValidationError(field: "client_nonce", code: "max_length") } if self.deviceSignature.isEmpty { throw ContractValidationError(field: "device_signature", code: "required") } if !self.deviceSignature.isEmpty && self.deviceSignature.utf8.count < 86 { throw ContractValidationError(field: "device_signature", code: "min_length") } if self.deviceSignature.utf8.count > 86 { throw ContractValidationError(field: "device_signature", code: "max_length") } try self.capabilities.validate() } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public struct VersionNegotiation: Codable, Equatable { public let supportedVersions: [String] public let features: [String] enum CodingKeys: String, CodingKey { case supportedVersions = "supported_versions" case features = "features" } public init(supportedVersions: [String], features: [String]) throws { self.supportedVersions = supportedVersions self.features = features try validate() } public init(from decoder: Decoder) throws { let all = try decoder.container(keyedBy: AnyCodingKey.self) for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") } let c = try decoder.container(keyedBy: CodingKeys.self) try self.init(supportedVersions: try c.decode([String].self, forKey: .supportedVersions), features: try c.decode([String].self, forKey: .features)) } public func validate() throws { if self.supportedVersions.count < 1 { throw ContractValidationError(field: "supported_versions", code: "min_items") } if self.supportedVersions.count > 3 { throw ContractValidationError(field: "supported_versions", code: "max_items") } if self.features.count > 64 { throw ContractValidationError(field: "features", code: "max_items") } } public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) } public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) } } public extension TunnelAdmissionRequest { func deviceAdmissionTranscript() -> Data { var fields = [sessionId, gatewayId, audience, grant, String(reconnectSequence), clientNonce, capabilities.transport, capabilities.framing, capabilities.media, capabilities.audio, capabilities.sourceRateControl, String(capabilities.clientDecode.count)] fields.append(contentsOf: capabilities.clientDecode) var transcript = "versevdi/tunnel-admission/v1" for field in fields { transcript += "\(field.utf8.count):\(field)" } return Data(transcript.utf8) } } public extension CapabilityProfile { static func intersection(_ profiles: [CapabilityProfile]) throws -> CapabilityProfile { guard let selected = profiles.first else { throw ContractValidationError(field: "capabilities", code: "no_overlap") } try selected.validate() var common = selected.clientDecode for profile in profiles.dropFirst() { try profile.validate() if profile.transport != selected.transport || profile.framing != selected.framing || profile.media != selected.media || profile.audio != selected.audio || profile.sourceRateControl != selected.sourceRateControl { throw ContractValidationError(field: "capabilities", code: "no_overlap") } common = common.filter { profile.clientDecode.contains($0) } if common.isEmpty { throw ContractValidationError(field: "capabilities", code: "no_overlap") } } return try CapabilityProfile(transport: selected.transport, framing: selected.framing, media: selected.media, audio: selected.audio, sourceRateControl: selected.sourceRateControl, clientDecode: common) } }