···2233import (
44 "encoding/json"
55+ "errors"
66+77+ "github.com/bluesky-social/indigo/api/agnostic"
58)
6977-type Lexicon interface {
1010+// Record represents an ATProto record.
1111+type Record interface {
812 Type() string
913}
10141115const (
1212- LexiconBase = "site.standard"
1313- LexiconBlob = "blob"
1616+ // CollectionBase is the base NSID for Standard.site.
1717+ CollectionBase = "site.standard"
1818+ CollectionBlob = "blob"
14191520 TimeFormat = "2006-01-02T15:04:05.000Z"
1621)
17221818-// LexiconJSON is used to encode and decode [Lexicon] from JSON.
1919-type LexiconJSON struct {
2020- // Lexicon parsed.
2121- // Nil if [Lexicon] is unknown.
2222- Lexicon Lexicon
2323- // Type stored if [Lexicon] is unknown.
2323+// RecordJSON is used to encode and to decode [Record] from JSON.
2424+type RecordJSON struct {
2525+ // Record parsed.
2626+ // Nil if [Record] is unknown.
2727+ Record Record
2828+ // Type stored if [Record] is unknown.
2429 // Set after [json.Unmarshal].
2530 Type string
2626- // Raw returns bytes stored if [Lexicon] is unknown.
3131+ // Raw returns bytes stored if [Record] is unknown.
2732 // Set after [json.Unmarshal].
2833 Raw []byte
2934}
30353131-func (l *LexiconJSON) MarshalJSON() ([]byte, error) {
3232- if l.Lexicon == nil {
3636+func (l *RecordJSON) MarshalJSON() ([]byte, error) {
3737+ if l.Record == nil {
3338 return l.Raw, nil
3439 }
3540 mp, err := l.MarshalMap()
3641 if err != nil {
3742 return nil, err
3843 }
3939- mp["$type"] = l.Lexicon.Type()
4444+ mp["$type"] = l.Record.Type()
4045 return json.Marshal(mp)
4146}
42474343-func (l *LexiconJSON) MarshalMap() (mp map[string]any, err error) {
4444- if l.Lexicon == nil {
4848+func (l *RecordJSON) MarshalMap() (mp map[string]any, err error) {
4949+ if l.Record == nil {
4550 err = json.Unmarshal(l.Raw, &mp)
4651 return
4752 }
4848- mp, err = MarshalToMap(l.Lexicon)
5353+ mp, err = MarshalToMap(l.Record)
4954 return
5055}
51565252-func (l *LexiconJSON) UnmarshalJSON(b []byte) error {
5757+func (l *RecordJSON) UnmarshalJSON(b []byte) error {
5358 var v struct {
5459 Type string `json:"$type"`
5560 }
···5863 return err
5964 }
6065 switch v.Type {
6161- case LexiconPublication:
6262- l.Lexicon = &Publication{}
6363- case LexiconDocument:
6464- l.Lexicon = &Document{}
6565- case LexiconSubscription:
6666- l.Lexicon = &Subscription{}
6767- case LexiconThemeBasic:
6868- l.Lexicon = &Theme{}
6969- case LexiconThemeColorRGB:
7070- l.Lexicon = &RGB{}
7171- case LexiconThemeColorRGBA:
7272- l.Lexicon = &RGBA{}
7373- case LexiconBlob:
7474- l.Lexicon = &Blob{}
6666+ case CollectionPublication:
6767+ l.Record = &Publication{}
6868+ case CollectionDocument:
6969+ l.Record = &Document{}
7070+ case CollectionSubscription:
7171+ l.Record = &Subscription{}
7272+ case CollectionThemeBasic:
7373+ l.Record = &Theme{}
7474+ case CollectionThemeColorRGB:
7575+ l.Record = &RGB{}
7676+ case CollectionThemeColorRGBA:
7777+ l.Record = &RGBA{}
7878+ case CollectionBlob:
7979+ l.Record = &Blob{}
7580 default:
7681 l.Raw = b
7782 l.Type = v.Type
7883 return nil
7984 }
8080- return json.Unmarshal(b, l.Lexicon)
8585+ return json.Unmarshal(b, l.Record)
8186}
82878388// Blob represents an ATProto `blob` type.
···8893}
89949095func (b *Blob) Type() string {
9191- return LexiconBlob
9696+ return CollectionBlob
9297}
93989499func (b *Blob) MarshalMap() (map[string]any, error) {
···115120 b.CID = v.Ref.Link
116121 return nil
117122}
123123+124124+var (
125125+ ErrInvalidType = errors.New("invalid collection type")
126126+)
127127+128128+// MaxItemsPerList is the number of items per list call.
129129+const MaxItemsPerList = 25
130130+131131+// Result is returned when after creating a record.
132132+type Result struct {
133133+ URI string
134134+ CID string
135135+ ValidationStatus *string
136136+ Commit *agnostic.RepoDefs_CommitMeta
137137+}
+2-2
map.go
···4040 return nil, nil
4141 }
4242 val := v.Interface()
4343- if conv, ok := val.(Lexicon); ok {
4444- val = &LexiconJSON{Lexicon: conv}
4343+ if conv, ok := val.(Record); ok {
4444+ val = &RecordJSON{Record: conv}
4545 }
4646 if conv, ok := val.(MarshalerMap); ok {
4747 return conv.MarshalMap()
+6-5
publication.go
···2233import "strings"
4455-const LexiconPublication = LexiconBase + ".publication"
55+const CollectionPublication = CollectionBase + ".publication"
6677-// Publication represents a collection of documents published to the web.
77+// Publication represents a collection of [Document]s published to the web.
88// It includes important information about a publication including its location on the web, theming information, user
99-// preferences, and more.
99+// [Preferences], and more.
1010//
1111-// The publication lexicon is not a requirement, but is recommended when publishing collections of related documents.
1111+// The [Publication] [Record] is not a requirement, but is recommended when publishing collections of related
1212+// [Document]s.
1213type Publication struct {
1314 // Base URL of the [Publication].
1415 // This value will be combined with the [Document.Path] to construct a full URL for the document.
···3233}
33343435func (p *Publication) Type() string {
3535- return LexiconPublication
3636+ return CollectionPublication
3637}
37383839func (p *Publication) MarshalMap() (map[string]any, error) {
+2-2
publication_test.go
···7272}`
73737474func TestPublication_JSON(t *testing.T) {
7575- var v *site.LexiconJSON
7575+ var v *site.RecordJSON
7676 err := json.Unmarshal([]byte(samplePub), &v)
7777 if err != nil {
7878 t.Fatal(err)
7979 }
8080- pub := v.Lexicon.(*site.Publication)
8080+ pub := v.Record.(*site.Publication)
8181 if pub.Name != "pckt - Dev Journal" {
8282 t.Errorf("invalid name: %s", pub.Name)
8383 }
+2-2
subscription.go
···11package site
2233-const LexiconSubscription = LexiconBase + ".graph.subscription"
33+const CollectionSubscription = CollectionBase + ".graph.subscription"
4455// Subscription enable users to follow publications and receive updates about new content.
66// They represent the social connection between readers and the publications they're interested in.
···1111}
12121313func (s *Subscription) Type() string {
1414- return LexiconSubscription
1414+ return CollectionSubscription
1515}