refactor(server): make server file back to clarity, move git server logic into own service folder@@ -1,5 +1,3 @@
-// std
-import { join, resolve } from "node:path";
// 3rd-party
import { InMemoryCacheAdapter } from "@ethicdevs/fastify-stream-react-views";
import {
@@ -14,7 +12,7 @@ import fastifyCustomSession, {
PrismaSessionAdapter,
} from "@ethicdevs/fastify-custom-session";
import fastifyFormBody from "@fastify/formbody";
-import fastifyGitServer, { GitServer } from "@ethicdevs/fastify-git-server";
+import fastifyGitServer from "@ethicdevs/fastify-git-server";
import fastifyServeStatic from "fastify-static";
// generated via script[generate:prisma]
import { PrismaClient } from "@prisma/client";
@@ -25,6 +23,7 @@ import { version as appVersion } from "../package.json";
import { Const } from "./const";
import { Env } from "./env";
import { cryptoPlugin, prismaPlugin } from "./plugins";
+import { makeGitServerService } from "./services/gitServer";
import {
getEnv,
localAppDomainPreHandler,
@@ -36,26 +35,9 @@ const PORT = process.env.PORT || 4100;
let server: null | AppServer = null;
-const ORGS_REPOS: Record<
- string,
- Record<
- string,
- { username: string; password: string; gitRepositoryDir: string }
- >
-> = {
- wnemencha: {
- "react-monolith-samples": {
- username: "wnemencha",
- password: "secret",
- gitRepositoryDir: resolve(
- join(Env.GIT_REPOSITORIES_ROOT, "wnemencha", "react-monolith-samples")
- ),
- },
- },
-};
-
async function main(): Promise<AppServer> {
const env = getEnv();
+ const gitService = makeGitServerService({});
const prisma = new PrismaClient();
const depsBaseUrl = `/${Paths.PUBLIC_FOLDER_NAME}/${Paths.ASSET_DEPS_FOLDER_NAME}`;
@@ -169,70 +151,9 @@ async function main(): Promise<AppServer> {
s.register(fastifyGitServer, {
withSideBandMessages: true,
- async authorizationResolver(repoSlug, { username, password }) {
- const [org, repo] = repoSlug.split("/");
- if (
- org == null ||
- org in ORGS_REPOS === false ||
- ORGS_REPOS[org] == null
- ) {
- throw new Error(`Unknown organization "${org}".`);
- }
- if (
- repo == null ||
- repo in ORGS_REPOS[org] === false ||
- ORGS_REPOS[org][repo] == null
- ) {
- throw new Error(
- `Unknown repository "${repo}" in (known) organization "${org}".`
- );
- }
- const orgRepo = ORGS_REPOS[org][repo];
- return username === orgRepo.username && password === orgRepo.password;
- },
- async repositoryResolver(repoSlug) {
- const [org, repo] = repoSlug.split("/");
- if (
- org == null ||
- org in ORGS_REPOS === false ||
- ORGS_REPOS[org] == null
- ) {
- throw new Error(`Unknown organization "${org}".`);
- }
- if (
- repo == null ||
- repo in ORGS_REPOS[org] === false ||
- ORGS_REPOS[org][repo] == null
- ) {
- throw new Error(
- `Unknown repository "${repo}" in (known) organization "${org}".`
- );
- }
- const orgRepo = ORGS_REPOS[org][repo];
- return {
- authMode: GitServer.AuthMode.ALWAYS,
- gitRepositoryDir: orgRepo.gitRepositoryDir,
- };
- },
- onPush({ data, message }) {
- message.write("\n");
- if (data.packType === GitServer.PackType.RECEIVE) {
- // client has done something like "git push"
- // it is uploading, we are receiving
- console.log("receive-pack");
- message.write("🖖 See the details of your push at:\n");
- message.write(
- `🧲 ${Env.DEPLOYMENT_SCHEME}://${Env.DEPLOYMENT_DOMAIN}:${PORT}/${data.repoSlug}/commits/some_commit_hash\n`
- );
- } else if (data.packType === GitServer.PackType.UPLOAD) {
- // client has done something like "git clone"
- // it is receiving, we are uploading
- console.log("upload-pack");
- message.write(`🖖 Welcome at GitFOSS ${data.username}!\n`);
- }
- message.write("\n");
- message.accept();
- },
+ authorizationResolver: gitService.authorizationResolver,
+ repositoryResolver: gitService.repositoryResolver,
+ onPush: gitService.onPushEvent,
});
s.get("/interceptor-imsw.js", {}, async (_, reply) => {
@@ -0,0 +1,32 @@
+// 1st-party
+import type { ServiceMethodFactory } from "@ethicdevs/react-monolith";
+import { GitServer } from "@ethicdevs/fastify-git-server";
+// app
+import { GitServerServiceDeps } from "./types";
+import { ORGS_REPOS } from "./temp_mock";
+
+const makeAuthorizationResolver: ServiceMethodFactory<
+ GitServerServiceDeps,
+ [string, GitServer.AuthCredentials],
+ PromiseLike<boolean>
+> = (_) => {
+ return async (repoSlug, { username, password }) => {
+ const [org, repo] = repoSlug.split("/");
+ if (org == null || org in ORGS_REPOS === false || ORGS_REPOS[org] == null) {
+ throw new Error(`Unknown organization "${org}".`);
+ }
+ if (
+ repo == null ||
+ repo in ORGS_REPOS[org] === false ||
+ ORGS_REPOS[org][repo] == null
+ ) {
+ throw new Error(
+ `Unknown repository "${repo}" in (known) organization "${org}".`
+ );
+ }
+ const orgRepo = ORGS_REPOS[org][repo];
+ return username === orgRepo.username && password === orgRepo.password;
+ };
+};
+
+export default makeAuthorizationResolver;
@@ -0,0 +1,17 @@
+// 1st-party
+import { makeService } from "@ethicdevs/react-monolith";
+// app
+import { GitServerServiceAPI, GitServerServiceDeps } from "./types";
+// service methods
+import { default as makeAuthorizationResolver } from "./authorizationResolver";
+import { default as makeRepositoryResolver } from "./repositoryResolver";
+import { default as makeOnPushEvent } from "./onPushEvent";
+
+export const makeGitServerService = makeService<
+ GitServerServiceAPI,
+ GitServerServiceDeps
+>({
+ authorizationResolver: makeAuthorizationResolver,
+ repositoryResolver: makeRepositoryResolver,
+ onPushEvent: makeOnPushEvent,
+});
@@ -0,0 +1,34 @@
+// 1st-party
+import type { ServiceMethodFactory } from "@ethicdevs/react-monolith";
+import { GitServer } from "@ethicdevs/fastify-git-server";
+// app
+import { Env } from "../../env";
+import { GitServerServiceDeps } from "./types";
+
+const makeOnPushEvent: ServiceMethodFactory<
+ GitServerServiceDeps,
+ [GitServer.Event],
+ void
+> = (_) => {
+ return ({ data, message }) => {
+ message.write("\n");
+ if (data.packType === GitServer.PackType.RECEIVE) {
+ // client has done something like "git push"
+ // it is uploading, we are receiving
+ console.log("receive-pack");
+ message.write("🖖 See the details of your push at:\n");
+ message.write(
+ `🧲 ${Env.DEPLOYMENT_SCHEME}://${Env.DEPLOYMENT_DOMAIN}/${data.repoSlug}/commits/some_commit_hash\n`
+ );
+ } else if (data.packType === GitServer.PackType.UPLOAD) {
+ // client has done something like "git clone"
+ // it is receiving, we are uploading
+ console.log("upload-pack");
+ message.write(`🖖 Welcome at GitFOSS ${data.username}!\n`);
+ }
+ message.write("\n");
+ message.accept();
+ };
+};
+
+export default makeOnPushEvent;
@@ -0,0 +1,35 @@
+// 1st-party
+import type { ServiceMethodFactory } from "@ethicdevs/react-monolith";
+import { GitServer } from "@ethicdevs/fastify-git-server";
+// app
+import { GitServerServiceDeps } from "./types";
+import { ORGS_REPOS } from "./temp_mock";
+
+const makeRepositoryResolver: ServiceMethodFactory<
+ GitServerServiceDeps,
+ [string],
+ PromiseLike<GitServer.RepositoryResolverResult>
+> = (_) => {
+ return async (repoSlug) => {
+ const [org, repo] = repoSlug.split("/");
+ if (org == null || org in ORGS_REPOS === false || ORGS_REPOS[org] == null) {
+ throw new Error(`Unknown organization "${org}".`);
+ }
+ if (
+ repo == null ||
+ repo in ORGS_REPOS[org] === false ||
+ ORGS_REPOS[org][repo] == null
+ ) {
+ throw new Error(
+ `Unknown repository "${repo}" in (known) organization "${org}".`
+ );
+ }
+ const orgRepo = ORGS_REPOS[org][repo];
+ return {
+ authMode: GitServer.AuthMode.ALWAYS,
+ gitRepositoryDir: orgRepo.gitRepositoryDir,
+ };
+ };
+};
+
+export default makeRepositoryResolver;
@@ -0,0 +1,20 @@
+import { join, resolve } from "node:path";
+import { Env } from "../../env";
+
+export const ORGS_REPOS: Record<
+ string,
+ Record<
+ string,
+ { username: string; password: string; gitRepositoryDir: string }
+ >
+> = {
+ wnemencha: {
+ "react-monolith-samples": {
+ username: "wnemencha",
+ password: "secret",
+ gitRepositoryDir: resolve(
+ join(Env.GIT_REPOSITORIES_ROOT, "wnemencha", "react-monolith-samples")
+ ),
+ },
+ },
+};
@@ -0,0 +1,15 @@
+import { GitServer } from "@ethicdevs/fastify-git-server";
+import { ServiceApiContract } from "@ethicdevs/react-monolith";
+
+export interface GitServerServiceAPI extends ServiceApiContract {
+ authorizationResolver(
+ repoSlug: string,
+ credentials: GitServer.AuthCredentials
+ ): PromiseLike<boolean>;
+ repositoryResolver(
+ repoSlug: string
+ ): PromiseLike<GitServer.RepositoryResolverResult>;
+ onPushEvent(event: GitServer.Event): void;
+}
+
+export interface GitServerServiceDeps {}