.ts
TypeScript
(application/typescript)
// 1st-party
import type { ReqHandler } from "@ethicdevs/react-monolith";
// app
import { AppRoute, AppRouteParams } from "../../routes.defs";
import { Const } from "../../const";
// app services
import { makeOrganizationService } from "../../services/organization";
import { makeRepositoryService } from "../../services/repository";
import { makeUsersService } from "../../services/user";
// app views
import RepositoryDetailsView, {
  RepositoryDetailsViewProps,
} from "../../views/repository/RepositoryDetailsView";
import {
  Organization,
  OrganizationMembership,
  ResourceVisibility,
} from "@prisma/client";

const getRepositoryDetailsView: ReqHandler = async (request, reply) => {
  const { orgSlug, repoSlug } =
    request.params as AppRouteParams[AppRoute.REPOSITORY_DETAILS]["params"];

  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 path = "/";
  const currentRef = Const.DEFAULT_HEAD_REF;

  const parentOrg = (await orgService.getOrganizationBySlug(orgSlug, {
    memberships: true,
  })) as Organization & {
    memberships: OrganizationMembership[];
  };
  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 readmeFiles = await repoService.isFileInRepositoryPath(
    repo,
    "",
    Const.README_FILE_NAMES
  );

  const readmeFileContent =
    readmeFiles.length >= 1
      ? await repoService.getRepositoryFileContent(repo, readmeFiles[0])
      : null;

  const commitLogs = await repoService.getRepositoryCommitLog(
    repo,
    "",
    currentRef,
    true
  );

  const lastCommit = commitLogs.length >= 1 ? commitLogs[0] : null;

  const branches = await repoService.getRepositoryBranches(repo);
  const tags = await repoService.getRepositoryTags(repo);

  const cloneUrl = {
    http: await repoService.getRepositoryHTTPCloneUrl(repo),
    ssh: await repoService.getRepositorySSHCloneUrl(repo),
  };

  const reqHandler = reply.makeRequestHandler(request, reply);
  const props = {
    branches,
    currentRef,
    currentUser,
    cloneUrl,
    lastCommit,
    parentOrg,
    path,
    readmeFileContent,
    repo,
    repoHead: null,
    repoFiles: [],
    tags,
  } as Omit<RepositoryDetailsViewProps, "commonProps">;

  try {
    props.repoHead = await repoService.getRepositoryHead(repo, currentRef);
  } catch (err) {
    const error = err as Error;
    if (error.message.includes(`${currentRef} is not a valid object name`)) {
      return reqHandler<RepositoryDetailsViewProps>(
        RepositoryDetailsView.name,
        props
      );
    } else if (
      error.message.includes("Could not find a valid git repository")
    ) {
      return reply.status(404).callNotFound();
    } else {
      console.log(`Could not get repo head. Error: ${error.message}`);
    }
  }

  try {
    props.repoFiles = await repoService.getRepositoryFiles(
      repo,
      "",
      currentRef
    );
  } catch (err) {
    console.log(`Could not get repo files. Error: ${(err as Error).message}`);
  }

  return reqHandler<RepositoryDetailsViewProps>(
    RepositoryDetailsView.name,
    props
  );
};

export default getRepositoryDetailsView;