6 Commits

6 changed files with 126 additions and 2 deletions

View File

@@ -1,5 +1,27 @@
# Changelog
## 2026-03-02 - 1.3.0 - feat(gitea)
add repository branches and tags support: new IGiteaBranch/IGiteaTag interfaces and getRepoBranches/getRepoTags client methods
- Added IGiteaBranch and IGiteaTag interfaces (ts/gitea.interfaces.ts).
- Added getRepoBranches and getRepoTags methods with pagination support to Gitea client (ts/gitea.classes.giteaclient.ts).
- Exported the new interfaces from the package index (ts/index.ts).
## 2026-02-28 - 1.2.0 - feat(giteaclient)
add deleteRepo method to delete a repository via Gitea API
- Implements deleteRepo(owner: string, repo: string): Promise<void>
- Uses DELETE /api/v1/repos/{owner}/{repo} and encodes owner and repo with encodeURIComponent
## 2026-02-28 - 1.1.0 - feat(orgs)
add organization and organization-repository APIs: getOrg, getOrgRepos, createOrg, createOrgRepo
- Added getOrg(orgName): fetch a single organization by name
- Added getOrgRepos(orgName, opts?): list repositories in an organization with pagination, sorting by updated, and optional search query
- Added createOrg(name, opts?): create a new organization with fullName, description, and visibility (defaults to public)
- Added createOrgRepo(orgName, name, opts?): create a repository within an organization; description optional and private defaults to true
- Endpoints use encodeURIComponent for orgName in URLs to ensure safe requests
## 2026-02-24 - 1.0.3 - fix(gitea)
no changes detected in the diff; no code or doc updates

View File

@@ -1,6 +1,6 @@
{
"name": "@apiclient.xyz/gitea",
"version": "1.0.3",
"version": "1.3.0",
"private": false,
"description": "A TypeScript client for the Gitea API, providing easy access to repositories, organizations, secrets, and action runs.",
"main": "dist_ts/index.js",

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@apiclient.xyz/gitea',
version: '1.0.3',
version: '1.3.0',
description: 'A TypeScript client for the Gitea API, providing easy access to repositories, organizations, secrets, and action runs.'
}

View File

@@ -5,6 +5,8 @@ import type {
IGiteaRepository,
IGiteaOrganization,
IGiteaSecret,
IGiteaBranch,
IGiteaTag,
IGiteaActionRun,
IGiteaActionRunJob,
ITestConnectionResult,
@@ -149,6 +151,78 @@ export class GiteaClient {
return this.request<IGiteaOrganization[]>('GET', `/api/v1/orgs?page=${page}&limit=${limit}`);
}
/**
* Get a single organization by name
*/
public async getOrg(orgName: string): Promise<IGiteaOrganization> {
return this.request<IGiteaOrganization>('GET', `/api/v1/orgs/${encodeURIComponent(orgName)}`);
}
/**
* List repositories within an organization
*/
public async getOrgRepos(orgName: string, opts?: IListOptions): Promise<IGiteaRepository[]> {
const page = opts?.page || 1;
const limit = opts?.perPage || 50;
let url = `/api/v1/orgs/${encodeURIComponent(orgName)}/repos?page=${page}&limit=${limit}&sort=updated`;
if (opts?.search) {
url += `&q=${encodeURIComponent(opts.search)}`;
}
return this.request<IGiteaRepository[]>('GET', url);
}
/**
* Create a new organization
*/
public async createOrg(name: string, opts?: {
fullName?: string;
description?: string;
visibility?: string;
}): Promise<IGiteaOrganization> {
return this.request<IGiteaOrganization>('POST', '/api/v1/orgs', {
username: name,
full_name: opts?.fullName || name,
description: opts?.description || '',
visibility: opts?.visibility || 'public',
});
}
/**
* Create a repository within an organization
*/
public async createOrgRepo(orgName: string, name: string, opts?: {
description?: string;
private?: boolean;
}): Promise<IGiteaRepository> {
return this.request<IGiteaRepository>('POST', `/api/v1/orgs/${encodeURIComponent(orgName)}/repos`, {
name,
description: opts?.description || '',
private: opts?.private ?? true,
});
}
// ---------------------------------------------------------------------------
// Repository Branches & Tags
// ---------------------------------------------------------------------------
public async getRepoBranches(ownerRepo: string, opts?: IListOptions): Promise<IGiteaBranch[]> {
const page = opts?.page || 1;
const limit = opts?.perPage || 50;
return this.request<IGiteaBranch[]>(
'GET',
`/api/v1/repos/${ownerRepo}/branches?page=${page}&limit=${limit}`,
);
}
public async getRepoTags(ownerRepo: string, opts?: IListOptions): Promise<IGiteaTag[]> {
const page = opts?.page || 1;
const limit = opts?.perPage || 50;
return this.request<IGiteaTag[]>(
'GET',
`/api/v1/repos/${ownerRepo}/tags?page=${page}&limit=${limit}`,
);
}
// ---------------------------------------------------------------------------
// Repository Secrets
// ---------------------------------------------------------------------------
@@ -208,4 +282,15 @@ export class GiteaClient {
public async cancelAction(ownerRepo: string, runId: number): Promise<void> {
await this.request('POST', `/api/v1/repos/${ownerRepo}/actions/runs/${runId}/cancel`);
}
// ---------------------------------------------------------------------------
// Repository Deletion
// ---------------------------------------------------------------------------
public async deleteRepo(owner: string, repo: string): Promise<void> {
await this.request(
'DELETE',
`/api/v1/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`,
);
}
}

View File

@@ -58,6 +58,21 @@ export interface IGiteaActionRunJob {
run_duration: number;
}
export interface IGiteaBranch {
name: string;
commit: {
id: string;
};
}
export interface IGiteaTag {
name: string;
id: string;
commit: {
sha: string;
};
}
export interface ITestConnectionResult {
ok: boolean;
error?: string;

View File

@@ -4,6 +4,8 @@ export type {
IGiteaRepository,
IGiteaOrganization,
IGiteaSecret,
IGiteaBranch,
IGiteaTag,
IGiteaActionRun,
IGiteaActionRunJob,
ITestConnectionResult,