import type { IRouteParams } from "@ethicdevs/react-monolith";
import { AppRouter, AppRouterGroup, Router } from "@ethicdevs/react-monolith";
import type { FastifySchema } from "fastify";
import React from "react";
import { ResourceVisibility } from "@prisma/client";
import { authenticatedOrLogin, guestOrRedirect } from "./utils/server";
import { AuthController } from "./controllers/auth";
import { RepositoryController } from "./controllers/repository";
import * as HomeController from "./controllers/HomeController";
import * as ThemeController from "./controllers/ThemeController";
export enum AppRoute {
HOME = "home",
SET_THEME = "set_theme.action",
AUTH_REGISTER = "auth.register",
AUTH_REGISTER_ACTION = "auth.register.action",
AUTH_LOGIN = "auth.login",
AUTH_LOGIN_ACTION = "auth.login.action",
AUTH_LOGOUT_ACTION = "auth.logout.action",
USER_DASHBOARD = "user.dashboard",
REPOSITORY_EXPLORE = "repository.explore",
REPOSITORY_COMMITS_LOG = "repository.commits_log",
REPOSITORY_CREATE = "repository.create",
REPOSITORY_CREATE_ACTION = "repository.create.action",
REPOSITORY_DETAILS = "repository.details",
REPOSITORY_BROWSER = "repository.browser",
}
export interface AppRoutesParams extends IRouteParams {
[AppRoute.HOME]: undefined;
[AppRoute.SET_THEME]: {
themeScheme: string;
};
[AppRoute.AUTH_REGISTER]: undefined;
[AppRoute.AUTH_REGISTER_ACTION]: {
body: {
email_address: string;
username: string;
password: string;
};
};
[AppRoute.AUTH_LOGIN]: undefined;
[AppRoute.AUTH_LOGIN_ACTION]: {
body: {
email_address: string;
password: string;
};
};
[AppRoute.AUTH_LOGOUT_ACTION]: undefined;
[AppRoute.USER_DASHBOARD]: undefined;
[AppRoute.REPOSITORY_EXPLORE]: undefined;
[AppRoute.REPOSITORY_COMMITS_LOG]: {
params: {
orgSlug: string;
repoSlug: string;
};
};
[AppRoute.REPOSITORY_CREATE]: undefined;
[AppRoute.REPOSITORY_CREATE_ACTION]: {
body: {
parent_org_slug: string;
repo_display_name: string;
repo_init_license_file: "on" | "off";
repo_init_license_kind: string;
repo_init_readme_file: "on" | "off";
repo_keywords: string;
repo_keywords_add: string;
repo_short_description: string;
repo_slug: string;
repo_visibility: ResourceVisibility;
repo_website_url: string;
};
};
[AppRoute.REPOSITORY_DETAILS]: {
params: {
orgSlug: string;
repoSlug: string;
};
};
[AppRoute.REPOSITORY_BROWSER]: {
params: {
orgSlug: string;
repoSlug: string;
ref: string;
"*": string;
};
};
}
export const AppRoutesSchemas: Record<AppRoute, undefined | FastifySchema> = {
[AppRoute.HOME]: undefined,
[AppRoute.SET_THEME]: {
params: {
type: "object",
required: ["themeScheme"],
additionalProperties: false,
properties: {
themeScheme: {
type: "string",
enum: ["light", "dark"],
},
},
},
},
[AppRoute.AUTH_REGISTER]: undefined,
[AppRoute.AUTH_REGISTER_ACTION]: {
body: {
type: "object",
required: ["email_address", "username", "password"],
additionalProperties: false,
properties: {
email_address: { type: "string" },
username: { type: "string" },
password: { type: "string" },
},
},
},
[AppRoute.AUTH_LOGIN]: undefined,
[AppRoute.AUTH_LOGIN_ACTION]: {
body: {
type: "object",
required: ["email_address", "password"],
additionalProperties: false,
properties: {
email_address: { type: "string" },
password: { type: "string" },
},
},
},
[AppRoute.AUTH_LOGOUT_ACTION]: undefined,
[AppRoute.USER_DASHBOARD]: undefined,
[AppRoute.REPOSITORY_EXPLORE]: undefined,
[AppRoute.REPOSITORY_COMMITS_LOG]: {
params: {
type: "object",
required: ["orgSlug", "repoSlug"],
additionalProperties: false,
properties: {
orgSlug: {
type: "string",
},
repoSlug: {
type: "string",
},
},
},
},
[AppRoute.REPOSITORY_CREATE]: undefined,
[AppRoute.REPOSITORY_CREATE_ACTION]: {
body: {
type: "object",
required: [
"parent_org_slug",
"repo_display_name",
"repo_init_license_file",
"repo_init_license_kind",
"repo_init_readme_file",
"repo_keywords",
"repo_keywords_add",
"repo_short_description",
"repo_slug",
"repo_visibility",
"repo_website_url",
],
additionalProperties: false,
properties: {
parent_org_slug: {
type: "string",
},
repo_display_name: {
type: "string",
minLength: 3,
maxLength: 64,
},
repo_init_license_file: {
type: "string",
enum: ["on", "off"],
},
repo_init_license_kind: {
type: "string",
},
repo_init_readme_file: {
type: "string",
enum: ["on", "off"],
},
repo_keywords: {
type: "string",
},
repo_keywords_add: {
type: "string",
},
repo_short_description: {
type: "string",
minLength: 10,
maxLength: 140,
},
repo_slug: {
type: "string",
minLength: 3,
maxLength: 64,
},
repo_visibility: {
type: "string",
enum: Object.values(ResourceVisibility),
},
repo_website_url: {
type: "string",
format: "uri",
},
},
},
},
[AppRoute.REPOSITORY_DETAILS]: {
params: {
type: "object",
required: ["orgSlug", "repoSlug"],
additionalProperties: false,
properties: {
orgSlug: {
type: "string",
},
repoSlug: {
type: "string",
},
},
},
},
[AppRoute.REPOSITORY_BROWSER]: {
params: {
type: "object",
required: ["orgSlug", "repoSlug", "ref", "*"],
additionalProperties: false,
properties: {
orgSlug: {
type: "string",
},
repoSlug: {
type: "string",
},
ref: {
type: "string",
},
"*": {
type: "string",
},
},
},
},
};
const RootAppRouter: AppRouter = () => {
const guestOrDashboardRedirect = guestOrRedirect("/dashboard");
const loggedOrLoginRedirect = authenticatedOrLogin();
return (
<Router.Root>
<></>
<Router.Group type={AppRouterGroup.API}>
<Router.Route
name={AppRoute.SET_THEME}
method={"GET"}
path={"/theme/:themeScheme"}
schema={AppRoutesSchemas[AppRoute.SET_THEME]}
handler={ThemeController.getTheme}
/>
{}
<Router.Route
name={AppRoute.HOME}
method={"GET"}
path={"/"}
preHandler={guestOrDashboardRedirect}
handler={HomeController.getHomeView}
/>
{}
<Router.Route
name={AppRoute.AUTH_REGISTER}
method={"GET"}
path={"/auth/register"}
preHandler={guestOrDashboardRedirect}
handler={AuthController.getRegisterView}
/>
<Router.Route
name={AppRoute.AUTH_REGISTER_ACTION}
method={"POST"}
path={"/auth/register"}
preHandler={guestOrDashboardRedirect}
schema={AppRoutesSchemas[AppRoute.AUTH_REGISTER_ACTION]}
handler={AuthController.postRegisterAction}
/>
{}
<Router.Route
name={AppRoute.AUTH_LOGIN}
method={"GET"}
path={"/auth/login"}
preHandler={guestOrDashboardRedirect}
handler={AuthController.getLoginView}
/>
<Router.Route
name={AppRoute.AUTH_LOGIN_ACTION}
method={"POST"}
path={"/auth/login"}
preHandler={guestOrDashboardRedirect}
schema={AppRoutesSchemas[AppRoute.AUTH_LOGIN_ACTION]}
handler={AuthController.postLoginAction}
/>
<Router.Route
name={AppRoute.AUTH_LOGOUT_ACTION}
method={"GET"}
path={"/auth/logout"}
preHandler={loggedOrLoginRedirect}
schema={AppRoutesSchemas[AppRoute.AUTH_LOGOUT_ACTION]}
handler={AuthController.getLogoutAction}
/>
{}
<Router.Route
name={AppRoute.USER_DASHBOARD}
method={"GET"}
path={"/dashboard"}
preHandler={loggedOrLoginRedirect}
handler={AuthController.getDashboardView}
/>
{}
<Router.Route
name={AppRoute.REPOSITORY_EXPLORE}
method={"GET"}
path={"/repo/explore"}
handler={RepositoryController.getRepositoryExploreView}
/>
<Router.Route
name={AppRoute.REPOSITORY_COMMITS_LOG}
method={"GET"}
path={"/:orgSlug/:repoSlug/commits"}
preHandler={loggedOrLoginRedirect}
schema={AppRoutesSchemas[AppRoute.REPOSITORY_COMMITS_LOG]}
handler={RepositoryController.getRepositoryCommitsLogView}
/>
<Router.Route
name={AppRoute.REPOSITORY_CREATE}
method={"GET"}
path={"/repo/new"}
preHandler={loggedOrLoginRedirect}
handler={RepositoryController.getRepositoryCreateView}
/>
<Router.Route
name={AppRoute.REPOSITORY_CREATE_ACTION}
method={"POST"}
path={"/repo/new"}
preHandler={loggedOrLoginRedirect}
schema={AppRoutesSchemas[AppRoute.REPOSITORY_CREATE_ACTION]}
handler={RepositoryController.postRepositoryCreateAction}
/>
<Router.Route
name={AppRoute.REPOSITORY_DETAILS}
method={"GET"}
path={"/:orgSlug/:repoSlug"}
schema={AppRoutesSchemas[AppRoute.REPOSITORY_DETAILS]}
handler={RepositoryController.getRepositoryDetailsView}
/>
<Router.Route
name={AppRoute.REPOSITORY_DETAILS}
method={"GET"}
path={"/:orgSlug/:repoSlug/"}
schema={AppRoutesSchemas[AppRoute.REPOSITORY_DETAILS]}
handler={RepositoryController.getRepositoryDetailsView}
/>
<Router.Route
name={AppRoute.REPOSITORY_BROWSER}
method={"GET"}
path={"/:orgSlug/:repoSlug/:ref/tree/*"}
schema={AppRoutesSchemas[AppRoute.REPOSITORY_BROWSER]}
handler={RepositoryController.getRepositoryBrowserView}
/>
</Router.Group>
</Router.Root>
);
};
export default RootAppRouter;