GitFOSS
~app/server.ts
.ts
TypeScript
(application/typescript)
// std
import { join, resolve } from "node:path";
// 3rd-party
import { InMemoryCacheAdapter } from "@ethicdevs/fastify-stream-react-views";
import {
  AppServer,
  makeAppServer,
  startAppServer,
  stopAppServerAndExit,
} from "@ethicdevs/react-monolith";
import cuid from "cuid";
import fastifyCookie, { CookieSerializeOptions } from "@fastify/cookie";
import fastifyCustomSession, {
  PrismaSessionAdapter,
} from "@ethicdevs/fastify-custom-session";
import fastifyFormBody from "@fastify/formbody";
import fastifyGitServer, { GitServer } from "@ethicdevs/fastify-git-server";
import fastifyServeStatic from "fastify-static";
// generated via script[generate:prisma]
import { PrismaClient } from "@prisma/client";
// app root
import * as Paths from "../paths";
import { version as appVersion } from "../package.json";
// app
import { Const } from "./const";
import { Env } from "./env";
import { prismaPlugin } from "./plugins";
import {
  getEnv,
  localAppDomainPreHandler,
  makeRequestHandler,
} from "./utils/server";

const HOST = process.env.HOST || "localhost";
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 prisma = new PrismaClient();

  const depsBaseUrl = `/${Paths.PUBLIC_FOLDER_NAME}/${Paths.ASSET_DEPS_FOLDER_NAME}`;
  const publicBaseUrl = `/${Paths.PUBLIC_FOLDER_NAME}`;

  const cookiesOpts: CookieSerializeOptions = {
    domain: `.${Env.DEPLOYMENT_DOMAIN}`,
    httpOnly: true,
    path: "/",
    secure: false,
    sameSite: "lax",
    signed: true,
  };

  server = await makeAppServer(HOST, PORT, {
    appName: Const.APP_NAME,
    appVersion,
    env,
    a11y: {
      localeDirection: "ltr",
    },
    assets: {
      depsFolder: Paths.ASSET_DEPS_FOLDER_NAME,
      importPrefix: publicBaseUrl,
    },
    cacheAdapter: new InMemoryCacheAdapter({
      maxSize: Const.SSR_CACHE_MAX_SIZE_BYTES,
    }),
    featureFlags: {
      withIncrementalBuild: true,
      withImportsMap: true,
      withInstantRouter: true,
      withStyledSSR: true,
      withTreeShaking: true,
    },
    paths: {
      assetsOutFolder: Paths.PUBLIC_FOLDER,
      distFolder: Paths.DIST_FOLDER,
      islandsFolder: Paths.ISLANDS_FOLDER,
      rootFolder: Paths.ROOT_FOLDER,
      routesFile: Paths.ROUTES_FILE,
      viewsFolder: Paths.VIEWS_FOLDER,
    },
    externalDependencies: {
      "cross-fetch": "CrossFetch",
      "markdown-to-jsx": "MarkdownToJSX",
    },
    baseHeadTags: [
      {
        kind: "meta",
        name: "og:site_name",
        content: Const.APP_NAME,
      },
    ],
    baseScriptTags: [
      {
        async: true,
        id: "es-importmap-shim",
        src: `${depsBaseUrl}/es-module-shims.production.min.js`,
        type: "application/javascript",
      },
      /*{
        async: true,
        defer: false,
        id: "importmap-service-worker-register",
        src: `/register-imsw.js`,
        type: "module",
      },*/
    ],
    setupServerBeforeRoutes(s) {
      s.addHook("preHandler", localAppDomainPreHandler);

      s.register(prismaPlugin, { prisma });

      s.register(fastifyFormBody);

      s.register(fastifyServeStatic, {
        root: Paths.PUBLIC_FOLDER,
        prefix: publicBaseUrl,
      });

      s.register(fastifyCookie, {
        secret: Env.COOKIE_SECRET,
        parseOptions: cookiesOpts,
      });

      // register the session plugin + prisma session store adapter
      s.register(fastifyCustomSession, {
        cookieName: Env.COOKIE_NAME,
        cookieOptions: cookiesOpts,
        getUniqId: cuid as () => string,
        password: Env.COOKIE_SECRET,
        storeAdapter: new PrismaSessionAdapter(prisma) as any,
        ttl: Const.SESSION_TTL_SECONDS,
        initialSession: {
          sessionId: null,
          authenticated: false,
          curr_user_avatar_uri: null,
          curr_user_uid: null,
          curr_user_username: null,
          curr_user_role: "GUEST",
          flash_message: null,
          flash_message_shown_once: false,
          two_factor_lock: false,
          two_factor_complete: false,
        },
      });

      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();
        },
      });

      s.decorateReply("makeRequestHandler", makeRequestHandler);

      s.get("/interceptor-imsw.js", {}, async (_, reply) => {
        return reply.sendFile("interceptor-imsw.js");
      });

      s.get("/register-imsw.js", {}, async (_, reply) => {
        return reply.sendFile("register-imsw.js");
      });
    },
  });

  await startAppServer(server);

  return server;
}

