mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-10-15 05:11:26 +00:00
6e1d020769
- Updated ShowIconSettings component to handle both application and compose service types. - Added new icon column to the compose table in the database. - Implemented fetching and updating of icons for services in the environment and application pages. - Introduced fetchTemplateLogo function to retrieve logos for templates, improving icon handling for compose services.
413 lines
8.8 KiB
TypeScript
413 lines
8.8 KiB
TypeScript
import { db } from "@dokploy/server/db";
|
|
import {
|
|
type apiCreateEnvironment,
|
|
type apiDuplicateEnvironment,
|
|
environments,
|
|
} from "@dokploy/server/db/schema";
|
|
import { TRPCError } from "@trpc/server";
|
|
import { asc, eq } from "drizzle-orm";
|
|
import type { z } from "zod";
|
|
|
|
export type Environment = typeof environments.$inferSelect;
|
|
|
|
export const createEnvironment = async (
|
|
input: z.infer<typeof apiCreateEnvironment>,
|
|
) => {
|
|
const newEnvironment = await db
|
|
.insert(environments)
|
|
.values({
|
|
...input,
|
|
})
|
|
.returning()
|
|
.then((value) => value[0]);
|
|
|
|
if (!newEnvironment) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error creating the environment",
|
|
});
|
|
}
|
|
|
|
return newEnvironment;
|
|
};
|
|
|
|
export const findEnvironmentById = async (environmentId: string) => {
|
|
const environment = await db.query.environments.findFirst({
|
|
where: eq(environments.environmentId, environmentId),
|
|
columns: {
|
|
name: true,
|
|
description: true,
|
|
environmentId: true,
|
|
isDefault: true,
|
|
projectId: true,
|
|
env: true,
|
|
},
|
|
with: {
|
|
applications: {
|
|
with: {
|
|
server: {
|
|
columns: {
|
|
name: true,
|
|
serverId: true,
|
|
},
|
|
},
|
|
},
|
|
columns: {
|
|
name: true,
|
|
applicationId: true,
|
|
createdAt: true,
|
|
applicationStatus: true,
|
|
description: true,
|
|
serverId: true,
|
|
icon: true,
|
|
},
|
|
},
|
|
mariadb: {
|
|
with: {
|
|
server: {
|
|
columns: {
|
|
name: true,
|
|
serverId: true,
|
|
},
|
|
},
|
|
},
|
|
columns: {
|
|
mariadbId: true,
|
|
name: true,
|
|
createdAt: true,
|
|
applicationStatus: true,
|
|
description: true,
|
|
serverId: true,
|
|
},
|
|
},
|
|
mongo: {
|
|
with: {
|
|
server: {
|
|
columns: {
|
|
name: true,
|
|
serverId: true,
|
|
},
|
|
},
|
|
},
|
|
columns: {
|
|
mongoId: true,
|
|
name: true,
|
|
createdAt: true,
|
|
applicationStatus: true,
|
|
description: true,
|
|
serverId: true,
|
|
},
|
|
},
|
|
mysql: {
|
|
with: {
|
|
server: {
|
|
columns: {
|
|
name: true,
|
|
serverId: true,
|
|
},
|
|
},
|
|
},
|
|
columns: {
|
|
mysqlId: true,
|
|
name: true,
|
|
createdAt: true,
|
|
applicationStatus: true,
|
|
description: true,
|
|
serverId: true,
|
|
},
|
|
},
|
|
postgres: {
|
|
with: {
|
|
server: {
|
|
columns: {
|
|
name: true,
|
|
serverId: true,
|
|
},
|
|
},
|
|
},
|
|
columns: {
|
|
postgresId: true,
|
|
name: true,
|
|
description: true,
|
|
createdAt: true,
|
|
applicationStatus: true,
|
|
serverId: true,
|
|
},
|
|
},
|
|
redis: {
|
|
with: {
|
|
server: {
|
|
columns: {
|
|
name: true,
|
|
serverId: true,
|
|
},
|
|
},
|
|
},
|
|
columns: {
|
|
redisId: true,
|
|
name: true,
|
|
createdAt: true,
|
|
applicationStatus: true,
|
|
description: true,
|
|
serverId: true,
|
|
},
|
|
},
|
|
compose: {
|
|
with: {
|
|
server: {
|
|
columns: {
|
|
name: true,
|
|
serverId: true,
|
|
},
|
|
},
|
|
},
|
|
columns: {
|
|
composeId: true,
|
|
name: true,
|
|
createdAt: true,
|
|
composeStatus: true,
|
|
description: true,
|
|
serverId: true,
|
|
icon: true,
|
|
},
|
|
},
|
|
libsql: {
|
|
with: {
|
|
server: {
|
|
columns: {
|
|
name: true,
|
|
serverId: true,
|
|
},
|
|
},
|
|
},
|
|
columns: {
|
|
libsqlId: true,
|
|
name: true,
|
|
createdAt: true,
|
|
applicationStatus: true,
|
|
description: true,
|
|
serverId: true,
|
|
},
|
|
},
|
|
project: true,
|
|
},
|
|
});
|
|
if (!environment) {
|
|
throw new TRPCError({
|
|
code: "NOT_FOUND",
|
|
message: "Environment not found",
|
|
});
|
|
}
|
|
return environment;
|
|
};
|
|
|
|
export const findEnvironmentsByProjectId = async (projectId: string) => {
|
|
const serviceColumns = {
|
|
name: true,
|
|
description: true,
|
|
appName: true,
|
|
createdAt: true,
|
|
serverId: true,
|
|
applicationStatus: true,
|
|
} as const;
|
|
|
|
const projectEnvironments = await db.query.environments.findMany({
|
|
where: eq(environments.projectId, projectId),
|
|
orderBy: asc(environments.createdAt),
|
|
with: {
|
|
applications: {
|
|
columns: { ...serviceColumns, applicationId: true, icon: true },
|
|
with: { server: { columns: { name: true } } },
|
|
},
|
|
mariadb: {
|
|
columns: { ...serviceColumns, mariadbId: true },
|
|
with: { server: { columns: { name: true } } },
|
|
},
|
|
mongo: {
|
|
columns: { ...serviceColumns, mongoId: true },
|
|
with: { server: { columns: { name: true } } },
|
|
},
|
|
mysql: {
|
|
columns: { ...serviceColumns, mysqlId: true },
|
|
with: { server: { columns: { name: true } } },
|
|
},
|
|
postgres: {
|
|
columns: { ...serviceColumns, postgresId: true },
|
|
with: { server: { columns: { name: true } } },
|
|
},
|
|
redis: {
|
|
columns: { ...serviceColumns, redisId: true },
|
|
with: { server: { columns: { name: true } } },
|
|
},
|
|
compose: {
|
|
columns: {
|
|
...serviceColumns,
|
|
composeId: true,
|
|
composeStatus: true,
|
|
icon: true,
|
|
},
|
|
with: { server: { columns: { name: true } } },
|
|
},
|
|
libsql: {
|
|
columns: { ...serviceColumns, libsqlId: true },
|
|
with: { server: { columns: { name: true } } },
|
|
},
|
|
project: true,
|
|
},
|
|
columns: {
|
|
name: true,
|
|
description: true,
|
|
environmentId: true,
|
|
isDefault: true,
|
|
},
|
|
});
|
|
return projectEnvironments;
|
|
};
|
|
|
|
const environmentHasServices = (
|
|
env: Awaited<ReturnType<typeof findEnvironmentById>>,
|
|
) => {
|
|
return (
|
|
(env.applications?.length ?? 0) > 0 ||
|
|
(env.compose?.length ?? 0) > 0 ||
|
|
(env.libsql?.length ?? 0) > 0 ||
|
|
(env.mariadb?.length ?? 0) > 0 ||
|
|
(env.mongo?.length ?? 0) > 0 ||
|
|
(env.mysql?.length ?? 0) > 0 ||
|
|
(env.postgres?.length ?? 0) > 0 ||
|
|
(env.redis?.length ?? 0) > 0
|
|
);
|
|
};
|
|
|
|
export const deleteEnvironment = async (environmentId: string) => {
|
|
const currentEnvironment = await findEnvironmentById(environmentId);
|
|
if (currentEnvironment.isDefault) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "You cannot delete the default environment",
|
|
});
|
|
}
|
|
if (environmentHasServices(currentEnvironment)) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message:
|
|
"Cannot delete environment: it has active services. Delete all services first.",
|
|
});
|
|
}
|
|
const deletedEnvironment = await db
|
|
.delete(environments)
|
|
.where(eq(environments.environmentId, environmentId))
|
|
.returning()
|
|
.then((value) => value[0]);
|
|
|
|
return deletedEnvironment;
|
|
};
|
|
|
|
export const updateEnvironmentById = async (
|
|
environmentId: string,
|
|
environmentData: Partial<Environment>,
|
|
) => {
|
|
const result = await db
|
|
.update(environments)
|
|
.set({
|
|
...environmentData,
|
|
})
|
|
.where(eq(environments.environmentId, environmentId))
|
|
.returning()
|
|
.then((res) => res[0]);
|
|
|
|
return result;
|
|
};
|
|
|
|
export const duplicateEnvironment = async (
|
|
input: z.infer<typeof apiDuplicateEnvironment>,
|
|
) => {
|
|
// Find the original environment
|
|
const originalEnvironment = await findEnvironmentById(input.environmentId);
|
|
|
|
// Create a new environment with the provided name and description
|
|
const newEnvironment = await db
|
|
.insert(environments)
|
|
.values({
|
|
name: input.name,
|
|
description: input.description || originalEnvironment.description,
|
|
projectId: originalEnvironment.projectId,
|
|
env: originalEnvironment.env,
|
|
})
|
|
.returning()
|
|
.then((value) => value[0]);
|
|
|
|
if (!newEnvironment) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error duplicating the environment",
|
|
});
|
|
}
|
|
|
|
return newEnvironment;
|
|
};
|
|
|
|
interface EnvironmentWithServices {
|
|
applications: { applicationId: string }[];
|
|
compose: { composeId: string }[];
|
|
libsql: { libsqlId: string }[];
|
|
mariadb: { mariadbId: string }[];
|
|
mongo: { mongoId: string }[];
|
|
mysql: { mysqlId: string }[];
|
|
postgres: { postgresId: string }[];
|
|
redis: { redisId: string }[];
|
|
}
|
|
|
|
export const filterEnvironmentServices = <T extends EnvironmentWithServices>(
|
|
environment: T,
|
|
accessedServices: string[],
|
|
): T => ({
|
|
...environment,
|
|
applications: environment.applications.filter((app) =>
|
|
accessedServices.includes(app.applicationId),
|
|
),
|
|
compose: environment.compose.filter((comp) =>
|
|
accessedServices.includes(comp.composeId),
|
|
),
|
|
libsql: environment.libsql.filter((db) =>
|
|
accessedServices.includes(db.libsqlId),
|
|
),
|
|
mariadb: environment.mariadb.filter((db) =>
|
|
accessedServices.includes(db.mariadbId),
|
|
),
|
|
mongo: environment.mongo.filter((db) =>
|
|
accessedServices.includes(db.mongoId),
|
|
),
|
|
mysql: environment.mysql.filter((db) =>
|
|
accessedServices.includes(db.mysqlId),
|
|
),
|
|
postgres: environment.postgres.filter((db) =>
|
|
accessedServices.includes(db.postgresId),
|
|
),
|
|
redis: environment.redis.filter((db) =>
|
|
accessedServices.includes(db.redisId),
|
|
),
|
|
});
|
|
|
|
export const createProductionEnvironment = async (projectId: string) => {
|
|
const newEnvironment = await db
|
|
.insert(environments)
|
|
.values({
|
|
name: "production",
|
|
description: "Production environment",
|
|
projectId,
|
|
isDefault: true,
|
|
})
|
|
.returning()
|
|
.then((value) => value[0]);
|
|
|
|
if (!newEnvironment) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Error creating the production environment",
|
|
});
|
|
}
|
|
|
|
return newEnvironment;
|
|
};
|