@@ -324,7 +324,7 @@ export interface JiraProjectLoaderParams {
324324}
325325
326326const API_ENDPOINTS = {
327- SEARCH : "/rest/api/2 /search" ,
327+ SEARCH : "/rest/api/3 /search/jql " ,
328328} ;
329329
330330/**
@@ -411,39 +411,59 @@ export class JiraProjectLoader extends BaseDocumentLoader {
411411 const url = `${ this . host } ${ API_ENDPOINTS . SEARCH } ` ;
412412 const createdAfterAsString = this . toJiraDateString ( this . createdAfter ) ;
413413 let startAt = 0 ;
414+ const seenIds = new Set < string > ( ) ;
415+ let hitDuplicate = false ;
414416
415- while ( true ) {
417+ while ( ! hitDuplicate ) {
416418 try {
417419 const jqlProps = [
418420 `project=${ this . projectKey } ` ,
419- ...( createdAfterAsString ? [ `created>=${ createdAfterAsString } ` ] : [ ] ) ,
420- ] ;
421- const params = new URLSearchParams ( {
422- jql : jqlProps . join ( " AND " ) ,
423- startAt : `${ startAt } ` ,
424- maxResults : `${ this . limitPerRequest } ` ,
425- } ) ;
426- const pageUrl = `${ url } ?${ params } ` ;
427-
428- const options = {
429- method : "GET" ,
430- headers : {
431- Authorization : authorizationHeader ,
432- Accept : "application/json" ,
433- } ,
434- } ;
435-
436- const response = await fetch ( pageUrl , options ) ;
437- const data : JiraAPIResponse = await response . json ( ) ;
438-
439- if ( ! data . issues || data . issues . length === 0 ) break ;
440-
441- yield data . issues ;
442- startAt += this . limitPerRequest ;
421+ ...( createdAfterAsString ? [ `created>= "${ createdAfterAsString } "` ] : [ ] ) ,
422+ ] ;
423+ const jql = `${ jqlProps . join ( " AND " ) } ORDER BY created ASC, key ASC` ;
424+
425+ const params = new URLSearchParams ( {
426+ jql,
427+ startAt : `${ startAt } ` ,
428+ maxResults : `${ this . limitPerRequest } ` ,
429+ fields : '*all' ,
430+ } ) ;
431+ const pageUrl = `${ url } ?${ params } ` ;
432+
433+ const options = {
434+ method : "GET" ,
435+ headers : {
436+ Authorization : authorizationHeader ,
437+ Accept : "application/json" ,
438+ } ,
439+ } ;
440+
441+ const response = await fetch ( pageUrl , options ) ;
442+ const data : JiraAPIResponse = await response . json ( ) ;
443+
444+ if ( ! data . issues || data . issues . length === 0 ) break ;
445+
446+ const uniqueIssues = [ ] ;
447+ for ( const issue of data . issues ) {
448+ if ( seenIds . has ( issue . id ) ) {
449+ hitDuplicate = true ;
450+ break ;
451+ }
452+ seenIds . add ( issue . id ) ;
453+ uniqueIssues . push ( issue ) ;
454+ }
455+
456+ if ( uniqueIssues . length > 0 ) yield uniqueIssues ;
457+
458+ startAt += this . limitPerRequest ;
459+
460+ // Exit if we have fewer issues than limit (end of result set)
461+ if ( data . issues . length < this . limitPerRequest ) break ;
462+
443463 } catch ( error ) {
444- console . error ( error ) ;
445- yield [ ] ;
464+ console . error ( "Error fetching Jira issues:" , error ) ;
465+ break ;
446466 }
447467 }
448468 }
449- }
469+ }
0 commit comments