@@ -45,6 +45,8 @@ import { fromGitLabMergeRequest, fromGitLabMergeRequestREST, fromGitLabMergeRequ
45
45
46
46
// drop it as soon as we switch to @gitkraken /providers-api
47
47
const gitlabUserIdPrefix = 'gid://gitlab/User/' ;
48
+ const gitlabMergeRequestIdPrefix = 'gid://gitlab/MergeRequest/' ;
49
+
48
50
function buildGitLabUserId ( id : string | undefined ) : string | undefined {
49
51
return id ?. startsWith ( gitlabUserIdPrefix ) ? id . substring ( gitlabUserIdPrefix . length ) : id ;
50
52
}
@@ -711,6 +713,116 @@ export class GitLabApi implements Disposable {
711
713
}
712
714
}
713
715
716
+ @debug < GitLabApi [ 'searchPullRequests' ] > ( { args : { 0 : p => p . name , 1 : '<token>' } } )
717
+ async searchPullRequests (
718
+ provider : Provider ,
719
+ token : string ,
720
+ options ?: { search ?: string ; user ?: string ; repos ?: string [ ] ; baseUrl ?: string ; avatarSize ?: number } ,
721
+ cancellation ?: CancellationToken ,
722
+ ) : Promise < PullRequest [ ] > {
723
+ const scope = getLogScope ( ) ;
724
+ const search = options ?. search ;
725
+ if ( ! search ) {
726
+ return [ ] ;
727
+ }
728
+ try {
729
+ const perPageLimit = 20 ; // with bigger amount we exceed the max GraphQL complexity in the next query
730
+ const restPRs = await this . request < GitLabMergeRequestREST [ ] > (
731
+ provider ,
732
+ token ,
733
+ options ?. baseUrl ,
734
+ `v4/search/?scope=merge_requests&search=${ search } &per_page=${ perPageLimit } ` ,
735
+ {
736
+ method : 'GET' ,
737
+ } ,
738
+ cancellation ,
739
+ scope ,
740
+ ) ;
741
+ if ( restPRs . length === 0 ) {
742
+ return [ ] ;
743
+ }
744
+
745
+ interface QueryResult {
746
+ data : Record < `mergeRequest_${number } `, GitLabMergeRequestFull > ;
747
+ }
748
+
749
+ const queryArgs = restPRs . map ( ( _ , i ) => `$id_${ i } : MergeRequestID!` ) . join ( '\n' ) ;
750
+ const queryFields = restPRs
751
+ . map ( ( _ , i ) => `mergeRequest_${ i } : mergeRequest(id: $id_${ i } ) { ...mergeRequestFields }` )
752
+ . join ( '\n' ) ;
753
+ // Set of fields includes only additional fields that are not included in GitLabMergeRequestREST.
754
+ // It's limited as much as possible to reduce complexity of the query.
755
+ const queryMrFields = `fragment mergeRequestFields on MergeRequest {
756
+ diffRefs {
757
+ baseSha
758
+ headSha
759
+ }
760
+ project {
761
+ id
762
+ fullPath
763
+ webUrl
764
+ }
765
+ sourceProject {
766
+ id
767
+ fullPath
768
+ webUrl
769
+ }
770
+ }` ;
771
+ const query = `query getMergeRequests (${ queryArgs } ) {${ queryFields } } ${ queryMrFields } ` ;
772
+
773
+ const params = restPRs . reduce < Record < `id_${number } `, string > > ( ( ids , gitlabRestPr , i ) => {
774
+ ids [ `id_${ i } ` ] = `${ gitlabMergeRequestIdPrefix } ${ gitlabRestPr . id } ` ;
775
+ return ids ;
776
+ } , { } ) ;
777
+ const rsp = await this . graphql < QueryResult > (
778
+ provider ,
779
+ token ,
780
+ options ?. baseUrl ,
781
+ query ,
782
+ params ,
783
+ cancellation ,
784
+ scope ,
785
+ ) ;
786
+ if ( rsp ?. data != null ) {
787
+ const resultPRs = restPRs . reduce < PullRequest [ ] > ( ( accum , restPR , i ) => {
788
+ const graphQlPR = rsp . data [ `mergeRequest_${ i } ` ] ;
789
+ if ( graphQlPR == null ) {
790
+ return accum ;
791
+ }
792
+
793
+ const fullPr : GitLabMergeRequestFull = {
794
+ ...graphQlPR ,
795
+ iid : String ( restPR . iid ) ,
796
+ id : String ( restPR . id ) ,
797
+ state : restPR . state ,
798
+ author : {
799
+ id : buildGitLabUserId ( restPR . author ?. id ) ?? '' ,
800
+ name : restPR . author ?. name ?? 'Unknown' ,
801
+ avatarUrl : restPR . author ?. avatar_url ?? '' ,
802
+ webUrl : restPR . author ?. web_url ?? '' ,
803
+ } ,
804
+ title : restPR . title ,
805
+ description : restPR . description ,
806
+ webUrl : restPR . web_url ,
807
+ createdAt : restPR . created_at ,
808
+ updatedAt : restPR . updated_at ,
809
+ mergedAt : restPR . merged_at ,
810
+ sourceBranch : restPR . source_branch ,
811
+ targetBranch : restPR . target_branch ,
812
+ } ;
813
+ accum . push ( fromGitLabMergeRequest ( fullPr , provider ) ) ;
814
+ return accum ;
815
+ } , [ ] ) ;
816
+ return resultPRs ;
817
+ }
818
+ return [ ] ;
819
+ } catch ( ex ) {
820
+ if ( ex instanceof RequestNotFoundError ) return [ ] ;
821
+
822
+ throw this . handleException ( ex , provider , scope ) ;
823
+ }
824
+ }
825
+
714
826
private async findUser (
715
827
provider : Provider ,
716
828
token : string ,
0 commit comments