Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kody/origin

src/repos.ts

122 lines · 3.0 KB · TypeScript
import { asRecord, isRecord, originErrorMessage } from './http.ts'
import { slimRepo } from './installations.ts'
import { originRequest } from './request.ts'
import {
	type OriginAccountInput,
	type OriginMutationInput,
	type OriginRepoSummary,
} from './types.ts'

/**
 * List Origin repositories for an owner slug.
 */
export async function listOriginRepos(
	params: OriginAccountInput & {
		ownerSlug: string
		pageSize?: number
		pageToken?: string
		filter?: string
	},
): Promise<{ items: Array<OriginRepoSummary>; nextPageToken: string | null }> {
	const ownerSlug = params.ownerSlug.trim()
	if (!ownerSlug) {
		throw new Error('ownerSlug is required.')
	}
	const result = await originRequest({
		...params,
		path: `/repos/${encodeURIComponent(ownerSlug)}`,
		auth: 'installation',
		query: {
			pageSize: params.pageSize,
			pageToken: params.pageToken,
			filter: params.filter,
		},
	})
	if (!result.ok) {
		throw new Error(
			`Failed to list Origin repos: ${originErrorMessage(result.body, result.status)}`,
		)
	}
	const payload = isRecord(result.body) ? result.body : {}
	const raw = Array.isArray(payload.repositories) ? payload.repositories : []
	return {
		items: raw.map((item) => slimRepo(asRecord(item))),
		nextPageToken:
			typeof payload.nextPageToken === 'string' && payload.nextPageToken
				? payload.nextPageToken
				: null,
	}
}

/**
 * Fetch one Origin repository.
 */
export async function getOriginRepo(
	params: OriginAccountInput & {
		ownerSlug: string
		repoName: string
	},
): Promise<OriginRepoSummary> {
	const ownerSlug = params.ownerSlug.trim()
	const repoName = params.repoName.trim()
	if (!ownerSlug || !repoName) {
		throw new Error('ownerSlug and repoName are required.')
	}
	const result = await originRequest({
		...params,
		path: `/repos/${encodeURIComponent(ownerSlug)}/${encodeURIComponent(repoName)}`,
		auth: 'installation',
	})
	if (!result.ok) {
		throw new Error(
			`Failed to get Origin repo: ${originErrorMessage(result.body, result.status)}`,
		)
	}
	return slimRepo(asRecord(result.body))
}

/**
 * Create an Origin repository. Pass `dryRun: true` to preview, or
 * `confirm: true` to create it.
 */
export async function createOriginRepo(
	params: OriginAccountInput &
		OriginMutationInput & {
			ownerSlug: string
			name: string
			defaultBranch?: string
		},
) {
	const ownerSlug = params.ownerSlug.trim()
	const name = params.name.trim()
	if (!ownerSlug || !name) {
		throw new Error('ownerSlug and name are required.')
	}
	const result = await originRequest({
		...params,
		path: `/repos/${encodeURIComponent(ownerSlug)}`,
		method: 'POST',
		auth: 'installation',
		body: {
			name,
			...(params.defaultBranch ? { defaultBranch: params.defaultBranch } : {}),
		},
	})
	if (result.dryRun) {
		return {
			dryRun: true,
			wouldCreate: true,
			ownerSlug,
			name,
			defaultBranch: params.defaultBranch ?? 'main',
		}
	}
	if (!result.ok) {
		throw new Error(
			`Failed to create Origin repo: ${originErrorMessage(result.body, result.status)}`,
		)
	}
	return slimRepo(asRecord(result.body))
}

export default listOriginRepos