johnandersen777.bsky.social/knotless
git that lives in your Atmosphere account
Forked from chadtmiller.com/knotless
0
0
import Foundation
/// Where some Markdown is written, so a picture it names can be found: inside
/// its repository as the pages resolve one, and from the server when it's one
/// a pull, issue or comment attaches.
struct MarkdownPlace: Hashable, Sendable {
let repo: RepoRef
/// The branch a file was read at; none for what's written about the repository.
var ref: String?
/// The pull, issue or comment that says it.
var subject: String?
static let site = "https://knotless.dev"
/// Where to look for the picture `dest` names, best first.
func pictures(_ dest: String) -> [URL] {
let scheme = dest.split(separator: ":", maxSplits: 1).first.map(String.init)
if let scheme, dest.contains(":"), !scheme.contains(where: { "/#?".contains($0) }) {
guard ["http", "https"].contains(scheme.lowercased()), let url = URL(string: dest) else { return [] }
return (attached(url).map { [$0] } ?? []) + [url]
}
if dest.hasPrefix("#") { return [] }
let cut = dest.firstIndex { "?#".contains($0) } ?? dest.endIndex
var parts: [Substring] = []
for part in dest[..<cut].split(separator: "/") {
if part == ".." {
_ = parts.popLast()
} else if part != "." {
parts.append(part)
}
}
let root = [repo.handle, repo.name] + (ref.map { ["raw", $0] } ?? [])
let path = (root + parts.map(String.init)).joined(separator: "/")
return URL(string: "\(Self.site)/\(path)\(dest[cut...])").map { [$0] } ?? []
}
/// Where the server shows a blob this subject's author attached, which is
/// how a member reads one of a private repository's.
private func attached(_ url: URL) -> URL? {
guard url.path.hasSuffix("/xrpc/com.atproto.sync.getBlob"),
let subject,
let asked = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems,
let did = asked.first(where: { $0.name == "did" })?.value,
let cid = asked.first(where: { $0.name == "cid" })?.value,
subject.hasPrefix("at://\(did)/"),
var parts = URLComponents(string: "\(Self.site)/xrpc/dev.knotless.getAttachment")
else { return nil }
parts.queryItems = [.init(name: "repo", value: repo.uri), .init(name: "uri", value: subject), .init(name: "cid", value: cid)]
return parts.url
}
}