// Catch errors that are fatal
["unhandledRejection", "uncaughtException"].forEach((exception) => {
  process.on(exception, async (reason: Error) => {
    await stopAppServerAndExit(server, reason);
  });
});

// Catch standard linux signals to kill a daemon
["SIGQUIT", "SIGTERM", "SIGINT"].forEach((killSignal) => {
  process.on(killSignal, async () => {
    await stopAppServerAndExit(server);
  });
});

// Start the application server
main()
  .then((server) => {
    // safe because it wont start if null
    const { $config, $host, $port } = server.reactMonolith!;
    console.log(
      `[🚀][${$config.env}] App Server ready at http://${$host}:${$port} !`
    );
  })
  .catch(async (err) => {
    const error = err as Error;
    console.error(`[❌] Cannot start App Server. Error: ${error.message}`);
    await stopAppServerAndExit(null, error);
  });

~app/server.ts
.ts
TypeScript
(application/typescript)
// std
import { join, resolve } from "node:path";
// 3rd-party
import { InMemoryCacheAdapter } from "@ethicdevs/fastify-stream-react-views";
import {
  AppServer,
  makeAppServer,
  startAppServer,
  stopAppServerAndExit,
} from "@ethicdevs/react-monolith";
import cuid from "cuid";
import fastifyCookie, { CookieSerializeOptions } from "@fastify/cookie";
import fastifyCustomSession, {
  PrismaSessionAdapter,
} from "@ethicdevs/fastify-custom-session";
import fastifyFormBody from "@fastify/formbody";
import fastifyGitServer, { GitServer } from "@ethicdevs/fastify-git-server";
import fastifyServeStatic from "fastify-static";
// generated via script[generate:prisma]
import { PrismaClient } from "@prisma/client";
// app root
import * as Paths from "../paths";
import { version as appVersion } from "../package.json";
// app
import { Const } from "./const";
import { Env } from "./env";
import { prismaPlugin } from "./plugins";
import {
  getEnv,
  localAppDomainPreHandler,
  makeRequestHandler,
} from "./utils/server";

