import type { ReqHandler } from "@ethicdevs/react-monolith";
import { ResourceVisibility } from "@prisma/client";
import type { RepositoryFileDiff } from "../../types";
import { AppRoute, AppRouteParams } from "../../routes.defs";
import { makeOrganizationService } from "../../services/organization";
import { makePullRequestService } from "../../services/pullRequest";
import { makeRepositoryService } from "../../services/repository";
import { makeUsersService } from "../../services/user";
import RepositoryPullRequestsView, {
RepositoryPullRequestsViewProps,
} from "../../views/repositoryPullRequests/RepositoryPullRequestsView";
const postRepositoryPullRequestMergeAction: ReqHandler<
AppRouteParams,
AppRoute.REPOSITORY_PULL_REQUEST_MERGE_ACTION
> = async (request, reply) => {
const { orgSlug, repoSlug, pullUid } = request.params;
const { merge_message, merge_summary } = request.body;
console.log("params:", {
merge_message,
merge_summary,
});
const orgService = makeOrganizationService({ request });
const prService = makePullRequestService({ request });
const repoService = makeRepositoryService({ request });
const usersService = makeUsersService({ request });
const currentUser =
request.session.data.authenticated &&
request.session.data.curr_user_uid != null
? await usersService.getUserById(request.session.data.curr_user_uid)
: null;
const pullRequest = await prService.getPullRequestByUid(
orgSlug,
repoSlug,
pullUid
);
if (pullRequest == null) {
return reply.status(404).callNotFound();
}
const sourceRepo = await repoService.getRepositoryById(
pullRequest.sourceRepositoryId
);
if (sourceRepo == null) {
return reply.status(404).callNotFound();
}
const targetRepo = await repoService.getRepositoryById(
pullRequest.targetRepositoryId
);
if (targetRepo == null) {
return reply.status(404).callNotFound();
}
const sourceParentOrg = await orgService.getOrganizationById(
sourceRepo.organizationId
);
if (sourceParentOrg == null) {
return reply.status(404).callNotFound();
}
if (sourceRepo.visibility === ResourceVisibility.PRIVATE) {
if (currentUser == null) {
return reply.status(404).callNotFound();
} else if (
(await repoService.canUserAccessRepository(currentUser, sourceRepo)) ===
false
) {
return reply.status(404).callNotFound();
}
}
const targetParentOrg = await orgService.getOrganizationById(
targetRepo.organizationId
);
if (targetParentOrg == null) {
return reply.status(404).callNotFound();
}
if (targetRepo.visibility === ResourceVisibility.PRIVATE) {
if (currentUser == null) {
return reply.status(404).callNotFound();
} else if (
(await repoService.canUserAccessRepository(currentUser, targetRepo)) ===
false
) {
return reply.status(404).callNotFound();
}
}
let fileDiffs = [] as RepositoryFileDiff[];
if (sourceParentOrg.slug === targetParentOrg.slug) {
fileDiffs = await repoService.getRepositoryRefDiff(
sourceRepo,
pullRequest.targetBranch,
pullRequest.sourceBranch
);
} else {
fileDiffs = await repoService.getRepositoryRemoteRefDiff(
sourceRepo,
pullRequest.sourceBranch,
targetRepo,
pullRequest.targetBranch
);
}
if (fileDiffs.length <= 0) {
throw new Error("Cannot merge two branches without difference.");
}
const reqHandler = reply.makeRequestHandler(request, reply);
return reqHandler<RepositoryPullRequestsViewProps>(
RepositoryPullRequestsView.name,
{
pullRequest,
}
);
};
export default postRepositoryPullRequestMergeAction;