@@ -34,9 +34,13 @@ def merge(self, set):
34
34
35
35
def parse_issue (issue , field_mapping ): # noqa: C901
36
36
result = OrderedDict ()
37
- result ["key" ] = issue ["key" ]
38
37
39
- for k , v in issue ["fields" ].items (): #
38
+ # Handle API v3 response format: key field may be missing, use id as fallback
39
+ result ["key" ] = issue .get ("key" , issue .get ("id" , "unknown" ))
40
+
41
+ # Handle API v3 response format: fields may be missing
42
+ fields = issue .get ("fields" , {})
43
+ for k , v in fields .items (): #
40
44
output_name = field_mapping .get_output_field_name (k )
41
45
member_names = field_mapping .get_dict_members (k )
42
46
@@ -98,7 +102,9 @@ def parse_issues(data, field_mapping):
98
102
99
103
def parse_count (data ):
100
104
results = ResultSet ()
101
- results .add_row ({"count" : data ["total" ]})
105
+ # API v3 may not return 'total' field, fallback to counting issues
106
+ count = data .get ("total" , len (data .get ("issues" , [])))
107
+ results .add_row ({"count" : count })
102
108
return results
103
109
104
110
@@ -160,18 +166,26 @@ def __init__(self, configuration):
160
166
self .syntax = "json"
161
167
162
168
def run_query (self , query , user ):
163
- jql_url = "{}/rest/api/2/search" .format (self .configuration ["url" ])
169
+ # Updated to API v3 endpoint, fix double slash issue
170
+ jql_url = "{}/rest/api/3/search/jql" .format (self .configuration ["url" ].rstrip ("/" ))
164
171
165
172
query = json_loads (query )
166
173
query_type = query .pop ("queryType" , "select" )
167
174
field_mapping = FieldMapping (query .pop ("fieldMapping" , {}))
168
175
176
+ # API v3 requires mandatory jql parameter with restrictions
177
+ if "jql" not in query or not query ["jql" ]:
178
+ query ["jql" ] = "created >= -30d order by created DESC"
179
+
169
180
if query_type == "count" :
170
181
query ["maxResults" ] = 1
171
182
query ["fields" ] = ""
172
183
else :
173
184
query ["maxResults" ] = query .get ("maxResults" , 1000 )
174
185
186
+ if "fields" not in query :
187
+ query ["fields" ] = "*all"
188
+
175
189
response , error = self .get_response (jql_url , params = query )
176
190
if error is not None :
177
191
return None , error
@@ -182,17 +196,15 @@ def run_query(self, query, user):
182
196
results = parse_count (data )
183
197
else :
184
198
results = parse_issues (data , field_mapping )
185
- index = data ["startAt" ] + data ["maxResults" ]
186
199
187
- while data ["total" ] > index :
188
- query ["startAt" ] = index
200
+ # API v3 uses token-based pagination instead of startAt/total
201
+ while not data .get ("isLast" , True ) and "nextPageToken" in data :
202
+ query ["nextPageToken" ] = data ["nextPageToken" ]
189
203
response , error = self .get_response (jql_url , params = query )
190
204
if error is not None :
191
205
return None , error
192
206
193
207
data = response .json ()
194
- index = data ["startAt" ] + data ["maxResults" ]
195
-
196
208
addl_results = parse_issues (data , field_mapping )
197
209
results .merge (addl_results )
198
210
0 commit comments