format: fix formatting

This commit is contained in:
djknaeckebrot 2024-12-23 08:39:50 +01:00
parent fa710d4855
commit c6892ba188

View File

@ -5,42 +5,42 @@ import { type apiCreateCompose, compose } from "@dokploy/server/db/schema";
import { buildAppName, cleanAppName } from "@dokploy/server/db/schema"; import { buildAppName, cleanAppName } from "@dokploy/server/db/schema";
import { generatePassword } from "@dokploy/server/templates/utils"; import { generatePassword } from "@dokploy/server/templates/utils";
import { import {
buildCompose, buildCompose,
getBuildComposeCommand, getBuildComposeCommand,
} from "@dokploy/server/utils/builders/compose"; } from "@dokploy/server/utils/builders/compose";
import { randomizeSpecificationFile } from "@dokploy/server/utils/docker/compose"; import { randomizeSpecificationFile } from "@dokploy/server/utils/docker/compose";
import { import {
cloneCompose, cloneCompose,
cloneComposeRemote, cloneComposeRemote,
loadDockerCompose, loadDockerCompose,
loadDockerComposeRemote, loadDockerComposeRemote,
} from "@dokploy/server/utils/docker/domain"; } from "@dokploy/server/utils/docker/domain";
import type { ComposeSpecification } from "@dokploy/server/utils/docker/types"; import type { ComposeSpecification } from "@dokploy/server/utils/docker/types";
import { sendBuildErrorNotifications } from "@dokploy/server/utils/notifications/build-error"; import { sendBuildErrorNotifications } from "@dokploy/server/utils/notifications/build-error";
import { sendBuildSuccessNotifications } from "@dokploy/server/utils/notifications/build-success"; import { sendBuildSuccessNotifications } from "@dokploy/server/utils/notifications/build-success";
import { import {
execAsync, execAsync,
execAsyncRemote, execAsyncRemote,
} from "@dokploy/server/utils/process/execAsync"; } from "@dokploy/server/utils/process/execAsync";
import { import {
cloneBitbucketRepository, cloneBitbucketRepository,
getBitbucketCloneCommand, getBitbucketCloneCommand,
} from "@dokploy/server/utils/providers/bitbucket"; } from "@dokploy/server/utils/providers/bitbucket";
import { import {
cloneGitRepository, cloneGitRepository,
getCustomGitCloneCommand, getCustomGitCloneCommand,
} from "@dokploy/server/utils/providers/git"; } from "@dokploy/server/utils/providers/git";
import { import {
cloneGithubRepository, cloneGithubRepository,
getGithubCloneCommand, getGithubCloneCommand,
} from "@dokploy/server/utils/providers/github"; } from "@dokploy/server/utils/providers/github";
import { import {
cloneGitlabRepository, cloneGitlabRepository,
getGitlabCloneCommand, getGitlabCloneCommand,
} from "@dokploy/server/utils/providers/gitlab"; } from "@dokploy/server/utils/providers/gitlab";
import { import {
createComposeFile, createComposeFile,
getCreateComposeFileCommand, getCreateComposeFileCommand,
} from "@dokploy/server/utils/providers/raw"; } from "@dokploy/server/utils/providers/raw";
import { TRPCError } from "@trpc/server"; import { TRPCError } from "@trpc/server";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
@ -52,501 +52,501 @@ import { validUniqueServerAppName } from "./project";
export type Compose = typeof compose.$inferSelect; export type Compose = typeof compose.$inferSelect;
export const createCompose = async (input: typeof apiCreateCompose._type) => { export const createCompose = async (input: typeof apiCreateCompose._type) => {
const appName = buildAppName("compose", input.appName); const appName = buildAppName("compose", input.appName);
const valid = await validUniqueServerAppName(appName); const valid = await validUniqueServerAppName(appName);
if (!valid) { if (!valid) {
throw new TRPCError({ throw new TRPCError({
code: "CONFLICT", code: "CONFLICT",
message: "Service with this 'AppName' already exists", message: "Service with this 'AppName' already exists",
}); });
} }
const newDestination = await db const newDestination = await db
.insert(compose) .insert(compose)
.values({ .values({
...input, ...input,
composeFile: "", composeFile: "",
appName, appName,
}) })
.returning() .returning()
.then((value) => value[0]); .then((value) => value[0]);
if (!newDestination) { if (!newDestination) {
throw new TRPCError({ throw new TRPCError({
code: "BAD_REQUEST", code: "BAD_REQUEST",
message: "Error input: Inserting compose", message: "Error input: Inserting compose",
}); });
} }
return newDestination; return newDestination;
}; };
export const createComposeByTemplate = async ( export const createComposeByTemplate = async (
input: typeof compose.$inferInsert input: typeof compose.$inferInsert,
) => { ) => {
const appName = cleanAppName(input.appName); const appName = cleanAppName(input.appName);
if (appName) { if (appName) {
const valid = await validUniqueServerAppName(appName); const valid = await validUniqueServerAppName(appName);
if (!valid) { if (!valid) {
throw new TRPCError({ throw new TRPCError({
code: "CONFLICT", code: "CONFLICT",
message: "Service with this 'AppName' already exists", message: "Service with this 'AppName' already exists",
}); });
} }
} }
const newDestination = await db const newDestination = await db
.insert(compose) .insert(compose)
.values({ .values({
...input, ...input,
appName, appName,
}) })
.returning() .returning()
.then((value) => value[0]); .then((value) => value[0]);
if (!newDestination) { if (!newDestination) {
throw new TRPCError({ throw new TRPCError({
code: "BAD_REQUEST", code: "BAD_REQUEST",
message: "Error input: Inserting compose", message: "Error input: Inserting compose",
}); });
} }
return newDestination; return newDestination;
}; };
export const findComposeById = async (composeId: string) => { export const findComposeById = async (composeId: string) => {
const result = await db.query.compose.findFirst({ const result = await db.query.compose.findFirst({
where: eq(compose.composeId, composeId), where: eq(compose.composeId, composeId),
with: { with: {
project: true, project: true,
deployments: true, deployments: true,
mounts: true, mounts: true,
domains: true, domains: true,
github: true, github: true,
gitlab: true, gitlab: true,
bitbucket: true, bitbucket: true,
server: true, server: true,
}, },
}); });
if (!result) { if (!result) {
throw new TRPCError({ throw new TRPCError({
code: "NOT_FOUND", code: "NOT_FOUND",
message: "Compose not found", message: "Compose not found",
}); });
} }
return result; return result;
}; };
export const loadServices = async ( export const loadServices = async (
composeId: string, composeId: string,
type: "fetch" | "cache" = "fetch" type: "fetch" | "cache" = "fetch",
) => { ) => {
const compose = await findComposeById(composeId); const compose = await findComposeById(composeId);
if (type === "fetch") { if (type === "fetch") {
if (compose.serverId) { if (compose.serverId) {
await cloneComposeRemote(compose); await cloneComposeRemote(compose);
} else { } else {
await cloneCompose(compose); await cloneCompose(compose);
} }
} }
let composeData: ComposeSpecification | null; let composeData: ComposeSpecification | null;
if (compose.serverId) { if (compose.serverId) {
composeData = await loadDockerComposeRemote(compose); composeData = await loadDockerComposeRemote(compose);
} else { } else {
composeData = await loadDockerCompose(compose); composeData = await loadDockerCompose(compose);
} }
if (compose.randomize && composeData) { if (compose.randomize && composeData) {
const randomizedCompose = randomizeSpecificationFile( const randomizedCompose = randomizeSpecificationFile(
composeData, composeData,
compose.suffix compose.suffix,
); );
composeData = randomizedCompose; composeData = randomizedCompose;
} }
if (!composeData?.services) { if (!composeData?.services) {
throw new TRPCError({ throw new TRPCError({
code: "NOT_FOUND", code: "NOT_FOUND",
message: "Services not found", message: "Services not found",
}); });
} }
const services = Object.keys(composeData.services); const services = Object.keys(composeData.services);
return [...services]; return [...services];
}; };
export const updateCompose = async ( export const updateCompose = async (
composeId: string, composeId: string,
composeData: Partial<Compose> composeData: Partial<Compose>,
) => { ) => {
const { appName, ...rest } = composeData; const { appName, ...rest } = composeData;
const composeResult = await db const composeResult = await db
.update(compose) .update(compose)
.set({ .set({
...rest, ...rest,
}) })
.where(eq(compose.composeId, composeId)) .where(eq(compose.composeId, composeId))
.returning(); .returning();
return composeResult[0]; return composeResult[0];
}; };
export const deployCompose = async ({ export const deployCompose = async ({
composeId, composeId,
titleLog = "Manual deployment", titleLog = "Manual deployment",
descriptionLog = "", descriptionLog = "",
}: { }: {
composeId: string; composeId: string;
titleLog: string; titleLog: string;
descriptionLog: string; descriptionLog: string;
}) => { }) => {
const compose = await findComposeById(composeId); const compose = await findComposeById(composeId);
const buildLink = `${await getDokployUrl()}/dashboard/project/${ const buildLink = `${await getDokployUrl()}/dashboard/project/${
compose.projectId compose.projectId
}/services/compose/${compose.composeId}?tab=deployments`; }/services/compose/${compose.composeId}?tab=deployments`;
const deployment = await createDeploymentCompose({ const deployment = await createDeploymentCompose({
composeId: composeId, composeId: composeId,
title: titleLog, title: titleLog,
description: descriptionLog, description: descriptionLog,
}); });
try { try {
if (compose.sourceType === "github") { if (compose.sourceType === "github") {
await cloneGithubRepository({ await cloneGithubRepository({
...compose, ...compose,
logPath: deployment.logPath, logPath: deployment.logPath,
type: "compose", type: "compose",
}); });
} else if (compose.sourceType === "gitlab") { } else if (compose.sourceType === "gitlab") {
await cloneGitlabRepository(compose, deployment.logPath, true); await cloneGitlabRepository(compose, deployment.logPath, true);
} else if (compose.sourceType === "bitbucket") { } else if (compose.sourceType === "bitbucket") {
await cloneBitbucketRepository(compose, deployment.logPath, true); await cloneBitbucketRepository(compose, deployment.logPath, true);
} else if (compose.sourceType === "git") { } else if (compose.sourceType === "git") {
await cloneGitRepository(compose, deployment.logPath, true); await cloneGitRepository(compose, deployment.logPath, true);
} else if (compose.sourceType === "raw") { } else if (compose.sourceType === "raw") {
await createComposeFile(compose, deployment.logPath); await createComposeFile(compose, deployment.logPath);
} }
await buildCompose(compose, deployment.logPath); await buildCompose(compose, deployment.logPath);
await updateDeploymentStatus(deployment.deploymentId, "done"); await updateDeploymentStatus(deployment.deploymentId, "done");
await updateCompose(composeId, { await updateCompose(composeId, {
composeStatus: "done", composeStatus: "done",
}); });
await sendBuildSuccessNotifications({ await sendBuildSuccessNotifications({
projectName: compose.project.name, projectName: compose.project.name,
applicationName: compose.name, applicationName: compose.name,
applicationType: "compose", applicationType: "compose",
buildLink, buildLink,
adminId: compose.project.adminId, adminId: compose.project.adminId,
}); });
} catch (error) { } catch (error) {
await updateDeploymentStatus(deployment.deploymentId, "error"); await updateDeploymentStatus(deployment.deploymentId, "error");
await updateCompose(composeId, { await updateCompose(composeId, {
composeStatus: "error", composeStatus: "error",
}); });
await sendBuildErrorNotifications({ await sendBuildErrorNotifications({
projectName: compose.project.name, projectName: compose.project.name,
applicationName: compose.name, applicationName: compose.name,
applicationType: "compose", applicationType: "compose",
// @ts-ignore // @ts-ignore
errorMessage: error?.message || "Error to build", errorMessage: error?.message || "Error to build",
buildLink, buildLink,
adminId: compose.project.adminId, adminId: compose.project.adminId,
}); });
throw error; throw error;
} }
}; };
export const rebuildCompose = async ({ export const rebuildCompose = async ({
composeId, composeId,
titleLog = "Rebuild deployment", titleLog = "Rebuild deployment",
descriptionLog = "", descriptionLog = "",
}: { }: {
composeId: string; composeId: string;
titleLog: string; titleLog: string;
descriptionLog: string; descriptionLog: string;
}) => { }) => {
const compose = await findComposeById(composeId); const compose = await findComposeById(composeId);
const deployment = await createDeploymentCompose({ const deployment = await createDeploymentCompose({
composeId: composeId, composeId: composeId,
title: titleLog, title: titleLog,
description: descriptionLog, description: descriptionLog,
}); });
try { try {
if (compose.serverId) { if (compose.serverId) {
await getBuildComposeCommand(compose, deployment.logPath); await getBuildComposeCommand(compose, deployment.logPath);
} else { } else {
await buildCompose(compose, deployment.logPath); await buildCompose(compose, deployment.logPath);
} }
await updateDeploymentStatus(deployment.deploymentId, "done"); await updateDeploymentStatus(deployment.deploymentId, "done");
await updateCompose(composeId, { await updateCompose(composeId, {
composeStatus: "done", composeStatus: "done",
}); });
} catch (error) { } catch (error) {
await updateDeploymentStatus(deployment.deploymentId, "error"); await updateDeploymentStatus(deployment.deploymentId, "error");
await updateCompose(composeId, { await updateCompose(composeId, {
composeStatus: "error", composeStatus: "error",
}); });
throw error; throw error;
} }
return true; return true;
}; };
export const deployRemoteCompose = async ({ export const deployRemoteCompose = async ({
composeId, composeId,
titleLog = "Manual deployment", titleLog = "Manual deployment",
descriptionLog = "", descriptionLog = "",
}: { }: {
composeId: string; composeId: string;
titleLog: string; titleLog: string;
descriptionLog: string; descriptionLog: string;
}) => { }) => {
const compose = await findComposeById(composeId); const compose = await findComposeById(composeId);
const buildLink = `${await getDokployUrl()}/dashboard/project/${ const buildLink = `${await getDokployUrl()}/dashboard/project/${
compose.projectId compose.projectId
}/services/compose/${compose.composeId}?tab=deployments`; }/services/compose/${compose.composeId}?tab=deployments`;
const deployment = await createDeploymentCompose({ const deployment = await createDeploymentCompose({
composeId: composeId, composeId: composeId,
title: titleLog, title: titleLog,
description: descriptionLog, description: descriptionLog,
}); });
try { try {
if (compose.serverId) { if (compose.serverId) {
let command = "set -e;"; let command = "set -e;";
if (compose.sourceType === "github") { if (compose.sourceType === "github") {
command += await getGithubCloneCommand({ command += await getGithubCloneCommand({
...compose, ...compose,
logPath: deployment.logPath, logPath: deployment.logPath,
type: "compose", type: "compose",
serverId: compose.serverId, serverId: compose.serverId,
}); });
} else if (compose.sourceType === "gitlab") { } else if (compose.sourceType === "gitlab") {
command += await getGitlabCloneCommand( command += await getGitlabCloneCommand(
compose, compose,
deployment.logPath, deployment.logPath,
true true,
); );
} else if (compose.sourceType === "bitbucket") { } else if (compose.sourceType === "bitbucket") {
command += await getBitbucketCloneCommand( command += await getBitbucketCloneCommand(
compose, compose,
deployment.logPath, deployment.logPath,
true true,
); );
} else if (compose.sourceType === "git") { } else if (compose.sourceType === "git") {
command += await getCustomGitCloneCommand( command += await getCustomGitCloneCommand(
compose, compose,
deployment.logPath, deployment.logPath,
true true,
); );
} else if (compose.sourceType === "raw") { } else if (compose.sourceType === "raw") {
command += getCreateComposeFileCommand(compose, deployment.logPath); command += getCreateComposeFileCommand(compose, deployment.logPath);
} }
await execAsyncRemote(compose.serverId, command); await execAsyncRemote(compose.serverId, command);
await getBuildComposeCommand(compose, deployment.logPath); await getBuildComposeCommand(compose, deployment.logPath);
} }
await updateDeploymentStatus(deployment.deploymentId, "done"); await updateDeploymentStatus(deployment.deploymentId, "done");
await updateCompose(composeId, { await updateCompose(composeId, {
composeStatus: "done", composeStatus: "done",
}); });
await sendBuildSuccessNotifications({ await sendBuildSuccessNotifications({
projectName: compose.project.name, projectName: compose.project.name,
applicationName: compose.name, applicationName: compose.name,
applicationType: "compose", applicationType: "compose",
buildLink, buildLink,
adminId: compose.project.adminId, adminId: compose.project.adminId,
}); });
} catch (error) { } catch (error) {
// @ts-ignore // @ts-ignore
const encodedContent = encodeBase64(error?.message); const encodedContent = encodeBase64(error?.message);
await execAsyncRemote( await execAsyncRemote(
compose.serverId, compose.serverId,
` `
echo "\n\n===================================EXTRA LOGS============================================" >> ${deployment.logPath}; echo "\n\n===================================EXTRA LOGS============================================" >> ${deployment.logPath};
echo "Error occurred ❌, check the logs for details." >> ${deployment.logPath}; echo "Error occurred ❌, check the logs for details." >> ${deployment.logPath};
echo "${encodedContent}" | base64 -d >> "${deployment.logPath}";` echo "${encodedContent}" | base64 -d >> "${deployment.logPath}";`,
); );
await updateDeploymentStatus(deployment.deploymentId, "error"); await updateDeploymentStatus(deployment.deploymentId, "error");
await updateCompose(composeId, { await updateCompose(composeId, {
composeStatus: "error", composeStatus: "error",
}); });
await sendBuildErrorNotifications({ await sendBuildErrorNotifications({
projectName: compose.project.name, projectName: compose.project.name,
applicationName: compose.name, applicationName: compose.name,
applicationType: "compose", applicationType: "compose",
// @ts-ignore // @ts-ignore
errorMessage: error?.message || "Error to build", errorMessage: error?.message || "Error to build",
buildLink, buildLink,
adminId: compose.project.adminId, adminId: compose.project.adminId,
}); });
throw error; throw error;
} }
}; };
export const rebuildRemoteCompose = async ({ export const rebuildRemoteCompose = async ({
composeId, composeId,
titleLog = "Rebuild deployment", titleLog = "Rebuild deployment",
descriptionLog = "", descriptionLog = "",
}: { }: {
composeId: string; composeId: string;
titleLog: string; titleLog: string;
descriptionLog: string; descriptionLog: string;
}) => { }) => {
const compose = await findComposeById(composeId); const compose = await findComposeById(composeId);
const deployment = await createDeploymentCompose({ const deployment = await createDeploymentCompose({
composeId: composeId, composeId: composeId,
title: titleLog, title: titleLog,
description: descriptionLog, description: descriptionLog,
}); });
try { try {
if (compose.serverId) { if (compose.serverId) {
await getBuildComposeCommand(compose, deployment.logPath); await getBuildComposeCommand(compose, deployment.logPath);
} }
await updateDeploymentStatus(deployment.deploymentId, "done"); await updateDeploymentStatus(deployment.deploymentId, "done");
await updateCompose(composeId, { await updateCompose(composeId, {
composeStatus: "done", composeStatus: "done",
}); });
} catch (error) { } catch (error) {
// @ts-ignore // @ts-ignore
const encodedContent = encodeBase64(error?.message); const encodedContent = encodeBase64(error?.message);
await execAsyncRemote( await execAsyncRemote(
compose.serverId, compose.serverId,
` `
echo "\n\n===================================EXTRA LOGS============================================" >> ${deployment.logPath}; echo "\n\n===================================EXTRA LOGS============================================" >> ${deployment.logPath};
echo "Error occurred ❌, check the logs for details." >> ${deployment.logPath}; echo "Error occurred ❌, check the logs for details." >> ${deployment.logPath};
echo "${encodedContent}" | base64 -d >> "${deployment.logPath}";` echo "${encodedContent}" | base64 -d >> "${deployment.logPath}";`,
); );
await updateDeploymentStatus(deployment.deploymentId, "error"); await updateDeploymentStatus(deployment.deploymentId, "error");
await updateCompose(composeId, { await updateCompose(composeId, {
composeStatus: "error", composeStatus: "error",
}); });
throw error; throw error;
} }
return true; return true;
}; };
export const removeCompose = async ( export const removeCompose = async (
compose: Compose, compose: Compose,
deleteVolumes: boolean deleteVolumes: boolean,
) => { ) => {
try { try {
const { COMPOSE_PATH } = paths(!!compose.serverId); const { COMPOSE_PATH } = paths(!!compose.serverId);
const projectPath = join(COMPOSE_PATH, compose.appName); const projectPath = join(COMPOSE_PATH, compose.appName);
console.log("API: DELETE VOLUMES=", deleteVolumes); console.log("API: DELETE VOLUMES=", deleteVolumes);
if (compose.composeType === "stack") { if (compose.composeType === "stack") {
const command = `cd ${projectPath} && docker stack rm ${compose.appName} && rm -rf ${projectPath}`; const command = `cd ${projectPath} && docker stack rm ${compose.appName} && rm -rf ${projectPath}`;
if (compose.serverId) { if (compose.serverId) {
await execAsyncRemote(compose.serverId, command); await execAsyncRemote(compose.serverId, command);
} else { } else {
await execAsync(command); await execAsync(command);
} }
await execAsync(command, { await execAsync(command, {
cwd: projectPath, cwd: projectPath,
}); });
} else { } else {
let command: string; let command: string;
if (deleteVolumes) { if (deleteVolumes) {
command = `cd ${projectPath} && docker compose -p ${compose.appName} down --volumes && rm -rf ${projectPath}`; command = `cd ${projectPath} && docker compose -p ${compose.appName} down --volumes && rm -rf ${projectPath}`;
} else { } else {
command = `cd ${projectPath} && docker compose -p ${compose.appName} down && rm -rf ${projectPath}`; command = `cd ${projectPath} && docker compose -p ${compose.appName} down && rm -rf ${projectPath}`;
} }
if (compose.serverId) { if (compose.serverId) {
await execAsyncRemote(compose.serverId, command); await execAsyncRemote(compose.serverId, command);
} else { } else {
await execAsync(command, { await execAsync(command, {
cwd: projectPath, cwd: projectPath,
}); });
} }
} }
} catch (error) { } catch (error) {
throw error; throw error;
} }
return true; return true;
}; };
export const startCompose = async (composeId: string) => { export const startCompose = async (composeId: string) => {
const compose = await findComposeById(composeId); const compose = await findComposeById(composeId);
try { try {
const { COMPOSE_PATH } = paths(!!compose.serverId); const { COMPOSE_PATH } = paths(!!compose.serverId);
if (compose.composeType === "docker-compose") { if (compose.composeType === "docker-compose") {
if (compose.serverId) { if (compose.serverId) {
await execAsyncRemote( await execAsyncRemote(
compose.serverId, compose.serverId,
`cd ${join( `cd ${join(
COMPOSE_PATH, COMPOSE_PATH,
compose.appName, compose.appName,
"code" "code",
)} && docker compose -p ${compose.appName} up -d` )} && docker compose -p ${compose.appName} up -d`,
); );
} else { } else {
await execAsync(`docker compose -p ${compose.appName} up -d`, { await execAsync(`docker compose -p ${compose.appName} up -d`, {
cwd: join(COMPOSE_PATH, compose.appName, "code"), cwd: join(COMPOSE_PATH, compose.appName, "code"),
}); });
} }
} }
await updateCompose(composeId, { await updateCompose(composeId, {
composeStatus: "done", composeStatus: "done",
}); });
} catch (error) { } catch (error) {
await updateCompose(composeId, { await updateCompose(composeId, {
composeStatus: "idle", composeStatus: "idle",
}); });
throw error; throw error;
} }
return true; return true;
}; };
export const stopCompose = async (composeId: string) => { export const stopCompose = async (composeId: string) => {
const compose = await findComposeById(composeId); const compose = await findComposeById(composeId);
try { try {
const { COMPOSE_PATH } = paths(!!compose.serverId); const { COMPOSE_PATH } = paths(!!compose.serverId);
if (compose.composeType === "docker-compose") { if (compose.composeType === "docker-compose") {
if (compose.serverId) { if (compose.serverId) {
await execAsyncRemote( await execAsyncRemote(
compose.serverId, compose.serverId,
`cd ${join(COMPOSE_PATH, compose.appName)} && docker compose -p ${ `cd ${join(COMPOSE_PATH, compose.appName)} && docker compose -p ${
compose.appName compose.appName
} stop` } stop`,
); );
} else { } else {
await execAsync(`docker compose -p ${compose.appName} stop`, { await execAsync(`docker compose -p ${compose.appName} stop`, {
cwd: join(COMPOSE_PATH, compose.appName), cwd: join(COMPOSE_PATH, compose.appName),
}); });
} }
} }
await updateCompose(composeId, { await updateCompose(composeId, {
composeStatus: "idle", composeStatus: "idle",
}); });
} catch (error) { } catch (error) {
await updateCompose(composeId, { await updateCompose(composeId, {
composeStatus: "error", composeStatus: "error",
}); });
throw error; throw error;
} }
return true; return true;
}; };