@apiclient.xyz/gitlab 2.5.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist_ts/gitlab.classes.branch.d.ts +7 -0
  2. package/dist_ts/gitlab.classes.branch.js +13 -0
  3. package/dist_ts/gitlab.classes.gitlabclient.d.ts +112 -81
  4. package/dist_ts/gitlab.classes.gitlabclient.js +236 -156
  5. package/dist_ts/gitlab.classes.group.d.ts +47 -0
  6. package/dist_ts/gitlab.classes.group.js +97 -0
  7. package/dist_ts/gitlab.classes.job.d.ts +29 -0
  8. package/dist_ts/gitlab.classes.job.js +74 -0
  9. package/dist_ts/gitlab.classes.pipeline.d.ts +32 -0
  10. package/dist_ts/gitlab.classes.pipeline.js +87 -0
  11. package/dist_ts/gitlab.classes.project.d.ts +63 -0
  12. package/dist_ts/gitlab.classes.project.js +122 -0
  13. package/dist_ts/gitlab.classes.protectedbranch.d.ts +8 -0
  14. package/dist_ts/gitlab.classes.protectedbranch.js +15 -0
  15. package/dist_ts/gitlab.classes.tag.d.ts +7 -0
  16. package/dist_ts/gitlab.classes.tag.js +13 -0
  17. package/dist_ts/gitlab.classes.testreport.d.ts +34 -0
  18. package/dist_ts/gitlab.classes.testreport.js +67 -0
  19. package/dist_ts/gitlab.classes.variable.d.ts +18 -0
  20. package/dist_ts/gitlab.classes.variable.js +35 -0
  21. package/dist_ts/gitlab.helpers.d.ts +8 -0
  22. package/dist_ts/gitlab.helpers.js +23 -0
  23. package/dist_ts/index.d.ts +10 -0
  24. package/dist_ts/index.js +15 -1
  25. package/package.json +1 -1
  26. package/readme.md +468 -163
  27. package/ts/gitlab.classes.branch.ts +18 -0
  28. package/ts/gitlab.classes.gitlabclient.ts +297 -196
  29. package/ts/gitlab.classes.group.ts +137 -0
  30. package/ts/gitlab.classes.job.ts +104 -0
  31. package/ts/gitlab.classes.pipeline.ts +122 -0
  32. package/ts/gitlab.classes.project.ts +177 -0
  33. package/ts/gitlab.classes.protectedbranch.ts +21 -0
  34. package/ts/gitlab.classes.tag.ts +18 -0
  35. package/ts/gitlab.classes.testreport.ts +97 -0
  36. package/ts/gitlab.classes.variable.ts +50 -0
  37. package/ts/gitlab.helpers.ts +26 -0
  38. package/ts/index.ts +19 -0
@@ -1,5 +1,4 @@
1
1
  import * as plugins from './gitlab.plugins.js';
