forked from tangled.org/core
this repo has no description

add stars to tangled

+693 -529
api/tangled/cbor_gen.go
··· 18 var _ = math.E 19 var _ = sort.Sort 20 21 - func (t *PublicKey) MarshalCBOR(w io.Writer) error { 22 if t == nil { 23 _, err := w.Write(cbg.CborNull) 24 return err ··· 26 27 cw := cbg.NewCborWriter(w) 28 29 - if _, err := cw.Write([]byte{164}); err != nil { 30 return err 31 } 32 33 - // t.Key (string) (string) 34 - if len("key") > 1000000 { 35 - return xerrors.Errorf("Value in field \"key\" was too long") 36 } 37 38 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("key"))); err != nil { 39 return err 40 } 41 - if _, err := cw.WriteString(string("key")); err != nil { 42 return err 43 } 44 45 - if len(t.Key) > 1000000 { 46 - return xerrors.Errorf("Value in field t.Key was too long") 47 - } 48 - 49 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Key))); err != nil { 50 return err 51 } 52 - if _, err := cw.WriteString(string(t.Key)); err != nil { 53 return err 54 } 55 56 - // t.Name (string) (string) 57 - if len("name") > 1000000 { 58 - return xerrors.Errorf("Value in field \"name\" was too long") 59 } 60 61 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("name"))); err != nil { 62 return err 63 } 64 - if _, err := cw.WriteString(string("name")); err != nil { 65 return err 66 } 67 68 - if len(t.Name) > 1000000 { 69 - return xerrors.Errorf("Value in field t.Name was too long") 70 } 71 72 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Name))); err != nil { 73 return err 74 } 75 - if _, err := cw.WriteString(string(t.Name)); err != nil { 76 return err 77 } 78 79 - // t.LexiconTypeID (string) (string) 80 - if len("$type") > 1000000 { 81 - return xerrors.Errorf("Value in field \"$type\" was too long") 82 - } 83 - 84 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("$type"))); err != nil { 85 - return err 86 - } 87 - if _, err := cw.WriteString(string("$type")); err != nil { 88 - return err 89 - } 90 - 91 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.publicKey"))); err != nil { 92 - return err 93 - } 94 - if _, err := cw.WriteString(string("sh.tangled.publicKey")); err != nil { 95 - return err 96 - } 97 - 98 - // t.Created (string) (string) 99 - if len("created") > 1000000 { 100 - return xerrors.Errorf("Value in field \"created\" was too long") 101 } 102 103 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("created"))); err != nil { 104 return err 105 } 106 - if _, err := cw.WriteString(string("created")); err != nil { 107 return err 108 } 109 110 - if len(t.Created) > 1000000 { 111 - return xerrors.Errorf("Value in field t.Created was too long") 112 } 113 114 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Created))); err != nil { 115 return err 116 } 117 - if _, err := cw.WriteString(string(t.Created)); err != nil { 118 return err 119 } 120 return nil 121 } 122 123 - func (t *PublicKey) UnmarshalCBOR(r io.Reader) (err error) { 124 - *t = PublicKey{} 125 126 cr := cbg.NewCborReader(r) 127 ··· 140 } 141 142 if extra > cbg.MaxLength { 143 - return fmt.Errorf("PublicKey: map struct too large (%d)", extra) 144 } 145 146 n := extra 147 148 - nameBuf := make([]byte, 7) 149 for i := uint64(0); i < n; i++ { 150 nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000) 151 if err != nil { ··· 161 } 162 163 switch string(nameBuf[:nameLen]) { 164 - // t.Key (string) (string) 165 - case "key": 166 - 167 - { 168 - sval, err := cbg.ReadStringWithMax(cr, 1000000) 169 - if err != nil { 170 - return err 171 - } 172 - 173 - t.Key = string(sval) 174 - } 175 - // t.Name (string) (string) 176 - case "name": 177 178 { 179 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 181 return err 182 } 183 184 - t.Name = string(sval) 185 } 186 - // t.LexiconTypeID (string) (string) 187 - case "$type": 188 189 { 190 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 192 return err 193 } 194 195 - t.LexiconTypeID = string(sval) 196 } 197 - // t.Created (string) (string) 198 - case "created": 199 200 { 201 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 203 return err 204 } 205 206 - t.Created = string(sval) 207 } 208 209 default: ··· 216 217 return nil 218 } 219 - func (t *KnotMember) MarshalCBOR(w io.Writer) error { 220 if t == nil { 221 _, err := w.Write(cbg.CborNull) 222 return err 223 } 224 225 cw := cbg.NewCborWriter(w) 226 - fieldCount := 4 227 228 - if t.AddedAt == nil { 229 - fieldCount-- 230 - } 231 - 232 - if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil { 233 return err 234 } 235 ··· 245 return err 246 } 247 248 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.knot.member"))); err != nil { 249 return err 250 } 251 - if _, err := cw.WriteString(string("sh.tangled.knot.member")); err != nil { 252 return err 253 } 254 255 - // t.Domain (string) (string) 256 - if len("domain") > 1000000 { 257 - return xerrors.Errorf("Value in field \"domain\" was too long") 258 } 259 260 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("domain"))); err != nil { 261 return err 262 } 263 - if _, err := cw.WriteString(string("domain")); err != nil { 264 return err 265 } 266 267 - if len(t.Domain) > 1000000 { 268 - return xerrors.Errorf("Value in field t.Domain was too long") 269 } 270 271 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Domain))); err != nil { 272 return err 273 } 274 - if _, err := cw.WriteString(string(t.Domain)); err != nil { 275 return err 276 } 277 278 - // t.Member (string) (string) 279 - if len("member") > 1000000 { 280 - return xerrors.Errorf("Value in field \"member\" was too long") 281 } 282 283 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("member"))); err != nil { 284 return err 285 } 286 - if _, err := cw.WriteString(string("member")); err != nil { 287 return err 288 } 289 290 - if len(t.Member) > 1000000 { 291 - return xerrors.Errorf("Value in field t.Member was too long") 292 } 293 294 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Member))); err != nil { 295 return err 296 } 297 - if _, err := cw.WriteString(string(t.Member)); err != nil { 298 return err 299 } 300 - 301 - // t.AddedAt (string) (string) 302 - if t.AddedAt != nil { 303 - 304 - if len("addedAt") > 1000000 { 305 - return xerrors.Errorf("Value in field \"addedAt\" was too long") 306 - } 307 - 308 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("addedAt"))); err != nil { 309 - return err 310 - } 311 - if _, err := cw.WriteString(string("addedAt")); err != nil { 312 - return err 313 - } 314 - 315 - if t.AddedAt == nil { 316 - if _, err := cw.Write(cbg.CborNull); err != nil { 317 - return err 318 - } 319 - } else { 320 - if len(*t.AddedAt) > 1000000 { 321 - return xerrors.Errorf("Value in field t.AddedAt was too long") 322 - } 323 - 324 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.AddedAt))); err != nil { 325 - return err 326 - } 327 - if _, err := cw.WriteString(string(*t.AddedAt)); err != nil { 328 - return err 329 - } 330 - } 331 - } 332 return nil 333 } 334 335 - func (t *KnotMember) UnmarshalCBOR(r io.Reader) (err error) { 336 - *t = KnotMember{} 337 338 cr := cbg.NewCborReader(r) 339 ··· 352 } 353 354 if extra > cbg.MaxLength { 355 - return fmt.Errorf("KnotMember: map struct too large (%d)", extra) 356 } 357 358 n := extra 359 360 - nameBuf := make([]byte, 7) 361 for i := uint64(0); i < n; i++ { 362 nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000) 363 if err != nil { ··· 384 385 t.LexiconTypeID = string(sval) 386 } 387 - // t.Domain (string) (string) 388 - case "domain": 389 390 { 391 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 393 return err 394 } 395 396 - t.Domain = string(sval) 397 } 398 - // t.Member (string) (string) 399 - case "member": 400 401 { 402 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 404 return err 405 } 406 407 - t.Member = string(sval) 408 - } 409 - // t.AddedAt (string) (string) 410 - case "addedAt": 411 - 412 - { 413 - b, err := cr.ReadByte() 414 - if err != nil { 415 - return err 416 - } 417 - if b != cbg.CborNull[0] { 418 - if err := cr.UnreadByte(); err != nil { 419 - return err 420 - } 421 - 422 - sval, err := cbg.ReadStringWithMax(cr, 1000000) 423 - if err != nil { 424 - return err 425 - } 426 - 427 - t.AddedAt = (*string)(&sval) 428 - } 429 } 430 431 default: ··· 438 439 return nil 440 } 441 - func (t *GraphFollow) MarshalCBOR(w io.Writer) error { 442 if t == nil { 443 _, err := w.Write(cbg.CborNull) 444 return err 445 } 446 447 cw := cbg.NewCborWriter(w) 448 449 - if _, err := cw.Write([]byte{163}); err != nil { 450 return err 451 } 452 ··· 462 return err 463 } 464 465 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.graph.follow"))); err != nil { 466 return err 467 } 468 - if _, err := cw.WriteString(string("sh.tangled.graph.follow")); err != nil { 469 return err 470 } 471 472 - // t.Subject (string) (string) 473 - if len("subject") > 1000000 { 474 - return xerrors.Errorf("Value in field \"subject\" was too long") 475 } 476 477 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("subject"))); err != nil { 478 return err 479 } 480 - if _, err := cw.WriteString(string("subject")); err != nil { 481 return err 482 } 483 484 - if len(t.Subject) > 1000000 { 485 - return xerrors.Errorf("Value in field t.Subject was too long") 486 } 487 488 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Subject))); err != nil { 489 return err 490 } 491 - if _, err := cw.WriteString(string(t.Subject)); err != nil { 492 return err 493 } 494 495 - // t.CreatedAt (string) (string) 496 - if len("createdAt") > 1000000 { 497 - return xerrors.Errorf("Value in field \"createdAt\" was too long") 498 } 499 500 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("createdAt"))); err != nil { 501 return err 502 } 503 - if _, err := cw.WriteString(string("createdAt")); err != nil { 504 return err 505 } 506 507 - if len(t.CreatedAt) > 1000000 { 508 - return xerrors.Errorf("Value in field t.CreatedAt was too long") 509 } 510 511 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.CreatedAt))); err != nil { 512 return err 513 } 514 - if _, err := cw.WriteString(string(t.CreatedAt)); err != nil { 515 return err 516 } 517 return nil 518 } 519 520 - func (t *GraphFollow) UnmarshalCBOR(r io.Reader) (err error) { 521 - *t = GraphFollow{} 522 523 cr := cbg.NewCborReader(r) 524 ··· 537 } 538 539 if extra > cbg.MaxLength { 540 - return fmt.Errorf("GraphFollow: map struct too large (%d)", extra) 541 } 542 543 n := extra 544 545 - nameBuf := make([]byte, 9) 546 for i := uint64(0); i < n; i++ { 547 nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000) 548 if err != nil { ··· 569 570 t.LexiconTypeID = string(sval) 571 } 572 - // t.Subject (string) (string) 573 - case "subject": 574 575 { 576 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 578 return err 579 } 580 581 - t.Subject = string(sval) 582 } 583 - // t.CreatedAt (string) (string) 584 - case "createdAt": 585 586 { 587 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 589 return err 590 } 591 592 - t.CreatedAt = string(sval) 593 } 594 595 default: ··· 602 603 return nil 604 } 605 - func (t *Repo) MarshalCBOR(w io.Writer) error { 606 if t == nil { 607 _, err := w.Write(cbg.CborNull) 608 return err 609 } 610 611 cw := cbg.NewCborWriter(w) 612 - fieldCount := 5 613 614 - if t.AddedAt == nil { 615 - fieldCount-- 616 - } 617 - 618 - if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil { 619 return err 620 } 621 622 - // t.Knot (string) (string) 623 - if len("knot") > 1000000 { 624 - return xerrors.Errorf("Value in field \"knot\" was too long") 625 } 626 627 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("knot"))); err != nil { 628 return err 629 } 630 - if _, err := cw.WriteString(string("knot")); err != nil { 631 return err 632 } 633 634 - if len(t.Knot) > 1000000 { 635 - return xerrors.Errorf("Value in field t.Knot was too long") 636 } 637 638 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Knot))); err != nil { 639 return err 640 } 641 - if _, err := cw.WriteString(string(t.Knot)); err != nil { 642 return err 643 } 644 ··· 677 return err 678 } 679 680 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.repo"))); err != nil { 681 return err 682 } 683 - if _, err := cw.WriteString(string("sh.tangled.repo")); err != nil { 684 return err 685 } 686 687 - // t.Owner (string) (string) 688 - if len("owner") > 1000000 { 689 - return xerrors.Errorf("Value in field \"owner\" was too long") 690 } 691 692 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("owner"))); err != nil { 693 return err 694 } 695 - if _, err := cw.WriteString(string("owner")); err != nil { 696 return err 697 } 698 699 - if len(t.Owner) > 1000000 { 700 - return xerrors.Errorf("Value in field t.Owner was too long") 701 } 702 703 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Owner))); err != nil { 704 return err 705 } 706 - if _, err := cw.WriteString(string(t.Owner)); err != nil { 707 return err 708 } 709 - 710 - // t.AddedAt (string) (string) 711 - if t.AddedAt != nil { 712 - 713 - if len("addedAt") > 1000000 { 714 - return xerrors.Errorf("Value in field \"addedAt\" was too long") 715 - } 716 - 717 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("addedAt"))); err != nil { 718 - return err 719 - } 720 - if _, err := cw.WriteString(string("addedAt")); err != nil { 721 - return err 722 - } 723 - 724 - if t.AddedAt == nil { 725 - if _, err := cw.Write(cbg.CborNull); err != nil { 726 - return err 727 - } 728 - } else { 729 - if len(*t.AddedAt) > 1000000 { 730 - return xerrors.Errorf("Value in field t.AddedAt was too long") 731 - } 732 - 733 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.AddedAt))); err != nil { 734 - return err 735 - } 736 - if _, err := cw.WriteString(string(*t.AddedAt)); err != nil { 737 - return err 738 - } 739 - } 740 - } 741 return nil 742 } 743 744 - func (t *Repo) UnmarshalCBOR(r io.Reader) (err error) { 745 - *t = Repo{} 746 747 cr := cbg.NewCborReader(r) 748 ··· 761 } 762 763 if extra > cbg.MaxLength { 764 - return fmt.Errorf("Repo: map struct too large (%d)", extra) 765 } 766 767 n := extra ··· 782 } 783 784 switch string(nameBuf[:nameLen]) { 785 - // t.Knot (string) (string) 786 - case "knot": 787 788 { 789 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 791 return err 792 } 793 794 - t.Knot = string(sval) 795 } 796 // t.Name (string) (string) 797 case "name": ··· 815 816 t.LexiconTypeID = string(sval) 817 } 818 - // t.Owner (string) (string) 819 - case "owner": 820 821 { 822 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 824 return err 825 } 826 827 - t.Owner = string(sval) 828 - } 829 - // t.AddedAt (string) (string) 830 - case "addedAt": 831 - 832 - { 833 - b, err := cr.ReadByte() 834 - if err != nil { 835 - return err 836 - } 837 - if b != cbg.CborNull[0] { 838 - if err := cr.UnreadByte(); err != nil { 839 - return err 840 - } 841 - 842 - sval, err := cbg.ReadStringWithMax(cr, 1000000) 843 - if err != nil { 844 - return err 845 - } 846 - 847 - t.AddedAt = (*string)(&sval) 848 - } 849 } 850 851 default: ··· 858 859 return nil 860 } 861 - func (t *RepoIssue) MarshalCBOR(w io.Writer) error { 862 if t == nil { 863 _, err := w.Write(cbg.CborNull) 864 return err ··· 871 fieldCount-- 872 } 873 874 if t.CreatedAt == nil { 875 fieldCount-- 876 } 877 ··· 912 } 913 914 // t.Repo (string) (string) 915 - if len("repo") > 1000000 { 916 - return xerrors.Errorf("Value in field \"repo\" was too long") 917 - } 918 919 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("repo"))); err != nil { 920 - return err 921 - } 922 - if _, err := cw.WriteString(string("repo")); err != nil { 923 - return err 924 - } 925 926 - if len(t.Repo) > 1000000 { 927 - return xerrors.Errorf("Value in field t.Repo was too long") 928 - } 929 930 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Repo))); err != nil { 931 - return err 932 - } 933 - if _, err := cw.WriteString(string(t.Repo)); err != nil { 934 - return err 935 } 936 937 // t.LexiconTypeID (string) (string) ··· 946 return err 947 } 948 949 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.repo.issue"))); err != nil { 950 return err 951 } 952 - if _, err := cw.WriteString(string("sh.tangled.repo.issue")); err != nil { 953 return err 954 } 955 956 - // t.Owner (string) (string) 957 - if len("owner") > 1000000 { 958 - return xerrors.Errorf("Value in field \"owner\" was too long") 959 } 960 961 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("owner"))); err != nil { 962 return err 963 } 964 - if _, err := cw.WriteString(string("owner")); err != nil { 965 return err 966 } 967 968 - if len(t.Owner) > 1000000 { 969 - return xerrors.Errorf("Value in field t.Owner was too long") 970 } 971 972 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Owner))); err != nil { 973 return err 974 } 975 - if _, err := cw.WriteString(string(t.Owner)); err != nil { 976 return err 977 } 978 979 - // t.Title (string) (string) 980 - if len("title") > 1000000 { 981 - return xerrors.Errorf("Value in field \"title\" was too long") 982 - } 983 984 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("title"))); err != nil { 985 - return err 986 - } 987 - if _, err := cw.WriteString(string("title")); err != nil { 988 - return err 989 - } 990 991 - if len(t.Title) > 1000000 { 992 - return xerrors.Errorf("Value in field t.Title was too long") 993 - } 994 995 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Title))); err != nil { 996 - return err 997 - } 998 - if _, err := cw.WriteString(string(t.Title)); err != nil { 999 - return err 1000 - } 1001 1002 - // t.IssueId (int64) (int64) 1003 - if len("issueId") > 1000000 { 1004 - return xerrors.Errorf("Value in field \"issueId\" was too long") 1005 } 1006 1007 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("issueId"))); err != nil { 1008 - return err 1009 - } 1010 - if _, err := cw.WriteString(string("issueId")); err != nil { 1011 - return err 1012 - } 1013 1014 - if t.IssueId >= 0 { 1015 - if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.IssueId)); err != nil { 1016 return err 1017 } 1018 - } else { 1019 - if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.IssueId-1)); err != nil { 1020 return err 1021 } 1022 } 1023 1024 // t.CreatedAt (string) (string) ··· 1055 return nil 1056 } 1057 1058 - func (t *RepoIssue) UnmarshalCBOR(r io.Reader) (err error) { 1059 - *t = RepoIssue{} 1060 1061 cr := cbg.NewCborReader(r) 1062 ··· 1075 } 1076 1077 if extra > cbg.MaxLength { 1078 - return fmt.Errorf("RepoIssue: map struct too large (%d)", extra) 1079 } 1080 1081 n := extra ··· 1121 case "repo": 1122 1123 { 1124 - sval, err := cbg.ReadStringWithMax(cr, 1000000) 1125 if err != nil { 1126 return err 1127 } 1128 1129 - t.Repo = string(sval) 1130 } 1131 // t.LexiconTypeID (string) (string) 1132 case "$type": ··· 1139 1140 t.LexiconTypeID = string(sval) 1141 } 1142 - // t.Owner (string) (string) 1143 - case "owner": 1144 1145 { 1146 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 1148 return err 1149 } 1150 1151 - t.Owner = string(sval) 1152 } 1153 - // t.Title (string) (string) 1154 - case "title": 1155 1156 { 1157 - sval, err := cbg.ReadStringWithMax(cr, 1000000) 1158 if err != nil { 1159 return err 1160 } 1161 1162 - t.Title = string(sval) 1163 } 1164 - // t.IssueId (int64) (int64) 1165 - case "issueId": 1166 { 1167 - maj, extra, err := cr.ReadHeader() 1168 if err != nil { 1169 return err 1170 } 1171 - var extraI int64 1172 - switch maj { 1173 - case cbg.MajUnsignedInt: 1174 - extraI = int64(extra) 1175 - if extraI < 0 { 1176 - return fmt.Errorf("int64 positive overflow") 1177 } 1178 - case cbg.MajNegativeInt: 1179 - extraI = int64(extra) 1180 - if extraI < 0 { 1181 - return fmt.Errorf("int64 negative overflow") 1182 } 1183 - extraI = -1 - extraI 1184 - default: 1185 - return fmt.Errorf("wrong type for int64 field: %d", maj) 1186 - } 1187 1188 - t.IssueId = int64(extraI) 1189 } 1190 // t.CreatedAt (string) (string) 1191 case "createdAt": ··· 1407 1408 return nil 1409 } 1410 - func (t *RepoIssueComment) MarshalCBOR(w io.Writer) error { 1411 if t == nil { 1412 _, err := w.Write(cbg.CborNull) 1413 return err ··· 1420 fieldCount-- 1421 } 1422 1423 - if t.CommentId == nil { 1424 - fieldCount-- 1425 - } 1426 - 1427 if t.CreatedAt == nil { 1428 - fieldCount-- 1429 - } 1430 - 1431 - if t.Owner == nil { 1432 - fieldCount-- 1433 - } 1434 - 1435 - if t.Repo == nil { 1436 fieldCount-- 1437 } 1438 ··· 1473 } 1474 1475 // t.Repo (string) (string) 1476 - if t.Repo != nil { 1477 - 1478 - if len("repo") > 1000000 { 1479 - return xerrors.Errorf("Value in field \"repo\" was too long") 1480 - } 1481 1482 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("repo"))); err != nil { 1483 - return err 1484 - } 1485 - if _, err := cw.WriteString(string("repo")); err != nil { 1486 - return err 1487 - } 1488 1489 - if t.Repo == nil { 1490 - if _, err := cw.Write(cbg.CborNull); err != nil { 1491 - return err 1492 - } 1493 - } else { 1494 - if len(*t.Repo) > 1000000 { 1495 - return xerrors.Errorf("Value in field t.Repo was too long") 1496 - } 1497 1498 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Repo))); err != nil { 1499 - return err 1500 - } 1501 - if _, err := cw.WriteString(string(*t.Repo)); err != nil { 1502 - return err 1503 - } 1504 - } 1505 } 1506 1507 // t.LexiconTypeID (string) (string) ··· 1516 return err 1517 } 1518 1519 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.repo.issue.comment"))); err != nil { 1520 return err 1521 } 1522 - if _, err := cw.WriteString(string("sh.tangled.repo.issue.comment")); err != nil { 1523 return err 1524 } 1525 1526 - // t.Issue (string) (string) 1527 - if len("issue") > 1000000 { 1528 - return xerrors.Errorf("Value in field \"issue\" was too long") 1529 } 1530 1531 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("issue"))); err != nil { 1532 return err 1533 } 1534 - if _, err := cw.WriteString(string("issue")); err != nil { 1535 return err 1536 } 1537 1538 - if len(t.Issue) > 1000000 { 1539 - return xerrors.Errorf("Value in field t.Issue was too long") 1540 } 1541 1542 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Issue))); err != nil { 1543 return err 1544 } 1545 - if _, err := cw.WriteString(string(t.Issue)); err != nil { 1546 return err 1547 } 1548 1549 - // t.Owner (string) (string) 1550 - if t.Owner != nil { 1551 1552 - if len("owner") > 1000000 { 1553 - return xerrors.Errorf("Value in field \"owner\" was too long") 1554 - } 1555 1556 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("owner"))); err != nil { 1557 - return err 1558 - } 1559 - if _, err := cw.WriteString(string("owner")); err != nil { 1560 - return err 1561 - } 1562 1563 - if t.Owner == nil { 1564 - if _, err := cw.Write(cbg.CborNull); err != nil { 1565 - return err 1566 - } 1567 - } else { 1568 - if len(*t.Owner) > 1000000 { 1569 - return xerrors.Errorf("Value in field t.Owner was too long") 1570 - } 1571 1572 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Owner))); err != nil { 1573 - return err 1574 - } 1575 - if _, err := cw.WriteString(string(*t.Owner)); err != nil { 1576 - return err 1577 - } 1578 - } 1579 } 1580 1581 - // t.CommentId (int64) (int64) 1582 - if t.CommentId != nil { 1583 - 1584 - if len("commentId") > 1000000 { 1585 - return xerrors.Errorf("Value in field \"commentId\" was too long") 1586 - } 1587 1588 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("commentId"))); err != nil { 1589 return err 1590 } 1591 - if _, err := cw.WriteString(string("commentId")); err != nil { 1592 return err 1593 } 1594 - 1595 - if t.CommentId == nil { 1596 - if _, err := cw.Write(cbg.CborNull); err != nil { 1597 - return err 1598 - } 1599 - } else { 1600 - if *t.CommentId >= 0 { 1601 - if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(*t.CommentId)); err != nil { 1602 - return err 1603 - } 1604 - } else { 1605 - if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-*t.CommentId-1)); err != nil { 1606 - return err 1607 - } 1608 - } 1609 - } 1610 - 1611 } 1612 1613 // t.CreatedAt (string) (string) ··· 1644 return nil 1645 } 1646 1647 - func (t *RepoIssueComment) UnmarshalCBOR(r io.Reader) (err error) { 1648 - *t = RepoIssueComment{} 1649 1650 cr := cbg.NewCborReader(r) 1651 ··· 1664 } 1665 1666 if extra > cbg.MaxLength { 1667 - return fmt.Errorf("RepoIssueComment: map struct too large (%d)", extra) 1668 } 1669 1670 n := extra ··· 1710 case "repo": 1711 1712 { 1713 - b, err := cr.ReadByte() 1714 if err != nil { 1715 return err 1716 } 1717 - if b != cbg.CborNull[0] { 1718 - if err := cr.UnreadByte(); err != nil { 1719 - return err 1720 - } 1721 1722 - sval, err := cbg.ReadStringWithMax(cr, 1000000) 1723 - if err != nil { 1724 - return err 1725 - } 1726 - 1727 - t.Repo = (*string)(&sval) 1728 - } 1729 } 1730 // t.LexiconTypeID (string) (string) 1731 case "$type": ··· 1738 1739 t.LexiconTypeID = string(sval) 1740 } 1741 - // t.Issue (string) (string) 1742 - case "issue": 1743 1744 { 1745 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 1747 return err 1748 } 1749 1750 - t.Issue = string(sval) 1751 } 1752 - // t.Owner (string) (string) 1753 - case "owner": 1754 1755 { 1756 b, err := cr.ReadByte() ··· 1767 return err 1768 } 1769 1770 - t.Owner = (*string)(&sval) 1771 } 1772 } 1773 - // t.CommentId (int64) (int64) 1774 - case "commentId": 1775 { 1776 1777 - b, err := cr.ReadByte() 1778 if err != nil { 1779 return err 1780 } 1781 - if b != cbg.CborNull[0] { 1782 - if err := cr.UnreadByte(); err != nil { 1783 - return err 1784 - } 1785 - maj, extra, err := cr.ReadHeader() 1786 - if err != nil { 1787 - return err 1788 - } 1789 - var extraI int64 1790 - switch maj { 1791 - case cbg.MajUnsignedInt: 1792 - extraI = int64(extra) 1793 - if extraI < 0 { 1794 - return fmt.Errorf("int64 positive overflow") 1795 - } 1796 - case cbg.MajNegativeInt: 1797 - extraI = int64(extra) 1798 - if extraI < 0 { 1799 - return fmt.Errorf("int64 negative overflow") 1800 - } 1801 - extraI = -1 - extraI 1802 - default: 1803 - return fmt.Errorf("wrong type for int64 field: %d", maj) 1804 - } 1805 1806 - t.CommentId = (*int64)(&extraI) 1807 } 1808 } 1809 - // t.CreatedAt (string) (string) 1810 - case "createdAt": 1811 1812 { 1813 b, err := cr.ReadByte() ··· 1824 return err 1825 } 1826 1827 - t.CreatedAt = (*string)(&sval) 1828 } 1829 } 1830
··· 18 var _ = math.E 19 var _ = sort.Sort 20 21 + func (t *FeedStar) MarshalCBOR(w io.Writer) error { 22 if t == nil { 23 _, err := w.Write(cbg.CborNull) 24 return err ··· 26 27 cw := cbg.NewCborWriter(w) 28 29 + if _, err := cw.Write([]byte{163}); err != nil { 30 return err 31 } 32 33 + // t.LexiconTypeID (string) (string) 34 + if len("$type") > 1000000 { 35 + return xerrors.Errorf("Value in field \"$type\" was too long") 36 } 37 38 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("$type"))); err != nil { 39 return err 40 } 41 + if _, err := cw.WriteString(string("$type")); err != nil { 42 return err 43 } 44 45 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.feed.star"))); err != nil { 46 return err 47 } 48 + if _, err := cw.WriteString(string("sh.tangled.feed.star")); err != nil { 49 return err 50 } 51 52 + // t.Subject (string) (string) 53 + if len("subject") > 1000000 { 54 + return xerrors.Errorf("Value in field \"subject\" was too long") 55 } 56 57 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("subject"))); err != nil { 58 return err 59 } 60 + if _, err := cw.WriteString(string("subject")); err != nil { 61 return err 62 } 63 64 + if len(t.Subject) > 1000000 { 65 + return xerrors.Errorf("Value in field t.Subject was too long") 66 } 67 68 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Subject))); err != nil { 69 return err 70 } 71 + if _, err := cw.WriteString(string(t.Subject)); err != nil { 72 return err 73 } 74 75 + // t.CreatedAt (string) (string) 76 + if len("createdAt") > 1000000 { 77 + return xerrors.Errorf("Value in field \"createdAt\" was too long") 78 } 79 80 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("createdAt"))); err != nil { 81 return err 82 } 83 + if _, err := cw.WriteString(string("createdAt")); err != nil { 84 return err 85 } 86 87 + if len(t.CreatedAt) > 1000000 { 88 + return xerrors.Errorf("Value in field t.CreatedAt was too long") 89 } 90 91 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.CreatedAt))); err != nil { 92 return err 93 } 94 + if _, err := cw.WriteString(string(t.CreatedAt)); err != nil { 95 return err 96 } 97 return nil 98 } 99 100 + func (t *FeedStar) UnmarshalCBOR(r io.Reader) (err error) { 101 + *t = FeedStar{} 102 103 cr := cbg.NewCborReader(r) 104 ··· 117 } 118 119 if extra > cbg.MaxLength { 120 + return fmt.Errorf("FeedStar: map struct too large (%d)", extra) 121 } 122 123 n := extra 124 125 + nameBuf := make([]byte, 9) 126 for i := uint64(0); i < n; i++ { 127 nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000) 128 if err != nil { ··· 138 } 139 140 switch string(nameBuf[:nameLen]) { 141 + // t.LexiconTypeID (string) (string) 142 + case "$type": 143 144 { 145 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 147 return err 148 } 149 150 + t.LexiconTypeID = string(sval) 151 } 152 + // t.Subject (string) (string) 153 + case "subject": 154 155 { 156 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 158 return err 159 } 160 161 + t.Subject = string(sval) 162 } 163 + // t.CreatedAt (string) (string) 164 + case "createdAt": 165 166 { 167 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 169 return err 170 } 171 172 + t.CreatedAt = string(sval) 173 } 174 175 default: ··· 182 183 return nil 184 } 185 + func (t *GraphFollow) MarshalCBOR(w io.Writer) error { 186 if t == nil { 187 _, err := w.Write(cbg.CborNull) 188 return err 189 } 190 191 cw := cbg.NewCborWriter(w) 192 193 + if _, err := cw.Write([]byte{163}); err != nil { 194 return err 195 } 196 ··· 206 return err 207 } 208 209 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.graph.follow"))); err != nil { 210 return err 211 } 212 + if _, err := cw.WriteString(string("sh.tangled.graph.follow")); err != nil { 213 return err 214 } 215 216 + // t.Subject (string) (string) 217 + if len("subject") > 1000000 { 218 + return xerrors.Errorf("Value in field \"subject\" was too long") 219 } 220 221 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("subject"))); err != nil { 222 return err 223 } 224 + if _, err := cw.WriteString(string("subject")); err != nil { 225 return err 226 } 227 228 + if len(t.Subject) > 1000000 { 229 + return xerrors.Errorf("Value in field t.Subject was too long") 230 } 231 232 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Subject))); err != nil { 233 return err 234 } 235 + if _, err := cw.WriteString(string(t.Subject)); err != nil { 236 return err 237 } 238 239 + // t.CreatedAt (string) (string) 240 + if len("createdAt") > 1000000 { 241 + return xerrors.Errorf("Value in field \"createdAt\" was too long") 242 } 243 244 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("createdAt"))); err != nil { 245 return err 246 } 247 + if _, err := cw.WriteString(string("createdAt")); err != nil { 248 return err 249 } 250 251 + if len(t.CreatedAt) > 1000000 { 252 + return xerrors.Errorf("Value in field t.CreatedAt was too long") 253 } 254 255 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.CreatedAt))); err != nil { 256 return err 257 } 258 + if _, err := cw.WriteString(string(t.CreatedAt)); err != nil { 259 return err 260 } 261 return nil 262 } 263 264 + func (t *GraphFollow) UnmarshalCBOR(r io.Reader) (err error) { 265 + *t = GraphFollow{} 266 267 cr := cbg.NewCborReader(r) 268 ··· 281 } 282 283 if extra > cbg.MaxLength { 284 + return fmt.Errorf("GraphFollow: map struct too large (%d)", extra) 285 } 286 287 n := extra 288 289 + nameBuf := make([]byte, 9) 290 for i := uint64(0); i < n; i++ { 291 nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000) 292 if err != nil { ··· 313 314 t.LexiconTypeID = string(sval) 315 } 316 + // t.Subject (string) (string) 317 + case "subject": 318 319 { 320 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 322 return err 323 } 324 325 + t.Subject = string(sval) 326 } 327 + // t.CreatedAt (string) (string) 328 + case "createdAt": 329 330 { 331 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 333 return err 334 } 335 336 + t.CreatedAt = string(sval) 337 } 338 339 default: ··· 346 347 return nil 348 } 349 + func (t *KnotMember) MarshalCBOR(w io.Writer) error { 350 if t == nil { 351 _, err := w.Write(cbg.CborNull) 352 return err 353 } 354 355 cw := cbg.NewCborWriter(w) 356 + fieldCount := 4 357 358 + if t.AddedAt == nil { 359 + fieldCount-- 360 + } 361 + 362 + if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil { 363 return err 364 } 365 ··· 375 return err 376 } 377 378 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.knot.member"))); err != nil { 379 return err 380 } 381 + if _, err := cw.WriteString(string("sh.tangled.knot.member")); err != nil { 382 return err 383 } 384 385 + // t.Domain (string) (string) 386 + if len("domain") > 1000000 { 387 + return xerrors.Errorf("Value in field \"domain\" was too long") 388 } 389 390 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("domain"))); err != nil { 391 return err 392 } 393 + if _, err := cw.WriteString(string("domain")); err != nil { 394 return err 395 } 396 397 + if len(t.Domain) > 1000000 { 398 + return xerrors.Errorf("Value in field t.Domain was too long") 399 } 400 401 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Domain))); err != nil { 402 return err 403 } 404 + if _, err := cw.WriteString(string(t.Domain)); err != nil { 405 return err 406 } 407 408 + // t.Member (string) (string) 409 + if len("member") > 1000000 { 410 + return xerrors.Errorf("Value in field \"member\" was too long") 411 } 412 413 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("member"))); err != nil { 414 return err 415 } 416 + if _, err := cw.WriteString(string("member")); err != nil { 417 return err 418 } 419 420 + if len(t.Member) > 1000000 { 421 + return xerrors.Errorf("Value in field t.Member was too long") 422 } 423 424 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Member))); err != nil { 425 return err 426 } 427 + if _, err := cw.WriteString(string(t.Member)); err != nil { 428 return err 429 } 430 + 431 + // t.AddedAt (string) (string) 432 + if t.AddedAt != nil { 433 + 434 + if len("addedAt") > 1000000 { 435 + return xerrors.Errorf("Value in field \"addedAt\" was too long") 436 + } 437 + 438 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("addedAt"))); err != nil { 439 + return err 440 + } 441 + if _, err := cw.WriteString(string("addedAt")); err != nil { 442 + return err 443 + } 444 + 445 + if t.AddedAt == nil { 446 + if _, err := cw.Write(cbg.CborNull); err != nil { 447 + return err 448 + } 449 + } else { 450 + if len(*t.AddedAt) > 1000000 { 451 + return xerrors.Errorf("Value in field t.AddedAt was too long") 452 + } 453 + 454 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.AddedAt))); err != nil { 455 + return err 456 + } 457 + if _, err := cw.WriteString(string(*t.AddedAt)); err != nil { 458 + return err 459 + } 460 + } 461 + } 462 return nil 463 } 464 465 + func (t *KnotMember) UnmarshalCBOR(r io.Reader) (err error) { 466 + *t = KnotMember{} 467 468 cr := cbg.NewCborReader(r) 469 ··· 482 } 483 484 if extra > cbg.MaxLength { 485 + return fmt.Errorf("KnotMember: map struct too large (%d)", extra) 486 } 487 488 n := extra 489 490 + nameBuf := make([]byte, 7) 491 for i := uint64(0); i < n; i++ { 492 nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000) 493 if err != nil { ··· 514 515 t.LexiconTypeID = string(sval) 516 } 517 + // t.Domain (string) (string) 518 + case "domain": 519 520 { 521 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 523 return err 524 } 525 526 + t.Domain = string(sval) 527 } 528 + // t.Member (string) (string) 529 + case "member": 530 531 { 532 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 534 return err 535 } 536 537 + t.Member = string(sval) 538 + } 539 + // t.AddedAt (string) (string) 540 + case "addedAt": 541 + 542 + { 543 + b, err := cr.ReadByte() 544 + if err != nil { 545 + return err 546 + } 547 + if b != cbg.CborNull[0] { 548 + if err := cr.UnreadByte(); err != nil { 549 + return err 550 + } 551 + 552 + sval, err := cbg.ReadStringWithMax(cr, 1000000) 553 + if err != nil { 554 + return err 555 + } 556 + 557 + t.AddedAt = (*string)(&sval) 558 + } 559 } 560 561 default: ··· 568 569 return nil 570 } 571 + func (t *PublicKey) MarshalCBOR(w io.Writer) error { 572 if t == nil { 573 _, err := w.Write(cbg.CborNull) 574 return err 575 } 576 577 cw := cbg.NewCborWriter(w) 578 579 + if _, err := cw.Write([]byte{164}); err != nil { 580 return err 581 } 582 583 + // t.Key (string) (string) 584 + if len("key") > 1000000 { 585 + return xerrors.Errorf("Value in field \"key\" was too long") 586 } 587 588 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("key"))); err != nil { 589 return err 590 } 591 + if _, err := cw.WriteString(string("key")); err != nil { 592 return err 593 } 594 595 + if len(t.Key) > 1000000 { 596 + return xerrors.Errorf("Value in field t.Key was too long") 597 } 598 599 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Key))); err != nil { 600 return err 601 } 602 + if _, err := cw.WriteString(string(t.Key)); err != nil { 603 return err 604 } 605 ··· 638 return err 639 } 640 641 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.publicKey"))); err != nil { 642 return err 643 } 644 + if _, err := cw.WriteString(string("sh.tangled.publicKey")); err != nil { 645 return err 646 } 647 648 + // t.Created (string) (string) 649 + if len("created") > 1000000 { 650 + return xerrors.Errorf("Value in field \"created\" was too long") 651 } 652 653 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("created"))); err != nil { 654 return err 655 } 656 + if _, err := cw.WriteString(string("created")); err != nil { 657 return err 658 } 659 660 + if len(t.Created) > 1000000 { 661 + return xerrors.Errorf("Value in field t.Created was too long") 662 } 663 664 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Created))); err != nil { 665 return err 666 } 667 + if _, err := cw.WriteString(string(t.Created)); err != nil { 668 return err 669 } 670 return nil 671 } 672 673 + func (t *PublicKey) UnmarshalCBOR(r io.Reader) (err error) { 674 + *t = PublicKey{} 675 676 cr := cbg.NewCborReader(r) 677 ··· 690 } 691 692 if extra > cbg.MaxLength { 693 + return fmt.Errorf("PublicKey: map struct too large (%d)", extra) 694 } 695 696 n := extra ··· 711 } 712 713 switch string(nameBuf[:nameLen]) { 714 + // t.Key (string) (string) 715 + case "key": 716 717 { 718 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 720 return err 721 } 722 723 + t.Key = string(sval) 724 } 725 // t.Name (string) (string) 726 case "name": ··· 744 745 t.LexiconTypeID = string(sval) 746 } 747 + // t.Created (string) (string) 748 + case "created": 749 750 { 751 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 753 return err 754 } 755 756 + t.Created = string(sval) 757 } 758 759 default: ··· 766 767 return nil 768 } 769 + func (t *RepoIssueComment) MarshalCBOR(w io.Writer) error { 770 if t == nil { 771 _, err := w.Write(cbg.CborNull) 772 return err ··· 779 fieldCount-- 780 } 781 782 + if t.CommentId == nil { 783 + fieldCount-- 784 + } 785 + 786 if t.CreatedAt == nil { 787 + fieldCount-- 788 + } 789 + 790 + if t.Owner == nil { 791 + fieldCount-- 792 + } 793 + 794 + if t.Repo == nil { 795 fieldCount-- 796 } 797 ··· 832 } 833 834 // t.Repo (string) (string) 835 + if t.Repo != nil { 836 837 + if len("repo") > 1000000 { 838 + return xerrors.Errorf("Value in field \"repo\" was too long") 839 + } 840 841 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("repo"))); err != nil { 842 + return err 843 + } 844 + if _, err := cw.WriteString(string("repo")); err != nil { 845 + return err 846 + } 847 848 + if t.Repo == nil { 849 + if _, err := cw.Write(cbg.CborNull); err != nil { 850 + return err 851 + } 852 + } else { 853 + if len(*t.Repo) > 1000000 { 854 + return xerrors.Errorf("Value in field t.Repo was too long") 855 + } 856 + 857 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Repo))); err != nil { 858 + return err 859 + } 860 + if _, err := cw.WriteString(string(*t.Repo)); err != nil { 861 + return err 862 + } 863 + } 864 } 865 866 // t.LexiconTypeID (string) (string) ··· 875 return err 876 } 877 878 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.repo.issue.comment"))); err != nil { 879 return err 880 } 881 + if _, err := cw.WriteString(string("sh.tangled.repo.issue.comment")); err != nil { 882 return err 883 } 884 885 + // t.Issue (string) (string) 886 + if len("issue") > 1000000 { 887 + return xerrors.Errorf("Value in field \"issue\" was too long") 888 } 889 890 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("issue"))); err != nil { 891 return err 892 } 893 + if _, err := cw.WriteString(string("issue")); err != nil { 894 return err 895 } 896 897 + if len(t.Issue) > 1000000 { 898 + return xerrors.Errorf("Value in field t.Issue was too long") 899 } 900 901 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Issue))); err != nil { 902 return err 903 } 904 + if _, err := cw.WriteString(string(t.Issue)); err != nil { 905 return err 906 } 907 908 + // t.Owner (string) (string) 909 + if t.Owner != nil { 910 911 + if len("owner") > 1000000 { 912 + return xerrors.Errorf("Value in field \"owner\" was too long") 913 + } 914 915 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("owner"))); err != nil { 916 + return err 917 + } 918 + if _, err := cw.WriteString(string("owner")); err != nil { 919 + return err 920 + } 921 922 + if t.Owner == nil { 923 + if _, err := cw.Write(cbg.CborNull); err != nil { 924 + return err 925 + } 926 + } else { 927 + if len(*t.Owner) > 1000000 { 928 + return xerrors.Errorf("Value in field t.Owner was too long") 929 + } 930 931 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Owner))); err != nil { 932 + return err 933 + } 934 + if _, err := cw.WriteString(string(*t.Owner)); err != nil { 935 + return err 936 + } 937 + } 938 } 939 940 + // t.CommentId (int64) (int64) 941 + if t.CommentId != nil { 942 943 + if len("commentId") > 1000000 { 944 + return xerrors.Errorf("Value in field \"commentId\" was too long") 945 + } 946 + 947 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("commentId"))); err != nil { 948 return err 949 } 950 + if _, err := cw.WriteString(string("commentId")); err != nil { 951 return err 952 } 953 + 954 + if t.CommentId == nil { 955 + if _, err := cw.Write(cbg.CborNull); err != nil { 956 + return err 957 + } 958 + } else { 959 + if *t.CommentId >= 0 { 960 + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(*t.CommentId)); err != nil { 961 + return err 962 + } 963 + } else { 964 + if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-*t.CommentId-1)); err != nil { 965 + return err 966 + } 967 + } 968 + } 969 + 970 } 971 972 // t.CreatedAt (string) (string) ··· 1003 return nil 1004 } 1005 1006 + func (t *RepoIssueComment) UnmarshalCBOR(r io.Reader) (err error) { 1007 + *t = RepoIssueComment{} 1008 1009 cr := cbg.NewCborReader(r) 1010 ··· 1023 } 1024 1025 if extra > cbg.MaxLength { 1026 + return fmt.Errorf("RepoIssueComment: map struct too large (%d)", extra) 1027 } 1028 1029 n := extra ··· 1069 case "repo": 1070 1071 { 1072 + b, err := cr.ReadByte() 1073 if err != nil { 1074 return err 1075 } 1076 + if b != cbg.CborNull[0] { 1077 + if err := cr.UnreadByte(); err != nil { 1078 + return err 1079 + } 1080 1081 + sval, err := cbg.ReadStringWithMax(cr, 1000000) 1082 + if err != nil { 1083 + return err 1084 + } 1085 + 1086 + t.Repo = (*string)(&sval) 1087 + } 1088 } 1089 // t.LexiconTypeID (string) (string) 1090 case "$type": ··· 1097 1098 t.LexiconTypeID = string(sval) 1099 } 1100 + // t.Issue (string) (string) 1101 + case "issue": 1102 1103 { 1104 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 1106 return err 1107 } 1108 1109 + t.Issue = string(sval) 1110 } 1111 + // t.Owner (string) (string) 1112 + case "owner": 1113 1114 { 1115 + b, err := cr.ReadByte() 1116 if err != nil { 1117 return err 1118 } 1119 + if b != cbg.CborNull[0] { 1120 + if err := cr.UnreadByte(); err != nil { 1121 + return err 1122 + } 1123 1124 + sval, err := cbg.ReadStringWithMax(cr, 1000000) 1125 + if err != nil { 1126 + return err 1127 + } 1128 + 1129 + t.Owner = (*string)(&sval) 1130 + } 1131 } 1132 + // t.CommentId (int64) (int64) 1133 + case "commentId": 1134 { 1135 + 1136 + b, err := cr.ReadByte() 1137 if err != nil { 1138 return err 1139 } 1140 + if b != cbg.CborNull[0] { 1141 + if err := cr.UnreadByte(); err != nil { 1142 + return err 1143 } 1144 + maj, extra, err := cr.ReadHeader() 1145 + if err != nil { 1146 + return err 1147 } 1148 + var extraI int64 1149 + switch maj { 1150 + case cbg.MajUnsignedInt: 1151 + extraI = int64(extra) 1152 + if extraI < 0 { 1153 + return fmt.Errorf("int64 positive overflow") 1154 + } 1155 + case cbg.MajNegativeInt: 1156 + extraI = int64(extra) 1157 + if extraI < 0 { 1158 + return fmt.Errorf("int64 negative overflow") 1159 + } 1160 + extraI = -1 - extraI 1161 + default: 1162 + return fmt.Errorf("wrong type for int64 field: %d", maj) 1163 + } 1164 1165 + t.CommentId = (*int64)(&extraI) 1166 + } 1167 } 1168 // t.CreatedAt (string) (string) 1169 case "createdAt": ··· 1385 1386 return nil 1387 } 1388 + func (t *RepoIssue) MarshalCBOR(w io.Writer) error { 1389 if t == nil { 1390 _, err := w.Write(cbg.CborNull) 1391 return err ··· 1398 fieldCount-- 1399 } 1400 1401 if t.CreatedAt == nil { 1402 fieldCount-- 1403 } 1404 ··· 1439 } 1440 1441 // t.Repo (string) (string) 1442 + if len("repo") > 1000000 { 1443 + return xerrors.Errorf("Value in field \"repo\" was too long") 1444 + } 1445 1446 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("repo"))); err != nil { 1447 + return err 1448 + } 1449 + if _, err := cw.WriteString(string("repo")); err != nil { 1450 + return err 1451 + } 1452 1453 + if len(t.Repo) > 1000000 { 1454 + return xerrors.Errorf("Value in field t.Repo was too long") 1455 + } 1456 1457 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Repo))); err != nil { 1458 + return err 1459 + } 1460 + if _, err := cw.WriteString(string(t.Repo)); err != nil { 1461 + return err 1462 } 1463 1464 // t.LexiconTypeID (string) (string) ··· 1473 return err 1474 } 1475 1476 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.repo.issue"))); err != nil { 1477 return err 1478 } 1479 + if _, err := cw.WriteString(string("sh.tangled.repo.issue")); err != nil { 1480 return err 1481 } 1482 1483 + // t.Owner (string) (string) 1484 + if len("owner") > 1000000 { 1485 + return xerrors.Errorf("Value in field \"owner\" was too long") 1486 } 1487 1488 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("owner"))); err != nil { 1489 return err 1490 } 1491 + if _, err := cw.WriteString(string("owner")); err != nil { 1492 return err 1493 } 1494 1495 + if len(t.Owner) > 1000000 { 1496 + return xerrors.Errorf("Value in field t.Owner was too long") 1497 } 1498 1499 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Owner))); err != nil { 1500 return err 1501 } 1502 + if _, err := cw.WriteString(string(t.Owner)); err != nil { 1503 return err 1504 } 1505 1506 + // t.Title (string) (string) 1507 + if len("title") > 1000000 { 1508 + return xerrors.Errorf("Value in field \"title\" was too long") 1509 + } 1510 1511 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("title"))); err != nil { 1512 + return err 1513 + } 1514 + if _, err := cw.WriteString(string("title")); err != nil { 1515 + return err 1516 + } 1517 1518 + if len(t.Title) > 1000000 { 1519 + return xerrors.Errorf("Value in field t.Title was too long") 1520 + } 1521 1522 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Title))); err != nil { 1523 + return err 1524 + } 1525 + if _, err := cw.WriteString(string(t.Title)); err != nil { 1526 + return err 1527 + } 1528 1529 + // t.IssueId (int64) (int64) 1530 + if len("issueId") > 1000000 { 1531 + return xerrors.Errorf("Value in field \"issueId\" was too long") 1532 } 1533 1534 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("issueId"))); err != nil { 1535 + return err 1536 + } 1537 + if _, err := cw.WriteString(string("issueId")); err != nil { 1538 + return err 1539 + } 1540 1541 + if t.IssueId >= 0 { 1542 + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.IssueId)); err != nil { 1543 return err 1544 } 1545 + } else { 1546 + if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.IssueId-1)); err != nil { 1547 return err 1548 } 1549 } 1550 1551 // t.CreatedAt (string) (string) ··· 1582 return nil 1583 } 1584 1585 + func (t *RepoIssue) UnmarshalCBOR(r io.Reader) (err error) { 1586 + *t = RepoIssue{} 1587 1588 cr := cbg.NewCborReader(r) 1589 ··· 1602 } 1603 1604 if extra > cbg.MaxLength { 1605 + return fmt.Errorf("RepoIssue: map struct too large (%d)", extra) 1606 } 1607 1608 n := extra ··· 1648 case "repo": 1649 1650 { 1651 + sval, err := cbg.ReadStringWithMax(cr, 1000000) 1652 if err != nil { 1653 return err 1654 } 1655 1656 + t.Repo = string(sval) 1657 } 1658 // t.LexiconTypeID (string) (string) 1659 case "$type": ··· 1666 1667 t.LexiconTypeID = string(sval) 1668 } 1669 + // t.Owner (string) (string) 1670 + case "owner": 1671 + 1672 + { 1673 + sval, err := cbg.ReadStringWithMax(cr, 1000000) 1674 + if err != nil { 1675 + return err 1676 + } 1677 + 1678 + t.Owner = string(sval) 1679 + } 1680 + // t.Title (string) (string) 1681 + case "title": 1682 1683 { 1684 sval, err := cbg.ReadStringWithMax(cr, 1000000) ··· 1686 return err 1687 } 1688 1689 + t.Title = string(sval) 1690 + } 1691 + // t.IssueId (int64) (int64) 1692 + case "issueId": 1693 + { 1694 + maj, extra, err := cr.ReadHeader() 1695 + if err != nil { 1696 + return err 1697 + } 1698 + var extraI int64 1699 + switch maj { 1700 + case cbg.MajUnsignedInt: 1701 + extraI = int64(extra) 1702 + if extraI < 0 { 1703 + return fmt.Errorf("int64 positive overflow") 1704 + } 1705 + case cbg.MajNegativeInt: 1706 + extraI = int64(extra) 1707 + if extraI < 0 { 1708 + return fmt.Errorf("int64 negative overflow") 1709 + } 1710 + extraI = -1 - extraI 1711 + default: 1712 + return fmt.Errorf("wrong type for int64 field: %d", maj) 1713 + } 1714 + 1715 + t.IssueId = int64(extraI) 1716 } 1717 + // t.CreatedAt (string) (string) 1718 + case "createdAt": 1719 1720 { 1721 b, err := cr.ReadByte() ··· 1732 return err 1733 } 1734 1735 + t.CreatedAt = (*string)(&sval) 1736 + } 1737 + } 1738 + 1739 + default: 1740 + // Field doesn't exist on this type, so ignore it 1741 + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { 1742 + return err 1743 + } 1744 + } 1745 + } 1746 + 1747 + return nil 1748 + } 1749 + func (t *Repo) MarshalCBOR(w io.Writer) error { 1750 + if t == nil { 1751 + _, err := w.Write(cbg.CborNull) 1752 + return err 1753 + } 1754 + 1755 + cw := cbg.NewCborWriter(w) 1756 + fieldCount := 5 1757 + 1758 + if t.AddedAt == nil { 1759 + fieldCount-- 1760 + } 1761 + 1762 + if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil { 1763 + return err 1764 + } 1765 + 1766 + // t.Knot (string) (string) 1767 + if len("knot") > 1000000 { 1768 + return xerrors.Errorf("Value in field \"knot\" was too long") 1769 + } 1770 + 1771 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("knot"))); err != nil { 1772 + return err 1773 + } 1774 + if _, err := cw.WriteString(string("knot")); err != nil { 1775 + return err 1776 + } 1777 + 1778 + if len(t.Knot) > 1000000 { 1779 + return xerrors.Errorf("Value in field t.Knot was too long") 1780 + } 1781 + 1782 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Knot))); err != nil { 1783 + return err 1784 + } 1785 + if _, err := cw.WriteString(string(t.Knot)); err != nil { 1786 + return err 1787 + } 1788 + 1789 + // t.Name (string) (string) 1790 + if len("name") > 1000000 { 1791 + return xerrors.Errorf("Value in field \"name\" was too long") 1792 + } 1793 + 1794 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("name"))); err != nil { 1795 + return err 1796 + } 1797 + if _, err := cw.WriteString(string("name")); err != nil { 1798 + return err 1799 + } 1800 + 1801 + if len(t.Name) > 1000000 { 1802 + return xerrors.Errorf("Value in field t.Name was too long") 1803 + } 1804 + 1805 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Name))); err != nil { 1806 + return err 1807 + } 1808 + if _, err := cw.WriteString(string(t.Name)); err != nil { 1809 + return err 1810 + } 1811 + 1812 + // t.LexiconTypeID (string) (string) 1813 + if len("$type") > 1000000 { 1814 + return xerrors.Errorf("Value in field \"$type\" was too long") 1815 + } 1816 + 1817 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("$type"))); err != nil { 1818 + return err 1819 + } 1820 + if _, err := cw.WriteString(string("$type")); err != nil { 1821 + return err 1822 + } 1823 + 1824 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.repo"))); err != nil { 1825 + return err 1826 + } 1827 + if _, err := cw.WriteString(string("sh.tangled.repo")); err != nil { 1828 + return err 1829 + } 1830 + 1831 + // t.Owner (string) (string) 1832 + if len("owner") > 1000000 { 1833 + return xerrors.Errorf("Value in field \"owner\" was too long") 1834 + } 1835 + 1836 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("owner"))); err != nil { 1837 + return err 1838 + } 1839 + if _, err := cw.WriteString(string("owner")); err != nil { 1840 + return err 1841 + } 1842 + 1843 + if len(t.Owner) > 1000000 { 1844 + return xerrors.Errorf("Value in field t.Owner was too long") 1845 + } 1846 + 1847 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Owner))); err != nil { 1848 + return err 1849 + } 1850 + if _, err := cw.WriteString(string(t.Owner)); err != nil { 1851 + return err 1852 + } 1853 + 1854 + // t.AddedAt (string) (string) 1855 + if t.AddedAt != nil { 1856 + 1857 + if len("addedAt") > 1000000 { 1858 + return xerrors.Errorf("Value in field \"addedAt\" was too long") 1859 + } 1860 + 1861 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("addedAt"))); err != nil { 1862 + return err 1863 + } 1864 + if _, err := cw.WriteString(string("addedAt")); err != nil { 1865 + return err 1866 + } 1867 + 1868 + if t.AddedAt == nil { 1869 + if _, err := cw.Write(cbg.CborNull); err != nil { 1870 + return err 1871 + } 1872 + } else { 1873 + if len(*t.AddedAt) > 1000000 { 1874 + return xerrors.Errorf("Value in field t.AddedAt was too long") 1875 + } 1876 + 1877 + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.AddedAt))); err != nil { 1878 + return err 1879 + } 1880 + if _, err := cw.WriteString(string(*t.AddedAt)); err != nil { 1881 + return err 1882 + } 1883 + } 1884 + } 1885 + return nil 1886 + } 1887 + 1888 + func (t *Repo) UnmarshalCBOR(r io.Reader) (err error) { 1889 + *t = Repo{} 1890 + 1891 + cr := cbg.NewCborReader(r) 1892 + 1893 + maj, extra, err := cr.ReadHeader() 1894 + if err != nil { 1895 + return err 1896 + } 1897 + defer func() { 1898 + if err == io.EOF { 1899 + err = io.ErrUnexpectedEOF 1900 + } 1901 + }() 1902 + 1903 + if maj != cbg.MajMap { 1904 + return fmt.Errorf("cbor input should be of type map") 1905 + } 1906 + 1907 + if extra > cbg.MaxLength { 1908 + return fmt.Errorf("Repo: map struct too large (%d)", extra) 1909 + } 1910 + 1911 + n := extra 1912 + 1913 + nameBuf := make([]byte, 7) 1914 + for i := uint64(0); i < n; i++ { 1915 + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000) 1916 + if err != nil { 1917 + return err 1918 + } 1919 + 1920 + if !ok { 1921 + // Field doesn't exist on this type, so ignore it 1922 + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { 1923 + return err 1924 + } 1925 + continue 1926 + } 1927 + 1928 + switch string(nameBuf[:nameLen]) { 1929 + // t.Knot (string) (string) 1930 + case "knot": 1931 + 1932 + { 1933 + sval, err := cbg.ReadStringWithMax(cr, 1000000) 1934 + if err != nil { 1935 + return err 1936 } 1937 + 1938 + t.Knot = string(sval) 1939 } 1940 + // t.Name (string) (string) 1941 + case "name": 1942 + 1943 { 1944 + sval, err := cbg.ReadStringWithMax(cr, 1000000) 1945 + if err != nil { 1946 + return err 1947 + } 1948 1949 + t.Name = string(sval) 1950 + } 1951 + // t.LexiconTypeID (string) (string) 1952 + case "$type": 1953 + 1954 + { 1955 + sval, err := cbg.ReadStringWithMax(cr, 1000000) 1956 if err != nil { 1957 return err 1958 } 1959 1960 + t.LexiconTypeID = string(sval) 1961 + } 1962 + // t.Owner (string) (string) 1963 + case "owner": 1964 + 1965 + { 1966 + sval, err := cbg.ReadStringWithMax(cr, 1000000) 1967 + if err != nil { 1968 + return err 1969 } 1970 + 1971 + t.Owner = string(sval) 1972 } 1973 + // t.AddedAt (string) (string) 1974 + case "addedAt": 1975 1976 { 1977 b, err := cr.ReadByte() ··· 1988 return err 1989 } 1990 1991 + t.AddedAt = (*string)(&sval) 1992 } 1993 } 1994
+23
api/tangled/feedstar.go
···
··· 1 + // Code generated by cmd/lexgen (see Makefile's lexgen); DO NOT EDIT. 2 + 3 + package tangled 4 + 5 + // schema: sh.tangled.feed.star 6 + 7 + import ( 8 + "github.com/bluesky-social/indigo/lex/util" 9 + ) 10 + 11 + const ( 12 + FeedStarNSID = "sh.tangled.feed.star" 13 + ) 14 + 15 + func init() { 16 + util.RegisterType("sh.tangled.feed.star", &FeedStar{}) 17 + } // 18 + // RECORDTYPE: FeedStar 19 + type FeedStar struct { 20 + LexiconTypeID string `json:"$type,const=sh.tangled.feed.star" cborgen:"$type,const=sh.tangled.feed.star"` 21 + CreatedAt string `json:"createdAt" cborgen:"createdAt"` 22 + Subject string `json:"subject" cborgen:"subject"` 23 + }
+10
appview/db/db.go
··· 112 next_issue_id integer not null default 1 113 ); 114 115 `) 116 if err != nil { 117 return nil, err
··· 112 next_issue_id integer not null default 1 113 ); 114 115 + create table if not exists stars ( 116 + id integer primary key autoincrement, 117 + starred_by_did text not null, 118 + repo_at text not null, 119 + rkey text not null, 120 + created text not null default (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), 121 + foreign key (repo_at) references repos(at_uri) on delete cascade, 122 + unique(starred_by_did, repo_at) 123 + ); 124 + 125 `) 126 if err != nil { 127 return nil, err
+11 -6
appview/db/follow.go
··· 9 UserDid string 10 SubjectDid string 11 FollowedAt time.Time 12 - RKey string 13 } 14 15 func AddFollow(e Execer, userDid, subjectDid, rkey string) error { ··· 25 26 var follow Follow 27 var followedAt string 28 - err := row.Scan(&follow.UserDid, &follow.SubjectDid, &followedAt, &follow.RKey) 29 if err != nil { 30 return nil, err 31 } ··· 41 return &follow, nil 42 } 43 44 - // Get a follow record 45 func DeleteFollow(e Execer, userDid, subjectDid string) error { 46 _, err := e.Exec(`delete from follows where user_did = ? and subject_did = ?`, userDid, subjectDid) 47 return err ··· 91 } 92 } 93 94 - func GetAllFollows(e Execer) ([]Follow, error) { 95 var follows []Follow 96 97 - rows, err := e.Query(`select user_did, subject_did, followed_at, rkey from follows`) 98 if err != nil { 99 return nil, err 100 } ··· 103 for rows.Next() { 104 var follow Follow 105 var followedAt string 106 - if err := rows.Scan(&follow.UserDid, &follow.SubjectDid, &followedAt, &follow.RKey); err != nil { 107 return nil, err 108 } 109
··· 9 UserDid string 10 SubjectDid string 11 FollowedAt time.Time 12 + Rkey string 13 } 14 15 func AddFollow(e Execer, userDid, subjectDid, rkey string) error { ··· 25 26 var follow Follow 27 var followedAt string 28 + err := row.Scan(&follow.UserDid, &follow.SubjectDid, &followedAt, &follow.Rkey) 29 if err != nil { 30 return nil, err 31 } ··· 41 return &follow, nil 42 } 43 44 + // Remove a follow 45 func DeleteFollow(e Execer, userDid, subjectDid string) error { 46 _, err := e.Exec(`delete from follows where user_did = ? and subject_did = ?`, userDid, subjectDid) 47 return err ··· 91 } 92 } 93 94 + func GetAllFollows(e Execer, limit int) ([]Follow, error) { 95 var follows []Follow 96 97 + rows, err := e.Query(` 98 + select user_did, subject_did, followed_at, rkey 99 + from follows 100 + order by followed_at desc 101 + limit ?`, limit, 102 + ) 103 if err != nil { 104 return nil, err 105 } ··· 108 for rows.Next() { 109 var follow Follow 110 var followedAt string 111 + if err := rows.Scan(&follow.UserDid, &follow.SubjectDid, &followedAt, &follow.Rkey); err != nil { 112 return nil, err 113 } 114
+37 -12
appview/db/issues.go
··· 3 import ( 4 "database/sql" 5 "time" 6 ) 7 8 type Issue struct { 9 - RepoAt string 10 OwnerDid string 11 IssueId int 12 IssueAt string ··· 18 19 type Comment struct { 20 OwnerDid string 21 - RepoAt string 22 CommentAt string 23 Issue int 24 CommentId int ··· 65 return nil 66 } 67 68 - func SetIssueAt(e Execer, repoAt string, issueId int, issueAt string) error { 69 _, err := e.Exec(`update issues set issue_at = ? where repo_at = ? and issue_id = ?`, issueAt, repoAt, issueId) 70 return err 71 } 72 73 - func GetIssueAt(e Execer, repoAt string, issueId int) (string, error) { 74 var issueAt string 75 err := e.QueryRow(`select issue_at from issues where repo_at = ? and issue_id = ?`, repoAt, issueId).Scan(&issueAt) 76 return issueAt, err 77 } 78 79 - func GetIssueId(e Execer, repoAt string) (int, error) { 80 var issueId int 81 err := e.QueryRow(`select next_issue_id from repo_issue_seqs where repo_at = ?`, repoAt).Scan(&issueId) 82 return issueId - 1, err 83 } 84 85 - func GetIssueOwnerDid(e Execer, repoAt string, issueId int) (string, error) { 86 var ownerDid string 87 err := e.QueryRow(`select owner_did from issues where repo_at = ? and issue_id = ?`, repoAt, issueId).Scan(&ownerDid) 88 return ownerDid, err 89 } 90 91 - func GetIssues(e Execer, repoAt string) ([]Issue, error) { 92 var issues []Issue 93 94 rows, err := e.Query(`select owner_did, issue_id, created, title, body, open from issues where repo_at = ? order by created desc`, repoAt) ··· 121 return issues, nil 122 } 123 124 - func GetIssue(e Execer, repoAt string, issueId int) (*Issue, error) { 125 query := `select owner_did, created, title, body, open from issues where repo_at = ? and issue_id = ?` 126 row := e.QueryRow(query, repoAt, issueId) 127 ··· 141 return &issue, nil 142 } 143 144 - func GetIssueWithComments(e Execer, repoAt string, issueId int) (*Issue, []Comment, error) { 145 query := `select owner_did, issue_id, created, title, body, open from issues where repo_at = ? and issue_id = ?` 146 row := e.QueryRow(query, repoAt, issueId) 147 ··· 180 return err 181 } 182 183 - func GetComments(e Execer, repoAt string, issueId int) ([]Comment, error) { 184 var comments []Comment 185 186 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) ··· 216 return comments, nil 217 } 218 219 - func CloseIssue(e Execer, repoAt string, issueId int) error { 220 _, err := e.Exec(`update issues set open = 0 where repo_at = ? and issue_id = ?`, repoAt, issueId) 221 return err 222 } 223 224 - func ReopenIssue(e Execer, repoAt string, issueId int) error { 225 _, err := e.Exec(`update issues set open = 1 where repo_at = ? and issue_id = ?`, repoAt, issueId) 226 return err 227 }
··· 3 import ( 4 "database/sql" 5 "time" 6 + 7 + "github.com/bluesky-social/indigo/atproto/syntax" 8 ) 9 10 type Issue struct { 11 + RepoAt syntax.ATURI 12 OwnerDid string 13 IssueId int 14 IssueAt string ··· 20 21 type Comment struct { 22 OwnerDid string 23 + RepoAt syntax.ATURI 24 CommentAt string 25 Issue int 26 CommentId int ··· 67 return nil 68 } 69 70 + func SetIssueAt(e Execer, repoAt syntax.ATURI, issueId int, issueAt string) error { 71 _, err := e.Exec(`update issues set issue_at = ? where repo_at = ? and issue_id = ?`, issueAt, repoAt, issueId) 72 return err 73 } 74 75 + func GetIssueAt(e Execer, repoAt syntax.ATURI, issueId int) (string, error) { 76 var issueAt string 77 err := e.QueryRow(`select issue_at from issues where repo_at = ? and issue_id = ?`, repoAt, issueId).Scan(&issueAt) 78 return issueAt, err 79 } 80 81 + func GetIssueId(e Execer, repoAt syntax.ATURI) (int, error) { 82 var issueId int 83 err := e.QueryRow(`select next_issue_id from repo_issue_seqs where repo_at = ?`, repoAt).Scan(&issueId) 84 return issueId - 1, err 85 } 86 87 + func GetIssueOwnerDid(e Execer, repoAt syntax.ATURI, issueId int) (string, error) { 88 var ownerDid string 89 err := e.QueryRow(`select owner_did from issues where repo_at = ? and issue_id = ?`, repoAt, issueId).Scan(&ownerDid) 90 return ownerDid, err 91 } 92 93 + func GetIssues(e Execer, repoAt syntax.ATURI) ([]Issue, error) { 94 var issues []Issue 95 96 rows, err := e.Query(`select owner_did, issue_id, created, title, body, open from issues where repo_at = ? order by created desc`, repoAt) ··· 123 return issues, nil 124 } 125 126 + func GetIssue(e Execer, repoAt syntax.ATURI, issueId int) (*Issue, error) { 127 query := `select owner_did, created, title, body, open from issues where repo_at = ? and issue_id = ?` 128 row := e.QueryRow(query, repoAt, issueId) 129 ··· 143 return &issue, nil 144 } 145 146 + func GetIssueWithComments(e Execer, repoAt syntax.ATURI, issueId int) (*Issue, []Comment, error) { 147 query := `select owner_did, issue_id, created, title, body, open from issues where repo_at = ? and issue_id = ?` 148 row := e.QueryRow(query, repoAt, issueId) 149 ··· 182 return err 183 } 184 185 + func GetComments(e Execer, repoAt syntax.ATURI, issueId int) ([]Comment, error) { 186 var comments []Comment 187 188 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) ··· 218 return comments, nil 219 } 220 221 + func CloseIssue(e Execer, repoAt syntax.ATURI, issueId int) error { 222 _, err := e.Exec(`update issues set open = 0 where repo_at = ? and issue_id = ?`, repoAt, issueId) 223 return err 224 } 225 226 + func ReopenIssue(e Execer, repoAt syntax.ATURI, issueId int) error { 227 _, err := e.Exec(`update issues set open = 1 where repo_at = ? and issue_id = ?`, repoAt, issueId) 228 return err 229 } 230 + 231 + type IssueCount struct { 232 + Open int 233 + Closed int 234 + } 235 + 236 + func GetIssueCount(e Execer, repoAt syntax.ATURI) (IssueCount, error) { 237 + row := e.QueryRow(` 238 + select 239 + count(case when open = 1 then 1 end) as open_count, 240 + count(case when open = 0 then 1 end) as closed_count 241 + from issues 242 + where repo_at = ?`, 243 + repoAt, 244 + ) 245 + 246 + var count IssueCount 247 + if err := row.Scan(&count.Open, &count.Closed); err != nil { 248 + return IssueCount{0, 0}, err 249 + } 250 + 251 + return count, nil 252 + }
+29 -2
appview/db/repos.go
··· 14 AtUri string 15 } 16 17 - func GetAllRepos(e Execer) ([]Repo, error) { 18 var repos []Repo 19 20 - rows, err := e.Query(`select did, name, knot, rkey, created from repos`) 21 if err != nil { 22 return nil, err 23 } ··· 79 return &repo, nil 80 } 81 82 func AddRepo(e Execer, repo *Repo) error { 83 _, err := e.Exec(`insert into repos (did, name, knot, rkey, at_uri) values (?, ?, ?, ?, ?)`, repo.Did, repo.Name, repo.Knot, repo.Rkey, repo.AtUri) 84 return err ··· 120 } 121 122 return repos, nil 123 } 124 125 func scanRepo(rows *sql.Rows, did, name, knot, rkey *string, created *time.Time) error {
··· 14 AtUri string 15 } 16 17 + func GetAllRepos(e Execer, limit int) ([]Repo, error) { 18 var repos []Repo 19 20 + rows, err := e.Query( 21 + `select did, name, knot, rkey, created 22 + from repos 23 + order by created desc 24 + limit ? 25 + `, 26 + limit, 27 + ) 28 if err != nil { 29 return nil, err 30 } ··· 86 return &repo, nil 87 } 88 89 + func GetRepoByAtUri(e Execer, atUri string) (*Repo, error) { 90 + var repo Repo 91 + 92 + row := e.QueryRow(`select did, name, knot, created, at_uri from repos where at_uri = ?`, atUri) 93 + 94 + var createdAt string 95 + if err := row.Scan(&repo.Did, &repo.Name, &repo.Knot, &createdAt, &repo.AtUri); err != nil { 96 + return nil, err 97 + } 98 + createdAtTime, _ := time.Parse(time.RFC3339, createdAt) 99 + repo.Created = createdAtTime 100 + 101 + return &repo, nil 102 + } 103 + 104 func AddRepo(e Execer, repo *Repo) error { 105 _, err := e.Exec(`insert into repos (did, name, knot, rkey, at_uri) values (?, ?, ?, ?, ?)`, repo.Did, repo.Name, repo.Knot, repo.Rkey, repo.AtUri) 106 return err ··· 142 } 143 144 return repos, nil 145 + } 146 + 147 + type RepoStats struct { 148 + StarCount int 149 + IssueCount IssueCount 150 } 151 152 func scanRepo(rows *sql.Rows, did, name, knot, rkey *string, created *time.Time) error {
+150
appview/db/star.go
···
··· 1 + package db 2 + 3 + import ( 4 + "log" 5 + "time" 6 + 7 + "github.com/bluesky-social/indigo/atproto/syntax" 8 + ) 9 + 10 + type Star struct { 11 + StarredByDid string 12 + RepoAt syntax.ATURI 13 + Repo *Repo 14 + Created time.Time 15 + Rkey string 16 + } 17 + 18 + func (star *Star) ResolveRepo(e Execer) error { 19 + if star.Repo != nil { 20 + return nil 21 + } 22 + 23 + repo, err := GetRepoByAtUri(e, star.RepoAt.String()) 24 + if err != nil { 25 + return err 26 + } 27 + 28 + star.Repo = repo 29 + return nil 30 + } 31 + 32 + func AddStar(e Execer, starredByDid string, repoAt syntax.ATURI, rkey string) error { 33 + query := `insert or ignore into stars (starred_by_did, repo_at, rkey) values (?, ?, ?)` 34 + _, err := e.Exec(query, starredByDid, repoAt, rkey) 35 + return err 36 + } 37 + 38 + // Get a star record 39 + func GetStar(e Execer, starredByDid string, repoAt syntax.ATURI) (*Star, error) { 40 + query := ` 41 + select starred_by_did, repo_at, created, rkey 42 + from stars 43 + where starred_by_did = ? and repo_at = ?` 44 + row := e.QueryRow(query, starredByDid, repoAt) 45 + 46 + var star Star 47 + var created string 48 + err := row.Scan(&star.StarredByDid, &star.RepoAt, &created, &star.Rkey) 49 + if err != nil { 50 + return nil, err 51 + } 52 + 53 + createdAtTime, err := time.Parse(time.RFC3339, created) 54 + if err != nil { 55 + log.Println("unable to determine followed at time") 56 + star.Created = time.Now() 57 + } else { 58 + star.Created = createdAtTime 59 + } 60 + 61 + return &star, nil 62 + } 63 + 64 + // Remove a star 65 + func DeleteStar(e Execer, starredByDid string, repoAt syntax.ATURI) error { 66 + _, err := e.Exec(`delete from stars where starred_by_did = ? and repo_at = ?`, starredByDid, repoAt) 67 + return err 68 + } 69 + 70 + func GetStarCount(e Execer, repoAt syntax.ATURI) (int, error) { 71 + stars := 0 72 + err := e.QueryRow( 73 + `select count(starred_by_did) from stars where repo_at = ?`, repoAt).Scan(&stars) 74 + if err != nil { 75 + return 0, err 76 + } 77 + return stars, nil 78 + } 79 + 80 + func GetStarStatus(e Execer, userDid string, repoAt syntax.ATURI) bool { 81 + if _, err := GetStar(e, userDid, repoAt); err != nil { 82 + return false 83 + } else { 84 + return true 85 + } 86 + } 87 + 88 + func GetAllStars(e Execer, limit int) ([]Star, error) { 89 + var stars []Star 90 + 91 + rows, err := e.Query(` 92 + select 93 + s.starred_by_did, 94 + s.repo_at, 95 + s.rkey, 96 + s.created, 97 + r.did, 98 + r.name, 99 + r.knot, 100 + r.rkey, 101 + r.created, 102 + r.at_uri 103 + from stars s 104 + join repos r on s.repo_at = r.at_uri 105 + `) 106 + 107 + if err != nil { 108 + return nil, err 109 + } 110 + defer rows.Close() 111 + 112 + for rows.Next() { 113 + var star Star 114 + var repo Repo 115 + var starCreatedAt, repoCreatedAt string 116 + 117 + if err := rows.Scan( 118 + &star.StarredByDid, 119 + &star.RepoAt, 120 + &star.Rkey, 121 + &starCreatedAt, 122 + &repo.Did, 123 + &repo.Name, 124 + &repo.Knot, 125 + &repo.Rkey, 126 + &repoCreatedAt, 127 + &repo.AtUri, 128 + ); err != nil { 129 + return nil, err 130 + } 131 + 132 + star.Created, err = time.Parse(time.RFC3339, starCreatedAt) 133 + if err != nil { 134 + star.Created = time.Now() 135 + } 136 + repo.Created, err = time.Parse(time.RFC3339, repoCreatedAt) 137 + if err != nil { 138 + repo.Created = time.Now() 139 + } 140 + star.Repo = &repo 141 + 142 + stars = append(stars, star) 143 + } 144 + 145 + if err := rows.Err(); err != nil { 146 + return nil, err 147 + } 148 + 149 + return stars, nil 150 + }
+20 -6
appview/db/timeline.go
··· 8 type TimelineEvent struct { 9 *Repo 10 *Follow 11 EventAt time.Time 12 } 13 14 func MakeTimeline(e Execer) ([]TimelineEvent, error) { 15 var events []TimelineEvent 16 17 - repos, err := GetAllRepos(e) 18 if err != nil { 19 return nil, err 20 } 21 22 - follows, err := GetAllFollows(e) 23 if err != nil { 24 return nil, err 25 } ··· 27 for _, repo := range repos { 28 events = append(events, TimelineEvent{ 29 Repo: &repo, 30 - Follow: nil, 31 EventAt: repo.Created, 32 }) 33 } 34 35 for _, follow := range follows { 36 events = append(events, TimelineEvent{ 37 - Repo: nil, 38 Follow: &follow, 39 EventAt: follow.FollowedAt, 40 }) 41 } 42 43 sort.Slice(events, func(i, j int) bool { 44 return events[i].EventAt.After(events[j].EventAt) 45 }) 46 47 // Limit the slice to 100 events 48 - if len(events) > 50 { 49 - events = events[:50] 50 } 51 52 return events, nil
··· 8 type TimelineEvent struct { 9 *Repo 10 *Follow 11 + *Star 12 EventAt time.Time 13 } 14 15 + // TODO: this gathers heterogenous events from different sources and aggregates 16 + // them in code; if we did this entirely in sql, we could order and limit and paginate easily 17 func MakeTimeline(e Execer) ([]TimelineEvent, error) { 18 var events []TimelineEvent 19 + limit := 50 20 21 + repos, err := GetAllRepos(e, limit) 22 + if err != nil { 23 + return nil, err 24 + } 25 + 26 + follows, err := GetAllFollows(e, limit) 27 if err != nil { 28 return nil, err 29 } 30 31 + stars, err := GetAllStars(e, limit) 32 if err != nil { 33 return nil, err 34 } ··· 36 for _, repo := range repos { 37 events = append(events, TimelineEvent{ 38 Repo: &repo, 39 EventAt: repo.Created, 40 }) 41 } 42 43 for _, follow := range follows { 44 events = append(events, TimelineEvent{ 45 Follow: &follow, 46 EventAt: follow.FollowedAt, 47 }) 48 } 49 50 + for _, star := range stars { 51 + events = append(events, TimelineEvent{ 52 + Star: &star, 53 + EventAt: star.Created, 54 + }) 55 + } 56 + 57 sort.Slice(events, func(i, j int) bool { 58 return events[i].EventAt.After(events[j].EventAt) 59 }) 60 61 // Limit the slice to 100 events 62 + if len(events) > limit { 63 + events = events[:limit] 64 } 65 66 return events, nil
+7
appview/pages/funcmap.go
··· 106 "markdown": func(text string) template.HTML { 107 return template.HTML(renderMarkdown(text)) 108 }, 109 } 110 }
··· 106 "markdown": func(text string) template.HTML { 107 return template.HTML(renderMarkdown(text)) 108 }, 109 + "isNil": func(t any) bool { 110 + // returns false for other "zero" values 111 + return t == nil 112 + }, 113 + "not": func(t bool) bool { 114 + return !t 115 + }, 116 } 117 }
+57 -2
appview/pages/pages.go
··· 17 chromahtml "github.com/alecthomas/chroma/v2/formatters/html" 18 "github.com/alecthomas/chroma/v2/lexers" 19 "github.com/alecthomas/chroma/v2/styles" 20 "github.com/microcosm-cc/bluemonday" 21 "github.com/sotangled/tangled/appview/auth" 22 "github.com/sotangled/tangled/appview/db" ··· 43 name := strings.TrimPrefix(path, "templates/") 44 name = strings.TrimSuffix(name, ".html") 45 46 - if !strings.HasPrefix(path, "templates/layouts/") { 47 // Add the page template on top of the base 48 tmpl, err := template.New(name). 49 Funcs(funcMap()). 50 - ParseFS(files, "templates/layouts/*.html", path) 51 if err != nil { 52 return fmt.Errorf("setting up template: %w", err) 53 } ··· 159 return p.execute("user/profile", w, params) 160 } 161 162 type RepoInfo struct { 163 Name string 164 OwnerDid string 165 OwnerHandle string 166 Description string 167 Knot string 168 SettingsAllowed bool 169 } 170 171 func (r RepoInfo) OwnerWithAt() string { ··· 192 } 193 194 return tabs 195 } 196 197 type RepoIndexParams struct {
··· 17 chromahtml "github.com/alecthomas/chroma/v2/formatters/html" 18 "github.com/alecthomas/chroma/v2/lexers" 19 "github.com/alecthomas/chroma/v2/styles" 20 + "github.com/bluesky-social/indigo/atproto/syntax" 21 "github.com/microcosm-cc/bluemonday" 22 "github.com/sotangled/tangled/appview/auth" 23 "github.com/sotangled/tangled/appview/db" ··· 44 name := strings.TrimPrefix(path, "templates/") 45 name = strings.TrimSuffix(name, ".html") 46 47 + // add fragments as templates 48 + if strings.HasPrefix(path, "templates/fragments/") { 49 + tmpl, err := template.New(name). 50 + Funcs(funcMap()). 51 + ParseFS(files, path) 52 + if err != nil { 53 + return fmt.Errorf("setting up fragment: %w", err) 54 + } 55 + 56 + templates[name] = tmpl 57 + log.Printf("loaded fragment: %s", name) 58 + } 59 + 60 + // layouts and fragments are applied first 61 + if !strings.HasPrefix(path, "templates/layouts/") && 62 + !strings.HasPrefix(path, "templates/fragments/") { 63 // Add the page template on top of the base 64 tmpl, err := template.New(name). 65 Funcs(funcMap()). 66 + ParseFS(files, "templates/layouts/*.html", "templates/fragments/*.html", path) 67 if err != nil { 68 return fmt.Errorf("setting up template: %w", err) 69 } ··· 175 return p.execute("user/profile", w, params) 176 } 177 178 + type FollowFragmentParams struct { 179 + UserDid string 180 + FollowStatus db.FollowStatus 181 + } 182 + 183 + func (p *Pages) FollowFragment(w io.Writer, params FollowFragmentParams) error { 184 + return p.executePlain("fragments/follow", w, params) 185 + } 186 + 187 + type StarFragmentParams struct { 188 + IsStarred bool 189 + RepoAt syntax.ATURI 190 + Stats db.RepoStats 191 + } 192 + 193 + func (p *Pages) StarFragment(w io.Writer, params StarFragmentParams) error { 194 + return p.executePlain("fragments/star", w, params) 195 + } 196 + 197 type RepoInfo struct { 198 Name string 199 OwnerDid string 200 OwnerHandle string 201 Description string 202 Knot string 203 + RepoAt syntax.ATURI 204 SettingsAllowed bool 205 + IsStarred bool 206 + Stats db.RepoStats 207 } 208 209 func (r RepoInfo) OwnerWithAt() string { ··· 230 } 231 232 return tabs 233 + } 234 + 235 + // each tab on a repo could have some metadata: 236 + // 237 + // issues -> number of open issues etc. 238 + // settings -> a warning icon to setup branch protection? idk 239 + // 240 + // we gather these bits of info here, because go templates 241 + // are difficult to program in 242 + func (r RepoInfo) TabMetadata() map[string]any { 243 + meta := make(map[string]any) 244 + 245 + meta["issues"] = r.Stats.IssueCount.Open 246 + 247 + // more stuff? 248 + 249 + return meta 250 } 251 252 type RepoIndexParams struct {
+17
appview/pages/templates/fragments/follow.html
···
··· 1 + {{ define "fragments/follow" }} 2 + <button id="followBtn" 3 + class="btn mt-2 w-full" 4 + 5 + {{ if eq .FollowStatus.String "IsNotFollowing" }} 6 + hx-post="/follow?subject={{.UserDid}}" 7 + {{ else }} 8 + hx-delete="/follow?subject={{.UserDid}}" 9 + {{ end }} 10 + 11 + hx-trigger="click" 12 + hx-target="#followBtn" 13 + hx-swap="outerHTML" 14 + > 15 + {{ if eq .FollowStatus.String "IsNotFollowing" }}Follow{{ else }}Unfollow{{ end }} 16 + </button> 17 + {{ end }}
+36
appview/pages/templates/fragments/star.html
···
··· 1 + {{ define "fragments/star" }} 2 + <button id="starBtn" 3 + class="btn text-sm disabled:opacity-50 disabled:cursor-not-allowed" 4 + 5 + {{ if .IsStarred }} 6 + hx-delete="/star?subject={{.RepoAt}}&countHint={{.Stats.StarCount}}" 7 + {{ else }} 8 + hx-post="/star?subject={{.RepoAt}}&countHint={{.Stats.StarCount}}" 9 + {{ end }} 10 + 11 + hx-trigger="click" 12 + hx-target="#starBtn" 13 + hx-swap="outerHTML" 14 + hx-disabled-elt="#starBtn" 15 + > 16 + <div class="flex gap-2 items-center"> 17 + {{ if .IsStarred }} 18 + <span class="w-3 h-3 fill-current" data-lucide="star"></span> 19 + {{ else }} 20 + <span class="w-3 h-3" data-lucide="star"></span> 21 + {{ end }} 22 + <span> 23 + {{ .Stats.StarCount }} 24 + </span> 25 + <span id="starSpinner" class="hidden"> 26 + loading 27 + </span> 28 + </div> 29 + </button> 30 + <script> 31 + document.body.addEventListener('htmx:afterRequest', function (evt) { 32 + lucide.createIcons(); 33 + }); 34 + </script> 35 + {{ end }} 36 +
+19 -11
appview/pages/templates/layouts/repobase.html
··· 2 3 {{ define "content" }} 4 <section id="repo-header" class="mb-4 py-2 px-6"> 5 <p class="text-lg"> 6 - <a href="/{{ .RepoInfo.OwnerWithAt }}">{{ .RepoInfo.OwnerWithAt }}</a> 7 - <span class="select-none">/</span> 8 - <a href="/{{ .RepoInfo.FullName }}" class="font-bold">{{ .RepoInfo.Name }}</a> 9 </p> 10 - <span> 11 - {{ if .RepoInfo.Description }} 12 - {{ .RepoInfo.Description }} 13 - {{ else }} 14 - <span class="italic">this repo has no description</span> 15 - {{ end }} 16 - </span> 17 </section> 18 <section id="repo-links" class="min-h-screen flex flex-col drop-shadow-sm"> 19 <nav class="w-full mx-auto ml-4"> 20 <div class="flex z-60"> 21 {{ $activeTabStyles := "-mb-px bg-white" }} 22 {{ $tabs := .RepoInfo.GetTabs }} 23 {{ range $item := $tabs }} 24 {{ $key := index $item 0 }} 25 {{ $value := index $item 1 }} 26 <a 27 href="/{{ $.RepoInfo.FullName }}{{ $value }}" 28 class="relative -mr-px group no-underline hover:no-underline" ··· 37 {{ end }} 38 " 39 > 40 - {{ $key }} 41 </div> 42 </a> 43 {{ end }}
··· 2 3 {{ define "content" }} 4 <section id="repo-header" class="mb-4 py-2 px-6"> 5 + <div class="flex gap-3"> 6 <p class="text-lg"> 7 + <a href="/{{ .RepoInfo.OwnerWithAt }}">{{ .RepoInfo.OwnerWithAt }}</a> 8 + <span class="select-none">/</span> 9 + <a href="/{{ .RepoInfo.FullName }}" class="font-bold">{{ .RepoInfo.Name }}</a> 10 </p> 11 + {{ template "fragments/star" .RepoInfo }} 12 + </div> 13 + <span> 14 + {{ if .RepoInfo.Description }} 15 + {{ .RepoInfo.Description }} 16 + {{ else }} 17 + <span class="italic">this repo has no description</span> 18 + {{ end }} 19 + </span> 20 </section> 21 <section id="repo-links" class="min-h-screen flex flex-col drop-shadow-sm"> 22 <nav class="w-full mx-auto ml-4"> 23 <div class="flex z-60"> 24 {{ $activeTabStyles := "-mb-px bg-white" }} 25 {{ $tabs := .RepoInfo.GetTabs }} 26 + {{ $tabmeta := .RepoInfo.TabMetadata }} 27 {{ range $item := $tabs }} 28 {{ $key := index $item 0 }} 29 {{ $value := index $item 1 }} 30 + {{ $meta := index $tabmeta $key }} 31 <a 32 href="/{{ $.RepoInfo.FullName }}{{ $value }}" 33 class="relative -mr-px group no-underline hover:no-underline" ··· 42 {{ end }} 43 " 44 > 45 + {{ $key }} 46 + {{ if not (isNil $meta) }} 47 + <span class="bg-gray-200 rounded py-1/2 px-1 text-sm font-mono">{{ $meta }}</span> 48 + {{ end }} 49 </div> 50 </a> 51 {{ end }}
+31 -19
appview/pages/templates/timeline.html
··· 40 {{ range .Timeline }} 41 <div class="px-6 py-2 bg-white rounded drop-shadow-sm w-fit"> 42 {{ if .Repo }} 43 - {{ $userHandle := index $.DidHandleMap .Repo.Did }} 44 - <div class="flex items-center"> 45 - <p class="text-gray-600"> 46 - <a href="/{{ $userHandle }}" class="no-underline hover:underline">{{ $userHandle }}</a> 47 - created 48 - <a href="/{{ $userHandle }}/{{ .Repo.Name }}" class="no-underline hover:underline">{{ .Repo.Name }}</a> 49 - <time class="text-gray-700">{{ .Repo.Created | timeFmt }}</time> 50 - </p> 51 - </div> 52 {{ else if .Follow }} 53 - {{ $userHandle := index $.DidHandleMap .Follow.UserDid }} 54 - {{ $subjectHandle := index $.DidHandleMap .Follow.SubjectDid }} 55 - <div class="flex items-center"> 56 - <p class="text-gray-600"> 57 - <a href="/{{ $userHandle }}" class="no-underline hover:underline">{{ $userHandle }}</a> 58 - followed 59 - <a href="/{{ $subjectHandle }}" class="no-underline hover:underline">{{ $subjectHandle }}</a> 60 - <time class="text-gray-700">{{ .Follow.FollowedAt | timeFmt }}</time> 61 - </p> 62 - </div> 63 {{ end }} 64 </div> 65 {{ end }} 66 </div> 67 </div> 68 {{ end }}
··· 40 {{ range .Timeline }} 41 <div class="px-6 py-2 bg-white rounded drop-shadow-sm w-fit"> 42 {{ if .Repo }} 43 + {{ $userHandle := index $.DidHandleMap .Repo.Did }} 44 + <div class="flex items-center"> 45 + <p class="text-gray-600"> 46 + <a href="/{{ $userHandle }}" class="no-underline hover:underline">{{ $userHandle }}</a> 47 + created 48 + <a href="/{{ $userHandle }}/{{ .Repo.Name }}" class="no-underline hover:underline">{{ .Repo.Name }}</a> 49 + <time class="text-gray-700">{{ .Repo.Created | timeFmt }}</time> 50 + </p> 51 + </div> 52 {{ else if .Follow }} 53 + {{ $userHandle := index $.DidHandleMap .Follow.UserDid }} 54 + {{ $subjectHandle := index $.DidHandleMap .Follow.SubjectDid }} 55 + <div class="flex items-center"> 56 + <p class="text-gray-600"> 57 + <a href="/{{ $userHandle }}" class="no-underline hover:underline">{{ $userHandle }}</a> 58 + followed 59 + <a href="/{{ $subjectHandle }}" class="no-underline hover:underline">{{ $subjectHandle }}</a> 60 + <time class="text-gray-700">{{ .Follow.FollowedAt | timeFmt }}</time> 61 + </p> 62 + </div> 63 + {{ else if .Star }} 64 + {{ $starrerHandle := index $.DidHandleMap .Star.StarredByDid }} 65 + {{ $repoOwnerHandle := index $.DidHandleMap .Star.Repo.Did }} 66 + <div class="flex items-center"> 67 + <p class="text-gray-600"> 68 + <a href="/{{ $starrerHandle }}" class="no-underline hover:underline">{{ $starrerHandle }}</a> 69 + starred 70 + <a href="/{{ $repoOwnerHandle }}/{{ .Star.Repo.Name }}" class="no-underline hover:underline">{{ $repoOwnerHandle }}/{{ .Star.Repo.Name }}</a> 71 + <time class="text-gray-700">{{ .Star.Created | timeFmt }}</time> 72 + </p> 73 + </div> 74 {{ end }} 75 </div> 76 {{ end }} 77 </div> 78 </div> 79 {{ end }} 80 +
+2 -14
appview/pages/templates/user/profile.html
··· 30 </div> 31 32 {{ if ne .FollowStatus.String "IsSelf" }} 33 - <button id="followBtn" 34 - class="btn mt-2 w-full" 35 - {{ if eq .FollowStatus.String "IsNotFollowing" }} 36 - hx-post="/follow?subject={{.UserDid}}" 37 - {{ else }} 38 - hx-delete="/follow?subject={{.UserDid}}" 39 - {{ end }} 40 - hx-trigger="click" 41 - hx-target="#followBtn" 42 - hx-swap="outerHTML" 43 - > 44 - {{ if eq .FollowStatus.String "IsNotFollowing" }}Follow{{ else }}Unfollow{{ end }} 45 - </button> 46 - {{ end }} 47 </div> 48 {{ end }} 49
··· 30 </div> 31 32 {{ if ne .FollowStatus.String "IsSelf" }} 33 + {{ template "fragments/follow" . }} 34 + {{ end }} 35 </div> 36 {{ end }} 37
+11 -22
appview/state/follow.go
··· 1 package state 2 3 import ( 4 - "fmt" 5 "log" 6 "net/http" 7 "time" ··· 10 lexutil "github.com/bluesky-social/indigo/lex/util" 11 tangled "github.com/sotangled/tangled/api/tangled" 12 "github.com/sotangled/tangled/appview/db" 13 ) 14 15 func (s *State) Follow(w http.ResponseWriter, r *http.Request) { ··· 60 61 log.Println("created atproto record: ", resp.Uri) 62 63 - w.Write([]byte(fmt.Sprintf(` 64 - <button id="followBtn" 65 - class="btn mt-2 w-full" 66 - hx-delete="/follow?subject=%s" 67 - hx-trigger="click" 68 - hx-target="#followBtn" 69 - hx-swap="outerHTML"> 70 - Unfollow 71 - </button> 72 - `, subjectIdent.DID.String()))) 73 74 return 75 case http.MethodDelete: ··· 83 _, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{ 84 Collection: tangled.GraphFollowNSID, 85 Repo: currentUser.Did, 86 - Rkey: follow.RKey, 87 }) 88 89 if err != nil { ··· 97 // this is not an issue, the firehose event might have already done this 98 } 99 100 - w.Write([]byte(fmt.Sprintf(` 101 - <button id="followBtn" 102 - class="btn mt-2 w-full" 103 - hx-post="/follow?subject=%s" 104 - hx-trigger="click" 105 - hx-target="#followBtn" 106 - hx-swap="outerHTML"> 107 - Follow 108 - </button> 109 - `, subjectIdent.DID.String()))) 110 return 111 } 112
··· 1 package state 2 3 import ( 4 "log" 5 "net/http" 6 "time" ··· 9 lexutil "github.com/bluesky-social/indigo/lex/util" 10 tangled "github.com/sotangled/tangled/api/tangled" 11 "github.com/sotangled/tangled/appview/db" 12 + "github.com/sotangled/tangled/appview/pages" 13 ) 14 15 func (s *State) Follow(w http.ResponseWriter, r *http.Request) { ··· 60 61 log.Println("created atproto record: ", resp.Uri) 62 63 + s.pages.FollowFragment(w, pages.FollowFragmentParams{ 64 + UserDid: subjectIdent.DID.String(), 65 + FollowStatus: db.IsFollowing, 66 + }) 67 68 return 69 case http.MethodDelete: ··· 77 _, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{ 78 Collection: tangled.GraphFollowNSID, 79 Repo: currentUser.Did, 80 + Rkey: follow.Rkey, 81 }) 82 83 if err != nil { ··· 91 // this is not an issue, the firehose event might have already done this 92 } 93 94 + s.pages.FollowFragment(w, pages.FollowFragmentParams{ 95 + UserDid: subjectIdent.DID.String(), 96 + FollowStatus: db.IsNotFollowing, 97 + }) 98 + 99 return 100 } 101
+20
appview/state/jetstream.go
··· 6 "fmt" 7 "log" 8 9 "github.com/bluesky-social/jetstream/pkg/models" 10 tangled "github.com/sotangled/tangled/api/tangled" 11 "github.com/sotangled/tangled/appview/db" ··· 40 return err 41 } 42 err = db.AddFollow(d, did, record.Subject, e.Commit.RKey) 43 if err != nil { 44 return fmt.Errorf("failed to add follow to db: %w", err) 45 }
··· 6 "fmt" 7 "log" 8 9 + "github.com/bluesky-social/indigo/atproto/syntax" 10 "github.com/bluesky-social/jetstream/pkg/models" 11 tangled "github.com/sotangled/tangled/api/tangled" 12 "github.com/sotangled/tangled/appview/db" ··· 41 return err 42 } 43 err = db.AddFollow(d, did, record.Subject, e.Commit.RKey) 44 + if err != nil { 45 + return fmt.Errorf("failed to add follow to db: %w", err) 46 + } 47 + case tangled.FeedStarNSID: 48 + record := tangled.FeedStar{} 49 + err := json.Unmarshal(raw, &record) 50 + if err != nil { 51 + log.Println("invalid record") 52 + return err 53 + } 54 + 55 + subjectUri, err := syntax.ParseATURI(record.Subject) 56 + 57 + if err != nil { 58 + log.Println("invalid record") 59 + return err 60 + } 61 + 62 + err = db.AddStar(d, did, subjectUri, e.Commit.RKey) 63 if err != nil { 64 return fmt.Errorf("failed to add follow to db: %w", err) 65 }
+73 -95
appview/state/repo.go
··· 15 "time" 16 17 "github.com/bluesky-social/indigo/atproto/identity" 18 securejoin "github.com/cyphar/filepath-securejoin" 19 "github.com/go-chi/chi/v5" 20 "github.com/sotangled/tangled/api/tangled" ··· 75 76 user := s.auth.GetUser(r) 77 78 - knot := f.Knot 79 - if knot == "knot1.tangled.sh" { 80 - knot = "tangled.sh" 81 - } 82 - 83 s.pages.RepoIndexPage(w, pages.RepoIndexParams{ 84 - LoggedInUser: user, 85 - RepoInfo: pages.RepoInfo{ 86 - OwnerDid: f.OwnerDid(), 87 - OwnerHandle: f.OwnerHandle(), 88 - Name: f.RepoName, 89 - Knot: knot, 90 - SettingsAllowed: settingsAllowed(s, user, f), 91 - }, 92 TagMap: tagMap, 93 RepoIndexResponse: result, 94 }) ··· 133 134 user := s.auth.GetUser(r) 135 s.pages.RepoLog(w, pages.RepoLogParams{ 136 - LoggedInUser: user, 137 - RepoInfo: pages.RepoInfo{ 138 - OwnerDid: f.OwnerDid(), 139 - OwnerHandle: f.OwnerHandle(), 140 - Name: f.RepoName, 141 - SettingsAllowed: settingsAllowed(s, user, f), 142 - }, 143 RepoLogResponse: repolog, 144 }) 145 return ··· 174 175 user := s.auth.GetUser(r) 176 s.pages.RepoCommit(w, pages.RepoCommitParams{ 177 - LoggedInUser: user, 178 - RepoInfo: pages.RepoInfo{ 179 - OwnerDid: f.OwnerDid(), 180 - OwnerHandle: f.OwnerHandle(), 181 - Name: f.RepoName, 182 - SettingsAllowed: settingsAllowed(s, user, f), 183 - }, 184 RepoCommitResponse: result, 185 }) 186 return ··· 228 baseBlobLink := path.Join(f.OwnerDid(), f.RepoName, "blob", ref, treePath) 229 230 s.pages.RepoTree(w, pages.RepoTreeParams{ 231 - LoggedInUser: user, 232 - BreadCrumbs: breadcrumbs, 233 - BaseTreeLink: baseTreeLink, 234 - BaseBlobLink: baseBlobLink, 235 - RepoInfo: pages.RepoInfo{ 236 - OwnerDid: f.OwnerDid(), 237 - OwnerHandle: f.OwnerHandle(), 238 - Name: f.RepoName, 239 - SettingsAllowed: settingsAllowed(s, user, f), 240 - }, 241 RepoTreeResponse: result, 242 }) 243 return ··· 271 272 user := s.auth.GetUser(r) 273 s.pages.RepoTags(w, pages.RepoTagsParams{ 274 - LoggedInUser: user, 275 - RepoInfo: pages.RepoInfo{ 276 - OwnerDid: f.OwnerDid(), 277 - OwnerHandle: f.OwnerHandle(), 278 - Name: f.RepoName, 279 - SettingsAllowed: settingsAllowed(s, user, f), 280 - }, 281 RepoTagsResponse: result, 282 }) 283 return ··· 311 312 user := s.auth.GetUser(r) 313 s.pages.RepoBranches(w, pages.RepoBranchesParams{ 314 - LoggedInUser: user, 315 - RepoInfo: pages.RepoInfo{ 316 - OwnerDid: f.OwnerDid(), 317 - OwnerHandle: f.OwnerHandle(), 318 - Name: f.RepoName, 319 - SettingsAllowed: settingsAllowed(s, user, f), 320 - }, 321 RepoBranchesResponse: result, 322 }) 323 return ··· 361 362 user := s.auth.GetUser(r) 363 s.pages.RepoBlob(w, pages.RepoBlobParams{ 364 - LoggedInUser: user, 365 - RepoInfo: pages.RepoInfo{ 366 - OwnerDid: f.OwnerDid(), 367 - OwnerHandle: f.OwnerHandle(), 368 - Name: f.RepoName, 369 - SettingsAllowed: settingsAllowed(s, user, f), 370 - }, 371 RepoBlobResponse: result, 372 BreadCrumbs: breadcrumbs, 373 }) ··· 488 } 489 490 s.pages.RepoSettings(w, pages.RepoSettingsParams{ 491 - LoggedInUser: user, 492 - RepoInfo: pages.RepoInfo{ 493 - OwnerDid: f.OwnerDid(), 494 - OwnerHandle: f.OwnerHandle(), 495 - Name: f.RepoName, 496 - SettingsAllowed: settingsAllowed(s, user, f), 497 - }, 498 Collaborators: repoCollaborators, 499 IsCollaboratorInviteAllowed: isCollaboratorInviteAllowed, 500 }) ··· 505 Knot string 506 OwnerId identity.Identity 507 RepoName string 508 - RepoAt string 509 } 510 511 func (f *FullyResolvedRepo) OwnerDid() string { ··· 565 return collaborators, nil 566 } 567 568 func (s *State) RepoSingleIssue(w http.ResponseWriter, r *http.Request) { 569 user := s.auth.GetUser(r) 570 f, err := fullyResolvedRepo(r) ··· 609 610 s.pages.RepoSingleIssue(w, pages.RepoSingleIssueParams{ 611 LoggedInUser: user, 612 - RepoInfo: pages.RepoInfo{ 613 - OwnerDid: f.OwnerDid(), 614 - OwnerHandle: f.OwnerHandle(), 615 - Name: f.RepoName, 616 - SettingsAllowed: settingsAllowed(s, user, f), 617 - }, 618 - Issue: *issue, 619 - Comments: comments, 620 621 IssueOwnerHandle: issueOwnerIdent.Handle.String(), 622 DidHandleMap: didHandleMap, ··· 777 return 778 } 779 780 client, _ := s.auth.AuthorizedClient(r) 781 _, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ 782 Collection: tangled.RepoIssueCommentNSID, ··· 784 Rkey: s.TID(), 785 Record: &lexutil.LexiconTypeDecoder{ 786 Val: &tangled.RepoIssueComment{ 787 - Repo: &f.RepoAt, 788 Issue: issueAt, 789 CommentId: &commentIdInt64, 790 Owner: &ownerDid, ··· 835 836 s.pages.RepoIssues(w, pages.RepoIssuesParams{ 837 LoggedInUser: s.auth.GetUser(r), 838 - RepoInfo: pages.RepoInfo{ 839 - OwnerDid: f.OwnerDid(), 840 - OwnerHandle: f.OwnerHandle(), 841 - Name: f.RepoName, 842 - SettingsAllowed: settingsAllowed(s, user, f), 843 - }, 844 Issues: issues, 845 DidHandleMap: didHandleMap, 846 }) ··· 860 case http.MethodGet: 861 s.pages.RepoNewIssue(w, pages.RepoNewIssueParams{ 862 LoggedInUser: user, 863 - RepoInfo: pages.RepoInfo{ 864 - Name: f.RepoName, 865 - OwnerDid: f.OwnerDid(), 866 - OwnerHandle: f.OwnerHandle(), 867 - SettingsAllowed: settingsAllowed(s, user, f), 868 - }, 869 }) 870 case http.MethodPost: 871 title := r.FormValue("title") ··· 902 } 903 904 client, _ := s.auth.AuthorizedClient(r) 905 resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ 906 Collection: tangled.RepoIssueNSID, 907 Repo: user.Did, 908 Rkey: s.TID(), 909 Record: &lexutil.LexiconTypeDecoder{ 910 Val: &tangled.RepoIssue{ 911 - Repo: f.RepoAt, 912 Title: title, 913 Body: &body, 914 Owner: user.Did, ··· 946 case http.MethodGet: 947 s.pages.RepoPulls(w, pages.RepoPullsParams{ 948 LoggedInUser: user, 949 - RepoInfo: pages.RepoInfo{ 950 - Name: f.RepoName, 951 - OwnerDid: f.OwnerDid(), 952 - OwnerHandle: f.OwnerHandle(), 953 - SettingsAllowed: settingsAllowed(s, user, f), 954 - }, 955 }) 956 } 957 } ··· 975 return nil, fmt.Errorf("malformed middleware") 976 } 977 978 return &FullyResolvedRepo{ 979 Knot: knot, 980 OwnerId: id, 981 RepoName: repoName, 982 - RepoAt: repoAt, 983 }, nil 984 } 985
··· 15 "time" 16 17 "github.com/bluesky-social/indigo/atproto/identity" 18 + "github.com/bluesky-social/indigo/atproto/syntax" 19 securejoin "github.com/cyphar/filepath-securejoin" 20 "github.com/go-chi/chi/v5" 21 "github.com/sotangled/tangled/api/tangled" ··· 76 77 user := s.auth.GetUser(r) 78 79 s.pages.RepoIndexPage(w, pages.RepoIndexParams{ 80 + LoggedInUser: user, 81 + RepoInfo: f.RepoInfo(s, user), 82 TagMap: tagMap, 83 RepoIndexResponse: result, 84 }) ··· 123 124 user := s.auth.GetUser(r) 125 s.pages.RepoLog(w, pages.RepoLogParams{ 126 + LoggedInUser: user, 127 + RepoInfo: f.RepoInfo(s, user), 128 RepoLogResponse: repolog, 129 }) 130 return ··· 159 160 user := s.auth.GetUser(r) 161 s.pages.RepoCommit(w, pages.RepoCommitParams{ 162 + LoggedInUser: user, 163 + RepoInfo: f.RepoInfo(s, user), 164 RepoCommitResponse: result, 165 }) 166 return ··· 208 baseBlobLink := path.Join(f.OwnerDid(), f.RepoName, "blob", ref, treePath) 209 210 s.pages.RepoTree(w, pages.RepoTreeParams{ 211 + LoggedInUser: user, 212 + BreadCrumbs: breadcrumbs, 213 + BaseTreeLink: baseTreeLink, 214 + BaseBlobLink: baseBlobLink, 215 + RepoInfo: f.RepoInfo(s, user), 216 RepoTreeResponse: result, 217 }) 218 return ··· 246 247 user := s.auth.GetUser(r) 248 s.pages.RepoTags(w, pages.RepoTagsParams{ 249 + LoggedInUser: user, 250 + RepoInfo: f.RepoInfo(s, user), 251 RepoTagsResponse: result, 252 }) 253 return ··· 281 282 user := s.auth.GetUser(r) 283 s.pages.RepoBranches(w, pages.RepoBranchesParams{ 284 + LoggedInUser: user, 285 + RepoInfo: f.RepoInfo(s, user), 286 RepoBranchesResponse: result, 287 }) 288 return ··· 326 327 user := s.auth.GetUser(r) 328 s.pages.RepoBlob(w, pages.RepoBlobParams{ 329 + LoggedInUser: user, 330 + RepoInfo: f.RepoInfo(s, user), 331 RepoBlobResponse: result, 332 BreadCrumbs: breadcrumbs, 333 }) ··· 448 } 449 450 s.pages.RepoSettings(w, pages.RepoSettingsParams{ 451 + LoggedInUser: user, 452 + RepoInfo: f.RepoInfo(s, user), 453 Collaborators: repoCollaborators, 454 IsCollaboratorInviteAllowed: isCollaboratorInviteAllowed, 455 }) ··· 460 Knot string 461 OwnerId identity.Identity 462 RepoName string 463 + RepoAt syntax.ATURI 464 } 465 466 func (f *FullyResolvedRepo) OwnerDid() string { ··· 520 return collaborators, nil 521 } 522 523 + func (f *FullyResolvedRepo) RepoInfo(s *State, u *auth.User) pages.RepoInfo { 524 + isStarred := false 525 + if u != nil { 526 + isStarred = db.GetStarStatus(s.db, u.Did, syntax.ATURI(f.RepoAt)) 527 + } 528 + 529 + starCount, err := db.GetStarCount(s.db, f.RepoAt) 530 + if err != nil { 531 + log.Println("failed to get star count for ", f.RepoAt) 532 + } 533 + issueCount, err := db.GetIssueCount(s.db, f.RepoAt) 534 + if err != nil { 535 + log.Println("failed to get issue count for ", f.RepoAt) 536 + } 537 + 538 + knot := f.Knot 539 + if knot == "knot1.tangled.sh" { 540 + knot = "tangled.sh" 541 + } 542 + 543 + return pages.RepoInfo{ 544 + OwnerDid: f.OwnerDid(), 545 + OwnerHandle: f.OwnerHandle(), 546 + Name: f.RepoName, 547 + RepoAt: f.RepoAt, 548 + SettingsAllowed: settingsAllowed(s, u, f), 549 + IsStarred: isStarred, 550 + Knot: knot, 551 + Stats: db.RepoStats{ 552 + StarCount: starCount, 553 + IssueCount: issueCount, 554 + }, 555 + } 556 + } 557 + 558 func (s *State) RepoSingleIssue(w http.ResponseWriter, r *http.Request) { 559 user := s.auth.GetUser(r) 560 f, err := fullyResolvedRepo(r) ··· 599 600 s.pages.RepoSingleIssue(w, pages.RepoSingleIssueParams{ 601 LoggedInUser: user, 602 + RepoInfo: f.RepoInfo(s, user), 603 + Issue: *issue, 604 + Comments: comments, 605 606 IssueOwnerHandle: issueOwnerIdent.Handle.String(), 607 DidHandleMap: didHandleMap, ··· 762 return 763 } 764 765 + atUri := f.RepoAt.String() 766 client, _ := s.auth.AuthorizedClient(r) 767 _, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ 768 Collection: tangled.RepoIssueCommentNSID, ··· 770 Rkey: s.TID(), 771 Record: &lexutil.LexiconTypeDecoder{ 772 Val: &tangled.RepoIssueComment{ 773 + Repo: &atUri, 774 Issue: issueAt, 775 CommentId: &commentIdInt64, 776 Owner: &ownerDid, ··· 821 822 s.pages.RepoIssues(w, pages.RepoIssuesParams{ 823 LoggedInUser: s.auth.GetUser(r), 824 + RepoInfo: f.RepoInfo(s, user), 825 Issues: issues, 826 DidHandleMap: didHandleMap, 827 }) ··· 841 case http.MethodGet: 842 s.pages.RepoNewIssue(w, pages.RepoNewIssueParams{ 843 LoggedInUser: user, 844 + RepoInfo: f.RepoInfo(s, user), 845 }) 846 case http.MethodPost: 847 title := r.FormValue("title") ··· 878 } 879 880 client, _ := s.auth.AuthorizedClient(r) 881 + atUri := f.RepoAt.String() 882 resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ 883 Collection: tangled.RepoIssueNSID, 884 Repo: user.Did, 885 Rkey: s.TID(), 886 Record: &lexutil.LexiconTypeDecoder{ 887 Val: &tangled.RepoIssue{ 888 + Repo: atUri, 889 Title: title, 890 Body: &body, 891 Owner: user.Did, ··· 923 case http.MethodGet: 924 s.pages.RepoPulls(w, pages.RepoPullsParams{ 925 LoggedInUser: user, 926 + RepoInfo: f.RepoInfo(s, user), 927 }) 928 } 929 } ··· 947 return nil, fmt.Errorf("malformed middleware") 948 } 949 950 + parsedRepoAt, err := syntax.ParseATURI(repoAt) 951 + if err != nil { 952 + log.Println("malformed repo at-uri") 953 + return nil, fmt.Errorf("malformed middleware") 954 + } 955 + 956 return &FullyResolvedRepo{ 957 Knot: knot, 958 OwnerId: id, 959 RepoName: repoName, 960 + RepoAt: parsedRepoAt, 961 }, nil 962 } 963
+115
appview/state/star.go
···
··· 1 + package state 2 + 3 + import ( 4 + "log" 5 + "net/http" 6 + "time" 7 + 8 + comatproto "github.com/bluesky-social/indigo/api/atproto" 9 + "github.com/bluesky-social/indigo/atproto/syntax" 10 + lexutil "github.com/bluesky-social/indigo/lex/util" 11 + tangled "github.com/sotangled/tangled/api/tangled" 12 + "github.com/sotangled/tangled/appview/db" 13 + "github.com/sotangled/tangled/appview/pages" 14 + ) 15 + 16 + func (s *State) Star(w http.ResponseWriter, r *http.Request) { 17 + currentUser := s.auth.GetUser(r) 18 + 19 + subject := r.URL.Query().Get("subject") 20 + if subject == "" { 21 + log.Println("invalid form") 22 + return 23 + } 24 + 25 + subjectUri, err := syntax.ParseATURI(subject) 26 + if err != nil { 27 + log.Println("invalid form") 28 + return 29 + } 30 + 31 + client, _ := s.auth.AuthorizedClient(r) 32 + 33 + switch r.Method { 34 + case http.MethodPost: 35 + createdAt := time.Now().Format(time.RFC3339) 36 + rkey := s.TID() 37 + resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ 38 + Collection: tangled.FeedStarNSID, 39 + Repo: currentUser.Did, 40 + Rkey: rkey, 41 + Record: &lexutil.LexiconTypeDecoder{ 42 + Val: &tangled.FeedStar{ 43 + Subject: subjectUri.String(), 44 + CreatedAt: createdAt, 45 + }}, 46 + }) 47 + if err != nil { 48 + log.Println("failed to create atproto record", err) 49 + return 50 + } 51 + 52 + err = db.AddStar(s.db, currentUser.Did, subjectUri, rkey) 53 + if err != nil { 54 + log.Println("failed to star", err) 55 + return 56 + } 57 + 58 + starCount, err := db.GetStarCount(s.db, subjectUri) 59 + if err != nil { 60 + log.Println("failed to get star count for ", subjectUri) 61 + } 62 + 63 + log.Println("created atproto record: ", resp.Uri) 64 + 65 + s.pages.StarFragment(w, pages.StarFragmentParams{ 66 + IsStarred: true, 67 + RepoAt: subjectUri, 68 + Stats: db.RepoStats{ 69 + StarCount: starCount, 70 + }, 71 + }) 72 + 73 + return 74 + case http.MethodDelete: 75 + // find the record in the db 76 + star, err := db.GetStar(s.db, currentUser.Did, subjectUri) 77 + if err != nil { 78 + log.Println("failed to get star relationship") 79 + return 80 + } 81 + 82 + _, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{ 83 + Collection: tangled.FeedStarNSID, 84 + Repo: currentUser.Did, 85 + Rkey: star.Rkey, 86 + }) 87 + 88 + if err != nil { 89 + log.Println("failed to unstar") 90 + return 91 + } 92 + 93 + err = db.DeleteStar(s.db, currentUser.Did, subjectUri) 94 + if err != nil { 95 + log.Println("failed to delete star from DB") 96 + // this is not an issue, the firehose event might have already done this 97 + } 98 + 99 + starCount, err := db.GetStarCount(s.db, subjectUri) 100 + if err != nil { 101 + log.Println("failed to get star count for ", subjectUri) 102 + } 103 + 104 + s.pages.StarFragment(w, pages.StarFragmentParams{ 105 + IsStarred: false, 106 + RepoAt: subjectUri, 107 + Stats: db.RepoStats{ 108 + StarCount: starCount, 109 + }, 110 + }) 111 + 112 + return 113 + } 114 + 115 + }
+9 -2
appview/state/state.go
··· 184 didsToResolve = append(didsToResolve, ev.Repo.Did) 185 } 186 if ev.Follow != nil { 187 - didsToResolve = append(didsToResolve, ev.Follow.UserDid) 188 - didsToResolve = append(didsToResolve, ev.Follow.SubjectDid) 189 } 190 } 191 ··· 931 r.With(AuthMiddleware(s)).Route("/follow", func(r chi.Router) { 932 r.Post("/", s.Follow) 933 r.Delete("/", s.Follow) 934 }) 935 936 r.Route("/settings", func(r chi.Router) {
··· 184 didsToResolve = append(didsToResolve, ev.Repo.Did) 185 } 186 if ev.Follow != nil { 187 + didsToResolve = append(didsToResolve, ev.Follow.UserDid, ev.Follow.SubjectDid) 188 + } 189 + if ev.Star != nil { 190 + didsToResolve = append(didsToResolve, ev.Star.StarredByDid, ev.Star.Repo.Did) 191 } 192 } 193 ··· 933 r.With(AuthMiddleware(s)).Route("/follow", func(r chi.Router) { 934 r.Post("/", s.Follow) 935 r.Delete("/", s.Follow) 936 + }) 937 + 938 + r.With(AuthMiddleware(s)).Route("/star", func(r chi.Router) { 939 + r.Post("/", s.Star) 940 + r.Delete("/", s.Star) 941 }) 942 943 r.Route("/settings", func(r chi.Router) {
+6 -5
cmd/gen.go
··· 14 if err := genCfg.WriteMapEncodersToFile( 15 "api/tangled/cbor_gen.go", 16 "tangled", 17 shtangled.PublicKey{}, 18 - shtangled.KnotMember{}, 19 - shtangled.GraphFollow{}, 20 shtangled.Repo{}, 21 - shtangled.RepoIssue{}, 22 - shtangled.RepoIssueState{}, 23 - shtangled.RepoIssueComment{}, 24 ); err != nil { 25 panic(err) 26 }
··· 14 if err := genCfg.WriteMapEncodersToFile( 15 "api/tangled/cbor_gen.go", 16 "tangled", 17 + shtangled.FeedStar{}, 18 + shtangled.GraphFollow{}, 19 + shtangled.KnotMember{}, 20 shtangled.PublicKey{}, 21 + shtangled.RepoIssueComment{}, 22 + shtangled.RepoIssueState{}, 23 + shtangled.RepoIssue{}, 24 shtangled.Repo{}, 25 ); err != nil { 26 panic(err) 27 }
+31
lexicons/star.json
···
··· 1 + { 2 + "lexicon": 1, 3 + "id": "sh.tangled.feed.star", 4 + "needsCbor": true, 5 + "needsType": true, 6 + "defs": { 7 + "main": { 8 + "type": "record", 9 + "key": "tid", 10 + "record": { 11 + "type": "object", 12 + "required": [ 13 + "createdAt", 14 + "subject" 15 + ], 16 + "properties": { 17 + "createdAt": { 18 + "type": "string", 19 + "format": "datetime" 20 + }, 21 + "subject": { 22 + "type": "string", 23 + "format": "at-uri" 24 + } 25 + } 26 + } 27 + } 28 + } 29 + } 30 + 31 +