/** * Gogs API Client * Provides methods to interact with a Gogs server REST API */ import axios, { AxiosInstance } from 'axios'; import type { GogsUser, GogsRepository, GogsSearchResponse, GogsFileContent, GogsBranch, GogsCommit, GogsConfig, GogsIssue, GogsIssueComment, GogsLabel, GogsOrganization, GogsTeam, } from './types.js'; export class GogsClient { private client: AxiosInstance; private serverUrl: string; constructor(config: GogsConfig) { this.serverUrl = config.serverUrl.replace(/\/$/, ''); this.client = axios.create({ baseURL: `${this.serverUrl}/api/v1`, headers: { 'Content-Type': 'application/json', ...(config.accessToken && { Authorization: `token ${config.accessToken}` }), }, }); } /** * Get information about the authenticated user */ async getCurrentUser(): Promise { const response = await this.client.get('/user'); return response.data; } /** * Get information about a specific user */ async getUser(username: string): Promise { const response = await this.client.get(`/users/${username}`); return response.data; } /** * Search for users */ async searchUsers(query: string, limit: number = 10): Promise { const response = await this.client.get>('/users/search', { params: { q: query, limit }, }); return response.data.data; } /** * List repositories for the authenticated user */ async listMyRepositories(): Promise { const response = await this.client.get('/user/repos'); return response.data; } /** * List repositories for a specific user */ async listUserRepositories(username: string): Promise { const response = await this.client.get(`/users/${username}/repos`); return response.data; } /** * Search for repositories */ async searchRepositories( query: string, options?: { uid?: number; limit?: number; page?: number } ): Promise { const response = await this.client.get>('/repos/search', { params: { q: query, uid: options?.uid || 0, limit: options?.limit || 10, page: options?.page || 1, }, }); return response.data.data; } /** * Get information about a specific repository */ async getRepository(owner: string, repo: string): Promise { const response = await this.client.get(`/repos/${owner}/${repo}`); return response.data; } /** * Create a new repository */ async createRepository(data: { name: string; description?: string; private?: boolean; auto_init?: boolean; gitignores?: string; license?: string; readme?: string; }): Promise { const response = await this.client.post('/user/repos', data); return response.data; } /** * Delete a repository */ async deleteRepository(owner: string, repo: string): Promise { await this.client.delete(`/repos/${owner}/${repo}`); } /** * Get file or directory contents */ async getContents( owner: string, repo: string, path: string, ref?: string ): Promise { const response = await this.client.get( `/repos/${owner}/${repo}/contents/${path}`, { params: ref ? { ref } : undefined, } ); return response.data; } /** * Get raw file content */ async getRawContent(owner: string, repo: string, ref: string, path: string): Promise { const response = await this.client.get( `/repos/${owner}/${repo}/raw/${ref}/${path}`, { responseType: 'text', } ); return response.data; } /** * List branches in a repository */ async listBranches(owner: string, repo: string): Promise { const response = await this.client.get(`/repos/${owner}/${repo}/branches`); return response.data; } /** * Get commits from a repository */ async getCommits( owner: string, repo: string, options?: { sha?: string; page?: number } ): Promise { const response = await this.client.get(`/repos/${owner}/${repo}/commits`, { params: { sha: options?.sha, page: options?.page || 1, }, }); return response.data; } /** * List issues in a repository */ async listIssues( owner: string, repo: string, options?: { state?: 'open' | 'closed' | 'all'; labels?: string; page?: number; per_page?: number; } ): Promise { const response = await this.client.get(`/repos/${owner}/${repo}/issues`, { params: { state: options?.state || 'open', labels: options?.labels, page: options?.page || 1, per_page: options?.per_page || 30, }, }); return response.data; } /** * Get a specific issue */ async getIssue(owner: string, repo: string, number: number): Promise { const response = await this.client.get(`/repos/${owner}/${repo}/issues/${number}`); return response.data; } /** * Create a new issue */ async createIssue( owner: string, repo: string, data: { title: string; body?: string; assignee?: string; milestone?: number; labels?: number[]; } ): Promise { const response = await this.client.post( `/repos/${owner}/${repo}/issues`, data ); return response.data; } /** * Update an existing issue */ async updateIssue( owner: string, repo: string, number: number, data: { title?: string; body?: string; assignee?: string; milestone?: number; state?: 'open' | 'closed'; labels?: number[]; } ): Promise { const response = await this.client.patch( `/repos/${owner}/${repo}/issues/${number}`, data ); return response.data; } /** * List comments on an issue */ async listIssueComments( owner: string, repo: string, number: number ): Promise { const response = await this.client.get( `/repos/${owner}/${repo}/issues/${number}/comments` ); return response.data; } /** * Create a comment on an issue */ async createIssueComment( owner: string, repo: string, number: number, body: string ): Promise { const response = await this.client.post( `/repos/${owner}/${repo}/issues/${number}/comments`, { body } ); return response.data; } /** * Edit a comment on an issue */ async updateIssueComment( owner: string, repo: string, commentId: number, body: string ): Promise { const response = await this.client.patch( `/repos/${owner}/${repo}/issues/comments/${commentId}`, { body } ); return response.data; } /** * List all labels in a repository */ async listLabels(owner: string, repo: string): Promise { const response = await this.client.get(`/repos/${owner}/${repo}/labels`); return response.data; } /** * Get a specific label by ID */ async getLabel(owner: string, repo: string, labelId: number): Promise { const response = await this.client.get(`/repos/${owner}/${repo}/labels/${labelId}`); return response.data; } /** * Create a new label */ async createLabel( owner: string, repo: string, data: { name: string; color: string; } ): Promise { const response = await this.client.post( `/repos/${owner}/${repo}/labels`, data ); return response.data; } /** * Update an existing label */ async updateLabel( owner: string, repo: string, labelId: number, data: { name?: string; color?: string; } ): Promise { const response = await this.client.patch( `/repos/${owner}/${repo}/labels/${labelId}`, data ); return response.data; } /** * Delete a label */ async deleteLabel(owner: string, repo: string, labelId: number): Promise { await this.client.delete(`/repos/${owner}/${repo}/labels/${labelId}`); } /** * List labels on a specific issue */ async listIssueLabels(owner: string, repo: string, issueNumber: number): Promise { const response = await this.client.get( `/repos/${owner}/${repo}/issues/${issueNumber}/labels` ); return response.data; } /** * Add labels to an issue */ async addIssueLabels( owner: string, repo: string, issueNumber: number, labelIds: number[] ): Promise { const response = await this.client.post( `/repos/${owner}/${repo}/issues/${issueNumber}/labels`, { labels: labelIds } ); return response.data; } /** * Remove a label from an issue */ async removeIssueLabel( owner: string, repo: string, issueNumber: number, labelId: number ): Promise { await this.client.delete(`/repos/${owner}/${repo}/issues/${issueNumber}/labels/${labelId}`); } /** * Replace all labels on an issue */ async replaceIssueLabels( owner: string, repo: string, issueNumber: number, labelIds: number[] ): Promise { const response = await this.client.put( `/repos/${owner}/${repo}/issues/${issueNumber}/labels`, { labels: labelIds } ); return response.data; } /** * Remove all labels from an issue */ async removeAllIssueLabels( owner: string, repo: string, issueNumber: number ): Promise { await this.client.delete(`/repos/${owner}/${repo}/issues/${issueNumber}/labels`); } /** * List organizations for the authenticated user */ async listUserOrganizations(): Promise { const response = await this.client.get('/user/orgs'); return response.data; } /** * List public organizations for a specific user */ async listPublicOrganizations(username: string): Promise { const response = await this.client.get(`/users/${username}/orgs`); return response.data; } /** * Get information about a specific organization */ async getOrganization(orgname: string): Promise { const response = await this.client.get(`/orgs/${orgname}`); return response.data; } /** * Update an organization */ async updateOrganization( orgname: string, data: { full_name?: string; description?: string; website?: string; location?: string; } ): Promise { const response = await this.client.patch(`/orgs/${orgname}`, data); return response.data; } /** * Add or update organization membership */ async addOrganizationMember( orgname: string, username: string, role: 'admin' | 'member' ): Promise { await this.client.put(`/orgs/${orgname}/memberships/${username}`, { role }); } /** * List teams in an organization */ async listOrganizationTeams(orgname: string): Promise { const response = await this.client.get(`/orgs/${orgname}/teams`); return response.data; } }