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.

feat(xrpc): publication crud

+123 -34
+2 -2
document.go
··· 116 116 } 117 117 118 118 // CreateDocument in a repo with the given rkey. 119 - // Always tries to validate the [Document] against the [Record] saved. 119 + // Always tries to validate the [Document] against the lexicon saved. 120 120 // 121 121 // Rkey can be nil. 122 122 func CreateDocument(ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, rkey *syntax.RecordKey, doc *Document) (*Result, error) { ··· 124 124 } 125 125 126 126 // UpdateDocument in a repo with the given rkey. 127 - // Always tries to validate the [Document] against the [Record] saved. 127 + // Always tries to validate the [Document] against the lexicon saved. 128 128 func UpdateDocument(ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, rkey syntax.RecordKey, doc *Document) (*Result, error) { 129 129 return updateRecord(ctx, client, CollectionDocument, repo, rkey, doc) 130 130 }
+2 -29
document_test.go
··· 7 7 "testing" 8 8 "time" 9 9 10 - "github.com/bluesky-social/indigo/atproto/atclient" 11 - "github.com/bluesky-social/indigo/atproto/identity" 12 10 "github.com/bluesky-social/indigo/atproto/syntax" 13 11 lexutil "github.com/bluesky-social/indigo/lex/util" 14 12 site "tangled.org/anhgelus.world/goat-site" ··· 66 64 docClient *lexutil.LexClient 67 65 ) 68 66 69 - func getClient(t *testing.T) (syntax.ATURI, lexutil.LexClient) { 70 - var err error 71 - defer func() { 72 - if err == nil { 73 - t.Log(docURI.String()) 74 - } 75 - }() 76 - if docClient != nil { 77 - return docURI, *docClient 78 - } 79 - dir := identity.DefaultDirectory() 80 - docURI, err = syntax.ParseATURI(testDoc) 81 - if err != nil { 82 - t.Fatal(err) 83 - } 84 - var id *identity.Identity 85 - id, err = dir.Lookup(context.Background(), docURI.Authority()) 86 - if err != nil { 87 - t.Fatal(err) 88 - } 89 - client := lexutil.LexClient(atclient.NewAPIClient(id.PDSEndpoint())) 90 - docClient = &client 91 - return docURI, *docClient 92 - } 93 - 94 67 func TestGetDocument(t *testing.T) { 95 68 if testing.Short() { 96 69 t.Skip() 97 70 } 98 - uri, client := getClient(t) 71 + uri, client := getClient(t, testDoc, &docURI, &docClient) 99 72 doc, err := site.GetDocument(context.Background(), client, uri.Authority(), uri.RecordKey()) 100 73 if err != nil { 101 74 t.Fatal(err) ··· 109 82 if testing.Short() { 110 83 t.Skip() 111 84 } 112 - uri, client := getClient(t) 85 + uri, client := getClient(t, testDoc, &docURI, &docClient) 113 86 docs, _, err := site.ListDocuments(context.Background(), client, uri.Authority(), "", false) 114 87 if err != nil { 115 88 t.Fatal(err)
+9 -2
lexicons.go
··· 161 161 err = ErrInvalidType{collection, v.Type} 162 162 return 163 163 } 164 + if v.Record.Type() != collection { 165 + err = ErrInvalidType{collection, v.Record.Type()} 166 + return 167 + } 164 168 return v.Record.(T), nil 165 169 } 166 170 ··· 184 188 if v.Record == nil { 185 189 return nil, nil, ErrInvalidType{collection, v.Type} 186 190 } 191 + if v.Record.Type() != collection { 192 + return nil, nil, ErrInvalidType{collection, v.Record.Type()} 193 + } 187 194 docs[i] = v.Record.(T) 188 195 i++ 189 196 } ··· 191 198 } 192 199 193 200 // createRecord a T in a repo with the given rkey. 194 - // Always tries to validate the [Document] against the [Record] saved. 201 + // Always tries to validate the [Document] against the lexicon saved. 195 202 // 196 203 // Rkey can be nil. 197 204 func createRecord[T Record](ctx context.Context, client lexutil.LexClient, collection string, repo syntax.AtIdentifier, rkey *syntax.RecordKey, v T) (*Result, error) { ··· 219 226 } 220 227 221 228 // updateRecord T in a repo with the given rkey. 222 - // Always tries to validate the [Document] against the [Record] saved. 229 + // Always tries to validate the [Document] against the lexicon saved. 223 230 func updateRecord[T Record](ctx context.Context, client lexutil.LexClient, collection string, repo syntax.AtIdentifier, rkey syntax.RecordKey, v T) (*Result, error) { 224 231 mp, err := MarshalToMap(&RecordJSON{Record: v}) 225 232 if err != nil {
+39 -1
publication.go
··· 1 1 package site 2 2 3 - import "strings" 3 + import ( 4 + "context" 5 + "strings" 6 + 7 + "github.com/bluesky-social/indigo/atproto/syntax" 8 + lexutil "github.com/bluesky-social/indigo/lex/util" 9 + ) 4 10 5 11 const CollectionPublication = CollectionBase + ".publication" 6 12 ··· 48 54 // ShowInDiscover decides whether the [Publication] should appear in discovery feeds. 49 55 ShowInDiscover bool `json:"showInDiscover"` 50 56 } 57 + 58 + // GetPublication returns the [Publication] in the repo associated with the rkey. 59 + // Automatically uses the latest CID. 60 + func GetPublication(ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, rkey syntax.RecordKey) (*Publication, error) { 61 + return get[*Publication](ctx, client, CollectionPublication, repo, rkey) 62 + } 63 + 64 + // ListPublications returns all the [Publication]s stored in the repo and the cursor. 65 + // 66 + // See [MaxItemsPerList]. 67 + func ListPublications(ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, cursor string, reverse bool) ([]*Publication, *string, error) { 68 + return listRecord[*Publication](ctx, client, CollectionPublication, repo, cursor, reverse) 69 + } 70 + 71 + // CreatePublication in a repo with the given rkey. 72 + // Always tries to validate the [Publication] against the lexicon saved. 73 + // 74 + // Rkey can be nil. 75 + func CreatePublication(ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, rkey *syntax.RecordKey, pub *Publication) (*Result, error) { 76 + return createRecord(ctx, client, CollectionPublication, repo, rkey, pub) 77 + } 78 + 79 + // UpdatePublication in a repo with the given rkey. 80 + // Always tries to validate the [Publication] against the lexicon saved. 81 + func UpdatePublication(ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, rkey syntax.RecordKey, pub *Publication) (*Result, error) { 82 + return updateRecord(ctx, client, CollectionPublication, repo, rkey, pub) 83 + } 84 + 85 + // DeletePublication in a repo with the given rkey. 86 + func DeletePublication(ctx context.Context, client lexutil.LexClient, repo syntax.AtIdentifier, rkey syntax.RecordKey) error { 87 + return deleteRecord(ctx, client, CollectionPublication, repo, rkey) 88 + }
+71
publication_test.go
··· 1 1 package site_test 2 2 3 3 import ( 4 + "context" 4 5 "encoding/json" 5 6 "testing" 6 7 8 + "github.com/bluesky-social/indigo/atproto/atclient" 9 + "github.com/bluesky-social/indigo/atproto/identity" 10 + "github.com/bluesky-social/indigo/atproto/syntax" 11 + lexutil "github.com/bluesky-social/indigo/lex/util" 7 12 site "tangled.org/anhgelus.world/goat-site" 8 13 ) 9 14 ··· 119 124 } 120 125 t.Log(string(b)) 121 126 } 127 + 128 + const testPub = "at://did:plc:yk4dd2qkboz2yv6tpubpc6co/site.standard.publication/3m6zrpzbs3s2y" 129 + 130 + var ( 131 + pubURI syntax.ATURI 132 + pubClient *lexutil.LexClient 133 + ) 134 + 135 + func getClient(t *testing.T, test string, uri *syntax.ATURI, client **lexutil.LexClient) (syntax.ATURI, lexutil.LexClient) { 136 + var err error 137 + defer func() { 138 + if err == nil { 139 + t.Log(uri.Authority().String(), uri.RecordKey()) 140 + } 141 + }() 142 + if *client != nil { 143 + return *uri, **client 144 + } 145 + dir := identity.DefaultDirectory() 146 + *uri, err = syntax.ParseATURI(test) 147 + if err != nil { 148 + t.Fatal(err) 149 + } 150 + var id *identity.Identity 151 + id, err = dir.Lookup(context.Background(), uri.Authority()) 152 + if err != nil { 153 + t.Fatal(err) 154 + } 155 + t.Log("using", id.PDSEndpoint(), "for", test) 156 + c := lexutil.LexClient(atclient.NewAPIClient(id.PDSEndpoint())) 157 + *client = &c 158 + return *uri, **client 159 + } 160 + 161 + func TestGetPublication(t *testing.T) { 162 + if testing.Short() { 163 + t.Skip() 164 + } 165 + uri, client := getClient(t, testPub, &pubURI, &pubClient) 166 + pub, err := site.GetPublication(context.Background(), client, uri.Authority(), uri.RecordKey()) 167 + if err != nil { 168 + t.Fatal(err) 169 + } 170 + if pub == nil { 171 + t.Errorf("pub is nil") 172 + } 173 + } 174 + 175 + func TestListPublications(t *testing.T) { 176 + if testing.Short() { 177 + t.Skip() 178 + } 179 + uri, client := getClient(t, testPub, &pubURI, &pubClient) 180 + pubs, _, err := site.ListDocuments(context.Background(), client, uri.Authority(), "", false) 181 + if err != nil { 182 + t.Fatal(err) 183 + } 184 + if pubs == nil { 185 + t.Errorf("pubs is nil") 186 + } 187 + for i, pub := range pubs { 188 + if pub == nil { 189 + t.Errorf("pub %d is nil", i) 190 + } 191 + } 192 + }