import type * as interfaces from '../../ts_interfaces/index.ts'; export interface ITestConnectionResult { ok: boolean; error?: string; } export interface IListOptions { search?: string; page?: number; perPage?: number; } /** * Abstract base class for Git provider implementations. * Subclasses implement Gitea API v1 or GitLab API v4. */ export abstract class BaseProvider { constructor( public readonly connectionId: string, public readonly baseUrl: string, protected readonly token: string, ) {} // Connection abstract testConnection(): Promise; // Projects abstract getProjects(opts?: IListOptions): Promise; // Groups / Orgs abstract getGroups(opts?: IListOptions): Promise; // Secrets — project scope abstract getProjectSecrets(projectId: string): Promise; abstract createProjectSecret( projectId: string, key: string, value: string, ): Promise; abstract updateProjectSecret( projectId: string, key: string, value: string, ): Promise; abstract deleteProjectSecret(projectId: string, key: string): Promise; // Secrets — group scope abstract getGroupSecrets(groupId: string): Promise; abstract createGroupSecret( groupId: string, key: string, value: string, ): Promise; abstract updateGroupSecret( groupId: string, key: string, value: string, ): Promise; abstract deleteGroupSecret(groupId: string, key: string): Promise; // Pipelines / CI abstract getPipelines( projectId: string, opts?: IListOptions, ): Promise; abstract getPipelineJobs( projectId: string, pipelineId: string, ): Promise; abstract getJobLog(projectId: string, jobId: string): Promise; abstract retryPipeline(projectId: string, pipelineId: string): Promise; abstract cancelPipeline(projectId: string, pipelineId: string): Promise; /** * Helper for making authenticated fetch requests */ protected async apiFetch( path: string, options: RequestInit = {}, ): Promise { const url = `${this.baseUrl.replace(/\/+$/, '')}${path}`; const headers = new Headers(options.headers); this.setAuthHeader(headers); return fetch(url, { ...options, headers }); } protected abstract setAuthHeader(headers: Headers): void; }