mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat: initial commit
This commit is contained in:
92
server/db/schema/admin.ts
Normal file
92
server/db/schema/admin.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import { boolean, integer, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { nanoid } from "nanoid";
|
||||
import { auth } from "./auth";
|
||||
import { users } from "./user";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import { certificateType } from "./shared";
|
||||
|
||||
export const admins = pgTable("admin", {
|
||||
adminId: text("adminId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
|
||||
githubAppId: integer("githubAppId"),
|
||||
githubAppName: text("githubAppName"),
|
||||
serverIp: text("serverIp"),
|
||||
certificateType: certificateType("certificateType").notNull().default("none"),
|
||||
host: text("host"),
|
||||
githubClientId: text("githubClientId"),
|
||||
githubClientSecret: text("githubClientSecret"),
|
||||
githubInstallationId: text("githubInstallationId"),
|
||||
githubPrivateKey: text("githubPrivateKey"),
|
||||
letsEncryptEmail: text("letsEncryptEmail"),
|
||||
sshPrivateKey: text("sshPrivateKey"),
|
||||
enableDockerCleanup: boolean("enableDockerCleanup").notNull().default(false),
|
||||
authId: text("authId")
|
||||
.notNull()
|
||||
.references(() => auth.id, { onDelete: "cascade" }),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
});
|
||||
|
||||
export const adminsRelations = relations(admins, ({ one, many }) => ({
|
||||
auth: one(auth, {
|
||||
fields: [admins.authId],
|
||||
references: [auth.id],
|
||||
}),
|
||||
users: many(users),
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(admins, {
|
||||
adminId: z.string(),
|
||||
githubAppName: z.string().optional(),
|
||||
githubClientId: z.string().optional(),
|
||||
githubClientSecret: z.string().optional(),
|
||||
githubInstallationId: z.string().optional(),
|
||||
githubPrivateKey: z.string().optional(),
|
||||
githubAppId: z.number().optional(),
|
||||
enableDockerCleanup: z.boolean().optional(),
|
||||
sshPrivateKey: z.string().optional(),
|
||||
certificateType: z.enum(["letsencrypt", "none"]).default("none"),
|
||||
serverIp: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiSaveSSHKey = createSchema
|
||||
.pick({
|
||||
sshPrivateKey: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiAssignDomain = createSchema
|
||||
.pick({
|
||||
letsEncryptEmail: true,
|
||||
host: true,
|
||||
certificateType: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiUpdateDockerCleanup = createSchema
|
||||
.pick({
|
||||
enableDockerCleanup: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiTraefikConfig = z.object({
|
||||
traefikConfig: z.string().min(1),
|
||||
});
|
||||
|
||||
export const apiGetBranches = z.object({
|
||||
repo: z.string().min(1),
|
||||
owner: z.string().min(1),
|
||||
});
|
||||
export const apiModifyTraefikConfig = z.object({
|
||||
path: z.string().min(1),
|
||||
traefikConfig: z.string().min(1),
|
||||
});
|
||||
export const apiReadTraefikConfig = z.object({
|
||||
path: z.string().min(1),
|
||||
});
|
||||
199
server/db/schema/application.ts
Normal file
199
server/db/schema/application.ts
Normal file
@@ -0,0 +1,199 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { deployments } from "./deployment";
|
||||
import { mounts } from "./mount";
|
||||
import { redirects } from "./redirects";
|
||||
import { domains } from "./domain";
|
||||
import { projects } from "./project";
|
||||
import { security } from "./security";
|
||||
import { applicationStatus } from "./shared";
|
||||
import { ports } from "./port";
|
||||
import { boolean, integer, pgEnum, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { generateAppName } from "./utils";
|
||||
|
||||
export const sourceType = pgEnum("sourceType", ["docker", "git", "github"]);
|
||||
|
||||
export const buildType = pgEnum("buildType", [
|
||||
"dockerfile",
|
||||
"heroku_buildpacks",
|
||||
"paketo_buildpacks",
|
||||
"nixpacks",
|
||||
]);
|
||||
|
||||
export const applications = pgTable("application", {
|
||||
applicationId: text("applicationId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
name: text("name").notNull(),
|
||||
appName: text("appName")
|
||||
.notNull()
|
||||
.$defaultFn(() => generateAppName("app"))
|
||||
.unique(),
|
||||
description: text("description"),
|
||||
env: text("env"),
|
||||
memoryReservation: integer("memoryReservation"),
|
||||
memoryLimit: integer("memoryLimit"),
|
||||
cpuReservation: integer("cpuReservation"),
|
||||
cpuLimit: integer("cpuLimit"),
|
||||
title: text("title"),
|
||||
enabled: boolean("enabled"),
|
||||
subtitle: text("subtitle"),
|
||||
command: text("command"),
|
||||
refreshToken: text("refreshToken").$defaultFn(() => nanoid()),
|
||||
sourceType: sourceType("sourceType").notNull().default("github"),
|
||||
// Github
|
||||
repository: text("repository"),
|
||||
owner: text("owner"),
|
||||
branch: text("branch"),
|
||||
buildPath: text("buildPath").default("/"),
|
||||
autoDeploy: boolean("autoDeploy"),
|
||||
// Docker
|
||||
username: text("username"),
|
||||
password: text("password"),
|
||||
dockerImage: text("dockerImage"),
|
||||
// Git
|
||||
customGitUrl: text("customGitUrl"),
|
||||
customGitBranch: text("customGitBranch"),
|
||||
customGitBuildPath: text("customGitBuildPath"),
|
||||
customGitSSHKey: text("customGitSSHKey"),
|
||||
dockerfile: text("dockerfile"),
|
||||
applicationStatus: applicationStatus("applicationStatus")
|
||||
.notNull()
|
||||
.default("idle"),
|
||||
buildType: buildType("buildType").notNull().default("nixpacks"),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
projectId: text("projectId")
|
||||
.notNull()
|
||||
.references(() => projects.projectId, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const applicationsRelations = relations(
|
||||
applications,
|
||||
({ one, many }) => ({
|
||||
project: one(projects, {
|
||||
fields: [applications.projectId],
|
||||
references: [projects.projectId],
|
||||
}),
|
||||
deployments: many(deployments),
|
||||
domains: many(domains),
|
||||
mounts: many(mounts),
|
||||
redirects: many(redirects),
|
||||
security: many(security),
|
||||
ports: many(ports),
|
||||
}),
|
||||
);
|
||||
|
||||
const createSchema = createInsertSchema(applications, {
|
||||
appName: z.string(),
|
||||
createdAt: z.string(),
|
||||
applicationId: z.string(),
|
||||
autoDeploy: z.boolean(),
|
||||
env: z.string().optional(),
|
||||
name: z.string().min(1),
|
||||
description: z.string().optional(),
|
||||
memoryReservation: z.number().optional(),
|
||||
memoryLimit: z.number().optional(),
|
||||
cpuReservation: z.number().optional(),
|
||||
cpuLimit: z.number().optional(),
|
||||
title: z.string().optional(),
|
||||
enabled: z.boolean().optional(),
|
||||
subtitle: z.string().optional(),
|
||||
dockerImage: z.string().optional(),
|
||||
username: z.string().optional(),
|
||||
password: z.string().optional(),
|
||||
customGitSSHKey: z.string().optional(),
|
||||
repository: z.string().optional(),
|
||||
dockerfile: z.string().optional(),
|
||||
branch: z.string().optional(),
|
||||
customGitBranch: z.string().optional(),
|
||||
customGitBuildPath: z.string().optional(),
|
||||
customGitUrl: z.string().optional(),
|
||||
buildPath: z.string().optional(),
|
||||
projectId: z.string(),
|
||||
sourceType: z.enum(["github", "docker", "git"]).optional(),
|
||||
applicationStatus: z.enum(["idle", "running", "done", "error"]),
|
||||
buildType: z.enum([
|
||||
"dockerfile",
|
||||
"heroku_buildpacks",
|
||||
"paketo_buildpacks",
|
||||
"nixpacks",
|
||||
]),
|
||||
owner: z.string(),
|
||||
});
|
||||
|
||||
export const apiCreateApplication = createSchema.pick({
|
||||
name: true,
|
||||
description: true,
|
||||
projectId: true,
|
||||
});
|
||||
|
||||
export const apiFindOneApplication = createSchema
|
||||
.pick({
|
||||
applicationId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiReloadApplication = createSchema
|
||||
.pick({
|
||||
appName: true,
|
||||
applicationId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiSaveBuildType = createSchema
|
||||
.pick({
|
||||
applicationId: true,
|
||||
buildType: true,
|
||||
dockerfile: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiSaveGithubProvider = createSchema
|
||||
.pick({
|
||||
applicationId: true,
|
||||
repository: true,
|
||||
branch: true,
|
||||
owner: true,
|
||||
buildPath: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiSaveDockerProvider = createSchema
|
||||
.pick({
|
||||
dockerImage: true,
|
||||
applicationId: true,
|
||||
username: true,
|
||||
password: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiSaveGitProvider = createSchema
|
||||
.pick({
|
||||
customGitBranch: true,
|
||||
applicationId: true,
|
||||
customGitBuildPath: true,
|
||||
customGitUrl: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiSaveEnviromentVariables = createSchema
|
||||
.pick({
|
||||
applicationId: true,
|
||||
env: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindMonitoringStats = createSchema
|
||||
.pick({
|
||||
appName: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiUpdateApplication = createSchema.partial().extend({
|
||||
applicationId: z.string().min(1),
|
||||
});
|
||||
123
server/db/schema/auth.ts
Normal file
123
server/db/schema/auth.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import { pgTable, pgEnum, text, boolean } from "drizzle-orm/pg-core";
|
||||
import { nanoid } from "nanoid";
|
||||
import { users } from "./user";
|
||||
import { admins } from "./admin";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import { getRandomValues } from "node:crypto";
|
||||
|
||||
const randomImages = [
|
||||
"/avatars/avatar-1.png",
|
||||
"/avatars/avatar-2.png",
|
||||
"/avatars/avatar-3.png",
|
||||
"/avatars/avatar-4.png",
|
||||
"/avatars/avatar-5.png",
|
||||
"/avatars/avatar-6.png",
|
||||
"/avatars/avatar-7.png",
|
||||
"/avatars/avatar-8.png",
|
||||
"/avatars/avatar-9.png",
|
||||
"/avatars/avatar-10.png",
|
||||
"/avatars/avatar-11.png",
|
||||
"/avatars/avatar-12.png",
|
||||
];
|
||||
|
||||
const generateRandomImage = () => {
|
||||
return (
|
||||
randomImages[
|
||||
// @ts-ignore
|
||||
getRandomValues(new Uint32Array(1))[0] % randomImages.length
|
||||
] || "/avatars/avatar-1.png"
|
||||
);
|
||||
};
|
||||
export type DatabaseUser = typeof auth.$inferSelect;
|
||||
export const roles = pgEnum("Roles", ["admin", "user"]);
|
||||
|
||||
export const auth = pgTable("auth", {
|
||||
id: text("id")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
email: text("email").notNull().unique(),
|
||||
password: text("password").notNull(),
|
||||
rol: roles("rol").notNull(),
|
||||
image: text("image").$defaultFn(() => generateRandomImage()),
|
||||
secret: text("secret"),
|
||||
is2FAEnabled: boolean("is2FAEnabled").notNull().default(false),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
});
|
||||
|
||||
export const authRelations = relations(auth, ({ many }) => ({
|
||||
admins: many(admins),
|
||||
users: many(users),
|
||||
}));
|
||||
const createSchema = createInsertSchema(auth, {
|
||||
email: z.string().email(),
|
||||
password: z.string().min(8),
|
||||
rol: z.enum(["admin", "user"]),
|
||||
image: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiCreateAdmin = createSchema.pick({
|
||||
email: true,
|
||||
password: true,
|
||||
});
|
||||
|
||||
export const apiCreateUser = createSchema
|
||||
.pick({
|
||||
password: true,
|
||||
id: true,
|
||||
})
|
||||
.required()
|
||||
.extend({
|
||||
token: z.string().min(1),
|
||||
});
|
||||
|
||||
export const apiLogin = createSchema
|
||||
.pick({
|
||||
email: true,
|
||||
password: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiUpdateAuth = createSchema.partial().extend({
|
||||
email: z.string().nullable(),
|
||||
password: z.string().nullable(),
|
||||
image: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiUpdateAuthByAdmin = createSchema.partial().extend({
|
||||
email: z.string().nullable(),
|
||||
password: z.string().nullable(),
|
||||
image: z.string().optional(),
|
||||
id: z.string().min(1),
|
||||
});
|
||||
|
||||
export const apiFindOneAuth = createSchema
|
||||
.pick({
|
||||
id: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiVerify2FA = createSchema
|
||||
.extend({
|
||||
pin: z.string().min(6),
|
||||
secret: z.string().min(1),
|
||||
})
|
||||
.pick({
|
||||
pin: true,
|
||||
secret: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiVerifyLogin2FA = createSchema
|
||||
.extend({
|
||||
pin: z.string().min(6),
|
||||
})
|
||||
.pick({
|
||||
pin: true,
|
||||
id: true,
|
||||
})
|
||||
.required();
|
||||
131
server/db/schema/backups.ts
Normal file
131
server/db/schema/backups.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import { destinations } from "./destination";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { postgres } from "./postgres";
|
||||
import { mariadb } from "./mariadb";
|
||||
import { mysql } from "./mysql";
|
||||
import { mongo } from "./mongo";
|
||||
import {
|
||||
type AnyPgColumn,
|
||||
boolean,
|
||||
pgEnum,
|
||||
pgTable,
|
||||
text,
|
||||
} from "drizzle-orm/pg-core";
|
||||
|
||||
export const databaseType = pgEnum("databaseType", [
|
||||
"postgres",
|
||||
"mariadb",
|
||||
"mysql",
|
||||
"mongo",
|
||||
]);
|
||||
|
||||
export const backups = pgTable("backup", {
|
||||
backupId: text("backupId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
schedule: text("schedule").notNull(),
|
||||
enabled: boolean("enabled"),
|
||||
database: text("database").notNull(),
|
||||
prefix: text("prefix").notNull(),
|
||||
|
||||
destinationId: text("destinationId")
|
||||
.notNull()
|
||||
.references(() => destinations.destinationId, { onDelete: "cascade" }),
|
||||
|
||||
databaseType: databaseType("databaseType").notNull(),
|
||||
postgresId: text("postgresId").references(
|
||||
(): AnyPgColumn => postgres.postgresId,
|
||||
{
|
||||
onDelete: "cascade",
|
||||
},
|
||||
),
|
||||
mariadbId: text("mariadbId").references(
|
||||
(): AnyPgColumn => mariadb.mariadbId,
|
||||
{
|
||||
onDelete: "cascade",
|
||||
},
|
||||
),
|
||||
mysqlId: text("mysqlId").references((): AnyPgColumn => mysql.mysqlId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
mongoId: text("mongoId").references((): AnyPgColumn => mongo.mongoId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
});
|
||||
|
||||
export const backupsRelations = relations(backups, ({ one }) => ({
|
||||
destination: one(destinations, {
|
||||
fields: [backups.destinationId],
|
||||
references: [destinations.destinationId],
|
||||
}),
|
||||
postgres: one(postgres, {
|
||||
fields: [backups.postgresId],
|
||||
references: [postgres.postgresId],
|
||||
}),
|
||||
mariadb: one(mariadb, {
|
||||
fields: [backups.mariadbId],
|
||||
references: [mariadb.mariadbId],
|
||||
}),
|
||||
mysql: one(mysql, {
|
||||
fields: [backups.mysqlId],
|
||||
references: [mysql.mysqlId],
|
||||
}),
|
||||
mongo: one(mongo, {
|
||||
fields: [backups.mongoId],
|
||||
references: [mongo.mongoId],
|
||||
}),
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(backups, {
|
||||
backupId: z.string(),
|
||||
destinationId: z.string(),
|
||||
enabled: z.boolean().optional(),
|
||||
prefix: z.string().min(1),
|
||||
database: z.string().min(1),
|
||||
schedule: z.string(),
|
||||
databaseType: z.enum(["postgres", "mariadb", "mysql", "mongo"]),
|
||||
postgresId: z.string().optional(),
|
||||
mariadbId: z.string().optional(),
|
||||
mysqlId: z.string().optional(),
|
||||
mongoId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiCreateBackup = createSchema.pick({
|
||||
schedule: true,
|
||||
enabled: true,
|
||||
prefix: true,
|
||||
destinationId: true,
|
||||
database: true,
|
||||
mariadbId: true,
|
||||
mysqlId: true,
|
||||
postgresId: true,
|
||||
mongoId: true,
|
||||
databaseType: true,
|
||||
});
|
||||
|
||||
export const apiFindOneBackup = createSchema
|
||||
.pick({
|
||||
backupId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiRemoveBackup = createSchema
|
||||
.pick({
|
||||
backupId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiUpdateBackup = createSchema
|
||||
.pick({
|
||||
schedule: true,
|
||||
enabled: true,
|
||||
prefix: true,
|
||||
backupId: true,
|
||||
destinationId: true,
|
||||
database: true,
|
||||
})
|
||||
.required();
|
||||
43
server/db/schema/certificate.ts
Normal file
43
server/db/schema/certificate.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { boolean, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { generateAppName } from "./utils";
|
||||
|
||||
export const certificates = pgTable("certificate", {
|
||||
certificateId: text("certificateId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
name: text("name").notNull(),
|
||||
certificateData: text("certificateData").notNull(),
|
||||
privateKey: text("privateKey").notNull(),
|
||||
certificatePath: text("certificatePath")
|
||||
.notNull()
|
||||
.$defaultFn(() => generateAppName("certificate"))
|
||||
.unique(),
|
||||
autoRenew: boolean("autoRenew"),
|
||||
});
|
||||
|
||||
export const apiCreateCertificate = createInsertSchema(certificates, {
|
||||
name: z.string().min(1),
|
||||
certificateData: z.string().min(1),
|
||||
privateKey: z.string().min(1),
|
||||
autoRenew: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export const apiFindCertificate = z.object({
|
||||
certificateId: z.string().min(1),
|
||||
});
|
||||
|
||||
export const apiUpdateCertificate = z.object({
|
||||
certificateId: z.string().min(1),
|
||||
name: z.string().min(1).optional(),
|
||||
certificateData: z.string().min(1).optional(),
|
||||
privateKey: z.string().min(1).optional(),
|
||||
autoRenew: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export const apiDeleteCertificate = z.object({
|
||||
certificateId: z.string().min(1),
|
||||
});
|
||||
57
server/db/schema/deployment.ts
Normal file
57
server/db/schema/deployment.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import { z } from "zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { applications } from "./application";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { pgEnum, pgTable, text } from "drizzle-orm/pg-core";
|
||||
|
||||
export const deploymentStatus = pgEnum("deploymentStatus", [
|
||||
"running",
|
||||
"done",
|
||||
"error",
|
||||
]);
|
||||
|
||||
export const deployments = pgTable("deployment", {
|
||||
deploymentId: text("deploymentId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
title: text("title").notNull(),
|
||||
status: deploymentStatus("status").default("running"),
|
||||
logPath: text("logPath").notNull(),
|
||||
applicationId: text("applicationId")
|
||||
.notNull()
|
||||
.references(() => applications.applicationId, { onDelete: "cascade" }),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
});
|
||||
|
||||
export const deploymentsRelations = relations(deployments, ({ one }) => ({
|
||||
application: one(applications, {
|
||||
fields: [deployments.applicationId],
|
||||
references: [applications.applicationId],
|
||||
}),
|
||||
}));
|
||||
|
||||
const schema = createInsertSchema(deployments, {
|
||||
title: z.string().min(1),
|
||||
status: z.string().default("running"),
|
||||
logPath: z.string().min(1),
|
||||
applicationId: z.string().min(1),
|
||||
});
|
||||
|
||||
export const apiCreateDeployment = schema
|
||||
.pick({
|
||||
title: true,
|
||||
status: true,
|
||||
logPath: true,
|
||||
applicationId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindAllByApplication = schema
|
||||
.pick({
|
||||
applicationId: true,
|
||||
})
|
||||
.required();
|
||||
80
server/db/schema/destination.ts
Normal file
80
server/db/schema/destination.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { admins } from "./admin";
|
||||
import { backups } from "./backups";
|
||||
|
||||
export const destinations = pgTable("destination", {
|
||||
destinationId: text("destinationId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
name: text("name").notNull(),
|
||||
accessKey: text("accessKey").notNull(),
|
||||
secretAccessKey: text("secretAccessKey").notNull(),
|
||||
bucket: text("bucket").notNull(),
|
||||
region: text("region").notNull(),
|
||||
// maybe it can be null
|
||||
endpoint: text("endpoint").notNull(),
|
||||
adminId: text("adminId")
|
||||
.notNull()
|
||||
.references(() => admins.adminId, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const destinationsRelations = relations(
|
||||
destinations,
|
||||
({ many, one }) => ({
|
||||
backups: many(backups),
|
||||
admin: one(admins, {
|
||||
fields: [destinations.adminId],
|
||||
references: [admins.adminId],
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
const createSchema = createInsertSchema(destinations, {
|
||||
destinationId: z.string(),
|
||||
name: z.string().min(1),
|
||||
accessKey: z.string(),
|
||||
bucket: z.string(),
|
||||
endpoint: z.string(),
|
||||
secretAccessKey: z.string(),
|
||||
region: z.string(),
|
||||
});
|
||||
|
||||
export const apiCreateDestination = createSchema
|
||||
.pick({
|
||||
name: true,
|
||||
accessKey: true,
|
||||
bucket: true,
|
||||
region: true,
|
||||
endpoint: true,
|
||||
secretAccessKey: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindOneDestination = createSchema
|
||||
.pick({
|
||||
destinationId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiRemoveDestination = createSchema
|
||||
.pick({
|
||||
destinationId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiUpdateDestination = createSchema
|
||||
.pick({
|
||||
name: true,
|
||||
accessKey: true,
|
||||
bucket: true,
|
||||
region: true,
|
||||
endpoint: true,
|
||||
secretAccessKey: true,
|
||||
destinationId: true,
|
||||
})
|
||||
.required();
|
||||
77
server/db/schema/domain.ts
Normal file
77
server/db/schema/domain.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { boolean, integer, pgTable, serial, text } from "drizzle-orm/pg-core";
|
||||
import { applications } from "./application";
|
||||
import { certificateType } from "./shared";
|
||||
|
||||
export const domains = pgTable("domain", {
|
||||
domainId: text("domainId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
host: text("host").notNull(),
|
||||
https: boolean("https").notNull().default(false),
|
||||
port: integer("port").default(80),
|
||||
path: text("path").default("/"),
|
||||
uniqueConfigKey: serial("uniqueConfigKey"),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
applicationId: text("applicationId")
|
||||
.notNull()
|
||||
.references(() => applications.applicationId, { onDelete: "cascade" }),
|
||||
certificateType: certificateType("certificateType").notNull().default("none"),
|
||||
});
|
||||
|
||||
export const domainsRelations = relations(domains, ({ one }) => ({
|
||||
application: one(applications, {
|
||||
fields: [domains.applicationId],
|
||||
references: [applications.applicationId],
|
||||
}),
|
||||
}));
|
||||
const hostnameRegex = /^[a-zA-Z0-9][a-zA-Z0-9\.-]*\.[a-zA-Z]{2,}$/;
|
||||
const createSchema = createInsertSchema(domains, {
|
||||
domainId: z.string().min(1),
|
||||
host: z.string().min(1),
|
||||
path: z.string().min(1),
|
||||
port: z.number(),
|
||||
https: z.boolean(),
|
||||
applicationId: z.string(),
|
||||
certificateType: z.enum(["letsencrypt", "none"]),
|
||||
});
|
||||
|
||||
export const apiCreateDomain = createSchema
|
||||
.pick({
|
||||
host: true,
|
||||
path: true,
|
||||
port: true,
|
||||
https: true,
|
||||
applicationId: true,
|
||||
certificateType: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindDomain = createSchema
|
||||
.pick({
|
||||
domainId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindDomainByApplication = createSchema
|
||||
.pick({
|
||||
applicationId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiUpdateDomain = createSchema
|
||||
.pick({
|
||||
domainId: true,
|
||||
host: true,
|
||||
path: true,
|
||||
port: true,
|
||||
https: true,
|
||||
certificateType: true,
|
||||
})
|
||||
.required();
|
||||
22
server/db/schema/index.ts
Normal file
22
server/db/schema/index.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
export * from "./application";
|
||||
export * from "./postgres";
|
||||
|
||||
export * from "./user";
|
||||
export * from "./admin";
|
||||
export * from "./auth";
|
||||
export * from "./project";
|
||||
export * from "./domain";
|
||||
export * from "./mariadb";
|
||||
export * from "./mongo";
|
||||
export * from "./mysql";
|
||||
export * from "./backups";
|
||||
export * from "./destination";
|
||||
export * from "./deployment";
|
||||
export * from "./mount";
|
||||
export * from "./certificate";
|
||||
export * from "./session";
|
||||
export * from "./redirects";
|
||||
export * from "./security";
|
||||
export * from "./port";
|
||||
export * from "./redis";
|
||||
export * from "./shared";
|
||||
134
server/db/schema/mariadb.ts
Normal file
134
server/db/schema/mariadb.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { applicationStatus } from "./shared";
|
||||
import { integer, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { projects } from "./project";
|
||||
import { backups } from "./backups";
|
||||
import { mounts } from "./mount";
|
||||
import { generateAppName } from "./utils";
|
||||
|
||||
export const mariadb = pgTable("mariadb", {
|
||||
mariadbId: text("mariadbId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
name: text("name").notNull(),
|
||||
appName: text("appName")
|
||||
.notNull()
|
||||
.$defaultFn(() => generateAppName("mariadb"))
|
||||
.unique(),
|
||||
description: text("description"),
|
||||
databaseName: text("databaseName").notNull(),
|
||||
databaseUser: text("databaseUser").notNull(),
|
||||
databasePassword: text("databasePassword").notNull(),
|
||||
databaseRootPassword: text("rootPassword").notNull(),
|
||||
dockerImage: text("dockerImage").notNull(),
|
||||
command: text("command"),
|
||||
env: text("env"),
|
||||
// RESOURCES
|
||||
memoryReservation: integer("memoryReservation"),
|
||||
memoryLimit: integer("memoryLimit"),
|
||||
cpuReservation: integer("cpuReservation"),
|
||||
cpuLimit: integer("cpuLimit"),
|
||||
//
|
||||
externalPort: integer("externalPort"),
|
||||
applicationStatus: applicationStatus("applicationStatus")
|
||||
.notNull()
|
||||
.default("idle"),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
projectId: text("projectId")
|
||||
.notNull()
|
||||
.references(() => projects.projectId, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const mariadbRelations = relations(mariadb, ({ one, many }) => ({
|
||||
project: one(projects, {
|
||||
fields: [mariadb.projectId],
|
||||
references: [projects.projectId],
|
||||
}),
|
||||
backups: many(backups),
|
||||
mounts: many(mounts),
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(mariadb, {
|
||||
mariadbId: z.string(),
|
||||
name: z.string().min(1),
|
||||
appName: z.string().min(1),
|
||||
createdAt: z.string(),
|
||||
databaseName: z.string().min(1),
|
||||
databaseUser: z.string().min(1),
|
||||
databasePassword: z.string(),
|
||||
databaseRootPassword: z.string().optional(),
|
||||
dockerImage: z.string().default("mariadb:6"),
|
||||
command: z.string().optional(),
|
||||
env: z.string().optional(),
|
||||
memoryReservation: z.number().optional(),
|
||||
memoryLimit: z.number().optional(),
|
||||
cpuReservation: z.number().optional(),
|
||||
cpuLimit: z.number().optional(),
|
||||
projectId: z.string(),
|
||||
applicationStatus: z.enum(["idle", "running", "done", "error"]),
|
||||
externalPort: z.number(),
|
||||
description: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiCreateMariaDB = createSchema
|
||||
.pick({
|
||||
name: true,
|
||||
dockerImage: true,
|
||||
databaseRootPassword: true,
|
||||
projectId: true,
|
||||
description: true,
|
||||
databaseName: true,
|
||||
databaseUser: true,
|
||||
databasePassword: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindOneMariaDB = createSchema
|
||||
.pick({
|
||||
mariadbId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiChangeMariaDBStatus = createSchema
|
||||
.pick({
|
||||
mariadbId: true,
|
||||
applicationStatus: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiSaveEnviromentVariablesMariaDB = createSchema
|
||||
.pick({
|
||||
mariadbId: true,
|
||||
env: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiSaveExternalPortMariaDB = createSchema
|
||||
.pick({
|
||||
mariadbId: true,
|
||||
externalPort: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiDeployMariaDB = createSchema
|
||||
.pick({
|
||||
mariadbId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiResetMariadb = createSchema
|
||||
.pick({
|
||||
mariadbId: true,
|
||||
appName: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiUpdateMariaDB = createSchema.partial().extend({
|
||||
mariadbId: z.string().min(1),
|
||||
});
|
||||
126
server/db/schema/mongo.ts
Normal file
126
server/db/schema/mongo.ts
Normal file
@@ -0,0 +1,126 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { applicationStatus } from "./shared";
|
||||
import { integer, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { projects } from "./project";
|
||||
import { backups } from "./backups";
|
||||
import { mounts } from "./mount";
|
||||
import { generateAppName } from "./utils";
|
||||
|
||||
export const mongo = pgTable("mongo", {
|
||||
mongoId: text("mongoId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
name: text("name").notNull(),
|
||||
appName: text("appName")
|
||||
.notNull()
|
||||
.$defaultFn(() => generateAppName("mongo"))
|
||||
.unique(),
|
||||
description: text("description"),
|
||||
databaseUser: text("databaseUser").notNull(),
|
||||
databasePassword: text("databasePassword").notNull(),
|
||||
dockerImage: text("dockerImage").notNull(),
|
||||
command: text("command"),
|
||||
env: text("env"),
|
||||
memoryReservation: integer("memoryReservation"),
|
||||
memoryLimit: integer("memoryLimit"),
|
||||
cpuReservation: integer("cpuReservation"),
|
||||
cpuLimit: integer("cpuLimit"),
|
||||
externalPort: integer("externalPort"),
|
||||
applicationStatus: applicationStatus("applicationStatus")
|
||||
.notNull()
|
||||
.default("idle"),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
projectId: text("projectId")
|
||||
.notNull()
|
||||
.references(() => projects.projectId, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const mongoRelations = relations(mongo, ({ one, many }) => ({
|
||||
project: one(projects, {
|
||||
fields: [mongo.projectId],
|
||||
references: [projects.projectId],
|
||||
}),
|
||||
backups: many(backups),
|
||||
mounts: many(mounts),
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(mongo, {
|
||||
appName: z.string().min(1),
|
||||
createdAt: z.string(),
|
||||
mongoId: z.string(),
|
||||
name: z.string().min(1),
|
||||
databasePassword: z.string(),
|
||||
databaseUser: z.string().min(1),
|
||||
dockerImage: z.string().default("mongo:15"),
|
||||
command: z.string().optional(),
|
||||
env: z.string().optional(),
|
||||
memoryReservation: z.number().optional(),
|
||||
memoryLimit: z.number().optional(),
|
||||
cpuReservation: z.number().optional(),
|
||||
cpuLimit: z.number().optional(),
|
||||
projectId: z.string(),
|
||||
applicationStatus: z.enum(["idle", "running", "done", "error"]),
|
||||
externalPort: z.number(),
|
||||
description: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiCreateMongo = createSchema
|
||||
.pick({
|
||||
name: true,
|
||||
dockerImage: true,
|
||||
projectId: true,
|
||||
description: true,
|
||||
databaseUser: true,
|
||||
databasePassword: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindOneMongo = createSchema
|
||||
.pick({
|
||||
mongoId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiChangeMongoStatus = createSchema
|
||||
.pick({
|
||||
mongoId: true,
|
||||
applicationStatus: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiSaveEnviromentVariablesMongo = createSchema
|
||||
.pick({
|
||||
mongoId: true,
|
||||
env: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiSaveExternalPortMongo = createSchema
|
||||
.pick({
|
||||
mongoId: true,
|
||||
externalPort: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiDeployMongo = createSchema
|
||||
.pick({
|
||||
mongoId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiUpdateMongo = createSchema.partial().extend({
|
||||
mongoId: z.string().min(1),
|
||||
});
|
||||
|
||||
export const apiResetMongo = createSchema
|
||||
.pick({
|
||||
mongoId: true,
|
||||
appName: true,
|
||||
})
|
||||
.required();
|
||||
136
server/db/schema/mount.ts
Normal file
136
server/db/schema/mount.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
import { nanoid } from "nanoid";
|
||||
import { applications } from "./application";
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import { pgEnum, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { postgres } from "./postgres";
|
||||
import { mariadb } from "./mariadb";
|
||||
import { mongo } from "./mongo";
|
||||
import { mysql } from "./mysql";
|
||||
import { redis } from "./redis";
|
||||
|
||||
export const serviceType = pgEnum("serviceType", [
|
||||
"application",
|
||||
"postgres",
|
||||
"mysql",
|
||||
"mariadb",
|
||||
"mongo",
|
||||
"redis",
|
||||
]);
|
||||
|
||||
export const mountType = pgEnum("mountType", ["bind", "volume", "file"]);
|
||||
|
||||
export const mounts = pgTable("mount", {
|
||||
mountId: text("mountId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
type: mountType("type").notNull(),
|
||||
hostPath: text("hostPath"),
|
||||
volumeName: text("volumeName"),
|
||||
content: text("content"),
|
||||
serviceType: serviceType("serviceType").notNull().default("application"),
|
||||
mountPath: text("mountPath").notNull(),
|
||||
applicationId: text("applicationId").references(
|
||||
() => applications.applicationId,
|
||||
{ onDelete: "cascade" },
|
||||
),
|
||||
postgresId: text("postgresId").references(() => postgres.postgresId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
mariadbId: text("mariadbId").references(() => mariadb.mariadbId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
mongoId: text("mongoId").references(() => mongo.mongoId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
mysqlId: text("mysqlId").references(() => mysql.mysqlId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
redisId: text("redisId").references(() => redis.redisId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
});
|
||||
|
||||
export const MountssRelations = relations(mounts, ({ one }) => ({
|
||||
application: one(applications, {
|
||||
fields: [mounts.applicationId],
|
||||
references: [applications.applicationId],
|
||||
}),
|
||||
postgres: one(postgres, {
|
||||
fields: [mounts.postgresId],
|
||||
references: [postgres.postgresId],
|
||||
}),
|
||||
mariadb: one(mariadb, {
|
||||
fields: [mounts.mariadbId],
|
||||
references: [mariadb.mariadbId],
|
||||
}),
|
||||
mongo: one(mongo, {
|
||||
fields: [mounts.mongoId],
|
||||
references: [mongo.mongoId],
|
||||
}),
|
||||
mysql: one(mysql, {
|
||||
fields: [mounts.mysqlId],
|
||||
references: [mysql.mysqlId],
|
||||
}),
|
||||
redis: one(redis, {
|
||||
fields: [mounts.redisId],
|
||||
references: [redis.redisId],
|
||||
}),
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(mounts, {
|
||||
applicationId: z.string(),
|
||||
type: z.enum(["bind", "volume", "file"]),
|
||||
hostPath: z.string().optional(),
|
||||
volumeName: z.string().optional(),
|
||||
content: z.string().optional(),
|
||||
mountPath: z.string().min(1),
|
||||
mountId: z.string().optional(),
|
||||
serviceType: z
|
||||
.enum(["application", "postgres", "mysql", "mariadb", "mongo", "redis"])
|
||||
.default("application"),
|
||||
});
|
||||
|
||||
export type ServiceType = NonNullable<
|
||||
z.infer<typeof createSchema>["serviceType"]
|
||||
>;
|
||||
|
||||
export const apiCreateMount = createSchema
|
||||
.pick({
|
||||
type: true,
|
||||
hostPath: true,
|
||||
volumeName: true,
|
||||
content: true,
|
||||
mountPath: true,
|
||||
serviceType: true,
|
||||
})
|
||||
.extend({
|
||||
serviceId: z.string().min(1),
|
||||
});
|
||||
|
||||
export const apiFindOneMount = createSchema
|
||||
.pick({
|
||||
mountId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiRemoveMount = createSchema
|
||||
.pick({
|
||||
mountId: true,
|
||||
})
|
||||
// .extend({
|
||||
// appName: z.string().min(1),
|
||||
// })
|
||||
.required();
|
||||
|
||||
export const apiFindMountByApplicationId = createSchema
|
||||
.extend({
|
||||
serviceId: z.string().min(1),
|
||||
})
|
||||
.pick({
|
||||
serviceId: true,
|
||||
serviceType: true,
|
||||
})
|
||||
.required();
|
||||
132
server/db/schema/mysql.ts
Normal file
132
server/db/schema/mysql.ts
Normal file
@@ -0,0 +1,132 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { applicationStatus } from "./shared";
|
||||
import { integer, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { projects } from "./project";
|
||||
import { backups } from "./backups";
|
||||
import { mounts } from "./mount";
|
||||
import { generateAppName } from "./utils";
|
||||
|
||||
export const mysql = pgTable("mysql", {
|
||||
mysqlId: text("mysqlId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
name: text("name").notNull(),
|
||||
appName: text("appName")
|
||||
.notNull()
|
||||
.$defaultFn(() => generateAppName("mysql"))
|
||||
.unique(),
|
||||
description: text("description"),
|
||||
databaseName: text("databaseName").notNull(),
|
||||
databaseUser: text("databaseUser").notNull(),
|
||||
databasePassword: text("databasePassword").notNull(),
|
||||
databaseRootPassword: text("rootPassword").notNull(),
|
||||
dockerImage: text("dockerImage").notNull(),
|
||||
command: text("command"),
|
||||
env: text("env"),
|
||||
memoryReservation: integer("memoryReservation"),
|
||||
memoryLimit: integer("memoryLimit"),
|
||||
cpuReservation: integer("cpuReservation"),
|
||||
cpuLimit: integer("cpuLimit"),
|
||||
externalPort: integer("externalPort"),
|
||||
applicationStatus: applicationStatus("applicationStatus")
|
||||
.notNull()
|
||||
.default("idle"),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
projectId: text("projectId")
|
||||
.notNull()
|
||||
.references(() => projects.projectId, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const mysqlRelations = relations(mysql, ({ one, many }) => ({
|
||||
project: one(projects, {
|
||||
fields: [mysql.projectId],
|
||||
references: [projects.projectId],
|
||||
}),
|
||||
backups: many(backups),
|
||||
mounts: many(mounts),
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(mysql, {
|
||||
mysqlId: z.string(),
|
||||
appName: z.string().min(1),
|
||||
createdAt: z.string(),
|
||||
name: z.string().min(1),
|
||||
databaseName: z.string().min(1),
|
||||
databaseUser: z.string().min(1),
|
||||
databasePassword: z.string(),
|
||||
databaseRootPassword: z.string().optional(),
|
||||
dockerImage: z.string().default("mysql:8"),
|
||||
command: z.string().optional(),
|
||||
env: z.string().optional(),
|
||||
memoryReservation: z.number().optional(),
|
||||
memoryLimit: z.number().optional(),
|
||||
cpuReservation: z.number().optional(),
|
||||
cpuLimit: z.number().optional(),
|
||||
projectId: z.string(),
|
||||
applicationStatus: z.enum(["idle", "running", "done", "error"]),
|
||||
externalPort: z.number(),
|
||||
description: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiCreateMySql = createSchema
|
||||
.pick({
|
||||
name: true,
|
||||
dockerImage: true,
|
||||
projectId: true,
|
||||
description: true,
|
||||
databaseName: true,
|
||||
databaseUser: true,
|
||||
databasePassword: true,
|
||||
databaseRootPassword: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindOneMySql = createSchema
|
||||
.pick({
|
||||
mysqlId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiChangeMySqlStatus = createSchema
|
||||
.pick({
|
||||
mysqlId: true,
|
||||
applicationStatus: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiSaveEnviromentVariablesMySql = createSchema
|
||||
.pick({
|
||||
mysqlId: true,
|
||||
env: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiSaveExternalPortMySql = createSchema
|
||||
.pick({
|
||||
mysqlId: true,
|
||||
externalPort: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiResetMysql = createSchema
|
||||
.pick({
|
||||
mysqlId: true,
|
||||
appName: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiDeployMySql = createSchema
|
||||
.pick({
|
||||
mysqlId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiUpdateMySql = createSchema.partial().extend({
|
||||
mysqlId: z.string().min(1),
|
||||
});
|
||||
61
server/db/schema/port.ts
Normal file
61
server/db/schema/port.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { integer, pgEnum, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { applications } from "./application";
|
||||
|
||||
export const protocolType = pgEnum("protocolType", ["tcp", "udp"]);
|
||||
|
||||
export const ports = pgTable("port", {
|
||||
portId: text("portId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
publishedPort: integer("publishedPort").notNull(),
|
||||
targetPort: integer("targetPort").notNull(),
|
||||
protocol: protocolType("protocol").notNull(),
|
||||
|
||||
applicationId: text("applicationId")
|
||||
.notNull()
|
||||
.references(() => applications.applicationId, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const portsRelations = relations(ports, ({ one }) => ({
|
||||
application: one(applications, {
|
||||
fields: [ports.applicationId],
|
||||
references: [applications.applicationId],
|
||||
}),
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(ports, {
|
||||
portId: z.string().min(1),
|
||||
applicationId: z.string().min(1),
|
||||
publishedPort: z.number(),
|
||||
targetPort: z.number(),
|
||||
protocol: z.enum(["tcp", "udp"]).default("tcp"),
|
||||
});
|
||||
|
||||
export const apiCreatePort = createSchema
|
||||
.pick({
|
||||
publishedPort: true,
|
||||
targetPort: true,
|
||||
protocol: true,
|
||||
applicationId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindOnePort = createSchema
|
||||
.pick({
|
||||
portId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiUpdatePort = createSchema
|
||||
.pick({
|
||||
portId: true,
|
||||
publishedPort: true,
|
||||
targetPort: true,
|
||||
protocol: true,
|
||||
})
|
||||
.required();
|
||||
128
server/db/schema/postgres.ts
Normal file
128
server/db/schema/postgres.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { applicationStatus } from "./shared";
|
||||
import { integer, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { projects } from "./project";
|
||||
import { backups } from "./backups";
|
||||
import { mounts } from "./mount";
|
||||
import { generateAppName } from "./utils";
|
||||
|
||||
export const postgres = pgTable("postgres", {
|
||||
postgresId: text("postgresId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
name: text("name").notNull(),
|
||||
appName: text("appName")
|
||||
.notNull()
|
||||
.$defaultFn(() => generateAppName("postgres"))
|
||||
.unique(),
|
||||
databaseName: text("databaseName").notNull(),
|
||||
databaseUser: text("databaseUser").notNull(),
|
||||
databasePassword: text("databasePassword").notNull(),
|
||||
description: text("description"),
|
||||
dockerImage: text("dockerImage").notNull(),
|
||||
command: text("command"),
|
||||
env: text("env"),
|
||||
memoryReservation: integer("memoryReservation"),
|
||||
externalPort: integer("externalPort"),
|
||||
memoryLimit: integer("memoryLimit"),
|
||||
cpuReservation: integer("cpuReservation"),
|
||||
cpuLimit: integer("cpuLimit"),
|
||||
applicationStatus: applicationStatus("applicationStatus")
|
||||
.notNull()
|
||||
.default("idle"),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
projectId: text("projectId")
|
||||
.notNull()
|
||||
.references(() => projects.projectId, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const postgresRelations = relations(postgres, ({ one, many }) => ({
|
||||
project: one(projects, {
|
||||
fields: [postgres.projectId],
|
||||
references: [projects.projectId],
|
||||
}),
|
||||
backups: many(backups),
|
||||
mounts: many(mounts),
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(postgres, {
|
||||
postgresId: z.string(),
|
||||
name: z.string().min(1),
|
||||
databasePassword: z.string(),
|
||||
databaseName: z.string().min(1),
|
||||
databaseUser: z.string().min(1),
|
||||
dockerImage: z.string().default("postgres:15"),
|
||||
command: z.string().optional(),
|
||||
env: z.string().optional(),
|
||||
memoryReservation: z.number().optional(),
|
||||
memoryLimit: z.number().optional(),
|
||||
cpuReservation: z.number().optional(),
|
||||
cpuLimit: z.number().optional(),
|
||||
projectId: z.string(),
|
||||
applicationStatus: z.enum(["idle", "running", "done", "error"]),
|
||||
externalPort: z.number(),
|
||||
createdAt: z.string(),
|
||||
description: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiCreatePostgres = createSchema
|
||||
.pick({
|
||||
name: true,
|
||||
databaseName: true,
|
||||
databaseUser: true,
|
||||
databasePassword: true,
|
||||
dockerImage: true,
|
||||
projectId: true,
|
||||
description: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindOnePostgres = createSchema
|
||||
.pick({
|
||||
postgresId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiChangePostgresStatus = createSchema
|
||||
.pick({
|
||||
postgresId: true,
|
||||
applicationStatus: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiSaveEnviromentVariablesPostgres = createSchema
|
||||
.pick({
|
||||
postgresId: true,
|
||||
env: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiSaveExternalPortPostgres = createSchema
|
||||
.pick({
|
||||
postgresId: true,
|
||||
externalPort: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiDeployPostgres = createSchema
|
||||
.pick({
|
||||
postgresId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiResetPostgres = createSchema
|
||||
.pick({
|
||||
postgresId: true,
|
||||
appName: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiUpdatePostgres = createSchema.partial().extend({
|
||||
postgresId: z.string().min(1),
|
||||
});
|
||||
72
server/db/schema/project.ts
Normal file
72
server/db/schema/project.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { mysql } from "./mysql";
|
||||
import { postgres } from "./postgres";
|
||||
import { mariadb } from "./mariadb";
|
||||
import { applications } from "./application";
|
||||
import { mongo } from "./mongo";
|
||||
import { redis } from "./redis";
|
||||
import { admins } from "./admin";
|
||||
|
||||
export const projects = pgTable("project", {
|
||||
projectId: text("projectId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
name: text("name").notNull(),
|
||||
description: text("description"),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
adminId: text("adminId")
|
||||
.notNull()
|
||||
.references(() => admins.adminId, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const projectRelations = relations(projects, ({ many, one }) => ({
|
||||
mysql: many(mysql),
|
||||
postgres: many(postgres),
|
||||
mariadb: many(mariadb),
|
||||
applications: many(applications),
|
||||
mongo: many(mongo),
|
||||
redis: many(redis),
|
||||
admin: one(admins, {
|
||||
fields: [projects.adminId],
|
||||
references: [admins.adminId],
|
||||
}),
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(projects, {
|
||||
projectId: z.string().min(1),
|
||||
name: z.string().min(1),
|
||||
description: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiCreateProject = createSchema.pick({
|
||||
name: true,
|
||||
description: true,
|
||||
});
|
||||
|
||||
export const apiFindOneProject = createSchema
|
||||
.pick({
|
||||
projectId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiRemoveProject = createSchema
|
||||
.pick({
|
||||
projectId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiUpdateProject = createSchema
|
||||
.pick({
|
||||
name: true,
|
||||
description: true,
|
||||
projectId: true,
|
||||
})
|
||||
.required();
|
||||
60
server/db/schema/redirects.ts
Normal file
60
server/db/schema/redirects.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { boolean, pgTable, serial, text } from "drizzle-orm/pg-core";
|
||||
import { applications } from "./application";
|
||||
|
||||
export const redirects = pgTable("redirect", {
|
||||
redirectId: text("redirectId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
regex: text("regex").notNull(),
|
||||
replacement: text("replacement").notNull(),
|
||||
permanent: boolean("permanent").notNull().default(false),
|
||||
uniqueConfigKey: serial("uniqueConfigKey"),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
applicationId: text("applicationId")
|
||||
.notNull()
|
||||
.references(() => applications.applicationId, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const redirectRelations = relations(redirects, ({ one }) => ({
|
||||
application: one(applications, {
|
||||
fields: [redirects.applicationId],
|
||||
references: [applications.applicationId],
|
||||
}),
|
||||
}));
|
||||
const createSchema = createInsertSchema(redirects, {
|
||||
redirectId: z.string().min(1),
|
||||
regex: z.string().min(1),
|
||||
replacement: z.string().min(1),
|
||||
permanent: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export const apiFindOneRedirect = createSchema
|
||||
.pick({
|
||||
redirectId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiCreateRedirect = createSchema
|
||||
.pick({
|
||||
regex: true,
|
||||
replacement: true,
|
||||
permanent: true,
|
||||
applicationId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiUpdateRedirect = createSchema
|
||||
.pick({
|
||||
redirectId: true,
|
||||
regex: true,
|
||||
replacement: true,
|
||||
permanent: true,
|
||||
})
|
||||
.required();
|
||||
122
server/db/schema/redis.ts
Normal file
122
server/db/schema/redis.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import { z } from "zod";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { applicationStatus } from "./shared";
|
||||
import { integer, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { projects } from "./project";
|
||||
import { mounts } from "./mount";
|
||||
import { generateAppName } from "./utils";
|
||||
|
||||
export const redis = pgTable("redis", {
|
||||
redisId: text("redisId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
name: text("name").notNull(),
|
||||
appName: text("appName")
|
||||
.notNull()
|
||||
.$defaultFn(() => generateAppName("redis"))
|
||||
.unique(),
|
||||
description: text("description"),
|
||||
databasePassword: text("password").notNull(),
|
||||
dockerImage: text("dockerImage").notNull(),
|
||||
command: text("command"),
|
||||
env: text("env"),
|
||||
memoryReservation: integer("memoryReservation"),
|
||||
memoryLimit: integer("memoryLimit"),
|
||||
cpuReservation: integer("cpuReservation"),
|
||||
cpuLimit: integer("cpuLimit"),
|
||||
externalPort: integer("externalPort"),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
applicationStatus: applicationStatus("applicationStatus")
|
||||
.notNull()
|
||||
.default("idle"),
|
||||
projectId: text("projectId")
|
||||
.notNull()
|
||||
.references(() => projects.projectId, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const redisRelations = relations(redis, ({ one, many }) => ({
|
||||
project: one(projects, {
|
||||
fields: [redis.projectId],
|
||||
references: [projects.projectId],
|
||||
}),
|
||||
mounts: many(mounts),
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(redis, {
|
||||
redisId: z.string(),
|
||||
appName: z.string().min(1),
|
||||
createdAt: z.string(),
|
||||
name: z.string().min(1),
|
||||
databasePassword: z.string(),
|
||||
dockerImage: z.string().default("redis:8"),
|
||||
command: z.string().optional(),
|
||||
env: z.string().optional(),
|
||||
memoryReservation: z.number().optional(),
|
||||
memoryLimit: z.number().optional(),
|
||||
cpuReservation: z.number().optional(),
|
||||
cpuLimit: z.number().optional(),
|
||||
projectId: z.string(),
|
||||
applicationStatus: z.enum(["idle", "running", "done", "error"]),
|
||||
externalPort: z.number(),
|
||||
description: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiCreateRedis = createSchema
|
||||
.pick({
|
||||
name: true,
|
||||
databasePassword: true,
|
||||
dockerImage: true,
|
||||
projectId: true,
|
||||
description: true,
|
||||
})
|
||||
|
||||
.required();
|
||||
|
||||
export const apiFindOneRedis = createSchema
|
||||
.pick({
|
||||
redisId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiChangeRedisStatus = createSchema
|
||||
.pick({
|
||||
redisId: true,
|
||||
applicationStatus: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiSaveEnviromentVariablesRedis = createSchema
|
||||
.pick({
|
||||
redisId: true,
|
||||
env: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiSaveExternalPortRedis = createSchema
|
||||
.pick({
|
||||
redisId: true,
|
||||
externalPort: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiDeployRedis = createSchema
|
||||
.pick({
|
||||
redisId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiResetRedis = createSchema
|
||||
.pick({
|
||||
redisId: true,
|
||||
appName: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiUpdateRedis = createSchema.partial().extend({
|
||||
redisId: z.string().min(1),
|
||||
});
|
||||
61
server/db/schema/security.ts
Normal file
61
server/db/schema/security.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { pgTable, text, unique } from "drizzle-orm/pg-core";
|
||||
import { applications } from "./application";
|
||||
|
||||
export const security = pgTable(
|
||||
"security",
|
||||
{
|
||||
securityId: text("securityId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
username: text("username").notNull(),
|
||||
password: text("password").notNull(),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
applicationId: text("applicationId")
|
||||
.notNull()
|
||||
.references(() => applications.applicationId, { onDelete: "cascade" }),
|
||||
},
|
||||
(t) => ({
|
||||
unq: unique().on(t.username, t.applicationId),
|
||||
}),
|
||||
);
|
||||
|
||||
export const securityRelations = relations(security, ({ one }) => ({
|
||||
application: one(applications, {
|
||||
fields: [security.applicationId],
|
||||
references: [applications.applicationId],
|
||||
}),
|
||||
}));
|
||||
const createSchema = createInsertSchema(security, {
|
||||
securityId: z.string().min(1),
|
||||
username: z.string().min(1),
|
||||
password: z.string().min(1),
|
||||
});
|
||||
|
||||
export const apiFindOneSecurity = createSchema
|
||||
.pick({
|
||||
securityId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiCreateSecurity = createSchema
|
||||
.pick({
|
||||
applicationId: true,
|
||||
username: true,
|
||||
password: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiUpdateSecurity = createSchema
|
||||
.pick({
|
||||
securityId: true,
|
||||
username: true,
|
||||
password: true,
|
||||
})
|
||||
.required();
|
||||
20
server/db/schema/session.ts
Normal file
20
server/db/schema/session.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { auth } from "./auth";
|
||||
import { pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
||||
|
||||
// export const sessionTable = sqliteTable("session", {
|
||||
// id: text("id").notNull().primaryKey(),
|
||||
// userId: text("user_id")
|
||||
// .notNull()
|
||||
// .references(() => users.id),
|
||||
// expiresAt: integer("expires_at").notNull(),
|
||||
// });
|
||||
export const sessionTable = pgTable("session", {
|
||||
id: text("id").primaryKey(),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => auth.id, { onDelete: "cascade" }),
|
||||
expiresAt: timestamp("expires_at", {
|
||||
withTimezone: true,
|
||||
mode: "date",
|
||||
}).notNull(),
|
||||
});
|
||||
13
server/db/schema/shared.ts
Normal file
13
server/db/schema/shared.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { pgEnum } from "drizzle-orm/pg-core";
|
||||
|
||||
export const applicationStatus = pgEnum("applicationStatus", [
|
||||
"idle",
|
||||
"running",
|
||||
"done",
|
||||
"error",
|
||||
]);
|
||||
|
||||
export const certificateType = pgEnum("certificateType", [
|
||||
"letsencrypt",
|
||||
"none",
|
||||
]);
|
||||
27
server/db/schema/source.ts
Normal file
27
server/db/schema/source.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { pgTable, text } from "drizzle-orm/pg-core";
|
||||
|
||||
export const source = pgTable("project", {
|
||||
projectId: text("projectId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
name: text("name").notNull(),
|
||||
description: text("description"),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
});
|
||||
|
||||
const createSchema = createInsertSchema(source, {
|
||||
name: z.string().min(1),
|
||||
description: z.string(),
|
||||
projectId: z.string(),
|
||||
});
|
||||
|
||||
export const apiCreate = createSchema.pick({
|
||||
name: true,
|
||||
description: true,
|
||||
});
|
||||
121
server/db/schema/user.ts
Normal file
121
server/db/schema/user.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { relations, sql } from "drizzle-orm";
|
||||
import { boolean, pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
||||
import { auth } from "./auth";
|
||||
import { admins } from "./admin";
|
||||
import { z } from "zod";
|
||||
/**
|
||||
* This is an example of how to use the multi-project schema feature of Drizzle ORM. Use the same
|
||||
* database instance for multiple projects.
|
||||
*
|
||||
* @see https://orm.drizzle.team/docs/goodies#multi-project-schema
|
||||
*/
|
||||
|
||||
export const users = pgTable("user", {
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
|
||||
token: text("token").notNull(),
|
||||
isRegistered: boolean("isRegistered").notNull().default(false),
|
||||
expirationDate: timestamp("expirationDate", {
|
||||
precision: 3,
|
||||
mode: "string",
|
||||
}).notNull(),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
canCreateProjects: boolean("canCreateProjects").notNull().default(false),
|
||||
canCreateServices: boolean("canCreateServices").notNull().default(false),
|
||||
canDeleteProjects: boolean("canDeleteProjects").notNull().default(false),
|
||||
canDeleteServices: boolean("canDeleteServices").notNull().default(false),
|
||||
canAccessToDocker: boolean("canAccessToDocker").notNull().default(false),
|
||||
canAccessToTraefikFiles: boolean("canAccessToTraefikFiles")
|
||||
.notNull()
|
||||
.default(false),
|
||||
accesedProjects: text("accesedProjects")
|
||||
.array()
|
||||
.notNull()
|
||||
.default(sql`ARRAY[]::text[]`),
|
||||
accesedServices: text("accesedServices")
|
||||
.array()
|
||||
.notNull()
|
||||
.default(sql`ARRAY[]::text[]`),
|
||||
adminId: text("adminId")
|
||||
.notNull()
|
||||
.references(() => admins.adminId, { onDelete: "cascade" }),
|
||||
authId: text("authId")
|
||||
.notNull()
|
||||
.references(() => auth.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const usersRelations = relations(users, ({ one }) => ({
|
||||
auth: one(auth, {
|
||||
fields: [users.authId],
|
||||
references: [auth.id],
|
||||
}),
|
||||
admin: one(admins, {
|
||||
fields: [users.adminId],
|
||||
references: [admins.adminId],
|
||||
}),
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(users, {
|
||||
userId: z.string().min(1),
|
||||
authId: z.string().min(1),
|
||||
token: z.string().min(1),
|
||||
isRegistered: z.boolean().optional(),
|
||||
adminId: z.string(),
|
||||
accesedProjects: z.array(z.string()).optional(),
|
||||
accesedServices: z.array(z.string()).optional(),
|
||||
canCreateProjects: z.boolean().optional(),
|
||||
canCreateServices: z.boolean().optional(),
|
||||
canDeleteProjects: z.boolean().optional(),
|
||||
canDeleteServices: z.boolean().optional(),
|
||||
canAccessToDocker: z.boolean().optional(),
|
||||
canAccessToTraefikFiles: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export const apiCreateUserInvitation = createSchema.pick({}).extend({
|
||||
email: z.string().email(),
|
||||
});
|
||||
|
||||
export const apiRemoveUser = createSchema
|
||||
.pick({
|
||||
authId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindOneToken = createSchema
|
||||
.pick({
|
||||
token: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiAssignPermissions = createSchema
|
||||
.pick({
|
||||
userId: true,
|
||||
canCreateProjects: true,
|
||||
canCreateServices: true,
|
||||
canDeleteProjects: true,
|
||||
canDeleteServices: true,
|
||||
accesedProjects: true,
|
||||
accesedServices: true,
|
||||
canAccessToTraefikFiles: true,
|
||||
canAccessToDocker: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindOneUser = createSchema
|
||||
.pick({
|
||||
userId: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindOneUserByAuth = createSchema
|
||||
.pick({
|
||||
authId: true,
|
||||
})
|
||||
.required();
|
||||
15
server/db/schema/utils.ts
Normal file
15
server/db/schema/utils.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { customAlphabet } from "nanoid";
|
||||
|
||||
const alphabet = "abcdefghijklmnopqrstuvwxyz123456789";
|
||||
|
||||
const customNanoid = customAlphabet(alphabet, 6);
|
||||
|
||||
export const generateAppName = (type: string) => {
|
||||
const verb = faker.hacker.verb().replace(/ /g, "-");
|
||||
const adjective = faker.hacker.adjective().replace(/ /g, "-");
|
||||
const noun = faker.hacker.noun().replace(/ /g, "-");
|
||||
const randomFakerElement = `${verb}-${adjective}-${noun}`;
|
||||
const nanoidPart = customNanoid();
|
||||
return `${type}-${randomFakerElement}-${nanoidPart}`;
|
||||
};
|
||||
Reference in New Issue
Block a user