.ts
TypeScript
(application/typescript)
// std
import { join, resolve } from "node:path";
// 1st-party
import type { ServiceMethodFactory } from "@ethicdevs/react-monolith";
import { GitServer } from "@ethicdevs/fastify-git-server";
// app
import type { GitServerServiceDeps } from "./types";
import { Env } from "../../env";

const makeRepositoryResolver: ServiceMethodFactory<
  GitServerServiceDeps,
  [string],
  PromiseLike<GitServer.RepositoryResolverResult>
> = ({ request }) => {
  return async (repoPath) => {
    const [orgSlug, repoSlug] = repoPath.split("/");

    const org = await request.prisma.organization.findUnique({
      where: {
        slug: orgSlug,
      },
    });

    if (org == null) {
      throw new Error(`Unknown organization "${org}".`);
    }

    const repo = await request.prisma.repository.findFirst({
      include: {
        organization: true,
      },
      where: {
        slug: repoSlug,
        organization: {
          slug: orgSlug,
        },
      },
    });

    if (repo == null) {
      throw new Error(
        `Unknown repository "${repo}" in (known) organization "${org}".`
      );
    }

    // /!\ Notice how it use db's data instead of user's input to build path.
    const gitRepositoryDir = resolve(
      join(Env.GIT_REPOSITORIES_ROOT, org.slug, repo.slug)
    );

    return {
      authMode: GitServer.AuthMode.ALWAYS,
      gitRepositoryDir,
    };
  };
};

export default makeRepositoryResolver;