import type { GiteaClient } from './gitea.classes.giteaclient.js'; import type { IGiteaRepository, IGiteaSecret, IListOptions, IActionRunListOptions } from './gitea.interfaces.js'; import { GiteaBranch } from './gitea.classes.branch.js'; import { GiteaTag } from './gitea.classes.tag.js'; import { GiteaSecret } from './gitea.classes.secret.js'; import { GiteaActionRun } from './gitea.classes.actionrun.js'; import { autoPaginate } from './gitea.helpers.js'; export class GiteaRepository { // Raw data public readonly id: number; public readonly name: string; public readonly fullName: string; public readonly description: string; public readonly defaultBranch: string; public readonly htmlUrl: string; public readonly isPrivate: boolean; public readonly topics: string[]; public readonly updatedAt: string; public readonly ownerId: number; public readonly ownerLogin: string; public readonly ownerAvatarUrl: string; /** @internal */ constructor( private client: GiteaClient, raw: IGiteaRepository, ) { this.id = raw.id; this.name = raw.name || ''; this.fullName = raw.full_name || ''; this.description = raw.description || ''; this.defaultBranch = raw.default_branch || 'main'; this.htmlUrl = raw.html_url || ''; this.isPrivate = raw.private ?? true; this.topics = raw.topics || []; this.updatedAt = raw.updated_at || ''; this.ownerId = raw.owner?.id || 0; this.ownerLogin = raw.owner?.login || ''; this.ownerAvatarUrl = raw.owner?.avatar_url || ''; } // --------------------------------------------------------------------------- // Branches & Tags // --------------------------------------------------------------------------- async getBranches(opts?: IListOptions): Promise { return autoPaginate( (page, perPage) => this.client.requestGetRepoBranches(this.fullName, { ...opts, page, perPage }), opts, ).then(branches => branches.map(b => new GiteaBranch(b))); } async getTags(opts?: IListOptions): Promise { return autoPaginate( (page, perPage) => this.client.requestGetRepoTags(this.fullName, { ...opts, page, perPage }), opts, ).then(tags => tags.map(t => new GiteaTag(t))); } // --------------------------------------------------------------------------- // Secrets // --------------------------------------------------------------------------- async getSecrets(): Promise { const secrets = await this.client.requestGetRepoSecrets(this.fullName); return secrets.map(s => new GiteaSecret(s)); } async setSecret(key: string, value: string): Promise { await this.client.requestSetRepoSecret(this.fullName, key, value); } async deleteSecret(key: string): Promise { await this.client.requestDeleteRepoSecret(this.fullName, key); } // --------------------------------------------------------------------------- // Action Runs // --------------------------------------------------------------------------- async getActionRuns(opts?: IActionRunListOptions): Promise { return autoPaginate( (page, perPage) => this.client.requestGetActionRuns(this.fullName, { ...opts, page, perPage }), opts, ).then(runs => runs.map(r => new GiteaActionRun(this.client, this.fullName, r))); } // --------------------------------------------------------------------------- // Mutation // --------------------------------------------------------------------------- /** * Update repository properties. */ async update(data: { name?: string; description?: string; defaultBranch?: string; private?: boolean; archived?: boolean; }): Promise { await this.client.requestPatchRepo(this.fullName, { name: data.name, description: data.description, default_branch: data.defaultBranch, private: data.private, archived: data.archived, }); } /** * Set topics for this repository (replaces all existing topics). */ async setTopics(topics: string[]): Promise { await this.client.requestSetRepoTopics(this.fullName, topics); } /** * Upload an avatar image for this repository. * @param imageBase64 - Base64-encoded image data */ async setAvatar(imageBase64: string): Promise { await this.client.requestPostRepoAvatar(this.fullName, imageBase64); } /** * Remove the repository's avatar. */ async deleteAvatar(): Promise { await this.client.requestDeleteRepoAvatar(this.fullName); } /** * Transfer this repository to a different owner (org or user). */ async transfer(newOwner: string, teamIds?: number[]): Promise { await this.client.requestTransferRepo(this.fullName, newOwner, teamIds); } /** * Delete this repository. */ async delete(): Promise { const [owner, repo] = this.fullName.split('/'); await this.client.requestDeleteRepo(owner, repo); } // --------------------------------------------------------------------------- // Serialization // --------------------------------------------------------------------------- toJSON(): IGiteaRepository { return { id: this.id, name: this.name, full_name: this.fullName, description: this.description, default_branch: this.defaultBranch, html_url: this.htmlUrl, private: this.isPrivate, topics: this.topics, updated_at: this.updatedAt, owner: { id: this.ownerId, login: this.ownerLogin, avatar_url: this.ownerAvatarUrl, }, }; } }