@@ -516,25 +516,76 @@ type CommentVisibility struct {
516516// response size for resources that return potentially large collection of items.
517517// A request to a pages API will result in a values array wrapped in a JSON object with some paging metadata
518518// Default Pagination options
519+ //
520+ // Docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-search/#api-rest-api-3-search-jql-get
519521type SearchOptions struct {
520- // StartAt: The starting index of the returned projects. Base index: 0.
521- StartAt int `url:"startAt,omitempty"`
522- // MaxResults: The maximum number of projects to return per page. Default: 50.
522+ // NextPageToken: The token for a page to fetch that is not the first page.
523+ // The first page has a nextPageToken of null.
524+ // Use the nextPageToken to fetch the next page of issues.
525+ // Note: The nextPageToken field is not included in the response for the last page,
526+ // indicating there is no next page.
527+ NextPageToken string `url:"nextPageToken,omitempty"`
528+
529+ // MaxResults: The maximum number of items to return per page.
530+ // To manage page size, API may return fewer items per page where a large number of fields or properties are requested.
531+ // The greatest number of items returned per page is achieved when requesting id or key only.
532+ // It returns max 5000 issues.
533+ // Default: 50
523534 MaxResults int `url:"maxResults,omitempty"`
524- // Expand: Expand specific sections in the returned issues
525- Expand string `url:"expand,omitempty"`
535+ // Fields: A list of fields to return for each issue
536+
537+ // Fields: A list of fields to return for each issue, use it to retrieve a subset of fields.
538+ // This parameter accepts a comma-separated list. Expand options include:
539+ //
540+ // `*all` Returns all fields.
541+ // `*navigable` Returns navigable fields.
542+ // `id` Returns only issue IDs.
543+ // Any issue field, prefixed with a minus to exclude.
544+ //
545+ // The default is id.
546+ //
547+ // Examples:
548+ //
549+ // `summary,comment` Returns only the summary and comments fields only.
550+ // `-description` Returns all navigable (default) fields except description.
551+ // `*all,-comment` Returns all fields except comments.
552+ //
553+ // Multiple `fields` parameters can be included in a request.
554+ //
555+ // Note: By default, this resource returns IDs only. This differs from GET issue where the default is all fields.
526556 Fields []string
527- // ValidateQuery: The validateQuery param offers control over whether to validate and how strictly to treat the validation. Default: strict.
528- ValidateQuery string `url:"validateQuery,omitempty"`
557+
558+ // Expand: Use expand to include additional information about issues in the response.
559+ // TODO add proper docs, see https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-search/#api-rest-api-3-search-jql-get
560+ Expand string `url:"expand,omitempty"`
561+ // A list of up to 5 issue properties to include in the results
562+ Properties []string `url:"properties,omitempty"`
563+ // FieldsByKeys: Reference fields by their key (rather than ID).
564+ // The default is false.
565+ FieldsByKeys bool `url:"fieldsByKeys,omitempty"`
566+ // FailFast: Fail this request early if we can't retrieve all field data.
567+ // Default false.
568+ FailFast bool `url:"failFast,omitempty"`
569+ // ReconcileIssues: Strong consistency issue ids to be reconciled with search results. Accepts max 50 ids
570+ ReconcileIssues []int `url:"reconcileIssues,omitempty"`
529571}
530572
531573// searchResult is only a small wrapper around the Search (with JQL) method
532574// to be able to parse the results
533575type searchResult struct {
534- Issues []Issue `json:"issues" structs:"issues"`
535- StartAt int `json:"startAt" structs:"startAt"`
536- MaxResults int `json:"maxResults" structs:"maxResults"`
537- Total int `json:"total" structs:"total"`
576+ // IsLast: Indicates whether this is the last page of the paginated response.
577+ IsLast bool `json:"isLast" structs:"isLast"`
578+ // Issues: The list of issues found by the search or reconsiliation.
579+ Issues []Issue `json:"issues" structs:"issues"`
580+
581+ // TODO Missing
582+ // Field names object
583+ // Field schema object
584+
585+ // NextPageToken: Continuation token to fetch the next page.
586+ // If this result represents the last or the only page this token will be null.
587+ // This token will expire in 7 days.
588+ NextPageToken string `json:"nextPageToken" structs:"nextPageToken"`
538589}
539590
540591// GetQueryOptions specifies the optional parameters for the Get Issue methods
@@ -1046,28 +1097,50 @@ func (s *IssueService) AddLink(ctx context.Context, issueLink *IssueLink) (*Resp
10461097// This double check effort is done for v2 - Remove this two lines if this is completed.
10471098func (s * IssueService ) Search (ctx context.Context , jql string , options * SearchOptions ) ([]Issue , * Response , error ) {
10481099 u := url.URL {
1049- Path : "rest/api/2 /search" ,
1100+ Path : "rest/api/3 /search/jql " ,
10501101 }
10511102 uv := url.Values {}
10521103 if jql != "" {
10531104 uv .Add ("jql" , jql )
10541105 }
10551106
1107+ // TODO Check this out if this works with addOptions as well
10561108 if options != nil {
1057- if options .StartAt != 0 {
1058- uv .Add ("startAt " , strconv . Itoa ( options .StartAt ) )
1109+ if options .NextPageToken != "" {
1110+ uv .Add ("nextPageToken " , options .NextPageToken )
10591111 }
10601112 if options .MaxResults != 0 {
10611113 uv .Add ("maxResults" , strconv .Itoa (options .MaxResults ))
10621114 }
1115+ if strings .Join (options .Fields , "," ) != "" {
1116+ uv .Add ("fields" , strings .Join (options .Fields , "," ))
1117+ }
10631118 if options .Expand != "" {
10641119 uv .Add ("expand" , options .Expand )
10651120 }
1066- if strings .Join (options .Fields , "," ) != "" {
1067- uv .Add ("fields" , strings .Join (options .Fields , "," ))
1121+ if len (options .Properties ) > 5 {
1122+ return nil , nil , fmt .Errorf ("Search option Properties accepts maximum five entries" )
1123+ }
1124+ if strings .Join (options .Properties , "," ) != "" {
1125+ uv .Add ("properties" , strings .Join (options .Properties , "," ))
1126+ }
1127+ if options .FieldsByKeys {
1128+ uv .Add ("fieldsByKeys" , "true" )
1129+ }
1130+ if options .FailFast {
1131+ uv .Add ("failFast" , "true" )
10681132 }
1069- if options .ValidateQuery != "" {
1070- uv .Add ("validateQuery" , options .ValidateQuery )
1133+ if len (options .ReconcileIssues ) > 50 {
1134+ return nil , nil , fmt .Errorf ("Search option ReconcileIssue accepts maximum 50 entries" )
1135+ }
1136+ if len (options .ReconcileIssues ) > 0 {
1137+ // TODO Extract this
1138+ // Convert []int to []string for strings.Join
1139+ reconcileIssuesStr := make ([]string , len (options .ReconcileIssues ))
1140+ for i , v := range options .ReconcileIssues {
1141+ reconcileIssuesStr [i ] = strconv .Itoa (v )
1142+ }
1143+ uv .Add ("reconcileIssues" , strings .Join (reconcileIssuesStr , "," ))
10711144 }
10721145 }
10731146
@@ -1095,7 +1168,6 @@ func (s *IssueService) Search(ctx context.Context, jql string, options *SearchOp
10951168func (s * IssueService ) SearchPages (ctx context.Context , jql string , options * SearchOptions , f func (Issue ) error ) error {
10961169 if options == nil {
10971170 options = & SearchOptions {
1098- StartAt : 0 ,
10991171 MaxResults : 50 ,
11001172 }
11011173 }
@@ -1121,16 +1193,18 @@ func (s *IssueService) SearchPages(ctx context.Context, jql string, options *Sea
11211193 }
11221194 }
11231195
1124- if resp .StartAt + resp . MaxResults >= resp . Total {
1125- return nil
1196+ if len ( resp .NextPageToken ) == 0 {
1197+ break
11261198 }
11271199
1128- options .StartAt + = resp .MaxResults
1200+ options .NextPageToken = resp .NextPageToken
11291201 issues , resp , err = s .Search (ctx , jql , options )
11301202 if err != nil {
11311203 return err
11321204 }
11331205 }
1206+
1207+ return nil
11341208}
11351209
11361210// GetCustomFields returns a map of customfield_* keys with string values
0 commit comments