Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions Sources/ATResolve/ATResolver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ enum ATResolverError: Error {
case requestFailed
}

struct XRPCError: Decodable, Error {
let error: String
let message: String?
}

public struct ResolvedData: Codable, Hashable, Sendable {
public let did: String
public let handle: String
Expand Down Expand Up @@ -61,16 +66,23 @@ public struct ATResolver<Provider: ResponseProviding> {
return did
}

return try await blueskyGetProfile(handle).did
return try await blueskyGetProfile(handle)?.did
}

public func blueskyGetProfile(_ actor: String) async throws -> BlueskyProfile {
try await provider.decodeJSON(
host: "public.api.bsky.app",
path: "/xrpc/app.bsky.actor.getProfile",
headers: ["Accept": "application/json"],
queryItems: [("actor", actor)]
)
public func blueskyGetProfile(_ actor: String) async throws -> BlueskyProfile? {
do {
return try await provider.decodeJSON(
host: "public.api.bsky.app",
path: "/xrpc/app.bsky.actor.getProfile",
headers: ["Accept": "application/json"],
queryItems: [("actor", actor)]
)
} catch let error as XRPCError
where error.error == "InvalidRequest" &&
(error.message?.localizedCaseInsensitiveContains("not found") == true ||
error.message?.localizedCaseInsensitiveContains("invalid app.bsky.actor.getProfile params") == true) {
return nil
}
}

public func plcDirectoryQuery(
Expand All @@ -87,7 +99,6 @@ public struct ATResolver<Provider: ResponseProviding> {
guard let did = try await didForHandle(handle) else {
return nil
}

print("did: \(did)")
let directoryResult = try await plcDirectoryQuery(did)

Expand Down
7 changes: 5 additions & 2 deletions Sources/ATResolve/Networking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ extension URLSession: ResponseProviding {
else {
print("data:", String(decoding: data, as: UTF8.self))
print("response:", response)

throw ATResolverError.requestFailed
if let xrpcError = try? JSONDecoder().decode(XRPCError.self, from: data) {
throw xrpcError
} else {
throw ATResolverError.requestFailed
}
}
return data
}
Expand Down
22 changes: 20 additions & 2 deletions Tests/ATResolveTests/ATResolveTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,33 @@ struct ATResolveTests {

let profile = try await resolver.blueskyGetProfile("massicotte.org")

#expect(profile.did == "did:plc:klsh7edzj3jmxucibyjqstb3")
#expect(profile?.did == "did:plc:klsh7edzj3jmxucibyjqstb3")
}

@Test
func blueskyGetProfileWithNonexistentHandle() async throws {
let resolver = ATResolver(provider: URLSession.shared)

let profile = try await resolver.blueskyGetProfile("nonexistent.example.com")

#expect(profile == nil)
}

@Test
func blueskyGetProfileReturnsNilForInvalidFormatHandle() async throws {
let resolver = ATResolver(provider: URLSession.shared)

let profile = try await resolver.blueskyGetProfile("[email protected]")

#expect(profile == nil)
}

@Test func bskySocialHandle() async throws {
let resolver = ATResolver(provider: URLSession.shared)

let profile = try await resolver.resolveHandle("cjrdev.bsky.social")

#expect(profile != nil)
#expect(profile?.did == "did:plc:wlef3srsa3hlyzj2hy6yncrh")
}

@Test func decodeWithCustomProvider() async throws {
Expand Down
Loading