GoAT Site is library that implements Standard.site in Go.
atprotocol standard-site atproto library
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

style(xrpc): move methods in new file

authored by

Anhgelus Morhtuuzh and committed by tangled.org 2f10d5aa 62b7520a

+141 -136
+2 -2
document.go
··· 173 173 // We don't use /> to end the tag, because it is only valid for HTML5 and only required for XHTML. 174 174 // See https://blog.novalistic.com/archives/2017/08/optional-end-tags-in-html/ 175 175 return template.HTML( 176 - fmt.Sprintf(`<link rel="%s" href="%s">`, CollectionDocument, createAtURI(repo, CollectionDocument, rkey)), 176 + fmt.Sprintf(`<link rel="%s" href="%s">`, CollectionDocument, createAtURL(repo, CollectionDocument, rkey)), 177 177 ) 178 178 } 179 179 180 180 // getPublicationVerification returns the string used during the verification of the [Publication]. 181 181 func getDocumentVerification(repo syntax.AtIdentifier, rkey syntax.RecordKey) string { 182 - return createAtURI(repo, CollectionDocument, rkey) 182 + return createAtURL(repo, CollectionDocument, rkey).String() 183 183 }
-133
lexicons.go
··· 1 1 package site 2 2 3 3 import ( 4 - "context" 5 4 "encoding/json" 6 5 "errors" 7 6 "fmt" 8 7 "time" 9 - 10 - "github.com/bluesky-social/indigo/api/agnostic" 11 - "github.com/bluesky-social/indigo/api/atproto" 12 - "github.com/bluesky-social/indigo/atproto/syntax" 13 - lexutil "github.com/bluesky-social/indigo/lex/util" 14 8 ) 15 9 16 10 // Record represents an ATProto record. ··· 189 183 b.CID = v.Ref.Link 190 184 return nil 191 185 } 192 - 193 - // MaxItemsPerList is the number of items per list call. 194 - const MaxItemsPerList = 25 195 - 196 - // Result is returned when after creating a record. 197 - type Result struct { 198 - URI string 199 - CID string 200 - ValidationStatus *string 201 - Commit *agnostic.RepoDefs_CommitMeta 202 - } 203 - 204 - // GetRecord returns the [Record] in the repo associated with the rkey. 205 - // Automatically uses the latest CID. 206 - // 207 - // Returns [ErrInvalidType] if the [Record] got doesn't have a valid type. 208 - func GetRecord[T Record](ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, rkey syntax.RecordKey) (t T, err error) { 209 - var rec *agnostic.RepoGetRecord_Output 210 - rec, err = agnostic.RepoGetRecord(ctx, client, "", t.Type(), repo.String(), rkey.String()) 211 - if err != nil { 212 - return 213 - } 214 - var v *RecordJSON 215 - err = json.Unmarshal(*rec.Value, &v) 216 - if err != nil { 217 - return 218 - } 219 - if v.GetType() != t.Type() { 220 - err = ErrInvalidType{t.Type(), v.Type} 221 - return 222 - } 223 - return v.Record.(T), nil 224 - } 225 - 226 - // ListRecords returns all the [Record]s stored in the repo and the cursor. 227 - // 228 - // Returns [ErrInvalidType] if a [Record] got doesn't have a valid type. 229 - // 230 - // See [MaxItemsPerList]. 231 - func ListRecords[T Record](ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, cursor string, reverse bool) ([]T, *string, error) { 232 - var t T 233 - rec, err := agnostic.RepoListRecords(ctx, client, t.Type(), cursor, MaxItemsPerList, repo.String(), reverse) 234 - if err != nil { 235 - return nil, nil, err 236 - } 237 - docs := make([]T, MaxItemsPerList) 238 - i := 0 239 - for i = range len(rec.Records) { 240 - r := rec.Records[i] 241 - var v *RecordJSON 242 - err = json.Unmarshal(*r.Value, &v) 243 - if err != nil { 244 - return nil, nil, err 245 - } 246 - if v.GetType() != t.Type() { 247 - return nil, nil, ErrInvalidType{t.Type(), v.Type} 248 - } 249 - docs[i] = v.Record.(T) 250 - } 251 - return docs[:i], rec.Cursor, nil 252 - } 253 - 254 - // CreateRecord in a repo with the given rkey. 255 - // Always tries to validate the [Record] against the lexicon saved. 256 - // 257 - // Rkey can be nil. 258 - func CreateRecord[T Record](ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, rkey *syntax.RecordKey, v T) (*Result, error) { 259 - mp, err := MarshalToMap(AsJSON(v)) 260 - if err != nil { 261 - return nil, err 262 - } 263 - var cv *string 264 - if rkey != nil { 265 - t := rkey.String() 266 - cv = &t 267 - } 268 - t := true 269 - out, err := agnostic.RepoCreateRecord(ctx, client, &agnostic.RepoCreateRecord_Input{ 270 - Collection: v.Type(), 271 - Record: mp, 272 - Repo: repo.String(), 273 - Rkey: cv, 274 - Validate: &t, 275 - }) 276 - if err != nil { 277 - return nil, err 278 - } 279 - return &Result{out.Uri, out.Cid, out.ValidationStatus, out.Commit}, nil 280 - } 281 - 282 - // UpdateRecord in a repo with the given rkey. 283 - // Always tries to validate the [Record] against the lexicon saved. 284 - func UpdateRecord[T Record](ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, rkey syntax.RecordKey, v T) (*Result, error) { 285 - mp, err := MarshalToMap(AsJSON(v)) 286 - if err != nil { 287 - return nil, err 288 - } 289 - t := true 290 - out, err := agnostic.RepoPutRecord(ctx, client, &agnostic.RepoPutRecord_Input{ 291 - Collection: v.Type(), 292 - Record: mp, 293 - Repo: repo.String(), 294 - Rkey: rkey.String(), 295 - Validate: &t, 296 - //SwapRecord: &cid, 297 - }) 298 - if err != nil { 299 - return nil, err 300 - } 301 - return &Result{out.Uri, out.Cid, out.ValidationStatus, out.Commit}, nil 302 - } 303 - 304 - // DeleteRecord in a repo with the given rkey. 305 - func DeleteRecord[T Record](ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, rkey syntax.RecordKey) error { 306 - var t T 307 - _, err := atproto.RepoDeleteRecord(ctx, client, &atproto.RepoDeleteRecord_Input{ 308 - Collection: t.Type(), 309 - Repo: repo.String(), 310 - Rkey: rkey.String(), 311 - }) 312 - return err 313 - } 314 - 315 - // createAtURI returns a valid [syntax.ATURI]. 316 - func createAtURI(repo syntax.AtIdentifier, collection string, rkey syntax.RecordKey) string { 317 - return fmt.Sprintf("at://%s/%s/%s", repo, collection, rkey) 318 - }
+1 -1
publication.go
··· 100 100 101 101 // getPublicationVerification returns the string used during the verification of the [Publication]. 102 102 func getPublicationVerification(repo syntax.AtIdentifier, rkey syntax.RecordKey) string { 103 - return createAtURI(repo, CollectionPublication, rkey) 103 + return createAtURL(repo, CollectionPublication, rkey).String() 104 104 } 105 105 106 106 // HandlePublicationVerification returns an [http.Handler] used during the verification of the [Publication].
+138
xrpc.go
··· 1 + package site 2 + 3 + import ( 4 + "context" 5 + "encoding/json" 6 + 7 + "github.com/bluesky-social/indigo/api/agnostic" 8 + "github.com/bluesky-social/indigo/api/atproto" 9 + "github.com/bluesky-social/indigo/atproto/syntax" 10 + lexutil "github.com/bluesky-social/indigo/lex/util" 11 + ) 12 + 13 + // MaxItemsPerList is the number of items per list call. 14 + const MaxItemsPerList = 25 15 + 16 + // Result is returned when after creating a record. 17 + type Result struct { 18 + URI string 19 + CID string 20 + ValidationStatus *string 21 + Commit *agnostic.RepoDefs_CommitMeta 22 + } 23 + 24 + // GetRecord returns the [Record] in the repo associated with the rkey. 25 + // Automatically uses the latest CID. 26 + // 27 + // Returns [ErrInvalidType] if the [Record] got doesn't have a valid type. 28 + func GetRecord[T Record](ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, rkey syntax.RecordKey) (t T, err error) { 29 + var rec *agnostic.RepoGetRecord_Output 30 + rec, err = agnostic.RepoGetRecord(ctx, client, "", t.Type(), repo.String(), rkey.String()) 31 + if err != nil { 32 + return 33 + } 34 + var v *RecordJSON 35 + err = json.Unmarshal(*rec.Value, &v) 36 + if err != nil { 37 + return 38 + } 39 + if v.GetType() != t.Type() { 40 + err = ErrInvalidType{t.Type(), v.Type} 41 + return 42 + } 43 + return v.Record.(T), nil 44 + } 45 + 46 + // ListRecords returns all the [Record]s stored in the repo and the cursor. 47 + // 48 + // Returns [ErrInvalidType] if a [Record] got doesn't have a valid type. 49 + // 50 + // See [MaxItemsPerList]. 51 + func ListRecords[T Record](ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, cursor string, reverse bool) ([]T, *string, error) { 52 + var t T 53 + rec, err := agnostic.RepoListRecords(ctx, client, t.Type(), cursor, MaxItemsPerList, repo.String(), reverse) 54 + if err != nil { 55 + return nil, nil, err 56 + } 57 + docs := make([]T, MaxItemsPerList) 58 + i := 0 59 + for i = range len(rec.Records) { 60 + r := rec.Records[i] 61 + var v *RecordJSON 62 + err = json.Unmarshal(*r.Value, &v) 63 + if err != nil { 64 + return nil, nil, err 65 + } 66 + if v.GetType() != t.Type() { 67 + return nil, nil, ErrInvalidType{t.Type(), v.Type} 68 + } 69 + docs[i] = v.Record.(T) 70 + } 71 + return docs[:i], rec.Cursor, nil 72 + } 73 + 74 + // CreateRecord in a repo with the given rkey. 75 + // Always tries to validate the [Record] against the lexicon saved. 76 + // 77 + // Rkey can be nil. 78 + func CreateRecord[T Record](ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, rkey *syntax.RecordKey, v T) (*Result, error) { 79 + mp, err := MarshalToMap(AsJSON(v)) 80 + if err != nil { 81 + return nil, err 82 + } 83 + var cv *string 84 + if rkey != nil { 85 + t := rkey.String() 86 + cv = &t 87 + } 88 + t := true 89 + out, err := agnostic.RepoCreateRecord(ctx, client, &agnostic.RepoCreateRecord_Input{ 90 + Collection: v.Type(), 91 + Record: mp, 92 + Repo: repo.String(), 93 + Rkey: cv, 94 + Validate: &t, 95 + }) 96 + if err != nil { 97 + return nil, err 98 + } 99 + return &Result{out.Uri, out.Cid, out.ValidationStatus, out.Commit}, nil 100 + } 101 + 102 + // UpdateRecord in a repo with the given rkey. 103 + // Always tries to validate the [Record] against the lexicon saved. 104 + func UpdateRecord[T Record](ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, rkey syntax.RecordKey, v T) (*Result, error) { 105 + mp, err := MarshalToMap(AsJSON(v)) 106 + if err != nil { 107 + return nil, err 108 + } 109 + t := true 110 + out, err := agnostic.RepoPutRecord(ctx, client, &agnostic.RepoPutRecord_Input{ 111 + Collection: v.Type(), 112 + Record: mp, 113 + Repo: repo.String(), 114 + Rkey: rkey.String(), 115 + Validate: &t, 116 + //SwapRecord: &cid, 117 + }) 118 + if err != nil { 119 + return nil, err 120 + } 121 + return &Result{out.Uri, out.Cid, out.ValidationStatus, out.Commit}, nil 122 + } 123 + 124 + // DeleteRecord in a repo with the given rkey. 125 + func DeleteRecord[T Record](ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, rkey syntax.RecordKey) error { 126 + var t T 127 + _, err := atproto.RepoDeleteRecord(ctx, client, &atproto.RepoDeleteRecord_Input{ 128 + Collection: t.Type(), 129 + Repo: repo.String(), 130 + Rkey: rkey.String(), 131 + }) 132 + return err 133 + } 134 + 135 + // createAtURL returns a valid [syntax.ATURI]. 136 + func createAtURL(repo syntax.AtIdentifier, collection string, rkey syntax.RecordKey) *ATURL { 137 + return &ATURL{syntax.ATURI("at://" + repo.String() + "/" + collection + "/" + rkey.String())} 138 + }