forked from tangled.org/core
Monorepo for Tangled — https://tangled.org

add stars to tangled

+693 -529
api/tangled/cbor_gen.go
···
var _ = math.E
var _ = sort.Sort
-
func (t *PublicKey) MarshalCBOR(w io.Writer) error {
+
func (t *FeedStar) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
···
cw := cbg.NewCborWriter(w)
-
if _, err := cw.Write([]byte{164}); err != nil {
+
if _, err := cw.Write([]byte{163}); err != nil {
return err
}
-
// t.Key (string) (string)
-
if len("key") > 1000000 {
-
return xerrors.Errorf("Value in field \"key\" was too long")
+
// t.LexiconTypeID (string) (string)
+
if len("$type") > 1000000 {
+
return xerrors.Errorf("Value in field \"$type\" was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("key"))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("$type"))); err != nil {
return err
}
-
if _, err := cw.WriteString(string("key")); err != nil {
+
if _, err := cw.WriteString(string("$type")); err != nil {
return err
}
-
if len(t.Key) > 1000000 {
-
return xerrors.Errorf("Value in field t.Key was too long")
-
}
-
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Key))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.feed.star"))); err != nil {
return err
}
-
if _, err := cw.WriteString(string(t.Key)); err != nil {
+
if _, err := cw.WriteString(string("sh.tangled.feed.star")); err != nil {
return err
}
-
// t.Name (string) (string)
-
if len("name") > 1000000 {
-
return xerrors.Errorf("Value in field \"name\" was too long")
+
// t.Subject (string) (string)
+
if len("subject") > 1000000 {
+
return xerrors.Errorf("Value in field \"subject\" was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("name"))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("subject"))); err != nil {
return err
}
-
if _, err := cw.WriteString(string("name")); err != nil {
+
if _, err := cw.WriteString(string("subject")); err != nil {
return err
}
-
if len(t.Name) > 1000000 {
-
return xerrors.Errorf("Value in field t.Name was too long")
+
if len(t.Subject) > 1000000 {
+
return xerrors.Errorf("Value in field t.Subject was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Name))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Subject))); err != nil {
return err
}
-
if _, err := cw.WriteString(string(t.Name)); err != nil {
+
if _, err := cw.WriteString(string(t.Subject)); err != nil {
return err
}
-
// t.LexiconTypeID (string) (string)
-
if len("$type") > 1000000 {
-
return xerrors.Errorf("Value in field \"$type\" was too long")
-
}
-
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("$type"))); err != nil {
-
return err
-
}
-
if _, err := cw.WriteString(string("$type")); err != nil {
-
return err
-
}
-
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.publicKey"))); err != nil {
-
return err
-
}
-
if _, err := cw.WriteString(string("sh.tangled.publicKey")); err != nil {
-
return err
-
}
-
-
// t.Created (string) (string)
-
if len("created") > 1000000 {
-
return xerrors.Errorf("Value in field \"created\" was too long")
+
// t.CreatedAt (string) (string)
+
if len("createdAt") > 1000000 {
+
return xerrors.Errorf("Value in field \"createdAt\" was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("created"))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("createdAt"))); err != nil {
return err
}
-
if _, err := cw.WriteString(string("created")); err != nil {
+
if _, err := cw.WriteString(string("createdAt")); err != nil {
return err
}
-
if len(t.Created) > 1000000 {
-
return xerrors.Errorf("Value in field t.Created was too long")
+
if len(t.CreatedAt) > 1000000 {
+
return xerrors.Errorf("Value in field t.CreatedAt was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Created))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.CreatedAt))); err != nil {
return err
}
-
if _, err := cw.WriteString(string(t.Created)); err != nil {
+
if _, err := cw.WriteString(string(t.CreatedAt)); err != nil {
return err
}
return nil
}
-
func (t *PublicKey) UnmarshalCBOR(r io.Reader) (err error) {
-
*t = PublicKey{}
+
func (t *FeedStar) UnmarshalCBOR(r io.Reader) (err error) {
+
*t = FeedStar{}
cr := cbg.NewCborReader(r)
···
}
if extra > cbg.MaxLength {
-
return fmt.Errorf("PublicKey: map struct too large (%d)", extra)
+
return fmt.Errorf("FeedStar: map struct too large (%d)", extra)
}
n := extra
-
nameBuf := make([]byte, 7)
+
nameBuf := make([]byte, 9)
for i := uint64(0); i < n; i++ {
nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000)
if err != nil {
···
}
switch string(nameBuf[:nameLen]) {
-
// t.Key (string) (string)
-
case "key":
-
-
{
-
sval, err := cbg.ReadStringWithMax(cr, 1000000)
-
if err != nil {
-
return err
-
}
-
-
t.Key = string(sval)
-
}
-
// t.Name (string) (string)
-
case "name":
+
// t.LexiconTypeID (string) (string)
+
case "$type":
{
sval, err := cbg.ReadStringWithMax(cr, 1000000)
···
return err
}
-
t.Name = string(sval)
+
t.LexiconTypeID = string(sval)
}
-
// t.LexiconTypeID (string) (string)
-
case "$type":
+
// t.Subject (string) (string)
+
case "subject":
{
sval, err := cbg.ReadStringWithMax(cr, 1000000)
···
return err
}
-
t.LexiconTypeID = string(sval)
+
t.Subject = string(sval)
}
-
// t.Created (string) (string)
-
case "created":
+
// t.CreatedAt (string) (string)
+
case "createdAt":
{
sval, err := cbg.ReadStringWithMax(cr, 1000000)
···
return err
}
-
t.Created = string(sval)
+
t.CreatedAt = string(sval)
}
default:
···
return nil
}
-
func (t *KnotMember) MarshalCBOR(w io.Writer) error {
+
func (t *GraphFollow) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
cw := cbg.NewCborWriter(w)
-
fieldCount := 4
-
if t.AddedAt == nil {
-
fieldCount--
-
}
-
-
if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil {
+
if _, err := cw.Write([]byte{163}); err != nil {
return err
}
···
return err
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.knot.member"))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.graph.follow"))); err != nil {
return err
}
-
if _, err := cw.WriteString(string("sh.tangled.knot.member")); err != nil {
+
if _, err := cw.WriteString(string("sh.tangled.graph.follow")); err != nil {
return err
}
-
// t.Domain (string) (string)
-
if len("domain") > 1000000 {
-
return xerrors.Errorf("Value in field \"domain\" was too long")
+
// t.Subject (string) (string)
+
if len("subject") > 1000000 {
+
return xerrors.Errorf("Value in field \"subject\" was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("domain"))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("subject"))); err != nil {
return err
}
-
if _, err := cw.WriteString(string("domain")); err != nil {
+
if _, err := cw.WriteString(string("subject")); err != nil {
return err
}
-
if len(t.Domain) > 1000000 {
-
return xerrors.Errorf("Value in field t.Domain was too long")
+
if len(t.Subject) > 1000000 {
+
return xerrors.Errorf("Value in field t.Subject was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Domain))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Subject))); err != nil {
return err
}
-
if _, err := cw.WriteString(string(t.Domain)); err != nil {
+
if _, err := cw.WriteString(string(t.Subject)); err != nil {
return err
}
-
// t.Member (string) (string)
-
if len("member") > 1000000 {
-
return xerrors.Errorf("Value in field \"member\" was too long")
+
// t.CreatedAt (string) (string)
+
if len("createdAt") > 1000000 {
+
return xerrors.Errorf("Value in field \"createdAt\" was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("member"))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("createdAt"))); err != nil {
return err
}
-
if _, err := cw.WriteString(string("member")); err != nil {
+
if _, err := cw.WriteString(string("createdAt")); err != nil {
return err
}
-
if len(t.Member) > 1000000 {
-
return xerrors.Errorf("Value in field t.Member was too long")
+
if len(t.CreatedAt) > 1000000 {
+
return xerrors.Errorf("Value in field t.CreatedAt was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Member))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.CreatedAt))); err != nil {
return err
}
-
if _, err := cw.WriteString(string(t.Member)); err != nil {
+
if _, err := cw.WriteString(string(t.CreatedAt)); err != nil {
return err
}
-
-
// t.AddedAt (string) (string)
-
if t.AddedAt != nil {
-
-
if len("addedAt") > 1000000 {
-
return xerrors.Errorf("Value in field \"addedAt\" was too long")
-
}
-
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("addedAt"))); err != nil {
-
return err
-
}
-
if _, err := cw.WriteString(string("addedAt")); err != nil {
-
return err
-
}
-
-
if t.AddedAt == nil {
-
if _, err := cw.Write(cbg.CborNull); err != nil {
-
return err
-
}
-
} else {
-
if len(*t.AddedAt) > 1000000 {
-
return xerrors.Errorf("Value in field t.AddedAt was too long")
-
}
-
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.AddedAt))); err != nil {
-
return err
-
}
-
if _, err := cw.WriteString(string(*t.AddedAt)); err != nil {
-
return err
-
}
-
}
-
}
return nil
}
-
func (t *KnotMember) UnmarshalCBOR(r io.Reader) (err error) {
-
*t = KnotMember{}
+
func (t *GraphFollow) UnmarshalCBOR(r io.Reader) (err error) {
+
*t = GraphFollow{}
cr := cbg.NewCborReader(r)
···
}
if extra > cbg.MaxLength {
-
return fmt.Errorf("KnotMember: map struct too large (%d)", extra)
+
return fmt.Errorf("GraphFollow: map struct too large (%d)", extra)
}
n := extra
-
nameBuf := make([]byte, 7)
+
nameBuf := make([]byte, 9)
for i := uint64(0); i < n; i++ {
nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000)
if err != nil {
···
t.LexiconTypeID = string(sval)
}
-
// t.Domain (string) (string)
-
case "domain":
+
// t.Subject (string) (string)
+
case "subject":
{
sval, err := cbg.ReadStringWithMax(cr, 1000000)
···
return err
}
-
t.Domain = string(sval)
+
t.Subject = string(sval)
}
-
// t.Member (string) (string)
-
case "member":
+
// t.CreatedAt (string) (string)
+
case "createdAt":
{
sval, err := cbg.ReadStringWithMax(cr, 1000000)
···
return err
}
-
t.Member = string(sval)
-
}
-
// t.AddedAt (string) (string)
-
case "addedAt":
-
-
{
-
b, err := cr.ReadByte()
-
if err != nil {
-
return err
-
}
-
if b != cbg.CborNull[0] {
-
if err := cr.UnreadByte(); err != nil {
-
return err
-
}
-
-
sval, err := cbg.ReadStringWithMax(cr, 1000000)
-
if err != nil {
-
return err
-
}
-
-
t.AddedAt = (*string)(&sval)
-
}
+
t.CreatedAt = string(sval)
}
default:
···
return nil
}
-
func (t *GraphFollow) MarshalCBOR(w io.Writer) error {
+
func (t *KnotMember) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
cw := cbg.NewCborWriter(w)
+
fieldCount := 4
-
if _, err := cw.Write([]byte{163}); err != nil {
+
if t.AddedAt == nil {
+
fieldCount--
+
}
+
+
if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil {
return err
}
···
return err
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.graph.follow"))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.knot.member"))); err != nil {
return err
}
-
if _, err := cw.WriteString(string("sh.tangled.graph.follow")); err != nil {
+
if _, err := cw.WriteString(string("sh.tangled.knot.member")); err != nil {
return err
}
-
// t.Subject (string) (string)
-
if len("subject") > 1000000 {
-
return xerrors.Errorf("Value in field \"subject\" was too long")
+
// t.Domain (string) (string)
+
if len("domain") > 1000000 {
+
return xerrors.Errorf("Value in field \"domain\" was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("subject"))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("domain"))); err != nil {
return err
}
-
if _, err := cw.WriteString(string("subject")); err != nil {
+
if _, err := cw.WriteString(string("domain")); err != nil {
return err
}
-
if len(t.Subject) > 1000000 {
-
return xerrors.Errorf("Value in field t.Subject was too long")
+
if len(t.Domain) > 1000000 {
+
return xerrors.Errorf("Value in field t.Domain was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Subject))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Domain))); err != nil {
return err
}
-
if _, err := cw.WriteString(string(t.Subject)); err != nil {
+
if _, err := cw.WriteString(string(t.Domain)); err != nil {
return err
}
-
// t.CreatedAt (string) (string)
-
if len("createdAt") > 1000000 {
-
return xerrors.Errorf("Value in field \"createdAt\" was too long")
+
// t.Member (string) (string)
+
if len("member") > 1000000 {
+
return xerrors.Errorf("Value in field \"member\" was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("createdAt"))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("member"))); err != nil {
return err
}
-
if _, err := cw.WriteString(string("createdAt")); err != nil {
+
if _, err := cw.WriteString(string("member")); err != nil {
return err
}
-
if len(t.CreatedAt) > 1000000 {
-
return xerrors.Errorf("Value in field t.CreatedAt was too long")
+
if len(t.Member) > 1000000 {
+
return xerrors.Errorf("Value in field t.Member was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.CreatedAt))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Member))); err != nil {
return err
}
-
if _, err := cw.WriteString(string(t.CreatedAt)); err != nil {
+
if _, err := cw.WriteString(string(t.Member)); err != nil {
return err
}
+
+
// t.AddedAt (string) (string)
+
if t.AddedAt != nil {
+
+
if len("addedAt") > 1000000 {
+
return xerrors.Errorf("Value in field \"addedAt\" was too long")
+
}
+
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("addedAt"))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string("addedAt")); err != nil {
+
return err
+
}
+
+
if t.AddedAt == nil {
+
if _, err := cw.Write(cbg.CborNull); err != nil {
+
return err
+
}
+
} else {
+
if len(*t.AddedAt) > 1000000 {
+
return xerrors.Errorf("Value in field t.AddedAt was too long")
+
}
+
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.AddedAt))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string(*t.AddedAt)); err != nil {
+
return err
+
}
+
}
+
}
return nil
}
-
func (t *GraphFollow) UnmarshalCBOR(r io.Reader) (err error) {
-
*t = GraphFollow{}
+
func (t *KnotMember) UnmarshalCBOR(r io.Reader) (err error) {
+
*t = KnotMember{}
cr := cbg.NewCborReader(r)
···
}
if extra > cbg.MaxLength {
-
return fmt.Errorf("GraphFollow: map struct too large (%d)", extra)
+
return fmt.Errorf("KnotMember: map struct too large (%d)", extra)
}
n := extra
-
nameBuf := make([]byte, 9)
+
nameBuf := make([]byte, 7)
for i := uint64(0); i < n; i++ {
nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000)
if err != nil {
···
t.LexiconTypeID = string(sval)
}
-
// t.Subject (string) (string)
-
case "subject":
+
// t.Domain (string) (string)
+
case "domain":
{
sval, err := cbg.ReadStringWithMax(cr, 1000000)
···
return err
}
-
t.Subject = string(sval)
+
t.Domain = string(sval)
}
-
// t.CreatedAt (string) (string)
-
case "createdAt":
+
// t.Member (string) (string)
+
case "member":
{
sval, err := cbg.ReadStringWithMax(cr, 1000000)
···
return err
}
-
t.CreatedAt = string(sval)
+
t.Member = string(sval)
+
}
+
// t.AddedAt (string) (string)
+
case "addedAt":
+
+
{
+
b, err := cr.ReadByte()
+
if err != nil {
+
return err
+
}
+
if b != cbg.CborNull[0] {
+
if err := cr.UnreadByte(); err != nil {
+
return err
+
}
+
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
+
if err != nil {
+
return err
+
}
+
+
t.AddedAt = (*string)(&sval)
+
}
}
default:
···
return nil
}
-
func (t *Repo) MarshalCBOR(w io.Writer) error {
+
func (t *PublicKey) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
cw := cbg.NewCborWriter(w)
-
fieldCount := 5
-
if t.AddedAt == nil {
-
fieldCount--
-
}
-
-
if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil {
+
if _, err := cw.Write([]byte{164}); err != nil {
return err
}
-
// t.Knot (string) (string)
-
if len("knot") > 1000000 {
-
return xerrors.Errorf("Value in field \"knot\" was too long")
+
// t.Key (string) (string)
+
if len("key") > 1000000 {
+
return xerrors.Errorf("Value in field \"key\" was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("knot"))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("key"))); err != nil {
return err
}
-
if _, err := cw.WriteString(string("knot")); err != nil {
+
if _, err := cw.WriteString(string("key")); err != nil {
return err
}
-
if len(t.Knot) > 1000000 {
-
return xerrors.Errorf("Value in field t.Knot was too long")
+
if len(t.Key) > 1000000 {
+
return xerrors.Errorf("Value in field t.Key was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Knot))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Key))); err != nil {
return err
}
-
if _, err := cw.WriteString(string(t.Knot)); err != nil {
+
if _, err := cw.WriteString(string(t.Key)); err != nil {
return err
}
···
return err
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.repo"))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.publicKey"))); err != nil {
return err
}
-
if _, err := cw.WriteString(string("sh.tangled.repo")); err != nil {
+
if _, err := cw.WriteString(string("sh.tangled.publicKey")); err != nil {
return err
}
-
// t.Owner (string) (string)
-
if len("owner") > 1000000 {
-
return xerrors.Errorf("Value in field \"owner\" was too long")
+
// t.Created (string) (string)
+
if len("created") > 1000000 {
+
return xerrors.Errorf("Value in field \"created\" was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("owner"))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("created"))); err != nil {
return err
}
-
if _, err := cw.WriteString(string("owner")); err != nil {
+
if _, err := cw.WriteString(string("created")); err != nil {
return err
}
-
if len(t.Owner) > 1000000 {
-
return xerrors.Errorf("Value in field t.Owner was too long")
+
if len(t.Created) > 1000000 {
+
return xerrors.Errorf("Value in field t.Created was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Owner))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Created))); err != nil {
return err
}
-
if _, err := cw.WriteString(string(t.Owner)); err != nil {
+
if _, err := cw.WriteString(string(t.Created)); err != nil {
return err
}
-
-
// t.AddedAt (string) (string)
-
if t.AddedAt != nil {
-
-
if len("addedAt") > 1000000 {
-
return xerrors.Errorf("Value in field \"addedAt\" was too long")
-
}
-
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("addedAt"))); err != nil {
-
return err
-
}
-
if _, err := cw.WriteString(string("addedAt")); err != nil {
-
return err
-
}
-
-
if t.AddedAt == nil {
-
if _, err := cw.Write(cbg.CborNull); err != nil {
-
return err
-
}
-
} else {
-
if len(*t.AddedAt) > 1000000 {
-
return xerrors.Errorf("Value in field t.AddedAt was too long")
-
}
-
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.AddedAt))); err != nil {
-
return err
-
}
-
if _, err := cw.WriteString(string(*t.AddedAt)); err != nil {
-
return err
-
}
-
}
-
}
return nil
}
-
func (t *Repo) UnmarshalCBOR(r io.Reader) (err error) {
-
*t = Repo{}
+
func (t *PublicKey) UnmarshalCBOR(r io.Reader) (err error) {
+
*t = PublicKey{}
cr := cbg.NewCborReader(r)
···
}
if extra > cbg.MaxLength {
-
return fmt.Errorf("Repo: map struct too large (%d)", extra)
+
return fmt.Errorf("PublicKey: map struct too large (%d)", extra)
}
n := extra
···
}
switch string(nameBuf[:nameLen]) {
-
// t.Knot (string) (string)
-
case "knot":
+
// t.Key (string) (string)
+
case "key":
{
sval, err := cbg.ReadStringWithMax(cr, 1000000)
···
return err
}
-
t.Knot = string(sval)
+
t.Key = string(sval)
}
// t.Name (string) (string)
case "name":
···
t.LexiconTypeID = string(sval)
}
-
// t.Owner (string) (string)
-
case "owner":
+
// t.Created (string) (string)
+
case "created":
{
sval, err := cbg.ReadStringWithMax(cr, 1000000)
···
return err
}
-
t.Owner = string(sval)
-
}
-
// t.AddedAt (string) (string)
-
case "addedAt":
-
-
{
-
b, err := cr.ReadByte()
-
if err != nil {
-
return err
-
}
-
if b != cbg.CborNull[0] {
-
if err := cr.UnreadByte(); err != nil {
-
return err
-
}
-
-
sval, err := cbg.ReadStringWithMax(cr, 1000000)
-
if err != nil {
-
return err
-
}
-
-
t.AddedAt = (*string)(&sval)
-
}
+
t.Created = string(sval)
}
default:
···
return nil
}
-
func (t *RepoIssue) MarshalCBOR(w io.Writer) error {
+
func (t *RepoIssueComment) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
···
fieldCount--
}
+
if t.CommentId == nil {
+
fieldCount--
+
}
+
if t.CreatedAt == nil {
+
fieldCount--
+
}
+
+
if t.Owner == nil {
+
fieldCount--
+
}
+
+
if t.Repo == nil {
fieldCount--
}
···
}
// t.Repo (string) (string)
-
if len("repo") > 1000000 {
-
return xerrors.Errorf("Value in field \"repo\" was too long")
-
}
+
if t.Repo != nil {
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("repo"))); err != nil {
-
return err
-
}
-
if _, err := cw.WriteString(string("repo")); err != nil {
-
return err
-
}
+
if len("repo") > 1000000 {
+
return xerrors.Errorf("Value in field \"repo\" was too long")
+
}
-
if len(t.Repo) > 1000000 {
-
return xerrors.Errorf("Value in field t.Repo was too long")
-
}
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("repo"))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string("repo")); err != nil {
+
return err
+
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Repo))); err != nil {
-
return err
-
}
-
if _, err := cw.WriteString(string(t.Repo)); err != nil {
-
return err
+
if t.Repo == nil {
+
if _, err := cw.Write(cbg.CborNull); err != nil {
+
return err
+
}
+
} else {
+
if len(*t.Repo) > 1000000 {
+
return xerrors.Errorf("Value in field t.Repo was too long")
+
}
+
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Repo))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string(*t.Repo)); err != nil {
+
return err
+
}
+
}
}
// t.LexiconTypeID (string) (string)
···
return err
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.repo.issue"))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.repo.issue.comment"))); err != nil {
return err
}
-
if _, err := cw.WriteString(string("sh.tangled.repo.issue")); err != nil {
+
if _, err := cw.WriteString(string("sh.tangled.repo.issue.comment")); err != nil {
return err
}
-
// t.Owner (string) (string)
-
if len("owner") > 1000000 {
-
return xerrors.Errorf("Value in field \"owner\" was too long")
+
// t.Issue (string) (string)
+
if len("issue") > 1000000 {
+
return xerrors.Errorf("Value in field \"issue\" was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("owner"))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("issue"))); err != nil {
return err
}
-
if _, err := cw.WriteString(string("owner")); err != nil {
+
if _, err := cw.WriteString(string("issue")); err != nil {
return err
}
-
if len(t.Owner) > 1000000 {
-
return xerrors.Errorf("Value in field t.Owner was too long")
+
if len(t.Issue) > 1000000 {
+
return xerrors.Errorf("Value in field t.Issue was too long")
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Owner))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Issue))); err != nil {
return err
}
-
if _, err := cw.WriteString(string(t.Owner)); err != nil {
+
if _, err := cw.WriteString(string(t.Issue)); err != nil {
return err
}
-
// t.Title (string) (string)
-
if len("title") > 1000000 {
-
return xerrors.Errorf("Value in field \"title\" was too long")
-
}
+
// t.Owner (string) (string)
+
if t.Owner != nil {
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("title"))); err != nil {
-
return err
-
}
-
if _, err := cw.WriteString(string("title")); err != nil {
-
return err
-
}
+
if len("owner") > 1000000 {
+
return xerrors.Errorf("Value in field \"owner\" was too long")
+
}
-
if len(t.Title) > 1000000 {
-
return xerrors.Errorf("Value in field t.Title was too long")
-
}
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("owner"))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string("owner")); err != nil {
+
return err
+
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Title))); err != nil {
-
return err
-
}
-
if _, err := cw.WriteString(string(t.Title)); err != nil {
-
return err
-
}
+
if t.Owner == nil {
+
if _, err := cw.Write(cbg.CborNull); err != nil {
+
return err
+
}
+
} else {
+
if len(*t.Owner) > 1000000 {
+
return xerrors.Errorf("Value in field t.Owner was too long")
+
}
-
// t.IssueId (int64) (int64)
-
if len("issueId") > 1000000 {
-
return xerrors.Errorf("Value in field \"issueId\" was too long")
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Owner))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string(*t.Owner)); err != nil {
+
return err
+
}
+
}
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("issueId"))); err != nil {
-
return err
-
}
-
if _, err := cw.WriteString(string("issueId")); err != nil {
-
return err
-
}
+
// t.CommentId (int64) (int64)
+
if t.CommentId != nil {
-
if t.IssueId >= 0 {
-
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.IssueId)); err != nil {
+
if len("commentId") > 1000000 {
+
return xerrors.Errorf("Value in field \"commentId\" was too long")
+
}
+
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("commentId"))); err != nil {
return err
}
-
} else {
-
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.IssueId-1)); err != nil {
+
if _, err := cw.WriteString(string("commentId")); err != nil {
return err
}
+
+
if t.CommentId == nil {
+
if _, err := cw.Write(cbg.CborNull); err != nil {
+
return err
+
}
+
} else {
+
if *t.CommentId >= 0 {
+
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(*t.CommentId)); err != nil {
+
return err
+
}
+
} else {
+
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-*t.CommentId-1)); err != nil {
+
return err
+
}
+
}
+
}
+
}
// t.CreatedAt (string) (string)
···
return nil
-
func (t *RepoIssue) UnmarshalCBOR(r io.Reader) (err error) {
-
*t = RepoIssue{}
+
func (t *RepoIssueComment) UnmarshalCBOR(r io.Reader) (err error) {
+
*t = RepoIssueComment{}
cr := cbg.NewCborReader(r)
···
if extra > cbg.MaxLength {
-
return fmt.Errorf("RepoIssue: map struct too large (%d)", extra)
+
return fmt.Errorf("RepoIssueComment: map struct too large (%d)", extra)
n := extra
···
case "repo":
-
sval, err := cbg.ReadStringWithMax(cr, 1000000)
+
b, err := cr.ReadByte()
if err != nil {
return err
+
if b != cbg.CborNull[0] {
+
if err := cr.UnreadByte(); err != nil {
+
return err
+
}
-
t.Repo = string(sval)
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
+
if err != nil {
+
return err
+
}
+
+
t.Repo = (*string)(&sval)
+
}
// t.LexiconTypeID (string) (string)
case "$type":
···
t.LexiconTypeID = string(sval)
-
// t.Owner (string) (string)
-
case "owner":
+
// t.Issue (string) (string)
+
case "issue":
sval, err := cbg.ReadStringWithMax(cr, 1000000)
···
return err
-
t.Owner = string(sval)
+
t.Issue = string(sval)
-
// t.Title (string) (string)
-
case "title":
+
// t.Owner (string) (string)
+
case "owner":
-
sval, err := cbg.ReadStringWithMax(cr, 1000000)
+
b, err := cr.ReadByte()
if err != nil {
return err
+
if b != cbg.CborNull[0] {
+
if err := cr.UnreadByte(); err != nil {
+
return err
+
}
-
t.Title = string(sval)
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
+
if err != nil {
+
return err
+
}
+
+
t.Owner = (*string)(&sval)
+
}
-
// t.IssueId (int64) (int64)
-
case "issueId":
+
// t.CommentId (int64) (int64)
+
case "commentId":
-
maj, extra, err := cr.ReadHeader()
+
+
b, err := cr.ReadByte()
if err != nil {
return err
-
var extraI int64
-
switch maj {
-
case cbg.MajUnsignedInt:
-
extraI = int64(extra)
-
if extraI < 0 {
-
return fmt.Errorf("int64 positive overflow")
+
if b != cbg.CborNull[0] {
+
if err := cr.UnreadByte(); err != nil {
+
return err
-
case cbg.MajNegativeInt:
-
extraI = int64(extra)
-
if extraI < 0 {
-
return fmt.Errorf("int64 negative overflow")
+
maj, extra, err := cr.ReadHeader()
+
if err != nil {
+
return err
-
extraI = -1 - extraI
-
default:
-
return fmt.Errorf("wrong type for int64 field: %d", maj)
-
}
+
var extraI int64
+
switch maj {
+
case cbg.MajUnsignedInt:
+
extraI = int64(extra)
+
if extraI < 0 {
+
return fmt.Errorf("int64 positive overflow")
+
}
+
case cbg.MajNegativeInt:
+
extraI = int64(extra)
+
if extraI < 0 {
+
return fmt.Errorf("int64 negative overflow")
+
}
+
extraI = -1 - extraI
+
default:
+
return fmt.Errorf("wrong type for int64 field: %d", maj)
+
}
-
t.IssueId = int64(extraI)
+
t.CommentId = (*int64)(&extraI)
+
}
// t.CreatedAt (string) (string)
case "createdAt":
···
return nil
-
func (t *RepoIssueComment) MarshalCBOR(w io.Writer) error {
+
func (t *RepoIssue) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
···
fieldCount--
-
if t.CommentId == nil {
-
fieldCount--
-
}
-
if t.CreatedAt == nil {
-
fieldCount--
-
}
-
-
if t.Owner == nil {
-
fieldCount--
-
}
-
-
if t.Repo == nil {
fieldCount--
···
// t.Repo (string) (string)
-
if t.Repo != nil {
-
-
if len("repo") > 1000000 {
-
return xerrors.Errorf("Value in field \"repo\" was too long")
-
}
+
if len("repo") > 1000000 {
+
return xerrors.Errorf("Value in field \"repo\" was too long")
+
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("repo"))); err != nil {
-
return err
-
}
-
if _, err := cw.WriteString(string("repo")); err != nil {
-
return err
-
}
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("repo"))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string("repo")); err != nil {
+
return err
+
}
-
if t.Repo == nil {
-
if _, err := cw.Write(cbg.CborNull); err != nil {
-
return err
-
}
-
} else {
-
if len(*t.Repo) > 1000000 {
-
return xerrors.Errorf("Value in field t.Repo was too long")
-
}
+
if len(t.Repo) > 1000000 {
+
return xerrors.Errorf("Value in field t.Repo was too long")
+
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Repo))); err != nil {
-
return err
-
}
-
if _, err := cw.WriteString(string(*t.Repo)); err != nil {
-
return err
-
}
-
}
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Repo))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string(t.Repo)); err != nil {
+
return err
// t.LexiconTypeID (string) (string)
···
return err
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.repo.issue.comment"))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.repo.issue"))); err != nil {
return err
-
if _, err := cw.WriteString(string("sh.tangled.repo.issue.comment")); err != nil {
+
if _, err := cw.WriteString(string("sh.tangled.repo.issue")); err != nil {
return err
-
// t.Issue (string) (string)
-
if len("issue") > 1000000 {
-
return xerrors.Errorf("Value in field \"issue\" was too long")
+
// t.Owner (string) (string)
+
if len("owner") > 1000000 {
+
return xerrors.Errorf("Value in field \"owner\" was too long")
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("issue"))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("owner"))); err != nil {
return err
-
if _, err := cw.WriteString(string("issue")); err != nil {
+
if _, err := cw.WriteString(string("owner")); err != nil {
return err
-
if len(t.Issue) > 1000000 {
-
return xerrors.Errorf("Value in field t.Issue was too long")
+
if len(t.Owner) > 1000000 {
+
return xerrors.Errorf("Value in field t.Owner was too long")
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Issue))); err != nil {
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Owner))); err != nil {
return err
-
if _, err := cw.WriteString(string(t.Issue)); err != nil {
+
if _, err := cw.WriteString(string(t.Owner)); err != nil {
return err
-
// t.Owner (string) (string)
-
if t.Owner != nil {
+
// t.Title (string) (string)
+
if len("title") > 1000000 {
+
return xerrors.Errorf("Value in field \"title\" was too long")
+
}
-
if len("owner") > 1000000 {
-
return xerrors.Errorf("Value in field \"owner\" was too long")
-
}
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("title"))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string("title")); err != nil {
+
return err
+
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("owner"))); err != nil {
-
return err
-
}
-
if _, err := cw.WriteString(string("owner")); err != nil {
-
return err
-
}
+
if len(t.Title) > 1000000 {
+
return xerrors.Errorf("Value in field t.Title was too long")
+
}
-
if t.Owner == nil {
-
if _, err := cw.Write(cbg.CborNull); err != nil {
-
return err
-
}
-
} else {
-
if len(*t.Owner) > 1000000 {
-
return xerrors.Errorf("Value in field t.Owner was too long")
-
}
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Title))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string(t.Title)); err != nil {
+
return err
+
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Owner))); err != nil {
-
return err
-
}
-
if _, err := cw.WriteString(string(*t.Owner)); err != nil {
-
return err
-
}
-
}
+
// t.IssueId (int64) (int64)
+
if len("issueId") > 1000000 {
+
return xerrors.Errorf("Value in field \"issueId\" was too long")
-
// t.CommentId (int64) (int64)
-
if t.CommentId != nil {
-
-
if len("commentId") > 1000000 {
-
return xerrors.Errorf("Value in field \"commentId\" was too long")
-
}
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("issueId"))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string("issueId")); err != nil {
+
return err
+
}
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("commentId"))); err != nil {
+
if t.IssueId >= 0 {
+
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.IssueId)); err != nil {
return err
-
if _, err := cw.WriteString(string("commentId")); err != nil {
+
} else {
+
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.IssueId-1)); err != nil {
return err
-
-
if t.CommentId == nil {
-
if _, err := cw.Write(cbg.CborNull); err != nil {
-
return err
-
}
-
} else {
-
if *t.CommentId >= 0 {
-
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(*t.CommentId)); err != nil {
-
return err
-
}
-
} else {
-
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-*t.CommentId-1)); err != nil {
-
return err
-
}
-
}
-
}
-
// t.CreatedAt (string) (string)
···
return nil
-
func (t *RepoIssueComment) UnmarshalCBOR(r io.Reader) (err error) {
-
*t = RepoIssueComment{}
+
func (t *RepoIssue) UnmarshalCBOR(r io.Reader) (err error) {
+
*t = RepoIssue{}
cr := cbg.NewCborReader(r)
···
if extra > cbg.MaxLength {
-
return fmt.Errorf("RepoIssueComment: map struct too large (%d)", extra)
+
return fmt.Errorf("RepoIssue: map struct too large (%d)", extra)
n := extra
···
case "repo":
-
b, err := cr.ReadByte()
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
if err != nil {
return err
-
if b != cbg.CborNull[0] {
-
if err := cr.UnreadByte(); err != nil {
-
return err
-
}
-
sval, err := cbg.ReadStringWithMax(cr, 1000000)
-
if err != nil {
-
return err
-
}
-
-
t.Repo = (*string)(&sval)
-
}
+
t.Repo = string(sval)
// t.LexiconTypeID (string) (string)
case "$type":
···
t.LexiconTypeID = string(sval)
-
// t.Issue (string) (string)
-
case "issue":
+
// t.Owner (string) (string)
+
case "owner":
+
+
{
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
+
if err != nil {
+
return err
+
}
+
+
t.Owner = string(sval)
+
}
+
// t.Title (string) (string)
+
case "title":
sval, err := cbg.ReadStringWithMax(cr, 1000000)
···
return err
-
t.Issue = string(sval)
+
t.Title = string(sval)
+
}
+
// t.IssueId (int64) (int64)
+
case "issueId":
+
{
+
maj, extra, err := cr.ReadHeader()
+
if err != nil {
+
return err
+
}
+
var extraI int64
+
switch maj {
+
case cbg.MajUnsignedInt:
+
extraI = int64(extra)
+
if extraI < 0 {
+
return fmt.Errorf("int64 positive overflow")
+
}
+
case cbg.MajNegativeInt:
+
extraI = int64(extra)
+
if extraI < 0 {
+
return fmt.Errorf("int64 negative overflow")
+
}
+
extraI = -1 - extraI
+
default:
+
return fmt.Errorf("wrong type for int64 field: %d", maj)
+
}
+
+
t.IssueId = int64(extraI)
-
// t.Owner (string) (string)
-
case "owner":
+
// t.CreatedAt (string) (string)
+
case "createdAt":
b, err := cr.ReadByte()
···
return err
-
t.Owner = (*string)(&sval)
+
t.CreatedAt = (*string)(&sval)
+
}
+
}
+
+
default:
+
// Field doesn't exist on this type, so ignore it
+
if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil {
+
return err
+
}
+
}
+
}
+
+
return nil
+
}
+
func (t *Repo) MarshalCBOR(w io.Writer) error {
+
if t == nil {
+
_, err := w.Write(cbg.CborNull)
+
return err
+
}
+
+
cw := cbg.NewCborWriter(w)
+
fieldCount := 5
+
+
if t.AddedAt == nil {
+
fieldCount--
+
}
+
+
if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil {
+
return err
+
}
+
+
// t.Knot (string) (string)
+
if len("knot") > 1000000 {
+
return xerrors.Errorf("Value in field \"knot\" was too long")
+
}
+
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("knot"))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string("knot")); err != nil {
+
return err
+
}
+
+
if len(t.Knot) > 1000000 {
+
return xerrors.Errorf("Value in field t.Knot was too long")
+
}
+
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Knot))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string(t.Knot)); err != nil {
+
return err
+
}
+
+
// t.Name (string) (string)
+
if len("name") > 1000000 {
+
return xerrors.Errorf("Value in field \"name\" was too long")
+
}
+
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("name"))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string("name")); err != nil {
+
return err
+
}
+
+
if len(t.Name) > 1000000 {
+
return xerrors.Errorf("Value in field t.Name was too long")
+
}
+
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Name))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string(t.Name)); err != nil {
+
return err
+
}
+
+
// t.LexiconTypeID (string) (string)
+
if len("$type") > 1000000 {
+
return xerrors.Errorf("Value in field \"$type\" was too long")
+
}
+
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("$type"))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string("$type")); err != nil {
+
return err
+
}
+
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.repo"))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string("sh.tangled.repo")); err != nil {
+
return err
+
}
+
+
// t.Owner (string) (string)
+
if len("owner") > 1000000 {
+
return xerrors.Errorf("Value in field \"owner\" was too long")
+
}
+
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("owner"))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string("owner")); err != nil {
+
return err
+
}
+
+
if len(t.Owner) > 1000000 {
+
return xerrors.Errorf("Value in field t.Owner was too long")
+
}
+
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Owner))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string(t.Owner)); err != nil {
+
return err
+
}
+
+
// t.AddedAt (string) (string)
+
if t.AddedAt != nil {
+
+
if len("addedAt") > 1000000 {
+
return xerrors.Errorf("Value in field \"addedAt\" was too long")
+
}
+
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("addedAt"))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string("addedAt")); err != nil {
+
return err
+
}
+
+
if t.AddedAt == nil {
+
if _, err := cw.Write(cbg.CborNull); err != nil {
+
return err
+
}
+
} else {
+
if len(*t.AddedAt) > 1000000 {
+
return xerrors.Errorf("Value in field t.AddedAt was too long")
+
}
+
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.AddedAt))); err != nil {
+
return err
+
}
+
if _, err := cw.WriteString(string(*t.AddedAt)); err != nil {
+
return err
+
}
+
}
+
}
+
return nil
+
}
+
+
func (t *Repo) UnmarshalCBOR(r io.Reader) (err error) {
+
*t = Repo{}
+
+
cr := cbg.NewCborReader(r)
+
+
maj, extra, err := cr.ReadHeader()
+
if err != nil {
+
return err
+
}
+
defer func() {
+
if err == io.EOF {
+
err = io.ErrUnexpectedEOF
+
}
+
}()
+
+
if maj != cbg.MajMap {
+
return fmt.Errorf("cbor input should be of type map")
+
}
+
+
if extra > cbg.MaxLength {
+
return fmt.Errorf("Repo: map struct too large (%d)", extra)
+
}
+
+
n := extra
+
+
nameBuf := make([]byte, 7)
+
for i := uint64(0); i < n; i++ {
+
nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000)
+
if err != nil {
+
return err
+
}
+
+
if !ok {
+
// Field doesn't exist on this type, so ignore it
+
if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil {
+
return err
+
}
+
continue
+
}
+
+
switch string(nameBuf[:nameLen]) {
+
// t.Knot (string) (string)
+
case "knot":
+
+
{
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
+
if err != nil {
+
return err
+
+
t.Knot = string(sval)
-
// t.CommentId (int64) (int64)
-
case "commentId":
+
// t.Name (string) (string)
+
case "name":
+
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
+
if err != nil {
+
return err
+
}
-
b, err := cr.ReadByte()
+
t.Name = string(sval)
+
}
+
// t.LexiconTypeID (string) (string)
+
case "$type":
+
+
{
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
if err != nil {
return err
-
if b != cbg.CborNull[0] {
-
if err := cr.UnreadByte(); err != nil {
-
return err
-
}
-
maj, extra, err := cr.ReadHeader()
-
if err != nil {
-
return err
-
}
-
var extraI int64
-
switch maj {
-
case cbg.MajUnsignedInt:
-
extraI = int64(extra)
-
if extraI < 0 {
-
return fmt.Errorf("int64 positive overflow")
-
}
-
case cbg.MajNegativeInt:
-
extraI = int64(extra)
-
if extraI < 0 {
-
return fmt.Errorf("int64 negative overflow")
-
}
-
extraI = -1 - extraI
-
default:
-
return fmt.Errorf("wrong type for int64 field: %d", maj)
-
}
-
t.CommentId = (*int64)(&extraI)
+
t.LexiconTypeID = string(sval)
+
}
+
// t.Owner (string) (string)
+
case "owner":
+
+
{
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
+
if err != nil {
+
return err
+
+
t.Owner = string(sval)
-
// t.CreatedAt (string) (string)
-
case "createdAt":
+
// t.AddedAt (string) (string)
+
case "addedAt":
b, err := cr.ReadByte()
···
return err
-
t.CreatedAt = (*string)(&sval)
+
t.AddedAt = (*string)(&sval)
+23
api/tangled/feedstar.go
···
+
// Code generated by cmd/lexgen (see Makefile's lexgen); DO NOT EDIT.
+
+
package tangled
+
+
// schema: sh.tangled.feed.star
+
+
import (
+
"github.com/bluesky-social/indigo/lex/util"
+
)
+
+
const (
+
FeedStarNSID = "sh.tangled.feed.star"
+
)
+
+
func init() {
+
util.RegisterType("sh.tangled.feed.star", &FeedStar{})
+
} //
+
// RECORDTYPE: FeedStar
+
type FeedStar struct {
+
LexiconTypeID string `json:"$type,const=sh.tangled.feed.star" cborgen:"$type,const=sh.tangled.feed.star"`
+
CreatedAt string `json:"createdAt" cborgen:"createdAt"`
+
Subject string `json:"subject" cborgen:"subject"`
+
}
+10
appview/db/db.go
···
next_issue_id integer not null default 1
);
+
create table if not exists stars (
+
id integer primary key autoincrement,
+
starred_by_did text not null,
+
repo_at text not null,
+
rkey text not null,
+
created text not null default (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
+
foreign key (repo_at) references repos(at_uri) on delete cascade,
+
unique(starred_by_did, repo_at)
+
);
+
`)
if err != nil {
return nil, err
+11 -6
appview/db/follow.go
···
UserDid string
SubjectDid string
FollowedAt time.Time
-
RKey string
+
Rkey string
}
func AddFollow(e Execer, userDid, subjectDid, rkey string) error {
···
var follow Follow
var followedAt string
-
err := row.Scan(&follow.UserDid, &follow.SubjectDid, &followedAt, &follow.RKey)
+
err := row.Scan(&follow.UserDid, &follow.SubjectDid, &followedAt, &follow.Rkey)
if err != nil {
return nil, err
}
···
return &follow, nil
}
-
// Get a follow record
+
// Remove a follow
func DeleteFollow(e Execer, userDid, subjectDid string) error {
_, err := e.Exec(`delete from follows where user_did = ? and subject_did = ?`, userDid, subjectDid)
return err
···
}
}
-
func GetAllFollows(e Execer) ([]Follow, error) {
+
func GetAllFollows(e Execer, limit int) ([]Follow, error) {
var follows []Follow
-
rows, err := e.Query(`select user_did, subject_did, followed_at, rkey from follows`)
+
rows, err := e.Query(`
+
select user_did, subject_did, followed_at, rkey
+
from follows
+
order by followed_at desc
+
limit ?`, limit,
+
)
if err != nil {
return nil, err
}
···
for rows.Next() {
var follow Follow
var followedAt string
-
if err := rows.Scan(&follow.UserDid, &follow.SubjectDid, &followedAt, &follow.RKey); err != nil {
+
if err := rows.Scan(&follow.UserDid, &follow.SubjectDid, &followedAt, &follow.Rkey); err != nil {
return nil, err
}
+37 -12
appview/db/issues.go
···
import (
"database/sql"
"time"
+
+
"github.com/bluesky-social/indigo/atproto/syntax"
)
type Issue struct {
-
RepoAt string
+
RepoAt syntax.ATURI
OwnerDid string
IssueId int
IssueAt string
···
type Comment struct {
OwnerDid string
-
RepoAt string
+
RepoAt syntax.ATURI
CommentAt string
Issue int
CommentId int
···
return nil
}
-
func SetIssueAt(e Execer, repoAt string, issueId int, issueAt string) error {
+
func SetIssueAt(e Execer, repoAt syntax.ATURI, issueId int, issueAt string) error {
_, err := e.Exec(`update issues set issue_at = ? where repo_at = ? and issue_id = ?`, issueAt, repoAt, issueId)
return err
}
-
func GetIssueAt(e Execer, repoAt string, issueId int) (string, error) {
+
func GetIssueAt(e Execer, repoAt syntax.ATURI, issueId int) (string, error) {
var issueAt string
err := e.QueryRow(`select issue_at from issues where repo_at = ? and issue_id = ?`, repoAt, issueId).Scan(&issueAt)
return issueAt, err
}
-
func GetIssueId(e Execer, repoAt string) (int, error) {
+
func GetIssueId(e Execer, repoAt syntax.ATURI) (int, error) {
var issueId int
err := e.QueryRow(`select next_issue_id from repo_issue_seqs where repo_at = ?`, repoAt).Scan(&issueId)
return issueId - 1, err
}
-
func GetIssueOwnerDid(e Execer, repoAt string, issueId int) (string, error) {
+
func GetIssueOwnerDid(e Execer, repoAt syntax.ATURI, issueId int) (string, error) {
var ownerDid string
err := e.QueryRow(`select owner_did from issues where repo_at = ? and issue_id = ?`, repoAt, issueId).Scan(&ownerDid)
return ownerDid, err
}
-
func GetIssues(e Execer, repoAt string) ([]Issue, error) {
+
func GetIssues(e Execer, repoAt syntax.ATURI) ([]Issue, error) {
var issues []Issue
rows, err := e.Query(`select owner_did, issue_id, created, title, body, open from issues where repo_at = ? order by created desc`, repoAt)
···
return issues, nil
}
-
func GetIssue(e Execer, repoAt string, issueId int) (*Issue, error) {
+
func GetIssue(e Execer, repoAt syntax.ATURI, issueId int) (*Issue, error) {
query := `select owner_did, created, title, body, open from issues where repo_at = ? and issue_id = ?`
row := e.QueryRow(query, repoAt, issueId)
···
return &issue, nil
}
-
func GetIssueWithComments(e Execer, repoAt string, issueId int) (*Issue, []Comment, error) {
+
func GetIssueWithComments(e Execer, repoAt syntax.ATURI, issueId int) (*Issue, []Comment, error) {
query := `select owner_did, issue_id, created, title, body, open from issues where repo_at = ? and issue_id = ?`
row := e.QueryRow(query, repoAt, issueId)
···
return err
}
-
func GetComments(e Execer, repoAt string, issueId int) ([]Comment, error) {
+
func GetComments(e Execer, repoAt syntax.ATURI, issueId int) ([]Comment, error) {
var comments []Comment
rows, err := e.Query(`select owner_did, issue_id, comment_id, comment_at, body, created from comments where repo_at = ? and issue_id = ? order by created asc`, repoAt, issueId)
···
return comments, nil
}
-
func CloseIssue(e Execer, repoAt string, issueId int) error {
+
func CloseIssue(e Execer, repoAt syntax.ATURI, issueId int) error {
_, err := e.Exec(`update issues set open = 0 where repo_at = ? and issue_id = ?`, repoAt, issueId)
return err
}
-
func ReopenIssue(e Execer, repoAt string, issueId int) error {
+
func ReopenIssue(e Execer, repoAt syntax.ATURI, issueId int) error {
_, err := e.Exec(`update issues set open = 1 where repo_at = ? and issue_id = ?`, repoAt, issueId)
return err
}
+
+
type IssueCount struct {
+
Open int
+
Closed int
+
}
+
+
func GetIssueCount(e Execer, repoAt syntax.ATURI) (IssueCount, error) {
+
row := e.QueryRow(`
+
select
+
count(case when open = 1 then 1 end) as open_count,
+
count(case when open = 0 then 1 end) as closed_count
+
from issues
+
where repo_at = ?`,
+
repoAt,
+
)
+
+
var count IssueCount
+
if err := row.Scan(&count.Open, &count.Closed); err != nil {
+
return IssueCount{0, 0}, err
+
}
+
+
return count, nil
+
}
+29 -2
appview/db/repos.go
···
AtUri string
}
-
func GetAllRepos(e Execer) ([]Repo, error) {
+
func GetAllRepos(e Execer, limit int) ([]Repo, error) {
var repos []Repo
-
rows, err := e.Query(`select did, name, knot, rkey, created from repos`)
+
rows, err := e.Query(
+
`select did, name, knot, rkey, created
+
from repos
+
order by created desc
+
limit ?
+
`,
+
limit,
+
)
if err != nil {
return nil, err
}
···
return &repo, nil
}
+
func GetRepoByAtUri(e Execer, atUri string) (*Repo, error) {
+
var repo Repo
+
+
row := e.QueryRow(`select did, name, knot, created, at_uri from repos where at_uri = ?`, atUri)
+
+
var createdAt string
+
if err := row.Scan(&repo.Did, &repo.Name, &repo.Knot, &createdAt, &repo.AtUri); err != nil {
+
return nil, err
+
}
+
createdAtTime, _ := time.Parse(time.RFC3339, createdAt)
+
repo.Created = createdAtTime
+
+
return &repo, nil
+
}
+
func AddRepo(e Execer, repo *Repo) error {
_, err := e.Exec(`insert into repos (did, name, knot, rkey, at_uri) values (?, ?, ?, ?, ?)`, repo.Did, repo.Name, repo.Knot, repo.Rkey, repo.AtUri)
return err
···
}
return repos, nil
+
}
+
+
type RepoStats struct {
+
StarCount int
+
IssueCount IssueCount
}
func scanRepo(rows *sql.Rows, did, name, knot, rkey *string, created *time.Time) error {
+150
appview/db/star.go
···
+
package db
+
+
import (
+
"log"
+
"time"
+
+
"github.com/bluesky-social/indigo/atproto/syntax"
+
)
+
+
type Star struct {
+
StarredByDid string
+
RepoAt syntax.ATURI
+
Repo *Repo
+
Created time.Time
+
Rkey string
+
}
+
+
func (star *Star) ResolveRepo(e Execer) error {
+
if star.Repo != nil {
+
return nil
+
}
+
+
repo, err := GetRepoByAtUri(e, star.RepoAt.String())
+
if err != nil {
+
return err
+
}
+
+
star.Repo = repo
+
return nil
+
}
+
+
func AddStar(e Execer, starredByDid string, repoAt syntax.ATURI, rkey string) error {
+
query := `insert or ignore into stars (starred_by_did, repo_at, rkey) values (?, ?, ?)`
+
_, err := e.Exec(query, starredByDid, repoAt, rkey)
+
return err
+
}
+
+
// Get a star record
+
func GetStar(e Execer, starredByDid string, repoAt syntax.ATURI) (*Star, error) {
+
query := `
+
select starred_by_did, repo_at, created, rkey
+
from stars
+
where starred_by_did = ? and repo_at = ?`
+
row := e.QueryRow(query, starredByDid, repoAt)
+
+
var star Star
+
var created string
+
err := row.Scan(&star.StarredByDid, &star.RepoAt, &created, &star.Rkey)
+
if err != nil {
+
return nil, err
+
}
+
+
createdAtTime, err := time.Parse(time.RFC3339, created)
+
if err != nil {
+
log.Println("unable to determine followed at time")
+
star.Created = time.Now()
+
} else {
+
star.Created = createdAtTime
+
}
+
+
return &star, nil
+
}
+
+
// Remove a star
+
func DeleteStar(e Execer, starredByDid string, repoAt syntax.ATURI) error {
+
_, err := e.Exec(`delete from stars where starred_by_did = ? and repo_at = ?`, starredByDid, repoAt)
+
return err
+
}
+
+
func GetStarCount(e Execer, repoAt syntax.ATURI) (int, error) {
+
stars := 0
+
err := e.QueryRow(
+
`select count(starred_by_did) from stars where repo_at = ?`, repoAt).Scan(&stars)
+
if err != nil {
+
return 0, err
+
}
+
return stars, nil
+
}
+
+
func GetStarStatus(e Execer, userDid string, repoAt syntax.ATURI) bool {
+
if _, err := GetStar(e, userDid, repoAt); err != nil {
+
return false
+
} else {
+
return true
+
}
+
}
+
+
func GetAllStars(e Execer, limit int) ([]Star, error) {
+
var stars []Star
+
+
rows, err := e.Query(`
+
select
+
s.starred_by_did,
+
s.repo_at,
+
s.rkey,
+
s.created,
+
r.did,
+
r.name,
+
r.knot,
+
r.rkey,
+
r.created,
+
r.at_uri
+
from stars s
+
join repos r on s.repo_at = r.at_uri
+
`)
+
+
if err != nil {
+
return nil, err
+
}
+
defer rows.Close()
+
+
for rows.Next() {
+
var star Star
+
var repo Repo
+
var starCreatedAt, repoCreatedAt string
+
+
if err := rows.Scan(
+
&star.StarredByDid,
+
&star.RepoAt,
+
&star.Rkey,
+
&starCreatedAt,
+
&repo.Did,
+
&repo.Name,
+
&repo.Knot,
+
&repo.Rkey,
+
&repoCreatedAt,
+
&repo.AtUri,
+
); err != nil {
+
return nil, err
+
}
+
+
star.Created, err = time.Parse(time.RFC3339, starCreatedAt)
+
if err != nil {
+
star.Created = time.Now()
+
}
+
repo.Created, err = time.Parse(time.RFC3339, repoCreatedAt)
+
if err != nil {
+
repo.Created = time.Now()
+
}
+
star.Repo = &repo
+
+
stars = append(stars, star)
+
}
+
+
if err := rows.Err(); err != nil {
+
return nil, err
+
}
+
+
return stars, nil
+
}
+20 -6
appview/db/timeline.go
···
type TimelineEvent struct {
*Repo
*Follow
+
*Star
EventAt time.Time
}
+
// TODO: this gathers heterogenous events from different sources and aggregates
+
// them in code; if we did this entirely in sql, we could order and limit and paginate easily
func MakeTimeline(e Execer) ([]TimelineEvent, error) {
var events []TimelineEvent
+
limit := 50
-
repos, err := GetAllRepos(e)
+
repos, err := GetAllRepos(e, limit)
+
if err != nil {
+
return nil, err
+
}
+
+
follows, err := GetAllFollows(e, limit)
if err != nil {
return nil, err
}
-
follows, err := GetAllFollows(e)
+
stars, err := GetAllStars(e, limit)
if err != nil {
return nil, err
}
···
for _, repo := range repos {
events = append(events, TimelineEvent{
Repo: &repo,
-
Follow: nil,
EventAt: repo.Created,
})
}
for _, follow := range follows {
events = append(events, TimelineEvent{
-
Repo: nil,
Follow: &follow,
EventAt: follow.FollowedAt,
})
}
+
for _, star := range stars {
+
events = append(events, TimelineEvent{
+
Star: &star,
+
EventAt: star.Created,
+
})
+
}
+
sort.Slice(events, func(i, j int) bool {
return events[i].EventAt.After(events[j].EventAt)
})
// Limit the slice to 100 events
-
if len(events) > 50 {
-
events = events[:50]
+
if len(events) > limit {
+
events = events[:limit]
}
return events, nil
+7
appview/pages/funcmap.go
···
"markdown": func(text string) template.HTML {
return template.HTML(renderMarkdown(text))
},
+
"isNil": func(t any) bool {
+
// returns false for other "zero" values
+
return t == nil
+
},
+
"not": func(t bool) bool {
+
return !t
+
},
}
}
+57 -2
appview/pages/pages.go
···
chromahtml "github.com/alecthomas/chroma/v2/formatters/html"
"github.com/alecthomas/chroma/v2/lexers"
"github.com/alecthomas/chroma/v2/styles"
+
"github.com/bluesky-social/indigo/atproto/syntax"
"github.com/microcosm-cc/bluemonday"
"github.com/sotangled/tangled/appview/auth"
"github.com/sotangled/tangled/appview/db"
···
name := strings.TrimPrefix(path, "templates/")
name = strings.TrimSuffix(name, ".html")
-
if !strings.HasPrefix(path, "templates/layouts/") {
+
// add fragments as templates
+
if strings.HasPrefix(path, "templates/fragments/") {
+
tmpl, err := template.New(name).
+
Funcs(funcMap()).
+
ParseFS(files, path)
+
if err != nil {
+
return fmt.Errorf("setting up fragment: %w", err)
+
}
+
+
templates[name] = tmpl
+
log.Printf("loaded fragment: %s", name)
+
}
+
+
// layouts and fragments are applied first
+
if !strings.HasPrefix(path, "templates/layouts/") &&
+
!strings.HasPrefix(path, "templates/fragments/") {
// Add the page template on top of the base
tmpl, err := template.New(name).
Funcs(funcMap()).
-
ParseFS(files, "templates/layouts/*.html", path)
+
ParseFS(files, "templates/layouts/*.html", "templates/fragments/*.html", path)
if err != nil {
return fmt.Errorf("setting up template: %w", err)
}
···
return p.execute("user/profile", w, params)
}
+
type FollowFragmentParams struct {
+
UserDid string
+
FollowStatus db.FollowStatus
+
}
+
+
func (p *Pages) FollowFragment(w io.Writer, params FollowFragmentParams) error {
+
return p.executePlain("fragments/follow", w, params)
+
}
+
+
type StarFragmentParams struct {
+
IsStarred bool
+
RepoAt syntax.ATURI
+
Stats db.RepoStats
+
}
+
+
func (p *Pages) StarFragment(w io.Writer, params StarFragmentParams) error {
+
return p.executePlain("fragments/star", w, params)
+
}
+
type RepoInfo struct {
Name string
OwnerDid string
OwnerHandle string
Description string
Knot string
+
RepoAt syntax.ATURI
SettingsAllowed bool
+
IsStarred bool
+
Stats db.RepoStats
}
func (r RepoInfo) OwnerWithAt() string {
···
}
return tabs
+
}
+
+
// each tab on a repo could have some metadata:
+
//
+
// issues -> number of open issues etc.
+
// settings -> a warning icon to setup branch protection? idk
+
//
+
// we gather these bits of info here, because go templates
+
// are difficult to program in
+
func (r RepoInfo) TabMetadata() map[string]any {
+
meta := make(map[string]any)
+
+
meta["issues"] = r.Stats.IssueCount.Open
+
+
// more stuff?
+
+
return meta
}
type RepoIndexParams struct {
+17
appview/pages/templates/fragments/follow.html
···
+
{{ define "fragments/follow" }}
+
<button id="followBtn"
+
class="btn mt-2 w-full"
+
+
{{ if eq .FollowStatus.String "IsNotFollowing" }}
+
hx-post="/follow?subject={{.UserDid}}"
+
{{ else }}
+
hx-delete="/follow?subject={{.UserDid}}"
+
{{ end }}
+
+
hx-trigger="click"
+
hx-target="#followBtn"
+
hx-swap="outerHTML"
+
>
+
{{ if eq .FollowStatus.String "IsNotFollowing" }}Follow{{ else }}Unfollow{{ end }}
+
</button>
+
{{ end }}
+36
appview/pages/templates/fragments/star.html
···
+
{{ define "fragments/star" }}
+
<button id="starBtn"
+
class="btn text-sm disabled:opacity-50 disabled:cursor-not-allowed"
+
+
{{ if .IsStarred }}
+
hx-delete="/star?subject={{.RepoAt}}&countHint={{.Stats.StarCount}}"
+
{{ else }}
+
hx-post="/star?subject={{.RepoAt}}&countHint={{.Stats.StarCount}}"
+
{{ end }}
+
+
hx-trigger="click"
+
hx-target="#starBtn"
+
hx-swap="outerHTML"
+
hx-disabled-elt="#starBtn"
+
>
+
<div class="flex gap-2 items-center">
+
{{ if .IsStarred }}
+
<span class="w-3 h-3 fill-current" data-lucide="star"></span>
+
{{ else }}
+
<span class="w-3 h-3" data-lucide="star"></span>
+
{{ end }}
+
<span>
+
{{ .Stats.StarCount }}
+
</span>
+
<span id="starSpinner" class="hidden">
+
loading
+
</span>
+
</div>
+
</button>
+
<script>
+
document.body.addEventListener('htmx:afterRequest', function (evt) {
+
lucide.createIcons();
+
});
+
</script>
+
{{ end }}
+
+19 -11
appview/pages/templates/layouts/repobase.html
···
{{ define "content" }}
<section id="repo-header" class="mb-4 py-2 px-6">
+
<div class="flex gap-3">
<p class="text-lg">
-
<a href="/{{ .RepoInfo.OwnerWithAt }}">{{ .RepoInfo.OwnerWithAt }}</a>
-
<span class="select-none">/</span>
-
<a href="/{{ .RepoInfo.FullName }}" class="font-bold">{{ .RepoInfo.Name }}</a>
+
<a href="/{{ .RepoInfo.OwnerWithAt }}">{{ .RepoInfo.OwnerWithAt }}</a>
+
<span class="select-none">/</span>
+
<a href="/{{ .RepoInfo.FullName }}" class="font-bold">{{ .RepoInfo.Name }}</a>
</p>
-
<span>
-
{{ if .RepoInfo.Description }}
-
{{ .RepoInfo.Description }}
-
{{ else }}
-
<span class="italic">this repo has no description</span>
-
{{ end }}
-
</span>
+
{{ template "fragments/star" .RepoInfo }}
+
</div>
+
<span>
+
{{ if .RepoInfo.Description }}
+
{{ .RepoInfo.Description }}
+
{{ else }}
+
<span class="italic">this repo has no description</span>
+
{{ end }}
+
</span>
</section>
<section id="repo-links" class="min-h-screen flex flex-col drop-shadow-sm">
<nav class="w-full mx-auto ml-4">
<div class="flex z-60">
{{ $activeTabStyles := "-mb-px bg-white" }}
{{ $tabs := .RepoInfo.GetTabs }}
+
{{ $tabmeta := .RepoInfo.TabMetadata }}
{{ range $item := $tabs }}
{{ $key := index $item 0 }}
{{ $value := index $item 1 }}
+
{{ $meta := index $tabmeta $key }}
<a
href="/{{ $.RepoInfo.FullName }}{{ $value }}"
class="relative -mr-px group no-underline hover:no-underline"
···
{{ end }}
"
>
-
{{ $key }}
+
{{ $key }}
+
{{ if not (isNil $meta) }}
+
<span class="bg-gray-200 rounded py-1/2 px-1 text-sm font-mono">{{ $meta }}</span>
+
{{ end }}
</div>
</a>
{{ end }}
+31 -19
appview/pages/templates/timeline.html
···
{{ range .Timeline }}
<div class="px-6 py-2 bg-white rounded drop-shadow-sm w-fit">
{{ if .Repo }}
-
{{ $userHandle := index $.DidHandleMap .Repo.Did }}
-
<div class="flex items-center">
-
<p class="text-gray-600">
-
<a href="/{{ $userHandle }}" class="no-underline hover:underline">{{ $userHandle }}</a>
-
created
-
<a href="/{{ $userHandle }}/{{ .Repo.Name }}" class="no-underline hover:underline">{{ .Repo.Name }}</a>
-
<time class="text-gray-700">{{ .Repo.Created | timeFmt }}</time>
-
</p>
-
</div>
+
{{ $userHandle := index $.DidHandleMap .Repo.Did }}
+
<div class="flex items-center">
+
<p class="text-gray-600">
+
<a href="/{{ $userHandle }}" class="no-underline hover:underline">{{ $userHandle }}</a>
+
created
+
<a href="/{{ $userHandle }}/{{ .Repo.Name }}" class="no-underline hover:underline">{{ .Repo.Name }}</a>
+
<time class="text-gray-700">{{ .Repo.Created | timeFmt }}</time>
+
</p>
+
</div>
{{ else if .Follow }}
-
{{ $userHandle := index $.DidHandleMap .Follow.UserDid }}
-
{{ $subjectHandle := index $.DidHandleMap .Follow.SubjectDid }}
-
<div class="flex items-center">
-
<p class="text-gray-600">
-
<a href="/{{ $userHandle }}" class="no-underline hover:underline">{{ $userHandle }}</a>
-
followed
-
<a href="/{{ $subjectHandle }}" class="no-underline hover:underline">{{ $subjectHandle }}</a>
-
<time class="text-gray-700">{{ .Follow.FollowedAt | timeFmt }}</time>
-
</p>
-
</div>
+
{{ $userHandle := index $.DidHandleMap .Follow.UserDid }}
+
{{ $subjectHandle := index $.DidHandleMap .Follow.SubjectDid }}
+
<div class="flex items-center">
+
<p class="text-gray-600">
+
<a href="/{{ $userHandle }}" class="no-underline hover:underline">{{ $userHandle }}</a>
+
followed
+
<a href="/{{ $subjectHandle }}" class="no-underline hover:underline">{{ $subjectHandle }}</a>
+
<time class="text-gray-700">{{ .Follow.FollowedAt | timeFmt }}</time>
+
</p>
+
</div>
+
{{ else if .Star }}
+
{{ $starrerHandle := index $.DidHandleMap .Star.StarredByDid }}
+
{{ $repoOwnerHandle := index $.DidHandleMap .Star.Repo.Did }}
+
<div class="flex items-center">
+
<p class="text-gray-600">
+
<a href="/{{ $starrerHandle }}" class="no-underline hover:underline">{{ $starrerHandle }}</a>
+
starred
+
<a href="/{{ $repoOwnerHandle }}/{{ .Star.Repo.Name }}" class="no-underline hover:underline">{{ $repoOwnerHandle }}/{{ .Star.Repo.Name }}</a>
+
<time class="text-gray-700">{{ .Star.Created | timeFmt }}</time>
+
</p>
+
</div>
{{ end }}
</div>
{{ end }}
</div>
</div>
{{ end }}
+
+2 -14
appview/pages/templates/user/profile.html
···
</div>
{{ if ne .FollowStatus.String "IsSelf" }}
-
<button id="followBtn"
-
class="btn mt-2 w-full"
-
{{ if eq .FollowStatus.String "IsNotFollowing" }}
-
hx-post="/follow?subject={{.UserDid}}"
-
{{ else }}
-
hx-delete="/follow?subject={{.UserDid}}"
-
{{ end }}
-
hx-trigger="click"
-
hx-target="#followBtn"
-
hx-swap="outerHTML"
-
>
-
{{ if eq .FollowStatus.String "IsNotFollowing" }}Follow{{ else }}Unfollow{{ end }}
-
</button>
-
{{ end }}
+
{{ template "fragments/follow" . }}
+
{{ end }}
</div>
{{ end }}
+11 -22
appview/state/follow.go
···
package state
import (
-
"fmt"
"log"
"net/http"
"time"
···
lexutil "github.com/bluesky-social/indigo/lex/util"
tangled "github.com/sotangled/tangled/api/tangled"
"github.com/sotangled/tangled/appview/db"
+
"github.com/sotangled/tangled/appview/pages"
)
func (s *State) Follow(w http.ResponseWriter, r *http.Request) {
···
log.Println("created atproto record: ", resp.Uri)
-
w.Write([]byte(fmt.Sprintf(`
-
<button id="followBtn"
-
class="btn mt-2 w-full"
-
hx-delete="/follow?subject=%s"
-
hx-trigger="click"
-
hx-target="#followBtn"
-
hx-swap="outerHTML">
-
Unfollow
-
</button>
-
`, subjectIdent.DID.String())))
+
s.pages.FollowFragment(w, pages.FollowFragmentParams{
+
UserDid: subjectIdent.DID.String(),
+
FollowStatus: db.IsFollowing,
+
})
return
case http.MethodDelete:
···
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
Collection: tangled.GraphFollowNSID,
Repo: currentUser.Did,
-
Rkey: follow.RKey,
+
Rkey: follow.Rkey,
})
if err != nil {
···
// this is not an issue, the firehose event might have already done this
}
-
w.Write([]byte(fmt.Sprintf(`
-
<button id="followBtn"
-
class="btn mt-2 w-full"
-
hx-post="/follow?subject=%s"
-
hx-trigger="click"
-
hx-target="#followBtn"
-
hx-swap="outerHTML">
-
Follow
-
</button>
-
`, subjectIdent.DID.String())))
+
s.pages.FollowFragment(w, pages.FollowFragmentParams{
+
UserDid: subjectIdent.DID.String(),
+
FollowStatus: db.IsNotFollowing,
+
})
+
return
}
+20
appview/state/jetstream.go
···
"fmt"
"log"
+
"github.com/bluesky-social/indigo/atproto/syntax"
"github.com/bluesky-social/jetstream/pkg/models"
tangled "github.com/sotangled/tangled/api/tangled"
"github.com/sotangled/tangled/appview/db"
···
return err
}
err = db.AddFollow(d, did, record.Subject, e.Commit.RKey)
+
if err != nil {
+
return fmt.Errorf("failed to add follow to db: %w", err)
+
}
+
case tangled.FeedStarNSID:
+
record := tangled.FeedStar{}
+
err := json.Unmarshal(raw, &record)
+
if err != nil {
+
log.Println("invalid record")
+
return err
+
}
+
+
subjectUri, err := syntax.ParseATURI(record.Subject)
+
+
if err != nil {
+
log.Println("invalid record")
+
return err
+
}
+
+
err = db.AddStar(d, did, subjectUri, e.Commit.RKey)
if err != nil {
return fmt.Errorf("failed to add follow to db: %w", err)
}
+73 -95
appview/state/repo.go
···
"time"
"github.com/bluesky-social/indigo/atproto/identity"
+
"github.com/bluesky-social/indigo/atproto/syntax"
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/go-chi/chi/v5"
"github.com/sotangled/tangled/api/tangled"
···
user := s.auth.GetUser(r)
-
knot := f.Knot
-
if knot == "knot1.tangled.sh" {
-
knot = "tangled.sh"
-
}
-
s.pages.RepoIndexPage(w, pages.RepoIndexParams{
-
LoggedInUser: user,
-
RepoInfo: pages.RepoInfo{
-
OwnerDid: f.OwnerDid(),
-
OwnerHandle: f.OwnerHandle(),
-
Name: f.RepoName,
-
Knot: knot,
-
SettingsAllowed: settingsAllowed(s, user, f),
-
},
+
LoggedInUser: user,
+
RepoInfo: f.RepoInfo(s, user),
TagMap: tagMap,
RepoIndexResponse: result,
})
···
user := s.auth.GetUser(r)
s.pages.RepoLog(w, pages.RepoLogParams{
-
LoggedInUser: user,
-
RepoInfo: pages.RepoInfo{
-
OwnerDid: f.OwnerDid(),
-
OwnerHandle: f.OwnerHandle(),
-
Name: f.RepoName,
-
SettingsAllowed: settingsAllowed(s, user, f),
-
},
+
LoggedInUser: user,
+
RepoInfo: f.RepoInfo(s, user),
RepoLogResponse: repolog,
})
return
···
user := s.auth.GetUser(r)
s.pages.RepoCommit(w, pages.RepoCommitParams{
-
LoggedInUser: user,
-
RepoInfo: pages.RepoInfo{
-
OwnerDid: f.OwnerDid(),
-
OwnerHandle: f.OwnerHandle(),
-
Name: f.RepoName,
-
SettingsAllowed: settingsAllowed(s, user, f),
-
},
+
LoggedInUser: user,
+
RepoInfo: f.RepoInfo(s, user),
RepoCommitResponse: result,
})
return
···
baseBlobLink := path.Join(f.OwnerDid(), f.RepoName, "blob", ref, treePath)
s.pages.RepoTree(w, pages.RepoTreeParams{
-
LoggedInUser: user,
-
BreadCrumbs: breadcrumbs,
-
BaseTreeLink: baseTreeLink,
-
BaseBlobLink: baseBlobLink,
-
RepoInfo: pages.RepoInfo{
-
OwnerDid: f.OwnerDid(),
-
OwnerHandle: f.OwnerHandle(),
-
Name: f.RepoName,
-
SettingsAllowed: settingsAllowed(s, user, f),
-
},
+
LoggedInUser: user,
+
BreadCrumbs: breadcrumbs,
+
BaseTreeLink: baseTreeLink,
+
BaseBlobLink: baseBlobLink,
+
RepoInfo: f.RepoInfo(s, user),
RepoTreeResponse: result,
})
return
···
user := s.auth.GetUser(r)
s.pages.RepoTags(w, pages.RepoTagsParams{
-
LoggedInUser: user,
-
RepoInfo: pages.RepoInfo{
-
OwnerDid: f.OwnerDid(),
-
OwnerHandle: f.OwnerHandle(),
-
Name: f.RepoName,
-
SettingsAllowed: settingsAllowed(s, user, f),
-
},
+
LoggedInUser: user,
+
RepoInfo: f.RepoInfo(s, user),
RepoTagsResponse: result,
})
return
···
user := s.auth.GetUser(r)
s.pages.RepoBranches(w, pages.RepoBranchesParams{
-
LoggedInUser: user,
-
RepoInfo: pages.RepoInfo{
-
OwnerDid: f.OwnerDid(),
-
OwnerHandle: f.OwnerHandle(),
-
Name: f.RepoName,
-
SettingsAllowed: settingsAllowed(s, user, f),
-
},
+
LoggedInUser: user,
+
RepoInfo: f.RepoInfo(s, user),
RepoBranchesResponse: result,
})
return
···
user := s.auth.GetUser(r)
s.pages.RepoBlob(w, pages.RepoBlobParams{
-
LoggedInUser: user,
-
RepoInfo: pages.RepoInfo{
-
OwnerDid: f.OwnerDid(),
-
OwnerHandle: f.OwnerHandle(),
-
Name: f.RepoName,
-
SettingsAllowed: settingsAllowed(s, user, f),
-
},
+
LoggedInUser: user,
+
RepoInfo: f.RepoInfo(s, user),
RepoBlobResponse: result,
BreadCrumbs: breadcrumbs,
})
···
}
s.pages.RepoSettings(w, pages.RepoSettingsParams{
-
LoggedInUser: user,
-
RepoInfo: pages.RepoInfo{
-
OwnerDid: f.OwnerDid(),
-
OwnerHandle: f.OwnerHandle(),
-
Name: f.RepoName,
-
SettingsAllowed: settingsAllowed(s, user, f),
-
},
+
LoggedInUser: user,
+
RepoInfo: f.RepoInfo(s, user),
Collaborators: repoCollaborators,
IsCollaboratorInviteAllowed: isCollaboratorInviteAllowed,
})
···
Knot string
OwnerId identity.Identity
RepoName string
-
RepoAt string
+
RepoAt syntax.ATURI
}
func (f *FullyResolvedRepo) OwnerDid() string {
···
return collaborators, nil
}
+
func (f *FullyResolvedRepo) RepoInfo(s *State, u *auth.User) pages.RepoInfo {
+
isStarred := false
+
if u != nil {
+
isStarred = db.GetStarStatus(s.db, u.Did, syntax.ATURI(f.RepoAt))
+
}
+
+
starCount, err := db.GetStarCount(s.db, f.RepoAt)
+
if err != nil {
+
log.Println("failed to get star count for ", f.RepoAt)
+
}
+
issueCount, err := db.GetIssueCount(s.db, f.RepoAt)
+
if err != nil {
+
log.Println("failed to get issue count for ", f.RepoAt)
+
}
+
+
knot := f.Knot
+
if knot == "knot1.tangled.sh" {
+
knot = "tangled.sh"
+
}
+
+
return pages.RepoInfo{
+
OwnerDid: f.OwnerDid(),
+
OwnerHandle: f.OwnerHandle(),
+
Name: f.RepoName,
+
RepoAt: f.RepoAt,
+
SettingsAllowed: settingsAllowed(s, u, f),
+
IsStarred: isStarred,
+
Knot: knot,
+
Stats: db.RepoStats{
+
StarCount: starCount,
+
IssueCount: issueCount,
+
},
+
}
+
}
+
func (s *State) RepoSingleIssue(w http.ResponseWriter, r *http.Request) {
user := s.auth.GetUser(r)
f, err := fullyResolvedRepo(r)
···
s.pages.RepoSingleIssue(w, pages.RepoSingleIssueParams{
LoggedInUser: user,
-
RepoInfo: pages.RepoInfo{
-
OwnerDid: f.OwnerDid(),
-
OwnerHandle: f.OwnerHandle(),
-
Name: f.RepoName,
-
SettingsAllowed: settingsAllowed(s, user, f),
-
},
-
Issue: *issue,
-
Comments: comments,
+
RepoInfo: f.RepoInfo(s, user),
+
Issue: *issue,
+
Comments: comments,
IssueOwnerHandle: issueOwnerIdent.Handle.String(),
DidHandleMap: didHandleMap,
···
return
}
+
atUri := f.RepoAt.String()
client, _ := s.auth.AuthorizedClient(r)
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
Collection: tangled.RepoIssueCommentNSID,
···
Rkey: s.TID(),
Record: &lexutil.LexiconTypeDecoder{
Val: &tangled.RepoIssueComment{
-
Repo: &f.RepoAt,
+
Repo: &atUri,
Issue: issueAt,
CommentId: &commentIdInt64,
Owner: &ownerDid,
···
s.pages.RepoIssues(w, pages.RepoIssuesParams{
LoggedInUser: s.auth.GetUser(r),
-
RepoInfo: pages.RepoInfo{
-
OwnerDid: f.OwnerDid(),
-
OwnerHandle: f.OwnerHandle(),
-
Name: f.RepoName,
-
SettingsAllowed: settingsAllowed(s, user, f),
-
},
+
RepoInfo: f.RepoInfo(s, user),
Issues: issues,
DidHandleMap: didHandleMap,
})
···
case http.MethodGet:
s.pages.RepoNewIssue(w, pages.RepoNewIssueParams{
LoggedInUser: user,
-
RepoInfo: pages.RepoInfo{
-
Name: f.RepoName,
-
OwnerDid: f.OwnerDid(),
-
OwnerHandle: f.OwnerHandle(),
-
SettingsAllowed: settingsAllowed(s, user, f),
-
},
+
RepoInfo: f.RepoInfo(s, user),
})
case http.MethodPost:
title := r.FormValue("title")
···
}
client, _ := s.auth.AuthorizedClient(r)
+
atUri := f.RepoAt.String()
resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
Collection: tangled.RepoIssueNSID,
Repo: user.Did,
Rkey: s.TID(),
Record: &lexutil.LexiconTypeDecoder{
Val: &tangled.RepoIssue{
-
Repo: f.RepoAt,
+
Repo: atUri,
Title: title,
Body: &body,
Owner: user.Did,
···
case http.MethodGet:
s.pages.RepoPulls(w, pages.RepoPullsParams{
LoggedInUser: user,
-
RepoInfo: pages.RepoInfo{
-
Name: f.RepoName,
-
OwnerDid: f.OwnerDid(),
-
OwnerHandle: f.OwnerHandle(),
-
SettingsAllowed: settingsAllowed(s, user, f),
-
},
+
RepoInfo: f.RepoInfo(s, user),
})
}
}
···
return nil, fmt.Errorf("malformed middleware")
}
+
parsedRepoAt, err := syntax.ParseATURI(repoAt)
+
if err != nil {
+
log.Println("malformed repo at-uri")
+
return nil, fmt.Errorf("malformed middleware")
+
}
+
return &FullyResolvedRepo{
Knot: knot,
OwnerId: id,
RepoName: repoName,
-
RepoAt: repoAt,
+
RepoAt: parsedRepoAt,
}, nil
}
+115
appview/state/star.go
···
+
package state
+
+
import (
+
"log"
+
"net/http"
+
"time"
+
+
comatproto "github.com/bluesky-social/indigo/api/atproto"
+
"github.com/bluesky-social/indigo/atproto/syntax"
+
lexutil "github.com/bluesky-social/indigo/lex/util"
+
tangled "github.com/sotangled/tangled/api/tangled"
+
"github.com/sotangled/tangled/appview/db"
+
"github.com/sotangled/tangled/appview/pages"
+
)
+
+
func (s *State) Star(w http.ResponseWriter, r *http.Request) {
+
currentUser := s.auth.GetUser(r)
+
+
subject := r.URL.Query().Get("subject")
+
if subject == "" {
+
log.Println("invalid form")
+
return
+
}
+
+
subjectUri, err := syntax.ParseATURI(subject)
+
if err != nil {
+
log.Println("invalid form")
+
return
+
}
+
+
client, _ := s.auth.AuthorizedClient(r)
+
+
switch r.Method {
+
case http.MethodPost:
+
createdAt := time.Now().Format(time.RFC3339)
+
rkey := s.TID()
+
resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
+
Collection: tangled.FeedStarNSID,
+
Repo: currentUser.Did,
+
Rkey: rkey,
+
Record: &lexutil.LexiconTypeDecoder{
+
Val: &tangled.FeedStar{
+
Subject: subjectUri.String(),
+
CreatedAt: createdAt,
+
}},
+
})
+
if err != nil {
+
log.Println("failed to create atproto record", err)
+
return
+
}
+
+
err = db.AddStar(s.db, currentUser.Did, subjectUri, rkey)
+
if err != nil {
+
log.Println("failed to star", err)
+
return
+
}
+
+
starCount, err := db.GetStarCount(s.db, subjectUri)
+
if err != nil {
+
log.Println("failed to get star count for ", subjectUri)
+
}
+
+
log.Println("created atproto record: ", resp.Uri)
+
+
s.pages.StarFragment(w, pages.StarFragmentParams{
+
IsStarred: true,
+
RepoAt: subjectUri,
+
Stats: db.RepoStats{
+
StarCount: starCount,
+
},
+
})
+
+
return
+
case http.MethodDelete:
+
// find the record in the db
+
star, err := db.GetStar(s.db, currentUser.Did, subjectUri)
+
if err != nil {
+
log.Println("failed to get star relationship")
+
return
+
}
+
+
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
+
Collection: tangled.FeedStarNSID,
+
Repo: currentUser.Did,
+
Rkey: star.Rkey,
+
})
+
+
if err != nil {
+
log.Println("failed to unstar")
+
return
+
}
+
+
err = db.DeleteStar(s.db, currentUser.Did, subjectUri)
+
if err != nil {
+
log.Println("failed to delete star from DB")
+
// this is not an issue, the firehose event might have already done this
+
}
+
+
starCount, err := db.GetStarCount(s.db, subjectUri)
+
if err != nil {
+
log.Println("failed to get star count for ", subjectUri)
+
}
+
+
s.pages.StarFragment(w, pages.StarFragmentParams{
+
IsStarred: false,
+
RepoAt: subjectUri,
+
Stats: db.RepoStats{
+
StarCount: starCount,
+
},
+
})
+
+
return
+
}
+
+
}
+9 -2
appview/state/state.go
···
didsToResolve = append(didsToResolve, ev.Repo.Did)
}
if ev.Follow != nil {
-
didsToResolve = append(didsToResolve, ev.Follow.UserDid)
-
didsToResolve = append(didsToResolve, ev.Follow.SubjectDid)
+
didsToResolve = append(didsToResolve, ev.Follow.UserDid, ev.Follow.SubjectDid)
+
}
+
if ev.Star != nil {
+
didsToResolve = append(didsToResolve, ev.Star.StarredByDid, ev.Star.Repo.Did)
}
}
···
r.With(AuthMiddleware(s)).Route("/follow", func(r chi.Router) {
r.Post("/", s.Follow)
r.Delete("/", s.Follow)
+
})
+
+
r.With(AuthMiddleware(s)).Route("/star", func(r chi.Router) {
+
r.Post("/", s.Star)
+
r.Delete("/", s.Star)
})
r.Route("/settings", func(r chi.Router) {
+6 -5
cmd/gen.go
···
if err := genCfg.WriteMapEncodersToFile(
"api/tangled/cbor_gen.go",
"tangled",
+
shtangled.FeedStar{},
+
shtangled.GraphFollow{},
+
shtangled.KnotMember{},
shtangled.PublicKey{},
-
shtangled.KnotMember{},
-
shtangled.GraphFollow{},
+
shtangled.RepoIssueComment{},
+
shtangled.RepoIssueState{},
+
shtangled.RepoIssue{},
shtangled.Repo{},
-
shtangled.RepoIssue{},
-
shtangled.RepoIssueState{},
-
shtangled.RepoIssueComment{},
); err != nil {
panic(err)
}
+31
lexicons/star.json
···
+
{
+
"lexicon": 1,
+
"id": "sh.tangled.feed.star",
+
"needsCbor": true,
+
"needsType": true,
+
"defs": {
+
"main": {
+
"type": "record",
+
"key": "tid",
+
"record": {
+
"type": "object",
+
"required": [
+
"createdAt",
+
"subject"
+
],
+
"properties": {
+
"createdAt": {
+
"type": "string",
+
"format": "datetime"
+
},
+
"subject": {
+
"type": "string",
+
"format": "at-uri"
+
}
+
}
+
}
+
}
+
}
+
}
+
+