import type { ReqHandler } from "@ethicdevs/react-monolith";
import { ResourceVisibility } from "@prisma/client";
import { AppRoute, AppRoutesParams } from "../../routes";
import { Const } from "../../const";
import { makeOrganizationService } from "../../services/organization";
import { makeRepositoryService } from "../../services/repository";
import { makeUsersService } from "../../services/user";
import RepositoryBrowserView, {
RepositoryBrowserViewProps,
} from "../../views/repository/RepositoryBrowserView";
import RepositoryDetailsView, {
RepositoryDetailsViewProps,
} from "../../views/repository/RepositoryDetailsView";
const getRepositoryBrowserView: ReqHandler = async (request, reply) => {
const params =
request.params as AppRoutesParams[AppRoute.REPOSITORY_BROWSER]["params"];
const { orgSlug, repoSlug, currentRef: currRef } = params;
const path = params["*"];
const currentRef = currRef || Const.DEFAULT_HEAD_REF;
const orgService = makeOrganizationService({ 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 parentOrg = await orgService.getOrganizationBySlug(orgSlug);
const repo = await repoService.getRepository(orgSlug, repoSlug);
if (parentOrg == null || repo == null) {
return reply.status(404).callNotFound();
}
if (repo.visibility === ResourceVisibility.PRIVATE) {
if (currentUser == null) {
return reply.status(404).callNotFound();
} else if (
(await repoService.canUserAccessRepository(currentUser, repo)) === false
) {
return reply.status(404).callNotFound();
}
}
const commitLogs = await repoService.getRepositoryCommitLog(
repo,
path,
currentRef,
true
);
const lastCommit = commitLogs.length >= 1 ? commitLogs[0] : null;
const reqHandler = reply.makeRequestHandler(request, reply);
if (path === "" || path.endsWith("/")) {
const readmeFiles = await repoService.isFileInRepositoryPath(
repo,
path,
Const.README_FILE_NAMES,
currentRef === Const.PRIMARY_BRANCH_REF
? Const.DEFAULT_HEAD_REF
: currentRef
);
const readmeFileContent =
readmeFiles.length >= 1
? await repoService.getRepositoryFileContent(
repo,
`${path}${readmeFiles[0]}`,
currentRef === Const.PRIMARY_BRANCH_REF
? Const.DEFAULT_HEAD_REF
: currentRef
)
: null;
const branches = await repoService.getRepositoryBranches(repo);
const tags = await repoService.getRepositoryTags(repo);
return reqHandler<RepositoryDetailsViewProps>(RepositoryDetailsView.name, {
branches,
currentRef,
currentUser,
cloneUrl: {
http: await repoService.getRepositoryHTTPCloneUrl(repo),
ssh: await repoService.getRepositorySSHCloneUrl(repo),
},
lastCommit,
parentOrg,
path,
readmeFileContent,
repo,
repoHead: await repoService.getRepositoryHead(repo, currentRef),
repoFiles: await repoService.getRepositoryFiles(repo, path, currentRef),
tags,
});
}
let linguistInfos = await request.codeAnalysisService.getLinguistFileInfos(
path
);
let fileContent =
linguistInfos.type === "image"
? await repoService.getRepositoryFileContentBase64(repo, path, currentRef)
: await repoService.getRepositoryFileContent(repo, path, currentRef);
if (fileContent == null) {
return reply.status(404).callNotFound();
}
linguistInfos = await request.codeAnalysisService.getLinguistFileInfos(
path,
fileContent.content
);
return reqHandler<RepositoryBrowserViewProps>(RepositoryBrowserView.name, {
currentRef,
currentUser,
fileContent,
lastCommit,
linguistInfos,
parentOrg,
path,
repo,
});
};
export default getRepositoryBrowserView;