@@ -28,6 +28,7 @@ type IssueService struct {
2828// opts := forge.IssueListOptions{State: "open", Labels: "bug"}
2929type IssueListOptions struct {
3030 State string
31+ Sort string
3132 Labels string
3233 Query string
3334 Type string
@@ -43,6 +44,7 @@ type IssueListOptions struct {
4344func (o IssueListOptions ) String () string {
4445 return optionString ("forge.IssueListOptions" ,
4546 "state" , o .State ,
47+ "sort" , o .Sort ,
4648 "labels" , o .Labels ,
4749 "q" , o .Query ,
4850 "type" , o .Type ,
@@ -63,6 +65,9 @@ func (o IssueListOptions) queryParams() map[string]string {
6365 if o .State != "" {
6466 query ["state" ] = o .State
6567 }
68+ if o .Sort != "" {
69+ query ["sort" ] = o .Sort
70+ }
6671 if o .Labels != "" {
6772 query ["labels" ] = o .Labels
6873 }
@@ -160,6 +165,21 @@ func newIssueService(c *Client) *IssueService {
160165 }
161166}
162167
168+ // GetIssue returns a single issue by index.
169+ func (s * IssueService ) GetIssue (ctx context.Context , owner , repo string , index int64 ) (* types.Issue , error ) {
170+ return s .Get (ctx , pathParams ("owner" , owner , "repo" , repo , "index" , int64String (index )))
171+ }
172+
173+ // EditIssue updates an existing issue.
174+ func (s * IssueService ) EditIssue (ctx context.Context , owner , repo string , index int64 , opts * types.EditIssueOption ) (* types.Issue , error ) {
175+ return s .Update (ctx , pathParams ("owner" , owner , "repo" , repo , "index" , int64String (index )), opts )
176+ }
177+
178+ // DeleteIssue deletes an issue.
179+ func (s * IssueService ) DeleteIssue (ctx context.Context , owner , repo string , index int64 ) error {
180+ return s .Delete (ctx , pathParams ("owner" , owner , "repo" , repo , "index" , int64String (index )))
181+ }
182+
163183// SearchIssuesOptions controls filtering for the global issue search endpoint.
164184//
165185// Usage:
@@ -276,17 +296,27 @@ func (s *IssueService) IterSearchIssues(ctx context.Context, opts SearchIssuesOp
276296}
277297
278298// ListIssues returns all issues in a repository.
279- func (s * IssueService ) ListIssues (ctx context.Context , owner , repo string , filters ... IssueListOptions ) ([]types.Issue , error ) {
299+ func (s * IssueService ) ListIssues (ctx context.Context , owner , repo string , filters ... any ) ([]types.Issue , error ) {
280300 path := ResolvePath ("/api/v1/repos/{owner}/{repo}/issues" , pathParams ("owner" , owner , "repo" , repo ))
281301 return ListAll [types.Issue ](ctx , s .client , path , issueListQuery (filters ... ))
282302}
283303
284304// IterIssues returns an iterator over all issues in a repository.
285- func (s * IssueService ) IterIssues (ctx context.Context , owner , repo string , filters ... IssueListOptions ) iter.Seq2 [types.Issue , error ] {
305+ func (s * IssueService ) IterIssues (ctx context.Context , owner , repo string , filters ... any ) iter.Seq2 [types.Issue , error ] {
286306 path := ResolvePath ("/api/v1/repos/{owner}/{repo}/issues" , pathParams ("owner" , owner , "repo" , repo ))
287307 return ListIter [types.Issue ](ctx , s .client , path , issueListQuery (filters ... ))
288308}
289309
310+ // ListRepoIssues returns all issues in a repository.
311+ func (s * IssueService ) ListRepoIssues (ctx context.Context , owner , repo string , filters ... any ) ([]types.Issue , error ) {
312+ return s .ListIssues (ctx , owner , repo , filters ... )
313+ }
314+
315+ // IterRepoIssues returns an iterator over all issues in a repository.
316+ func (s * IssueService ) IterRepoIssues (ctx context.Context , owner , repo string , filters ... any ) iter.Seq2 [types.Issue , error ] {
317+ return s .IterIssues (ctx , owner , repo , filters ... )
318+ }
319+
290320// CreateIssue creates a new issue in a repository.
291321func (s * IssueService ) CreateIssue (ctx context.Context , owner , repo string , opts * types.CreateIssueOption ) (* types.Issue , error ) {
292322 var out types.Issue
@@ -430,12 +460,42 @@ func (s *IssueService) ListComments(ctx context.Context, owner, repo string, ind
430460 return ListAll [types.Comment ](ctx , s .client , path , nil )
431461}
432462
463+ // ListIssueComments returns all comments on an issue.
464+ func (s * IssueService ) ListIssueComments (ctx context.Context , owner , repo string , index int64 ) ([]types.Comment , error ) {
465+ return s .ListComments (ctx , owner , repo , index )
466+ }
467+
433468// IterComments returns an iterator over all comments on an issue.
434469func (s * IssueService ) IterComments (ctx context.Context , owner , repo string , index int64 ) iter.Seq2 [types.Comment , error ] {
435470 path := ResolvePath ("/api/v1/repos/{owner}/{repo}/issues/{index}/comments" , pathParams ("owner" , owner , "repo" , repo , "index" , int64String (index )))
436471 return ListIter [types.Comment ](ctx , s .client , path , nil )
437472}
438473
474+ // IterIssueComments returns an iterator over all comments on an issue.
475+ func (s * IssueService ) IterIssueComments (ctx context.Context , owner , repo string , index int64 ) iter.Seq2 [types.Comment , error ] {
476+ return s .IterComments (ctx , owner , repo , index )
477+ }
478+
479+ // GetIssueComment returns a single comment on an issue.
480+ func (s * IssueService ) GetIssueComment (ctx context.Context , owner , repo string , index , id int64 ) (* types.Comment , error ) {
481+ path := ResolvePath ("/api/v1/repos/{owner}/{repo}/issues/{index}/comments/{id}" , pathParams ("owner" , owner , "repo" , repo , "index" , int64String (index ), "id" , int64String (id )))
482+ var out types.Comment
483+ if err := s .client .Get (ctx , path , & out ); err != nil {
484+ return nil , err
485+ }
486+ return & out , nil
487+ }
488+
489+ // EditIssueComment updates an issue comment.
490+ func (s * IssueService ) EditIssueComment (ctx context.Context , owner , repo string , index , id int64 , opts * types.EditIssueCommentOption ) (* types.Comment , error ) {
491+ return s .EditComment (ctx , owner , repo , index , id , opts )
492+ }
493+
494+ // DeleteIssueComment deletes an issue comment.
495+ func (s * IssueService ) DeleteIssueComment (ctx context.Context , owner , repo string , index , id int64 ) error {
496+ return s .DeleteComment (ctx , owner , repo , index , id )
497+ }
498+
439499// CreateComment creates a comment on an issue.
440500func (s * IssueService ) CreateComment (ctx context.Context , owner , repo string , index int64 , body string ) (* types.Comment , error ) {
441501 path := ResolvePath ("/api/v1/repos/{owner}/{repo}/issues/{index}/comments" , pathParams ("owner" , owner , "repo" , repo , "index" , int64String (index )))
@@ -529,11 +589,30 @@ func (s *IssueService) DeleteCommentReaction(ctx context.Context, owner, repo st
529589 return s .client .DeleteWithBody (ctx , path , types.EditReactionOption {Reaction : reaction })
530590}
531591
532- func issueListQuery (filters ... IssueListOptions ) map [string ]string {
592+ func issueListQuery (filters ... any ) map [string ]string {
533593 query := make (map [string ]string , len (filters ))
534594 for _ , filter := range filters {
535- for key , value := range filter .queryParams () {
536- query [key ] = value
595+ switch v := filter .(type ) {
596+ case IssueListOptions :
597+ for key , value := range issueListQueryFromOption (v ) {
598+ query [key ] = value
599+ }
600+ case * IssueListOptions :
601+ if v != nil {
602+ for key , value := range issueListQueryFromOption (* v ) {
603+ query [key ] = value
604+ }
605+ }
606+ case types.ListIssueOption :
607+ for key , value := range issueListQueryFromCompat (v ) {
608+ query [key ] = value
609+ }
610+ case * types.ListIssueOption :
611+ if v != nil {
612+ for key , value := range issueListQueryFromCompat (* v ) {
613+ query [key ] = value
614+ }
615+ }
537616 }
538617 }
539618 if len (query ) == 0 {
@@ -542,6 +621,82 @@ func issueListQuery(filters ...IssueListOptions) map[string]string {
542621 return query
543622}
544623
624+ func issueListQueryFromOption (filter IssueListOptions ) map [string ]string {
625+ query := make (map [string ]string , 10 )
626+ if filter .State != "" {
627+ query ["state" ] = filter .State
628+ }
629+ if filter .Sort != "" {
630+ query ["sort" ] = filter .Sort
631+ }
632+ if filter .Labels != "" {
633+ query ["labels" ] = filter .Labels
634+ }
635+ if filter .Query != "" {
636+ query ["q" ] = filter .Query
637+ }
638+ if filter .Type != "" {
639+ query ["type" ] = filter .Type
640+ }
641+ if filter .Milestones != "" {
642+ query ["milestones" ] = filter .Milestones
643+ }
644+ if filter .Since != nil {
645+ query ["since" ] = filter .Since .Format (time .RFC3339 )
646+ }
647+ if filter .Before != nil {
648+ query ["before" ] = filter .Before .Format (time .RFC3339 )
649+ }
650+ if filter .CreatedBy != "" {
651+ query ["created_by" ] = filter .CreatedBy
652+ }
653+ if filter .AssignedBy != "" {
654+ query ["assigned_by" ] = filter .AssignedBy
655+ }
656+ if filter .MentionedBy != "" {
657+ query ["mentioned_by" ] = filter .MentionedBy
658+ }
659+ return query
660+ }
661+
662+ func issueListQueryFromCompat (filter types.ListIssueOption ) map [string ]string {
663+ query := make (map [string ]string , 10 )
664+ if filter .State != "" {
665+ query ["state" ] = filter .State
666+ }
667+ if filter .Sort != "" {
668+ query ["sort" ] = filter .Sort
669+ }
670+ if filter .Labels != "" {
671+ query ["labels" ] = filter .Labels
672+ }
673+ if filter .Query != "" {
674+ query ["q" ] = filter .Query
675+ }
676+ if filter .Type != "" {
677+ query ["type" ] = filter .Type
678+ }
679+ if filter .Milestones != "" {
680+ query ["milestones" ] = filter .Milestones
681+ }
682+ if filter .Since != nil {
683+ query ["since" ] = filter .Since .Format (time .RFC3339 )
684+ }
685+ if filter .Before != nil {
686+ query ["before" ] = filter .Before .Format (time .RFC3339 )
687+ }
688+ if filter .CreatedBy != "" {
689+ query ["created_by" ] = filter .CreatedBy
690+ }
691+ if filter .AssignedBy != "" {
692+ query ["assigned_by" ] = filter .AssignedBy
693+ }
694+ if filter .MentionedBy != "" {
695+ query ["mentioned_by" ] = filter .MentionedBy
696+ }
697+ return query
698+ }
699+
545700func attachmentUploadQuery (opts * AttachmentUploadOptions ) map [string ]string {
546701 if opts == nil {
547702 return nil
0 commit comments