main
/**
* Refs domain: branches and tags — wire types and endpoints. The branch list
* is the source of truth for the ref picker and the branch management tab.
*/
import { unwrapApi } from '@app/lib'
import type { EnvelopePageBranchDto, EnvelopePageTagDto } from '@app/services/api'
import Apis from '@app/services/api'
export type BranchRow = NonNullable<NonNullable<EnvelopePageBranchDto['data']>['items']>[number]
export type TagRow = NonNullable<NonNullable<EnvelopePageTagDto['data']>['items']>[number]
export type RefKind = 'branch' | 'tag'
/** Server-side total matters: `RepoDto.branches_count` can lag behind the
* actual refs (imported repos), and the branch list is the truth. */
export async function listBranches(
space: string,
repo: string,
limit = 100,
): Promise<{ items: BranchRow[]; total: number }> {
const page = await unwrapApi<{ items?: BranchRow[]; total?: number }>(
Apis.branches.list_branches({
pathParams: { space_name: space, repo_name: repo },
params: { limit },
}),
)
const items = page.items ?? []
return { items, total: page.total ?? items.length }
}
export const createBranch = (space: string, repo: string, name: string, startPoint: string) =>
unwrapApi<BranchRow>(
Apis.branches.create_branch({
pathParams: { space_name: space, repo_name: repo },
data: { name, start_point: startPoint || null },
}),
)
export const renameBranch = (space: string, repo: string, name: string, newName: string) =>
unwrapApi<null>(
Apis.branches.rename_branch({
pathParams: { space_name: space, repo_name: repo, name },
data: { new_name: newName },
}),
)
/** `force` is what lets the server delete a branch nothing else contains. */
export const deleteBranch = (space: string, repo: string, name: string, force = false) =>
unwrapApi<null>(
Apis.branches.delete_branch({
pathParams: { space_name: space, repo_name: repo, name },
params: { force },
}),
)
export const setDefaultBranch = (space: string, repo: string, name: string) =>
unwrapApi<null>(
Apis.branches.set_default_branch({
pathParams: { space_name: space, repo_name: repo, name },
}),
)
export async function listTags(space: string, repo: string, limit = 100): Promise<{ items: TagRow[]; total: number }> {
const page = await unwrapApi<{ items?: TagRow[]; total?: number }>(
Apis.tags.list_tags({
pathParams: { space_name: space, repo_name: repo },
params: { limit },
}),
)
const items = page.items ?? []
return { items, total: page.total ?? items.length }
}
/** Single tag incl. tagger/message for annotated tags. */
export const fetchTag = (space: string, repo: string, name: string) =>
unwrapApi<TagRow>(Apis.tags.get_tag({ pathParams: { space_name: space, repo_name: repo, name } }))
export const createTag = (
space: string,
repo: string,
cmd: { name: string; target: string; message?: string | null; annotated?: boolean },
) =>
unwrapApi<TagRow>(
Apis.tags.create_tag({
pathParams: { space_name: space, repo_name: repo },
data: {
name: cmd.name,
target: cmd.target,
message: cmd.message ?? null,
annotated: cmd.annotated ?? false,
},
}),
)
export const deleteTag = (space: string, repo: string, name: string) =>
unwrapApi<null>(Apis.tags.delete_tag({ pathParams: { space_name: space, repo_name: repo, name } }))