11import { createHash } from 'node:crypto'
22import { PluginApi , type Project , type UniqueRepo } from '@cpn-console/hooks'
3- import type { AccessTokenScopes , CommitAction , GroupSchema , GroupStatisticsSchema , MemberSchema , ProjectVariableSchema , VariableSchema } from '@gitbeaker/rest'
4- import type { AllRepositoryTreesOptions , CondensedProjectSchema , Gitlab , PaginationRequestOptions , ProjectSchema , RepositoryFileExpandedSchema , RepositoryTreeSchema } from '@gitbeaker/core'
3+ import type { AccessTokenScopes , CommitAction , GroupSchema , MemberSchema , ProjectVariableSchema , VariableSchema , AllRepositoryTreesOptions , CondensedProjectSchema , Gitlab , ProjectSchema , RepositoryFileExpandedSchema } from '@gitbeaker/core'
54import { AccessLevel } from '@gitbeaker/core'
65import type { VaultProjectApi } from '@cpn-console/vault-plugin/types/vault-project-api.js'
76import { objectEntries } from '@cpn-console/shared'
87import type { GitbeakerRequestError } from '@gitbeaker/requester-utils'
9- import { getApi , getGroupRootId , infraAppsRepoName , internalMirrorRepoName } from './utils.js'
8+ import { find , getApi , getAll , getGroupRootId , infraAppsRepoName , internalMirrorRepoName , offsetPaginate } from './utils.js'
109import config from './config.js'
1110
1211type setVariableResult = 'created' | 'updated' | 'already up-to-date'
@@ -69,8 +68,8 @@ export class GitlabApi extends PluginApi {
6968 ) : Promise < boolean > {
7069 let action : CommitAction [ 'action' ] = 'create'
7170
72- const branches = await this . api . Branches . all ( repoId )
73- if ( branches . some ( b => b . name === branch ) ) {
71+ const existingBranch = await find ( offsetPaginate ( opts => this . api . Branches . all ( repoId , opts ) ) , b => b . name === branch )
72+ if ( existingBranch ) {
7473 let actualFile : RepositoryFileExpandedSchema | undefined
7574 try {
7675 actualFile = await this . api . RepositoryFiles . show ( repoId , filePath , branch )
@@ -152,12 +151,12 @@ export class GitlabApi extends PluginApi {
152151 return filesUpdated
153152 }
154153
155- public async listFiles ( repoId : number , options : AllRepositoryTreesOptions & PaginationRequestOptions < 'keyset' > = { } ) {
154+ public async listFiles ( repoId : number , options : AllRepositoryTreesOptions = { } ) {
156155 options . path = options ?. path ?? '/'
157156 options . ref = options ?. ref ?? 'main'
158157 options . recursive = options ?. recursive ?? false
159158 try {
160- const files : RepositoryTreeSchema [ ] = await this . api . Repositories . allRepositoryTrees ( repoId , options )
159+ const files = await this . api . Repositories . allRepositoryTrees ( repoId , options )
161160 // if (depth >= 0) {
162161 // for (const file of files) {
163162 // if (file.type !== 'tree') {
@@ -199,8 +198,11 @@ export class GitlabZoneApi extends GitlabApi {
199198 public async getOrCreateInfraGroup ( ) : Promise < GroupSchema > {
200199 const rootId = await getGroupRootId ( )
201200 // Get or create projects_root_dir/infra group
202- const searchResult = await this . api . Groups . search ( infraGroupName )
203- const existingParentGroup = searchResult . find ( group => group . parent_id === rootId && group . name === infraGroupName )
201+ const existingParentGroup = await find ( offsetPaginate ( opts => this . api . Groups . all ( {
202+ search : infraGroupName ,
203+ orderBy : 'id' ,
204+ ...opts ,
205+ } ) ) , group => group . parent_id === rootId && group . name === infraGroupName )
204206 return existingParentGroup || await this . api . Groups . create ( infraGroupName , infraGroupPath , {
205207 parentId : rootId ,
206208 projectCreationLevel : 'maintainer' ,
@@ -216,26 +218,24 @@ export class GitlabZoneApi extends GitlabApi {
216218 }
217219 const infraGroup = await this . getOrCreateInfraGroup ( )
218220 // Get or create projects_root_dir/infra/zone
219- const infraProjects = await this . api . Groups . allProjects ( infraGroup . id , {
221+ const project = await find ( offsetPaginate ( opts => this . api . Groups . allProjects ( infraGroup . id , {
220222 search : zone ,
221223 simple : true ,
222- perPage : 100 ,
223- } )
224- const project : ProjectSchema = infraProjects . find ( repo => repo . name === zone ) ?? await this . createEmptyRepository ( {
224+ ...opts ,
225+ } ) ) , repo => repo . name === zone ) ?? await this . createEmptyRepository ( {
225226 repoName : zone ,
226227 groupId : infraGroup . id ,
227228 description : 'Repository hosting deployment files for this zone.' ,
228229 createFirstCommit : true ,
229- } ,
230- )
230+ } )
231231 this . infraProjectsByZoneSlug . set ( zone , project )
232232 return project
233233 }
234234}
235235
236236export class GitlabProjectApi extends GitlabApi {
237237 private project : Project | UniqueRepo
238- private gitlabGroup : GroupSchema & { statistics : GroupStatisticsSchema } | undefined
238+ private gitlabGroup : GroupSchema | undefined
239239 private specialRepositories : string [ ] = [ infraAppsRepoName , internalMirrorRepoName ]
240240 private zoneApi : GitlabZoneApi
241241
@@ -248,9 +248,12 @@ export class GitlabProjectApi extends GitlabApi {
248248
249249 // Group Project
250250 private async createProjectGroup ( ) : Promise < GroupSchema > {
251- const searchResult = await this . api . Groups . search ( this . project . slug )
252251 const parentId = await getGroupRootId ( )
253- const existingGroup = searchResult . find ( group => group . parent_id === parentId && group . name === this . project . slug )
252+ const existingGroup = await find ( offsetPaginate ( opts => this . api . Groups . all ( {
253+ search : this . project . slug ,
254+ orderBy : 'id' ,
255+ ...opts ,
256+ } ) ) , group => group . parent_id === parentId && group . name === this . project . slug )
254257
255258 if ( existingGroup ) return existingGroup
256259
@@ -265,8 +268,7 @@ export class GitlabProjectApi extends GitlabApi {
265268 public async getProjectGroup ( ) : Promise < GroupSchema | undefined > {
266269 if ( this . gitlabGroup ) return this . gitlabGroup
267270 const parentId = await getGroupRootId ( )
268- const searchResult = await this . api . Groups . allSubgroups ( parentId )
269- this . gitlabGroup = searchResult . find ( group => group . name === this . project . slug )
271+ this . gitlabGroup = await find ( offsetPaginate ( opts => this . api . Groups . allSubgroups ( parentId , opts ) ) , group => group . name === this . project . slug )
270272 return this . gitlabGroup
271273 }
272274
@@ -323,21 +325,15 @@ export class GitlabProjectApi extends GitlabApi {
323325
324326 public async getProjectId ( projectName : string ) {
325327 const projectGroup = await this . getProjectGroup ( )
326- if ( ! projectGroup ) {
327- throw new Error ( 'Parent DSO Project group has not been created yet' )
328- }
329- const projectsInGroup = await this . api . Groups . allProjects ( projectGroup . id , {
328+ if ( ! projectGroup ) throw new Error ( `Gitlab inaccessible, impossible de trouver le groupe ${ this . project . slug } ` )
329+
330+ const project = await find ( offsetPaginate ( opts => this . api . Groups . allProjects ( projectGroup . id , {
330331 search : projectName ,
331332 simple : true ,
332- perPage : 100 ,
333- } )
334- const project = projectsInGroup . find ( p => p . path === projectName )
333+ ...opts ,
334+ } ) ) , repo => repo . name === projectName )
335335
336- if ( ! project ) {
337- const pathProjectName = `${ config ( ) . projectsRootDir } /${ this . project . slug } /${ projectName } `
338- throw new Error ( `Gitlab project "${ pathProjectName } " not found` )
339- }
340- return project . id
336+ return project ?. id
341337 }
342338
343339 public async getProjectById ( projectId : number ) {
@@ -351,8 +347,7 @@ export class GitlabProjectApi extends GitlabApi {
351347 public async getProjectToken ( tokenName : string ) {
352348 const group = await this . getProjectGroup ( )
353349 if ( ! group ) throw new Error ( 'Unable to retrieve gitlab project group' )
354- const groupTokens = await this . api . GroupAccessTokens . all ( group . id )
355- return groupTokens . find ( token => token . name === tokenName )
350+ return find ( offsetPaginate ( opts => this . api . GroupAccessTokens . all ( group . id , opts ) ) , token => token . name === tokenName )
356351 }
357352
358353 public async createProjectToken ( tokenName : string , scopes : AccessTokenScopes [ ] ) {
@@ -375,8 +370,7 @@ export class GitlabProjectApi extends GitlabApi {
375370 const gitlabRepositories = await this . listRepositories ( )
376371 const mirrorRepo = gitlabRepositories . find ( repo => repo . name === internalMirrorRepoName )
377372 if ( ! mirrorRepo ) throw new Error ( 'Don\'t know how mirror repo could not exist' )
378- const allTriggerTokens = await this . api . PipelineTriggerTokens . all ( mirrorRepo . id )
379- const currentTriggerToken = allTriggerTokens . find ( token => token . description === tokenDescription )
373+ const currentTriggerToken = await find ( offsetPaginate ( opts => this . api . PipelineTriggerTokens . all ( mirrorRepo . id , opts ) ) , token => token . description === tokenDescription )
380374
381375 const tokenVaultSecret = await vaultApi . read ( 'GITLAB' , { throwIfNoEntry : false } )
382376
@@ -398,7 +392,7 @@ export class GitlabProjectApi extends GitlabApi {
398392
399393 public async listRepositories ( ) {
400394 const group = await this . getOrCreateProjectGroup ( )
401- const projects = await this . api . Groups . allProjects ( group . id , { simple : false } ) // to refactor with https://github.com/jdalrymple/gitbeaker/pull/3624
395+ const projects = await getAll ( offsetPaginate ( opts => this . api . Groups . allProjects ( group . id , { simple : false , ... opts } ) ) ) // to refactor with https://github.com/jdalrymple/gitbeaker/pull/3624
402396 return Promise . all ( projects . map ( async ( project ) => {
403397 if ( this . specialRepositories . includes ( project . name ) && ( ! project . topics || ! project . topics . includes ( pluginManagedTopic ) ) ) {
404398 return this . api . Projects . edit ( project . id , { topics : project . topics ? [ ...project . topics , pluginManagedTopic ] : [ pluginManagedTopic ] } )
@@ -432,7 +426,7 @@ export class GitlabProjectApi extends GitlabApi {
432426 // Group members
433427 public async getGroupMembers ( ) {
434428 const group = await this . getOrCreateProjectGroup ( )
435- return this . api . GroupMembers . all ( group . id )
429+ return getAll ( offsetPaginate ( opts => this . api . GroupMembers . all ( group . id , opts ) ) )
436430 }
437431
438432 public async addGroupMember ( userId : number , accessLevel : AccessLevelAllowed = AccessLevel . DEVELOPER ) : Promise < MemberSchema > {
@@ -448,7 +442,7 @@ export class GitlabProjectApi extends GitlabApi {
448442 // CI Variables
449443 public async getGitlabGroupVariables ( ) : Promise < VariableSchema [ ] > {
450444 const group = await this . getOrCreateProjectGroup ( )
451- return await this . api . GroupVariables . all ( group . id )
445+ return await getAll ( offsetPaginate ( opts => this . api . GroupVariables . all ( group . id , opts ) ) )
452446 }
453447
454448 public async setGitlabGroupVariable ( listVars : VariableSchema [ ] , toSetVariable : VariableSchema ) : Promise < setVariableResult > {
@@ -491,7 +485,7 @@ export class GitlabProjectApi extends GitlabApi {
491485 }
492486
493487 public async getGitlabRepoVariables ( repoId : number ) : Promise < VariableSchema [ ] > {
494- return await this . api . ProjectVariables . all ( repoId )
488+ return await getAll ( offsetPaginate ( opts => this . api . ProjectVariables . all ( repoId , opts ) ) )
495489 }
496490
497491 public async setGitlabRepoVariable ( repoId : number , listVars : VariableSchema [ ] , toSetVariable : ProjectVariableSchema ) : Promise < setVariableResult | 'repository not found' > {
0 commit comments