import ApiClient, { encodeQueryString } from './client'; import type { Agent, Cron, ExtensionSettings, Forge, Org, OrgPermissions, Pipeline, PipelineConfig, PipelineFeed, PipelineLog, PullRequest, QueueInfo, Registry, Repo, RepoPermissions, RepoSettings, Secret, User, } from './types'; const DEFAULT_FORGE_ID = 1; interface RepoListOptions { all?: boolean; } // PipelineOptions is the data for creating a new pipeline interface PipelineOptions { branch: string; variables: Record; } interface DeploymentOptions { id: string; environment: string; task: string; variables: Record; } interface PaginationOptions { page?: number; perPage?: number; } export default class WoodpeckerClient extends ApiClient { async getRepoList(opts?: RepoListOptions): Promise { const query = encodeQueryString(opts); return this._get(`/api/user/repos?${query}`) as Promise; } async lookupRepo(owner: string, name: string): Promise { return this._get(`/api/repos/lookup/${owner}/${name}`) as Promise; } async getRepo(repoId: number): Promise { return this._get(`/api/repos/${repoId}`) as Promise; } async getRepoPermissions(repoId: number): Promise { return this._get(`/api/repos/${repoId}/permissions`) as Promise; } async getRepoBranches(repoId: number, opts?: PaginationOptions): Promise { const query = encodeQueryString(opts); return this._get(`/api/repos/${repoId}/branches?${query}`) as Promise; } async getRepoPullRequests(repoId: number, opts?: PaginationOptions): Promise { const query = encodeQueryString(opts); return this._get(`/api/repos/${repoId}/pull_requests?${query}`) as Promise; } async activateRepo(forgeRemoteId: string): Promise { return this._post(`/api/repos?forge_remote_id=${forgeRemoteId}`) as Promise; } async updateRepo(repoId: number, repoSettings: Partial): Promise { return this._patch(`/api/repos/${repoId}`, repoSettings); } async deleteRepo(repoId: number, remove = true): Promise { const query = encodeQueryString({ remove }); return this._delete(`/api/repos/${repoId}?${query}`); } async repairRepo(repoId: number): Promise { return this._post(`/api/repos/${repoId}/repair`); } async createPipeline(repoId: number, options: PipelineOptions): Promise { return this._post(`/api/repos/${repoId}/pipelines`, options) as Promise; } // Deploy triggers a deployment for an existing pipeline using the // specified target environment and task. async deployPipeline(repoId: number, pipelineNumber: string, options: DeploymentOptions): Promise { const vars = { ...options.variables, event: 'deployment', deploy_to: options.environment, deploy_task: options.task, }; const query = encodeQueryString(vars); return this._post(`/api/repos/${repoId}/pipelines/${pipelineNumber}?${query}`) as Promise; } async getPipelineList( repoId: number, opts?: PaginationOptions & { before?: string; after?: string; ref?: string; branch?: string; events?: string }, ): Promise { const query = encodeQueryString(opts); return this._get(`/api/repos/${repoId}/pipelines?${query}`) as Promise; } async getPipeline(repoId: number, pipelineNumber: number | 'latest'): Promise { return this._get(`/api/repos/${repoId}/pipelines/${pipelineNumber}`) as Promise; } async getPipelineConfig(repoId: number, pipelineNumber: number): Promise { return this._get(`/api/repos/${repoId}/pipelines/${pipelineNumber}/config`) as Promise; } async getPipelineMetadata(repoId: number, pipelineNumber: number): Promise { return this._get(`/api/repos/${repoId}/pipelines/${pipelineNumber}/metadata`) as Promise; } async getPipelineFeed(): Promise { return this._get(`/api/user/feed`) as Promise; } async cancelPipeline(repoId: number, pipelineNumber: number): Promise { return this._post(`/api/repos/${repoId}/pipelines/${pipelineNumber}/cancel`); } async approvePipeline(repoId: number, pipelineNumber: string): Promise { return this._post(`/api/repos/${repoId}/pipelines/${pipelineNumber}/approve`); } async declinePipeline(repoId: number, pipelineNumber: string): Promise { return this._post(`/api/repos/${repoId}/pipelines/${pipelineNumber}/decline`); } async restartPipeline( repoId: number, pipeline: string, opts?: { event?: string; deploy_to?: string; fork?: boolean }, ): Promise { const query = encodeQueryString(opts); return this._post(`/api/repos/${repoId}/pipelines/${pipeline}?${query}`) as Promise; } async getLogs(repoId: number, pipeline: number, step: number): Promise { return this._get(`/api/repos/${repoId}/logs/${pipeline}/${step}`) as Promise; } async deleteLogs(repoId: number, pipeline: number, step: number): Promise { return this._delete(`/api/repos/${repoId}/logs/${pipeline}/${step}`); } async getSecretList(repoId: number, opts?: PaginationOptions): Promise { const query = encodeQueryString(opts); return this._get(`/api/repos/${repoId}/secrets?${query}`) as Promise; } async createSecret(repoId: number, secret: Partial): Promise { return this._post(`/api/repos/${repoId}/secrets`, secret); } async updateSecret(repoId: number, secret: Partial): Promise { const secretName = encodeURIComponent(secret.name ?? ''); return this._patch(`/api/repos/${repoId}/secrets/${secretName}`, secret); } async deleteSecret(repoId: number, secretName: string): Promise { const name = encodeURIComponent(secretName); return this._delete(`/api/repos/${repoId}/secrets/${name}`); } async getRegistryList(repoId: number, opts?: PaginationOptions): Promise { const query = encodeQueryString(opts); return this._get(`/api/repos/${repoId}/registries?${query}`) as Promise; } async createRegistry(repoId: number, registry: Partial): Promise { return this._post(`/api/repos/${repoId}/registries`, registry); } async updateRegistry(repoId: number, registry: Partial): Promise { return this._patch(`/api/repos/${repoId}/registries/${registry.address}`, registry); } async deleteRegistry(repoId: number, registryAddress: string): Promise { return this._delete(`/api/repos/${repoId}/registries/${registryAddress}`); } async getOrgRegistryList(orgId: number, opts?: PaginationOptions): Promise { const query = encodeQueryString(opts); return this._get(`/api/orgs/${orgId}/registries?${query}`) as Promise; } async createOrgRegistry(orgId: number, registry: Partial): Promise { return this._post(`/api/orgs/${orgId}/registries`, registry); } async updateOrgRegistry(orgId: number, registry: Partial): Promise { return this._patch(`/api/orgs/${orgId}/registries/${registry.address}`, registry); } async deleteOrgRegistry(orgId: number, registryAddress: string): Promise { return this._delete(`/api/orgs/${orgId}/registries/${registryAddress}`); } async getGlobalRegistryList(opts?: PaginationOptions): Promise { const query = encodeQueryString(opts); return this._get(`/api/registries?${query}`) as Promise; } async createGlobalRegistry(registry: Partial): Promise { return this._post(`/api/registries`, registry); } async updateGlobalRegistry(registry: Partial): Promise { return this._patch(`/api/registries/${registry.address}`, registry); } async deleteGlobalRegistry(registryAddress: string): Promise { return this._delete(`/api/registries/${registryAddress}`); } async getCronList(repoId: number, opts?: PaginationOptions): Promise { const query = encodeQueryString(opts); return this._get(`/api/repos/${repoId}/cron?${query}`) as Promise; } async createCron(repoId: number, cron: Partial): Promise { return this._post(`/api/repos/${repoId}/cron`, cron); } async updateCron(repoId: number, cron: Partial): Promise { return this._patch(`/api/repos/${repoId}/cron/${cron.id}`, cron); } async deleteCron(repoId: number, cronId: number): Promise { return this._delete(`/api/repos/${repoId}/cron/${cronId}`); } async runCron(repoId: number, cronId: number): Promise { return this._post(`/api/repos/${repoId}/cron/${cronId}`) as Promise; } async getOrg(orgId: number): Promise { return this._get(`/api/orgs/${orgId}`) as Promise; } async lookupOrg(name: string): Promise { return this._get(`/api/orgs/lookup/${name}`) as Promise; } async getOrgPermissions(orgId: number): Promise { return this._get(`/api/orgs/${orgId}/permissions`) as Promise; } async getOrgSecretList(orgId: number, opts?: PaginationOptions): Promise { const query = encodeQueryString(opts); return this._get(`/api/orgs/${orgId}/secrets?${query}`) as Promise; } async createOrgSecret(orgId: number, secret: Partial): Promise { return this._post(`/api/orgs/${orgId}/secrets`, secret); } async updateOrgSecret(orgId: number, secret: Partial): Promise { const secretName = encodeURIComponent(secret.name ?? ''); return this._patch(`/api/orgs/${orgId}/secrets/${secretName}`, secret); } async deleteOrgSecret(orgId: number, secretName: string): Promise { const name = encodeURIComponent(secretName); return this._delete(`/api/orgs/${orgId}/secrets/${name}`); } async getGlobalSecretList(opts?: PaginationOptions): Promise { const query = encodeQueryString(opts); return this._get(`/api/secrets?${query}`) as Promise; } async createGlobalSecret(secret: Partial): Promise { return this._post(`/api/secrets`, secret); } async updateGlobalSecret(secret: Partial): Promise { const secretName = encodeURIComponent(secret.name ?? ''); return this._patch(`/api/secrets/${secretName}`, secret); } async deleteGlobalSecret(secretName: string): Promise { const name = encodeURIComponent(secretName); return this._delete(`/api/secrets/${name}`); } async getSelf(): Promise { return this._get('/api/user'); } async getToken(): Promise { return this._post('/api/user/token') as Promise; } async getSignaturePublicKey(): Promise { return this._get('/api/signature/public-key') as Promise; } async getAgents(opts?: PaginationOptions): Promise { const query = encodeQueryString(opts); return this._get(`/api/agents?${query}`) as Promise; } async getAgent(agentId: Agent['id']): Promise { return this._get(`/api/agents/${agentId}`) as Promise; } async createAgent(agent: Partial): Promise { return this._post('/api/agents', agent) as Promise; } async updateAgent(agent: Partial): Promise { return this._patch(`/api/agents/${agent.id}`, agent) as Promise; } async deleteAgent(agent: Agent): Promise { return this._delete(`/api/agents/${agent.id}`); } async getOrgAgents(orgId: number, opts?: PaginationOptions): Promise { const query = encodeQueryString(opts); return this._get(`/api/orgs/${orgId}/agents?${query}`) as Promise; } async createOrgAgent(orgId: number, agent: Partial): Promise { return this._post(`/api/orgs/${orgId}/agents`, agent) as Promise; } async updateOrgAgent(orgId: number, agentId: number, agent: Partial): Promise { return this._patch(`/api/orgs/${orgId}/agents/${agentId}`, agent) as Promise; } async deleteOrgAgent(orgId: number, agentId: number): Promise { return this._delete(`/api/orgs/${orgId}/agents/${agentId}`); } async getForges(opts?: PaginationOptions): Promise { const query = encodeQueryString(opts); return this._get(`/api/forges?${query}`) as Promise; } async getForge(forgeId: Forge['id']): Promise { return this._get(`/api/forges/${forgeId}`) as Promise; } async createForge(forge: Partial): Promise { return this._post('/api/forges', forge) as Promise; } async updateForge(forge: Partial): Promise { return this._patch(`/api/forges/${forge.id}`, forge); } async deleteForge(forge: Forge): Promise { return this._delete(`/api/forges/${forge.id}`); } async getQueueInfo(): Promise { return this._get('/api/queue/info') as Promise; } async pauseQueue(): Promise { return this._post('/api/queue/pause'); } async resumeQueue(): Promise { return this._post('/api/queue/resume'); } async getUsers(opts?: PaginationOptions): Promise { const query = encodeQueryString(opts); return this._get(`/api/users?${query}`) as Promise; } async getUser(username: string, forgeID?: number): Promise { const forge = forgeID ?? DEFAULT_FORGE_ID; return this._get(`/api/users/${username}?forge_id=${forge}`) as Promise; } async createUser(user: Partial): Promise { return this._post('/api/users', user) as Promise; } async updateUser(user: Partial): Promise { return this._patch(`/api/users/${user.login}`, user); } async deleteUser(user: User): Promise { return this._delete(`/api/users/${user.login}?forge_id=${user.forge_id}`); } async resetToken(): Promise { return this._delete('/api/user/token') as Promise; } async getOrgs(opts?: PaginationOptions): Promise { const query = encodeQueryString(opts); return this._get(`/api/orgs?${query}`) as Promise; } async deleteOrg(org: Org): Promise { return this._delete(`/api/orgs/${org.id}`); } async getAllRepos(opts?: PaginationOptions): Promise { const query = encodeQueryString(opts); return this._get(`/api/repos?${query}`) as Promise; } async repairAllRepos(): Promise { return this._post(`/api/repos/repair`); } // eslint-disable-next-line promise/prefer-await-to-callbacks on(callback: (data: { pipeline?: Pipeline; repo?: Repo }) => void): EventSource { return this._subscribe('/api/stream/events', callback, { reconnect: true, }); } streamLogs( repoId: number, pipeline: number, step: number, // eslint-disable-next-line promise/prefer-await-to-callbacks callback: (data: PipelineLog) => void, ): EventSource { return this._subscribe(`/api/stream/logs/${repoId}/${pipeline}/${step}`, callback, { reconnect: true, }); } }