Files
gitea/ts/gitea.helpers.ts

88 lines
2.7 KiB
TypeScript

/**
* Auto-paginate a list endpoint.
* If opts includes a specific page, returns just that page (no auto-pagination).
*/
export async function autoPaginate<T>(
fetchPage: (page: number, perPage: number) => Promise<T[]>,
opts?: { page?: number; perPage?: number },
): Promise<T[]> {
const perPage = opts?.perPage || 50;
// If caller requests a specific page, return just that page
if (opts?.page) {
return fetchPage(opts.page, perPage);
}
// Otherwise auto-paginate through all pages
const all: T[] = [];
let page = 1;
while (true) {
const items = await fetchPage(page, perPage);
all.push(...items);
if (items.length < perPage) break;
page++;
}
return all;
}
/**
* Compute duration in seconds from two ISO timestamps.
*/
export function computeDuration(startedAt?: string, completedAt?: string): number {
if (!startedAt || !completedAt) return 0;
const ms = new Date(completedAt).getTime() - new Date(startedAt).getTime();
return ms > 0 ? Math.round(ms / 1000) : 0;
}
/**
* Gitea uses `status` for run state (running, waiting, completed)
* and `conclusion` for the actual result (success, failure, cancelled, skipped).
* When status is "completed", the conclusion carries the meaningful status.
*/
export function resolveGiteaStatus(status: string, conclusion: string): string {
if (status === 'completed' && conclusion) {
return conclusion;
}
return status || conclusion || '';
}
/**
* Extract a human-readable ref from the Gitea `path` field.
* path format: "workflow.yaml@refs/tags/v1.0.0" or "workflow.yaml@refs/heads/main"
*/
export function extractRefFromPath(path?: string): string {
if (!path) return '';
const atIdx = path.indexOf('@');
if (atIdx < 0) return '';
const ref = path.substring(atIdx + 1);
return ref.replace(/^refs\/tags\//, '').replace(/^refs\/heads\//, '');
}
/**
* Extract the workflow filename from the Gitea `path` field.
* path format: "workflow.yaml@refs/tags/v1.0.0" → "workflow.yaml"
*/
export function extractWorkflowIdFromPath(path?: string): string {
if (!path) return '';
const atIdx = path.indexOf('@');
return atIdx >= 0 ? path.substring(0, atIdx) : path;
}
/**
* Translate normalized status names to Gitea API-native query parameter values.
* Gitea accepts: pending, queued, in_progress, failure, success, skipped
*/
export function toGiteaApiStatus(status?: string): string | undefined {
if (!status) return undefined;
const map: Record<string, string> = {
running: 'in_progress',
failed: 'failure',
canceled: 'cancelled',
pending: 'pending',
success: 'success',
skipped: 'skipped',
waiting: 'queued',
};
return map[status] || status;
}