From 938b0b4ed397fc047c98ce0648d73eec738efd09 Mon Sep 17 00:00:00 2001 From: Mohammed Imran Date: Mon, 16 Feb 2026 14:01:00 +0530 Subject: [PATCH] chore: Reorder and clean up imports, update openapi schema, and improve cache invalidation logic --- apps/dokploy/__test__/setup.ts | 1 + .../traefik/update-traefik-config.tsx | 2 +- .../dashboard/compose/logs/show.tsx | 4 +- .../dashboard/project/add-compose.tsx | 4 +- .../project/advanced-environment-selector.tsx | 2 + .../settings/git/gitea/add-gitea-provider.tsx | 2 +- .../git/gitea/edit-gitea-provider.tsx | 2 +- .../git/gitlab/add-gitlab-provider.tsx | 2 +- .../git/gitlab/edit-gitlab-provider.tsx | 2 +- .../settings/web-server/edit-traefik-env.tsx | 2 +- .../web-server/manage-traefik-ports.tsx | 2 +- .../proprietary/auth/sign-in-with-github.tsx | 2 +- .../proprietary/auth/sign-in-with-google.tsx | 2 +- apps/dokploy/server/api/root.ts | 4 +- apps/dokploy/setup.ts | 3 +- openapi.json | 2471 +++++++++++++++-- packages/server/src/services/ai.ts | 26 +- packages/server/src/services/domain.ts | 2 +- .../server/src/services/preview-deployment.ts | 2 +- 19 files changed, 2323 insertions(+), 214 deletions(-) diff --git a/apps/dokploy/__test__/setup.ts b/apps/dokploy/__test__/setup.ts index 5af01d147..41510fe72 100644 --- a/apps/dokploy/__test__/setup.ts +++ b/apps/dokploy/__test__/setup.ts @@ -12,6 +12,7 @@ vi.mock("@dokploy/server/db", () => { chain.where = () => chain; chain.values = () => chain; chain.returning = () => Promise.resolve([{}]); + // biome-ignore lint/suspicious/noThenProperty: this is for testing chain.then = undefined; const tableMock = { diff --git a/apps/dokploy/components/dashboard/application/advanced/traefik/update-traefik-config.tsx b/apps/dokploy/components/dashboard/application/advanced/traefik/update-traefik-config.tsx index 928949d9f..21893802b 100644 --- a/apps/dokploy/components/dashboard/application/advanced/traefik/update-traefik-config.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/traefik/update-traefik-config.tsx @@ -7,6 +7,7 @@ import { z } from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; import { CodeEditor } from "@/components/shared/code-editor"; import { Button } from "@/components/ui/button"; +import { Checkbox } from "@/components/ui/checkbox"; import { Dialog, DialogContent, @@ -24,7 +25,6 @@ import { FormLabel, FormMessage, } from "@/components/ui/form"; -import { Checkbox } from "@/components/ui/checkbox"; import { Label } from "@/components/ui/label"; import { api } from "@/utils/api"; diff --git a/apps/dokploy/components/dashboard/compose/logs/show.tsx b/apps/dokploy/components/dashboard/compose/logs/show.tsx index fbcdf7292..20c70e739 100644 --- a/apps/dokploy/components/dashboard/compose/logs/show.tsx +++ b/apps/dokploy/components/dashboard/compose/logs/show.tsx @@ -1,8 +1,8 @@ import { Loader2 } from "lucide-react"; -import { badgeStateColor } from "@/components/dashboard/application/logs/show"; -import { Badge } from "@/components/ui/badge"; import dynamic from "next/dynamic"; import { useEffect, useState } from "react"; +import { badgeStateColor } from "@/components/dashboard/application/logs/show"; +import { Badge } from "@/components/ui/badge"; import { Card, CardContent, diff --git a/apps/dokploy/components/dashboard/project/add-compose.tsx b/apps/dokploy/components/dashboard/project/add-compose.tsx index bb911373f..0d7e85b51 100644 --- a/apps/dokploy/components/dashboard/project/add-compose.tsx +++ b/apps/dokploy/components/dashboard/project/add-compose.tsx @@ -79,7 +79,7 @@ export const AddCompose = ({ environmentId, projectName }: Props) => { api.compose.create.useMutation(); // Get environment data to extract projectId - const { data: environment } = api.environment.one.useQuery({ environmentId }); + // const { data: environment } = api.environment.one.useQuery({ environmentId }); const hasServers = servers && servers.length > 0; // Show dropdown logic based on cloud environment @@ -117,6 +117,8 @@ export const AddCompose = ({ environmentId, projectName }: Props) => { await utils.environment.one.invalidate({ environmentId, }); + // Invalidate the project query to refresh the project data for the advance-breadcrumb + await utils.project.all.invalidate(); }) .catch(() => { toast.error("Error creating the compose"); diff --git a/apps/dokploy/components/dashboard/project/advanced-environment-selector.tsx b/apps/dokploy/components/dashboard/project/advanced-environment-selector.tsx index 678928990..42c49675f 100644 --- a/apps/dokploy/components/dashboard/project/advanced-environment-selector.tsx +++ b/apps/dokploy/components/dashboard/project/advanced-environment-selector.tsx @@ -98,6 +98,8 @@ export const AdvancedEnvironmentSelector = ({ toast.success("Environment created successfully"); utils.environment.byProjectId.invalidate({ projectId }); + // Invalidate the project query to refresh the project data for the advance-breadcrumb + utils.project.all.invalidate(); setIsCreateDialogOpen(false); setName(""); setDescription(""); diff --git a/apps/dokploy/components/dashboard/settings/git/gitea/add-gitea-provider.tsx b/apps/dokploy/components/dashboard/settings/git/gitea/add-gitea-provider.tsx index f474c376d..aa6b379c8 100644 --- a/apps/dokploy/components/dashboard/settings/git/gitea/add-gitea-provider.tsx +++ b/apps/dokploy/components/dashboard/settings/git/gitea/add-gitea-provider.tsx @@ -19,9 +19,9 @@ import { import { Form, FormControl, + FormDescription, FormField, FormItem, - FormDescription, FormLabel, FormMessage, } from "@/components/ui/form"; diff --git a/apps/dokploy/components/dashboard/settings/git/gitea/edit-gitea-provider.tsx b/apps/dokploy/components/dashboard/settings/git/gitea/edit-gitea-provider.tsx index fe578acce..cc9261a5a 100644 --- a/apps/dokploy/components/dashboard/settings/git/gitea/edit-gitea-provider.tsx +++ b/apps/dokploy/components/dashboard/settings/git/gitea/edit-gitea-provider.tsx @@ -17,9 +17,9 @@ import { import { Form, FormControl, + FormDescription, FormField, FormItem, - FormDescription, FormLabel, FormMessage, } from "@/components/ui/form"; diff --git a/apps/dokploy/components/dashboard/settings/git/gitlab/add-gitlab-provider.tsx b/apps/dokploy/components/dashboard/settings/git/gitlab/add-gitlab-provider.tsx index 69d926194..eb805743a 100644 --- a/apps/dokploy/components/dashboard/settings/git/gitlab/add-gitlab-provider.tsx +++ b/apps/dokploy/components/dashboard/settings/git/gitlab/add-gitlab-provider.tsx @@ -19,9 +19,9 @@ import { import { Form, FormControl, + FormDescription, FormField, FormItem, - FormDescription, FormLabel, FormMessage, } from "@/components/ui/form"; diff --git a/apps/dokploy/components/dashboard/settings/git/gitlab/edit-gitlab-provider.tsx b/apps/dokploy/components/dashboard/settings/git/gitlab/edit-gitlab-provider.tsx index 394e25281..3c4bad112 100644 --- a/apps/dokploy/components/dashboard/settings/git/gitlab/edit-gitlab-provider.tsx +++ b/apps/dokploy/components/dashboard/settings/git/gitlab/edit-gitlab-provider.tsx @@ -18,9 +18,9 @@ import { import { Form, FormControl, + FormDescription, FormField, FormItem, - FormDescription, FormLabel, FormMessage, } from "@/components/ui/form"; diff --git a/apps/dokploy/components/dashboard/settings/web-server/edit-traefik-env.tsx b/apps/dokploy/components/dashboard/settings/web-server/edit-traefik-env.tsx index 482b98579..e0a0bca00 100644 --- a/apps/dokploy/components/dashboard/settings/web-server/edit-traefik-env.tsx +++ b/apps/dokploy/components/dashboard/settings/web-server/edit-traefik-env.tsx @@ -1,7 +1,6 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; -import { useHealthCheckAfterMutation } from "@/hooks/use-health-check-after-mutation"; import { toast } from "sonner"; import { z } from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; @@ -24,6 +23,7 @@ import { FormLabel, FormMessage, } from "@/components/ui/form"; +import { useHealthCheckAfterMutation } from "@/hooks/use-health-check-after-mutation"; import { api } from "@/utils/api"; const schema = z.object({ diff --git a/apps/dokploy/components/dashboard/settings/web-server/manage-traefik-ports.tsx b/apps/dokploy/components/dashboard/settings/web-server/manage-traefik-ports.tsx index 73973ef06..a30cefb94 100644 --- a/apps/dokploy/components/dashboard/settings/web-server/manage-traefik-ports.tsx +++ b/apps/dokploy/components/dashboard/settings/web-server/manage-traefik-ports.tsx @@ -1,7 +1,6 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { ArrowRightLeft, Plus, Trash2 } from "lucide-react"; import { useTranslation } from "next-i18next"; -import { useHealthCheckAfterMutation } from "@/hooks/use-health-check-after-mutation"; import type React from "react"; import { useEffect, useState } from "react"; import { useFieldArray, useForm } from "react-hook-form"; @@ -36,6 +35,7 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; +import { useHealthCheckAfterMutation } from "@/hooks/use-health-check-after-mutation"; import { api } from "@/utils/api"; interface Props { diff --git a/apps/dokploy/components/proprietary/auth/sign-in-with-github.tsx b/apps/dokploy/components/proprietary/auth/sign-in-with-github.tsx index 988eeae05..22b0aef81 100644 --- a/apps/dokploy/components/proprietary/auth/sign-in-with-github.tsx +++ b/apps/dokploy/components/proprietary/auth/sign-in-with-github.tsx @@ -2,8 +2,8 @@ import { useState } from "react"; import { toast } from "sonner"; -import { authClient } from "@/lib/auth-client"; import { Button } from "@/components/ui/button"; +import { authClient } from "@/lib/auth-client"; export function SignInWithGithub() { const [isLoading, setIsLoading] = useState(false); diff --git a/apps/dokploy/components/proprietary/auth/sign-in-with-google.tsx b/apps/dokploy/components/proprietary/auth/sign-in-with-google.tsx index bff0e69ab..e40d8d9b5 100644 --- a/apps/dokploy/components/proprietary/auth/sign-in-with-google.tsx +++ b/apps/dokploy/components/proprietary/auth/sign-in-with-google.tsx @@ -2,8 +2,8 @@ import { useState } from "react"; import { toast } from "sonner"; -import { authClient } from "@/lib/auth-client"; import { Button } from "@/components/ui/button"; +import { authClient } from "@/lib/auth-client"; export function SignInWithGoogle() { const [isLoading, setIsLoading] = useState(false); diff --git a/apps/dokploy/server/api/root.ts b/apps/dokploy/server/api/root.ts index c8b4295fe..5792e8a27 100644 --- a/apps/dokploy/server/api/root.ts +++ b/apps/dokploy/server/api/root.ts @@ -22,12 +22,12 @@ import { mountRouter } from "./routers/mount"; import { mysqlRouter } from "./routers/mysql"; import { notificationRouter } from "./routers/notification"; import { organizationRouter } from "./routers/organization"; -import { licenseKeyRouter } from "./routers/proprietary/license-key"; -import { ssoRouter } from "./routers/proprietary/sso"; import { portRouter } from "./routers/port"; import { postgresRouter } from "./routers/postgres"; import { previewDeploymentRouter } from "./routers/preview-deployment"; import { projectRouter } from "./routers/project"; +import { licenseKeyRouter } from "./routers/proprietary/license-key"; +import { ssoRouter } from "./routers/proprietary/sso"; import { redirectsRouter } from "./routers/redirects"; import { redisRouter } from "./routers/redis"; import { registryRouter } from "./routers/registry"; diff --git a/apps/dokploy/setup.ts b/apps/dokploy/setup.ts index dc0c0847f..0f993e14a 100644 --- a/apps/dokploy/setup.ts +++ b/apps/dokploy/setup.ts @@ -1,8 +1,9 @@ -import { exit } from "node:process"; import { exec } from "node:child_process"; +import { exit } from "node:process"; import { promisify } from "node:util"; const execAsync = promisify(exec); + import { setupDirectories } from "@dokploy/server/setup/config-paths"; import { initializePostgres } from "@dokploy/server/setup/postgres-setup"; import { initializeRedis } from "@dokploy/server/setup/redis-setup"; diff --git a/openapi.json b/openapi.json index 76366bdb2..d71ac6255 100644 --- a/openapi.json +++ b/openapi.json @@ -758,7 +758,10 @@ "minLength": 1 }, "appName": { - "type": "string" + "type": "string", + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" }, "description": { "type": "string", @@ -841,7 +844,10 @@ "type": "object", "properties": { "appName": { - "type": "string" + "type": "string", + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" }, "applicationId": { "type": "string" @@ -1064,9 +1070,12 @@ "buildSecrets": { "type": "string", "nullable": true + }, + "createEnvFile": { + "type": "boolean" } }, - "required": ["applicationId"], + "required": ["applicationId", "createEnvFile"], "additionalProperties": false } } @@ -1370,6 +1379,10 @@ "type": "string", "nullable": true }, + "bitbucketRepositorySlug": { + "type": "string", + "nullable": true + }, "bitbucketId": { "type": "string", "nullable": true @@ -1393,6 +1406,7 @@ "bitbucketBuildPath", "bitbucketOwner", "bitbucketRepository", + "bitbucketRepositorySlug", "bitbucketId", "applicationId", "enableSubmodules" @@ -1721,7 +1735,10 @@ "minLength": 1 }, "appName": { - "type": "string" + "type": "string", + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" }, "description": { "type": "string", @@ -1836,6 +1853,13 @@ "type": "string", "nullable": true }, + "args": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true + }, "refreshToken": { "type": "string", "nullable": true @@ -1925,6 +1949,10 @@ "type": "string", "nullable": true }, + "bitbucketRepositorySlug": { + "type": "string", + "nullable": true + }, "bitbucketOwner": { "type": "string", "nullable": true @@ -2197,8 +2225,9 @@ }, "DriverOpts": { "type": "object", - "properties": {}, - "additionalProperties": false + "additionalProperties": { + "type": "string" + } } }, "additionalProperties": false @@ -2240,6 +2269,29 @@ "additionalProperties": false, "nullable": true }, + "ulimitsSwarm": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Name": { + "type": "string", + "minLength": 1 + }, + "Soft": { + "type": "integer", + "minimum": -1 + }, + "Hard": { + "type": "integer", + "minimum": -1 + } + }, + "required": ["Name", "Soft", "Hard"], + "additionalProperties": false + }, + "nullable": true + }, "replicas": { "type": "number" }, @@ -2274,6 +2326,9 @@ "type": "boolean", "nullable": true }, + "createEnvFile": { + "type": "boolean" + }, "createdAt": { "type": "string" }, @@ -2281,6 +2336,10 @@ "type": "string", "nullable": true }, + "rollbackRegistryId": { + "type": "string", + "nullable": true + }, "environmentId": { "type": "string" }, @@ -2586,7 +2645,10 @@ "in": "query", "required": true, "schema": { - "type": "string" + "type": "string", + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" } } ], @@ -2708,7 +2770,9 @@ }, "appName": { "type": "string", - "minLength": 1 + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" }, "dockerImage": { "type": "string", @@ -2744,12 +2808,10 @@ }, "required": [ "name", - "appName", "environmentId", "databaseName", "databaseUser", - "databasePassword", - "databaseRootPassword" + "databasePassword" ], "additionalProperties": false } @@ -3031,7 +3093,9 @@ }, "appName": { "type": "string", - "minLength": 1 + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" } }, "required": ["mysqlId", "appName"], @@ -3164,7 +3228,9 @@ }, "appName": { "type": "string", - "minLength": 1 + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" }, "description": { "type": "string", @@ -3194,6 +3260,13 @@ "type": "string", "nullable": true }, + "args": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true + }, "env": { "type": "string", "nullable": true @@ -3431,8 +3504,9 @@ }, "DriverOpts": { "type": "object", - "properties": {}, - "additionalProperties": false + "additionalProperties": { + "type": "string" + } } }, "additionalProperties": false @@ -3474,6 +3548,29 @@ "additionalProperties": false, "nullable": true }, + "ulimitsSwarm": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Name": { + "type": "string", + "minLength": 1 + }, + "Soft": { + "type": "integer", + "minimum": -1 + }, + "Hard": { + "type": "integer", + "minimum": -1 + } + }, + "required": ["Name", "Soft", "Hard"], + "additionalProperties": false + }, + "nullable": true + }, "replicas": { "type": "number" }, @@ -3608,7 +3705,10 @@ "minLength": 1 }, "appName": { - "type": "string" + "type": "string", + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" }, "databaseName": { "type": "string", @@ -3624,7 +3724,7 @@ }, "dockerImage": { "type": "string", - "default": "postgres:15" + "default": "postgres:18" }, "environmentId": { "type": "string" @@ -3640,7 +3740,6 @@ }, "required": [ "name", - "appName", "databaseName", "databaseUser", "databasePassword", @@ -4009,7 +4108,10 @@ "type": "string" }, "appName": { - "type": "string" + "type": "string", + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" } }, "required": ["postgresId", "appName"], @@ -4057,7 +4159,10 @@ "minLength": 1 }, "appName": { - "type": "string" + "type": "string", + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" }, "databaseName": { "type": "string", @@ -4077,12 +4182,19 @@ }, "dockerImage": { "type": "string", - "default": "postgres:15" + "default": "postgres:18" }, "command": { "type": "string", "nullable": true }, + "args": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true + }, "env": { "type": "string", "nullable": true @@ -4320,8 +4432,9 @@ }, "DriverOpts": { "type": "object", - "properties": {}, - "additionalProperties": false + "additionalProperties": { + "type": "string" + } } }, "additionalProperties": false @@ -4363,6 +4476,29 @@ "additionalProperties": false, "nullable": true }, + "ulimitsSwarm": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Name": { + "type": "string", + "minLength": 1 + }, + "Soft": { + "type": "integer", + "minimum": -1 + }, + "Hard": { + "type": "integer", + "minimum": -1 + } + }, + "required": ["Name", "Soft", "Hard"], + "additionalProperties": false + }, + "nullable": true + }, "replicas": { "type": "number" }, @@ -4498,7 +4634,9 @@ }, "appName": { "type": "string", - "minLength": 1 + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" }, "databasePassword": { "type": "string" @@ -4519,12 +4657,7 @@ "nullable": true } }, - "required": [ - "name", - "appName", - "databasePassword", - "environmentId" - ], + "required": ["name", "databasePassword", "environmentId"], "additionalProperties": false } } @@ -4637,7 +4770,9 @@ }, "appName": { "type": "string", - "minLength": 1 + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" } }, "required": ["redisId", "appName"], @@ -4938,7 +5073,9 @@ }, "appName": { "type": "string", - "minLength": 1 + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" }, "description": { "type": "string", @@ -4955,6 +5092,13 @@ "type": "string", "nullable": true }, + "args": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true + }, "env": { "type": "string", "nullable": true @@ -5195,8 +5339,9 @@ }, "DriverOpts": { "type": "object", - "properties": {}, - "additionalProperties": false + "additionalProperties": { + "type": "string" + } } }, "additionalProperties": false @@ -5238,6 +5383,29 @@ "additionalProperties": false, "nullable": true }, + "ulimitsSwarm": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Name": { + "type": "string", + "minLength": 1 + }, + "Soft": { + "type": "integer", + "minimum": -1 + }, + "Hard": { + "type": "integer", + "minimum": -1 + } + }, + "required": ["Name", "Soft", "Hard"], + "additionalProperties": false + }, + "nullable": true + }, "replicas": { "type": "number" }, @@ -5370,7 +5538,9 @@ }, "appName": { "type": "string", - "minLength": 1 + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" }, "dockerImage": { "type": "string", @@ -5403,7 +5573,6 @@ }, "required": [ "name", - "appName", "environmentId", "databaseUser", "databasePassword" @@ -5688,7 +5857,9 @@ }, "appName": { "type": "string", - "minLength": 1 + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" } }, "required": ["mongoId", "appName"], @@ -5821,7 +5992,9 @@ }, "appName": { "type": "string", - "minLength": 1 + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" }, "description": { "type": "string", @@ -5843,6 +6016,13 @@ "type": "string", "nullable": true }, + "args": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true + }, "env": { "type": "string", "nullable": true @@ -6080,8 +6260,9 @@ }, "DriverOpts": { "type": "object", - "properties": {}, - "additionalProperties": false + "additionalProperties": { + "type": "string" + } } }, "additionalProperties": false @@ -6123,6 +6304,29 @@ "additionalProperties": false, "nullable": true }, + "ulimitsSwarm": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Name": { + "type": "string", + "minLength": 1 + }, + "Soft": { + "type": "integer", + "minimum": -1 + }, + "Hard": { + "type": "integer", + "minimum": -1 + } + }, + "required": ["Name", "Soft", "Hard"], + "additionalProperties": false + }, + "nullable": true + }, "replicas": { "type": "number" }, @@ -6263,7 +6467,9 @@ }, "appName": { "type": "string", - "minLength": 1 + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" }, "dockerImage": { "type": "string", @@ -6299,8 +6505,6 @@ }, "required": [ "name", - "appName", - "databaseRootPassword", "environmentId", "databaseName", "databaseUser", @@ -6670,7 +6874,9 @@ }, "appName": { "type": "string", - "minLength": 1 + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" } }, "required": ["mariadbId", "appName"], @@ -6719,7 +6925,9 @@ }, "appName": { "type": "string", - "minLength": 1 + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" }, "description": { "type": "string", @@ -6749,6 +6957,13 @@ "type": "string", "nullable": true }, + "args": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true + }, "env": { "type": "string", "nullable": true @@ -6986,8 +7201,9 @@ }, "DriverOpts": { "type": "object", - "properties": {}, - "additionalProperties": false + "additionalProperties": { + "type": "string" + } } }, "additionalProperties": false @@ -7029,6 +7245,29 @@ "additionalProperties": false, "nullable": true }, + "ulimitsSwarm": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Name": { + "type": "string", + "minLength": 1 + }, + "Soft": { + "type": "integer", + "minimum": -1 + }, + "Hard": { + "type": "integer", + "minimum": -1 + } + }, + "required": ["Name", "Soft", "Hard"], + "additionalProperties": false + }, + "nullable": true + }, "replicas": { "type": "number" }, @@ -7174,7 +7413,10 @@ "enum": ["docker-compose", "stack"] }, "appName": { - "type": "string" + "type": "string", + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" }, "serverId": { "type": "string", @@ -7261,7 +7503,10 @@ "minLength": 1 }, "appName": { - "type": "string" + "type": "string", + "minLength": 1, + "maxLength": 63, + "pattern": "^[a-zA-Z0-9._-]+$" }, "description": { "type": "string", @@ -7333,6 +7578,10 @@ "type": "string", "nullable": true }, + "bitbucketRepositorySlug": { + "type": "string", + "nullable": true + }, "bitbucketOwner": { "type": "string", "nullable": true @@ -8569,7 +8818,10 @@ "type": "string", "minLength": 1 }, - "name": { + "firstName": { + "type": "string" + }, + "lastName": { "type": "string" }, "isRegistered": { @@ -8619,137 +8871,18 @@ "type": "string", "format": "date-time" }, - "serverIp": { - "type": "string", - "nullable": true - }, - "certificateType": { - "type": "string", - "enum": ["letsencrypt", "none", "custom"] - }, - "https": { - "type": "boolean" - }, - "host": { - "type": "string", - "nullable": true - }, - "letsEncryptEmail": { - "type": "string", - "nullable": true - }, - "sshPrivateKey": { - "type": "string", - "nullable": true - }, - "enableDockerCleanup": { - "type": "boolean" - }, - "logCleanupCron": { - "type": "string", - "nullable": true - }, "enablePaidFeatures": { "type": "boolean" }, "allowImpersonation": { "type": "boolean" }, - "metricsConfig": { - "type": "object", - "properties": { - "server": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": ["Dokploy", "Remote"] - }, - "refreshRate": { - "type": "number" - }, - "port": { - "type": "number" - }, - "token": { - "type": "string" - }, - "urlCallback": { - "type": "string" - }, - "retentionDays": { - "type": "number" - }, - "cronJob": { - "type": "string" - }, - "thresholds": { - "type": "object", - "properties": { - "cpu": { - "type": "number" - }, - "memory": { - "type": "number" - } - }, - "required": ["cpu", "memory"], - "additionalProperties": false - } - }, - "required": [ - "type", - "refreshRate", - "port", - "token", - "urlCallback", - "retentionDays", - "cronJob", - "thresholds" - ], - "additionalProperties": false - }, - "containers": { - "type": "object", - "properties": { - "refreshRate": { - "type": "number" - }, - "services": { - "type": "object", - "properties": { - "include": { - "type": "array", - "items": { - "type": "string" - } - }, - "exclude": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": ["include", "exclude"], - "additionalProperties": false - } - }, - "required": ["refreshRate", "services"], - "additionalProperties": false - } - }, - "required": ["server", "containers"], - "additionalProperties": false - }, - "cleanupCacheApplications": { + "enableEnterpriseFeatures": { "type": "boolean" }, - "cleanupCacheOnPreviews": { - "type": "boolean" - }, - "cleanupCacheOnCompose": { - "type": "boolean" + "licenseKey": { + "type": "string", + "nullable": true }, "stripeCustomerId": { "type": "string", @@ -10878,6 +11011,52 @@ } } }, + "/previewDeployment.redeploy": { + "post": { + "operationId": "previewDeployment-redeploy", + "tags": ["previewDeployment"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "previewDeploymentId": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "required": ["previewDeploymentId"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, "/mounts.create": { "post": { "operationId": "mounts-create", @@ -11335,6 +11514,29 @@ } } }, + "/settings.getWebServerSettings": { + "get": { + "operationId": "settings-getWebServerSettings", + "tags": ["settings"], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, "/settings.reloadServer": { "post": { "operationId": "settings-reloadServer", @@ -11404,6 +11606,29 @@ } } }, + "/settings.cleanAllDeploymentQueue": { + "post": { + "operationId": "settings-cleanAllDeploymentQueue", + "tags": ["settings"], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, "/settings.reloadTraefik": { "post": { "operationId": "settings-reloadTraefik", @@ -11759,8 +11984,7 @@ "type": "object", "properties": { "sshPrivateKey": { - "type": "string", - "nullable": true + "type": "string" } }, "required": ["sshPrivateKey"], @@ -11800,15 +12024,23 @@ "type": "object", "properties": { "host": { - "type": "string", - "nullable": true + "type": "string" }, "certificateType": { "type": "string", "enum": ["letsencrypt", "none", "custom"] }, "letsEncryptEmail": { - "type": "string", + "anyOf": [ + { + "type": "string", + "format": "email" + }, + { + "type": "string", + "enum": [""] + } + ], "nullable": true }, "https": { @@ -12329,6 +12561,46 @@ } } }, + "/settings.updateServerIp": { + "post": { + "operationId": "settings-updateServerIp", + "tags": ["settings"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "serverIp": { + "type": "string" + } + }, + "required": ["serverIp"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, "/settings.getOpenApiDocument": { "get": { "operationId": "settings-getOpenApiDocument", @@ -13690,6 +13962,49 @@ } } }, + "/registry.testRegistryById": { + "post": { + "operationId": "registry-testRegistryById", + "tags": ["registry"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "registryId": { + "type": "string", + "minLength": 1 + }, + "serverId": { + "type": "string" + } + }, + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, "/cluster.getNodes": { "get": { "operationId": "cluster-getNodes", @@ -13851,6 +14166,9 @@ "databaseBackup": { "type": "boolean" }, + "volumeBackup": { + "type": "boolean" + }, "dokployRestart": { "type": "boolean" }, @@ -13877,6 +14195,7 @@ "required": [ "appBuildError", "databaseBackup", + "volumeBackup", "dokployRestart", "name", "appDeploy", @@ -13926,6 +14245,9 @@ "databaseBackup": { "type": "boolean" }, + "volumeBackup": { + "type": "boolean" + }, "dokployRestart": { "type": "boolean" }, @@ -14045,6 +14367,9 @@ "databaseBackup": { "type": "boolean" }, + "volumeBackup": { + "type": "boolean" + }, "dokployRestart": { "type": "boolean" }, @@ -14075,6 +14400,7 @@ "required": [ "appBuildError", "databaseBackup", + "volumeBackup", "dokployRestart", "name", "appDeploy", @@ -14125,6 +14451,9 @@ "databaseBackup": { "type": "boolean" }, + "volumeBackup": { + "type": "boolean" + }, "dokployRestart": { "type": "boolean" }, @@ -14253,6 +14582,9 @@ "databaseBackup": { "type": "boolean" }, + "volumeBackup": { + "type": "boolean" + }, "dokployRestart": { "type": "boolean" }, @@ -14279,6 +14611,7 @@ "required": [ "appBuildError", "databaseBackup", + "volumeBackup", "dokployRestart", "name", "appDeploy", @@ -14328,6 +14661,9 @@ "databaseBackup": { "type": "boolean" }, + "volumeBackup": { + "type": "boolean" + }, "dokployRestart": { "type": "boolean" }, @@ -14448,6 +14784,9 @@ "databaseBackup": { "type": "boolean" }, + "volumeBackup": { + "type": "boolean" + }, "dokployRestart": { "type": "boolean" }, @@ -14494,6 +14833,7 @@ "required": [ "appBuildError", "databaseBackup", + "volumeBackup", "dokployRestart", "name", "appDeploy", @@ -14547,6 +14887,9 @@ "databaseBackup": { "type": "boolean" }, + "volumeBackup": { + "type": "boolean" + }, "dokployRestart": { "type": "boolean" }, @@ -14692,6 +15035,233 @@ } } }, + "/notification.createResend": { + "post": { + "operationId": "notification-createResend", + "tags": ["notification"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "appBuildError": { + "type": "boolean" + }, + "databaseBackup": { + "type": "boolean" + }, + "volumeBackup": { + "type": "boolean" + }, + "dokployRestart": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "appDeploy": { + "type": "boolean" + }, + "dockerCleanup": { + "type": "boolean" + }, + "serverThreshold": { + "type": "boolean" + }, + "apiKey": { + "type": "string", + "minLength": 1 + }, + "fromAddress": { + "type": "string", + "minLength": 1 + }, + "toAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + } + }, + "required": [ + "appBuildError", + "databaseBackup", + "volumeBackup", + "dokployRestart", + "name", + "appDeploy", + "dockerCleanup", + "serverThreshold", + "apiKey", + "fromAddress", + "toAddresses" + ], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/notification.updateResend": { + "post": { + "operationId": "notification-updateResend", + "tags": ["notification"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "appBuildError": { + "type": "boolean" + }, + "databaseBackup": { + "type": "boolean" + }, + "volumeBackup": { + "type": "boolean" + }, + "dokployRestart": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "appDeploy": { + "type": "boolean" + }, + "dockerCleanup": { + "type": "boolean" + }, + "serverThreshold": { + "type": "boolean" + }, + "apiKey": { + "type": "string", + "minLength": 1 + }, + "fromAddress": { + "type": "string", + "minLength": 1 + }, + "toAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "notificationId": { + "type": "string", + "minLength": 1 + }, + "resendId": { + "type": "string", + "minLength": 1 + }, + "organizationId": { + "type": "string" + } + }, + "required": ["notificationId", "resendId"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/notification.testResendConnection": { + "post": { + "operationId": "notification-testResendConnection", + "tags": ["notification"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "apiKey": { + "type": "string", + "minLength": 1 + }, + "fromAddress": { + "type": "string", + "minLength": 1 + }, + "toAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + } + }, + "required": ["apiKey", "fromAddress", "toAddresses"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, "/notification.remove": { "post": { "operationId": "notification-remove", @@ -14877,6 +15447,9 @@ "databaseBackup": { "type": "boolean" }, + "volumeBackup": { + "type": "boolean" + }, "dokployRestart": { "type": "boolean" }, @@ -14908,6 +15481,7 @@ "required": [ "appBuildError", "databaseBackup", + "volumeBackup", "dokployRestart", "name", "appDeploy", @@ -14958,6 +15532,9 @@ "databaseBackup": { "type": "boolean" }, + "volumeBackup": { + "type": "boolean" + }, "dokployRestart": { "type": "boolean" }, @@ -15091,6 +15668,9 @@ "databaseBackup": { "type": "boolean" }, + "volumeBackup": { + "type": "boolean" + }, "dokployRestart": { "type": "boolean" }, @@ -15112,8 +15692,7 @@ "minLength": 1 }, "accessToken": { - "type": "string", - "minLength": 1 + "type": "string" }, "priority": { "type": "number", @@ -15123,6 +15702,7 @@ "required": [ "appBuildError", "databaseBackup", + "volumeBackup", "dokployRestart", "name", "appDeploy", @@ -15173,6 +15753,9 @@ "databaseBackup": { "type": "boolean" }, + "volumeBackup": { + "type": "boolean" + }, "dokployRestart": { "type": "boolean" }, @@ -15194,8 +15777,7 @@ "minLength": 1 }, "accessToken": { - "type": "string", - "minLength": 1 + "type": "string" }, "priority": { "type": "number", @@ -15258,8 +15840,7 @@ "minLength": 1 }, "accessToken": { - "type": "string", - "minLength": 1 + "type": "string" }, "priority": { "type": "number", @@ -15286,6 +15867,206 @@ } } }, + "/notification.createCustom": { + "post": { + "operationId": "notification-createCustom", + "tags": ["notification"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "appBuildError": { + "type": "boolean" + }, + "databaseBackup": { + "type": "boolean" + }, + "volumeBackup": { + "type": "boolean" + }, + "dokployRestart": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "appDeploy": { + "type": "boolean" + }, + "dockerCleanup": { + "type": "boolean" + }, + "serverThreshold": { + "type": "boolean" + }, + "endpoint": { + "type": "string", + "minLength": 1 + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "required": ["name", "endpoint"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/notification.updateCustom": { + "post": { + "operationId": "notification-updateCustom", + "tags": ["notification"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "appBuildError": { + "type": "boolean" + }, + "databaseBackup": { + "type": "boolean" + }, + "volumeBackup": { + "type": "boolean" + }, + "dokployRestart": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "appDeploy": { + "type": "boolean" + }, + "dockerCleanup": { + "type": "boolean" + }, + "serverThreshold": { + "type": "boolean" + }, + "endpoint": { + "type": "string", + "minLength": 1 + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "notificationId": { + "type": "string", + "minLength": 1 + }, + "customId": { + "type": "string", + "minLength": 1 + }, + "organizationId": { + "type": "string" + } + }, + "required": ["notificationId", "customId"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/notification.testCustomConnection": { + "post": { + "operationId": "notification-testCustomConnection", + "tags": ["notification"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "endpoint": { + "type": "string", + "minLength": 1 + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "required": ["endpoint"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, "/notification.createLark": { "post": { "operationId": "notification-createLark", @@ -15308,6 +16089,9 @@ "databaseBackup": { "type": "boolean" }, + "volumeBackup": { + "type": "boolean" + }, "dokployRestart": { "type": "boolean" }, @@ -15331,6 +16115,7 @@ "required": [ "appBuildError", "databaseBackup", + "volumeBackup", "dokployRestart", "name", "appDeploy", @@ -15379,6 +16164,9 @@ "databaseBackup": { "type": "boolean" }, + "volumeBackup": { + "type": "boolean" + }, "dokployRestart": { "type": "boolean" }, @@ -15471,6 +16259,249 @@ } } }, + "/notification.createPushover": { + "post": { + "operationId": "notification-createPushover", + "tags": ["notification"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "appBuildError": { + "type": "boolean" + }, + "databaseBackup": { + "type": "boolean" + }, + "volumeBackup": { + "type": "boolean" + }, + "dokployRestart": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "appDeploy": { + "type": "boolean" + }, + "dockerCleanup": { + "type": "boolean" + }, + "serverThreshold": { + "type": "boolean" + }, + "userKey": { + "type": "string", + "minLength": 1 + }, + "apiToken": { + "type": "string", + "minLength": 1 + }, + "priority": { + "type": "number", + "minimum": -2, + "maximum": 2, + "default": 0 + }, + "retry": { + "type": "number", + "minimum": 30, + "nullable": true + }, + "expire": { + "type": "number", + "minimum": 1, + "maximum": 10800, + "nullable": true + } + }, + "required": ["name", "userKey", "apiToken"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/notification.updatePushover": { + "post": { + "operationId": "notification-updatePushover", + "tags": ["notification"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "notificationId": { + "type": "string", + "minLength": 1 + }, + "pushoverId": { + "type": "string", + "minLength": 1 + }, + "organizationId": { + "type": "string" + }, + "userKey": { + "type": "string", + "minLength": 1 + }, + "apiToken": { + "type": "string", + "minLength": 1 + }, + "priority": { + "type": "number", + "minimum": -2, + "maximum": 2 + }, + "retry": { + "type": "number", + "minimum": 30, + "nullable": true + }, + "expire": { + "type": "number", + "minimum": 1, + "maximum": 10800, + "nullable": true + }, + "appBuildError": { + "type": "boolean" + }, + "databaseBackup": { + "type": "boolean" + }, + "volumeBackup": { + "type": "boolean" + }, + "dokployRestart": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "appDeploy": { + "type": "boolean" + }, + "dockerCleanup": { + "type": "boolean" + }, + "serverThreshold": { + "type": "boolean" + } + }, + "required": ["notificationId", "pushoverId"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/notification.testPushoverConnection": { + "post": { + "operationId": "notification-testPushoverConnection", + "tags": ["notification"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "userKey": { + "type": "string", + "minLength": 1 + }, + "apiToken": { + "type": "string", + "minLength": 1 + }, + "priority": { + "type": "number", + "minimum": -2, + "maximum": 2 + }, + "retry": { + "type": "number", + "minimum": 30, + "nullable": true + }, + "expire": { + "type": "number", + "minimum": 1, + "maximum": 10800, + "nullable": true + } + }, + "required": ["userKey", "apiToken", "priority"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, "/notification.getEmailProviders": { "get": { "operationId": "notification-getEmailProviders", @@ -15827,6 +16858,10 @@ "type": "string", "minLength": 1 }, + "giteaInternalUrl": { + "type": "string", + "nullable": true + }, "redirectUri": { "type": "string" }, @@ -16090,6 +17125,10 @@ "type": "string", "minLength": 1 }, + "giteaInternalUrl": { + "type": "string", + "nullable": true + }, "redirectUri": { "type": "string" }, @@ -16532,6 +17571,10 @@ "type": "string", "minLength": 1 }, + "gitlabInternalUrl": { + "type": "string", + "nullable": true + }, "applicationId": { "type": "string" }, @@ -16799,6 +17842,10 @@ "type": "string", "minLength": 1 }, + "gitlabInternalUrl": { + "type": "string", + "nullable": true + }, "applicationId": { "type": "string" }, @@ -17905,6 +18952,29 @@ } } }, + "/stripe.getInvoices": { + "get": { + "operationId": "stripe-getInvoices", + "tags": ["stripe"], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, "/swarm.getNodes": { "get": { "operationId": "swarm-getNodes", @@ -18696,6 +19766,50 @@ } } }, + "/organization.updateMemberRole": { + "post": { + "operationId": "organization-updateMemberRole", + "tags": ["organization"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "memberId": { + "type": "string" + }, + "role": { + "type": "string", + "enum": ["admin", "member"] + } + }, + "required": ["memberId", "role"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, "/organization.setDefault": { "post": { "operationId": "organization-setDefault", @@ -18737,6 +19851,987 @@ } } }, + "/licenseKey.activate": { + "post": { + "operationId": "licenseKey-activate", + "tags": ["licenseKey"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "licenseKey": { + "type": "string", + "minLength": 1 + } + }, + "required": ["licenseKey"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/licenseKey.validate": { + "post": { + "operationId": "licenseKey-validate", + "tags": ["licenseKey"], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/licenseKey.deactivate": { + "post": { + "operationId": "licenseKey-deactivate", + "tags": ["licenseKey"], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/licenseKey.getEnterpriseSettings": { + "get": { + "operationId": "licenseKey-getEnterpriseSettings", + "tags": ["licenseKey"], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/licenseKey.haveValidLicenseKey": { + "get": { + "operationId": "licenseKey-haveValidLicenseKey", + "tags": ["licenseKey"], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/licenseKey.updateEnterpriseSettings": { + "post": { + "operationId": "licenseKey-updateEnterpriseSettings", + "tags": ["licenseKey"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "enableEnterpriseFeatures": { + "type": "boolean" + } + }, + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/sso.showSignInWithSSO": { + "get": { + "operationId": "sso-showSignInWithSSO", + "tags": ["sso"], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/sso.listProviders": { + "get": { + "operationId": "sso-listProviders", + "tags": ["sso"], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/sso.one": { + "get": { + "operationId": "sso-one", + "tags": ["sso"], + "security": [ + { + "Authorization": [] + } + ], + "parameters": [ + { + "name": "providerId", + "in": "query", + "required": true, + "schema": { + "type": "string", + "minLength": 1 + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/sso.update": { + "post": { + "operationId": "sso-update", + "tags": ["sso"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "providerId": { + "type": "string" + }, + "issuer": { + "type": "string" + }, + "domains": { + "type": "array", + "items": { + "type": "string" + } + }, + "oidcConfig": { + "type": "object", + "properties": { + "clientId": { + "type": "string" + }, + "clientSecret": { + "type": "string" + }, + "authorizationEndpoint": { + "type": "string" + }, + "tokenEndpoint": { + "type": "string" + }, + "userInfoEndpoint": { + "type": "string" + }, + "tokenEndpointAuthentication": { + "type": "string", + "enum": ["client_secret_post", "client_secret_basic"] + }, + "jwksEndpoint": { + "type": "string" + }, + "discoveryEndpoint": { + "type": "string" + }, + "skipDiscovery": { + "type": "boolean" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + } + }, + "pkce": { + "type": "boolean", + "default": true + }, + "mapping": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "emailVerified": { + "type": "string" + }, + "name": { + "type": "string" + }, + "image": { + "type": "string" + }, + "extraFields": { + "type": "object", + "additionalProperties": {} + } + }, + "required": ["id", "email", "name"], + "additionalProperties": false + } + }, + "required": ["clientId", "clientSecret"], + "additionalProperties": false + }, + "samlConfig": { + "type": "object", + "properties": { + "entryPoint": { + "type": "string" + }, + "cert": { + "type": "string" + }, + "callbackUrl": { + "type": "string" + }, + "audience": { + "type": "string" + }, + "idpMetadata": { + "type": "object", + "properties": { + "metadata": { + "type": "string" + }, + "entityID": { + "type": "string" + }, + "cert": { + "type": "string" + }, + "privateKey": { + "type": "string" + }, + "privateKeyPass": { + "type": "string" + }, + "isAssertionEncrypted": { + "type": "boolean" + }, + "encPrivateKey": { + "type": "string" + }, + "encPrivateKeyPass": { + "type": "string" + }, + "singleSignOnService": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Binding": { + "type": "string" + }, + "Location": { + "type": "string" + } + }, + "required": ["Binding", "Location"], + "additionalProperties": false + } + } + }, + "additionalProperties": false + }, + "spMetadata": { + "type": "object", + "properties": { + "metadata": { + "type": "string" + }, + "entityID": { + "type": "string" + }, + "binding": { + "type": "string" + }, + "privateKey": { + "type": "string" + }, + "privateKeyPass": { + "type": "string" + }, + "isAssertionEncrypted": { + "type": "boolean" + }, + "encPrivateKey": { + "type": "string" + }, + "encPrivateKeyPass": { + "type": "string" + } + }, + "additionalProperties": false + }, + "wantAssertionsSigned": { + "type": "boolean" + }, + "authnRequestsSigned": { + "type": "boolean" + }, + "signatureAlgorithm": { + "type": "string" + }, + "digestAlgorithm": { + "type": "string" + }, + "identifierFormat": { + "type": "string" + }, + "privateKey": { + "type": "string" + }, + "decryptionPvk": { + "type": "string" + }, + "additionalParams": { + "type": "object", + "additionalProperties": {} + }, + "mapping": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "emailVerified": { + "type": "string" + }, + "name": { + "type": "string" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "extraFields": { + "type": "object", + "additionalProperties": {} + } + }, + "required": ["id", "email", "name"], + "additionalProperties": false + } + }, + "required": [ + "entryPoint", + "cert", + "callbackUrl", + "spMetadata" + ], + "additionalProperties": false + }, + "organizationId": { + "type": "string" + }, + "overrideUserInfo": { + "type": "boolean", + "default": false + } + }, + "required": ["providerId", "issuer", "domains"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/sso.deleteProvider": { + "post": { + "operationId": "sso-deleteProvider", + "tags": ["sso"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "providerId": { + "type": "string", + "minLength": 1 + } + }, + "required": ["providerId"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/sso.register": { + "post": { + "operationId": "sso-register", + "tags": ["sso"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "providerId": { + "type": "string" + }, + "issuer": { + "type": "string" + }, + "domains": { + "type": "array", + "items": { + "type": "string" + } + }, + "oidcConfig": { + "type": "object", + "properties": { + "clientId": { + "type": "string" + }, + "clientSecret": { + "type": "string" + }, + "authorizationEndpoint": { + "type": "string" + }, + "tokenEndpoint": { + "type": "string" + }, + "userInfoEndpoint": { + "type": "string" + }, + "tokenEndpointAuthentication": { + "type": "string", + "enum": ["client_secret_post", "client_secret_basic"] + }, + "jwksEndpoint": { + "type": "string" + }, + "discoveryEndpoint": { + "type": "string" + }, + "skipDiscovery": { + "type": "boolean" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + } + }, + "pkce": { + "type": "boolean", + "default": true + }, + "mapping": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "emailVerified": { + "type": "string" + }, + "name": { + "type": "string" + }, + "image": { + "type": "string" + }, + "extraFields": { + "type": "object", + "additionalProperties": {} + } + }, + "required": ["id", "email", "name"], + "additionalProperties": false + } + }, + "required": ["clientId", "clientSecret"], + "additionalProperties": false + }, + "samlConfig": { + "type": "object", + "properties": { + "entryPoint": { + "type": "string" + }, + "cert": { + "type": "string" + }, + "callbackUrl": { + "type": "string" + }, + "audience": { + "type": "string" + }, + "idpMetadata": { + "type": "object", + "properties": { + "metadata": { + "type": "string" + }, + "entityID": { + "type": "string" + }, + "cert": { + "type": "string" + }, + "privateKey": { + "type": "string" + }, + "privateKeyPass": { + "type": "string" + }, + "isAssertionEncrypted": { + "type": "boolean" + }, + "encPrivateKey": { + "type": "string" + }, + "encPrivateKeyPass": { + "type": "string" + }, + "singleSignOnService": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Binding": { + "type": "string" + }, + "Location": { + "type": "string" + } + }, + "required": ["Binding", "Location"], + "additionalProperties": false + } + } + }, + "additionalProperties": false + }, + "spMetadata": { + "type": "object", + "properties": { + "metadata": { + "type": "string" + }, + "entityID": { + "type": "string" + }, + "binding": { + "type": "string" + }, + "privateKey": { + "type": "string" + }, + "privateKeyPass": { + "type": "string" + }, + "isAssertionEncrypted": { + "type": "boolean" + }, + "encPrivateKey": { + "type": "string" + }, + "encPrivateKeyPass": { + "type": "string" + } + }, + "additionalProperties": false + }, + "wantAssertionsSigned": { + "type": "boolean" + }, + "authnRequestsSigned": { + "type": "boolean" + }, + "signatureAlgorithm": { + "type": "string" + }, + "digestAlgorithm": { + "type": "string" + }, + "identifierFormat": { + "type": "string" + }, + "privateKey": { + "type": "string" + }, + "decryptionPvk": { + "type": "string" + }, + "additionalParams": { + "type": "object", + "additionalProperties": {} + }, + "mapping": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "emailVerified": { + "type": "string" + }, + "name": { + "type": "string" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "extraFields": { + "type": "object", + "additionalProperties": {} + } + }, + "required": ["id", "email", "name"], + "additionalProperties": false + } + }, + "required": [ + "entryPoint", + "cert", + "callbackUrl", + "spMetadata" + ], + "additionalProperties": false + }, + "organizationId": { + "type": "string" + }, + "overrideUserInfo": { + "type": "boolean", + "default": false + } + }, + "required": ["providerId", "issuer", "domains"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/sso.addTrustedOrigin": { + "post": { + "operationId": "sso-addTrustedOrigin", + "tags": ["sso"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "origin": { + "type": "string", + "minLength": 1 + } + }, + "required": ["origin"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/sso.removeTrustedOrigin": { + "post": { + "operationId": "sso-removeTrustedOrigin", + "tags": ["sso"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "origin": { + "type": "string", + "minLength": 1 + } + }, + "required": ["origin"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/sso.updateTrustedOrigin": { + "post": { + "operationId": "sso-updateTrustedOrigin", + "tags": ["sso"], + "security": [ + { + "Authorization": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "oldOrigin": { + "type": "string", + "minLength": 1 + }, + "newOrigin": { + "type": "string", + "minLength": 1 + } + }, + "required": ["oldOrigin", "newOrigin"], + "additionalProperties": false + } + } + } + }, + "parameters": [], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": {} + } + }, + "default": { + "$ref": "#/components/responses/error" + } + } + } + }, "/schedule.create": { "post": { "operationId": "schedule-create", @@ -18808,6 +20903,10 @@ "enabled": { "type": "boolean" }, + "timezone": { + "type": "string", + "nullable": true + }, "createdAt": { "type": "string" } @@ -18904,6 +21003,10 @@ "enabled": { "type": "boolean" }, + "timezone": { + "type": "string", + "nullable": true + }, "createdAt": { "type": "string" } diff --git a/packages/server/src/services/ai.ts b/packages/server/src/services/ai.ts index fefc82eae..875fe06ed 100644 --- a/packages/server/src/services/ai.ts +++ b/packages/server/src/services/ai.ts @@ -105,21 +105,21 @@ export const suggestVariants = async ({ }), prompt: ` Act as advanced DevOps engineer and analyze the user's request to determine the appropriate suggestions (up to 3 items). - + CRITICAL - Read the user's request carefully and follow the appropriate strategy: - + Strategy A - If the user specifies a PARTICULAR APPLICATION/SERVICE (e.g., "deploy Chatwoot", "install sendingtk/chatwoot:develop", "setup Bitwarden"): - Generate different deployment VARIANTS of that SAME application - Each variant should be a different configuration (minimal, full stack, with different databases, development vs production, etc.) - Example: For "Chatwoot" → "Chatwoot with PostgreSQL", "Chatwoot Development", "Chatwoot Full Stack" - The name MUST include the specific application name the user mentioned - + Strategy B - If the user describes a GENERAL NEED or USE CASE (e.g., "personal blog", "project management tool", "chat application"): - Suggest different open source projects that fulfill that need - Each suggestion should be a different tool/platform that solves the same problem - Example: For "personal blog" → "WordPress", "Ghost", "Hugo with Nginx" - The name should be the actual project name - + Return your response as a JSON object with the following structure: { "suggestions": [ @@ -131,7 +131,7 @@ export const suggestVariants = async ({ } ] } - + Important rules for the response: 1. Use slug format for the id field (lowercase, hyphenated) 2. Determine which strategy to use based on whether the user specified a particular application or described a general need @@ -142,9 +142,9 @@ export const suggestVariants = async ({ 7. The shortDescription should be a single-line summary focusing on key technologies or differentiators 8. All suggestions should be installable in docker and have docker compose support 9. Provide variety in your suggestions - different complexity levels, tech stacks, or approaches - + User wants to create a new project with the following details: - + ${input} `, }); @@ -182,7 +182,7 @@ export const suggestVariants = async ({ }), prompt: ` Act as advanced DevOps engineer and generate docker compose with environment variables and domain configurations needed to install the following project. - + Return your response as a JSON object with this structure: { "dockerCompose": "yaml string here", @@ -190,9 +190,9 @@ export const suggestVariants = async ({ "domains": [{"host": "domain.com", "port": 3000, "serviceName": "service"}], "configFiles": [{"content": "file content", "filePath": "path/to/file"}] } - + Note: configFiles is optional - only include it if configuration files are absolutely required. - + Follow these rules: Docker Compose Rules: @@ -242,16 +242,16 @@ export const suggestVariants = async ({ 4. ONLY include environment variables that are actually used in the docker-compose 5. Every environment variable referenced in the docker-compose MUST have a corresponding entry in envVariables 6. Do not include environment variables for services that don't exist in the docker-compose - + For each service that needs to be exposed to the internet: 1. Define a domain configuration with: - host: the domain name for the service in format: {service-name}-{random-3-chars-hex}-${ip ? ip.replaceAll(".", "-") : ""}.traefik.me - port: the internal port the service runs on - serviceName: the name of the service in the docker-compose 2. Make sure the service is properly configured to work with the specified port - + User's original request: ${input} - + Project details: ${suggestion?.description} `, diff --git a/packages/server/src/services/domain.ts b/packages/server/src/services/domain.ts index b2e15ed91..232fbd55c 100644 --- a/packages/server/src/services/domain.ts +++ b/packages/server/src/services/domain.ts @@ -44,7 +44,7 @@ export const createDomain = async (input: typeof apiCreateDomain._type) => { export const generateTraefikMeDomain = async ( appName: string, - userId: string, + _userId: string, serverId?: string, ) => { if (serverId) { diff --git a/packages/server/src/services/preview-deployment.ts b/packages/server/src/services/preview-deployment.ts index 1ece3bc53..bc9bd0f5a 100644 --- a/packages/server/src/services/preview-deployment.ts +++ b/packages/server/src/services/preview-deployment.ts @@ -235,7 +235,7 @@ const generateWildcardDomain = async ( baseDomain: string, appName: string, serverIp: string, - userId: string, + _userId: string, ): Promise => { if (!baseDomain.startsWith("*.")) { throw new Error('The base domain must start with "*."');