import type { ReqHandler } from "@ethicdevs/react-monolith";
import { ResourceVisibility, User } 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 RepositoryPullRequestDetailsView, {
RepositoryPullRequestDetailsViewProps,
} from "../../views/repositoryPullRequests/RepositoryPullRequestDetailsView";
const getRepositoryPullRequestDetailsView: ReqHandler = async (
request,
reply
) => {
const { orgSlug, repoSlug, pullUid } =
request.params as AppRouteParams[AppRoute.REPOSITORY_PULL_REQUEST_DETAILS]["params"];
const orgService = makeOrganizationService({ request });
const prService = makePullRequestService({ request });
const repoService = makeRepositoryService({ request });
const usersService = makeUsersService({ request });
const pullRequest = await prService.getPullRequestByUid(
orgSlug,
repoSlug,
pullUid
);
if (pullRequest == null) {
return reply.status(404).callNotFound();
}
let pullRequestAuthor = await usersService.getUserById(pullRequest.authorId);
if (pullRequestAuthor == null) {
pullRequestAuthor = {
createdAt: new Date(0),
updatedAt: new Date(0),
avatarUri: "",
id: "ghost",
username: "ghost",
displayName: "Ghost",
email: "ghost@gitfoss.io",
hashedPassword: "ghostpassword",
role: "GUEST",
} as User;
}
const currentUser =
request.session.data.authenticated &&
request.session.data.curr_user_uid != null
? await usersService.getUserById(request.session.data.curr_user_uid)
: null;
const sourceRepo = await repoService.getRepositoryById(
pullRequest.sourceRepositoryId
);
const targetRepo = await repoService.getRepositoryById(
pullRequest.targetRepositoryId
);
if (sourceRepo == null || targetRepo == null) {
return reply.status(404).callNotFound();
}
const sourceParentOrg = await orgService.getOrganizationById(
sourceRepo.organizationId
);
const targetParentOrg = await orgService.getOrganizationById(
targetRepo.organizationId
);
if (sourceParentOrg == null || targetParentOrg == 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();
}
}
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();
}
}
const commitLogs = await repoService.getRepositoryCommitLog(
sourceRepo,
"",
pullRequest.sourceBranch,
true
);
const lastCommit = commitLogs.length >= 1 ? commitLogs[0] : null;
let filesDiffs = [] as RepositoryFileDiff[];
if (sourceParentOrg.slug === targetParentOrg.slug) {
filesDiffs = await repoService.getRepositoryRefDiff(
sourceRepo,
pullRequest.targetBranch,
pullRequest.sourceBranch
);
} else {
filesDiffs = await repoService.getRepositoryRemoteRefDiff(
sourceRepo,
pullRequest.sourceBranch,
targetRepo,
pullRequest.targetBranch
);
}
const reqHandler = reply.makeRequestHandler(request, reply);
return reqHandler<RepositoryPullRequestDetailsViewProps>(
RepositoryPullRequestDetailsView.name,
{
filesDiffs,
lastCommit,
pullRequest,
pullRequestAuthor,
sourceParentOrg,
sourceRepo,
targetParentOrg,
targetRepo,
isCurrentUserAllowedToMerge: true,
}
);
};
export default getRepositoryPullRequestDetailsView;