89 lines
2.8 KiB
Swift
89 lines
2.8 KiB
Swift
//
|
|
// FervorClient.swift
|
|
// Fervor
|
|
//
|
|
// Created by Shadowfacts on 11/25/21.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
public class FervorClient {
|
|
|
|
let instanceURL: URL
|
|
let session: URLSession
|
|
public var accessToken: String?
|
|
|
|
private let decoder: JSONDecoder = {
|
|
let d = JSONDecoder()
|
|
d.dateDecodingStrategy = .iso8601
|
|
return d
|
|
}()
|
|
|
|
public init(instanceURL: URL, accessToken: String?, session: URLSession = .shared) {
|
|
self.instanceURL = instanceURL
|
|
self.accessToken = accessToken
|
|
self.session = session
|
|
}
|
|
|
|
private func buildURL(path: String) -> URL {
|
|
var components = URLComponents(url: instanceURL, resolvingAgainstBaseURL: false)!
|
|
components.path = path
|
|
return components.url!
|
|
}
|
|
|
|
private func performRequest<T: Decodable>(_ request: URLRequest) async throws -> T {
|
|
var request = request
|
|
if let accessToken = accessToken {
|
|
request.addValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
|
|
}
|
|
let (data, _) = try await session.data(for: request, delegate: nil)
|
|
let decoded = try decoder.decode(T.self, from: data)
|
|
return decoded
|
|
}
|
|
|
|
public func register(clientName: String, website: URL? = nil, redirectURI: URL) async throws -> ClientRegistration {
|
|
var request = URLRequest(url: buildURL(path: "/api/v1/register"))
|
|
request.httpMethod = "POST"
|
|
request.setURLEncodedBody(params: [
|
|
"client_name": clientName,
|
|
"website": website?.absoluteString,
|
|
"redirect_uri": redirectURI.absoluteString,
|
|
])
|
|
return try await performRequest(request)
|
|
}
|
|
|
|
public func token(authCode: String, redirectURI: URL, clientID: String, clientSecret: String) async throws -> Token {
|
|
var request = URLRequest(url: buildURL(path: "/oauth/token"))
|
|
request.httpMethod = "POST"
|
|
request.setURLEncodedBody(params: [
|
|
"grant_type": "authorization_code",
|
|
"authorization_code": authCode,
|
|
"redirect_uri": redirectURI.absoluteString,
|
|
"client_id": clientID,
|
|
"client_secret": clientSecret,
|
|
])
|
|
return try await performRequest(request)
|
|
}
|
|
|
|
public func groups() async throws -> [Group] {
|
|
let request = URLRequest(url: buildURL(path: "/api/v1/groups"))
|
|
return try await performRequest(request)
|
|
}
|
|
|
|
public func feeds() async throws -> [Feed] {
|
|
let request = URLRequest(url: buildURL(path: "/api/v1/feeds"))
|
|
return try await performRequest(request)
|
|
}
|
|
|
|
public struct Auth {
|
|
public let accessToken: String
|
|
public let refreshToken: String?
|
|
}
|
|
|
|
public enum Error: Swift.Error {
|
|
case urlSession(Swift.Error)
|
|
case decode(Swift.Error)
|
|
}
|
|
|
|
}
|