- Extract OAuth UserDefaults keys into shared OAuthKeys enum - Extract triplicated mimeTypeFor() into shared mimeTypeForImage() - Cache normalized base URL at client init instead of per-request
49 lines
1.8 KiB
Swift
49 lines
1.8 KiB
Swift
import Foundation
|
|
|
|
enum URLNormalizer {
|
|
static func normalizeBaseURL(_ input: String, fieldName: String = "URL") throws -> String {
|
|
let trimmed = input.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
guard !trimmed.isEmpty else {
|
|
throw PostingError(message: "\(fieldName) cannot be empty.")
|
|
}
|
|
|
|
let prefixed = if trimmed.hasPrefix("http://") || trimmed.hasPrefix("https://") {
|
|
trimmed
|
|
} else {
|
|
"https://\(trimmed)"
|
|
}
|
|
|
|
guard var components = URLComponents(string: prefixed),
|
|
let scheme = components.scheme?.lowercased(),
|
|
(scheme == "https" || scheme == "http"),
|
|
components.host != nil
|
|
else {
|
|
throw PostingError(message: "Invalid \(fieldName). Please provide a full domain, e.g. example.com.")
|
|
}
|
|
|
|
components.path = ""
|
|
components.query = nil
|
|
components.fragment = nil
|
|
|
|
guard let normalized = components.url?.absoluteString else {
|
|
throw PostingError(message: "Invalid \(fieldName).")
|
|
}
|
|
|
|
return normalized.trimmingCharacters(in: CharacterSet(charactersIn: "/"))
|
|
}
|
|
|
|
static func endpointURL(baseURL: String, path: String, fieldName: String = "URL") throws -> URL {
|
|
let normalizedBase = try normalizeBaseURL(baseURL, fieldName: fieldName)
|
|
guard let url = URL(string: normalizedBase + path) else {
|
|
throw PostingError(message: "Failed to build API URL from \(fieldName).")
|
|
}
|
|
return url
|
|
}
|
|
|
|
static func endpointURL(base normalizedBase: String, path: String) throws -> URL {
|
|
guard let url = URL(string: normalizedBase + path) else {
|
|
throw PostingError(message: "Failed to build API URL.")
|
|
}
|
|
return url
|
|
}
|
|
}
|