Files
wehub-resource-sync a789495a98
FreeBSD Smoke / FreeBSD Smoke (x86_64) (push) Has been cancelled
CI / Quality Guardrails (push) Has been cancelled
CI / Build & Test (macos-latest) (push) Has been cancelled
CI / Build & Test (ubuntu-latest) (push) Has been cancelled
CI / Build & Test (windows-latest) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / PowerShell Syntax (push) Has been cancelled
CI / Windows Cross-Target Check (Linux) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:34 +08:00

76 lines
2.5 KiB
Swift

import Foundation
/// Describes a jcode server gateway endpoint.
///
/// The server exposes:
/// - `GET http://host:port/health` reachability + version probe
/// - `POST http://host:port/pair` pairing-code -> auth-token exchange
/// - `ws://host:port/ws` newline-delimited JSON protocol over WebSocket
public struct Gateway: Hashable, Sendable {
public static let defaultPort: UInt16 = 7643
public var host: String
public var port: UInt16
public init(host: String, port: UInt16 = Gateway.defaultPort) {
self.host = host
self.port = port
}
public var healthURL: URL {
url(scheme: "http", path: "/health")
}
public var pairURL: URL {
url(scheme: "http", path: "/pair")
}
public var webSocketURL: URL {
url(scheme: "ws", path: "/ws")
}
private func url(scheme: String, path: String) -> URL {
var components = URLComponents()
components.scheme = scheme
components.host = host
components.port = Int(port)
components.path = path
guard let url = components.url else {
// Host strings from pairing are validated before reaching here;
// a failure indicates programmer error.
preconditionFailure("invalid gateway endpoint: \(scheme)://\(host):\(port)\(path)")
}
return url
}
}
/// Parses `jcode://pair?host=H&port=P&code=C` URIs from QR codes.
public enum PairURI {
public struct Payload: Equatable, Sendable {
public var gateway: Gateway
public var code: String
public init(gateway: Gateway, code: String) {
self.gateway = gateway
self.code = code
}
}
public static func parse(_ string: String) -> Payload? {
guard let components = URLComponents(string: string),
components.scheme == "jcode",
components.host == "pair" || components.path == "pair"
|| components.host == nil && components.path == "/pair"
else { return nil }
let items = components.queryItems ?? []
func value(_ name: String) -> String? {
items.first(where: { $0.name == name })?.value
}
guard let host = value("host"), !host.isEmpty,
let code = value("code"), !code.isEmpty
else { return nil }
let port = value("port").flatMap(UInt16.init) ?? Gateway.defaultPort
return Payload(gateway: Gateway(host: host, port: port), code: code)
}
}