2
- import { logger } from './gitlab.logging.js';
3
2
  import type {
4
3
  IGitLabUser,
5
4
  IGitLabProject,
@@ -18,22 +17,26 @@ import type {
18
17
  IPipelineListOptions,
19
18
  IJobListOptions,
20
19
  } from './gitlab.interfaces.js';
20
+ import { GitLabGroup } from './gitlab.classes.group.js';
21
+ import { GitLabProject } from './gitlab.classes.project.js';
22
+ import { GitLabPipeline } from './gitlab.classes.pipeline.js';
23
+ import { autoPaginate } from './gitlab.helpers.js';
21
24
 
22
25
  export class GitLabClient {
23
26
  private baseUrl: string;
24
27
  private token: string;
25
28
 
26
29
  constructor(baseUrl: string, token: string) {
27
- // Remove trailing slash if present
28
30
  this.baseUrl = baseUrl.replace(/\/+$/, '');
29
31
  this.token = token;
30
32
  }
31
33
 
32
- // ---------------------------------------------------------------------------
33
- // HTTP helpers
34
- // ---------------------------------------------------------------------------
34
+ // ===========================================================================
35
+ // HTTP helpers (internal)
36
+ // ===========================================================================
35
37
 
36
- private async request<T = any>(
38
+ /** @internal */
39
+ async request<T = any>(
37
40
  method: 'GET' | 'POST' | 'PUT' | 'DELETE',
38
41
  path: string,
39
42
  data?: any,
@@ -84,7 +87,8 @@ export class GitLabClient {
84
87
  }
85
88
  }
86
89
 
87
- private async requestText(
90
+ /** @internal */
91
+ async requestText(
88
92
  method: 'GET' | 'POST' | 'PUT' | 'DELETE',
89
93
  path: string,
90
94
  ): Promise<string> {
@@ -119,9 +123,45 @@ export class GitLabClient {
119
123
  return response.text();
120
124
  }
121
125
 
122
- // ---------------------------------------------------------------------------
123
- // Connection
124
- // ---------------------------------------------------------------------------
126
+ /** @internal — multipart form upload (for avatars) */
127
+ async requestMultipart<T = any>(
128
+ method: 'PUT' | 'POST',
129
+ path: string,
130
+ formData: FormData,
131
+ ): Promise<T> {
132
+ const url = `${this.baseUrl}${path}`;
133
+ const response = await fetch(url, {
134
+ method,
135
+ headers: { 'PRIVATE-TOKEN': this.token },
136
+ body: formData,
137
+ });
138
+ if (!response.ok) {
139
+ const errorText = await response.text();
140
+ throw new Error(`${method} ${path}: ${response.status} ${response.statusText} - ${errorText}`);
141
+ }
142
+ try {
143
+ return await response.json() as T;
144
+ } catch {
145
+ return undefined as unknown as T;
146
+ }
147
+ }
148
+
149
+ /** @internal — fetch binary data (e.g. avatar images) */
150
+ async requestBinary(url: string): Promise<Uint8Array> {
151
+ const fullUrl = url.startsWith('http') ? url : `${this.baseUrl}${url}`;
152
+ const response = await fetch(fullUrl, {
153
+ headers: { 'PRIVATE-TOKEN': this.token },
154
+ });
155
+ if (!response.ok) {
156
+ throw new Error(`GET ${url}: ${response.status} ${response.statusText}`);
157
+ }
158
+ const buf = await response.arrayBuffer();
159
+ return new Uint8Array(buf);
160
+ }
161
+
162
+ // ===========================================================================
163
+ // Public API — Connection
164
+ // ===========================================================================
125
165
 
126
166
  public async testConnection(): Promise<ITestConnectionResult> {
127
167
  try {
@@ -132,24 +172,95 @@ export class GitLabClient {
132
172
  }
133
173
  }
134
174
 
135
- // ---------------------------------------------------------------------------
136
- // Groupsscoped queries
137
- // ---------------------------------------------------------------------------
175
+ // ===========================================================================
176
+ // Public API Groups (returns rich objects)
177
+ // ===========================================================================
138
178
 
139
179
  /**
140
- * Get a single group by its full path (e.g. "foss.global" or "foss.global/push.rocks")
180
+ * Get all groups (auto-paginated).
141
181
  */
142
- public async getGroupByPath(fullPath: string): Promise<IGitLabGroup> {
143
- return this.request<IGitLabGroup>(
144
- 'GET',
145
- `/api/v4/groups/${encodeURIComponent(fullPath)}`,
146
- );
182
+ public async getGroups(opts?: IListOptions): Promise<GitLabGroup[]> {
183
+ return autoPaginate(
184
+ (page, perPage) => this.requestGetGroups({ ...opts, page, perPage }),
185
+ opts,
186
+ ).then(groups => groups.map(g => new GitLabGroup(this, g)));
147
187
  }
148
188
 
149
189
  /**
150
- * List projects within a group (includes subgroups when include_subgroups=true)
190
+ * Get a single group by full path.
151
191
  */
152
- public async getGroupProjects(groupId: number | string, opts?: IListOptions): Promise<IGitLabProject[]> {
192
+ public async getGroup(fullPath: string): Promise<GitLabGroup> {
193
+ const raw = await this.requestGetGroupByPath(fullPath);
194
+ return new GitLabGroup(this, raw);
195
+ }
196
+
197
+ /**
198
+ * Create a new group.
199
+ */
200
+ public async createGroup(name: string, path: string, parentId?: number): Promise<GitLabGroup> {
201
+ const raw = await this.requestCreateGroup(name, path, parentId);
202
+ return new GitLabGroup(this, raw);
203
+ }
204
+
205
+ // ===========================================================================
206
+ // Public API — Projects (returns rich objects)
207
+ // ===========================================================================
208
+
209
+ /**
210
+ * Get all projects (auto-paginated, membership=true).
211
+ */
212
+ public async getProjects(opts?: IListOptions): Promise<GitLabProject[]> {
213
+ return autoPaginate(
214
+ (page, perPage) => this.requestGetProjects({ ...opts, page, perPage }),
215
+ opts,
216
+ ).then(projects => projects.map(p => new GitLabProject(this, p)));
217
+ }
218
+
219
+ /**
220
+ * Get a single project by ID or path.
221
+ */
222
+ public async getProject(idOrPath: number | string): Promise<GitLabProject> {
223
+ const raw = await this.requestGetProject(idOrPath);
224
+ return new GitLabProject(this, raw);
225
+ }
226
+
227
+ /**
228
+ * Create a new project.
229
+ */
230
+ public async createProject(name: string, opts?: {
231
+ path?: string;
232
+ namespaceId?: number;
233
+ visibility?: string;
234
+ description?: string;
235
+ }): Promise<GitLabProject> {
236
+ const raw = await this.requestCreateProject(name, opts);
237
+ return new GitLabProject(this, raw);
238
+ }
239
+
240
+ // ===========================================================================
241
+ // Internal request methods — called by domain classes
242
+ // ===========================================================================
243
+
244
+ // --- Groups ---
245
+
246
+ /** @internal */
247
+ async requestGetGroups(opts?: IListOptions): Promise<IGitLabGroup[]> {
248
+ const page = opts?.page || 1;
249
+ const perPage = opts?.perPage || 50;
250
+ let url = `/api/v4/groups?order_by=name&sort=asc&page=${page}&per_page=${perPage}`;
251
+ if (opts?.search) {
252
+ url += `&search=${encodeURIComponent(opts.search)}`;
253
+ }
254
+ return this.request<IGitLabGroup[]>('GET', url);
255
+ }
256
+
257
+ /** @internal */
258
+ async requestGetGroupByPath(fullPath: string): Promise<IGitLabGroup> {
259
+ return this.request<IGitLabGroup>('GET', `/api/v4/groups/${encodeURIComponent(fullPath)}`);
260
+ }
261
+
262
+ /** @internal */
263
+ async requestGetGroupProjects(groupId: number | string, opts?: IListOptions): Promise<IGitLabProject[]> {
153
264
  const page = opts?.page || 1;
154
265
  const perPage = opts?.perPage || 50;
155
266
  let url = `/api/v4/groups/${encodeURIComponent(groupId)}/projects?include_subgroups=true&order_by=updated_at&sort=desc&page=${page}&per_page=${perPage}`;
@@ -159,10 +270,8 @@ export class GitLabClient {
159
270
  return this.request<IGitLabProject[]>('GET', url);
160
271
  }
161
272
 
162
- /**
163
- * List all descendant groups (recursive subgroups) within a group
164
- */
165
- public async getDescendantGroups(groupId: number | string, opts?: IListOptions): Promise<IGitLabGroup[]> {
273
+ /** @internal */
274
+ async requestGetDescendantGroups(groupId: number | string, opts?: IListOptions): Promise<IGitLabGroup[]> {
166
275
  const page = opts?.page || 1;
167
276
  const perPage = opts?.perPage || 50;
168
277
  let url = `/api/v4/groups/${encodeURIComponent(groupId)}/descendant_groups?order_by=name&sort=asc&page=${page}&per_page=${perPage}`;
@@ -172,19 +281,58 @@ export class GitLabClient {
172
281
  return this.request<IGitLabGroup[]>('GET', url);
173
282
  }
174
283
 
175
- /**
176
- * Create a new group. Optionally nested under a parent group.
177
- */
178
- public async createGroup(name: string, path: string, parentId?: number): Promise<IGitLabGroup> {
284
+ /** @internal */
285
+ async requestCreateGroup(name: string, path: string, parentId?: number): Promise<IGitLabGroup> {
179
286
  const body: any = { name, path, visibility: 'private' };
180
287
  if (parentId) body.parent_id = parentId;
181
288
  return this.request<IGitLabGroup>('POST', '/api/v4/groups', body);
182
289
  }
183
290
 
184
- /**
185
- * Create a new project (repository).
186
- */
187
- public async createProject(name: string, opts?: {
291
+ /** @internal */
292
+ async requestUpdateGroup(groupId: number | string, data: Record<string, any>): Promise<void> {
293
+ await this.request('PUT', `/api/v4/groups/${encodeURIComponent(groupId)}`, data);
294
+ }
295
+
296
+ /** @internal */
297
+ async requestSetGroupAvatar(groupId: number | string, imageData: Uint8Array, filename: string): Promise<void> {
298
+ const blob = new Blob([imageData.buffer as ArrayBuffer]);
299
+ const formData = new FormData();
300
+ formData.append('avatar', blob, filename);
301
+ await this.requestMultipart('PUT', `/api/v4/groups/${encodeURIComponent(groupId)}`, formData);
302
+ }
303
+
304
+ /** @internal */
305
+ async requestTransferGroup(groupId: number | string, parentGroupId: number): Promise<void> {
306
+ await this.request('POST', `/api/v4/groups/${encodeURIComponent(groupId)}/transfer`, {
307
+ group_id: parentGroupId,
308
+ });
309
+ }
310
+
311
+ /** @internal */
312
+ async requestDeleteGroup(groupId: number | string): Promise<void> {
313
+ await this.request('DELETE', `/api/v4/groups/${encodeURIComponent(groupId)}`);
314
+ }
315
+
316
+ // --- Projects ---
317
+
318
+ /** @internal */
319
+ async requestGetProjects(opts?: IListOptions): Promise<IGitLabProject[]> {
320
+ const page = opts?.page || 1;
321
+ const perPage = opts?.perPage || 50;
322
+ let url = `/api/v4/projects?membership=true&order_by=updated_at&sort=desc&page=${page}&per_page=${perPage}`;
323
+ if (opts?.search) {
324
+ url += `&search=${encodeURIComponent(opts.search)}`;
325
+ }
326
+ return this.request<IGitLabProject[]>('GET', url);
327
+ }
328
+
329
+ /** @internal */
330
+ async requestGetProject(idOrPath: number | string): Promise<IGitLabProject> {
331
+ return this.request<IGitLabProject>('GET', `/api/v4/projects/${encodeURIComponent(idOrPath)}`);
332
+ }
333
+
334
+ /** @internal */
335
+ async requestCreateProject(name: string, opts?: {
188
336
  path?: string;
189
337
  namespaceId?: number;
190
338
  visibility?: string;
@@ -199,46 +347,83 @@ export class GitLabClient {
199
347
  });
200
348
  }
201
349
 
202
- // ---------------------------------------------------------------------------
203
- // Projects
204
- // ---------------------------------------------------------------------------
350
+ /** @internal */
351
+ async requestUpdateProject(projectId: number | string, data: Record<string, any>): Promise<void> {
352
+ await this.request('PUT', `/api/v4/projects/${encodeURIComponent(projectId)}`, data);
353
+ }
354
+
355
+ /** @internal */
356
+ async requestSetProjectAvatar(projectId: number | string, imageData: Uint8Array, filename: string): Promise<void> {
357
+ const blob = new Blob([imageData.buffer as ArrayBuffer]);
358
+ const formData = new FormData();
359
+ formData.append('avatar', blob, filename);
360
+ await this.requestMultipart('PUT', `/api/v4/projects/${encodeURIComponent(projectId)}`, formData);
361
+ }
362
+
363
+ /** @internal */
364
+ async requestTransferProject(projectId: number | string, namespaceId: number): Promise<void> {
365
+ await this.request('PUT', `/api/v4/projects/${encodeURIComponent(projectId)}/transfer`, {
366
+ namespace: namespaceId,
367
+ });
368
+ }
369
+
370
+ /** @internal */
371
+ async requestDeleteProject(projectId: number | string): Promise<void> {
372
+ await this.request('DELETE', `/api/v4/projects/${encodeURIComponent(projectId)}`);
373
+ }
374
+
375
+ // --- Repo Branches & Tags ---
205
376
 
206
- public async getProjects(opts?: IListOptions): Promise<IGitLabProject[]> {
377
+ /** @internal */
378
+ async requestGetRepoBranches(projectId: number | string, opts?: IListOptions): Promise<IGitLabBranch[]> {
207
379
  const page = opts?.page || 1;
208
380
  const perPage = opts?.perPage || 50;
209
- let url = `/api/v4/projects?membership=true&order_by=updated_at&sort=desc&page=${page}&per_page=${perPage}`;
210
- if (opts?.search) {
211
- url += `&search=${encodeURIComponent(opts.search)}`;
212
- }
213
- return this.request<IGitLabProject[]>('GET', url);
381
+ return this.request<IGitLabBranch[]>(
382
+ 'GET',
383
+ `/api/v4/projects/${encodeURIComponent(projectId)}/repository/branches?page=${page}&per_page=${perPage}`,
384
+ );
214
385
  }
215
386
 
216
- // ---------------------------------------------------------------------------
217
- // Groups
218
- // ---------------------------------------------------------------------------
219
-
220
- public async getGroups(opts?: IListOptions): Promise<IGitLabGroup[]> {
387
+ /** @internal */
388
+ async requestGetRepoTags(projectId: number | string, opts?: IListOptions): Promise<IGitLabTag[]> {
221
389
  const page = opts?.page || 1;
222
390
  const perPage = opts?.perPage || 50;
223
- let url = `/api/v4/groups?order_by=name&sort=asc&page=${page}&per_page=${perPage}`;
224
- if (opts?.search) {
225
- url += `&search=${encodeURIComponent(opts.search)}`;
226
- }
227
- return this.request<IGitLabGroup[]>('GET', url);
391
+ return this.request<IGitLabTag[]>(
392
+ 'GET',
393
+ `/api/v4/projects/${encodeURIComponent(projectId)}/repository/tags?page=${page}&per_page=${perPage}`,
394
+ );
395
+ }
396
+
397
+ // --- Protected Branches ---
398
+
399
+ /** @internal */
400
+ async requestGetProtectedBranches(projectId: number | string): Promise<IGitLabProtectedBranch[]> {
401
+ return this.request<IGitLabProtectedBranch[]>(
402
+ 'GET',
403
+ `/api/v4/projects/${encodeURIComponent(projectId)}/protected_branches`,
404
+ );
405
+ }
406
+
407
+ /** @internal */
408
+ async requestUnprotectBranch(projectId: number | string, branchName: string): Promise<void> {
409
+ await this.request(
410
+ 'DELETE',
411
+ `/api/v4/projects/${encodeURIComponent(projectId)}/protected_branches/${encodeURIComponent(branchName)}`,
412
+ );
228
413
  }
229
414
 
230
- // ---------------------------------------------------------------------------
231
- // Project Variables (CI/CD)
232
- // ---------------------------------------------------------------------------
415
+ // --- Project Variables ---
233
416
 
234
- public async getProjectVariables(projectId: number | string): Promise<IGitLabVariable[]> {
417
+ /** @internal */
418
+ async requestGetProjectVariables(projectId: number | string): Promise<IGitLabVariable[]> {
235
419
  return this.request<IGitLabVariable[]>(
236
420
  'GET',
237
421
  `/api/v4/projects/${encodeURIComponent(projectId)}/variables`,
238
422
  );
239
423
  }
240
424
 
241
- public async createProjectVariable(
425
+ /** @internal */
426
+ async requestCreateProjectVariable(
242
427
  projectId: number | string,
243
428
  key: string,
244
429
  value: string,
@@ -257,7 +442,8 @@ export class GitLabClient {
257
442
  );
258
443
  }
259
444
 
260
- public async updateProjectVariable(
445
+ /** @internal */
446
+ async requestUpdateProjectVariable(
261
447
  projectId: number | string,
262
448
  key: string,
263
449
  value: string,
@@ -274,25 +460,26 @@ export class GitLabClient {
274
460
  );
275
461
  }
276
462
 
277
- public async deleteProjectVariable(projectId: number | string, key: string): Promise<void> {
463
+ /** @internal */
464
+ async requestDeleteProjectVariable(projectId: number | string, key: string): Promise<void> {
278
465
  await this.request(
279
466
  'DELETE',
280
467
  `/api/v4/projects/${encodeURIComponent(projectId)}/variables/${encodeURIComponent(key)}`,
281
468
  );
282
469
  }
283
470
 
284
- // ---------------------------------------------------------------------------
285
- // Group Variables (CI/CD)
286
- // ---------------------------------------------------------------------------
471
+ // --- Group Variables ---
287
472
 
288
- public async getGroupVariables(groupId: number | string): Promise<IGitLabVariable[]> {
473
+ /** @internal */
474
+ async requestGetGroupVariables(groupId: number | string): Promise<IGitLabVariable[]> {
289
475
  return this.request<IGitLabVariable[]>(
290
476
  'GET',
291
477
  `/api/v4/groups/${encodeURIComponent(groupId)}/variables`,
292
478
  );
293
479
  }
294
480
 
295
- public async createGroupVariable(
481
+ /** @internal */
482
+ async requestCreateGroupVariable(
296
483
  groupId: number | string,
297
484
  key: string,
298
485
  value: string,
@@ -311,7 +498,8 @@ export class GitLabClient {
311
498
  );
312
499
  }
313
500
 
314
- public async updateGroupVariable(
501
+ /** @internal */
502
+ async requestUpdateGroupVariable(
315
503
  groupId: number | string,
316
504
  key: string,
317
505
  value: string,
@@ -328,22 +516,18 @@ export class GitLabClient {
328
516
  );
329
517
  }
330
518
 
331
- public async deleteGroupVariable(groupId: number | string, key: string): Promise<void> {
519
+ /** @internal */
520
+ async requestDeleteGroupVariable(groupId: number | string, key: string): Promise<void> {
332
521
  await this.request(
333
522
  'DELETE',
334
523
  `/api/v4/groups/${encodeURIComponent(groupId)}/variables/${encodeURIComponent(key)}`,
335
524
  );
336
525
  }
337
526
 
338
- // ---------------------------------------------------------------------------
339
- // Pipelines
340
- // ---------------------------------------------------------------------------
527
+ // --- Pipelines ---
341
528
 
342
- /**
343
- * List pipelines for a project with optional filters.
344
- * Supports status, ref, source, scope, username, date range, ordering.
345
- */
346
- public async getPipelines(projectId: number | string, opts?: IPipelineListOptions): Promise<IGitLabPipeline[]> {
529
+ /** @internal */
530
+ async requestGetPipelines(projectId: number | string, opts?: IPipelineListOptions): Promise<IGitLabPipeline[]> {
347
531
  const page = opts?.page || 1;
348
532
  const perPage = opts?.perPage || 30;
349
533
  const orderBy = opts?.orderBy || 'updated_at';
@@ -359,20 +543,16 @@ export class GitLabClient {
359
543
  return this.request<IGitLabPipeline[]>('GET', url);
360
544
  }
361
545
 
362
- /**
363
- * Get a single pipeline's full details.
364
- */
365
- public async getPipeline(projectId: number | string, pipelineId: number): Promise<IGitLabPipeline> {
546
+ /** @internal */
547
+ async requestGetPipeline(projectId: number | string, pipelineId: number): Promise<IGitLabPipeline> {
366
548
  return this.request<IGitLabPipeline>(
367
549
  'GET',
368
550
  `/api/v4/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}`,
369
551
  );
370
552
  }
371
553
 
372
- /**
373
- * Trigger a new pipeline on the given ref, optionally with variables.
374
- */
375
- public async triggerPipeline(
554
+ /** @internal */
555
+ async requestTriggerPipeline(
376
556
  projectId: number | string,
377
557
  ref: string,
378
558
  variables?: { key: string; value: string; variable_type?: string }[],
@@ -388,58 +568,50 @@ export class GitLabClient {
388
568
  );
389
569
  }
390
570
 
391
- /**
392
- * Delete a pipeline and all its jobs.
393
- */
394
- public async deletePipeline(projectId: number | string, pipelineId: number): Promise<void> {
571
+ /** @internal */
572
+ async requestRetryPipeline(projectId: number | string, pipelineId: number): Promise<IGitLabPipeline> {
573
+ return this.request<IGitLabPipeline>(
574
+ 'POST',
575
+ `/api/v4/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/retry`,
576
+ );
577
+ }
578
+
579
+ /** @internal */
580
+ async requestCancelPipeline(projectId: number | string, pipelineId: number): Promise<IGitLabPipeline> {
581
+ return this.request<IGitLabPipeline>(
582
+ 'POST',
583
+ `/api/v4/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/cancel`,
584
+ );
585
+ }
586
+
587
+ /** @internal */
588
+ async requestDeletePipeline(projectId: number | string, pipelineId: number): Promise<void> {
395
589
  await this.request(
396
590
  'DELETE',
397
591
  `/api/v4/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}`,
398
592
  );
399
593
  }
400
594
 
401
- /**
402
- * Get variables used in a specific pipeline run.
403
- */
404
- public async getPipelineVariables(projectId: number | string, pipelineId: number): Promise<IGitLabPipelineVariable[]> {
595
+ /** @internal */
596
+ async requestGetPipelineVariables(projectId: number | string, pipelineId: number): Promise<IGitLabPipelineVariable[]> {
405
597
  return this.request<IGitLabPipelineVariable[]>(
406
598
  'GET',
407
599
  `/api/v4/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/variables`,
408
600
  );
409
601
  }
410
602
 
411
- /**
412
- * Get the test report for a pipeline.
413
- */
414
- public async getPipelineTestReport(projectId: number | string, pipelineId: number): Promise<IGitLabTestReport> {
603
+ /** @internal */
604
+ async requestGetPipelineTestReport(projectId: number | string, pipelineId: number): Promise<IGitLabTestReport> {
415
605
  return this.request<IGitLabTestReport>(
416
606
  'GET',
417
607
  `/api/v4/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/test_report`,
418
608
  );
419
609
  }
420
610
 
421
- public async retryPipeline(projectId: number | string, pipelineId: number): Promise<IGitLabPipeline> {
422
- return this.request<IGitLabPipeline>(
423
- 'POST',
424
- `/api/v4/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/retry`,
425
- );
426
- }
611
+ // --- Jobs ---
427
612
 
428
- public async cancelPipeline(projectId: number | string, pipelineId: number): Promise<IGitLabPipeline> {
429
- return this.request<IGitLabPipeline>(
430
- 'POST',
431
- `/api/v4/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/cancel`,
432
- );
433
- }
434
-
435
- // ---------------------------------------------------------------------------
436
- // Jobs
437
- // ---------------------------------------------------------------------------
438
-
439
- /**
440
- * List jobs for a pipeline with optional scope filter and pagination.
441
- */
442
- public async getPipelineJobs(projectId: number | string, pipelineId: number, opts?: IJobListOptions): Promise<IGitLabJob[]> {
613
+ /** @internal */
614
+ async requestGetPipelineJobs(projectId: number | string, pipelineId: number, opts?: IJobListOptions): Promise<IGitLabJob[]> {
443
615
  const page = opts?.page || 1;
444
616
  const perPage = opts?.perPage || 100;
445
617
  let url = `/api/v4/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/jobs?page=${page}&per_page=${perPage}`;
@@ -451,114 +623,43 @@ export class GitLabClient {
451
623
  return this.request<IGitLabJob[]>('GET', url);
452
624
  }
453
625
 
454
- /**
455
- * Get a single job's full details.
456
- */
457
- public async getJob(projectId: number | string, jobId: number): Promise<IGitLabJob> {
458
- return this.request<IGitLabJob>(
459
- 'GET',
460
- `/api/v4/projects/${encodeURIComponent(projectId)}/jobs/${jobId}`,
461
- );
462
- }
463
-
464
- /**
465
- * Get a job's raw log (trace) output.
466
- */
467
- public async getJobLog(projectId: number | string, jobId: number): Promise<string> {
626
+ /** @internal */
627
+ async requestGetJobLog(projectId: number | string, jobId: number): Promise<string> {
468
628
  return this.requestText(
469
629
  'GET',
470
630
  `/api/v4/projects/${encodeURIComponent(projectId)}/jobs/${jobId}/trace`,
471
631
  );
472
632
  }
473
633
 
474
- /**
475
- * Retry a single job.
476
- */
477
- public async retryJob(projectId: number | string, jobId: number): Promise<IGitLabJob> {
634
+ /** @internal */
635
+ async requestRetryJob(projectId: number | string, jobId: number): Promise<IGitLabJob> {
478
636
  return this.request<IGitLabJob>(
479
637
  'POST',
480
638
  `/api/v4/projects/${encodeURIComponent(projectId)}/jobs/${jobId}/retry`,
481
639
  );
482
640
  }
483
641
 
484
- /**
485
- * Cancel a running job.
486
- */
487
- public async cancelJob(projectId: number | string, jobId: number): Promise<IGitLabJob> {
642
+ /** @internal */
643
+ async requestCancelJob(projectId: number | string, jobId: number): Promise<IGitLabJob> {
488
644
  return this.request<IGitLabJob>(
489
645
  'POST',
490
646
  `/api/v4/projects/${encodeURIComponent(projectId)}/jobs/${jobId}/cancel`,
491
647
  );
492
648
  }
493
649
 
494
- /**
495
- * Trigger a manual job (play action).
496
- */
497
- public async playJob(projectId: number | string, jobId: number): Promise<IGitLabJob> {
650
+ /** @internal */
651
+ async requestPlayJob(projectId: number | string, jobId: number): Promise<IGitLabJob> {
498
652
  return this.request<IGitLabJob>(
499
653
  'POST',
500
654
  `/api/v4/projects/${encodeURIComponent(projectId)}/jobs/${jobId}/play`,
501
655
  );
502
656
  }
503
657
 
504
- /**
505
- * Erase a job's trace and artifacts.
506
- */
507
- public async eraseJob(projectId: number | string, jobId: number): Promise<void> {
658
+ /** @internal */
659
+ async requestEraseJob(projectId: number | string, jobId: number): Promise<void> {
508
660
  await this.request(
509
661
  'POST',
510
662
  `/api/v4/projects/${encodeURIComponent(projectId)}/jobs/${jobId}/erase`,
511
663
  );
512
664
  }
513
-
514
- // ---------------------------------------------------------------------------
515
- // Repository Branches & Tags
516
- // ---------------------------------------------------------------------------
517
-
518
- public async getRepoBranches(projectId: number | string, opts?: IListOptions): Promise<IGitLabBranch[]> {
519
- const page = opts?.page || 1;
520
- const perPage = opts?.perPage || 50;
521
- return this.request<IGitLabBranch[]>(
522
- 'GET',
523
- `/api/v4/projects/${encodeURIComponent(projectId)}/repository/branches?page=${page}&per_page=${perPage}`,
524
- );
525
- }
526
-
527
- public async getRepoTags(projectId: number | string, opts?: IListOptions): Promise<IGitLabTag[]> {
528
- const page = opts?.page || 1;
529
- const perPage = opts?.perPage || 50;
530
- return this.request<IGitLabTag[]>(
531
- 'GET',
532
- `/api/v4/projects/${encodeURIComponent(projectId)}/repository/tags?page=${page}&per_page=${perPage}`,
533
- );
534
- }
535
-
536
- // ---------------------------------------------------------------------------
537
- // Protected Branches
538
- // ---------------------------------------------------------------------------
539
-
540
- public async getProtectedBranches(projectId: number | string): Promise<IGitLabProtectedBranch[]> {
541
- return this.request<IGitLabProtectedBranch[]>(
542
- 'GET',
543
- `/api/v4/projects/${encodeURIComponent(projectId)}/protected_branches`,
544
- );
545
- }
546
-
547
- public async unprotectBranch(projectId: number | string, branchName: string): Promise<void> {
548
- await this.request(
549
- 'DELETE',
550
- `/api/v4/projects/${encodeURIComponent(projectId)}/protected_branches/${encodeURIComponent(branchName)}`,
551
- );
552
- }
553
-
554
- // ---------------------------------------------------------------------------
555
- // Project Deletion
556
- // ---------------------------------------------------------------------------
557
-
558
- public async deleteProject(projectId: number | string): Promise<void> {
559
- await this.request(
560
- 'DELETE',
561
- `/api/v4/projects/${encodeURIComponent(projectId)}`,
562
- );
563
- }
564
665
  }