const HOST = process.env.HOST || "localhost";
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 prisma = new PrismaClient();

  const depsBaseUrl = `/${Paths.PUBLIC_FOLDER_NAME}/${Paths.ASSET_DEPS_FOLDER_NAME}`;
  const publicBaseUrl = `/${Paths.PUBLIC_FOLDER_NAME}`;

  const cookiesOpts: CookieSerializeOptions = {
    domain: `.${Env.DEPLOYMENT_DOMAIN}`,
    httpOnly: true,
    path: "/",
    secure: false,
    sameSite: "lax",
    signed: true,
  };

  server = await makeAppServer(HOST, PORT, {
    appName: Const.APP_NAME,
    appVersion,
    env,
    a11y: {
      localeDirection: "ltr",
    },
    assets: {
      depsFolder: Paths.ASSET_DEPS_FOLDER_NAME,
      importPrefix: publicBaseUrl,
    },
    cacheAdapter: new InMemoryCacheAdapter({
      maxSize: Const.SSR_CACHE_MAX_SIZE_BYTES,
    }),
    featureFlags: {
      withIncrementalBuild: true,
      withImportsMap: true,
      withInstantRouter: true,
      withStyledSSR: true,
      withTreeShaking: true,
    },
    paths: {
      assetsOutFolder: Paths.PUBLIC_FOLDER,
      distFolder: Paths.DIST_FOLDER,
      islandsFolder: Paths.ISLANDS_FOLDER,
      rootFolder: Paths.ROOT_FOLDER,
      routesFile: Paths.ROUTES_FILE,
      viewsFolder: Paths.VIEWS_FOLDER,
    },
    externalDependencies: {
      "cross-fetch": "CrossFetch",
      "markdown-to-jsx": "MarkdownToJSX",
    },
    baseHeadTags: [
      {
        kind: "meta",
        name: "og:site_name",
        content: Const.APP_NAME,
      },
    ],
    baseScriptTags: [
      {
        async: true,
        id: "es-importmap-shim",
        src: `${depsBaseUrl}/es-module-shims.production.min.js`,
        type: "application/javascript",
      },
      /*{
        async: true,
        defer: false,
        id: "importmap-service-worker-register",
        src: `/register-imsw.js`,
        type: "module",
      },*/
    ],
    setupServerBeforeRoutes(s) {
      s.addHook("preHandler", localAppDomainPreHandler);

      s.register(prismaPlugin, { prisma });

      s.register(fastifyFormBody);

      s.register(fastifyServeStatic, {
        root: Paths.PUBLIC_FOLDER,
        prefix: publicBaseUrl,
      });

      s.register(fastifyCookie, {
        secret: Env.COOKIE_SECRET,
        parseOptions: cookiesOpts,
      });

      // register the session plugin + prisma session store adapter
      s.register(fastifyCustomSession, {
        cookieName: Env.COOKIE_NAME,
        cookieOptions: cookiesOpts,
        getUniqId: cuid as () => string,
        password: Env.COOKIE_SECRET,
        storeAdapter: new PrismaSessionAdapter(prisma) as any,
        ttl: Const.SESSION_TTL_SECONDS,
        initialSession: {
          sessionId: null,
          authenticated: false,
          curr_user_avatar_uri: null,
          curr_user_uid: null,
          curr_user_username: null,
          curr_user_role: "GUEST",
          flash_message: null,
          flash_message_shown_once: false,
          two_factor_lock: false,
          two_factor_complete: false,
        },
      });

      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();
        },
      });

      s.decorateReply("makeRequestHandler", makeRequestHandler);

      s.get("/interceptor-imsw.js", {}, async (_, reply) => {
        return reply.sendFile("interceptor-imsw.js");
      });

      s.get("/register-imsw.js", {}, async (_, reply) => {
        return reply.sendFile("register-imsw.js");
      });
    },
  });

  await startAppServer(server);

  return server;
}

// Catch errors that are fatal
["unhandledRejection", "uncaughtException"].forEach((exception) => {
  process.on(exception, async (reason: Error) => {
    await stopAppServerAndExit(server, reason);
  });
});

// Catch standard linux signals to kill a daemon
["SIGQUIT", "SIGTERM", "SIGINT"].forEach((killSignal) => {
  process.on(killSignal, async () => {
    await stopAppServerAndExit(server);
  });
});

// Start the application server
main()
  .then((server) => {
    // safe because it wont start if null
    const { $config, $host, $port } = server.reactMonolith!;
    console.log(
      `[🚀][${$config.env}] App Server ready at http://${$host}:${$port} !`
    );
  })
  .catch(async (err) => {
    const error = err as Error;
    console.error(`[❌] Cannot start App Server. Error: ${error.message}`);
    await stopAppServerAndExit(null, error);
  });

GitFOSS • v0.2.0 (#421408f) • MIT License