feat(repository): add a "createRepository" service method in "repository" service
+ 105
- 6
new file
app/services/repository/createRepository.ts
@@ -0,0 +1,74 @@
+// 1st-party
+import type { ServiceMethodFactory } from "@ethicdevs/react-monolith";
+// generated via script[generate:prisma]
+import type { Repository } from "@prisma/client";
+// service
+import type { CreateRepositoryDTO, RepositoryServiceDeps } from "./types";
+
+const makeCreateRepository: ServiceMethodFactory<
+  RepositoryServiceDeps,
+  [CreateRepositoryDTO],
+  Promise<Repository>
+> = ({ request }) => {
+  return async ({ parentOrgSlug, repoSlug, repoData, repoInitFlags }) => {
+    const {
+      gitRepositoryDir,
+      withBaseReadmeFile: _,
+      withLicenseFile: __,
+    } = repoInitFlags;
+
+    const parentOrg = await request.prisma.organization.findUnique({
+      where: {
+        slug: parentOrgSlug,
+      },
+    });
+
+    if (parentOrg == null) {
+      throw new Error(
+        `Could not find the parent organization to create new repository in.`
+      );
+    }
+
+    console.log(
+      `[..] creating repository "${parentOrg.slug}/${repoSlug}" in database`
+    );
+
+    const newRepo = await request.prisma.repository.create({
+      data: {
+        ...repoData,
+        organizationId: parentOrg.id,
+        slug: repoSlug,
+      },
+    });
+
+    console.log(
+      `[ok] created repository in database with id "${newRepo.id}" and slug "${parentOrg.slug}/${newRepo.slug}"!`
+    );
+
+    console.log(
+      `[..] creating repository folder with "git init --bare --shared=group"`
+    );
+
+    const gitInitBareRepoProcess = request.spawnGitCommand(
+      ["init --bare --shared=group"],
+      gitRepositoryDir
+    );
+
+    const gitInitBareRepoResult = await new Promise<string>((resolve) => {
+      let buffer = [] as string[];
+      gitInitBareRepoProcess.stdout.on("data", (chunk) => buffer.push(chunk));
+      gitInitBareRepoProcess.stdout.on("close", () => {
+        resolve(buffer.join(""));
+      });
+    });
+
+    console.log(
+      `[ok] finished execution of "git init --bare --shared=group" with result:\n\t`,
+      gitInitBareRepoResult
+    );
+
+    return newRepo;
+  };
+};
+
+export default makeCreateRepository;

app/services/repository/types.ts
@@ -1,3 +1,5 @@
+// std
+import { PathLike } from "node:fs";
 // 1st-party
 import type { ServiceApiContract } from "@ethicdevs/react-monolith";
 // 3rd-party

...
@@ -5,10 +7,29 @@ import type { FastifyRequest } from "fastify";
 // generated via script[generate:prisma]
 import type { Repository } from "@prisma/client";
 
+export interface CreateRepositoryDTO {
+  parentOrgSlug: string;
+  repoSlug: string;
+  repoData: Omit<
+    Repository,
+    "id" | "slug" | "createdAt" | "updatedAt" | "organizationId"
+  >;
+  repoInitFlags: {
+    gitRepositoryDir: PathLike;
+    withBaseReadmeFile: boolean;
+    withLicenseFile: string;
+  };
+}
+
 export interface RepositoryServiceAPI extends ServiceApiContract {
+  createRepository(
+    parentOrgSlug: string,
+    repoSlug: string,
+    repoData: Repository
+  ): Promise<Repository>;
   getRepositoryExploreCollection(): Promise<Repository[]>;
-  getHttpCloneUrl(): Promise<string>;
-  getSshCloneUrl(): Promise<string>;
+  getHttpCloneUrl(repository: Repository): Promise<string>;
+  getSshCloneUrl(repository: Repository): Promise<string>;
 }
 
 export interface RepositoryServiceDeps {

@@ -28,7 +28,7 @@
   },
   "dependencies": {
     "@ethicdevs/fastify-custom-session": "^0.6.0",
-    "@ethicdevs/fastify-git-server": "^1.4.3",
+    "@ethicdevs/fastify-git-server": "^1.5.0",
     "@ethicdevs/fastify-stream-react-views": "^1.9.9",
     "@ethicdevs/react-monolith": "^1.6.1",
     "@fastify/cookie": "6.0.0",

types/global/index.d.ts
@@ -1,3 +1,5 @@
+// 1st-party
+import { GitServer } from "@ethicdevs/fastify-git-server";
 // 3rd-party
 import fastify from "fastify";
 // generated via script[generate:prisma]

...
@@ -22,6 +24,8 @@ declare module "fastify" {
     prisma: PrismaClient;
   }
   interface FastifyRequest {
+    // from git server plugin
+    spawnGitCommand: GitServer.SpawnGitCommandDecorator;
     // from crypto plugin
     cryptoService: CryptoServiceAPI;
     // from prisma plugin

@@ -303,9 +303,9 @@
     pg "^8.7.3"
     pg-pool "^3.5.1"
 
-"@ethicdevs/fastify-git-server@^1.4.3":
-  version "1.4.3"
-  resolved "https://registry.yarnpkg.com/@ethicdevs/fastify-git-server/-/fastify-git-server-1.4.3.tgz#c415827f265266896df413797dd8f1172b2d982a"
+"@ethicdevs/fastify-git-server@^1.5.0":
+  version "1.5.0"
+  resolved "https://registry.yarnpkg.com/@ethicdevs/fastify-git-server/-/fastify-git-server-1.5.0.tgz#9429d01c96e4d06ec0f3579dcdc62ec646bbef72"
   dependencies:
     debug "^4.3.4"
     fastify-plugin "^3.0.1"