547 lines · 15.7 KB · TypeScript
RawDownload
import { VALID_BRANCH_REGEX } from "@dokploy/server/utils/git-branch-validation";import { relations } from "drizzle-orm";import {	bigint,	boolean,	integer,	json,	pgEnum,	pgTable,	text,} from "drizzle-orm/pg-core";import { createInsertSchema } from "drizzle-zod";import { nanoid } from "nanoid";import { z } from "zod";import { bitbucket } from "./bitbucket";import { deployments } from "./deployment";import { domains } from "./domain";import { environments } from "./environment";import { gitea } from "./gitea";import { github } from "./github";import { gitlab } from "./gitlab";import { mounts } from "./mount";import { patch } from "./patch";import { ports } from "./port";import { previewDeployments } from "./preview-deployments";import { redirects } from "./redirects";import { registry } from "./registry";import { security } from "./security";import { server } from "./server";import {	applicationStatus,	certificateType,	type EndpointSpecSwarm,	EndpointSpecSwarmSchema,	type HealthCheckSwarm,	HealthCheckSwarmSchema,	type LabelsSwarm,	LabelsSwarmSchema,	type NetworkSwarm,	NetworkSwarmSchema,	type PlacementSwarm,	PlacementSwarmSchema,	type RestartPolicySwarm,	RestartPolicySwarmSchema,	type ServiceModeSwarm,	ServiceModeSwarmSchema,	triggerType,	type UlimitsSwarm,	UlimitsSwarmSchema,	type UpdateConfigSwarm,	UpdateConfigSwarmSchema,} from "./shared";import { sshKeys } from "./ssh-key";import {	APP_NAME_MESSAGE,	APP_NAME_REGEX,	encryptedText,	generateAppName,} from "./utils";export const sourceType = pgEnum("sourceType", [	"docker",	"git",	"github",	"gitlab",	"bitbucket",	"gitea",	"drop",]); export const buildType = pgEnum("buildType", [	"dockerfile",	"heroku_buildpacks",	"paketo_buildpacks",	"nixpacks",	"static",	"railpack",]); 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: encryptedText("env"),	previewEnv: encryptedText("previewEnv"),	watchPaths: text("watchPaths").array(),	previewBuildArgs: encryptedText("previewBuildArgs"),	previewBuildSecrets: encryptedText("previewBuildSecrets"),	previewLabels: text("previewLabels").array(),	previewWildcard: text("previewWildcard"),	previewPort: integer("previewPort").default(3000),	previewHttps: boolean("previewHttps").notNull().default(false),	previewPath: text("previewPath").default("/"),	previewCertificateType: certificateType("certificateType")		.notNull()		.default("none"),	previewCustomCertResolver: text("previewCustomCertResolver"),	previewLimit: integer("previewLimit").default(3),	isPreviewDeploymentsActive: boolean("isPreviewDeploymentsActive").default(		false,	),	// Security: Require collaborator permissions for preview deployments	previewRequireCollaboratorPermissions: boolean(		"previewRequireCollaboratorPermissions",	).default(true),	rollbackActive: boolean("rollbackActive").default(false),	buildArgs: encryptedText("buildArgs"),	buildSecrets: encryptedText("buildSecrets"),	memoryReservation: text("memoryReservation"),	memoryLimit: text("memoryLimit"),	cpuReservation: text("cpuReservation"),	cpuLimit: text("cpuLimit"),	title: text("title"),	enabled: boolean("enabled"),	subtitle: text("subtitle"),	command: text("command"),	args: text("args").array(),	icon: text("icon"),	refreshToken: text("refreshToken").$defaultFn(() => nanoid()),	sourceType: sourceType("sourceType").notNull().default("github"),	cleanCache: boolean("cleanCache").default(false),	// Github	repository: text("repository"),	owner: text("owner"),	branch: text("branch"),	buildPath: text("buildPath").default("/"),	triggerType: triggerType("triggerType").default("push"),	autoDeploy: boolean("autoDeploy").$defaultFn(() => true),	// Gitlab	gitlabProjectId: integer("gitlabProjectId"),	gitlabRepository: text("gitlabRepository"),	gitlabOwner: text("gitlabOwner"),	gitlabBranch: text("gitlabBranch"),	gitlabBuildPath: text("gitlabBuildPath").default("/"),	gitlabPathNamespace: text("gitlabPathNamespace"),	// Gitea	giteaRepository: text("giteaRepository"),	giteaOwner: text("giteaOwner"),	giteaBranch: text("giteaBranch"),	giteaBuildPath: text("giteaBuildPath").default("/"),	// Bitbucket	bitbucketRepository: text("bitbucketRepository"),	bitbucketRepositorySlug: text("bitbucketRepositorySlug"),	bitbucketOwner: text("bitbucketOwner"),	bitbucketBranch: text("bitbucketBranch"),	bitbucketBuildPath: text("bitbucketBuildPath").default("/"),	// Docker	username: text("username"),	password: text("password"),	dockerImage: text("dockerImage"),	registryUrl: text("registryUrl"),	// Git	customGitUrl: text("customGitUrl"),	customGitBranch: text("customGitBranch"),	customGitBuildPath: text("customGitBuildPath"),	customGitSSHKeyId: text("customGitSSHKeyId").references(		() => sshKeys.sshKeyId,		{			onDelete: "set null",		},	),	enableSubmodules: boolean("enableSubmodules").notNull().default(false),	dockerfile: text("dockerfile").default("Dockerfile"),	dockerContextPath: text("dockerContextPath"),	dockerBuildStage: text("dockerBuildStage"),	// Drop	dropBuildPath: text("dropBuildPath"),	// Docker swarm json	healthCheckSwarm: json("healthCheckSwarm").$type<HealthCheckSwarm>(),	restartPolicySwarm: json("restartPolicySwarm").$type<RestartPolicySwarm>(),	placementSwarm: json("placementSwarm").$type<PlacementSwarm>(),	updateConfigSwarm: json("updateConfigSwarm").$type<UpdateConfigSwarm>(),	rollbackConfigSwarm: json("rollbackConfigSwarm").$type<UpdateConfigSwarm>(),	modeSwarm: json("modeSwarm").$type<ServiceModeSwarm>(),	labelsSwarm: json("labelsSwarm").$type<LabelsSwarm>(),	networkSwarm: json("networkSwarm").$type<NetworkSwarm[]>(),	stopGracePeriodSwarm: bigint("stopGracePeriodSwarm", { mode: "number" }),	endpointSpecSwarm: json("endpointSpecSwarm").$type<EndpointSpecSwarm>(),	ulimitsSwarm: json("ulimitsSwarm").$type<UlimitsSwarm>(),	//	replicas: integer("replicas").default(1).notNull(),	applicationStatus: applicationStatus("applicationStatus")		.notNull()		.default("idle"),	buildType: buildType("buildType").notNull().default("nixpacks"),	railpackVersion: text("railpackVersion").default("0.15.4"),	herokuVersion: text("herokuVersion").default("24"),	publishDirectory: text("publishDirectory"),	isStaticSpa: boolean("isStaticSpa"),	createEnvFile: boolean("createEnvFile").notNull().default(true),	createdAt: text("createdAt")		.notNull()		.$defaultFn(() => new Date().toISOString()),	registryId: text("registryId").references(() => registry.registryId, {		onDelete: "set null",	}),	rollbackRegistryId: text("rollbackRegistryId").references(		() => registry.registryId,		{			onDelete: "set null",		},	),	environmentId: text("environmentId")		.notNull()		.references(() => environments.environmentId, { onDelete: "cascade" }),	githubId: text("githubId").references(() => github.githubId, {		onDelete: "set null",	}),	gitlabId: text("gitlabId").references(() => gitlab.gitlabId, {		onDelete: "set null",	}),	giteaId: text("giteaId").references(() => gitea.giteaId, {		onDelete: "set null",	}),	bitbucketId: text("bitbucketId").references(() => bitbucket.bitbucketId, {		onDelete: "set null",	}),	serverId: text("serverId").references(() => server.serverId, {		onDelete: "cascade",	}),	buildServerId: text("buildServerId").references(() => server.serverId, {		onDelete: "set null",	}),	buildRegistryId: text("buildRegistryId").references(		() => registry.registryId,		{			onDelete: "set null",		},	),}); export const applicationsRelations = relations(	applications,	({ one, many }) => ({		environment: one(environments, {			fields: [applications.environmentId],			references: [environments.environmentId],		}),		deployments: many(deployments),		customGitSSHKey: one(sshKeys, {			fields: [applications.customGitSSHKeyId],			references: [sshKeys.sshKeyId],		}),		domains: many(domains),		mounts: many(mounts),		redirects: many(redirects),		security: many(security),		ports: many(ports),		registry: one(registry, {			fields: [applications.registryId],			references: [registry.registryId],			relationName: "applicationRegistry",		}),		github: one(github, {			fields: [applications.githubId],			references: [github.githubId],		}),		gitlab: one(gitlab, {			fields: [applications.gitlabId],			references: [gitlab.gitlabId],		}),		gitea: one(gitea, {			fields: [applications.giteaId],			references: [gitea.giteaId],		}),		bitbucket: one(bitbucket, {			fields: [applications.bitbucketId],			references: [bitbucket.bitbucketId],		}),		server: one(server, {			fields: [applications.serverId],			references: [server.serverId],			relationName: "applicationServer",		}),		buildServer: one(server, {			fields: [applications.buildServerId],			references: [server.serverId],			relationName: "applicationBuildServer",		}),		buildRegistry: one(registry, {			fields: [applications.buildRegistryId],			references: [registry.registryId],			relationName: "applicationBuildRegistry",		}),		previewDeployments: many(previewDeployments),		rollbackRegistry: one(registry, {			fields: [applications.rollbackRegistryId],			references: [registry.registryId],			relationName: "applicationRollbackRegistry",		}),		patches: many(patch),	}),); const createSchema = createInsertSchema(applications, {	appName: z		.string()		.min(1)		.max(63)		.regex(APP_NAME_REGEX, APP_NAME_MESSAGE)		.optional(),	createdAt: z.string(),	applicationId: z.string(),	autoDeploy: z.boolean(),	env: z.string().optional(),	buildArgs: z.string().optional(),	buildSecrets: z.string().optional(),	name: z.string().min(1),	description: z.string().optional(),	memoryReservation: z.string().optional(),	memoryLimit: z.string().optional(),	cpuReservation: z.string().optional(),	cpuLimit: z.string().optional(),	title: z.string().optional(),	enabled: z.boolean().optional(),	subtitle: z.string().optional(),	dockerImage: z.string().optional(),	username: z.string().optional(),	isPreviewDeploymentsActive: z.boolean().optional(),	password: z.string().optional(),	args: z.array(z.string()).optional(),	registryUrl: z.string().optional(),	customGitSSHKeyId: 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(),	environmentId: z.string(),	sourceType: z		.enum(["github", "docker", "git", "gitlab", "bitbucket", "gitea", "drop"])		.optional(),	triggerType: z.enum(["push", "tag"]).optional(),	applicationStatus: z.enum(["idle", "running", "done", "error"]),	buildType: z.enum([		"dockerfile",		"heroku_buildpacks",		"paketo_buildpacks",		"nixpacks",		"static",		"railpack",	]),	railpackVersion: z.string().optional(),	herokuVersion: z.string().optional(),	publishDirectory: z.string().optional(),	isStaticSpa: z.boolean().optional(),	createEnvFile: z.boolean().optional(),	owner: z.string(),	healthCheckSwarm: HealthCheckSwarmSchema.nullable(),	restartPolicySwarm: RestartPolicySwarmSchema.nullable(),	placementSwarm: PlacementSwarmSchema.nullable(),	updateConfigSwarm: UpdateConfigSwarmSchema.nullable(),	rollbackConfigSwarm: UpdateConfigSwarmSchema.nullable(),	modeSwarm: ServiceModeSwarmSchema.nullable(),	labelsSwarm: LabelsSwarmSchema.nullable(),	networkSwarm: NetworkSwarmSchema.nullable(),	previewPort: z.number().optional(),	previewEnv: z.string().optional(),	previewBuildArgs: z.string().optional(),	previewBuildSecrets: z.string().optional(),	previewWildcard: z.string().optional(),	previewLimit: z.number().optional(),	previewHttps: z.boolean().optional(),	previewPath: z.string().optional(),	previewCertificateType: z.enum(["letsencrypt", "none", "custom"]).optional(),	previewRequireCollaboratorPermissions: z.boolean().optional(),	watchPaths: z.array(z.string()).optional().optional(),	previewLabels: z.array(z.string()).optional(),	cleanCache: z.boolean().optional(),	stopGracePeriodSwarm: z.number().nullable(),	endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(),	ulimitsSwarm: UlimitsSwarmSchema.nullable(),	enableSubmodules: z.boolean().optional(),	icon: z		.string()		.max(2 * 1024 * 1024, "Icon must be less than 2MB")		.nullable()		.optional(),}); export const apiCreateApplication = createSchema.pick({	name: true,	appName: true,	description: true,	environmentId: true,	serverId: true,}); export const apiFindOneApplication = z.object({	applicationId: z.string().min(1),}); export const apiDeployApplication = createSchema	.pick({		applicationId: true,	})	.extend({		applicationId: z.string().min(1),		title: z.string().optional(),		description: z.string().optional(),	}); export const apiRedeployApplication = createSchema	.pick({		applicationId: true,	})	.extend({		applicationId: z.string().min(1),		title: z.string().optional(),		description: z.string().optional(),	}); export const apiReloadApplication = createSchema	.pick({		appName: true,		applicationId: true,	})	.required(); export const apiSaveBuildType = createSchema	.pick({		applicationId: true,		buildType: true,		dockerfile: true,		dockerContextPath: true,		dockerBuildStage: true,		herokuVersion: true,		railpackVersion: true,	})	.required()	.merge(createSchema.pick({ publishDirectory: true, isStaticSpa: true })); const branchField = z	.string()	.min(1)	.regex(VALID_BRANCH_REGEX, "Invalid branch name"); export const apiSaveGithubProvider = createSchema	.pick({		applicationId: true,		repository: true,		owner: true,		buildPath: true,		githubId: true,	})	.required()	.extend({		branch: branchField,		triggerType: z.enum(["push", "tag"]).default("push"),	})	.required()	.merge(createSchema.pick({ enableSubmodules: true, watchPaths: true })); export const apiSaveGitlabProvider = createSchema	.pick({		applicationId: true,		gitlabBuildPath: true,		gitlabOwner: true,		gitlabRepository: true,		gitlabId: true,		gitlabProjectId: true,		gitlabPathNamespace: true,	})	.required()	.extend({ gitlabBranch: branchField })	.merge(createSchema.pick({ enableSubmodules: true, watchPaths: true })); export const apiSaveBitbucketProvider = createSchema	.pick({		bitbucketBuildPath: true,		bitbucketOwner: true,		bitbucketRepository: true,		bitbucketRepositorySlug: true,		bitbucketId: true,		applicationId: true,	})	.required()	.extend({ bitbucketBranch: branchField })	.merge(createSchema.pick({ enableSubmodules: true, watchPaths: true })); export const apiSaveGiteaProvider = createSchema	.pick({		applicationId: true,		giteaBuildPath: true,		giteaOwner: true,		giteaRepository: true,		giteaId: true,	})	.required()	.extend({ giteaBranch: branchField })	.merge(createSchema.pick({ enableSubmodules: true, watchPaths: true })); 

Lines 1–500 of 547.