import Foundation /// A release is a representation of a downloadable update. public struct Release: Codable { /// The user-facing name of the release. Typically "Secretive 1.2.3" public let name: String /// A boolean describing whether or not the release is a prerelase build. public let prerelease: Bool /// A URL pointing to the HTML page for the release. public let html_url: URL /// A user-facing description of the contents of the update. public let body: String /// Initializes a Release. /// - Parameters: /// - name: The user-facing name of the release. /// - prerelease: A boolean describing whether or not the release is a prerelase build. /// - html_url: A URL pointing to the HTML page for the release. /// - body: A user-facing description of the contents of the update. public init(name: String, prerelease: Bool, html_url: URL, body: String) { self.name = name self.prerelease = prerelease self.html_url = html_url self.body = body } } extension Release: Identifiable { public var id: String { html_url.absoluteString } } extension Release: Comparable { public static func < (lhs: Release, rhs: Release) -> Bool { lhs.version < rhs.version } } extension Release { /// A boolean describing whether or not the release contains critical security content. /// - Note: this is determined by the presence of the phrase "Critical Security Update" in the ``body``. /// - Warning: If this property is true, the user will not be able to dismiss UI or reminders associated with the update. public var critical: Bool { body.contains(Constants.securityContent) } /// A ``SemVer`` representation of the version number of the release. public var version: SemVer { SemVer(name) } /// The minimum macOS version required to run the update. public var minimumOSVersion: SemVer { guard let range = body.range(of: "Minimum macOS Version"), let numberStart = body.rangeOfCharacter(from: CharacterSet.decimalDigits, options: [], range: range.upperBound..