Skip to content

Commit 2577099

Browse files
committed
Update lexicon models and methods
1 parent 00b7ffc commit 2577099

File tree

8 files changed

+159
-4
lines changed

8 files changed

+159
-4
lines changed

Sources/ATProtoKit/APIReference/ATProtoBlueskyAPI/FollowRecord/CreateFollowRecord.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@ extension ATProtoBluesky {
1414

1515
/// Creates a follow record to follow a specific user account.
1616
///
17+
/// - Note: A delay of 5 milliseconds is added after the follow record is created; any shorter delay
18+
/// may cause the next request to fail.
19+
///
1720
/// - Parameters:
1821
/// - actorDID: The decentralized identifier (DID) for the user account to follow.
1922
/// - createdAt: The date and time the follow record is created. Defaults to `Date()`.
23+
/// - via: A strong reference to the user account that recommended the followed account. Optional.
2024
/// - recordKey: The record key of the collection. Optional. Defaults to `nil`.
2125
/// - shouldValidate: Indicates whether the record should be validated. Optional.
2226
/// Defaults to `true`.
@@ -27,6 +31,7 @@ extension ATProtoBluesky {
2731
public func createFollowRecord(
2832
actorDID: String,
2933
createdAt: Date = Date(),
34+
via: ComAtprotoLexicon.Repository.StrongReference,
3035
recordKey: String? = nil,
3136
shouldValidate: Bool? = true,
3237
swapCommit: String? = nil
@@ -37,7 +42,8 @@ extension ATProtoBluesky {
3742

3843
let followRecord = AppBskyLexicon.Graph.FollowRecord(
3944
subjectDID: actorDID,
40-
createdAt: createdAt
45+
createdAt: createdAt,
46+
via: via
4147
)
4248

4349
do {
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//
2+
// ComAtprotoLexiconResolveLexiconMethod.swift
3+
// ATProtoKit
4+
//
5+
// Created by Christopher Jr Riley on 2025-11-13.
6+
//
7+
8+
import Foundation
9+
#if canImport(FoundationNetworking)
10+
import FoundationNetworking
11+
#endif
12+
13+
extension ATProtoKit {
14+
15+
/// Maps a Namespaced Identifier (NSID) to its corresponding lexicon schema definition.
16+
///
17+
/// - Note: According to the AT Protocol specifications: "Resolves an atproto lexicon (NSID) to
18+
/// a schema."
19+
///
20+
/// - SeeAlso: This is based on the [`com.atproto.lexicon.resolveLexicon`][github] lexicon.
21+
///
22+
/// [github]: https://github.com/bluesky-social/atproto/blob/main/lexicons/com/atproto/lexicon/resolveLexicon.json
23+
///
24+
/// - Parameter nsid: The lexicon Namespaced Identifier (NSID) to resolve.
25+
/// - Returns: A record containing the resolved lexicon schema, along with the CID and AT-URI assocated
26+
/// with the schema.
27+
///
28+
/// - Throws: An ``ATProtoError``-conforming error type, depending on the issue. Go to
29+
/// ``ATAPIError`` and ``ATRequestPrepareError`` for more details.
30+
public func resolveLexicon(by nsid: String) async throws -> ComAtprotoLexicon.Lexicon.ResolveLexiconOutput {
31+
guard let requestURL = URL(string: "\(self.pdsURL)/xrpc/com.atproto.lexicon.resolveLexicon") else {
32+
throw ATRequestPrepareError.invalidRequestURL
33+
}
34+
35+
var queryItems = [(String, String)]()
36+
37+
queryItems.append(("nsid", nsid))
38+
39+
let queryURL: URL
40+
41+
do {
42+
queryURL = try apiClientService.setQueryItems(
43+
for: requestURL,
44+
with: queryItems
45+
)
46+
47+
let request = apiClientService.createRequest(
48+
forRequest: queryURL,
49+
andMethod: .get,
50+
acceptValue: "application/json",
51+
contentTypeValue: nil,
52+
authorizationValue: nil
53+
)
54+
let response = try await apiClientService.sendRequest(
55+
request,
56+
decodeTo: ComAtprotoLexicon.Lexicon.ResolveLexiconOutput.self
57+
)
58+
59+
return response
60+
} catch {
61+
throw error
62+
}
63+
}
64+
}

Sources/ATProtoKit/ATProtoKit.docc/Extensions/ATProtoBluesky/ATProtoBluesky.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636
### Follows and Blocks
3737

38-
- ``createFollowRecord(actorDID:createdAt:recordKey:shouldValidate:swapCommit:)``
38+
- ``createFollowRecord(actorDID:createdAt:via:recordKey:shouldValidate:swapCommit:)``
3939

4040
- ``createBlockRecord(ofType:createdAt:recordKey:shouldValidate:swapCommit:)``
4141

Sources/ATProtoKit/ATProtoKit.docc/Extensions/Lexicons/Models/com.atproto/ComAtprotoLexicon.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@
55
### com.atproto.lexicon.schema
66

77
- ``SchemaRecord``
8+
9+
### com.atproto.lexicon.resolveLexicon
10+
11+
- ``ResolveLexiconOutput``

Sources/ATProtoKit/Models/Lexicons/app.bsky/Actor/AppBskyActorDefs.swift

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ extension AppBskyLexicon.Actor {
5555
/// The status of the user account. Optional.
5656
public let status: StatusViewDefinition?
5757

58+
/// An internal object used for debugging. Optional.
59+
///
60+
/// - Note: According to the AT Protocol specifications: "Debug information for internal development."
61+
public let debug: UnknownType?
62+
5863
public init(from decoder: any Decoder) throws {
5964
let container = try decoder.container(keyedBy: CodingKeys.self)
6065

@@ -69,6 +74,7 @@ extension AppBskyLexicon.Actor {
6974
self.createdAt = try container.decodeDateIfPresent(forKey: .createdAt)
7075
self.verificationState = try container.decodeIfPresent(VerificationStateDefinition.self, forKey: .verificationState)
7176
self.status = try container.decodeIfPresent(StatusViewDefinition.self, forKey: .status)
77+
self.debug = try container.decodeIfPresent(UnknownType.self, forKey: .debug)
7278
}
7379

7480
public func encode(to encoder: Encoder) throws {
@@ -85,6 +91,7 @@ extension AppBskyLexicon.Actor {
8591
try container.encodeDateIfPresent(self.createdAt, forKey: .createdAt)
8692
try container.encodeIfPresent(self.verificationState, forKey: .verificationState)
8793
try container.encodeIfPresent(self.status, forKey: .status)
94+
try container.encodeIfPresent(self.debug, forKey: .debug)
8895
}
8996

9097
enum CodingKeys: String, CodingKey {
@@ -99,6 +106,7 @@ extension AppBskyLexicon.Actor {
99106
case createdAt
100107
case verificationState = "verification"
101108
case status
109+
case debug
102110
}
103111
}
104112

@@ -156,6 +164,11 @@ extension AppBskyLexicon.Actor {
156164
/// The status of the user account. Optional.
157165
public let status: StatusViewDefinition?
158166

167+
/// An internal object used for debugging. Optional.
168+
///
169+
/// - Note: According to the AT Protocol specifications: "Debug information for internal development."
170+
public let debug: UnknownType?
171+
159172
public init(from decoder: any Decoder) throws {
160173
let container = try decoder.container(keyedBy: CodingKeys.self)
161174

@@ -173,6 +186,7 @@ extension AppBskyLexicon.Actor {
173186
self.labels = try container.decodeIfPresent([ComAtprotoLexicon.Label.LabelDefinition].self, forKey: .labels)
174187
self.verificationState = try container.decodeIfPresent(VerificationStateDefinition.self, forKey: .verificationState)
175188
self.status = try container.decodeIfPresent(StatusViewDefinition.self, forKey: .status)
189+
self.debug = try container.decodeIfPresent(UnknownType.self, forKey: .debug)
176190
}
177191

178192
public func encode(to encoder: Encoder) throws {
@@ -192,6 +206,7 @@ extension AppBskyLexicon.Actor {
192206
try container.encodeIfPresent(self.labels, forKey: .labels)
193207
try container.encodeIfPresent(self.verificationState, forKey: .verificationState)
194208
try container.encodeIfPresent(self.status, forKey: .status)
209+
try container.encodeIfPresent(self.debug, forKey: .debug)
195210
}
196211

197212
enum CodingKeys: String, CodingKey {
@@ -209,6 +224,7 @@ extension AppBskyLexicon.Actor {
209224
case labels
210225
case verificationState = "verification"
211226
case status
227+
case debug
212228
}
213229
}
214230

@@ -281,12 +297,17 @@ extension AppBskyLexicon.Actor {
281297
/// The status of the user account. Optional.
282298
public let status: StatusViewDefinition?
283299

300+
/// An internal object used for debugging. Optional.
301+
///
302+
/// - Note: According to the AT Protocol specifications: "Debug information for internal development."
303+
public let debug: UnknownType?
304+
284305
public init(actorDID: String, actorHandle: String, displayName: String? = nil, pronouns: String? = nil, description: String? = nil,
285306
avatarImageURL: URL? = nil, bannerImageURL: URL? = nil, followerCount: Int? = nil, followCount: Int? = nil, postCount: Int? = nil,
286307
associated: ProfileAssociatedDefinition?, joinedViaStarterPack: AppBskyLexicon.Graph.StarterPackViewBasicDefinition?, indexedAt: Date?,
287308
createdAt: Date?, viewer: ViewerStateDefinition? = nil, labels: [ComAtprotoLexicon.Label.LabelDefinition]? = nil,
288309
pinnedPost: ComAtprotoLexicon.Repository.StrongReference?, verificationState: VerificationStateDefinition? = nil,
289-
status: StatusViewDefinition? = nil) {
310+
status: StatusViewDefinition? = nil, debug: UnknownType? = nil) {
290311
self.actorDID = actorDID
291312
self.actorHandle = actorHandle
292313
self.displayName = displayName
@@ -306,6 +327,7 @@ extension AppBskyLexicon.Actor {
306327
self.pinnedPost = pinnedPost
307328
self.verificationState = verificationState
308329
self.status = status
330+
self.debug = debug
309331
}
310332

311333
public init(from decoder: any Decoder) throws {
@@ -330,6 +352,7 @@ extension AppBskyLexicon.Actor {
330352
self.pinnedPost = try container.decodeIfPresent(ComAtprotoLexicon.Repository.StrongReference.self, forKey: .pinnedPost)
331353
self.verificationState = try container.decodeIfPresent(VerificationStateDefinition.self, forKey: .verificationState)
332354
self.status = try container.decodeIfPresent(StatusViewDefinition.self, forKey: .status)
355+
self.debug = try container.decodeIfPresent(UnknownType.self, forKey: .debug)
333356
}
334357

335358
public func encode(to encoder: Encoder) throws {
@@ -354,6 +377,7 @@ extension AppBskyLexicon.Actor {
354377
try container.encodeIfPresent(self.pinnedPost, forKey: .pinnedPost)
355378
try container.encodeIfPresent(self.verificationState, forKey: .verificationState)
356379
try container.encodeIfPresent(self.status, forKey: .status)
380+
try container.encodeIfPresent(self.debug, forKey: .debug)
357381
}
358382

359383
enum CodingKeys: String, CodingKey {
@@ -376,6 +400,7 @@ extension AppBskyLexicon.Actor {
376400
case pinnedPost
377401
case verificationState = "verification"
378402
case status
403+
case debug
379404
}
380405
}
381406

Sources/ATProtoKit/Models/Lexicons/app.bsky/Feed/AppBskyFeedDefs.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ extension AppBskyLexicon.Feed {
6161
/// The ruleset of who can reply to the post. Optional.
6262
public let threadgate: ThreadgateViewDefinition?
6363

64+
/// An internal object used for debugging. Optional.
65+
///
66+
/// - Note: According to the AT Protocol specifications: "Debug information for internal development."
67+
public let debug: UnknownType?
68+
6469
public init(from decoder: any Decoder) throws {
6570
let container = try decoder.container(keyedBy: CodingKeys.self)
6671

@@ -78,6 +83,7 @@ extension AppBskyLexicon.Feed {
7883
self.viewer = try container.decodeIfPresent(AppBskyLexicon.Feed.ViewerStateDefinition.self, forKey: .viewer)
7984
self.labels = try container.decodeIfPresent([ComAtprotoLexicon.Label.LabelDefinition].self, forKey: .labels)
8085
self.threadgate = try container.decodeIfPresent(AppBskyLexicon.Feed.ThreadgateViewDefinition.self, forKey: .threadgate)
86+
self.debug = try container.decodeIfPresent(UnknownType.self, forKey: .debug)
8187
}
8288

8389
public func encode(to encoder: any Encoder) throws {
@@ -97,6 +103,7 @@ extension AppBskyLexicon.Feed {
97103
try container.encodeIfPresent(self.viewer, forKey: .viewer)
98104
try container.encodeIfPresent(self.labels, forKey: .labels)
99105
try container.encodeIfPresent(self.threadgate, forKey: .threadgate)
106+
try container.encodeIfPresent(self.debug, forKey: .debug)
100107
}
101108

102109
enum CodingKeys: CodingKey {
@@ -114,6 +121,7 @@ extension AppBskyLexicon.Feed {
114121
case viewer
115122
case labels
116123
case threadgate
124+
case debug
117125
}
118126

119127
// Unions

Sources/ATProtoKit/Models/Lexicons/app.bsky/Graph/AppBskyGraphFollow.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,29 +33,36 @@ extension AppBskyLexicon.Graph {
3333
/// The date and time the record was created.
3434
public let createdAt: Date
3535

36-
public init(subjectDID: String, createdAt: Date) {
36+
/// A strong reference to the user account that recommended the followed account. Optional.
37+
public let via: ComAtprotoLexicon.Repository.StrongReference?
38+
39+
public init(subjectDID: String, createdAt: Date, via: ComAtprotoLexicon.Repository.StrongReference?) {
3740
self.subjectDID = subjectDID
3841
self.createdAt = createdAt
42+
self.via = via
3943
}
4044

4145
public init(from decoder: any Decoder) throws {
4246
let container = try decoder.container(keyedBy: CodingKeys.self)
4347

4448
self.subjectDID = try container.decode(String.self, forKey: .subjectDID)
4549
self.createdAt = try container.decodeDate(forKey: .createdAt)
50+
self.via = try container.decodeIfPresent(ComAtprotoLexicon.Repository.StrongReference.self, forKey: .via)
4651
}
4752

4853
public func encode(to encoder: any Encoder) throws {
4954
var container = encoder.container(keyedBy: CodingKeys.self)
5055

5156
try container.encode(self.subjectDID, forKey: .subjectDID)
5257
try container.encodeDate(self.createdAt, forKey: .createdAt)
58+
try container.encodeIfPresent(self.via, forKey: .via)
5359
}
5460

5561
enum CodingKeys: String, CodingKey {
5662
case type = "$type"
5763
case subjectDID = "subject"
5864
case createdAt
65+
case via
5966
}
6067
}
6168
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//
2+
// ComAtprotoLexiconResolveLexicon.swift
3+
// ATProtoKit
4+
//
5+
// Created by Christopher Jr Riley on 2025-11-13.
6+
//
7+
8+
import Foundation
9+
#if canImport(FoundationNetworking)
10+
import FoundationNetworking
11+
#endif
12+
13+
extension ComAtprotoLexicon.Lexicon {
14+
15+
/// An output model for mapping a Namespaced Identifier (NSID) to its corresponding lexicon
16+
/// schema definition.
17+
///
18+
/// - Note: According to the AT Protocol specifications: "Resolves an atproto lexicon (NSID) to
19+
/// a schema."
20+
///
21+
/// - SeeAlso: This is based on the [`com.atproto.lexicon.resolveLexicon`][github] lexicon.
22+
///
23+
/// [github]: https://github.com/bluesky-social/atproto/blob/main/lexicons/com/atproto/lexicon/resolveLexicon.json
24+
public struct ResolveLexiconOutput: Codable, Sendable {
25+
26+
/// The CID that identifies the lexicon schema record.
27+
///
28+
/// - Note: According to the AT Protocol specifications: "The CID of the lexicon schema record."
29+
public let cid: String
30+
31+
/// The lexicon schema record after it has been fully resolved.
32+
///
33+
/// - Note: According to the AT Protocol specifications: "The resolved lexicon schema record."
34+
public let schema: ComAtprotoLexicon.Lexicon.SchemaRecord
35+
36+
/// The AT-URI that points to the lexicon schema record.
37+
///
38+
/// - Note: According to the AT Protocol specifications: "The AT-URI of the lexicon schema record."
39+
public let uri: String
40+
}
41+
}

0 commit comments

Comments
 (0)