First Commit

This commit is contained in:
2026-03-04 14:21:07 +00:00
commit 86cfe54f6e
38 changed files with 1399 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
import { Box, Card, Heading } from "@radix-ui/themes";
export default function Main() {
return (
<Card>
<Box>
<Heading size={"5"}>Home</Heading>
</Box>
</Card>
);
}
+11
View File
@@ -0,0 +1,11 @@
import { Box, Card, Heading } from "@radix-ui/themes";
export default function Main() {
return (
<Card className="max-w-4xl w-full xl:p-8">
<Box>
<Heading size={"5"}>Login</Heading>
</Box>
</Card>
);
}
+24
View File
@@ -0,0 +1,24 @@
import grabTurboCiConfig from "@/utils/grab-turboci-config";
export default async function cronCheckServices() {
const config = grabTurboCiConfig();
for (let i = 0; i < config.services.length; i++) {
const service = config.services[i];
if (!service.servers) {
continue;
}
for (let srv = 0; srv < service.servers.length; srv++) {
const server = service.servers[srv];
console.log("service", service.service_name);
console.log(server.private_ip);
if (service.healthcheck) {
let cmd = ``;
}
}
}
}
+12
View File
@@ -0,0 +1,12 @@
import { AppData } from "@/data/app-data";
import cronCheckServices from "./functions/check-services";
while (true) {
console.log(`Running Cron Services ...`);
await cronCheckServices();
await Bun.sleep(AppData["CronInterval"]);
}
export {};
+4
View File
@@ -0,0 +1,4 @@
export const AppData = {
TerminalBinName: "ttyd",
CronInterval: 30000,
} as const;
+30
View File
@@ -0,0 +1,30 @@
import type { BUN_SQLITE_DatabaseSchemaType } from "@moduletrace/bun-sqlite/dist/types";
const schema: BUN_SQLITE_DatabaseSchemaType = {
dbName: "test-db",
tables: [
{
tableName: "users",
fields: [
{
fieldName: "first_name",
dataType: "TEXT",
},
{
fieldName: "last_name",
dataType: "TEXT",
},
{
fieldName: "email",
dataType: "TEXT",
},
{
fieldName: "image",
dataType: "TEXT",
},
],
},
],
};
export default schema;
+24
View File
@@ -0,0 +1,24 @@
export const BunSQLiteTables = [
"users",
] as const
export type BUN_SQLITE_TEST_DB_USERS = {
/**
* The unique identifier of the record.
*/
id?: number;
/**
* The time when the record was created. (Unix Timestamp)
*/
created_at?: number;
/**
* The time when the record was updated. (Unix Timestamp)
*/
updated_at?: number;
first_name?: string;
last_name?: string;
email?: string;
image?: string;
}
export type BUN_SQLITE_TEST_DB_ALL_TYPEDEFS = BUN_SQLITE_TEST_DB_USERS
+14
View File
@@ -0,0 +1,14 @@
import { Box, Container, Section } from "@radix-ui/themes";
import { PropsWithChildren } from "react";
type Props = PropsWithChildren & {};
export default function Layout({ children }: Props) {
return (
<Section className="w-screen h-screen flex flex-col items-center justify-center">
<Container className="flex flex-col items-center justify-center">
<Box>{children}</Box>
</Container>
</Section>
);
}
+13
View File
@@ -0,0 +1,13 @@
import "@/styles/globals.css";
import "@radix-ui/themes/styles.css";
import type { AppProps } from "next/app";
import { Theme } from "@radix-ui/themes";
export default function App({ Component, pageProps }: AppProps) {
return (
<Theme>
<Component {...pageProps} />
</Theme>
);
}
+13
View File
@@ -0,0 +1,13 @@
import { Html, Head, Main, NextScript } from "next/document";
export default function Document() {
return (
<Html lang="en">
<Head />
<body className="antialiased">
<Main />
<NextScript />
</body>
</Html>
);
}
+13
View File
@@ -0,0 +1,13 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next";
type Data = {
name: string;
};
export default function handler(
req: NextApiRequest,
res: NextApiResponse<Data>,
) {
res.status(200).json({ name: "John Doe" });
}
+10
View File
@@ -0,0 +1,10 @@
import Main from "@/components/pages/auth/login";
import Layout from "@/layouts/login";
export default function LoginPage() {
return (
<Layout>
<Main />
</Layout>
);
}
+11
View File
@@ -0,0 +1,11 @@
import Main from "@/components/pages/home";
import Layout from "@/layouts/login";
import { Heading } from "@radix-ui/themes";
export default function Home() {
return (
<Layout>
<Main />
</Layout>
);
}
+26
View File
@@ -0,0 +1,26 @@
@import "tailwindcss";
:root {
--background: #ffffff;
--foreground: #171717;
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}
@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
}
body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}
+159
View File
@@ -0,0 +1,159 @@
export const CloudProviders = [
{
title: "Hetzner",
value: "hetzner",
},
{
title: "Amazon Web Services",
value: "aws",
},
{
title: "Google Cloud Platform",
value: "gcp",
},
{
title: "Microsoft Azure",
value: "azure",
},
] as const;
export type ParsedDeploymentServiceConfig = TCIConfigServiceConfig & {
service_name: string;
parent_service_name?: string;
servers?: NormalizedServerObject[];
};
export type NormalizedServerObject = {
public_ip?: string;
private_ip?: string;
};
export type TCIConfig = {
deployment_name: string;
duplicate_deployment_name?: string;
description?: string;
location?: string;
availability_zone?: string;
provider: (typeof CloudProviders)[number]["value"];
services: TCIConfigService;
env?: { [k: string]: string };
env_file?: string;
pre_deployment?: TCIRunObj;
};
export type TCIGlobalConfig = Omit<TCIConfig, "services"> & {
services: ParsedDeploymentServiceConfig[];
relay_server_ip?: string;
};
export type TCIConfigService = {
[k: string]: TCIConfigServiceConfig;
};
export const TCIServiceTypes = [
{
title: "Default Service",
value: "default",
},
{
title: "Docker",
value: "docker",
},
{
title: "Load Balancer",
value: "load_balancer",
},
] as const;
export const TCIServiceOS = [
{
title: "Debian 12 Bookworm",
value: "debian_12",
},
{
title: "Debian 13 Buster",
value: "debian_13",
},
{
title: "Ubuntu 23.0.4",
value: "ubuntu_23_0_4",
},
] as const;
export const TCIServiceDependecyTypes = [
{
title: "Debian APT",
value: "apt",
},
{
title: "Turbo CI",
value: "turboci",
},
] as const;
export type TCIConfigServiceConfig = {
type?: (typeof TCIServiceTypes)[number]["value"];
os?: string;
server_type?: string;
enable_public_ip?: boolean;
instances?: number;
clusters?: number;
dir_mappings?: TCIConfigServiceConfigDirMApping[];
dependencies?: {
[k in (typeof TCIServiceDependecyTypes)[number]["value"]]?: string[];
};
env?: { [k: string]: string };
env_file?: string;
target_services?: TCIConfigServiceConfigLBTarget[];
run?: TCIConfigServiceConfigRun;
ssl?: TCIConfigServiceSSL;
duplicate_service_name?: string;
healthcheck?: TCIConfigServiceHealthcheck;
/**
* Commoands to Run on first run
*/
init?: string[];
};
export type TCIConfigServiceHealthcheck = {
cmd: string;
test: string;
};
export type TCIConfigServiceDomain = {
domain_name: string;
};
export type TCIConfigServiceSSL = {
email: string;
};
export type TCIConfigServiceConfigLBTarget = {
service_name: string;
port: number;
weight?: number;
backup?: boolean;
domains?: (string | TCIConfigServiceDomain)[];
};
export type TCIConfigServiceConfigRun = {
preflight?: TCIRunObj;
start?: TCIRunObj;
postflight?: TCIRunObj;
work_dir?: string;
};
export type TCIRunObj = {
cmds?: string[];
work_dir?: string;
file?: string;
};
export type TCIConfigServiceConfigDirMApping = {
src: string;
dst: string;
ignore_file?: string;
ignore_patterns?: string[];
use_gitignore?: boolean;
relay_ignore?: string[];
};
+73
View File
@@ -0,0 +1,73 @@
import { exec, execSync, type ExecSyncOptions } from "child_process";
import grabSSHPrefix from "./grab-ssh-prefix";
import _ from "lodash";
type Param = {
cmd: string | string[];
debug?: boolean;
ip: string;
user?: string;
options?: ExecSyncOptions;
detached?: boolean;
return_cmd_only?: boolean;
cmd_prefix?: string;
};
export default async function execSSH(
params: Param,
): Promise<string | undefined> {
const {
cmd,
debug,
ip,
user = "root",
options,
detached,
return_cmd_only,
cmd_prefix,
} = params;
try {
let cmdPrefix = cmd_prefix || grabSSHPrefix();
let finalCmd = `${cmdPrefix}`;
finalCmd += ` ${user}@${ip}`;
const parsedCmd =
typeof cmd == "string"
? cmd
: Array.isArray(cmd)
? cmd.join("\n")
: undefined;
finalCmd += ` << 'TURBOCIEXEC' \n${parsedCmd}\nTURBOCIEXEC`;
if (debug) {
console.log("finalCmd", finalCmd);
}
if (return_cmd_only) {
return finalCmd;
}
const str = detached
? ""
: execSync(finalCmd, {
stdio: "pipe",
...options,
encoding: "utf-8",
});
if (debug) {
console.log(str);
}
if (detached) {
exec(finalCmd);
}
return str.trim();
} catch (error: any) {
return undefined;
}
}
+23
View File
@@ -0,0 +1,23 @@
import path from "path";
export default function grabDirNames() {
const APP_DIR = path.resolve(__dirname, "../../");
const TURBOCI_DIR = `/root/.turboci`;
const TURBOCI_CONFIG_DIR = path.join(TURBOCI_DIR, ".config");
const TURBOCI_CONFIG_JSON_FILE = path.join(
TURBOCI_CONFIG_DIR,
"turboci.json",
);
const TURBOCI_SSH_DIR = path.join(TURBOCI_DIR, ".ssh");
const TURBOCI_SSH_KEY_FILE = path.join(TURBOCI_SSH_DIR, "turboci");
return {
APP_DIR,
TURBOCI_CONFIG_DIR,
TURBOCI_CONFIG_JSON_FILE,
TURBOCI_DIR,
TURBOCI_SSH_DIR,
TURBOCI_SSH_KEY_FILE,
};
}
+8
View File
@@ -0,0 +1,8 @@
import grabDirNames from "./grab-dir-names";
type Params = {};
export default function grabSSHPrefix(params?: Params) {
const { TURBOCI_SSH_KEY_FILE } = grabDirNames();
return `ssh -i ${TURBOCI_SSH_KEY_FILE} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -C -c aes128-ctr`;
}
+31
View File
@@ -0,0 +1,31 @@
type Params = {
cmd: string;
cwd?: string;
flags?: string[];
};
export default function grabTtydCmd({ cmd: ttydCmd, cwd, flags }: Params) {
const port = 8080;
let cmd = ``;
cmd += `${AppData["TerminalBinName"]}`;
cmd += ` --writable --max-clients 1`;
cmd += ` --client-option 'theme={"background":"#0c0e11"}'`;
cmd += ` --client-option fontSize=14`;
if (cwd) {
cmd += ` --cwd ${cwd}`;
}
if (flags?.[0]) {
for (let i = 0; i < flags.length; i++) {
const flag = flags[i];
cmd += ` ${flag}`;
}
}
cmd += ` -p ${port}`;
cmd += ` ${ttydCmd}`;
return { cmd, port };
}
+17
View File
@@ -0,0 +1,17 @@
import fs from "fs";
import grabDirNames from "./grab-dir-names";
import { TCIGlobalConfig } from "@/types";
export default function grabTurboCiConfig() {
const { TURBOCI_CONFIG_JSON_FILE } = grabDirNames();
if (!fs.existsSync(TURBOCI_CONFIG_JSON_FILE)) {
throw new Error(`TurboCI config JSON file not found!`);
}
const config = JSON.parse(
fs.readFileSync(TURBOCI_CONFIG_JSON_FILE, "utf-8"),
) as TCIGlobalConfig;
return config;
}
+12
View File
@@ -0,0 +1,12 @@
import datasquirel from "@moduletrace/datasquirel";
import { NextApiRequest } from "next";
type Params = {
req: NextApiRequest;
};
export default async function userAuth({ req }: Params) {
const auth = datasquirel.user.auth.auth({ req });
const user = auth.payload;
return { user };
}