feat(client): add rich domain classes, helpers, and refactor GitLabClient internals

This commit is contained in:
2026-03-02 13:10:54 +00:00
parent 4d90bb01cf
commit 7ba0fc984e
13 changed files with 1587 additions and 392 deletions

137
ts/gitlab.classes.group.ts Normal file
View File

@@ -0,0 +1,137 @@
import type { GitLabClient } from './gitlab.classes.gitlabclient.js';
import type { IGitLabGroup, IListOptions, IVariableOptions } from './gitlab.interfaces.js';
import { GitLabProject } from './gitlab.classes.project.js';
import { GitLabVariable } from './gitlab.classes.variable.js';
import { autoPaginate } from './gitlab.helpers.js';
export class GitLabGroup {
// Raw data
public readonly id: number;
public readonly name: string;
public readonly fullPath: string;
public readonly description: string;
public readonly webUrl: string;
public readonly visibility: string;
/** @internal */
constructor(
private client: GitLabClient,
raw: IGitLabGroup,
) {
this.id = raw.id;
this.name = raw.name || '';
this.fullPath = raw.full_path || '';
this.description = raw.description || '';
this.webUrl = raw.web_url || '';
this.visibility = raw.visibility || 'private';
}
// ---------------------------------------------------------------------------
// Projects
// ---------------------------------------------------------------------------
async getProjects(opts?: IListOptions): Promise<GitLabProject[]> {
return autoPaginate(
(page, perPage) => this.client.requestGetGroupProjects(this.id, { ...opts, page, perPage }),
opts,
).then(projects => projects.map(p => new GitLabProject(this.client, p)));
}
// ---------------------------------------------------------------------------
// Descendant Groups
// ---------------------------------------------------------------------------
async getDescendantGroups(opts?: IListOptions): Promise<GitLabGroup[]> {
return autoPaginate(
(page, perPage) => this.client.requestGetDescendantGroups(this.id, { ...opts, page, perPage }),
opts,
).then(groups => groups.map(g => new GitLabGroup(this.client, g)));
}
// ---------------------------------------------------------------------------
// Variables (CI/CD)
// ---------------------------------------------------------------------------
async getVariables(): Promise<GitLabVariable[]> {
const vars = await this.client.requestGetGroupVariables(this.id);
return vars.map(v => new GitLabVariable(v));
}
async createVariable(key: string, value: string, opts?: IVariableOptions): Promise<GitLabVariable> {
const raw = await this.client.requestCreateGroupVariable(this.id, key, value, opts);
return new GitLabVariable(raw);
}
async updateVariable(key: string, value: string, opts?: IVariableOptions): Promise<GitLabVariable> {
const raw = await this.client.requestUpdateGroupVariable(this.id, key, value, opts);
return new GitLabVariable(raw);
}
async deleteVariable(key: string): Promise<void> {
await this.client.requestDeleteGroupVariable(this.id, key);
}
// ---------------------------------------------------------------------------
// Mutation
// ---------------------------------------------------------------------------
/**
* Update group properties.
*/
async update(data: {
name?: string;
path?: string;
description?: string;
visibility?: string;
}): Promise<void> {
await this.client.requestUpdateGroup(this.id, {
name: data.name,
path: data.path,
description: data.description,
visibility: data.visibility,
});
}
/**
* Upload an avatar image for this group (multipart FormData).
*/
async setAvatar(imageData: Uint8Array, filename: string): Promise<void> {
await this.client.requestSetGroupAvatar(this.id, imageData, filename);
}
/**
* Remove the group's avatar.
*/
async deleteAvatar(): Promise<void> {
await this.client.requestUpdateGroup(this.id, { avatar: '' });
}
/**
* Transfer this group to be a child of another group.
*/
async transfer(parentGroupId: number): Promise<void> {
await this.client.requestTransferGroup(this.id, parentGroupId);
}
/**
* Delete this group.
*/
async delete(): Promise<void> {
await this.client.requestDeleteGroup(this.id);
}
// ---------------------------------------------------------------------------
// Serialization
// ---------------------------------------------------------------------------
toJSON(): IGitLabGroup {
return {
id: this.id,
name: this.name,
full_path: this.fullPath,
description: this.description,
web_url: this.webUrl,
visibility: this.visibility,
};
}
}