mirror of
https://github.com/LukeHagar/plexswift.git
synced 2025-12-06 04:20:52 +00:00
ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.213.0
This commit is contained in:
@@ -3,14 +3,15 @@ id: 5d77204e-e413-4fd0-a14a-bad3aee2247a
|
||||
management:
|
||||
docChecksum: e34dac84738ebf2d447ea2b9055a6eeb
|
||||
docVersion: 0.0.3
|
||||
speakeasyVersion: 1.210.0
|
||||
generationVersion: 2.281.2
|
||||
releaseVersion: 0.0.1
|
||||
configChecksum: b1ec644cb39ebdb23044adf16e6d5e0f
|
||||
speakeasyVersion: 1.213.0
|
||||
generationVersion: 2.283.1
|
||||
releaseVersion: 0.0.2
|
||||
configChecksum: 9eb228df4cab70cbab8695a6a5458559
|
||||
repoURL: https://github.com/LukeHagar/plexswift.git
|
||||
features:
|
||||
swift:
|
||||
core: 3.2.2
|
||||
globalSecurity: 2.81.4
|
||||
globalSecurity: 2.81.5
|
||||
globalServerURLs: 2.82.1
|
||||
methodServerURLs: 3.0.1
|
||||
nameOverrides: 2.81.1
|
||||
|
||||
@@ -12,7 +12,7 @@ generation:
|
||||
auth:
|
||||
oAuth2ClientCredentialsEnabled: true
|
||||
swift:
|
||||
version: 0.0.1
|
||||
version: 0.0.2
|
||||
author: LukeHagar
|
||||
description: Swift Client SDK Generated by Speakeasy
|
||||
imports:
|
||||
|
||||
@@ -27,7 +27,13 @@ It has been generated successfully based on your OpenAPI spec. However, it is no
|
||||
|
||||
### Swift Package Manager
|
||||
|
||||
You can add `plexswift` to your project directly in Xcode `(File > Add Packages...)` or by adding it to your project's Package.swift file.
|
||||
You can add `plexswift` to your project directly in Xcode `(File > Add Packages...)` or by adding it to your project's Package.swift file:
|
||||
|
||||
```bash
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/LukeHagar/plexswift.git", .upToNextMajor(from: "0.0.2"))
|
||||
]
|
||||
```
|
||||
<!-- End SDK Installation [installation] -->
|
||||
|
||||
<!-- Start SDK Example Usage [usage] -->
|
||||
|
||||
9
RELEASES.md
Normal file
9
RELEASES.md
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
|
||||
## 2024-03-20 00:53:07
|
||||
### Changes
|
||||
Based on:
|
||||
- OpenAPI Doc
|
||||
- Speakeasy CLI 1.213.0 (2.283.1) https://github.com/speakeasy-api/speakeasy
|
||||
### Generated
|
||||
- [swift v0.0.2] .
|
||||
220
Sources/plexswift/AnyValue.swift
Normal file
220
Sources/plexswift/AnyValue.swift
Normal file
@@ -0,0 +1,220 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
|
||||
/// A type that describes any value that can be used in a request or response object.
|
||||
public protocol APIValue {}
|
||||
|
||||
extension NSNull: APIValue {}
|
||||
extension String: APIValue {}
|
||||
extension Int: APIValue {}
|
||||
extension Double: APIValue {}
|
||||
extension Bool: APIValue {}
|
||||
extension Optional: APIValue where Wrapped: APIValue {}
|
||||
extension Array: APIValue where Element: APIValue {}
|
||||
extension Dictionary: APIValue where Key == String, Value: APIValue {}
|
||||
|
||||
enum APIValueConversionError: Error {
|
||||
case invalidType
|
||||
}
|
||||
|
||||
/// A type-erased wrapper for passing around ``APIValue`` values.
|
||||
public struct AnyValue: Codable {
|
||||
// This is a type-erased wrapper which allows us to store Serializable values in collections, as well as handle
|
||||
// JSON encoding and decoding.
|
||||
|
||||
private var _serialize: (_ format: SerializableFormat) throws -> String
|
||||
private var _serializeQueryParameters: (_ format: SerializableFormat) throws -> [QueryParameter]
|
||||
private var _description: () -> String
|
||||
private var _serializable: () -> any Serializable
|
||||
|
||||
init(serializable: Serializable) {
|
||||
_serialize = { format in try serializable.serialize(with: format) }
|
||||
_serializeQueryParameters = { format in try serializable.serializeQueryParameters(with: format) }
|
||||
_serializable = { return serializable }
|
||||
_description = {
|
||||
if let serializable = serializable as? CustomStringConvertible {
|
||||
return serializable.description
|
||||
} else {
|
||||
return String(describing: serializable)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates an object from an `NSNull` value
|
||||
public init(_ null: NSNull) {
|
||||
self.init(serializable: null)
|
||||
}
|
||||
|
||||
/// Creates an object from a string value
|
||||
public init(_ string: String) {
|
||||
self.init(serializable: string)
|
||||
}
|
||||
|
||||
/// Creates an object from an integer value
|
||||
public init(_ int: Int) {
|
||||
self.init(serializable: int)
|
||||
}
|
||||
|
||||
/// Creates an object from a double value
|
||||
public init(_ double: Double) {
|
||||
self.init(serializable: double)
|
||||
}
|
||||
|
||||
/// Creates an object from a boolean value
|
||||
public init(_ bool: Bool) {
|
||||
self.init(serializable: bool)
|
||||
}
|
||||
|
||||
/// Creates an object from any ``APIValue`` value
|
||||
public init(_ value: APIValue) throws {
|
||||
guard let serializable = value as? Serializable else {
|
||||
throw APIValueConversionError.invalidType
|
||||
}
|
||||
self.init(serializable: serializable)
|
||||
}
|
||||
|
||||
/// Creates an object from an optional value
|
||||
public init<T: APIValue>(_ optional: Optional<T>) throws {
|
||||
guard let serializable = optional as? Serializable else {
|
||||
throw APIValueConversionError.invalidType
|
||||
}
|
||||
self.init(serializable: serializable)
|
||||
}
|
||||
|
||||
/// Creates an object from an array value
|
||||
public init<T: APIValue>(_ array: Array<T>) throws {
|
||||
guard let serializable = array as? Serializable else {
|
||||
throw APIValueConversionError.invalidType
|
||||
}
|
||||
self.init(serializable: serializable)
|
||||
}
|
||||
|
||||
/// Creates an object from a dictionary value
|
||||
public init<T: APIValue>(_ dictionary: Dictionary<String, T>) throws {
|
||||
guard let serializable = dictionary as? Serializable else {
|
||||
throw APIValueConversionError.invalidType
|
||||
}
|
||||
self.init(serializable: serializable)
|
||||
}
|
||||
|
||||
// MARK: - Codable
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
|
||||
if container.decodeNil() {
|
||||
self.init(serializable: NSNull())
|
||||
} else if let boolValue = try? container.decode(Bool.self) {
|
||||
self.init(serializable: boolValue)
|
||||
} else if let intValue = try? container.decode(Int.self) {
|
||||
self.init(serializable: intValue)
|
||||
} else if let doubleValue = try? container.decode(Double.self) {
|
||||
self.init(serializable: doubleValue)
|
||||
} else if let stringValue = try? container.decode(String.self) {
|
||||
self.init(serializable: stringValue)
|
||||
} else if let arrayValue = try? container.decode([AnyValue].self) {
|
||||
self.init(serializable: arrayValue)
|
||||
} else if let dictionaryValue = try? container.decode([String: AnyValue].self) {
|
||||
self.init(serializable: dictionaryValue)
|
||||
} else {
|
||||
throw DecodingError.dataCorruptedError(
|
||||
in: container,
|
||||
debugDescription: "Unsupported value in container. Is this valid JSON?"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.singleValueContainer()
|
||||
let value = _serializable()
|
||||
|
||||
if value is NSNull {
|
||||
try container.encodeNil()
|
||||
} else if let boolValue = value as? Bool {
|
||||
try container.encode(boolValue)
|
||||
} else if let intValue = value as? Int {
|
||||
try container.encode(intValue)
|
||||
} else if let doubleValue = value as? Double {
|
||||
try container.encode(doubleValue)
|
||||
} else if let stringValue = value as? String {
|
||||
try container.encode(stringValue)
|
||||
} else if let arrayValue = value as? [AnyValue] {
|
||||
try container.encode(arrayValue)
|
||||
} else if let dictionaryValue = value as? [String: AnyValue] {
|
||||
try container.encode(dictionaryValue)
|
||||
} else if let encodableValue = value as? Encodable {
|
||||
try container.encode(encodableValue)
|
||||
} else {
|
||||
let context = EncodingError.Context(codingPath: container.codingPath, debugDescription: "Cannot encode value")
|
||||
throw EncodingError.invalidValue(value, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Serializable
|
||||
|
||||
extension AnyValue: Serializable {
|
||||
func serialize(with format: SerializableFormat) throws -> String {
|
||||
return try _serialize(format)
|
||||
}
|
||||
|
||||
func serializeQueryParameters(with format: SerializableFormat) throws -> [QueryParameter] {
|
||||
return try _serializeQueryParameters(format)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
extension AnyValue {
|
||||
subscript(key: String) -> AnyValue? {
|
||||
if let serializable = _serializable() as? [String: Serializable], let value = serializable[key] {
|
||||
return AnyValue(serializable: value)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func `as`<T>(type: T.Type) -> T? {
|
||||
return _serializable() as? T
|
||||
}
|
||||
|
||||
func asArray<T>(elementType: T.Type) -> [T]? {
|
||||
guard let array = _serializable() as? [AnyValue] else { return nil }
|
||||
var result: [T] = []
|
||||
for element in array {
|
||||
guard let element = element.as(type: T.self) else { return nil }
|
||||
result.append(element)
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Equatable
|
||||
|
||||
extension AnyValue: Equatable {
|
||||
public static func == (lhs: AnyValue, rhs: AnyValue) -> Bool {
|
||||
let lhsValue = lhs._serializable()
|
||||
let rhsValue = rhs._serializable()
|
||||
|
||||
switch (lhsValue, rhsValue) {
|
||||
case is (NSNull, NSNull): return true
|
||||
case let (lhsValue as Bool, rhsValue as Bool): return lhsValue == rhsValue
|
||||
case let (lhsValue as Int, rhsValue as Int): return lhsValue == rhsValue
|
||||
case let (lhsValue as Double, rhsValue as Double): return lhsValue == rhsValue
|
||||
case let (lhsValue as String, rhsValue as String): return lhsValue == rhsValue
|
||||
case let (lhsValue as [AnyValue], rhsValue as [AnyValue]): return lhsValue == rhsValue
|
||||
case let (lhsValue as [String: AnyValue], rhsValue as [String: AnyValue]): return lhsValue == rhsValue
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - CustomStringConvertible
|
||||
|
||||
extension AnyValue: CustomStringConvertible {
|
||||
public var description: String {
|
||||
return _description()
|
||||
}
|
||||
}
|
||||
980
Sources/plexswift/PlexswiftAPI.swift
Normal file
980
Sources/plexswift/PlexswiftAPI.swift
Normal file
@@ -0,0 +1,980 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Defines the operations supported by the API.
|
||||
///
|
||||
/// This protocol defines all of the operations supported by the API. It is implemented by ``Client`` which can be used to make these API requests and handle their responses.
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### API calls
|
||||
///
|
||||
/// These methods allow you to make requests to the API.
|
||||
///
|
||||
///
|
||||
/// ### Scoped API calls
|
||||
///
|
||||
/// These properties logically group other parts of the API.
|
||||
///
|
||||
/// - ``server``
|
||||
/// - ``media``
|
||||
/// - ``video``
|
||||
/// - ``activities``
|
||||
/// - ``butler``
|
||||
/// - ``hubs``
|
||||
/// - ``search``
|
||||
/// - ``library``
|
||||
/// - ``log``
|
||||
/// - ``plex``
|
||||
/// - ``playlists``
|
||||
/// - ``authentication``
|
||||
/// - ``statistics``
|
||||
/// - ``sessions``
|
||||
/// - ``updater``
|
||||
///
|
||||
public protocol PlexswiftAPI {
|
||||
|
||||
// MARK: - Scoped APIs
|
||||
/// Operations against the Plex Media Server System.
|
||||
///
|
||||
var server: ServerAPI { get }
|
||||
/// API Calls interacting with Plex Media Server Media
|
||||
///
|
||||
var media: MediaAPI { get }
|
||||
/// API Calls that perform operations with Plex Media Server Videos
|
||||
///
|
||||
var video: VideoAPI { get }
|
||||
/// Activities are awesome. They provide a way to monitor and control asynchronous operations on the server. In order to receive real-time updates for activities, a client would normally subscribe via either EventSource or Websocket endpoints.
|
||||
/// Activities are associated with HTTP replies via a special `X-Plex-Activity` header which contains the UUID of the activity.
|
||||
/// Activities are optional cancellable. If cancellable, they may be cancelled via the `DELETE` endpoint. Other details:
|
||||
/// - They can contain a `progress` (from 0 to 100) marking the percent completion of the activity.
|
||||
/// - They must contain an `type` which is used by clients to distinguish the specific activity.
|
||||
/// - They may contain a `Context` object with attributes which associate the activity with various specific entities (items, libraries, etc.)
|
||||
/// - The may contain a `Response` object which attributes which represent the result of the asynchronous operation.
|
||||
///
|
||||
var activities: ActivitiesAPI { get }
|
||||
/// Butler is the task manager of the Plex Media Server Ecosystem.
|
||||
///
|
||||
var butler: ButlerAPI { get }
|
||||
/// Hubs are a structured two-dimensional container for media, generally represented by multiple horizontal rows.
|
||||
///
|
||||
var hubs: HubsAPI { get }
|
||||
/// API Calls that perform search operations with Plex Media Server
|
||||
///
|
||||
var search: SearchAPI { get }
|
||||
/// API Calls interacting with Plex Media Server Libraries
|
||||
///
|
||||
var library: LibraryAPI { get }
|
||||
/// Submit logs to the Log Handler for Plex Media Server
|
||||
///
|
||||
var log: LogAPI { get }
|
||||
/// API Calls that perform operations directly against https://Plex.tv
|
||||
///
|
||||
var plex: PlexAPI { get }
|
||||
/// Playlists are ordered collections of media. They can be dumb (just a list of media) or smart (based on a media query, such as "all albums from 2017").
|
||||
/// They can be organized in (optionally nesting) folders.
|
||||
/// Retrieving a playlist, or its items, will trigger a refresh of its metadata.
|
||||
/// This may cause the duration and number of items to change.
|
||||
///
|
||||
var playlists: PlaylistsAPI { get }
|
||||
/// API Calls regarding authentication for Plex Media Server
|
||||
///
|
||||
var authentication: AuthenticationAPI { get }
|
||||
/// API Calls that perform operations with Plex Media Server Statistics
|
||||
///
|
||||
var statistics: StatisticsAPI { get }
|
||||
/// API Calls that perform search operations with Plex Media Server Sessions
|
||||
///
|
||||
var sessions: SessionsAPI { get }
|
||||
/// This describes the API for searching and applying updates to the Plex Media Server.
|
||||
/// Updates to the status can be observed via the Event API.
|
||||
///
|
||||
var updater: UpdaterAPI { get }
|
||||
}
|
||||
|
||||
// MARK: - ServerAPI
|
||||
|
||||
/// Operations against the Plex Media Server System.
|
||||
///
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### API calls
|
||||
///
|
||||
/// - ``getServerCapabilities()``
|
||||
/// - ``getServerPreferences()``
|
||||
/// - ``getAvailableClients()``
|
||||
/// - ``getDevices()``
|
||||
/// - ``getServerIdentity()``
|
||||
/// - ``getMyPlexAccount()``
|
||||
/// - ``getResizedPhoto(request:)``
|
||||
/// - ``getServerList()``
|
||||
///
|
||||
public protocol ServerAPI {
|
||||
/// Server Capabilities
|
||||
///
|
||||
/// - Returns: A ``Operations/GetServerCapabilitiesResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getServerCapabilities() async throws -> Response<Operations.GetServerCapabilitiesResponse>
|
||||
|
||||
/// Get Server Preferences
|
||||
///
|
||||
/// - Returns: A ``Operations/GetServerPreferencesResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getServerPreferences() async throws -> Response<Operations.GetServerPreferencesResponse>
|
||||
|
||||
/// Get Available Clients
|
||||
///
|
||||
/// - Returns: A ``Operations/GetAvailableClientsResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getAvailableClients() async throws -> Response<Operations.GetAvailableClientsResponse>
|
||||
|
||||
/// Get Devices
|
||||
///
|
||||
/// - Returns: A ``Operations/GetDevicesResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getDevices() async throws -> Response<Operations.GetDevicesResponse>
|
||||
|
||||
/// Get Server Identity
|
||||
///
|
||||
/// - Returns: A ``Operations/GetServerIdentityResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getServerIdentity() async throws -> Response<Operations.GetServerIdentityResponse>
|
||||
|
||||
/// Returns MyPlex Account Information
|
||||
///
|
||||
/// - Returns: A ``Operations/GetMyPlexAccountResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getMyPlexAccount() async throws -> Response<Operations.GetMyPlexAccountResponse>
|
||||
|
||||
/// Plex's Photo transcoder is used throughout the service to serve images at specified sizes.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetResizedPhotoRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/GetResizedPhotoResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getResizedPhoto(request: Operations.GetResizedPhotoRequest) async throws -> Response<Operations.GetResizedPhotoResponse>
|
||||
|
||||
/// Get Server List
|
||||
///
|
||||
/// - Returns: A ``Operations/GetServerListResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getServerList() async throws -> Response<Operations.GetServerListResponse>
|
||||
}
|
||||
|
||||
// MARK: - MediaAPI
|
||||
|
||||
/// API Calls interacting with Plex Media Server Media
|
||||
///
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### API calls
|
||||
///
|
||||
/// - ``markPlayed(request:)``
|
||||
/// - ``markUnplayed(request:)``
|
||||
/// - ``updatePlayProgress(request:)``
|
||||
///
|
||||
public protocol MediaAPI {
|
||||
/// This will mark the provided media key as Played.
|
||||
///
|
||||
/// - Parameter request: A ``Operations/MarkPlayedRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/MarkPlayedResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func markPlayed(request: Operations.MarkPlayedRequest) async throws -> Response<Operations.MarkPlayedResponse>
|
||||
|
||||
/// This will mark the provided media key as Unplayed.
|
||||
///
|
||||
/// - Parameter request: A ``Operations/MarkUnplayedRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/MarkUnplayedResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func markUnplayed(request: Operations.MarkUnplayedRequest) async throws -> Response<Operations.MarkUnplayedResponse>
|
||||
|
||||
/// This API command can be used to update the play progress of a media item.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/UpdatePlayProgressRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/UpdatePlayProgressResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func updatePlayProgress(request: Operations.UpdatePlayProgressRequest) async throws -> Response<Operations.UpdatePlayProgressResponse>
|
||||
}
|
||||
|
||||
// MARK: - VideoAPI
|
||||
|
||||
/// API Calls that perform operations with Plex Media Server Videos
|
||||
///
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### API calls
|
||||
///
|
||||
/// - ``getTimeline(request:)``
|
||||
/// - ``startUniversalTranscode(request:)``
|
||||
///
|
||||
public protocol VideoAPI {
|
||||
/// Get the timeline for a media item
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetTimelineRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/GetTimelineResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getTimeline(request: Operations.GetTimelineRequest) async throws -> Response<Operations.GetTimelineResponse>
|
||||
|
||||
/// Begin a Universal Transcode Session
|
||||
///
|
||||
/// - Parameter request: A ``Operations/StartUniversalTranscodeRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/StartUniversalTranscodeResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func startUniversalTranscode(request: Operations.StartUniversalTranscodeRequest) async throws -> Response<Operations.StartUniversalTranscodeResponse>
|
||||
}
|
||||
|
||||
// MARK: - ActivitiesAPI
|
||||
|
||||
/// Activities are awesome. They provide a way to monitor and control asynchronous operations on the server. In order to receive real-time updates for activities, a client would normally subscribe via either EventSource or Websocket endpoints.
|
||||
/// Activities are associated with HTTP replies via a special `X-Plex-Activity` header which contains the UUID of the activity.
|
||||
/// Activities are optional cancellable. If cancellable, they may be cancelled via the `DELETE` endpoint. Other details:
|
||||
/// - They can contain a `progress` (from 0 to 100) marking the percent completion of the activity.
|
||||
/// - They must contain an `type` which is used by clients to distinguish the specific activity.
|
||||
/// - They may contain a `Context` object with attributes which associate the activity with various specific entities (items, libraries, etc.)
|
||||
/// - The may contain a `Response` object which attributes which represent the result of the asynchronous operation.
|
||||
///
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### API calls
|
||||
///
|
||||
/// - ``getServerActivities()``
|
||||
/// - ``cancelServerActivities(request:)``
|
||||
///
|
||||
public protocol ActivitiesAPI {
|
||||
/// Get Server Activities
|
||||
///
|
||||
/// - Returns: A ``Operations/GetServerActivitiesResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getServerActivities() async throws -> Response<Operations.GetServerActivitiesResponse>
|
||||
|
||||
/// Cancel Server Activities
|
||||
///
|
||||
/// - Parameter request: A ``Operations/CancelServerActivitiesRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/CancelServerActivitiesResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func cancelServerActivities(request: Operations.CancelServerActivitiesRequest) async throws -> Response<Operations.CancelServerActivitiesResponse>
|
||||
}
|
||||
|
||||
// MARK: - ButlerAPI
|
||||
|
||||
/// Butler is the task manager of the Plex Media Server Ecosystem.
|
||||
///
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### API calls
|
||||
///
|
||||
/// - ``getButlerTasks()``
|
||||
/// - ``startAllTasks()``
|
||||
/// - ``stopAllTasks()``
|
||||
/// - ``startTask(request:)``
|
||||
/// - ``stopTask(request:)``
|
||||
///
|
||||
public protocol ButlerAPI {
|
||||
/// Returns a list of butler tasks
|
||||
///
|
||||
/// - Returns: A ``Operations/GetButlerTasksResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getButlerTasks() async throws -> Response<Operations.GetButlerTasksResponse>
|
||||
|
||||
/// This endpoint will attempt to start all Butler tasks that are enabled in the settings. Butler tasks normally run automatically during a time window configured on the server's Settings page but can be manually started using this endpoint. Tasks will run with the following criteria:
|
||||
/// 1. Any tasks not scheduled to run on the current day will be skipped.
|
||||
/// 2. If a task is configured to run at a random time during the configured window and we are outside that window, the task will start immediately.
|
||||
/// 3. If a task is configured to run at a random time during the configured window and we are within that window, the task will be scheduled at a random time within the window.
|
||||
/// 4. If we are outside the configured window, the task will start immediately.
|
||||
///
|
||||
///
|
||||
/// - Returns: A ``Operations/StartAllTasksResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func startAllTasks() async throws -> Response<Operations.StartAllTasksResponse>
|
||||
|
||||
/// This endpoint will stop all currently running tasks and remove any scheduled tasks from the queue.
|
||||
///
|
||||
///
|
||||
/// - Returns: A ``Operations/StopAllTasksResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func stopAllTasks() async throws -> Response<Operations.StopAllTasksResponse>
|
||||
|
||||
/// This endpoint will attempt to start a single Butler task that is enabled in the settings. Butler tasks normally run automatically during a time window configured on the server's Settings page but can be manually started using this endpoint. Tasks will run with the following criteria:
|
||||
/// 1. Any tasks not scheduled to run on the current day will be skipped.
|
||||
/// 2. If a task is configured to run at a random time during the configured window and we are outside that window, the task will start immediately.
|
||||
/// 3. If a task is configured to run at a random time during the configured window and we are within that window, the task will be scheduled at a random time within the window.
|
||||
/// 4. If we are outside the configured window, the task will start immediately.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/StartTaskRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/StartTaskResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func startTask(request: Operations.StartTaskRequest) async throws -> Response<Operations.StartTaskResponse>
|
||||
|
||||
/// This endpoint will stop a currently running task by name, or remove it from the list of scheduled tasks if it exists. See the section above for a list of task names for this endpoint.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/StopTaskRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/StopTaskResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func stopTask(request: Operations.StopTaskRequest) async throws -> Response<Operations.StopTaskResponse>
|
||||
}
|
||||
|
||||
// MARK: - HubsAPI
|
||||
|
||||
/// Hubs are a structured two-dimensional container for media, generally represented by multiple horizontal rows.
|
||||
///
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### API calls
|
||||
///
|
||||
/// - ``getGlobalHubs(request:)``
|
||||
/// - ``getLibraryHubs(request:)``
|
||||
///
|
||||
public protocol HubsAPI {
|
||||
/// Get Global Hubs filtered by the parameters provided.
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetGlobalHubsRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/GetGlobalHubsResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getGlobalHubs(request: Operations.GetGlobalHubsRequest) async throws -> Response<Operations.GetGlobalHubsResponse>
|
||||
|
||||
/// This endpoint will return a list of library specific hubs
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetLibraryHubsRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/GetLibraryHubsResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getLibraryHubs(request: Operations.GetLibraryHubsRequest) async throws -> Response<Operations.GetLibraryHubsResponse>
|
||||
}
|
||||
|
||||
// MARK: - SearchAPI
|
||||
|
||||
/// API Calls that perform search operations with Plex Media Server
|
||||
///
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### API calls
|
||||
///
|
||||
/// - ``performSearch(request:)``
|
||||
/// - ``performVoiceSearch(request:)``
|
||||
/// - ``getSearchResults(request:)``
|
||||
///
|
||||
public protocol SearchAPI {
|
||||
/// This endpoint performs a search across all library sections, or a single section, and returns matches as hubs, split up by type. It performs spell checking, looks for partial matches, and orders the hubs based on quality of results. In addition, based on matches, it will return other related matches (e.g. for a genre match, it may return movies in that genre, or for an actor match, movies with that actor).
|
||||
///
|
||||
/// In the response's items, the following extra attributes are returned to further describe or disambiguate the result:
|
||||
///
|
||||
/// - `reason`: The reason for the result, if not because of a direct search term match; can be either:
|
||||
/// - `section`: There are multiple identical results from different sections.
|
||||
/// - `originalTitle`: There was a search term match from the original title field (sometimes those can be very different or in a foreign language).
|
||||
/// - `<hub identifier>`: If the reason for the result is due to a result in another hub, the source hub identifier is returned. For example, if the search is for "dylan" then Bob Dylan may be returned as an artist result, an a few of his albums returned as album results with a reason code of `artist` (the identifier of that particular hub). Or if the search is for "arnold", there might be movie results returned with a reason of `actor`
|
||||
/// - `reasonTitle`: The string associated with the reason code. For a section reason, it'll be the section name; For a hub identifier, it'll be a string associated with the match (e.g. `Arnold Schwarzenegger` for movies which were returned because the search was for "arnold").
|
||||
/// - `reasonID`: The ID of the item associated with the reason for the result. This might be a section ID, a tag ID, an artist ID, or a show ID.
|
||||
///
|
||||
/// This request is intended to be very fast, and called as the user types.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/PerformSearchRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/PerformSearchResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func performSearch(request: Operations.PerformSearchRequest) async throws -> Response<Operations.PerformSearchResponse>
|
||||
|
||||
/// This endpoint performs a search specifically tailored towards voice or other imprecise input which may work badly with the substring and spell-checking heuristics used by the `/hubs/search` endpoint.
|
||||
/// It uses a [Levenshtein distance](https://en.wikipedia.org/wiki/Levenshtein_distance) heuristic to search titles, and as such is much slower than the other search endpoint.
|
||||
/// Whenever possible, clients should limit the search to the appropriate type.
|
||||
/// Results, as well as their containing per-type hubs, contain a `distance` attribute which can be used to judge result quality.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/PerformVoiceSearchRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/PerformVoiceSearchResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func performVoiceSearch(request: Operations.PerformVoiceSearchRequest) async throws -> Response<Operations.PerformVoiceSearchResponse>
|
||||
|
||||
/// This will search the database for the string provided.
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetSearchResultsRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/GetSearchResultsResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getSearchResults(request: Operations.GetSearchResultsRequest) async throws -> Response<Operations.GetSearchResultsResponse>
|
||||
}
|
||||
|
||||
// MARK: - LibraryAPI
|
||||
|
||||
/// API Calls interacting with Plex Media Server Libraries
|
||||
///
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### API calls
|
||||
///
|
||||
/// - ``getFileHash(request:)``
|
||||
/// - ``getRecentlyAdded()``
|
||||
/// - ``getLibraries()``
|
||||
/// - ``getLibrary(request:)``
|
||||
/// - ``deleteLibrary(request:)``
|
||||
/// - ``getLibraryItems(request:)``
|
||||
/// - ``refreshLibrary(request:)``
|
||||
/// - ``searchLibrary(request:)``
|
||||
/// - ``getMetadata(request:)``
|
||||
/// - ``getMetadataChildren(request:)``
|
||||
/// - ``getOnDeck()``
|
||||
///
|
||||
public protocol LibraryAPI {
|
||||
/// This resource returns hash values for local files
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetFileHashRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/GetFileHashResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getFileHash(request: Operations.GetFileHashRequest) async throws -> Response<Operations.GetFileHashResponse>
|
||||
|
||||
/// This endpoint will return the recently added content.
|
||||
///
|
||||
///
|
||||
/// - Returns: A ``Operations/GetRecentlyAddedResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getRecentlyAdded() async throws -> Response<Operations.GetRecentlyAddedResponse>
|
||||
|
||||
/// A library section (commonly referred to as just a library) is a collection of media.
|
||||
/// Libraries are typed, and depending on their type provide either a flat or a hierarchical view of the media.
|
||||
/// For example, a music library has an artist > albums > tracks structure, whereas a movie library is flat.
|
||||
///
|
||||
/// Libraries have features beyond just being a collection of media; for starters, they include information about supported types, filters and sorts.
|
||||
/// This allows a client to provide a rich interface around the media (e.g. allow sorting movies by release year).
|
||||
///
|
||||
///
|
||||
/// - Returns: A ``Operations/GetLibrariesResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getLibraries() async throws -> Response<Operations.GetLibrariesResponse>
|
||||
|
||||
/// ## Library Details Endpoint
|
||||
///
|
||||
/// This endpoint provides comprehensive details about the library, focusing on organizational aspects rather than the content itself.
|
||||
///
|
||||
/// The details include:
|
||||
///
|
||||
/// ### Directories
|
||||
/// Organized into three categories:
|
||||
///
|
||||
/// - **Primary Directories**:
|
||||
/// - Used in some clients for quick access to media subsets (e.g., "All", "On Deck").
|
||||
/// - Most can be replicated via media queries.
|
||||
/// - Customizable by users.
|
||||
///
|
||||
/// - **Secondary Directories**:
|
||||
/// - Marked with `secondary="1"`.
|
||||
/// - Used in older clients for structured navigation.
|
||||
///
|
||||
/// - **Special Directories**:
|
||||
/// - Includes a "By Folder" entry for filesystem-based browsing.
|
||||
/// - Contains an obsolete `search="1"` entry for on-the-fly search dialog creation.
|
||||
///
|
||||
/// ### Types
|
||||
/// Each type in the library comes with a set of filters and sorts, aiding in building dynamic media controls:
|
||||
///
|
||||
/// - **Type Object Attributes**:
|
||||
/// - `key`: Endpoint for the media list of this type.
|
||||
/// - `type`: Metadata type (if standard Plex type).
|
||||
/// - `title`: Title for this content type (e.g., "Movies").
|
||||
///
|
||||
/// - **Filter Objects**:
|
||||
/// - Subset of the media query language.
|
||||
/// - Attributes include `filter` (name), `filterType` (data type), `key` (endpoint for value range), and `title`.
|
||||
///
|
||||
/// - **Sort Objects**:
|
||||
/// - Description of sort fields.
|
||||
/// - Attributes include `defaultDirection` (asc/desc), `descKey` and `key` (sort parameters), and `title`.
|
||||
///
|
||||
/// > **Note**: Filters and sorts are optional; without them, no filtering controls are rendered.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetLibraryRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/GetLibraryResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getLibrary(request: Operations.GetLibraryRequest) async throws -> Response<Operations.GetLibraryResponse>
|
||||
|
||||
/// Delate a library using a specific section
|
||||
///
|
||||
/// - Parameter request: A ``Operations/DeleteLibraryRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/DeleteLibraryResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func deleteLibrary(request: Operations.DeleteLibraryRequest) async throws -> Response<Operations.DeleteLibraryResponse>
|
||||
|
||||
/// Fetches details from a specific section of the library identified by a section key and a tag. The tag parameter accepts the following values:
|
||||
/// - `all`: All items in the section.
|
||||
/// - `unwatched`: Items that have not been played.
|
||||
/// - `newest`: Items that are recently released.
|
||||
/// - `recentlyAdded`: Items that are recently added to the library.
|
||||
/// - `recentlyViewed`: Items that were recently viewed.
|
||||
/// - `onDeck`: Items to continue watching.
|
||||
/// - `collection`: Items categorized by collection.
|
||||
/// - `edition`: Items categorized by edition.
|
||||
/// - `genre`: Items categorized by genre.
|
||||
/// - `year`: Items categorized by year of release.
|
||||
/// - `decade`: Items categorized by decade.
|
||||
/// - `director`: Items categorized by director.
|
||||
/// - `actor`: Items categorized by starring actor.
|
||||
/// - `country`: Items categorized by country of origin.
|
||||
/// - `contentRating`: Items categorized by content rating.
|
||||
/// - `rating`: Items categorized by rating.
|
||||
/// - `resolution`: Items categorized by resolution.
|
||||
/// - `firstCharacter`: Items categorized by the first letter.
|
||||
/// - `folder`: Items categorized by folder.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetLibraryItemsRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/GetLibraryItemsResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getLibraryItems(request: Operations.GetLibraryItemsRequest) async throws -> Response<Operations.GetLibraryItemsResponse>
|
||||
|
||||
/// This endpoint Refreshes the library.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/RefreshLibraryRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/RefreshLibraryResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func refreshLibrary(request: Operations.RefreshLibraryRequest) async throws -> Response<Operations.RefreshLibraryResponse>
|
||||
|
||||
/// Search for content within a specific section of the library.
|
||||
///
|
||||
/// ### Types
|
||||
/// Each type in the library comes with a set of filters and sorts, aiding in building dynamic media controls:
|
||||
///
|
||||
/// - **Type Object Attributes**:
|
||||
/// - `type`: Metadata type (if standard Plex type).
|
||||
/// - `title`: Title for this content type (e.g., "Movies").
|
||||
///
|
||||
/// - **Filter Objects**:
|
||||
/// - Subset of the media query language.
|
||||
/// - Attributes include `filter` (name), `filterType` (data type), `key` (endpoint for value range), and `title`.
|
||||
///
|
||||
/// - **Sort Objects**:
|
||||
/// - Description of sort fields.
|
||||
/// - Attributes include `defaultDirection` (asc/desc), `descKey` and `key` (sort parameters), and `title`.
|
||||
///
|
||||
/// > **Note**: Filters and sorts are optional; without them, no filtering controls are rendered.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/SearchLibraryRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/SearchLibraryResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func searchLibrary(request: Operations.SearchLibraryRequest) async throws -> Response<Operations.SearchLibraryResponse>
|
||||
|
||||
/// This endpoint will return the metadata of a library item specified with the ratingKey.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetMetadataRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/GetMetadataResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getMetadata(request: Operations.GetMetadataRequest) async throws -> Response<Operations.GetMetadataResponse>
|
||||
|
||||
/// This endpoint will return the children of of a library item specified with the ratingKey.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetMetadataChildrenRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/GetMetadataChildrenResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getMetadataChildren(request: Operations.GetMetadataChildrenRequest) async throws -> Response<Operations.GetMetadataChildrenResponse>
|
||||
|
||||
/// This endpoint will return the on deck content.
|
||||
///
|
||||
///
|
||||
/// - Returns: A ``Operations/GetOnDeckResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getOnDeck() async throws -> Response<Operations.GetOnDeckResponse>
|
||||
}
|
||||
|
||||
// MARK: - LogAPI
|
||||
|
||||
/// Submit logs to the Log Handler for Plex Media Server
|
||||
///
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### API calls
|
||||
///
|
||||
/// - ``logLine(request:)``
|
||||
/// - ``logMultiLine(request:)``
|
||||
/// - ``enablePaperTrail()``
|
||||
///
|
||||
public protocol LogAPI {
|
||||
/// This endpoint will write a single-line log message, including a level and source to the main Plex Media Server log.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/LogLineRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/LogLineResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func logLine(request: Operations.LogLineRequest) async throws -> Response<Operations.LogLineResponse>
|
||||
|
||||
/// This endpoint allows for the batch addition of log entries to the main Plex Media Server log.
|
||||
/// It accepts a text/plain request body, where each line represents a distinct log entry.
|
||||
/// Each log entry consists of URL-encoded key-value pairs, specifying log attributes such as 'level', 'message', and 'source'.
|
||||
///
|
||||
/// Log entries are separated by a newline character (`\n`).
|
||||
/// Each entry's parameters should be URL-encoded to ensure accurate parsing and handling of special characters.
|
||||
/// This method is efficient for logging multiple entries in a single API call, reducing the overhead of multiple individual requests.
|
||||
///
|
||||
/// The 'level' parameter specifies the log entry's severity or importance, with the following integer values:
|
||||
/// - `0`: Error - Critical issues that require immediate attention.
|
||||
/// - `1`: Warning - Important events that are not critical but may indicate potential issues.
|
||||
/// - `2`: Info - General informational messages about system operation.
|
||||
/// - `3`: Debug - Detailed information useful for debugging purposes.
|
||||
/// - `4`: Verbose - Highly detailed diagnostic information for in-depth analysis.
|
||||
///
|
||||
/// The 'message' parameter contains the log text, and 'source' identifies the log message's origin (e.g., an application name or module).
|
||||
///
|
||||
/// Example of a single log entry format:
|
||||
/// `level=4&message=Sample%20log%20entry&source=applicationName`
|
||||
///
|
||||
/// Ensure each parameter is properly URL-encoded to avoid interpretation issues.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A string input to the API operation
|
||||
/// - Returns: A ``Operations/LogMultiLineResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func logMultiLine(request: String) async throws -> Response<Operations.LogMultiLineResponse>
|
||||
|
||||
/// This endpoint will enable all Plex Media Serverlogs to be sent to the Papertrail networked logging site for a period of time.
|
||||
///
|
||||
///
|
||||
/// - Returns: A ``Operations/EnablePaperTrailResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func enablePaperTrail() async throws -> Response<Operations.EnablePaperTrailResponse>
|
||||
}
|
||||
|
||||
// MARK: - PlexAPI
|
||||
public enum PlexServers {
|
||||
|
||||
/// Describes the available servers that can be used when making 'getPin' requests.
|
||||
///
|
||||
/// Use this type when making calls to ``PlexAPI/getPin(request:server:)`` to customize the server which is used.
|
||||
public enum GetPin: Servers, ServerConvertible {
|
||||
/// Supported server value.
|
||||
///
|
||||
/// Corresponds to `https://plex.tv/api/v2`
|
||||
case server1
|
||||
|
||||
/// Defines the raw URL strings for each server option.
|
||||
///
|
||||
/// > Note: You do not need to use these values directly.
|
||||
///
|
||||
/// The available URL strings are defined as:
|
||||
/// ```swift
|
||||
/// public static let urlStrings = [
|
||||
/// "https://plex.tv/api/v2"
|
||||
/// ]
|
||||
/// ```
|
||||
public static let urlStrings = [
|
||||
"https://plex.tv/api/v2"
|
||||
]
|
||||
|
||||
static func `default`() throws -> Server {
|
||||
return try PlexServers.GetPin.server1.server()
|
||||
}
|
||||
|
||||
func server() throws -> Server {
|
||||
switch self {
|
||||
case .server1:
|
||||
return try type(of: self).server(at: 0, substituting: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes the available servers that can be used when making 'getToken' requests.
|
||||
///
|
||||
/// Use this type when making calls to ``PlexAPI/getToken(request:server:)`` to customize the server which is used.
|
||||
public enum GetToken: Servers, ServerConvertible {
|
||||
/// Supported server value.
|
||||
///
|
||||
/// Corresponds to `https://plex.tv/api/v2`
|
||||
case server1
|
||||
|
||||
/// Defines the raw URL strings for each server option.
|
||||
///
|
||||
/// > Note: You do not need to use these values directly.
|
||||
///
|
||||
/// The available URL strings are defined as:
|
||||
/// ```swift
|
||||
/// public static let urlStrings = [
|
||||
/// "https://plex.tv/api/v2"
|
||||
/// ]
|
||||
/// ```
|
||||
public static let urlStrings = [
|
||||
"https://plex.tv/api/v2"
|
||||
]
|
||||
|
||||
static func `default`() throws -> Server {
|
||||
return try PlexServers.GetToken.server1.server()
|
||||
}
|
||||
|
||||
func server() throws -> Server {
|
||||
switch self {
|
||||
case .server1:
|
||||
return try type(of: self).server(at: 0, substituting: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// API Calls that perform operations directly against https://Plex.tv
|
||||
///
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### API calls
|
||||
///
|
||||
/// - ``getPin(request:server:)``
|
||||
/// - ``getToken(request:server:)``
|
||||
///
|
||||
public protocol PlexAPI {
|
||||
/// Retrieve a Pin from Plex.tv for authentication flows
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetPinRequest`` object describing the input to the API operation
|
||||
/// - Parameter server: An optional server override to use for this operation
|
||||
/// - Returns: A ``Operations/GetPinResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getPin(request: Operations.GetPinRequest, server: PlexServers.GetPin?) async throws -> Response<Operations.GetPinResponse>
|
||||
|
||||
/// Retrieve an Access Token from Plex.tv after the Pin has already been authenticated
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetTokenRequest`` object describing the input to the API operation
|
||||
/// - Parameter server: An optional server override to use for this operation
|
||||
/// - Returns: A ``Operations/GetTokenResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getToken(request: Operations.GetTokenRequest, server: PlexServers.GetToken?) async throws -> Response<Operations.GetTokenResponse>
|
||||
}
|
||||
|
||||
// MARK: - PlaylistsAPI
|
||||
|
||||
/// Playlists are ordered collections of media. They can be dumb (just a list of media) or smart (based on a media query, such as "all albums from 2017").
|
||||
/// They can be organized in (optionally nesting) folders.
|
||||
/// Retrieving a playlist, or its items, will trigger a refresh of its metadata.
|
||||
/// This may cause the duration and number of items to change.
|
||||
///
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### API calls
|
||||
///
|
||||
/// - ``createPlaylist(request:)``
|
||||
/// - ``getPlaylists(request:)``
|
||||
/// - ``getPlaylist(request:)``
|
||||
/// - ``deletePlaylist(request:)``
|
||||
/// - ``updatePlaylist(request:)``
|
||||
/// - ``getPlaylistContents(request:)``
|
||||
/// - ``clearPlaylistContents(request:)``
|
||||
/// - ``addPlaylistContents(request:)``
|
||||
/// - ``uploadPlaylist(request:)``
|
||||
///
|
||||
public protocol PlaylistsAPI {
|
||||
/// Create a new playlist. By default the playlist is blank. To create a playlist along with a first item, pass:
|
||||
/// - `uri` - The content URI for what we're playing (e.g. `server://1234/com.plexapp.plugins.library/library/metadata/1`).
|
||||
/// - `playQueueID` - To create a playlist from an existing play queue.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/CreatePlaylistRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/CreatePlaylistResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func createPlaylist(request: Operations.CreatePlaylistRequest) async throws -> Response<Operations.CreatePlaylistResponse>
|
||||
|
||||
/// Get All Playlists given the specified filters.
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetPlaylistsRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/GetPlaylistsResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getPlaylists(request: Operations.GetPlaylistsRequest) async throws -> Response<Operations.GetPlaylistsResponse>
|
||||
|
||||
/// Gets detailed metadata for a playlist. A playlist for many purposes (rating, editing metadata, tagging), can be treated like a regular metadata item:
|
||||
/// Smart playlist details contain the `content` attribute. This is the content URI for the generator. This can then be parsed by a client to provide smart playlist editing.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetPlaylistRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/GetPlaylistResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getPlaylist(request: Operations.GetPlaylistRequest) async throws -> Response<Operations.GetPlaylistResponse>
|
||||
|
||||
/// This endpoint will delete a playlist
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/DeletePlaylistRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/DeletePlaylistResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func deletePlaylist(request: Operations.DeletePlaylistRequest) async throws -> Response<Operations.DeletePlaylistResponse>
|
||||
|
||||
/// From PMS version 1.9.1 clients can also edit playlist metadata using this endpoint as they would via `PUT /library/metadata/{playlistID}`
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/UpdatePlaylistRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/UpdatePlaylistResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func updatePlaylist(request: Operations.UpdatePlaylistRequest) async throws -> Response<Operations.UpdatePlaylistResponse>
|
||||
|
||||
/// Gets the contents of a playlist. Should be paged by clients via standard mechanisms.
|
||||
/// By default leaves are returned (e.g. episodes, movies). In order to return other types you can use the `type` parameter.
|
||||
/// For example, you could use this to display a list of recently added albums vis a smart playlist.
|
||||
/// Note that for dumb playlists, items have a `playlistItemID` attribute which is used for deleting or moving items.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetPlaylistContentsRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/GetPlaylistContentsResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getPlaylistContents(request: Operations.GetPlaylistContentsRequest) async throws -> Response<Operations.GetPlaylistContentsResponse>
|
||||
|
||||
/// Clears a playlist, only works with dumb playlists. Returns the playlist.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/ClearPlaylistContentsRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/ClearPlaylistContentsResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func clearPlaylistContents(request: Operations.ClearPlaylistContentsRequest) async throws -> Response<Operations.ClearPlaylistContentsResponse>
|
||||
|
||||
/// Adds a generator to a playlist, same parameters as the POST to create. With a dumb playlist, this adds the specified items to the playlist.
|
||||
/// With a smart playlist, passing a new `uri` parameter replaces the rules for the playlist. Returns the playlist.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/AddPlaylistContentsRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/AddPlaylistContentsResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func addPlaylistContents(request: Operations.AddPlaylistContentsRequest) async throws -> Response<Operations.AddPlaylistContentsResponse>
|
||||
|
||||
/// Imports m3u playlists by passing a path on the server to scan for m3u-formatted playlist files, or a path to a single playlist file.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/UploadPlaylistRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/UploadPlaylistResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func uploadPlaylist(request: Operations.UploadPlaylistRequest) async throws -> Response<Operations.UploadPlaylistResponse>
|
||||
}
|
||||
|
||||
// MARK: - AuthenticationAPI
|
||||
|
||||
/// API Calls regarding authentication for Plex Media Server
|
||||
///
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### API calls
|
||||
///
|
||||
/// - ``getTransientToken(request:)``
|
||||
/// - ``getSourceConnectionInformation(request:)``
|
||||
///
|
||||
public protocol AuthenticationAPI {
|
||||
/// This endpoint provides the caller with a temporary token with the same access level as the caller's token. These tokens are valid for up to 48 hours and are destroyed if the server instance is restarted.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetTransientTokenRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/GetTransientTokenResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getTransientToken(request: Operations.GetTransientTokenRequest) async throws -> Response<Operations.GetTransientTokenResponse>
|
||||
|
||||
/// If a caller requires connection details and a transient token for a source that is known to the server, for example a cloud media provider or shared PMS, then this endpoint can be called. This endpoint is only accessible with either an admin token or a valid transient token generated from an admin token.
|
||||
/// Note: requires Plex Media Server >= 1.15.4.
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetSourceConnectionInformationRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/GetSourceConnectionInformationResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getSourceConnectionInformation(request: Operations.GetSourceConnectionInformationRequest) async throws -> Response<Operations.GetSourceConnectionInformationResponse>
|
||||
}
|
||||
|
||||
// MARK: - StatisticsAPI
|
||||
|
||||
/// API Calls that perform operations with Plex Media Server Statistics
|
||||
///
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### API calls
|
||||
///
|
||||
/// - ``getStatistics(request:)``
|
||||
///
|
||||
public protocol StatisticsAPI {
|
||||
/// This will return the media statistics for the server
|
||||
///
|
||||
/// - Parameter request: A ``Operations/GetStatisticsRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/GetStatisticsResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getStatistics(request: Operations.GetStatisticsRequest) async throws -> Response<Operations.GetStatisticsResponse>
|
||||
}
|
||||
|
||||
// MARK: - SessionsAPI
|
||||
|
||||
/// API Calls that perform search operations with Plex Media Server Sessions
|
||||
///
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### API calls
|
||||
///
|
||||
/// - ``getSessions()``
|
||||
/// - ``getSessionHistory()``
|
||||
/// - ``getTranscodeSessions()``
|
||||
/// - ``stopTranscodeSession(request:)``
|
||||
///
|
||||
public protocol SessionsAPI {
|
||||
/// This will retrieve the "Now Playing" Information of the PMS.
|
||||
///
|
||||
/// - Returns: A ``Operations/GetSessionsResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getSessions() async throws -> Response<Operations.GetSessionsResponse>
|
||||
|
||||
/// This will Retrieve a listing of all history views.
|
||||
///
|
||||
/// - Returns: A ``Operations/GetSessionHistoryResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getSessionHistory() async throws -> Response<Operations.GetSessionHistoryResponse>
|
||||
|
||||
/// Get Transcode Sessions
|
||||
///
|
||||
/// - Returns: A ``Operations/GetTranscodeSessionsResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getTranscodeSessions() async throws -> Response<Operations.GetTranscodeSessionsResponse>
|
||||
|
||||
/// Stop a Transcode Session
|
||||
///
|
||||
/// - Parameter request: A ``Operations/StopTranscodeSessionRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/StopTranscodeSessionResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func stopTranscodeSession(request: Operations.StopTranscodeSessionRequest) async throws -> Response<Operations.StopTranscodeSessionResponse>
|
||||
}
|
||||
|
||||
// MARK: - UpdaterAPI
|
||||
|
||||
/// This describes the API for searching and applying updates to the Plex Media Server.
|
||||
/// Updates to the status can be observed via the Event API.
|
||||
///
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### API calls
|
||||
///
|
||||
/// - ``getUpdateStatus()``
|
||||
/// - ``checkForUpdates(request:)``
|
||||
/// - ``applyUpdates(request:)``
|
||||
///
|
||||
public protocol UpdaterAPI {
|
||||
/// Querying status of updates
|
||||
///
|
||||
/// - Returns: A ``Operations/GetUpdateStatusResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func getUpdateStatus() async throws -> Response<Operations.GetUpdateStatusResponse>
|
||||
|
||||
/// Checking for updates
|
||||
///
|
||||
/// - Parameter request: A ``Operations/CheckForUpdatesRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/CheckForUpdatesResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func checkForUpdates(request: Operations.CheckForUpdatesRequest) async throws -> Response<Operations.CheckForUpdatesResponse>
|
||||
|
||||
/// Note that these two parameters are effectively mutually exclusive. The `tonight` parameter takes precedence and `skip` will be ignored if `tonight` is also passed
|
||||
///
|
||||
///
|
||||
/// - Parameter request: A ``Operations/ApplyUpdatesRequest`` object describing the input to the API operation
|
||||
/// - Returns: A ``Operations/ApplyUpdatesResponse`` object describing the result of the API operation
|
||||
/// - Throws: An error of type ``PlexswiftError``
|
||||
func applyUpdates(request: Operations.ApplyUpdatesRequest) async throws -> Response<Operations.ApplyUpdatesResponse>
|
||||
}
|
||||
208
Sources/plexswift/PlexswiftError.swift
Normal file
208
Sources/plexswift/PlexswiftError.swift
Normal file
@@ -0,0 +1,208 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Describes errors that occur when making requests to the API.
|
||||
///
|
||||
/// ``PlexswiftError`` describes problems which occur through the lifecycle of making a request to the API, from constructing the underlying network request, through making the network request and handling the resulting response.
|
||||
///
|
||||
/// Most of the error values have associated failure reasons:
|
||||
/// - ``PlexswiftError/failedToConstructRequestURL(_:)``
|
||||
/// - ``PlexswiftError/failedToSerializeRequestParameters(_:)``
|
||||
/// - ``PlexswiftError/failedToConstructRequest(_:)``
|
||||
/// - ``PlexswiftError/failedToHandleResponse(_:)``
|
||||
///
|
||||
/// which provide more information about why the error occurred.
|
||||
///
|
||||
/// If a network error occurs when making an API request, ``PlexswiftError/failedToMakeNetworkRequest(error:)`` has an associated [`Error`](https://developer.apple.com/documentation/swift/error) value which describes more information about why the network error occurred.
|
||||
///
|
||||
/// In exceptional circumstances there may be an internal error which occurs in the implementation of ``Plexswift`` or in the underlying system frameworks. Where this occurs, ``PlexswiftError/internalError(error:)`` provides this information, with additional context if it is available.
|
||||
///
|
||||
/// ### Getting an error description
|
||||
///
|
||||
/// ``PlexswiftError`` conforms to the [`LocalizedError`](https://developer.apple.com/documentation/foundation/localizederror) protocol. As such a readable description of the error is provided through the [`errorDescription`](https://developer.apple.com/documentation/foundation/localizederror/2946895-errordescription) property.
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### Errors
|
||||
/// - ``PlexswiftError/failedToConstructRequestURL(_:)``
|
||||
/// - ``PlexswiftError/failedToSerializeRequestParameters(_:)``
|
||||
/// - ``PlexswiftError/failedToConstructRequest(_:)``
|
||||
/// - ``PlexswiftError/failedToMakeNetworkRequest(error:)``
|
||||
/// - ``PlexswiftError/failedToHandleResponse(_:)``
|
||||
/// - ``PlexswiftError/internalError(error:)``
|
||||
///
|
||||
/// ### Error failure information
|
||||
/// - ``PlexswiftError/RequestURLConstructionFailureReason``
|
||||
/// - ``PlexswiftError/ParameterSerializationFailureReason``
|
||||
/// - ``PlexswiftError/RequestConstructionFailureReason``
|
||||
/// - ``PlexswiftError/ResponseHandlingFailureReason``
|
||||
///
|
||||
/// ### Convenience properties
|
||||
/// - ``PlexswiftError/underlyingError``
|
||||
public enum PlexswiftError: Swift.Error {
|
||||
/// Failure reasons for ``PlexswiftError/failedToConstructRequestURL(_:)`` errors
|
||||
public enum RequestURLConstructionFailureReason {
|
||||
/// An invalid URL was returned when using a specified server definition to make a network request.
|
||||
case invalidServerURL(string: String)
|
||||
/// An invalid URL was used to make a network request.
|
||||
case invalidRequestURL(string: String)
|
||||
/// No default server could be found when making a network request.
|
||||
case missingDefaultServer(serverType: String)
|
||||
/// A server in a server list was specified but the index of that server is outside of the bounds of the list.
|
||||
case invalidServerIndex(serverType: String, index: Int)
|
||||
}
|
||||
|
||||
/// Failure reasons for ``PlexswiftError/failedToSerializeRequestParameters(_:)`` errors
|
||||
public enum ParameterSerializationFailureReason {
|
||||
/// A server URL with parameters was used but the substitution parameter named `key` was not provided.
|
||||
///
|
||||
/// A server URL with substitution parameters — for example `https://domain.com:{port}/{configurable}/path` — was specified.
|
||||
case missingServerParameterSubstitutionKey(_ key: String, serverString: String)
|
||||
/// An API operation path with parameters was used but the substitution parameter named `key` was not specified.
|
||||
///
|
||||
/// An API operation with a path with substitution parameters — for example `"/{configurable}/endpoint"` — was specified.
|
||||
case missingPathParameterSubstitutionKey(_ key: String, path: String)
|
||||
/// A parameter was unexpectedly requested to be serialized to a given format.
|
||||
case invalidSerializationParameter(type: String, format: String)
|
||||
/// Failed to serialize a [Data](https://developer.apple.com/documentation/foundation/data) object when constructing the request.
|
||||
case failedToSerializeData
|
||||
}
|
||||
|
||||
/// Failure reasons for ``PlexswiftError/failedToConstructRequest(_:)`` errors
|
||||
public enum RequestConstructionFailureReason {
|
||||
/// During request construction, a request body was not provided when one was expected.
|
||||
case missingRequiredRequestBody
|
||||
}
|
||||
|
||||
/// Failure reasons for ``PlexswiftError/failedToHandleResponse(_:)`` errors
|
||||
public enum ResponseHandlingFailureReason {
|
||||
/// Failed to decode response data.
|
||||
case failedToDecodeResponse
|
||||
/// Failed to deserialize response JSON.
|
||||
case failedToDeserializeJSON(_ error: Swift.Error)
|
||||
}
|
||||
|
||||
/// Constructing the URL to make a network request failed.
|
||||
case failedToConstructRequestURL(_ reason: RequestURLConstructionFailureReason)
|
||||
/// Serializing the parameters required to make the network request failed.
|
||||
case failedToSerializeRequestParameters(_ reason: ParameterSerializationFailureReason)
|
||||
/// Constructing a underlying request object to make a network request failed.
|
||||
case failedToConstructRequest(_ reason: RequestConstructionFailureReason)
|
||||
/// Making an underlying network request failed.
|
||||
case failedToMakeNetworkRequest(error: Swift.Error)
|
||||
/// Handling the response data from an API request failed.
|
||||
case failedToHandleResponse(_ reason: ResponseHandlingFailureReason)
|
||||
|
||||
/// An attempt to get response data from a response failed because it was missing.
|
||||
case missingResponseData
|
||||
|
||||
/// An error internal to the implementation of ``Client`` occurred.
|
||||
case internalError(error: Swift.Error?)
|
||||
|
||||
}
|
||||
|
||||
extension PlexswiftError: LocalizedError {
|
||||
public var errorDescription: String? {
|
||||
switch self {
|
||||
case .failedToConstructRequestURL(let reason):
|
||||
return "Failed to construct URL for request: \(reason.localizedDescription)"
|
||||
case .failedToSerializeRequestParameters(let reason):
|
||||
return "Failed to serialize parameters for request: \(reason.localizedDescription)"
|
||||
case .failedToConstructRequest(let reason):
|
||||
return "Failed to construct request: \(reason.localizedDescription)"
|
||||
case .failedToMakeNetworkRequest(let error):
|
||||
return "Failed to make network request: \(error.localizedDescription)"
|
||||
case .failedToHandleResponse(let reason):
|
||||
return "Failed to handle response: \(reason.localizedDescription)"
|
||||
case .missingResponseData:
|
||||
return "The response didn't contain the requested data"
|
||||
case .internalError:
|
||||
return "The operation couldn't be completed"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension PlexswiftError {
|
||||
/// Returns the associated underlying error, if available.
|
||||
public var underlyingError: Swift.Error? {
|
||||
switch self {
|
||||
case .internalError(let error):
|
||||
return error
|
||||
case .failedToMakeNetworkRequest(let error):
|
||||
return error
|
||||
case .failedToHandleResponse(let reason):
|
||||
switch reason {
|
||||
case .failedToDecodeResponse:
|
||||
return nil
|
||||
case .failedToDeserializeJSON(let error):
|
||||
return error
|
||||
}
|
||||
case .failedToConstructRequestURL, .failedToSerializeRequestParameters, .failedToConstructRequest, .missingResponseData:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension PlexswiftError.RequestURLConstructionFailureReason {
|
||||
public var localizedDescription: String {
|
||||
switch self {
|
||||
case .invalidServerURL(string: let serverString):
|
||||
return "Server URL '\(serverString)' is not valid"
|
||||
case .invalidRequestURL(string: let string):
|
||||
return "Request URL '\(string)' is not valid"
|
||||
case .missingDefaultServer(let serverType):
|
||||
return "No default server is available for type '\(serverType)'"
|
||||
case .invalidServerIndex(serverType: let serverType, index: let index):
|
||||
return "Server type '\(serverType)' has no server defined at index \(index)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension PlexswiftError.ParameterSerializationFailureReason {
|
||||
public var localizedDescription: String {
|
||||
switch self {
|
||||
case .missingServerParameterSubstitutionKey(let key, serverString: let serverString):
|
||||
return "Missing substitution parameter '\(key)' when building server URL '\(serverString)'"
|
||||
case .missingPathParameterSubstitutionKey(let key, path: let path):
|
||||
return "Missing substitution parameter '\(key)' when building path '\(path)'"
|
||||
case .invalidSerializationParameter(type: let type, format: let format):
|
||||
return "Invalid parameter type '\(type)' when serializing for \(format)"
|
||||
case .failedToSerializeData:
|
||||
return "Failed to serialize data parameter"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension PlexswiftError.RequestConstructionFailureReason {
|
||||
public var localizedDescription: String {
|
||||
switch self {
|
||||
case .missingRequiredRequestBody:
|
||||
return "Required request body is missing"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension PlexswiftError.ResponseHandlingFailureReason {
|
||||
public var localizedDescription: String {
|
||||
switch self {
|
||||
case .failedToDecodeResponse:
|
||||
return "Failed to decode response data"
|
||||
case .failedToDeserializeJSON(let error):
|
||||
return "Failed to deserialize JSON: \(error.localizedDescription)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SerializableFormat {
|
||||
var formatDescription: String {
|
||||
switch self {
|
||||
case .path: return "path parameter"
|
||||
case .query: return "query parameter"
|
||||
case .header: return "request header"
|
||||
case .multipart: return "multipart encoding"
|
||||
case .form: return "form encoding"
|
||||
}
|
||||
}
|
||||
}
|
||||
74
Sources/plexswift/internal/api/Client+PlexswiftAPI.swift
Normal file
74
Sources/plexswift/internal/api/Client+PlexswiftAPI.swift
Normal file
@@ -0,0 +1,74 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Client: PlexswiftAPI {
|
||||
// MARK: - Root operations
|
||||
|
||||
// MARK: - Scoped API operations
|
||||
|
||||
public var server: ServerAPI {
|
||||
return _ServerAPI(client: self)
|
||||
}
|
||||
|
||||
public var media: MediaAPI {
|
||||
return _MediaAPI(client: self)
|
||||
}
|
||||
|
||||
public var video: VideoAPI {
|
||||
return _VideoAPI(client: self)
|
||||
}
|
||||
|
||||
public var activities: ActivitiesAPI {
|
||||
return _ActivitiesAPI(client: self)
|
||||
}
|
||||
|
||||
public var butler: ButlerAPI {
|
||||
return _ButlerAPI(client: self)
|
||||
}
|
||||
|
||||
public var hubs: HubsAPI {
|
||||
return _HubsAPI(client: self)
|
||||
}
|
||||
|
||||
public var search: SearchAPI {
|
||||
return _SearchAPI(client: self)
|
||||
}
|
||||
|
||||
public var library: LibraryAPI {
|
||||
return _LibraryAPI(client: self)
|
||||
}
|
||||
|
||||
public var log: LogAPI {
|
||||
return _LogAPI(client: self)
|
||||
}
|
||||
|
||||
public var plex: PlexAPI {
|
||||
return _PlexAPI(client: self)
|
||||
}
|
||||
|
||||
public var playlists: PlaylistsAPI {
|
||||
return _PlaylistsAPI(client: self)
|
||||
}
|
||||
|
||||
public var authentication: AuthenticationAPI {
|
||||
return _AuthenticationAPI(client: self)
|
||||
}
|
||||
|
||||
public var statistics: StatisticsAPI {
|
||||
return _StatisticsAPI(client: self)
|
||||
}
|
||||
|
||||
public var sessions: SessionsAPI {
|
||||
return _SessionsAPI(client: self)
|
||||
}
|
||||
|
||||
public var updater: UpdaterAPI {
|
||||
return _UpdaterAPI(client: self)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Request Configuration
|
||||
|
||||
// MARK: - Response Handlers
|
||||
|
||||
121
Sources/plexswift/internal/client/Response.swift
Normal file
121
Sources/plexswift/internal/client/Response.swift
Normal file
@@ -0,0 +1,121 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
#if os(Linux)
|
||||
import FoundationNetworking
|
||||
#endif
|
||||
|
||||
/// Describes any header values returned as part of a response to a call made to the API.
|
||||
///
|
||||
/// As per the HTTP RFCs, header values can be queried in a case-insensitive manner.
|
||||
public struct ResponseHeaders {
|
||||
private let httpResponse: HTTPURLResponse
|
||||
|
||||
init(httpResponse: HTTPURLResponse) {
|
||||
self.httpResponse = httpResponse
|
||||
}
|
||||
|
||||
public func value(forHeaderNamed name: String) -> String? {
|
||||
return httpResponse.value(forHTTPHeaderField: name)
|
||||
}
|
||||
|
||||
public subscript(name: String) -> String? {
|
||||
return value(forHeaderNamed: name)
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes the result of making a request to the API.
|
||||
///
|
||||
/// This type is returned by all functions which make calls to the API. It returns information about the response
|
||||
/// and is parameterised by `T` over the type of data which is returned by the API operation.
|
||||
public struct Response<T>: ResponseFields {
|
||||
|
||||
/// The HTTP status code returned by the server.
|
||||
///
|
||||
/// This property contains the HTTP status code returned by the server in response to the underlying network request
|
||||
/// made to fulfill the given API operation.
|
||||
public var statusCode: Int {
|
||||
return httpResponse.statusCode
|
||||
}
|
||||
|
||||
/// The media type returned by the server.
|
||||
///
|
||||
/// This property contains the media type returned by the server in response to the underlying network request
|
||||
/// made to fulfill the given API operation.
|
||||
public var contentType: String {
|
||||
return httpResponse.contentType
|
||||
}
|
||||
|
||||
/// The raw HTTP response object.
|
||||
///
|
||||
/// This property contains the [HTTPURLResponse](https://developer.apple.com/documentation/foundation/httpurlresponse) object
|
||||
/// returned from making the underlying network request to fulfill the given API operation.
|
||||
public let httpResponse: HTTPURLResponse
|
||||
|
||||
/// The response data.
|
||||
///
|
||||
/// This property contains any response data associated with the API operation.
|
||||
public let data: T
|
||||
|
||||
public init(httpResponse: HTTPURLResponse, data: T) {
|
||||
self.httpResponse = httpResponse
|
||||
self.data = data
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes the result of making a request to the API which can contain resulting response header fields.
|
||||
///
|
||||
/// This type is returned by all functions which make calls to the API. It returns information about the response
|
||||
/// and is parameterised by `T` over the type of data which is returned by the API operation.
|
||||
public struct ResponseWithHeaders<T>: ResponseFields {
|
||||
|
||||
/// The HTTP status code returned by the server.
|
||||
///
|
||||
/// This property contains the HTTP status code returned by the server in response to the underlying network request
|
||||
/// made to fulfill the given API operation.
|
||||
public var statusCode: Int {
|
||||
return httpResponse.statusCode
|
||||
}
|
||||
|
||||
/// The media type returned by the server.
|
||||
///
|
||||
/// This property contains the media type returned by the server in response to the underlying network request
|
||||
/// made to fulfill the given API operation.
|
||||
public var contentType: String {
|
||||
return httpResponse.contentType
|
||||
}
|
||||
|
||||
/// The raw HTTP response object.
|
||||
///
|
||||
/// This property contains the [HTTPURLResponse](https://developer.apple.com/documentation/foundation/httpurlresponse) object
|
||||
/// returned from making the underlying network request to fulfill the given API operation.
|
||||
public let httpResponse: HTTPURLResponse
|
||||
|
||||
/// Any response headers returned by the underlying network request made to fulfill the given API operation.
|
||||
public let headers: ResponseHeaders?
|
||||
|
||||
/// The response data.
|
||||
///
|
||||
/// This property contains any response data associated with the API operation.
|
||||
public let data: T
|
||||
|
||||
public init(httpResponse: HTTPURLResponse, data: T) {
|
||||
self.httpResponse = httpResponse
|
||||
self.data = data
|
||||
self.headers = ResponseHeaders(httpResponse: httpResponse)
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes the fields which are included in all responses to requests made to the API.
|
||||
///
|
||||
/// This protocol is adopted by ``Response`` and ``ResponseWithHeaders`` depending on the individual API operation.
|
||||
public protocol ResponseFields {
|
||||
associatedtype T;
|
||||
|
||||
var statusCode: Int { get }
|
||||
var contentType: String { get }
|
||||
var httpResponse: HTTPURLResponse { get }
|
||||
var data: T { get }
|
||||
|
||||
init(httpResponse: HTTPURLResponse, data: T)
|
||||
}
|
||||
60
Sources/plexswift/internal/client/Servers.swift
Normal file
60
Sources/plexswift/internal/client/Servers.swift
Normal file
@@ -0,0 +1,60 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
|
||||
struct Server {
|
||||
public let urlString: String
|
||||
}
|
||||
|
||||
protocol Servers {
|
||||
static var urlStrings: [String] { get }
|
||||
|
||||
static func `default`() throws -> Server
|
||||
static func server(at index: Int) throws -> Server
|
||||
static func server(at index: Int, substituting parameters: [String: String]?) throws -> Server
|
||||
}
|
||||
|
||||
protocol ServerConvertible {
|
||||
func server() throws -> Server
|
||||
}
|
||||
|
||||
enum ServerConversionError: Swift.Error {
|
||||
case `internal`
|
||||
case missingDefaultServer(serverType: String)
|
||||
case invalidServerIndex(serverType: String, index: Int)
|
||||
case missingServerParameterSubstitutionKey(_ key: String, serverString: String)
|
||||
}
|
||||
|
||||
extension Servers {
|
||||
static func `default`() throws -> Server {
|
||||
guard urlStrings.count > 0 else {
|
||||
throw ServerConversionError.missingDefaultServer(serverType: String(describing: self))
|
||||
}
|
||||
|
||||
return Server(urlString: urlStrings[0])
|
||||
}
|
||||
|
||||
static func server(at index: Int) throws -> Server {
|
||||
return try server(at: index, substituting: nil)
|
||||
}
|
||||
|
||||
static func server(at index: Int, substituting parameters: [String: String]?) throws -> Server {
|
||||
guard index >= 0 && index < urlStrings.count else {
|
||||
throw ServerConversionError.invalidServerIndex(serverType: String(describing: self), index: index)
|
||||
}
|
||||
if let parameters = parameters {
|
||||
do {
|
||||
return Server(urlString: try urlStrings[index].substituteComponents { key in parameters[key] })
|
||||
} catch let error as StringSubstitutionError {
|
||||
switch error {
|
||||
case .internal:
|
||||
throw ServerConversionError.internal
|
||||
case .missingParameter(named: let name, in: let string):
|
||||
throw ServerConversionError.missingServerParameterSubstitutionKey(name, serverString: string)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Server(urlString: urlStrings[index])
|
||||
}
|
||||
}
|
||||
}
|
||||
154
Sources/plexswift/internal/client/URLRequestBuilder.swift
Normal file
154
Sources/plexswift/internal/client/URLRequestBuilder.swift
Normal file
@@ -0,0 +1,154 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
|
||||
import Foundation
|
||||
#if os(Linux)
|
||||
import FoundationNetworking
|
||||
#endif
|
||||
|
||||
enum URLRequestBuilderError: Swift.Error {
|
||||
case internalError
|
||||
case invalidURL(String)
|
||||
case missingPathParameterSubstitutionKey(_ key: String, path: String)
|
||||
}
|
||||
|
||||
final class URLRequestBuilder: URLRequestConfiguration {
|
||||
private let baseURL: URL
|
||||
private let parameterDefaults: ParameterDefaults?
|
||||
private let defaultSecurityParameterProviding: SecurityParameterProviding?
|
||||
|
||||
var path: String = ""
|
||||
var method: URLRequestHTTPMethod = .get
|
||||
var contentType: String?
|
||||
|
||||
var securityParameterProviding: SecurityParameterProviding?
|
||||
|
||||
var pathParameterSerializable: PathParameterSerializable?
|
||||
var queryParameterSerializable: QueryParameterSerializable?
|
||||
var headerParameterSerializable: HeaderParameterSerializable?
|
||||
|
||||
var body: Data?
|
||||
|
||||
var telemetryHeader: TelemetryHeader = .userAgent
|
||||
|
||||
init(baseURL: URL, parameterDefaults: ParameterDefaults?, defaultSecurityParameterProviding: SecurityParameterProviding?) {
|
||||
self.baseURL = baseURL
|
||||
self.parameterDefaults = parameterDefaults
|
||||
self.defaultSecurityParameterProviding = defaultSecurityParameterProviding
|
||||
}
|
||||
|
||||
func build() throws -> URLRequest {
|
||||
guard var urlComponents = URLComponents(url: baseURL, resolvingAgainstBaseURL: true) else {
|
||||
throw URLRequestBuilderError.invalidURL(baseURL.absoluteString)
|
||||
}
|
||||
|
||||
try buildPathComponents(in: &urlComponents)
|
||||
|
||||
guard let url = urlComponents.url else {
|
||||
throw URLRequestBuilderError.invalidURL(baseURL.absoluteString)
|
||||
}
|
||||
|
||||
var urlRequest = URLRequest(url: url)
|
||||
if let headerParameterSerializable {
|
||||
for header in try headerParameterSerializable.serializedHeaderParameters() {
|
||||
urlRequest.setValue(header.serialized, forHTTPHeaderField: header.name)
|
||||
}
|
||||
}
|
||||
|
||||
urlRequest.httpMethod = method.rawValue
|
||||
urlRequest.httpBody = body
|
||||
|
||||
if let contentType {
|
||||
urlRequest.setValue(contentType, forHTTPHeaderField: "Content-Type")
|
||||
}
|
||||
|
||||
urlRequest.setValue("speakeasy-sdk/swift 0.0.2 2.283.1 0.0.3 plexswift", forHTTPHeaderField: telemetryHeader.headerName)
|
||||
|
||||
addSecurityParameters(to: &urlRequest)
|
||||
|
||||
return urlRequest
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func buildPathComponents(in urlComponents: inout URLComponents) throws {
|
||||
let (path, fragment) = parsePath(path)
|
||||
|
||||
if let pathParameterSerializable {
|
||||
urlComponents.path = (urlComponents.path as NSString).appendingPathComponent(
|
||||
try substitutePathParameters(in: path, with: pathParameterSerializable, parameterDefaults: parameterDefaults)
|
||||
)
|
||||
} else {
|
||||
urlComponents.path = (urlComponents.path as NSString).appendingPathComponent(path)
|
||||
}
|
||||
|
||||
if let queryParameterSerializable {
|
||||
urlComponents.percentEncodedQuery = queryString(
|
||||
from: try queryParameterSerializable.serializedQueryParameters(with: parameterDefaults, formatOverride: nil)
|
||||
)
|
||||
}
|
||||
|
||||
urlComponents.fragment = fragment
|
||||
}
|
||||
|
||||
private func parsePath(_ path: String) -> (path: String, fragment: String?) {
|
||||
let components = path.components(separatedBy: "#")
|
||||
guard let first = components.first else {
|
||||
return (path: "", fragment: nil)
|
||||
}
|
||||
return (path: first, fragment: components.count > 1 ? components[1] : nil)
|
||||
}
|
||||
|
||||
private func addSecurityParameters(to request: inout URLRequest) {
|
||||
guard let securityParameterProviding = securityParameterProviding ?? defaultSecurityParameterProviding else { return }
|
||||
|
||||
let parameters = securityParameterProviding.securityParameters()
|
||||
for parameter in parameters {
|
||||
switch parameter {
|
||||
case .httpBasic(username: let username, password: let password):
|
||||
if let username, let password, let encoded = "\(username):\(password)".data(using: .utf8)?.base64EncodedString() {
|
||||
request.addValue("Basic \(encoded)", forHTTPHeaderField: "Authorization")
|
||||
}
|
||||
case .httpBearer(value: let value):
|
||||
if let value {
|
||||
let headerValue = value.range(of: "Bearer ")?.lowerBound == value.startIndex ? value : "Bearer \(value)"
|
||||
request.addValue(headerValue, forHTTPHeaderField: "Authorization")
|
||||
}
|
||||
case .apiKey(name: let name, value: let value), .oauth2(name: let name, value: let value), .openIdConnect(name: let name, value: let value):
|
||||
if let value {
|
||||
request.addValue(value, forHTTPHeaderField: name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Substitute path parameters and rethrow `StringSubstitutionError`s as `URLRequestBuilderError`s.
|
||||
fileprivate func substitutePathParameters(
|
||||
in path: String,
|
||||
with pathParameterSerializable: PathParameterSerializable,
|
||||
parameterDefaults: ParameterDefaults?
|
||||
) throws -> String {
|
||||
do {
|
||||
let parameters = try pathParameterSerializable.serializedPathParameters(formatOverride: nil)
|
||||
return try path.substituteComponents { key in
|
||||
return try parameters[key] ?? parameterDefaults?.defaultSerializedPathParameter(for: key)
|
||||
}
|
||||
} catch let error as StringSubstitutionError {
|
||||
switch error {
|
||||
case .internal:
|
||||
throw URLRequestBuilderError.internalError
|
||||
case .missingParameter(named: let name, in: let string):
|
||||
throw URLRequestBuilderError.missingPathParameterSubstitutionKey(name, path: string)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate extension TelemetryHeader {
|
||||
var headerName: String {
|
||||
switch self {
|
||||
case .userAgent: return "User-Agent"
|
||||
case .speakeasyUserAgent: return "X-Speakeasy-User-Agent"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
|
||||
enum URLRequestHTTPMethod: String {
|
||||
case get = "GET"
|
||||
case post = "POST"
|
||||
case put = "PUT"
|
||||
case patch = "PATCH"
|
||||
case delete = "DELETE"
|
||||
case head = "HEAD"
|
||||
case options = "OPTIONS"
|
||||
case trace = "TRACE"
|
||||
}
|
||||
|
||||
enum TelemetryHeader {
|
||||
case userAgent
|
||||
case speakeasyUserAgent
|
||||
}
|
||||
|
||||
protocol URLRequestConfiguration: AnyObject {
|
||||
var path: String { get set }
|
||||
var method: URLRequestHTTPMethod { get set }
|
||||
var contentType: String? { get set }
|
||||
|
||||
var securityParameterProviding: SecurityParameterProviding? { get set }
|
||||
|
||||
var pathParameterSerializable: PathParameterSerializable? { get set }
|
||||
var queryParameterSerializable: QueryParameterSerializable? { get set }
|
||||
var headerParameterSerializable: HeaderParameterSerializable? { get set }
|
||||
|
||||
var body: Data? { get set }
|
||||
|
||||
var telemetryHeader: TelemetryHeader { get set }
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
#if os(Linux)
|
||||
import FoundationNetworking
|
||||
#endif
|
||||
|
||||
extension HTTPURLResponse {
|
||||
var contentType: String {
|
||||
return value(forHTTPHeaderField: "Content-Type") ?? "application/octet-stream"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
|
||||
extension String {
|
||||
func matchContentType(pattern: String) -> Bool {
|
||||
// Match wildcard types
|
||||
if pattern == "*" || pattern == "*/*" {
|
||||
return true
|
||||
}
|
||||
|
||||
// Match content type of the format 'application/json; charset=UTF-8'
|
||||
let contentTypeComponents = pattern.components(separatedBy: ";").map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
|
||||
guard let mediaType = contentTypeComponents.first else { return false }
|
||||
if mediaType == pattern {
|
||||
return true
|
||||
}
|
||||
|
||||
// Match wildcard parts on the media type
|
||||
let mediaTypeComponents = mediaType.components(separatedBy: "/")
|
||||
guard mediaTypeComponents.count == 2 else { return false }
|
||||
|
||||
return pattern == "\(mediaTypeComponents[0])/*" || pattern == "*/\(mediaTypeComponents[1])"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
|
||||
enum StringSubstitutionError: Swift.Error {
|
||||
case `internal`
|
||||
case missingParameter(named: String, in: String)
|
||||
}
|
||||
|
||||
extension String {
|
||||
typealias SubstitutionHandler = (_ key: String) throws -> String?
|
||||
|
||||
func substituteComponents(using substitutionHandler: SubstitutionHandler) throws -> String {
|
||||
let regex = try NSRegularExpression(pattern: "\\{([^}]+)\\}")
|
||||
let range = NSRange(startIndex..<endIndex, in: self)
|
||||
let matches = regex.matches(in: self, range: range)
|
||||
|
||||
var substitutedPath = self
|
||||
// Reverse matches so that we can replace substrings in place.
|
||||
for match in matches.reversed() {
|
||||
let templateRange = match.range
|
||||
guard let keyRange = Range(match.range(at: 1), in: self) else {
|
||||
throw StringSubstitutionError.internal
|
||||
}
|
||||
|
||||
let key = String(self[keyRange])
|
||||
guard let serializedParameter = try substitutionHandler(key) else {
|
||||
throw StringSubstitutionError.missingParameter(named: key, in: self)
|
||||
}
|
||||
|
||||
let startIndex = substitutedPath.index(substitutedPath.startIndex, offsetBy: templateRange.location)
|
||||
let endIndex = substitutedPath.index(startIndex, offsetBy: templateRange.length)
|
||||
substitutedPath.replaceSubrange(startIndex..<endIndex, with: serializedParameter)
|
||||
}
|
||||
return substitutedPath
|
||||
}
|
||||
}
|
||||
58
Sources/plexswift/internal/serialization/Form.swift
Normal file
58
Sources/plexswift/internal/serialization/Form.swift
Normal file
@@ -0,0 +1,58 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
|
||||
func multipartContentType(with boundary: String) -> String {
|
||||
return "multipart/form-data; boundary=\(boundary)"
|
||||
}
|
||||
|
||||
func serializeMultipartFormData(with multipartFormBodySerializable: MultipartFormBodySerializable) throws -> (boundary: String, data: Data) {
|
||||
let boundary = UUID().uuidString
|
||||
|
||||
var data = Data()
|
||||
let parameters = try multipartFormBodySerializable.serializedMultipartFormParameters(formatOverride: nil)
|
||||
parameters.forEach { parameter in
|
||||
switch parameter {
|
||||
case .value(name: let name, serialized: let serialized):
|
||||
guard let serialized else { return }
|
||||
|
||||
data.append(utf8String: "--\(boundary)\r\n")
|
||||
data.append(utf8String: "Content-Disposition: multipart/form-data; name=\"\(name)\"\r\n")
|
||||
data.append(utf8String: "Content-Type: text/plain\r\n\r\n")
|
||||
data.append(utf8String: "\(serialized)\r\n")
|
||||
case .file(name: let name, filename: let filename, data: let content):
|
||||
guard let filename, let content, let contentString = String(data: content, encoding: .ascii) else { return }
|
||||
|
||||
data.append(utf8String: "--\(boundary)\r\n")
|
||||
data.append(utf8String: "Content-Disposition: multipart/form-data; name=\"\(name)\"; filename=\"\(filename)\"\r\n")
|
||||
data.append(utf8String: "Content-Type: text/plain\r\n\r\n")
|
||||
data.append(utf8String: "\(contentString)\r\n")
|
||||
}
|
||||
}
|
||||
|
||||
data.append(utf8String: "--\(boundary)--")
|
||||
|
||||
return (boundary: boundary, data: data)
|
||||
}
|
||||
|
||||
func serializeFormData(with formBodySerializable: FormBodySerializable) throws -> Data? {
|
||||
let encoded = (try formBodySerializable.serializedFormParameters(formatOverride: nil))
|
||||
.compactMap { parameter -> (String, String)? in
|
||||
guard let serialized = parameter.serialized else { return nil }
|
||||
return (parameter.name, serialized)
|
||||
}
|
||||
.map { (name, serialized) in
|
||||
return "\(name)=\(serialized)"
|
||||
}
|
||||
.joined(separator: "&")
|
||||
|
||||
return encoded.data(using: .utf8)
|
||||
}
|
||||
|
||||
fileprivate extension Data {
|
||||
mutating func append(utf8String: String) {
|
||||
if let data = utf8String.data(using: .utf8) {
|
||||
append(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
17
Sources/plexswift/internal/serialization/JSON.swift
Normal file
17
Sources/plexswift/internal/serialization/JSON.swift
Normal file
@@ -0,0 +1,17 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
|
||||
func jsonEncoder() -> JSONEncoder {
|
||||
let jsonEncoder = JSONEncoder()
|
||||
// Sort keys to make this easier to test resulting JSON.
|
||||
jsonEncoder.outputFormatting = [.sortedKeys]
|
||||
return jsonEncoder
|
||||
}
|
||||
|
||||
func serializeEncodable(_ encodable: Encodable?) throws -> String? {
|
||||
guard let encodable else { return nil }
|
||||
|
||||
let data = try jsonEncoder().encode(encodable)
|
||||
return String(data: data, encoding: .utf8)
|
||||
}
|
||||
7
Sources/plexswift/internal/serialization/Maps.swift
Normal file
7
Sources/plexswift/internal/serialization/Maps.swift
Normal file
@@ -0,0 +1,7 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
|
||||
func namedQueryParameters(from serializable: Serializable, name: String, format: SerializableFormat) throws -> [QueryParameter] {
|
||||
return try serializable.serializeQueryParameters(with: format).mapKeys { _ in [name] }
|
||||
}
|
||||
102
Sources/plexswift/internal/serialization/Parameters.swift
Normal file
102
Sources/plexswift/internal/serialization/Parameters.swift
Normal file
@@ -0,0 +1,102 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
|
||||
struct SerializedParameter {
|
||||
let name: String
|
||||
let serialized: String?
|
||||
}
|
||||
|
||||
protocol ParameterDefaults {
|
||||
func defaultSerializedPathParameter(for key: String) throws -> String?
|
||||
func defaultQueryParameter(for key: String) -> AnyValue?
|
||||
}
|
||||
|
||||
// MARK: - Serialization Types
|
||||
|
||||
protocol PathParameterSerializable {
|
||||
func serializedPathParameters(formatOverride: SerializableFormat?) throws -> [String: String]
|
||||
}
|
||||
|
||||
protocol QueryParameterSerializable {
|
||||
func serializedQueryParameters(with parameterDefaults: ParameterDefaults?, formatOverride: SerializableFormat?) throws -> [QueryParameter]
|
||||
}
|
||||
|
||||
protocol HeaderParameterSerializable {
|
||||
func serializedHeaderParameters() throws -> [SerializedParameter]
|
||||
}
|
||||
|
||||
enum MultipartFormParameter {
|
||||
case value(name: String, serialized: String?)
|
||||
case file(name: String, filename: String?, data: Data?)
|
||||
}
|
||||
|
||||
protocol MultipartFormBodySerializable {
|
||||
func serializedMultipartFormParameters(formatOverride: SerializableFormat?) throws -> [MultipartFormParameter]
|
||||
}
|
||||
|
||||
protocol FormBodySerializable {
|
||||
func serializedFormParameters(formatOverride: SerializableFormat?) throws -> [SerializedParameter]
|
||||
}
|
||||
|
||||
// MARK: - Models
|
||||
|
||||
func serializePathParameterSerializable(
|
||||
_ pathParameterSerializable: PathParameterSerializable,
|
||||
with format: SerializableFormat
|
||||
) throws -> String {
|
||||
let fields = try pathParameterSerializable
|
||||
.serializedPathParameters(formatOverride: format)
|
||||
.map { (key, value) in
|
||||
SerializedParameter(name: key, serialized: value)
|
||||
}
|
||||
.sorted { a, b in
|
||||
a.name < b.name
|
||||
}
|
||||
return serializeModel(with: fields, format: format)
|
||||
}
|
||||
|
||||
func serializeQueryParameterSerializable(
|
||||
_ queryParameterSerializable: QueryParameterSerializable,
|
||||
with format: SerializableFormat
|
||||
) throws -> String {
|
||||
let fields = try queryParameterSerializable
|
||||
.serializedQueryParameters(with: nil, formatOverride: format)
|
||||
.compactMap { queryParameter -> SerializedParameter? in
|
||||
guard let key = queryParameter.key.last else { return nil }
|
||||
return SerializedParameter(name: key, serialized: queryParameter.serialized)
|
||||
}
|
||||
return serializeModel(with: fields, format: format)
|
||||
}
|
||||
|
||||
func serializeModel(
|
||||
with fields: [SerializedParameter],
|
||||
format: SerializableFormat
|
||||
) -> String {
|
||||
return fields.map { field in
|
||||
guard let serialized = field.serialized else { return nil }
|
||||
if format.explode {
|
||||
return "\(field.name)=\(serialized)"
|
||||
} else {
|
||||
return "\(field.name)\(format.separator)\(serialized)"
|
||||
}
|
||||
}.compactMap { $0 }.joined(separator: format.separator)
|
||||
}
|
||||
|
||||
// MARK: - Maps
|
||||
|
||||
extension Dictionary: MultipartFormBodySerializable where Key == String, Value: Serializable {
|
||||
func serializedMultipartFormParameters(formatOverride: SerializableFormat?) throws -> [MultipartFormParameter] {
|
||||
return try map { key, value in
|
||||
return .value(name: key, serialized: try value.serialize(with: formatOverride ?? .multipart))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Dictionary: FormBodySerializable where Key == String, Value: Serializable {
|
||||
func serializedFormParameters(formatOverride: SerializableFormat?) throws -> [SerializedParameter] {
|
||||
return try map { key, value in
|
||||
return SerializedParameter(name: key, serialized: try value.serialize(with: formatOverride ?? .form(explode: false)))
|
||||
}
|
||||
}
|
||||
}
|
||||
232
Sources/plexswift/internal/serialization/PropertyWrappers.swift
Normal file
232
Sources/plexswift/internal/serialization/PropertyWrappers.swift
Normal file
@@ -0,0 +1,232 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - Wrappers
|
||||
|
||||
/// An internal type used to aid in serializing request data and deserializing response data.
|
||||
///
|
||||
/// > Important: This type should not be used directly.
|
||||
@propertyWrapper public struct DecimalSerialized<Value>: Codable, Serializable where Value: DoubleConvertible {
|
||||
// This property wrapper ensures that we (de)serialize values as Decimals to avoid floating-point rounding errors.
|
||||
|
||||
public var wrappedValue: Value
|
||||
|
||||
public init(wrappedValue: Value) {
|
||||
self.wrappedValue = wrappedValue
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
wrappedValue = try Value.decodeValue(with: container)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.singleValueContainer()
|
||||
if let double = wrappedValue.toDouble() {
|
||||
try container.encode(Decimal(double))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Serializable
|
||||
|
||||
func serialize(with format: SerializableFormat) throws -> String {
|
||||
return wrappedValue.toDouble().map { String($0) } ?? ""
|
||||
}
|
||||
|
||||
func serializeQueryParameters(with format: SerializableFormat) throws -> [QueryParameter] {
|
||||
return [QueryParameter(key: [], serialized: try serialize(with: format))]
|
||||
}
|
||||
}
|
||||
|
||||
extension DecimalSerialized: CustomStringConvertible where Value: CustomStringConvertible {
|
||||
public var description: String {
|
||||
return wrappedValue.description
|
||||
}
|
||||
}
|
||||
|
||||
/// An internal type used to aid in serializing request data and deserializing response data.
|
||||
///
|
||||
/// > Important: This type should not be used directly.
|
||||
@propertyWrapper public struct DateTime<Value>: Codable, Serializable where Value: DateConvertible {
|
||||
// This property wrapper ensures that we (de)serialize Swift Dates in the correct datetime format.
|
||||
|
||||
public var wrappedValue: Value
|
||||
|
||||
public init(wrappedValue: Value) {
|
||||
self.wrappedValue = wrappedValue
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
wrappedValue = try Value.decodeValue(with: container, formatter: dateTimeFormatter)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.singleValueContainer()
|
||||
if let formatted = wrappedValue.formattedString(with: dateTimeFormatter) {
|
||||
try container.encode(formatted)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Serializable
|
||||
|
||||
func serialize(with format: SerializableFormat) throws -> String {
|
||||
return wrappedValue.formattedString(with: dateTimeFormatter) ?? ""
|
||||
}
|
||||
|
||||
func serializeQueryParameters(with format: SerializableFormat) throws -> [QueryParameter] {
|
||||
return [QueryParameter(key: [], serialized: try serialize(with: format))]
|
||||
}
|
||||
}
|
||||
|
||||
extension DateTime: CustomStringConvertible where Value: CustomStringConvertible {
|
||||
public var description: String {
|
||||
return wrappedValue.description
|
||||
}
|
||||
}
|
||||
|
||||
/// An internal type used to aid in serializing request data and deserializing response data.
|
||||
///
|
||||
/// > Important: This type should not be used directly.
|
||||
@propertyWrapper public struct DateOnly<Value>: Codable, Serializable where Value: DateConvertible {
|
||||
// This property wrapper ensures that we (de)serialize dates in the date-only format, as Date doesn't distinguish between these types.
|
||||
|
||||
public var wrappedValue: Value
|
||||
|
||||
public init(wrappedValue: Value) {
|
||||
self.wrappedValue = wrappedValue
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
wrappedValue = try Value.decodeValue(with: container, formatter: dateOnlyFormatter)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.singleValueContainer()
|
||||
if let formatted = wrappedValue.formattedString(with: dateOnlyFormatter) {
|
||||
try container.encode(formatted)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Serializable
|
||||
|
||||
func serialize(with format: SerializableFormat) throws -> String {
|
||||
return wrappedValue.formattedString(with: dateOnlyFormatter) ?? ""
|
||||
}
|
||||
|
||||
func serializeQueryParameters(with format: SerializableFormat) throws -> [QueryParameter] {
|
||||
return [QueryParameter(key: [], serialized: try serialize(with: format))]
|
||||
}
|
||||
}
|
||||
|
||||
extension DateOnly: CustomStringConvertible where Value: CustomStringConvertible {
|
||||
public var description: String {
|
||||
return wrappedValue.description
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Formatters
|
||||
|
||||
private let dateTimeFormatter = {
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
|
||||
return dateFormatter
|
||||
}()
|
||||
|
||||
private let dateOnlyFormatter = {
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.dateFormat = "yyyy-MM-dd"
|
||||
return dateFormatter
|
||||
}()
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
/// An internal type used to aid in serializing request data.
|
||||
///
|
||||
/// > Important: This type should not be used directly.
|
||||
public protocol DoubleConvertible {
|
||||
func toDouble() -> Double?
|
||||
static func decodeValue(with container: SingleValueDecodingContainer) throws -> Self
|
||||
}
|
||||
|
||||
extension Double: DoubleConvertible {
|
||||
public static func decodeValue(with container: SingleValueDecodingContainer) throws -> Double {
|
||||
return try container.decode(Double.self)
|
||||
}
|
||||
|
||||
public func toDouble() -> Double? {
|
||||
return self
|
||||
}
|
||||
}
|
||||
|
||||
extension Optional: DoubleConvertible where Wrapped == Double {
|
||||
public static func decodeValue(with container: SingleValueDecodingContainer) throws -> Optional<Double> {
|
||||
if container.decodeNil() {
|
||||
return nil
|
||||
} else {
|
||||
return try container.decode(Double.self)
|
||||
}
|
||||
}
|
||||
|
||||
public func toDouble() -> Double? {
|
||||
return self
|
||||
}
|
||||
}
|
||||
|
||||
/// An internal type used to aid in serializing request data.
|
||||
///
|
||||
/// > Important: This type should not be used directly.
|
||||
public protocol DateConvertible {
|
||||
func toDate() -> Date?
|
||||
func formattedString(with formatter: DateFormatter) -> String?
|
||||
|
||||
static func decodeValue(with container: SingleValueDecodingContainer, formatter: DateFormatter) throws -> Self
|
||||
}
|
||||
|
||||
extension Date: DateConvertible {
|
||||
public static func decodeValue(with container: SingleValueDecodingContainer, formatter: DateFormatter) throws -> Date {
|
||||
let string = try container.decode(String.self)
|
||||
guard let date = formatter.date(from: string) else {
|
||||
throw DecodingError.dataCorruptedError(
|
||||
in: container,
|
||||
debugDescription: "Invalid date string value '\(string)'"
|
||||
)
|
||||
}
|
||||
return date
|
||||
}
|
||||
|
||||
public func toDate() -> Date? {
|
||||
return self
|
||||
}
|
||||
|
||||
public func formattedString(with formatter: DateFormatter) -> String? {
|
||||
return formatter.string(from: self)
|
||||
}
|
||||
}
|
||||
|
||||
extension Optional: DateConvertible where Wrapped == Date {
|
||||
public static func decodeValue(with container: SingleValueDecodingContainer, formatter: DateFormatter) throws -> Optional<Date> {
|
||||
if container.decodeNil() {
|
||||
return nil
|
||||
} else {
|
||||
let string = try container.decode(String.self)
|
||||
guard let date = formatter.date(from: string) else {
|
||||
throw DecodingError.dataCorruptedError(
|
||||
in: container,
|
||||
debugDescription: "Invalid date string value '\(string)'"
|
||||
)
|
||||
}
|
||||
return date
|
||||
}
|
||||
}
|
||||
|
||||
public func toDate() -> Date? {
|
||||
return self
|
||||
}
|
||||
|
||||
public func formattedString(with formatter: DateFormatter) -> String? {
|
||||
return self.map { formatter.string(from: $0) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
|
||||
func queryString(from queryParameters: [QueryParameter]) -> String {
|
||||
return queryParameters
|
||||
.sorted { qp1, qp2 in
|
||||
if qp1.key == qp2.key {
|
||||
return qp1.index < qp2.index
|
||||
}
|
||||
|
||||
// Lexicographically sort components.
|
||||
for (c1, c2) in zip(qp1.key, qp2.key) {
|
||||
if c1 < c2 { return true }
|
||||
else if c1 > c2 { return false }
|
||||
}
|
||||
return true
|
||||
}.compactMap { queryParam in
|
||||
guard
|
||||
let encodedName = percentEncode(string: queryParameterName(from: queryParam.key)),
|
||||
let encodedValue = percentEncode(string: queryParam.serialized)
|
||||
else { return nil }
|
||||
return "\(encodedName)=\(encodedValue)"
|
||||
}.joined(separator: "&")
|
||||
}
|
||||
|
||||
// Helps build nested and exploded query parameters.
|
||||
class QueryParameterBuilder {
|
||||
private var queryParameters: [QueryParameter] = []
|
||||
|
||||
func addQueryParameters(from serializable: Serializable?, named name: String, format: SerializableFormat, parameterDefaults: ParameterDefaults?) throws {
|
||||
guard let serializable = serializable ?? parameterDefaults?.defaultQueryParameter(for: name) else { return }
|
||||
if format.explode {
|
||||
queryParameters.append(
|
||||
contentsOf: try serializable
|
||||
.serializeQueryParameters(with: format)
|
||||
.mapKeys { parameterKey(from: $0, nameOverride: name, with: format) }
|
||||
)
|
||||
} else {
|
||||
queryParameters.append(QueryParameter(key: [name], serialized: try serializable.serialize(with: format)))
|
||||
}
|
||||
}
|
||||
|
||||
func addJSONQueryParameter(named name: String, with encodable: Encodable?) throws {
|
||||
guard let encodable, let encoded = try serializeEncodable(encodable) else { return }
|
||||
queryParameters.append(QueryParameter(key: [name], serialized: encoded))
|
||||
}
|
||||
|
||||
func build() -> [QueryParameter] {
|
||||
return queryParameters
|
||||
}
|
||||
}
|
||||
|
||||
extension Array where Element == QueryParameter {
|
||||
func mapKeys(_ f: ([String]) -> [String]) -> [QueryParameter] {
|
||||
return map { QueryParameter(key: f($0.key), serialized: $0.serialized, index: $0.index) }
|
||||
}
|
||||
}
|
||||
|
||||
private func parameterKey(from key: [String], nameOverride: String, with format: SerializableFormat) -> [String] {
|
||||
if format.isDeep {
|
||||
return [nameOverride] + key
|
||||
} else {
|
||||
return key.isEmpty ? [nameOverride] : key
|
||||
}
|
||||
}
|
||||
|
||||
private let allowedPercentEncodingCharacters = CharacterSet.alphanumerics.union(CharacterSet(charactersIn: "-."))
|
||||
|
||||
private func percentEncode(string: String) -> String? {
|
||||
return string.addingPercentEncoding(withAllowedCharacters: allowedPercentEncodingCharacters)
|
||||
}
|
||||
|
||||
private func queryParameterName(from key: [String]) -> String {
|
||||
guard let first = key.first else { return "" }
|
||||
let rest = key.dropFirst()
|
||||
return "\(first)\(rest.map { "[\($0)]" }.joined())"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
|
||||
enum SecurityParameter {
|
||||
case httpBasic(username: String?, password: String?)
|
||||
case httpBearer(value: String?)
|
||||
case apiKey(name: String, value: String?)
|
||||
case oauth2(name: String, value: String?)
|
||||
case openIdConnect(name: String, value: String?)
|
||||
}
|
||||
|
||||
protocol SecurityParameterProviding {
|
||||
func securityParameters() -> [SecurityParameter]
|
||||
}
|
||||
213
Sources/plexswift/internal/serialization/Serializable.swift
Normal file
213
Sources/plexswift/internal/serialization/Serializable.swift
Normal file
@@ -0,0 +1,213 @@
|
||||
// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
|
||||
|
||||
import Foundation
|
||||
|
||||
enum QueryParameterSerializableStyle {
|
||||
case form
|
||||
case pipeDelimited
|
||||
case deepObject
|
||||
}
|
||||
|
||||
enum SerializableFormat {
|
||||
case path(explode: Bool)
|
||||
case query(style: QueryParameterSerializableStyle, explode: Bool)
|
||||
case header(explode: Bool)
|
||||
case multipart
|
||||
case form(explode: Bool)
|
||||
|
||||
var explode: Bool {
|
||||
switch self {
|
||||
case .path(let explode), .query(_, let explode), .header(let explode), .form(let explode):
|
||||
return explode
|
||||
case .multipart:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var isDeep: Bool {
|
||||
switch self {
|
||||
case .path, .header, .multipart, .form:
|
||||
return false
|
||||
case .query(let style, _):
|
||||
switch style {
|
||||
case .form, .pipeDelimited:
|
||||
return false
|
||||
case .deepObject:
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct QueryParameter {
|
||||
let key: [String]
|
||||
let serialized: String
|
||||
let index: Int
|
||||
|
||||
init(key: [String], serialized: String) {
|
||||
self.key = key
|
||||
self.serialized = serialized
|
||||
self.index = 0
|
||||
}
|
||||
|
||||
init(key: [String], serialized: String, index: Int) {
|
||||
self.key = key
|
||||
self.serialized = serialized
|
||||
self.index = index
|
||||
}
|
||||
}
|
||||
|
||||
enum SerializationError: Swift.Error {
|
||||
case failedToSerializeData
|
||||
case missingRequiredRequestBody
|
||||
case invalidSerializationParameter(type: String, format: String)
|
||||
}
|
||||
|
||||
protocol Serializable {
|
||||
func serialize(with format: SerializableFormat) throws -> String
|
||||
func serializeQueryParameters(with format: SerializableFormat) throws -> [QueryParameter]
|
||||
}
|
||||
|
||||
extension Serializable {
|
||||
func serializeQueryParameters(with format: SerializableFormat) throws -> [QueryParameter] {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Primitives
|
||||
|
||||
extension NSNull: Serializable {
|
||||
func serialize(with format: SerializableFormat) throws -> String {
|
||||
return "null"
|
||||
}
|
||||
|
||||
func serializeQueryParameters(with format: SerializableFormat) throws -> [QueryParameter] {
|
||||
return [QueryParameter(key: [], serialized: try serialize(with: format))]
|
||||
}
|
||||
}
|
||||
|
||||
extension String: Serializable {
|
||||
func serialize(with format: SerializableFormat) throws -> String {
|
||||
return self
|
||||
}
|
||||
|
||||
func serializeQueryParameters(with format: SerializableFormat) throws -> [QueryParameter] {
|
||||
return [QueryParameter(key: [], serialized: try serialize(with: format))]
|
||||
}
|
||||
}
|
||||
|
||||
extension Int: Serializable {
|
||||
func serialize(with format: SerializableFormat) throws -> String {
|
||||
return String(self)
|
||||
}
|
||||
|
||||
func serializeQueryParameters(with format: SerializableFormat) throws -> [QueryParameter] {
|
||||
return [QueryParameter(key: [], serialized: try serialize(with: format))]
|
||||
}
|
||||
}
|
||||
|
||||
extension Double: Serializable {
|
||||
func serialize(with format: SerializableFormat) throws -> String {
|
||||
return String(self)
|
||||
}
|
||||
|
||||
func serializeQueryParameters(with format: SerializableFormat) throws -> [QueryParameter] {
|
||||
return [QueryParameter(key: [], serialized: try serialize(with: format))]
|
||||
}
|
||||
}
|
||||
|
||||
extension Bool: Serializable {
|
||||
func serialize(with format: SerializableFormat) throws -> String {
|
||||
return String(self)
|
||||
}
|
||||
|
||||
func serializeQueryParameters(with format: SerializableFormat) throws -> [QueryParameter] {
|
||||
return [QueryParameter(key: [], serialized: try serialize(with: format))]
|
||||
}
|
||||
}
|
||||
|
||||
extension Data: Serializable {
|
||||
func serialize(with format: SerializableFormat) throws -> String {
|
||||
guard let string = String(data: self, encoding: .ascii) else {
|
||||
throw SerializationError.failedToSerializeData
|
||||
}
|
||||
return string
|
||||
}
|
||||
|
||||
func serializeQueryParameters(with format: SerializableFormat) throws -> [QueryParameter] {
|
||||
return [QueryParameter(key: [], serialized: try serialize(with: format))]
|
||||
}
|
||||
}
|
||||
|
||||
extension Optional: Serializable where Wrapped: Serializable {
|
||||
func serialize(with format: SerializableFormat) throws -> String {
|
||||
return try self?.serialize(with: format) ?? ""
|
||||
}
|
||||
|
||||
func serializeQueryParameters(with format: SerializableFormat) throws -> [QueryParameter] {
|
||||
return try self?.serializeQueryParameters(with: format) ?? []
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Collections
|
||||
|
||||
extension Array: Serializable where Element: Serializable {
|
||||
func serialize(with format: SerializableFormat) throws -> String {
|
||||
return try map { try $0.serialize(with: format) }.joined(separator: format.separator)
|
||||
}
|
||||
|
||||
func serializeQueryParameters(with format: SerializableFormat) throws -> [QueryParameter] {
|
||||
if format.explode {
|
||||
return try enumerated().map { index, value in
|
||||
QueryParameter(key: [], serialized: try value.serialize(with: format), index: index)
|
||||
}
|
||||
} else {
|
||||
return [QueryParameter(key: [], serialized: try serialize(with: format))]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Dictionary: Serializable where Key == String, Value: Serializable {
|
||||
func serialize(with format: SerializableFormat) throws -> String {
|
||||
// Sort by keys first to make serialization deterministic.
|
||||
return try map { key, value in
|
||||
(key, value)
|
||||
}.sorted {
|
||||
$0.0 < $1.0
|
||||
}.map { (key, value) in
|
||||
if format.explode {
|
||||
return "\(key)=\(try value.serialize(with: format))"
|
||||
} else {
|
||||
return "\(key)\(format.separator)\(try value.serialize(with: format))"
|
||||
}
|
||||
}.joined(separator: format.separator)
|
||||
}
|
||||
|
||||
func serializeQueryParameters(with format: SerializableFormat) throws -> [QueryParameter] {
|
||||
if format.explode {
|
||||
return try flatMap { key, value in
|
||||
try value.serializeQueryParameters(with: format).mapKeys { _ in [key] }
|
||||
}
|
||||
} else {
|
||||
return [QueryParameter(key: [], serialized: try serialize(with: format))]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Extensions
|
||||
|
||||
extension SerializableFormat {
|
||||
var separator: String {
|
||||
switch self {
|
||||
case .path, .header, .multipart, .form:
|
||||
return ","
|
||||
case .query(let style, _):
|
||||
switch style {
|
||||
case .form, .deepObject:
|
||||
return ","
|
||||
case .pipeDelimited:
|
||||
return "|"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user