diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f6a603ae53c..75d614557d7 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -21,6 +21,9 @@ updates: update-types: ["version-update:semver-minor"] - dependency-name: "@better-auth/*" update-types: ["version-update:semver-minor"] + # Pinned in the root overrides so better-auth and better-call share one copy; + # a bump of the direct dependency alone does nothing. + - dependency-name: "@better-auth/utils" - dependency-name: "stripe" - dependency-name: "@stepperize/react" - dependency-name: "@dokploy/trpc-openapi" diff --git a/apps/api/package.json b/apps/api/package.json index 6a0b1b9d000..0d911506761 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -12,9 +12,9 @@ "dependencies": { "@dokploy/server": "workspace:*", "@hono/node-server": "^1.19.17", - "@hono/zod-validator": "0.7.6", + "@hono/zod-validator": "0.9.1", "dotenv": "^18.0.5", - "hono": "^4.13.12", + "hono": "^4.13.13", "inngest": "4.21.1", "pino": "10.4.0", "pino-pretty": "13.1.3", diff --git a/apps/dokploy/__test__/lib/terminal-keyboard.test.ts b/apps/dokploy/__test__/lib/terminal-keyboard.test.ts new file mode 100644 index 00000000000..c0929e71921 --- /dev/null +++ b/apps/dokploy/__test__/lib/terminal-keyboard.test.ts @@ -0,0 +1,88 @@ +import type { Terminal } from "@xterm/xterm"; +import { afterEach, describe, expect, it, vi } from "vitest"; +import { attachTerminalKeyHandlers } from "@/lib/terminal-keyboard"; + +const setup = (platform: string) => { + vi.stubGlobal("navigator", { platform }); + let handler: ((event: KeyboardEvent) => boolean) | undefined; + const input = vi.fn(); + const term = { + attachCustomKeyEventHandler: (fn: (event: KeyboardEvent) => boolean) => { + handler = fn; + }, + input, + } as unknown as Terminal; + attachTerminalKeyHandlers(term); + const press = ( + key: string, + modifiers: Partial< + Pick + > = {}, + type = "keydown", + ) => { + const preventDefault = vi.fn(); + const result = handler?.({ + type, + key, + altKey: false, + ctrlKey: false, + metaKey: false, + shiftKey: false, + ...modifiers, + preventDefault, + } as unknown as KeyboardEvent); + return { result, preventDefault }; + }; + return { press, input }; +}; + +afterEach(() => { + vi.unstubAllGlobals(); +}); + +describe("attachTerminalKeyHandlers", () => { + it.each([ + ["ArrowUp", "\x1b[1;5A"], + ["ArrowDown", "\x1b[1;5B"], + ["ArrowRight", "\x1b[1;5C"], + ["ArrowLeft", "\x1b[1;5D"], + ])("sends Ctrl+%s for Alt+%s on every platform", (key, sequence) => { + for (const platform of ["MacIntel", "Win32", "Linux x86_64"]) { + const { press, input } = setup(platform); + const { result, preventDefault } = press(key, { altKey: true }); + expect(result).toBe(false); + expect(preventDefault).toHaveBeenCalled(); + expect(input).toHaveBeenCalledWith(sequence); + } + }); + + it.each([{ shiftKey: true }, { ctrlKey: true }, { metaKey: true }])( + "leaves Alt+Arrow with %o to xterm", + (extra) => { + const { press, input } = setup("Linux x86_64"); + expect(press("ArrowLeft", { altKey: true, ...extra }).result).toBe(true); + expect(input).not.toHaveBeenCalled(); + }, + ); + + it("leaves plain arrows and keyup events to xterm", () => { + const { press, input } = setup("MacIntel"); + expect(press("ArrowLeft").result).toBe(true); + expect(press("ArrowLeft", { altKey: true }, "keyup").result).toBe(true); + expect(input).not.toHaveBeenCalled(); + }); + + it("types Option-composed characters on macOS", () => { + const { press, input } = setup("MacIntel"); + const { result, preventDefault } = press("@", { altKey: true }); + expect(result).toBe(false); + expect(preventDefault).toHaveBeenCalled(); + expect(input).toHaveBeenCalledWith("@"); + }); + + it("keeps Alt+letter for xterm outside macOS", () => { + const { press, input } = setup("Win32"); + expect(press("l", { altKey: true }).result).toBe(true); + expect(input).not.toHaveBeenCalled(); + }); +}); diff --git a/apps/dokploy/components/dashboard/docker/terminal/docker-terminal.tsx b/apps/dokploy/components/dashboard/docker/terminal/docker-terminal.tsx index f0877cf221b..333cad6ac94 100644 --- a/apps/dokploy/components/dashboard/docker/terminal/docker-terminal.tsx +++ b/apps/dokploy/components/dashboard/docker/terminal/docker-terminal.tsx @@ -6,7 +6,7 @@ import { AttachAddon } from "@xterm/addon-attach"; import { ClipboardAddon } from "@xterm/addon-clipboard"; import { useTheme } from "next-themes"; import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; -import { fixMacOsAltKeys } from "@/lib/terminal-keyboard"; +import { attachTerminalKeyHandlers } from "@/lib/terminal-keyboard"; interface Props { id: string; @@ -63,7 +63,7 @@ export const DockerTerminal: React.FC = ({ const addonFit = new FitAddon(); const clipboardAddon = new ClipboardAddon(); term.loadAddon(clipboardAddon); - fixMacOsAltKeys(term); + attachTerminalKeyHandlers(term); // @ts-expect-error term.open(termRef.current); term.loadAddon(addonFit); diff --git a/apps/dokploy/components/dashboard/settings/web-server/terminal.tsx b/apps/dokploy/components/dashboard/settings/web-server/terminal.tsx index 68806ad7c94..5fd3b8d1512 100644 --- a/apps/dokploy/components/dashboard/settings/web-server/terminal.tsx +++ b/apps/dokploy/components/dashboard/settings/web-server/terminal.tsx @@ -6,7 +6,7 @@ import "@xterm/xterm/css/xterm.css"; import { AttachAddon } from "@xterm/addon-attach"; import { ClipboardAddon } from "@xterm/addon-clipboard"; import { useTheme } from "next-themes"; -import { fixMacOsAltKeys } from "@/lib/terminal-keyboard"; +import { attachTerminalKeyHandlers } from "@/lib/terminal-keyboard"; import { getLocalServerData } from "./local-server-config"; interface Props { @@ -43,7 +43,7 @@ export const Terminal: React.FC = ({ id, serverId }) => { const addonFit = new FitAddon(); const clipboardAddon = new ClipboardAddon(); term.loadAddon(clipboardAddon); - fixMacOsAltKeys(term); + attachTerminalKeyHandlers(term); // @ts-expect-error term.open(termRef.current); diff --git a/apps/dokploy/lib/terminal-keyboard.ts b/apps/dokploy/lib/terminal-keyboard.ts index 534ea981489..3afa633d3ce 100644 --- a/apps/dokploy/lib/terminal-keyboard.ts +++ b/apps/dokploy/lib/terminal-keyboard.ts @@ -1,21 +1,41 @@ import type { Terminal } from "@xterm/xterm"; +const ALT_ARROW_AS_CTRL_ARROW: Record = { + ArrowUp: "\x1b[1;5A", + ArrowDown: "\x1b[1;5B", + ArrowRight: "\x1b[1;5C", + ArrowLeft: "\x1b[1;5D", +}; + // xterm's platform detection mistakes the bundled Next.js `process` polyfill // for Node.js, so it never treats Option/Alt as third-level shift on macOS and // swallows composed characters like Option+L (@ on German layouts). // https://github.com/Dokploy/dokploy/issues/4297 -export const fixMacOsAltKeys = (term: Terminal) => { - if (!/Mac/.test(navigator.platform)) { - return; - } +// +// xterm 6 also dropped its Alt+Arrow -> Ctrl+Arrow rewrite (xtermjs/xterm.js#5346), +// which shells bind to word jumps. Because of the same detection bug, xterm 5 +// always took its non-macOS branch here, so these are the sequences it sent. +// xterm keeps a single custom key handler, so both fixes share it. +export const attachTerminalKeyHandlers = (term: Terminal) => { + const isMac = /Mac/.test(navigator.platform); term.attachCustomKeyEventHandler((event) => { if ( - event.type === "keydown" && - event.altKey && - !event.ctrlKey && - !event.metaKey && - event.key.length === 1 + event.type !== "keydown" || + !event.altKey || + event.ctrlKey || + event.metaKey ) { + return true; + } + const ctrlArrow = event.shiftKey + ? undefined + : ALT_ARROW_AS_CTRL_ARROW[event.key]; + if (ctrlArrow) { + event.preventDefault(); + term.input(ctrlArrow); + return false; + } + if (isMac && event.key.length === 1) { event.preventDefault(); term.input(event.key); return false; diff --git a/apps/dokploy/package.json b/apps/dokploy/package.json index 295ada0f0e1..f9e83e0c2e5 100644 --- a/apps/dokploy/package.json +++ b/apps/dokploy/package.json @@ -82,10 +82,10 @@ "@trpc/server": "^11.19.0", "@uiw/codemirror-theme-github": "^4.25.12", "@uiw/react-codemirror": "^4.25.12", - "@xterm/addon-attach": "0.10.0", - "@xterm/addon-clipboard": "0.1.0", - "@xterm/addon-fit": "0.10.0", - "@xterm/xterm": "^5.5.0", + "@xterm/addon-attach": "0.12.0", + "@xterm/addon-clipboard": "0.2.0", + "@xterm/addon-fit": "0.11.0", + "@xterm/xterm": "^6.0.0", "adm-zip": "^0.6.1", "ai": "^7.0.127", "ai-sdk-ollama": "^4.4.0", @@ -111,12 +111,12 @@ "micromatch": "4.0.8", "nanoid": "3.3.19", "next": "16.3.8", - "next-themes": "^0.2.1", + "next-themes": "^0.4.6", "nextjs-toploader": "^3.9.17", "node-os-utils": "2.0.5", "node-pty": "1.1.0", "node-schedule": "2.1.1", - "nodemailer": "10.0.13", + "nodemailer": "10.0.14", "octokit": "3.2.2", "pino": "10.4.0", "pino-pretty": "13.1.3", @@ -174,7 +174,7 @@ "esbuild": "0.28.2", "lint-staged": "^15.5.2", "memfs": "^4.80.0", - "simple-icons": "^16.33.0", + "simple-icons": "^16.34.0", "tailwindcss": "^4.3.3", "tsx": "^4.23.15", "typescript": "^7.0.2", diff --git a/apps/dokploy/styles/globals.css b/apps/dokploy/styles/globals.css index 97522e4934c..ae5e6fb8125 100644 --- a/apps/dokploy/styles/globals.css +++ b/apps/dokploy/styles/globals.css @@ -306,6 +306,9 @@ body[data-scroll-locked] [data-slot="sidebar-inset"] { .xterm .xterm-viewport { overflow-y: auto !important; + /* xterm 6 paints the theme background on its new scroll container and + leaves this element on xterm.css's #000, which hid our transparent theme. */ + background-color: transparent !important; } .xterm .xterm-screen { diff --git a/apps/schedules/package.json b/apps/schedules/package.json index 774f393ee79..23d5bb23b8a 100644 --- a/apps/schedules/package.json +++ b/apps/schedules/package.json @@ -10,11 +10,11 @@ "dependencies": { "@dokploy/server": "workspace:*", "@hono/node-server": "^1.19.17", - "@hono/zod-validator": "0.7.6", + "@hono/zod-validator": "0.9.1", "bullmq": "5.81.5", "dotenv": "^18.0.5", "drizzle-orm": "0.45.3", - "hono": "^4.13.12", + "hono": "^4.13.13", "ioredis": "5.11.1", "pino": "10.4.0", "pino-pretty": "13.1.3", diff --git a/bun.lock b/bun.lock index a89faabbf2b..61ba4006cd9 100644 --- a/bun.lock +++ b/bun.lock @@ -20,9 +20,9 @@ "dependencies": { "@dokploy/server": "workspace:*", "@hono/node-server": "^1.19.17", - "@hono/zod-validator": "0.7.6", + "@hono/zod-validator": "0.9.1", "dotenv": "^18.0.5", - "hono": "^4.13.12", + "hono": "^4.13.13", "inngest": "4.21.1", "pino": "10.4.0", "pino-pretty": "13.1.3", @@ -85,10 +85,10 @@ "@trpc/server": "^11.19.0", "@uiw/codemirror-theme-github": "^4.25.12", "@uiw/react-codemirror": "^4.25.12", - "@xterm/addon-attach": "0.10.0", - "@xterm/addon-clipboard": "0.1.0", - "@xterm/addon-fit": "0.10.0", - "@xterm/xterm": "^5.5.0", + "@xterm/addon-attach": "0.12.0", + "@xterm/addon-clipboard": "0.2.0", + "@xterm/addon-fit": "0.11.0", + "@xterm/xterm": "^6.0.0", "adm-zip": "^0.6.1", "ai": "^7.0.127", "ai-sdk-ollama": "^4.4.0", @@ -114,12 +114,12 @@ "micromatch": "4.0.8", "nanoid": "3.3.19", "next": "16.3.8", - "next-themes": "^0.2.1", + "next-themes": "^0.4.6", "nextjs-toploader": "^3.9.17", "node-os-utils": "2.0.5", "node-pty": "1.1.0", "node-schedule": "2.1.1", - "nodemailer": "10.0.13", + "nodemailer": "10.0.14", "octokit": "3.2.2", "pino": "10.4.0", "pino-pretty": "13.1.3", @@ -177,7 +177,7 @@ "esbuild": "0.28.2", "lint-staged": "^15.5.2", "memfs": "^4.80.0", - "simple-icons": "^16.33.0", + "simple-icons": "^16.34.0", "tailwindcss": "^4.3.3", "tsx": "^4.23.15", "typescript": "^7.0.2", @@ -190,11 +190,11 @@ "dependencies": { "@dokploy/server": "workspace:*", "@hono/node-server": "^1.19.17", - "@hono/zod-validator": "0.7.6", + "@hono/zod-validator": "0.9.1", "bullmq": "5.81.5", "dotenv": "^18.0.5", "drizzle-orm": "0.45.3", - "hono": "^4.13.12", + "hono": "^4.13.13", "ioredis": "5.11.1", "pino": "10.4.0", "pino-pretty": "13.1.3", @@ -229,7 +229,7 @@ "@better-auth/passkey": "1.7.7", "@better-auth/scim": "1.7.7", "@better-auth/sso": "1.7.7", - "@better-auth/utils": "0.4.2", + "@better-auth/utils": "0.5.0", "@faker-js/faker": "^10.6.0", "@octokit/auth-app": "^6.1.4", "@octokit/rest": "^20.1.2", @@ -249,14 +249,14 @@ "dotenv": "18.0.5", "drizzle-dbml-generator": "0.10.0", "drizzle-orm": "0.45.3", - "drizzle-zod": "0.5.1", + "drizzle-zod": "0.8.3", "lodash": "4.18.1", "micromatch": "4.0.8", "nanoid": "3.3.19", "node-os-utils": "2.0.5", "node-pty": "1.1.0", "node-schedule": "2.1.1", - "nodemailer": "10.0.13", + "nodemailer": "10.0.14", "octokit": "3.2.2", "pino": "10.4.0", "pino-pretty": "13.1.3", @@ -302,6 +302,7 @@ }, }, "overrides": { + "@better-auth/utils": "0.5.0", "@better-fetch/fetch": "1.3.2", "@codemirror/state": "6.7.6", "@grpc/grpc-js": ">=1.14.5 <2.0.0", @@ -314,7 +315,7 @@ "drizzle-orm": "0.45.3", "esbuild": "0.28.2", "h3": "1.15.11", - "hono": "4.13.12", + "hono": "4.13.13", "http-cache-semantics": ">=4.3.0 <5.0.0", "js-yaml": "4.3.2", "lodash": "4.18.1", @@ -491,7 +492,7 @@ "@better-auth/telemetry": ["@better-auth/telemetry@1.7.7", "", { "peerDependencies": { "@better-auth/core": "^1.7.7", "@better-auth/utils": "0.4.2", "@better-fetch/fetch": "1.3.2" } }, "sha512-PaRA6i+kAioVYmza2gHPcdrxP0hAotph4KV9hft2GeNJq+AZXDiBu3FuLM9HxvcmiZeUT74Vufqd9ypmB8veTA=="], - "@better-auth/utils": ["@better-auth/utils@0.4.2", "", { "dependencies": { "@noble/hashes": "^2.0.1" } }, "sha512-AUxrvu+HaaODsUyzDxFgwd/8RZ1yZaYo42LXKSrU2oGgR38pS1ij8nqQKNgtTWoYGpNevNXtCfgTy6loHveW9A=="], + "@better-auth/utils": ["@better-auth/utils@0.5.0", "", { "dependencies": { "@noble/hashes": "^2.0.1" } }, "sha512-BL8W4EfIZFwlu0r54m3v1ztjDhu6dDe/amLTm0xybmbZaNgYUqhD3SjpAsnq0q8YD6/ki4iwIgxJNLP/N3TxiA=="], "@better-fetch/fetch": ["@better-fetch/fetch@1.3.2", "", {}, "sha512-Gs7n99b5tqUC6cQAPbV0uED3IraHB6xQbHLQ/C3l7ZFafHScOx9pQ+DYmP5blbLFShVWLqxNUlI9wi4xU/X+ow=="], @@ -647,7 +648,7 @@ "@hono/node-server": ["@hono/node-server@1.19.17", "", { "peerDependencies": { "hono": "^4" } }, "sha512-dSneS5qhiauZWGDCeK4o695Xd9nUNjviSZCMQrj10eetr8Uln1ucn6bbphOM6UynAMMtNIzZNSpL9vnASJwrPQ=="], - "@hono/zod-validator": ["@hono/zod-validator@0.7.6", "", { "peerDependencies": { "hono": ">=3.9.0", "zod": "^3.25.0 || ^4.0.0" } }, "sha512-Io1B6d011Gj1KknV4rXYz4le5+5EubcWEU/speUjuw9XMMIaP3n78yXLhjd2A3PXaXaUwEAluOiAyLqhBEJgsw=="], + "@hono/zod-validator": ["@hono/zod-validator@0.9.1", "", { "peerDependencies": { "hono": ">=4.11.2", "zod": "^3.25.0 || ^4.0.0" } }, "sha512-iiv6w0qrIc0arfvCtUqBWsvl4fXjzaTcQcCJTTtCnkawF9HHGE+KjEl0ox3gQJ6rKZEgE3mLExlQCF72M+mNuw=="], "@hookform/resolvers": ["@hookform/resolvers@5.9.1", "", { "dependencies": { "@standard-schema/utils": "^0.3.0" }, "peerDependencies": { "@sinclair/typebox": ">=0.25.24", "@standard-schema/spec": "^1.0.0", "@typeschema/main": ">=0.13.7", "@vinejs/vine": "^2.0.0 || ^3.0.0 || ^4.0.0", "ajv": "^8.12.0", "ajv-errors": "^3.0.0", "ajv-formats": "^2.1.1", "arktype": "^2.0.0", "ata-validator": "^1.2.0", "class-transformer": ">=0.4.0", "class-validator": ">=0.12.0", "computed-types": "^1.0.0", "effect": "^3.10.3", "fluentvalidation-ts": "^3.0.0", "fp-ts": "^2.7.0", "io-ts": "^2.0.0", "joi": "^17.0.0 || ^18.0.0", "nope-validator": ">=0.12.0", "react-hook-form": "^7.55.0", "superstruct": ">=0.12.0", "typanion": "^3.3.2", "valibot": ">=0.31.0 || ^1.0.0-beta.4 || ^1.0.0-rc", "vest": ">=6.0.0", "yup": "^1.0.0", "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["@sinclair/typebox", "@standard-schema/spec", "@typeschema/main", "@vinejs/vine", "ajv", "ajv-errors", "ajv-formats", "arktype", "ata-validator", "class-transformer", "class-validator", "computed-types", "effect", "fluentvalidation-ts", "fp-ts", "io-ts", "joi", "nope-validator", "superstruct", "typanion", "valibot", "vest", "yup", "zod"] }, "sha512-7b7vsbraJxKgjVSA1Nur9tLwj539WGJUBLA7QNvXnFoT2pM5Z7G+6rlukk4B2/QrTZy6huRtH6wKeESPKuIr6w=="], @@ -1671,13 +1672,13 @@ "@xstate/fsm": ["@xstate/fsm@1.6.5", "", {}, "sha512-b5o1I6aLNeYlU/3CPlj/Z91ybk1gUsKT+5NAJI+2W4UjvS5KLG28K9v5UvNoFVjHV8PajVZ00RH3vnjyQO7ZAw=="], - "@xterm/addon-attach": ["@xterm/addon-attach@0.10.0", "", { "peerDependencies": { "@xterm/xterm": "^5.0.0" } }, "sha512-ES/XO8pC1tPHSkh4j7qzM8ajFt++u8KMvfRc9vKIbjHTDOxjl9IUVo+vcQgLn3FTCM3w2czTvBss8nMWlD83Cg=="], + "@xterm/addon-attach": ["@xterm/addon-attach@0.12.0", "", {}, "sha512-1lxvXM4JYSm60lbFmE8WMOy2oF2ip3Ye8jWorSAmwy7x8FiC53netEJ5RguL8+FSRj79MUQsNCb2hprY2QA2ig=="], - "@xterm/addon-clipboard": ["@xterm/addon-clipboard@0.1.0", "", { "dependencies": { "js-base64": "^3.7.5" }, "peerDependencies": { "@xterm/xterm": "^5.4.0" } }, "sha512-zdoM7p53T5sv/HbRTyp4hY0kKmEQ3MZvAvEtiXqNIHc/JdpqwByCtsTaQF5DX2n4hYdXRPO4P/eOS0QEhX1nPw=="], + "@xterm/addon-clipboard": ["@xterm/addon-clipboard@0.2.0", "", { "dependencies": { "js-base64": "^3.7.5" } }, "sha512-Dl31BCtBhLaUEECUbEiVcCLvLBbaeGYdT7NofB8OJkGTD3MWgBsaLjXvfGAD4tQNHhm6mbKyYkR7XD8kiZsdNg=="], - "@xterm/addon-fit": ["@xterm/addon-fit@0.10.0", "", { "peerDependencies": { "@xterm/xterm": "^5.0.0" } }, "sha512-UFYkDm4HUahf2lnEyHvio51TNGiLK66mqP2JoATy7hRZeXaGMRDr00JiSF7m63vR5WKATF605yEggJKsw0JpMQ=="], + "@xterm/addon-fit": ["@xterm/addon-fit@0.11.0", "", {}, "sha512-jYcgT6xtVYhnhgxh3QgYDnnNMYTcf8ElbxxFzX0IZo+vabQqSPAjC3c1wJrKB5E19VwQei89QCiZZP86DCPF7g=="], - "@xterm/xterm": ["@xterm/xterm@5.5.0", "", {}, "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A=="], + "@xterm/xterm": ["@xterm/xterm@6.0.0", "", {}, "sha512-TQwDdQGtwwDt+2cgKDLn0IRaSxYu1tSUjgKarSDkUM0ZNiSRXFpjxEsvc/Zgc5kq5omJ+V0a8/kIM2WD3sMOYg=="], "abbrev": ["abbrev@5.0.0", "", {}, "sha512-/XrFJgzQQQHpti1raDJC6m4ws6aNktmjBlhk8Fdlk7LwCEuDoieEJJY9OFHjfiFJFFRM2tK+Ky/IsfbbmlMu1w=="], @@ -2059,7 +2060,7 @@ "drizzle-orm": ["drizzle-orm@0.45.3", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@netlify/db": ">=0.4.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "prisma": "*", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@netlify/db", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "prisma", "sql.js", "sqlite3"] }, "sha512-CAloER21cDdcgZ1OmjrZX82EeRNsdP+y0onX/eyoYDaYzki/adrAa91lzM5jWh7zZPK4qUbw/6LGv9J+A+uizA=="], - "drizzle-zod": ["drizzle-zod@0.5.1", "", { "peerDependencies": { "drizzle-orm": ">=0.23.13", "zod": "*" } }, "sha512-C/8bvzUH/zSnVfwdSibOgFjLhtDtbKYmkbPbUCq46QZyZCH6kODIMSOgZ8R7rVjoI+tCj3k06MRJMDqsIeoS4A=="], + "drizzle-zod": ["drizzle-zod@0.8.3", "", { "peerDependencies": { "drizzle-orm": ">=0.36.0", "zod": "^3.25.0 || ^4.0.0" } }, "sha512-66yVOuvGhKJnTdiqj1/Xaaz9/qzOdRJADpDa68enqS6g3t0kpNkwNYjUuaeXgZfO/UWuIM9HIhSlJ6C5ZraMww=="], "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], @@ -2289,7 +2290,7 @@ "highlightjs-vue": ["highlightjs-vue@1.0.0", "", {}, "sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA=="], - "hono": ["hono@4.13.12", "", {}, "sha512-6E2QDAc9Ick9Sq77ZrGS/dk2WUYni91aufTw6LJKpV7w8kW5/GxVUc650FOADOmlwg3K+f7Pun6XlV+pYmW6gw=="], + "hono": ["hono@4.13.13", "", {}, "sha512-CQ46U0ZkAGmbT/4UxdzzGJpacP2IeKgY4a5/tOI9AABbpOMfK739wfDXmv1usCk+3RkKj1hQy4/fjhiwa2xlrA=="], "html-to-text": ["html-to-text@9.0.5", "", { "dependencies": { "@selderee/plugin-htmlparser2": "^0.11.0", "deepmerge": "^4.3.1", "dom-serializer": "^2.0.0", "htmlparser2": "^8.0.2", "selderee": "^0.11.0" } }, "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg=="], @@ -2665,7 +2666,7 @@ "next": ["next@16.3.8", "", { "dependencies": { "@next/env": "16.3.8", "@swc/helpers": "0.5.23", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", "postcss": "8.5.23", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.3.8", "@next/swc-darwin-x64": "16.3.8", "@next/swc-linux-arm64-gnu": "16.3.8", "@next/swc-linux-arm64-musl": "16.3.8", "@next/swc-linux-x64-gnu": "16.3.8", "@next/swc-linux-x64-musl": "16.3.8", "@next/swc-win32-arm64-msvc": "16.3.8", "@next/swc-win32-x64-msvc": "16.3.8", "sharp": "^0.35.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-U7QEZaTini6wKrb8A8hqLLqYQyCetegKjCpJOyxk642vWoMoU1x5PyZCJFvgYgiptA8xc5j/9xYlZFO7w9Sjmw=="], - "next-themes": ["next-themes@0.2.1", "", { "peerDependencies": { "next": "*", "react": "*", "react-dom": "*" } }, "sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A=="], + "next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="], "nextjs-toploader": ["nextjs-toploader@3.9.17", "", { "dependencies": { "nprogress": "^0.2.0", "prop-types": "^15.8.1" }, "peerDependencies": { "next": ">= 6.0.0", "react": ">= 16.0.0", "react-dom": ">= 16.0.0" } }, "sha512-9OF0KSSLtoSAuNg2LZ3aTl4hR9mBDj5L9s9DZiFCbMlXehyICGjkIz5dVGzuATU2bheJZoBdFgq9w07AKSuQQw=="], @@ -2695,7 +2696,7 @@ "node-schedule": ["node-schedule@2.1.1", "", { "dependencies": { "cron-parser": "^4.2.0", "long-timeout": "0.1.1", "sorted-array-functions": "^1.3.0" } }, "sha512-OXdegQq03OmXEjt2hZP33W2YPs/E5BcFQks46+G2gAxs4gHOIVD1u7EqlYLYSKsaIpyKCK9Gbk0ta1/gjRSMRQ=="], - "nodemailer": ["nodemailer@10.0.13", "", {}, "sha512-SzG86OlvcW/NNhUFC6uROMwRTL4n7MswfQqC/T8mhkmnY1YVa23zUEMYi4ijSeXSl9GLz9ZeTJDUatEDuY5FeQ=="], + "nodemailer": ["nodemailer@10.0.14", "", {}, "sha512-eJoLFKg55fesSlzUekmfOv/SBXh4KUYT8oiQc2RLP0tfG0rbNMJBK7wgHJwXTJwqyKlSJMz9UzDZ4v+aHEvo8g=="], "nopt": ["nopt@10.0.1", "", { "dependencies": { "abbrev": "^5.0.0" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-df3sBr/6ax9hSGuC3CspvLlbnX8cP5L5nZwXF8cGN8l0zSWR6BvzmQ6jPUKjvo6+/xdpkNvEcucBNUdBeeV13g=="], @@ -3069,7 +3070,7 @@ "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], - "simple-icons": ["simple-icons@16.33.0", "", {}, "sha512-z14u6A8ngAg9mgERRsNO8YkjIMefehIpBk7A8Dz3Gd91945qFP19MLPSHgV4z8P5u/MRYd5e07OTzaDoB4d6qA=="], + "simple-icons": ["simple-icons@16.34.0", "", {}, "sha512-UTxKn0PVspk84B2hHF3Dqiqht1yDjJmDc/t4cO7PyCQxCMk6OjEu95pnpGjhLaGeQ4qBrGASbefTIe/+czrX7g=="], "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], @@ -3515,8 +3516,6 @@ "auth/dotenv": ["dotenv@17.4.2", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="], - "better-call/@better-auth/utils": ["@better-auth/utils@0.5.0", "", { "dependencies": { "@noble/hashes": "^2.0.1" } }, "sha512-BL8W4EfIZFwlu0r54m3v1ztjDhu6dDe/amLTm0xybmbZaNgYUqhD3SjpAsnq0q8YD6/ki4iwIgxJNLP/N3TxiA=="], - "body-parser/content-type": ["content-type@2.1.0", "", {}, "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag=="], "body-parser/raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="], @@ -3547,8 +3546,6 @@ "docker-modem/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], - "dokploy/drizzle-zod": ["drizzle-zod@0.8.3", "", { "peerDependencies": { "drizzle-orm": ">=0.36.0", "zod": "^3.25.0 || ^4.0.0" } }, "sha512-66yVOuvGhKJnTdiqj1/Xaaz9/qzOdRJADpDa68enqS6g3t0kpNkwNYjUuaeXgZfO/UWuIM9HIhSlJ6C5ZraMww=="], - "dot-prop/is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="], "enquirer/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], diff --git a/package.json b/package.json index f94898c709a..5f214fb3e25 100644 --- a/package.json +++ b/package.json @@ -51,11 +51,12 @@ "better-auth": "1.7.7", "next": "16.3.8", "better-call": "1.4.0", + "@better-auth/utils": "0.5.0", "@better-fetch/fetch": "1.3.2", "drizzle-orm": "0.45.3", "esbuild": "0.28.2", "h3": "1.15.11", - "hono": "4.13.12", + "hono": "4.13.13", "js-yaml": "4.3.2", "lodash": "4.18.1", "postcss": "8.5.28", diff --git a/packages/server/package.json b/packages/server/package.json index 513df15ff47..b40ca6d8bda 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -52,7 +52,7 @@ "@better-auth/passkey": "1.7.7", "@better-auth/scim": "1.7.7", "@better-auth/sso": "1.7.7", - "@better-auth/utils": "0.4.2", + "@better-auth/utils": "0.5.0", "@faker-js/faker": "^10.6.0", "@octokit/auth-app": "^6.1.4", "@octokit/rest": "^20.1.2", @@ -72,14 +72,14 @@ "dotenv": "18.0.5", "drizzle-dbml-generator": "0.10.0", "drizzle-orm": "0.45.3", - "drizzle-zod": "0.5.1", + "drizzle-zod": "0.8.3", "lodash": "4.18.1", "micromatch": "4.0.8", "nanoid": "3.3.19", "node-os-utils": "2.0.5", "node-pty": "1.1.0", "node-schedule": "2.1.1", - "nodemailer": "10.0.13", + "nodemailer": "10.0.14", "octokit": "3.2.2", "pino": "10.4.0", "pino-pretty": "13.1.3", diff --git a/packages/server/src/db/schema/application.ts b/packages/server/src/db/schema/application.ts index d4f2015535c..5659fa6f8ea 100644 --- a/packages/server/src/db/schema/application.ts +++ b/packages/server/src/db/schema/application.ts @@ -358,86 +358,88 @@ const createSchema = createInsertSchema(applications, { .max(63) .regex(APP_NAME_REGEX, APP_NAME_MESSAGE) .optional(), - createdAt: z.string(), - applicationId: z.string(), - autoDeploy: z.boolean(), - env: z.string().optional(), - buildArgs: z.string().optional(), - buildSecrets: z.string().optional(), + createdAt: z.string().optional(), + applicationId: z.string().optional(), + autoDeploy: z.boolean().nullable().optional(), + env: z.string().nullable().optional(), + buildArgs: z.string().nullable().optional(), + buildSecrets: z.string().nullable().optional(), name: z.string().min(1), description: z.string().nullable().optional(), memoryReservation: z.string().nullable().optional(), memoryLimit: z.string().nullable().optional(), cpuReservation: z.string().nullable().optional(), cpuLimit: z.string().nullable().optional(), - title: z.string().optional(), - enabled: z.boolean().optional(), - subtitle: z.string().optional(), + title: z.string().nullable().optional(), + enabled: z.boolean().nullable().optional(), + subtitle: z.string().nullable().optional(), dockerImage: z.string().nullable().optional(), username: z.string().nullable().optional(), - isPreviewDeploymentsActive: z.boolean().optional(), + isPreviewDeploymentsActive: z.boolean().nullable().optional(), password: z.string().nullable().optional(), - args: z.array(z.string()).optional(), + args: z.array(z.string()).nullable().optional(), registryUrl: z.string().nullable().optional(), customGitSSHKeyId: z.string().nullable().optional(), - repository: z.string().optional(), + repository: z.string().nullable().optional(), dockerfile: nullableRelativeFilePathSchema, dockerContextPath: nullableBuildDirectorySchema, - branch: z.string().optional(), - customGitBranch: z.string().optional(), - customGitBuildPath: buildDirectorySchema, - customGitUrl: z.string().optional(), - buildPath: buildDirectorySchema, - gitlabBuildPath: buildDirectorySchema, - bitbucketBuildPath: buildDirectorySchema, - giteaBuildPath: buildDirectorySchema, - dropBuildPath: buildDirectorySchema, + branch: z.string().nullable().optional(), + customGitBranch: z.string().nullable().optional(), + customGitBuildPath: buildDirectorySchema.nullable(), + customGitUrl: z.string().nullable().optional(), + buildPath: buildDirectorySchema.nullable(), + gitlabBuildPath: buildDirectorySchema.nullable(), + bitbucketBuildPath: buildDirectorySchema.nullable(), + giteaBuildPath: buildDirectorySchema.nullable(), + dropBuildPath: buildDirectorySchema.nullable(), environmentId: z.string(), sourceType: z .enum(["github", "docker", "git", "gitlab", "bitbucket", "gitea", "drop"]) .optional(), - triggerType: z.enum(["push", "tag"]).optional(), - applicationStatus: z.enum(["idle", "running", "done", "error"]), - buildType: z.enum([ - "dockerfile", - "heroku_buildpacks", - "paketo_buildpacks", - "nixpacks", - "static", - "railpack", - ]), + triggerType: z.enum(["push", "tag"]).nullable().optional(), + applicationStatus: z.enum(["idle", "running", "done", "error"]).optional(), + buildType: z + .enum([ + "dockerfile", + "heroku_buildpacks", + "paketo_buildpacks", + "nixpacks", + "static", + "railpack", + ]) + .optional(), railpackVersion: z.string().nullable().optional(), herokuVersion: z.string().nullable().optional(), publishDirectory: nullableRelativeFilePathSchema, isStaticSpa: z.boolean().nullable().optional(), createEnvFile: z.boolean().optional(), - owner: z.string(), - healthCheckSwarm: HealthCheckSwarmSchema.nullable(), - restartPolicySwarm: RestartPolicySwarmSchema.nullable(), - placementSwarm: PlacementSwarmSchema.nullable(), - updateConfigSwarm: UpdateConfigSwarmSchema.nullable(), - rollbackConfigSwarm: UpdateConfigSwarmSchema.nullable(), - modeSwarm: ServiceModeSwarmSchema.nullable(), - labelsSwarm: LabelsSwarmSchema.nullable(), - networkSwarm: NetworkSwarmSchema.nullable(), - previewPort: z.number().optional(), - previewEnv: z.string().optional(), - previewBuildArgs: z.string().optional(), - previewBuildSecrets: z.string().optional(), - previewWildcard: z.string().optional(), - previewLimit: z.number().optional(), + owner: z.string().nullable().optional(), + healthCheckSwarm: HealthCheckSwarmSchema.nullable().optional(), + restartPolicySwarm: RestartPolicySwarmSchema.nullable().optional(), + placementSwarm: PlacementSwarmSchema.nullable().optional(), + updateConfigSwarm: UpdateConfigSwarmSchema.nullable().optional(), + rollbackConfigSwarm: UpdateConfigSwarmSchema.nullable().optional(), + modeSwarm: ServiceModeSwarmSchema.nullable().optional(), + labelsSwarm: LabelsSwarmSchema.nullable().optional(), + networkSwarm: NetworkSwarmSchema.nullable().optional(), + previewPort: z.number().nullable().optional(), + previewEnv: z.string().nullable().optional(), + previewBuildArgs: z.string().nullable().optional(), + previewBuildSecrets: z.string().nullable().optional(), + previewWildcard: z.string().nullable().optional(), + previewLimit: z.number().nullable().optional(), previewHttps: z.boolean().optional(), - previewPath: z.string().optional(), + previewPath: z.string().nullable().optional(), previewCertificateType: z.enum(["letsencrypt", "none", "custom"]).optional(), - previewRequireCollaboratorPermissions: z.boolean().optional(), - watchPaths: z.array(z.string()).optional().optional(), - previewLabels: z.array(z.string()).optional(), - networkIds: z.array(z.string()).optional(), + previewRequireCollaboratorPermissions: z.boolean().nullable().optional(), + watchPaths: z.array(z.string()).nullable().optional(), + previewLabels: z.array(z.string()).nullable().optional(), + networkIds: z.array(z.string()).nullable().optional(), detachDokployNetwork: z.boolean().optional(), - cleanCache: z.boolean().optional(), - stopGracePeriodSwarm: z.number().nullable(), - endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(), - ulimitsSwarm: UlimitsSwarmSchema.nullable(), + cleanCache: z.boolean().nullable().optional(), + stopGracePeriodSwarm: z.number().nullable().optional(), + endpointSpecSwarm: EndpointSpecSwarmSchema.nullable().optional(), + ulimitsSwarm: UlimitsSwarmSchema.nullable().optional(), enableSubmodules: z.boolean().optional(), icon: z .string() diff --git a/packages/server/src/db/schema/backups.ts b/packages/server/src/db/schema/backups.ts index df473388ba8..f14273c6c1a 100644 --- a/packages/server/src/db/schema/backups.ts +++ b/packages/server/src/db/schema/backups.ts @@ -182,7 +182,7 @@ export const backupsRelations = relations(backups, ({ one, many }) => ({ })); const createSchema = createInsertSchema(backups, { - backupId: z.string(), + backupId: z.string().optional(), destinationId: z.string(), enabled: z.boolean().nullable().optional(), prefix: z.string().min(1), diff --git a/packages/server/src/db/schema/certificate.ts b/packages/server/src/db/schema/certificate.ts index 49456d6996f..048b08faa21 100644 --- a/packages/server/src/db/schema/certificate.ts +++ b/packages/server/src/db/schema/certificate.ts @@ -52,8 +52,8 @@ export const apiCreateCertificate = createInsertSchema(certificates, { message: "Invalid certificate path", }) .optional(), - autoRenew: z.boolean().optional(), - serverId: z.string().optional(), + autoRenew: z.boolean().nullable().optional(), + serverId: z.string().nullable().optional(), }); export const apiFindCertificate = z.object({ diff --git a/packages/server/src/db/schema/compose.ts b/packages/server/src/db/schema/compose.ts index df32db563eb..0a01676e841 100644 --- a/packages/server/src/db/schema/compose.ts +++ b/packages/server/src/db/schema/compose.ts @@ -181,19 +181,19 @@ const createSchema = createInsertSchema(compose, { .regex(APP_NAME_REGEX, APP_NAME_MESSAGE) .optional(), description: z.string().nullable().optional(), - env: z.string().optional(), + env: z.string().nullable().optional(), composeFile: z.string().optional(), environmentId: z.string(), customGitSSHKeyId: z.string().nullable().optional(), command: z.string().optional(), createEnvFile: z.boolean().optional(), - composePath: z.string().min(1), + composePath: z.string().min(1).optional(), composeType: z.enum(["docker-compose", "stack"]).optional(), - watchPaths: z.array(z.string()).optional(), + watchPaths: z.array(z.string()).nullable().optional(), sourceType: z .enum(["git", "github", "gitlab", "bitbucket", "gitea", "raw"]) .optional(), - triggerType: z.enum(["push", "tag"]).optional(), + triggerType: z.enum(["push", "tag"]).nullable().optional(), composeStatus: z.enum(["idle", "running", "done", "error"]).optional(), icon: z .string() @@ -208,6 +208,7 @@ const createSchema = createInsertSchema(compose, { detachDokployNetwork: z.boolean(), }), ) + .nullable() .optional(), }); diff --git a/packages/server/src/db/schema/deployment.ts b/packages/server/src/db/schema/deployment.ts index 0c8d7e534ba..11ca50d9aad 100644 --- a/packages/server/src/db/schema/deployment.ts +++ b/packages/server/src/db/schema/deployment.ts @@ -179,13 +179,13 @@ export const deploymentsRelations = relations(deployments, ({ one }) => ({ const schema = createInsertSchema(deployments, { title: z.string().min(1), - status: z.string().default("running"), + status: z.string().default("running").nullable().optional(), logPath: z.string().min(1), - applicationId: z.string(), - composeId: z.string(), - description: z.string().optional(), - previewDeploymentId: z.string(), - buildServerId: z.string(), + applicationId: z.string().nullable().optional(), + composeId: z.string().nullable().optional(), + description: z.string().nullable().optional(), + previewDeploymentId: z.string().nullable().optional(), + buildServerId: z.string().nullable().optional(), }); export const apiCreateDeployment = schema .pick({ diff --git a/packages/server/src/db/schema/destination.ts b/packages/server/src/db/schema/destination.ts index beb26b6029a..e67bfb54bb1 100644 --- a/packages/server/src/db/schema/destination.ts +++ b/packages/server/src/db/schema/destination.ts @@ -43,9 +43,9 @@ export const destinationsRelations = relations( ); const createSchema = createInsertSchema(destinations, { - destinationId: z.string(), + destinationId: z.string().optional(), name: z.string().min(1), - provider: z.string(), + provider: z.string().nullable().optional(), accessKey: z.string(), bucket: z.string(), endpoint: z.string(), @@ -58,7 +58,9 @@ const createSchema = createInsertSchema(destinations, { .regex(ADDITIONAL_FLAG_REGEX, ADDITIONAL_FLAG_ERROR) .refine(isRcloneAdditionalFlagAllowed, RCLONE_ADDITIONAL_FLAG_ERROR), ) - .default([]), + .default([]) + .nullable() + .optional(), }); export const apiCreateDestination = createSchema diff --git a/packages/server/src/db/schema/domain.ts b/packages/server/src/db/schema/domain.ts index 54a0a5851a3..e9c9542c9cf 100644 --- a/packages/server/src/db/schema/domain.ts +++ b/packages/server/src/db/schema/domain.ts @@ -77,7 +77,10 @@ export const domainsRelations = relations(domains, ({ one }) => ({ const createSchema = createInsertSchema(domains, { ...domain.shape, // Override pgEnum so Zod 4 infers only string literals, not numeric enum index - domainType: z.enum(["compose", "application", "preview"]).optional(), + domainType: z + .enum(["compose", "application", "preview"]) + .nullable() + .optional(), }); export const apiCreateDomain = createSchema.pick({ diff --git a/packages/server/src/db/schema/libsql.ts b/packages/server/src/db/schema/libsql.ts index b6103e0bc9c..810cd46c12c 100644 --- a/packages/server/src/db/schema/libsql.ts +++ b/packages/server/src/db/schema/libsql.ts @@ -115,7 +115,7 @@ export const libsqlRelations = relations(libsql, ({ one, many }) => ({ })); const createSchema = createInsertSchema(libsql, { - libsqlId: z.string(), + libsqlId: z.string().optional(), name: z.string().min(1), appName: z .string() @@ -123,41 +123,41 @@ const createSchema = createInsertSchema(libsql, { .max(63) .regex(APP_NAME_REGEX, APP_NAME_MESSAGE) .optional(), - createdAt: z.string(), + createdAt: z.string().optional(), databaseUser: z.string().min(1), databasePassword: z.string().regex(DATABASE_PASSWORD_REGEX, { message: DATABASE_PASSWORD_MESSAGE, }), - sqldNode: z.enum(sqldNode.enumValues), - sqldPrimaryUrl: z.string().nullable(), - enableNamespaces: z.boolean().default(false), + sqldNode: z.enum(sqldNode.enumValues).optional(), + sqldPrimaryUrl: z.string().nullable().optional(), + enableNamespaces: z.boolean().default(false).optional(), dockerImage: z .string() .default("ghcr.io/tursodatabase/libsql-server:v0.24.32"), - command: z.string().optional(), - env: z.string().optional(), + command: z.string().nullable().optional(), + env: z.string().nullable().optional(), memoryReservation: z.string().nullable().optional(), memoryLimit: z.string().nullable().optional(), cpuReservation: z.string().nullable().optional(), cpuLimit: z.string().nullable().optional(), environmentId: z.string(), - applicationStatus: z.enum(["idle", "running", "done", "error"]), + applicationStatus: z.enum(["idle", "running", "done", "error"]).optional(), externalPort: z.number().nullable().optional(), externalGRPCPort: z.number().nullable().optional(), externalAdminPort: z.number().nullable().optional(), description: z.string().nullable().optional(), serverId: z.string().nullable().optional(), - healthCheckSwarm: HealthCheckSwarmSchema.nullable(), - restartPolicySwarm: RestartPolicySwarmSchema.nullable(), - placementSwarm: PlacementSwarmSchema.nullable(), - updateConfigSwarm: UpdateConfigSwarmSchema.nullable(), - rollbackConfigSwarm: UpdateConfigSwarmSchema.nullable(), - modeSwarm: ServiceModeSwarmSchema.nullable(), - labelsSwarm: LabelsSwarmSchema.nullable(), - networkSwarm: NetworkSwarmSchema.nullable(), - stopGracePeriodSwarm: z.number().nullable(), - endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(), - networkIds: z.array(z.string()).optional(), + healthCheckSwarm: HealthCheckSwarmSchema.nullable().optional(), + restartPolicySwarm: RestartPolicySwarmSchema.nullable().optional(), + placementSwarm: PlacementSwarmSchema.nullable().optional(), + updateConfigSwarm: UpdateConfigSwarmSchema.nullable().optional(), + rollbackConfigSwarm: UpdateConfigSwarmSchema.nullable().optional(), + modeSwarm: ServiceModeSwarmSchema.nullable().optional(), + labelsSwarm: LabelsSwarmSchema.nullable().optional(), + networkSwarm: NetworkSwarmSchema.nullable().optional(), + stopGracePeriodSwarm: z.number().nullable().optional(), + endpointSpecSwarm: EndpointSpecSwarmSchema.nullable().optional(), + networkIds: z.array(z.string()).nullable().optional(), detachDokployNetwork: z.boolean().optional(), }); diff --git a/packages/server/src/db/schema/mariadb.ts b/packages/server/src/db/schema/mariadb.ts index 201ed322fdb..8f5ad6b0f0b 100644 --- a/packages/server/src/db/schema/mariadb.ts +++ b/packages/server/src/db/schema/mariadb.ts @@ -117,7 +117,7 @@ export const mariadbRelations = relations(mariadb, ({ one, many }) => ({ })); const createSchema = createInsertSchema(mariadb, { - mariadbId: z.string(), + mariadbId: z.string().optional(), name: z.string().min(1), appName: z .string() @@ -125,7 +125,7 @@ const createSchema = createInsertSchema(mariadb, { .max(63) .regex(APP_NAME_REGEX, APP_NAME_MESSAGE) .optional(), - createdAt: z.string(), + createdAt: z.string().optional(), databaseName: z.string().min(1), databaseUser: z .string() @@ -141,30 +141,30 @@ const createSchema = createInsertSchema(mariadb, { }) .optional(), dockerImage: z.string().default("mariadb:6"), - command: z.string().optional(), - args: z.array(z.string()).optional(), - env: z.string().optional(), + command: z.string().nullable().optional(), + args: z.array(z.string()).nullable().optional(), + env: z.string().nullable().optional(), memoryReservation: z.string().nullable().optional(), memoryLimit: z.string().nullable().optional(), cpuReservation: z.string().nullable().optional(), cpuLimit: z.string().nullable().optional(), environmentId: z.string(), - applicationStatus: z.enum(["idle", "running", "done", "error"]), + applicationStatus: z.enum(["idle", "running", "done", "error"]).optional(), externalPort: z.number().nullable().optional(), description: z.string().nullable().optional(), serverId: z.string().nullable().optional(), - healthCheckSwarm: HealthCheckSwarmSchema.nullable(), - restartPolicySwarm: RestartPolicySwarmSchema.nullable(), - placementSwarm: PlacementSwarmSchema.nullable(), - updateConfigSwarm: UpdateConfigSwarmSchema.nullable(), - rollbackConfigSwarm: UpdateConfigSwarmSchema.nullable(), - modeSwarm: ServiceModeSwarmSchema.nullable(), - labelsSwarm: LabelsSwarmSchema.nullable(), - networkSwarm: NetworkSwarmSchema.nullable(), - stopGracePeriodSwarm: z.number().nullable(), - endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(), - ulimitsSwarm: UlimitsSwarmSchema.nullable(), - networkIds: z.array(z.string()).optional(), + healthCheckSwarm: HealthCheckSwarmSchema.nullable().optional(), + restartPolicySwarm: RestartPolicySwarmSchema.nullable().optional(), + placementSwarm: PlacementSwarmSchema.nullable().optional(), + updateConfigSwarm: UpdateConfigSwarmSchema.nullable().optional(), + rollbackConfigSwarm: UpdateConfigSwarmSchema.nullable().optional(), + modeSwarm: ServiceModeSwarmSchema.nullable().optional(), + labelsSwarm: LabelsSwarmSchema.nullable().optional(), + networkSwarm: NetworkSwarmSchema.nullable().optional(), + stopGracePeriodSwarm: z.number().nullable().optional(), + endpointSpecSwarm: EndpointSpecSwarmSchema.nullable().optional(), + ulimitsSwarm: UlimitsSwarmSchema.nullable().optional(), + networkIds: z.array(z.string()).nullable().optional(), detachDokployNetwork: z.boolean().optional(), }); diff --git a/packages/server/src/db/schema/mongo.ts b/packages/server/src/db/schema/mongo.ts index da962a95d9c..1a357a41b1a 100644 --- a/packages/server/src/db/schema/mongo.ts +++ b/packages/server/src/db/schema/mongo.ts @@ -120,8 +120,8 @@ const createSchema = createInsertSchema(mongo, { .max(63) .regex(APP_NAME_REGEX, APP_NAME_MESSAGE) .optional(), - createdAt: z.string(), - mongoId: z.string(), + createdAt: z.string().optional(), + mongoId: z.string().optional(), name: z.string().min(1), databasePassword: z.string().regex(DATABASE_PASSWORD_REGEX, { message: DATABASE_PASSWORD_MESSAGE, @@ -130,32 +130,32 @@ const createSchema = createInsertSchema(mongo, { .string() .min(1) .regex(DATABASE_IDENTIFIER_REGEX, DATABASE_IDENTIFIER_MESSAGE), - dockerImage: z.string().default("mongo:15"), - command: z.string().optional(), - args: z.array(z.string()).optional(), - env: z.string().optional(), + dockerImage: z.string().default("mongo:15").optional(), + command: z.string().nullable().optional(), + args: z.array(z.string()).nullable().optional(), + env: z.string().nullable().optional(), memoryReservation: z.string().nullable().optional(), memoryLimit: z.string().nullable().optional(), cpuReservation: z.string().nullable().optional(), cpuLimit: z.string().nullable().optional(), environmentId: z.string(), - applicationStatus: z.enum(["idle", "running", "done", "error"]), + applicationStatus: z.enum(["idle", "running", "done", "error"]).optional(), externalPort: z.number().nullable().optional(), description: z.string().nullable().optional(), serverId: z.string().nullable().optional(), - replicaSets: z.boolean().nullable().default(false), - healthCheckSwarm: HealthCheckSwarmSchema.nullable(), - restartPolicySwarm: RestartPolicySwarmSchema.nullable(), - placementSwarm: PlacementSwarmSchema.nullable(), - updateConfigSwarm: UpdateConfigSwarmSchema.nullable(), - rollbackConfigSwarm: UpdateConfigSwarmSchema.nullable(), - modeSwarm: ServiceModeSwarmSchema.nullable(), - labelsSwarm: LabelsSwarmSchema.nullable(), - networkSwarm: NetworkSwarmSchema.nullable(), - stopGracePeriodSwarm: z.number().nullable(), - endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(), - ulimitsSwarm: UlimitsSwarmSchema.nullable(), - networkIds: z.array(z.string()).optional(), + replicaSets: z.boolean().nullable().default(false).optional(), + healthCheckSwarm: HealthCheckSwarmSchema.nullable().optional(), + restartPolicySwarm: RestartPolicySwarmSchema.nullable().optional(), + placementSwarm: PlacementSwarmSchema.nullable().optional(), + updateConfigSwarm: UpdateConfigSwarmSchema.nullable().optional(), + rollbackConfigSwarm: UpdateConfigSwarmSchema.nullable().optional(), + modeSwarm: ServiceModeSwarmSchema.nullable().optional(), + labelsSwarm: LabelsSwarmSchema.nullable().optional(), + networkSwarm: NetworkSwarmSchema.nullable().optional(), + stopGracePeriodSwarm: z.number().nullable().optional(), + endpointSpecSwarm: EndpointSpecSwarmSchema.nullable().optional(), + ulimitsSwarm: UlimitsSwarmSchema.nullable().optional(), + networkIds: z.array(z.string()).nullable().optional(), detachDokployNetwork: z.boolean().optional(), }); diff --git a/packages/server/src/db/schema/mount.ts b/packages/server/src/db/schema/mount.ts index c09c92e48b7..148d09aa627 100644 --- a/packages/server/src/db/schema/mount.ts +++ b/packages/server/src/db/schema/mount.ts @@ -111,7 +111,7 @@ export const MountssRelations = relations(mounts, ({ one }) => ({ })); const createSchema = createInsertSchema(mounts, { - applicationId: z.string(), + applicationId: z.string().nullable().optional(), type: z.enum(["bind", "volume", "file"]), hostPath: z.string().nullable().optional(), volumeName: dockerVolumeNameSchema.nullable().optional(), @@ -119,16 +119,18 @@ const createSchema = createInsertSchema(mounts, { mountPath: z.string().min(1), mountId: z.string().optional(), filePath: z.string().nullable().optional(), - serviceType: z.enum([ - "application", - "postgres", - "mysql", - "mariadb", - "mongo", - "redis", - "compose", - "libsql", - ]), + serviceType: z + .enum([ + "application", + "postgres", + "mysql", + "mariadb", + "mongo", + "redis", + "compose", + "libsql", + ]) + .optional(), }); export const apiCreateMount = createSchema diff --git a/packages/server/src/db/schema/mysql.ts b/packages/server/src/db/schema/mysql.ts index b16225fe0f4..516dece0726 100644 --- a/packages/server/src/db/schema/mysql.ts +++ b/packages/server/src/db/schema/mysql.ts @@ -115,14 +115,14 @@ export const mysqlRelations = relations(mysql, ({ one, many }) => ({ })); const createSchema = createInsertSchema(mysql, { - mysqlId: z.string(), + mysqlId: z.string().optional(), appName: z .string() .min(1) .max(63) .regex(APP_NAME_REGEX, APP_NAME_MESSAGE) .optional(), - createdAt: z.string(), + createdAt: z.string().optional(), name: z.string().min(1), databaseName: z.string().min(1), databaseUser: z @@ -139,29 +139,29 @@ const createSchema = createInsertSchema(mysql, { }) .optional(), dockerImage: z.string().default("mysql:8"), - command: z.string().optional(), - args: z.array(z.string()).optional(), - env: z.string().optional(), + command: z.string().nullable().optional(), + args: z.array(z.string()).nullable().optional(), + env: z.string().nullable().optional(), memoryReservation: z.string().nullable().optional(), memoryLimit: z.string().nullable().optional(), cpuReservation: z.string().nullable().optional(), cpuLimit: z.string().nullable().optional(), - applicationStatus: z.enum(["idle", "running", "done", "error"]), + applicationStatus: z.enum(["idle", "running", "done", "error"]).optional(), externalPort: z.number().nullable().optional(), description: z.string().nullable().optional(), serverId: z.string().nullable().optional(), - healthCheckSwarm: HealthCheckSwarmSchema.nullable(), - restartPolicySwarm: RestartPolicySwarmSchema.nullable(), - placementSwarm: PlacementSwarmSchema.nullable(), - updateConfigSwarm: UpdateConfigSwarmSchema.nullable(), - rollbackConfigSwarm: UpdateConfigSwarmSchema.nullable(), - modeSwarm: ServiceModeSwarmSchema.nullable(), - labelsSwarm: LabelsSwarmSchema.nullable(), - networkSwarm: NetworkSwarmSchema.nullable(), - stopGracePeriodSwarm: z.number().nullable(), - endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(), - ulimitsSwarm: UlimitsSwarmSchema.nullable(), - networkIds: z.array(z.string()).optional(), + healthCheckSwarm: HealthCheckSwarmSchema.nullable().optional(), + restartPolicySwarm: RestartPolicySwarmSchema.nullable().optional(), + placementSwarm: PlacementSwarmSchema.nullable().optional(), + updateConfigSwarm: UpdateConfigSwarmSchema.nullable().optional(), + rollbackConfigSwarm: UpdateConfigSwarmSchema.nullable().optional(), + modeSwarm: ServiceModeSwarmSchema.nullable().optional(), + labelsSwarm: LabelsSwarmSchema.nullable().optional(), + networkSwarm: NetworkSwarmSchema.nullable().optional(), + stopGracePeriodSwarm: z.number().nullable().optional(), + endpointSpecSwarm: EndpointSpecSwarmSchema.nullable().optional(), + ulimitsSwarm: UlimitsSwarmSchema.nullable().optional(), + networkIds: z.array(z.string()).nullable().optional(), detachDokployNetwork: z.boolean().optional(), }); diff --git a/packages/server/src/db/schema/network.ts b/packages/server/src/db/schema/network.ts index b8947fc89a3..221eaed60e3 100644 --- a/packages/server/src/db/schema/network.ts +++ b/packages/server/src/db/schema/network.ts @@ -57,7 +57,7 @@ export const networkRelations = relations(network, ({ one }) => ({ })); const createSchema = createInsertSchema(network, { - networkId: z.string().min(1), + networkId: z.string().min(1).optional(), name: z.string().min(1), driver: z.enum(["bridge", "overlay"]).optional(), internal: z.boolean().optional(), @@ -78,6 +78,7 @@ const createSchema = createInsertSchema(network, { ) .optional(), }) + .nullable() .optional(), organizationId: z.string().min(1), serverId: z.string().optional().nullable(), diff --git a/packages/server/src/db/schema/patch.ts b/packages/server/src/db/schema/patch.ts index 61d787cedb8..8a0e0bf6c9d 100644 --- a/packages/server/src/db/schema/patch.ts +++ b/packages/server/src/db/schema/patch.ts @@ -58,8 +58,8 @@ const createSchema = createInsertSchema(patch, { content: z.string(), type: z.enum(["create", "update", "delete"]).optional(), enabled: z.boolean().optional(), - applicationId: z.string().optional(), - composeId: z.string().optional(), + applicationId: z.string().nullable().optional(), + composeId: z.string().nullable().optional(), }); export const apiCreatePatch = createSchema diff --git a/packages/server/src/db/schema/port.ts b/packages/server/src/db/schema/port.ts index 4ba27b5e3c0..7ff9a27862d 100644 --- a/packages/server/src/db/schema/port.ts +++ b/packages/server/src/db/schema/port.ts @@ -31,10 +31,10 @@ export const portsRelations = relations(ports, ({ one }) => ({ })); const createSchema = createInsertSchema(ports, { - portId: z.string().min(1), + portId: z.string().min(1).optional(), applicationId: z.string().min(1), publishedPort: z.number(), - publishMode: z.enum(["ingress", "host"]).default("ingress"), + publishMode: z.enum(["ingress", "host"]).default("ingress").optional(), targetPort: z.number(), protocol: z.enum(["tcp", "udp"]).default("tcp"), }); diff --git a/packages/server/src/db/schema/postgres.ts b/packages/server/src/db/schema/postgres.ts index 66acda3f1bf..4534b43a40b 100644 --- a/packages/server/src/db/schema/postgres.ts +++ b/packages/server/src/db/schema/postgres.ts @@ -115,7 +115,7 @@ export const postgresRelations = relations(postgres, ({ one, many }) => ({ })); const createSchema = createInsertSchema(postgres, { - postgresId: z.string(), + postgresId: z.string().optional(), name: z.string().min(1), appName: z .string() @@ -132,31 +132,31 @@ const createSchema = createInsertSchema(postgres, { .min(1) .regex(DATABASE_IDENTIFIER_REGEX, DATABASE_IDENTIFIER_MESSAGE), dockerImage: z.string().default("postgres:18"), - command: z.string().optional(), - args: z.array(z.string()).optional(), - env: z.string().optional(), + command: z.string().nullable().optional(), + args: z.array(z.string()).nullable().optional(), + env: z.string().nullable().optional(), memoryReservation: z.string().nullable().optional(), memoryLimit: z.string().nullable().optional(), cpuReservation: z.string().nullable().optional(), cpuLimit: z.string().nullable().optional(), environmentId: z.string(), - applicationStatus: z.enum(["idle", "running", "done", "error"]), + applicationStatus: z.enum(["idle", "running", "done", "error"]).optional(), externalPort: z.number().nullable().optional(), - createdAt: z.string(), + createdAt: z.string().optional(), description: z.string().nullable().optional(), serverId: z.string().nullable().optional(), - healthCheckSwarm: HealthCheckSwarmSchema.nullable(), - restartPolicySwarm: RestartPolicySwarmSchema.nullable(), - placementSwarm: PlacementSwarmSchema.nullable(), - updateConfigSwarm: UpdateConfigSwarmSchema.nullable(), - rollbackConfigSwarm: UpdateConfigSwarmSchema.nullable(), - modeSwarm: ServiceModeSwarmSchema.nullable(), - labelsSwarm: LabelsSwarmSchema.nullable(), - networkSwarm: NetworkSwarmSchema.nullable(), - stopGracePeriodSwarm: z.number().nullable(), - endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(), - ulimitsSwarm: UlimitsSwarmSchema.nullable(), - networkIds: z.array(z.string()).optional(), + healthCheckSwarm: HealthCheckSwarmSchema.nullable().optional(), + restartPolicySwarm: RestartPolicySwarmSchema.nullable().optional(), + placementSwarm: PlacementSwarmSchema.nullable().optional(), + updateConfigSwarm: UpdateConfigSwarmSchema.nullable().optional(), + rollbackConfigSwarm: UpdateConfigSwarmSchema.nullable().optional(), + modeSwarm: ServiceModeSwarmSchema.nullable().optional(), + labelsSwarm: LabelsSwarmSchema.nullable().optional(), + networkSwarm: NetworkSwarmSchema.nullable().optional(), + stopGracePeriodSwarm: z.number().nullable().optional(), + endpointSpecSwarm: EndpointSpecSwarmSchema.nullable().optional(), + ulimitsSwarm: UlimitsSwarmSchema.nullable().optional(), + networkIds: z.array(z.string()).nullable().optional(), detachDokployNetwork: z.boolean().optional(), }); diff --git a/packages/server/src/db/schema/project.ts b/packages/server/src/db/schema/project.ts index 2e47c18554c..72a6895ba96 100644 --- a/packages/server/src/db/schema/project.ts +++ b/packages/server/src/db/schema/project.ts @@ -35,9 +35,9 @@ export const projectRelations = relations(projects, ({ many, one }) => ({ })); const createSchema = createInsertSchema(projects, { - projectId: z.string().min(1), + projectId: z.string().min(1).optional(), name: z.string().min(1), - description: z.string().optional(), + description: z.string().nullable().optional(), env: z.string().optional(), }); diff --git a/packages/server/src/db/schema/redirects.ts b/packages/server/src/db/schema/redirects.ts index 6d14537d09b..df3a41ebc08 100644 --- a/packages/server/src/db/schema/redirects.ts +++ b/packages/server/src/db/schema/redirects.ts @@ -29,7 +29,7 @@ export const redirectRelations = relations(redirects, ({ one }) => ({ }), })); const createSchema = createInsertSchema(redirects, { - redirectId: z.string().min(1), + redirectId: z.string().min(1).optional(), regex: z.string().min(1), replacement: z.string().min(1), permanent: z.boolean().optional(), diff --git a/packages/server/src/db/schema/redis.ts b/packages/server/src/db/schema/redis.ts index 3cf34832a4d..ab79934c06c 100644 --- a/packages/server/src/db/schema/redis.ts +++ b/packages/server/src/db/schema/redis.ts @@ -108,43 +108,43 @@ export const redisRelations = relations(redis, ({ one, many }) => ({ })); const createSchema = createInsertSchema(redis, { - redisId: z.string(), + redisId: z.string().optional(), appName: z .string() .min(1) .max(63) .regex(APP_NAME_REGEX, APP_NAME_MESSAGE) .optional(), - createdAt: z.string(), + createdAt: z.string().optional(), name: z.string().min(1), databasePassword: z.string().regex(DATABASE_PASSWORD_REGEX, { message: DATABASE_PASSWORD_MESSAGE, }), dockerImage: z.string().default("redis:8"), - command: z.string().optional(), - args: z.array(z.string()).optional(), - env: z.string().optional(), + command: z.string().nullable().optional(), + args: z.array(z.string()).nullable().optional(), + env: z.string().nullable().optional(), memoryReservation: z.string().nullable().optional(), memoryLimit: z.string().nullable().optional(), cpuReservation: z.string().nullable().optional(), cpuLimit: z.string().nullable().optional(), environmentId: z.string(), - applicationStatus: z.enum(["idle", "running", "done", "error"]), + applicationStatus: z.enum(["idle", "running", "done", "error"]).optional(), externalPort: z.number().nullable().optional(), description: z.string().nullable().optional(), serverId: z.string().nullable().optional(), - healthCheckSwarm: HealthCheckSwarmSchema.nullable(), - restartPolicySwarm: RestartPolicySwarmSchema.nullable(), - placementSwarm: PlacementSwarmSchema.nullable(), - updateConfigSwarm: UpdateConfigSwarmSchema.nullable(), - rollbackConfigSwarm: UpdateConfigSwarmSchema.nullable(), - modeSwarm: ServiceModeSwarmSchema.nullable(), - labelsSwarm: LabelsSwarmSchema.nullable(), - networkSwarm: NetworkSwarmSchema.nullable(), - stopGracePeriodSwarm: z.number().nullable(), - endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(), - ulimitsSwarm: UlimitsSwarmSchema.nullable(), - networkIds: z.array(z.string()).optional(), + healthCheckSwarm: HealthCheckSwarmSchema.nullable().optional(), + restartPolicySwarm: RestartPolicySwarmSchema.nullable().optional(), + placementSwarm: PlacementSwarmSchema.nullable().optional(), + updateConfigSwarm: UpdateConfigSwarmSchema.nullable().optional(), + rollbackConfigSwarm: UpdateConfigSwarmSchema.nullable().optional(), + modeSwarm: ServiceModeSwarmSchema.nullable().optional(), + labelsSwarm: LabelsSwarmSchema.nullable().optional(), + networkSwarm: NetworkSwarmSchema.nullable().optional(), + stopGracePeriodSwarm: z.number().nullable().optional(), + endpointSpecSwarm: EndpointSpecSwarmSchema.nullable().optional(), + ulimitsSwarm: UlimitsSwarmSchema.nullable().optional(), + networkIds: z.array(z.string()).nullable().optional(), detachDokployNetwork: z.boolean().optional(), }); diff --git a/packages/server/src/db/schema/registry.ts b/packages/server/src/db/schema/registry.ts index a65399083d5..c84b77a91c1 100644 --- a/packages/server/src/db/schema/registry.ts +++ b/packages/server/src/db/schema/registry.ts @@ -65,10 +65,10 @@ const createSchema = createInsertSchema(registry, { registryName: z.string().min(1), username: registryUsernameSchema, password: z.string().min(1), - registryUrl: registryUrlSchema, + registryUrl: registryUrlSchema.optional(), organizationId: z.string().min(1), - registryId: z.string().min(1), - registryType: z.enum(["cloud"]), + registryId: z.string().min(1).optional(), + registryType: z.enum(["cloud"]).optional(), imagePrefix: z.string().nullable().optional(), }); diff --git a/packages/server/src/db/schema/schedule.ts b/packages/server/src/db/schema/schedule.ts index 2cc96014812..3d40127708f 100644 --- a/packages/server/src/db/schema/schedule.ts +++ b/packages/server/src/db/schema/schedule.ts @@ -86,7 +86,9 @@ export const createScheduleSchema = createInsertSchema(schedules, { .max(63) .regex(APP_NAME_REGEX, APP_NAME_MESSAGE) .optional(), - scheduleType: z.enum(["application", "compose", "server", "dokploy-server"]), + scheduleType: z + .enum(["application", "compose", "server", "dokploy-server"]) + .optional(), }); export const updateScheduleSchema = createScheduleSchema.extend({ diff --git a/packages/server/src/db/schema/security.ts b/packages/server/src/db/schema/security.ts index b669a7900ad..45f68446a03 100644 --- a/packages/server/src/db/schema/security.ts +++ b/packages/server/src/db/schema/security.ts @@ -33,7 +33,7 @@ export const securityRelations = relations(security, ({ one }) => ({ }), })); const createSchema = createInsertSchema(security, { - securityId: z.string().min(1), + securityId: z.string().min(1).optional(), username: z.string().min(1), password: z.string().min(1), }); diff --git a/packages/server/src/db/schema/server.ts b/packages/server/src/db/schema/server.ts index fee83d9f6f7..934b4658b61 100644 --- a/packages/server/src/db/schema/server.ts +++ b/packages/server/src/db/schema/server.ts @@ -135,7 +135,7 @@ export const serverRelations = relations(server, ({ one, many }) => ({ })); const createSchema = createInsertSchema(server, { - serverId: z.string().min(1), + serverId: z.string().min(1).optional(), name: z.string().min(1), description: z.string().nullable().optional(), serverType: z.enum(["deploy", "build"]).optional(), diff --git a/packages/server/src/db/schema/ssh-key.ts b/packages/server/src/db/schema/ssh-key.ts index d90a921ca25..38b75ba3a06 100644 --- a/packages/server/src/db/schema/ssh-key.ts +++ b/packages/server/src/db/schema/ssh-key.ts @@ -37,11 +37,15 @@ export const sshKeysRelations = relations(sshKeys, ({ many, one }) => ({ }), })); -const createSchema = createInsertSchema( - sshKeys, - /* Private key is not stored in the DB */ - sshKeyCreate.omit({ privateKey: true }).shape, -); +/* Private key is not stored in the DB */ +const { description, ...sshKeyFields } = sshKeyCreate.omit({ + privateKey: true, +}).shape; + +const createSchema = createInsertSchema(sshKeys, { + ...sshKeyFields, + description: description.nullable(), +}); export const apiCreateSshKey = createSchema .pick({ diff --git a/packages/server/src/db/schema/tag.ts b/packages/server/src/db/schema/tag.ts index 62414976036..576860f4485 100644 --- a/packages/server/src/db/schema/tag.ts +++ b/packages/server/src/db/schema/tag.ts @@ -74,9 +74,9 @@ export const projectTagRelations = relations(projectTags, ({ one }) => ({ })); const createSchema = createInsertSchema(tags, { - tagId: z.string().min(1), + tagId: z.string().min(1).optional(), name: z.string().min(1), - color: z.string().optional(), + color: z.string().nullable().optional(), }); export const apiCreateTag = createSchema.pick({ diff --git a/packages/server/src/db/schema/user.ts b/packages/server/src/db/schema/user.ts index 9a432478fe5..1b6e4741c10 100644 --- a/packages/server/src/db/schema/user.ts +++ b/packages/server/src/db/schema/user.ts @@ -90,7 +90,7 @@ export const usersRelations = relations(user, ({ one, many }) => ({ })); const createSchema = createInsertSchema(user, { - id: z.string().min(1), + id: z.string().min(1).optional(), isRegistered: z.boolean().optional(), }).omit({ role: true, diff --git a/packages/server/src/db/schema/web-server-settings.ts b/packages/server/src/db/schema/web-server-settings.ts index 93635ee82e7..30d29a22320 100644 --- a/packages/server/src/db/schema/web-server-settings.ts +++ b/packages/server/src/db/schema/web-server-settings.ts @@ -130,7 +130,7 @@ export const webServerSettingsRelations = relations( ); const createSchema = createInsertSchema(webServerSettings, { - id: z.string().min(1), + id: z.string().min(1).optional(), }); export const apiUpdateWebServerSettings = createSchema.partial().extend({