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

Compare changes

Choose any two refs to compare.

Changed files
+308 -179
api
appview
db
issues
pages
templates
repo
state
lexicons
+2 -122
api/tangled/cbor_gen.go
··· 5512 5512 } 5513 5513 5514 5514 cw := cbg.NewCborWriter(w) 5515 - fieldCount := 7 5515 + fieldCount := 6 5516 5516 5517 5517 if t.Body == nil { 5518 5518 fieldCount-- ··· 5642 5642 return err 5643 5643 } 5644 5644 5645 - // t.IssueId (int64) (int64) 5646 - if len("issueId") > 1000000 { 5647 - return xerrors.Errorf("Value in field \"issueId\" was too long") 5648 - } 5649 - 5650 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("issueId"))); err != nil { 5651 - return err 5652 - } 5653 - if _, err := cw.WriteString(string("issueId")); err != nil { 5654 - return err 5655 - } 5656 - 5657 - if t.IssueId >= 0 { 5658 - if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.IssueId)); err != nil { 5659 - return err 5660 - } 5661 - } else { 5662 - if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.IssueId-1)); err != nil { 5663 - return err 5664 - } 5665 - } 5666 - 5667 5645 // t.CreatedAt (string) (string) 5668 5646 if len("createdAt") > 1000000 { 5669 5647 return xerrors.Errorf("Value in field \"createdAt\" was too long") ··· 5795 5773 5796 5774 t.Title = string(sval) 5797 5775 } 5798 - // t.IssueId (int64) (int64) 5799 - case "issueId": 5800 - { 5801 - maj, extra, err := cr.ReadHeader() 5802 - if err != nil { 5803 - return err 5804 - } 5805 - var extraI int64 5806 - switch maj { 5807 - case cbg.MajUnsignedInt: 5808 - extraI = int64(extra) 5809 - if extraI < 0 { 5810 - return fmt.Errorf("int64 positive overflow") 5811 - } 5812 - case cbg.MajNegativeInt: 5813 - extraI = int64(extra) 5814 - if extraI < 0 { 5815 - return fmt.Errorf("int64 negative overflow") 5816 - } 5817 - extraI = -1 - extraI 5818 - default: 5819 - return fmt.Errorf("wrong type for int64 field: %d", maj) 5820 - } 5821 - 5822 - t.IssueId = int64(extraI) 5823 - } 5824 5776 // t.CreatedAt (string) (string) 5825 5777 case "createdAt": 5826 5778 ··· 5850 5802 } 5851 5803 5852 5804 cw := cbg.NewCborWriter(w) 5853 - fieldCount := 7 5854 - 5855 - if t.CommentId == nil { 5856 - fieldCount-- 5857 - } 5805 + fieldCount := 6 5858 5806 5859 5807 if t.Owner == nil { 5860 5808 fieldCount-- ··· 5997 5945 } 5998 5946 } 5999 5947 6000 - // t.CommentId (int64) (int64) 6001 - if t.CommentId != nil { 6002 - 6003 - if len("commentId") > 1000000 { 6004 - return xerrors.Errorf("Value in field \"commentId\" was too long") 6005 - } 6006 - 6007 - if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("commentId"))); err != nil { 6008 - return err 6009 - } 6010 - if _, err := cw.WriteString(string("commentId")); err != nil { 6011 - return err 6012 - } 6013 - 6014 - if t.CommentId == nil { 6015 - if _, err := cw.Write(cbg.CborNull); err != nil { 6016 - return err 6017 - } 6018 - } else { 6019 - if *t.CommentId >= 0 { 6020 - if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(*t.CommentId)); err != nil { 6021 - return err 6022 - } 6023 - } else { 6024 - if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-*t.CommentId-1)); err != nil { 6025 - return err 6026 - } 6027 - } 6028 - } 6029 - 6030 - } 6031 - 6032 5948 // t.CreatedAt (string) (string) 6033 5949 if len("createdAt") > 1000000 { 6034 5950 return xerrors.Errorf("Value in field \"createdAt\" was too long") ··· 6168 6084 } 6169 6085 6170 6086 t.Owner = (*string)(&sval) 6171 - } 6172 - } 6173 - // t.CommentId (int64) (int64) 6174 - case "commentId": 6175 - { 6176 - 6177 - b, err := cr.ReadByte() 6178 - if err != nil { 6179 - return err 6180 - } 6181 - if b != cbg.CborNull[0] { 6182 - if err := cr.UnreadByte(); err != nil { 6183 - return err 6184 - } 6185 - maj, extra, err := cr.ReadHeader() 6186 - if err != nil { 6187 - return err 6188 - } 6189 - var extraI int64 6190 - switch maj { 6191 - case cbg.MajUnsignedInt: 6192 - extraI = int64(extra) 6193 - if extraI < 0 { 6194 - return fmt.Errorf("int64 positive overflow") 6195 - } 6196 - case cbg.MajNegativeInt: 6197 - extraI = int64(extra) 6198 - if extraI < 0 { 6199 - return fmt.Errorf("int64 negative overflow") 6200 - } 6201 - extraI = -1 - extraI 6202 - default: 6203 - return fmt.Errorf("wrong type for int64 field: %d", maj) 6204 - } 6205 - 6206 - t.CommentId = (*int64)(&extraI) 6207 6087 } 6208 6088 } 6209 6089 // t.CreatedAt (string) (string)
-1
api/tangled/issuecomment.go
··· 19 19 type RepoIssueComment struct { 20 20 LexiconTypeID string `json:"$type,const=sh.tangled.repo.issue.comment" cborgen:"$type,const=sh.tangled.repo.issue.comment"` 21 21 Body string `json:"body" cborgen:"body"` 22 - CommentId *int64 `json:"commentId,omitempty" cborgen:"commentId,omitempty"` 23 22 CreatedAt string `json:"createdAt" cborgen:"createdAt"` 24 23 Issue string `json:"issue" cborgen:"issue"` 25 24 Owner *string `json:"owner,omitempty" cborgen:"owner,omitempty"`
-1
api/tangled/repoissue.go
··· 20 20 LexiconTypeID string `json:"$type,const=sh.tangled.repo.issue" cborgen:"$type,const=sh.tangled.repo.issue"` 21 21 Body *string `json:"body,omitempty" cborgen:"body,omitempty"` 22 22 CreatedAt string `json:"createdAt" cborgen:"createdAt"` 23 - IssueId int64 `json:"issueId" cborgen:"issueId"` 24 23 Owner string `json:"owner" cborgen:"owner"` 25 24 Repo string `json:"repo" cborgen:"repo"` 26 25 Title string `json:"title" cborgen:"title"`
+105
appview/db/issues.go
··· 3 3 import ( 4 4 "database/sql" 5 5 "fmt" 6 + mathrand "math/rand/v2" 6 7 "strings" 7 8 "time" 8 9 ··· 47 48 48 49 func (i *Issue) AtUri() syntax.ATURI { 49 50 return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", i.OwnerDid, tangled.RepoIssueNSID, i.Rkey)) 51 + } 52 + 53 + func IssueFromRecord(did, rkey string, record tangled.RepoIssue) Issue { 54 + created, err := time.Parse(time.RFC3339, record.CreatedAt) 55 + if err != nil { 56 + created = time.Now() 57 + } 58 + 59 + body := "" 60 + if record.Body != nil { 61 + body = *record.Body 62 + } 63 + 64 + return Issue{ 65 + RepoAt: syntax.ATURI(record.Repo), 66 + OwnerDid: record.Owner, 67 + Rkey: rkey, 68 + Created: created, 69 + Title: record.Title, 70 + Body: body, 71 + Open: true, // new issues are open by default 72 + } 73 + } 74 + 75 + func ResolveIssueFromAtUri(e Execer, issueUri syntax.ATURI) (syntax.ATURI, int, error) { 76 + ownerDid := issueUri.Authority().String() 77 + issueRkey := issueUri.RecordKey().String() 78 + 79 + var repoAt string 80 + var issueId int 81 + 82 + query := `select repo_at, issue_id from issues where owner_did = ? and rkey = ?` 83 + err := e.QueryRow(query, ownerDid, issueRkey).Scan(&repoAt, &issueId) 84 + if err != nil { 85 + return "", 0, err 86 + } 87 + 88 + return syntax.ATURI(repoAt), issueId, nil 89 + } 90 + 91 + func IssueCommentFromRecord(e Execer, did, rkey string, record tangled.RepoIssueComment) (Comment, error) { 92 + created, err := time.Parse(time.RFC3339, record.CreatedAt) 93 + if err != nil { 94 + created = time.Now() 95 + } 96 + 97 + ownerDid := did 98 + if record.Owner != nil { 99 + ownerDid = *record.Owner 100 + } 101 + 102 + issueUri, err := syntax.ParseATURI(record.Issue) 103 + if err != nil { 104 + return Comment{}, err 105 + } 106 + 107 + repoAt, issueId, err := ResolveIssueFromAtUri(e, issueUri) 108 + if err != nil { 109 + return Comment{}, err 110 + } 111 + 112 + comment := Comment{ 113 + OwnerDid: ownerDid, 114 + RepoAt: repoAt, 115 + Rkey: rkey, 116 + Body: record.Body, 117 + Issue: issueId, 118 + CommentId: mathrand.IntN(1000000), 119 + Created: &created, 120 + } 121 + 122 + return comment, nil 50 123 } 51 124 52 125 func NewIssue(tx *sql.Tx, issue *Issue) error { ··· 550 623 deleted = strftime('%Y-%m-%dT%H:%M:%SZ', 'now') 551 624 where repo_at = ? and issue_id = ? and comment_id = ? 552 625 `, repoAt, issueId, commentId) 626 + return err 627 + } 628 + 629 + func UpdateCommentByRkey(e Execer, ownerDid, rkey, newBody string) error { 630 + _, err := e.Exec( 631 + ` 632 + update comments 633 + set body = ?, 634 + edited = strftime('%Y-%m-%dT%H:%M:%SZ', 'now') 635 + where owner_did = ? and rkey = ? 636 + `, newBody, ownerDid, rkey) 637 + return err 638 + } 639 + 640 + func DeleteCommentByRkey(e Execer, ownerDid, rkey string) error { 641 + _, err := e.Exec( 642 + ` 643 + update comments 644 + set body = "", 645 + deleted = strftime('%Y-%m-%dT%H:%M:%SZ', 'now') 646 + where owner_did = ? and rkey = ? 647 + `, ownerDid, rkey) 648 + return err 649 + } 650 + 651 + func UpdateIssueByRkey(e Execer, ownerDid, rkey, title, body string) error { 652 + _, err := e.Exec(`update issues set title = ?, body = ? where owner_did = ? and rkey = ?`, title, body, ownerDid, rkey) 653 + return err 654 + } 655 + 656 + func DeleteIssueByRkey(e Execer, ownerDid, rkey string) error { 657 + _, err := e.Exec(`delete from issues where owner_did = ? and rkey = ?`, ownerDid, rkey) 553 658 return err 554 659 } 555 660
+179 -6
appview/ingester.go
··· 5 5 "encoding/json" 6 6 "fmt" 7 7 "log/slog" 8 + "strings" 8 9 "time" 9 10 10 11 "github.com/bluesky-social/indigo/atproto/syntax" ··· 14 15 "tangled.sh/tangled.sh/core/api/tangled" 15 16 "tangled.sh/tangled.sh/core/appview/config" 16 17 "tangled.sh/tangled.sh/core/appview/db" 18 + "tangled.sh/tangled.sh/core/appview/pages/markup" 17 19 "tangled.sh/tangled.sh/core/appview/spindleverify" 18 20 "tangled.sh/tangled.sh/core/idresolver" 19 21 "tangled.sh/tangled.sh/core/rbac" ··· 61 63 case tangled.ActorProfileNSID: 62 64 err = i.ingestProfile(e) 63 65 case tangled.SpindleMemberNSID: 64 - err = i.ingestSpindleMember(e) 66 + err = i.ingestSpindleMember(ctx, e) 65 67 case tangled.SpindleNSID: 66 - err = i.ingestSpindle(e) 68 + err = i.ingestSpindle(ctx, e) 67 69 case tangled.StringNSID: 68 70 err = i.ingestString(e) 71 + case tangled.RepoIssueNSID: 72 + err = i.ingestIssue(ctx, e) 73 + case tangled.RepoIssueCommentNSID: 74 + err = i.ingestIssueComment(e) 69 75 } 70 76 l = i.Logger.With("nsid", e.Commit.Collection) 71 77 } ··· 336 342 return nil 337 343 } 338 344 339 - func (i *Ingester) ingestSpindleMember(e *models.Event) error { 345 + func (i *Ingester) ingestSpindleMember(ctx context.Context, e *models.Event) error { 340 346 did := e.Did 341 347 var err error 342 348 ··· 359 365 return fmt.Errorf("failed to enforce permissions: %w", err) 360 366 } 361 367 362 - memberId, err := i.IdResolver.ResolveIdent(context.Background(), record.Subject) 368 + memberId, err := i.IdResolver.ResolveIdent(ctx, record.Subject) 363 369 if err != nil { 364 370 return err 365 371 } ··· 442 448 return nil 443 449 } 444 450 445 - func (i *Ingester) ingestSpindle(e *models.Event) error { 451 + func (i *Ingester) ingestSpindle(ctx context.Context, e *models.Event) error { 446 452 did := e.Did 447 453 var err error 448 454 ··· 475 481 return err 476 482 } 477 483 478 - err = spindleverify.RunVerification(context.Background(), instance, did, i.Config.Core.Dev) 484 + err = spindleverify.RunVerification(ctx, instance, did, i.Config.Core.Dev) 479 485 if err != nil { 480 486 l.Error("failed to add spindle to db", "err", err, "instance", instance) 481 487 return err ··· 609 615 610 616 return nil 611 617 } 618 + 619 + func (i *Ingester) ingestIssue(ctx context.Context, e *models.Event) error { 620 + did := e.Did 621 + rkey := e.Commit.RKey 622 + 623 + var err error 624 + 625 + l := i.Logger.With("handler", "ingestIssue", "nsid", e.Commit.Collection, "did", did, "rkey", rkey) 626 + l.Info("ingesting record") 627 + 628 + ddb, ok := i.Db.Execer.(*db.DB) 629 + if !ok { 630 + return fmt.Errorf("failed to index issue record, invalid db cast") 631 + } 632 + 633 + switch e.Commit.Operation { 634 + case models.CommitOperationCreate: 635 + raw := json.RawMessage(e.Commit.Record) 636 + record := tangled.RepoIssue{} 637 + err = json.Unmarshal(raw, &record) 638 + if err != nil { 639 + l.Error("invalid record", "err", err) 640 + return err 641 + } 642 + 643 + issue := db.IssueFromRecord(did, rkey, record) 644 + 645 + sanitizer := markup.NewSanitizer() 646 + if st := strings.TrimSpace(sanitizer.SanitizeDescription(issue.Title)); st == "" { 647 + return fmt.Errorf("title is empty after HTML sanitization") 648 + } 649 + if sb := strings.TrimSpace(sanitizer.SanitizeDefault(issue.Body)); sb == "" { 650 + return fmt.Errorf("body is empty after HTML sanitization") 651 + } 652 + 653 + tx, err := ddb.BeginTx(ctx, nil) 654 + if err != nil { 655 + l.Error("failed to begin transaction", "err", err) 656 + return err 657 + } 658 + 659 + err = db.NewIssue(tx, &issue) 660 + if err != nil { 661 + l.Error("failed to create issue", "err", err) 662 + return err 663 + } 664 + 665 + return nil 666 + 667 + case models.CommitOperationUpdate: 668 + raw := json.RawMessage(e.Commit.Record) 669 + record := tangled.RepoIssue{} 670 + err = json.Unmarshal(raw, &record) 671 + if err != nil { 672 + l.Error("invalid record", "err", err) 673 + return err 674 + } 675 + 676 + body := "" 677 + if record.Body != nil { 678 + body = *record.Body 679 + } 680 + 681 + sanitizer := markup.NewSanitizer() 682 + if st := strings.TrimSpace(sanitizer.SanitizeDescription(record.Title)); st == "" { 683 + return fmt.Errorf("title is empty after HTML sanitization") 684 + } 685 + if sb := strings.TrimSpace(sanitizer.SanitizeDefault(body)); sb == "" { 686 + return fmt.Errorf("body is empty after HTML sanitization") 687 + } 688 + 689 + err = db.UpdateIssueByRkey(ddb, did, rkey, record.Title, body) 690 + if err != nil { 691 + l.Error("failed to update issue", "err", err) 692 + return err 693 + } 694 + 695 + return nil 696 + 697 + case models.CommitOperationDelete: 698 + if err := db.DeleteIssueByRkey(ddb, did, rkey); err != nil { 699 + l.Error("failed to delete", "err", err) 700 + return fmt.Errorf("failed to delete issue record: %w", err) 701 + } 702 + 703 + return nil 704 + } 705 + 706 + return fmt.Errorf("unknown operation: %s", e.Commit.Operation) 707 + } 708 + 709 + func (i *Ingester) ingestIssueComment(e *models.Event) error { 710 + did := e.Did 711 + rkey := e.Commit.RKey 712 + 713 + var err error 714 + 715 + l := i.Logger.With("handler", "ingestIssueComment", "nsid", e.Commit.Collection, "did", did, "rkey", rkey) 716 + l.Info("ingesting record") 717 + 718 + ddb, ok := i.Db.Execer.(*db.DB) 719 + if !ok { 720 + return fmt.Errorf("failed to index issue comment record, invalid db cast") 721 + } 722 + 723 + switch e.Commit.Operation { 724 + case models.CommitOperationCreate: 725 + raw := json.RawMessage(e.Commit.Record) 726 + record := tangled.RepoIssueComment{} 727 + err = json.Unmarshal(raw, &record) 728 + if err != nil { 729 + l.Error("invalid record", "err", err) 730 + return err 731 + } 732 + 733 + comment, err := db.IssueCommentFromRecord(ddb, did, rkey, record) 734 + if err != nil { 735 + l.Error("failed to parse comment from record", "err", err) 736 + return err 737 + } 738 + 739 + sanitizer := markup.NewSanitizer() 740 + if sb := strings.TrimSpace(sanitizer.SanitizeDefault(comment.Body)); sb == "" { 741 + return fmt.Errorf("body is empty after HTML sanitization") 742 + } 743 + 744 + err = db.NewIssueComment(ddb, &comment) 745 + if err != nil { 746 + l.Error("failed to create issue comment", "err", err) 747 + return err 748 + } 749 + 750 + return nil 751 + 752 + case models.CommitOperationUpdate: 753 + raw := json.RawMessage(e.Commit.Record) 754 + record := tangled.RepoIssueComment{} 755 + err = json.Unmarshal(raw, &record) 756 + if err != nil { 757 + l.Error("invalid record", "err", err) 758 + return err 759 + } 760 + 761 + sanitizer := markup.NewSanitizer() 762 + if sb := strings.TrimSpace(sanitizer.SanitizeDefault(record.Body)); sb == "" { 763 + return fmt.Errorf("body is empty after HTML sanitization") 764 + } 765 + 766 + err = db.UpdateCommentByRkey(ddb, did, rkey, record.Body) 767 + if err != nil { 768 + l.Error("failed to update issue comment", "err", err) 769 + return err 770 + } 771 + 772 + return nil 773 + 774 + case models.CommitOperationDelete: 775 + if err := db.DeleteCommentByRkey(ddb, did, rkey); err != nil { 776 + l.Error("failed to delete", "err", err) 777 + return fmt.Errorf("failed to delete issue comment record: %w", err) 778 + } 779 + 780 + return nil 781 + } 782 + 783 + return fmt.Errorf("unknown operation: %s", e.Commit.Operation) 784 + }
+4 -9
appview/issues/issues.go
··· 278 278 } 279 279 280 280 createdAt := time.Now().Format(time.RFC3339) 281 - commentIdInt64 := int64(commentId) 282 281 ownerDid := user.Did 283 282 issueAt, err := db.GetIssueAt(rp.db, f.RepoAt(), issueIdInt) 284 283 if err != nil { ··· 302 301 Val: &tangled.RepoIssueComment{ 303 302 Repo: &atUri, 304 303 Issue: issueAt, 305 - CommentId: &commentIdInt64, 306 304 Owner: &ownerDid, 307 305 Body: body, 308 306 CreatedAt: createdAt, ··· 451 449 repoAt := record["repo"].(string) 452 450 issueAt := record["issue"].(string) 453 451 createdAt := record["createdAt"].(string) 454 - commentIdInt64 := int64(commentIdInt) 455 452 456 453 _, err = client.RepoPutRecord(r.Context(), &comatproto.RepoPutRecord_Input{ 457 454 Collection: tangled.RepoIssueCommentNSID, ··· 462 459 Val: &tangled.RepoIssueComment{ 463 460 Repo: &repoAt, 464 461 Issue: issueAt, 465 - CommentId: &commentIdInt64, 466 462 Owner: &comment.OwnerDid, 467 463 Body: newBody, 468 464 CreatedAt: createdAt, ··· 687 683 Rkey: issue.Rkey, 688 684 Record: &lexutil.LexiconTypeDecoder{ 689 685 Val: &tangled.RepoIssue{ 690 - Repo: atUri, 691 - Title: title, 692 - Body: &body, 693 - Owner: user.Did, 694 - IssueId: int64(issue.IssueId), 686 + Repo: atUri, 687 + Title: title, 688 + Body: &body, 689 + Owner: user.Did, 695 690 }, 696 691 }, 697 692 })
+14 -22
appview/pages/templates/repo/index.html
··· 356 356 357 357 {{ define "repoAfter" }} 358 358 {{- if or .HTMLReadme .Readme -}} 359 - <div class="mt-4 rounded bg-white dark:bg-gray-800 drop-shadow-sm w-full mx-auto overflow-hidden"> 360 - {{- if .ReadmeFileName -}} 361 - <div class="px-4 py-2 bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600 flex items-center gap-2"> 362 - {{ i "file-text" "w-4 h-4" "text-gray-600 dark:text-gray-400" }} 363 - <span class="font-mono text-sm text-gray-800 dark:text-gray-200">{{ .ReadmeFileName }}</span> 364 - </div> 365 - {{- end -}} 366 - <section 367 - class="p-6 overflow-auto {{ if not .Raw }} 368 - prose dark:prose-invert dark:[&_pre]:bg-gray-900 369 - dark:[&_code]:text-gray-300 dark:[&_pre_code]:bg-gray-900 370 - dark:[&_pre]:border dark:[&_pre]:border-gray-700 371 - {{ end }}" 372 - > 373 - <article class="{{ if .Raw }}whitespace-pre{{ end }}">{{- if .Raw -}}<pre class="dark:bg-gray-800 dark:text-white overflow-x-auto"> 374 - {{- .Readme -}} 375 - </pre> 376 - {{- else -}} 377 - {{ .HTMLReadme }} 378 - {{- end -}}</article> 379 - </section> 380 - </div> 359 + <section 360 + class="p-6 mt-4 rounded-br rounded-bl bg-white dark:bg-gray-800 dark:text-white drop-shadow-sm w-full mx-auto overflow-auto {{ if not .Raw }} 361 + prose dark:prose-invert dark:[&_pre]:bg-gray-900 362 + dark:[&_code]:text-gray-300 dark:[&_pre_code]:bg-gray-900 363 + dark:[&_pre]:border dark:[&_pre]:border-gray-700 364 + {{ end }}" 365 + > 366 + <article class="{{ if .Raw }}whitespace-pre{{ end }}">{{- if .Raw -}}<pre class="dark:bg-gray-800 dark:text-white overflow-x-auto"> 367 + {{- .Readme -}} 368 + </pre> 369 + {{- else -}} 370 + {{ .HTMLReadme }} 371 + {{- end -}}</article> 372 + </section> 381 373 {{- end -}} 382 374 {{ end }}
+2
appview/state/state.go
··· 94 94 tangled.SpindleMemberNSID, 95 95 tangled.SpindleNSID, 96 96 tangled.StringNSID, 97 + tangled.RepoIssueNSID, 98 + tangled.RepoIssueCommentNSID, 97 99 }, 98 100 nil, 99 101 slog.Default(),
+1 -8
lexicons/issue/comment.json
··· 9 9 "key": "tid", 10 10 "record": { 11 11 "type": "object", 12 - "required": [ 13 - "issue", 14 - "body", 15 - "createdAt" 16 - ], 12 + "required": ["issue", "body", "createdAt"], 17 13 "properties": { 18 14 "issue": { 19 15 "type": "string", ··· 22 18 "repo": { 23 19 "type": "string", 24 20 "format": "at-uri" 25 - }, 26 - "commentId": { 27 - "type": "integer" 28 21 }, 29 22 "owner": { 30 23 "type": "string",
+1 -10
lexicons/issue/issue.json
··· 9 9 "key": "tid", 10 10 "record": { 11 11 "type": "object", 12 - "required": [ 13 - "repo", 14 - "issueId", 15 - "owner", 16 - "title", 17 - "createdAt" 18 - ], 12 + "required": ["repo", "owner", "title", "createdAt"], 19 13 "properties": { 20 14 "repo": { 21 15 "type": "string", 22 16 "format": "at-uri" 23 - }, 24 - "issueId": { 25 - "type": "integer" 26 17 }, 27 18 "owner": { 28 19 "type": "string",