90 lines
2.6 KiB
TypeScript
90 lines
2.6 KiB
TypeScript
import { error, redirect } from '@sveltejs/kit';
|
|
import type { Actions, PageServerLoad } from './$types';
|
|
import { db } from '$lib/server/db';
|
|
import { githubInstallation, githubRepositoryLink, project } from '$lib/server/db/schema';
|
|
import { and, eq } from 'drizzle-orm';
|
|
import { listGitHubInstallationRepositories } from '$lib/server/github-app';
|
|
|
|
export const load: PageServerLoad = async (event) => {
|
|
if (!event.locals.user) throw redirect(302, '/auth/login');
|
|
const projectId = Number(event.params.id);
|
|
if (!Number.isFinite(projectId)) throw error(404, 'Project not found');
|
|
|
|
const [record] = await db
|
|
.select()
|
|
.from(project)
|
|
.where(and(eq(project.id, projectId), eq(project.ownerId, event.locals.user.id)))
|
|
.limit(1);
|
|
|
|
if (!record) throw error(404, 'Project not found');
|
|
|
|
const installations = await db
|
|
.select()
|
|
.from(githubInstallation)
|
|
.where(eq(githubInstallation.userId, event.locals.user.id));
|
|
|
|
const repositoryCatalog = await Promise.all(
|
|
installations.map(async (installation) => ({
|
|
installationId: installation.id,
|
|
accountLogin: installation.accountLogin,
|
|
repositories: await listGitHubInstallationRepositories(installation.installationId)
|
|
}))
|
|
);
|
|
|
|
return { project: record, installations, repositoryCatalog };
|
|
};
|
|
|
|
export const actions: Actions = {
|
|
link: async (event) => {
|
|
if (!event.locals.user) throw redirect(302, '/auth/login');
|
|
const projectId = Number(event.params.id);
|
|
const formData = await event.request.formData();
|
|
const repository = formData.get('repository')?.toString() ?? '';
|
|
|
|
if (!repository) {
|
|
return { error: 'Choose a repository to link' };
|
|
}
|
|
|
|
const parsed = JSON.parse(repository) as {
|
|
installationId: number;
|
|
owner: string;
|
|
repo: string;
|
|
fullName: string;
|
|
defaultBranch: string;
|
|
};
|
|
|
|
if (!parsed.installationId || !parsed.fullName) {
|
|
return { error: 'Choose a valid repository' };
|
|
}
|
|
|
|
const [projectRecord] = await db
|
|
.select()
|
|
.from(project)
|
|
.where(and(eq(project.id, projectId), eq(project.ownerId, event.locals.user.id)))
|
|
.limit(1);
|
|
|
|
if (!projectRecord) throw error(404, 'Project not found');
|
|
|
|
const [installation] = await db
|
|
.select()
|
|
.from(githubInstallation)
|
|
.where(and(eq(githubInstallation.id, parsed.installationId), eq(githubInstallation.userId, event.locals.user.id)))
|
|
.limit(1);
|
|
|
|
if (!installation) throw error(404, 'Installation not found');
|
|
|
|
await db
|
|
.insert(githubRepositoryLink)
|
|
.values({
|
|
projectId,
|
|
installationId: installation.id,
|
|
owner: parsed.owner,
|
|
repo: parsed.repo,
|
|
fullName: parsed.fullName,
|
|
defaultBranch: parsed.defaultBranch || 'main'
|
|
});
|
|
|
|
throw redirect(303, `/projects/${projectId}`);
|
|
}
|
|
};
|