import { join, resolve } from "node:path";
import type { ReqHandler } from "@ethicdevs/react-monolith";
import { AppRoute, AppRoutesParams } from "../../routes";
import { Env } from "../../env";
import { makeOrganizationService } from "../../services/organization";
import { makeRepositoryService } from "../../services/repository";
import { makeUsersService } from "../../services/user";
import RepositoryForkView, {
RepositoryForkViewProps,
} from "../../views/repository/RepositoryForkView";
const postRepositoryForkAction: ReqHandler = async (request, reply) => {
if (
request.session.data.authenticated === false ||
request.session.data.curr_user_uid == null
) {
reply.redirect(302, request.namedViewsPathMap[AppRoute.AUTH_LOGIN]);
return reply;
}
const reqHandler = reply.makeRequestHandler(request, reply);
const organizationService = makeOrganizationService({ request });
const repoService = makeRepositoryService({ request });
const usersService = makeUsersService({ request });
const { body, params, validationError } = request;
const { orgSlug: sourceOrgSlug, repoSlug: sourceRepoSlug } =
params as AppRoutesParams[AppRoute.REPOSITORY_FORK_ACTION]["params"];
const {
target_org_slug: targetOrgSlug,
target_repo_slug: targetRepoSlug,
target_repo_display_name: targetRepoDisplayName,
target_repo_visibility: targetRepoVisibility,
} = body as AppRoutesParams[AppRoute.REPOSITORY_FORK_ACTION]["body"];
const sourceParentOrg = await organizationService.getOrganizationBySlug(
sourceOrgSlug
);
if (sourceParentOrg == null) {
return reply.status(404).callNotFound();
}
const sourceRepo = await repoService.getRepository(
sourceOrgSlug,
sourceRepoSlug
);
if (sourceRepo == null) {
return reply.status(404).callNotFound();
}
const targetParentOrg = await organizationService.getOrganizationBySlug(
targetOrgSlug
);
if (targetParentOrg == null) {
return reply.status(404).callNotFound();
}
const availableParentOrgs = await usersService.getUserOrganizations(
request.session.data.curr_user_uid
);
if (validationError != null) {
const { message: errorMessage } = validationError;
return reqHandler<RepositoryForkViewProps>(RepositoryForkView.name, {
availableParentOrgs,
sourceParentOrg,
sourceRepo,
errorMessage,
initialValues:
body as AppRoutesParams[AppRoute.REPOSITORY_FORK_ACTION]["body"],
});
}
try {
const newRepo = await repoService.forkRepository({
source: {
parentOrg: sourceParentOrg,
parentOrgRepositoriesDir: resolve(
join(Env.GIT_REPOSITORIES_ROOT, sourceParentOrg.slug)
),
repository: sourceRepo,
},
target: {
parentOrg: targetParentOrg,
parentOrgRepositoriesDir: resolve(
join(Env.GIT_REPOSITORIES_ROOT, targetParentOrg.slug)
),
repoSlug: targetRepoSlug,
repoData: {
displayName: targetRepoDisplayName,
visibility: targetRepoVisibility,
},
},
});
reply.redirect(302, `/${targetParentOrg.slug}/${newRepo.slug}`);
return reply;
} catch (err) {
return reqHandler<RepositoryForkViewProps>(RepositoryForkView.name, {
availableParentOrgs,
sourceParentOrg,
sourceRepo,
errorMessage: (err as Error).message,
initialValues:
body as AppRoutesParams[AppRoute.REPOSITORY_FORK_ACTION]["body"],
});
}
};
export default postRepositoryForkAction;