From 5fd7b07cc7492f5e1e40a317408d14207bc691cf Mon Sep 17 00:00:00 2001 From: agentHits <140916359+agentHits@users.noreply.github.com> Date: Fri, 23 Oct 2026 17:42:43 -0400 Subject: [PATCH 1/2] fix(traefik): read the Traefik ports when an exposed port is not published The additional ports dialog of the web server settings has failed with an internal error since Traefik stopped publishing port 80 (#53): settings.getTraefikPorts answered 500 "Cannot read properties of null (reading '0')". `docker container inspect` reports a port the image exposes but the container does not publish as `"80/tcp": null`, and readPorts took the first element of that value. readPorts now skips ports without a host binding. 80 and 443 stay out of the list as before, and no port publishing changes. Tests: new __test__/settings/traefik-ports.test.ts with the port map of the dev Traefik container (80 exposed, 443 tcp/udp published), an extra published port next to an unpublished one, and a remote server. The three cases fail with the dev error before the change and pass after it. __test__/settings, __test__/traefik and __test__/server pass (824 tests); typecheck passes in all four workspaces. Co-Authored-By: Claude Opus 5.5 --- .../__test__/settings/traefik-ports.test.ts | 78 +++++++++++++++++++ packages/server/src/services/settings.ts | 4 +- 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 apps/dokploy/__test__/settings/traefik-ports.test.ts diff --git a/apps/dokploy/__test__/settings/traefik-ports.test.ts b/apps/dokploy/__test__/settings/traefik-ports.test.ts new file mode 100644 index 00000000000..0410708eab3 --- /dev/null +++ b/apps/dokploy/__test__/settings/traefik-ports.test.ts @@ -0,0 +1,78 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +const mocks = vi.hoisted(() => ({ + execAsync: vi.fn(), + execAsyncRemote: vi.fn(), +})); + +vi.mock("@dokploy/server/db", () => ({ + db: {}, +})); + +vi.mock("@dokploy/server/utils/process/execAsync", () => ({ + execAsync: mocks.execAsync, + execAsyncRemote: mocks.execAsyncRemote, +})); + +const { readPorts } = await import("@dokploy/server/services/settings"); + +// `docker container inspect --format '{{json .NetworkSettings.Ports}}'` of a +// Traefik container that publishes only 443: the image still exposes 80. +const traefikPorts = { + "80/tcp": null, + "443/tcp": [ + { HostIp: "0.0.0.0", HostPort: "443" }, + { HostIp: "::", HostPort: "443" }, + ], + "443/udp": [ + { HostIp: "0.0.0.0", HostPort: "443" }, + { HostIp: "::", HostPort: "443" }, + ], +}; + +const standaloneWith = (ports: Record) => (command: string) => + Promise.resolve({ + stdout: command.includes("RESOURCE_NAME=") + ? "standalone\n" + : `${JSON.stringify(ports)}\n`, + stderr: "", + }); + +describe("readPorts for a standalone Traefik container", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it("skips exposed ports that have no host binding", async () => { + mocks.execAsync.mockImplementation(standaloneWith(traefikPorts)); + + await expect(readPorts("dokploy-traefik")).resolves.toEqual([]); + }); + + it("still lists additional published ports next to an unpublished one", async () => { + mocks.execAsync.mockImplementation( + standaloneWith({ + ...traefikPorts, + "8080/tcp": null, + "5432/tcp": [ + { HostIp: "0.0.0.0", HostPort: "5433" }, + { HostIp: "::", HostPort: "5433" }, + ], + }), + ); + + await expect(readPorts("dokploy-traefik")).resolves.toEqual([ + { targetPort: 5432, publishedPort: 5433, protocol: "tcp" }, + ]); + }); + + it("reads the ports of a remote server's Traefik the same way", async () => { + mocks.execAsyncRemote.mockImplementation( + (_serverId: string, command: string) => + standaloneWith(traefikPorts)(command), + ); + + await expect(readPorts("dokploy-traefik", "server-1")).resolves.toEqual([]); + expect(mocks.execAsync).not.toHaveBeenCalled(); + }); +}); diff --git a/packages/server/src/services/settings.ts b/packages/server/src/services/settings.ts index 08f042509c0..ffbe0e99377 100644 --- a/packages/server/src/services/settings.ts +++ b/packages/server/src/services/settings.ts @@ -1070,8 +1070,10 @@ export const readPorts = async ( const protocol = key.split("/")[1]; const targetPort = Number.parseInt(key.split("/")[0] ?? "0", 10); + // A port the image exposes but the container does not publish comes + // back as null (Traefik exposes 80, which is never published here). // Take only the first mapping to avoid duplicates (IPv4 and IPv6) - const firstMapping = containerPortMappings[0]; + const firstMapping = containerPortMappings?.[0]; if (firstMapping) { const publishedPort = Number.parseInt(firstMapping.HostPort, 10); const portKey = `${targetPort}-${publishedPort}-${protocol}`; From 487bda8a5c6a6bf86c14ebae37f9ef60abc06b7e Mon Sep 17 00:00:00 2001 From: agentHits <140916359+agentHits@users.noreply.github.com> Date: Fri, 23 Oct 2026 18:04:49 -0400 Subject: [PATCH 2/2] fix(deps): move every zod copy past GHSA-mrhx-c7xc-m3w5 bun audit started failing on this PR with a new high advisory: zod before 4.6.6 can exhaust memory while validating oversized constrained collections. It affected zod 4.6.5 in all workspaces and three zod 3.25.76 copies, for which no 3.x fix exists. - zod goes to ^4.6.7 in api, dokploy, schedules and server. - shadcn goes to ^4.22.1, which (with @shadcn/registry 0.2.0) uses zod 4. Its dist/tailwind.css, imported by globals.css, is byte-identical to 4.21.4. - inngest declares zod ^3.25.0 as a dependency but zod ^3.25.0 || ^4.0.0 as a peer, so the override "inngest>zod": "^4.6.7" gives it the shared zod 4. The lockfile drops the three zod 3 copies; every version is older than the 3-day release age. Checks: bun audit reports no vulnerabilities; bun install --frozen-lockfile; typecheck in all four workspaces; the full vitest run passes (4084 passed, 5 skipped) except the nixpacks real build, which timed out under full-suite load on this Mac and passes alone (35 s). Co-Authored-By: Claude Opus 5.5 --- apps/api/package.json | 2 +- apps/dokploy/package.json | 4 ++-- apps/schedules/package.json | 2 +- bun.lock | 25 +++++++++++-------------- package.json | 3 ++- packages/server/package.json | 2 +- 6 files changed, 18 insertions(+), 20 deletions(-) diff --git a/apps/api/package.json b/apps/api/package.json index d1f3ff48956..c8889036145 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -21,7 +21,7 @@ "react": "19.3.0", "react-dom": "19.3.0", "redis": "4.7.1", - "zod": "^4.6.5" + "zod": "^4.6.7" }, "devDependencies": { "@types/node": "^24.19.1", diff --git a/apps/dokploy/package.json b/apps/dokploy/package.json index eb3d6e628a0..f8cd88d1d10 100644 --- a/apps/dokploy/package.json +++ b/apps/dokploy/package.json @@ -137,7 +137,7 @@ "recharts": "^3.10.1", "resend": "^6.32.1", "semver": "7.8.5", - "shadcn": "^4.21.4", + "shadcn": "^4.22.1", "shell-quote": "^1.12.0", "slugify": "^1.6.9", "sonner": "^2.0.8", @@ -154,7 +154,7 @@ "ws": "8.22.0", "xterm-addon-fit": "^0.8.0", "yaml": "2.9.1", - "zod": "^4.6.5", + "zod": "^4.6.7", "zod-form-data": "^3.0.3" }, "devDependencies": { diff --git a/apps/schedules/package.json b/apps/schedules/package.json index 898e50fbe5b..1466f5b8681 100644 --- a/apps/schedules/package.json +++ b/apps/schedules/package.json @@ -20,7 +20,7 @@ "pino-pretty": "13.2.0", "react": "19.3.0", "react-dom": "19.3.0", - "zod": "^4.6.5" + "zod": "^4.6.7" }, "devDependencies": { "rimraf": "6.1.3", diff --git a/bun.lock b/bun.lock index 808cad9177f..85b1338f638 100644 --- a/bun.lock +++ b/bun.lock @@ -29,7 +29,7 @@ "react": "19.3.0", "react-dom": "19.3.0", "redis": "4.7.1", - "zod": "^4.6.5", + "zod": "^4.6.7", }, "devDependencies": { "@types/node": "^24.19.1", @@ -138,7 +138,7 @@ "recharts": "^3.10.1", "resend": "^6.32.1", "semver": "7.8.5", - "shadcn": "^4.21.4", + "shadcn": "^4.22.1", "shell-quote": "^1.12.0", "slugify": "^1.6.9", "sonner": "^2.0.8", @@ -155,7 +155,7 @@ "ws": "8.22.0", "xterm-addon-fit": "^0.8.0", "yaml": "2.9.1", - "zod": "^4.6.5", + "zod": "^4.6.7", "zod-form-data": "^3.0.3", }, "devDependencies": { @@ -202,7 +202,7 @@ "pino-pretty": "13.2.0", "react": "19.3.0", "react-dom": "19.3.0", - "zod": "^4.6.5", + "zod": "^4.6.7", }, "devDependencies": { "@types/node": "^24.19.1", @@ -278,7 +278,7 @@ "undici": "8.11.2", "ws": "8.22.0", "yaml": "2.9.1", - "zod": "^4.6.5", + "zod": "^4.6.7", }, "devDependencies": { "@types/bcrypt": "5.0.2", @@ -322,6 +322,9 @@ "h3": "1.15.11", "hono": "4.13.13", "http-cache-semantics": ">=4.3.0 <5.0.0", + "inngest": { + "zod": "^4.6.7", + }, "ip-address": ">=10.7.4 <11.0.0", "js-yaml": "4.3.2", "lodash": "4.18.1", @@ -1336,7 +1339,7 @@ "@selderee/plugin-htmlparser2": ["@selderee/plugin-htmlparser2@0.11.0", "", { "dependencies": { "domhandler": "^5.0.3", "selderee": "^0.11.0" } }, "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ=="], - "@shadcn/registry": ["@shadcn/registry@0.1.3", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/plugin-transform-typescript": "^7.28.0", "@babel/preset-typescript": "^7.27.1", "@dotenvx/dotenvx": "^1.48.4", "cn": "^0.2.4", "code-block-writer": "^13.0.3", "deepmerge": "^4.3.1", "execa": "^9.6.0", "fast-glob": "^3.3.3", "fs-extra": "^11.3.1", "fuzzysort": "^3.1.0", "kleur": "^4.1.5", "ora": "^8.2.0", "postcss": "^8.5.23", "prompts": "^2.4.2", "recast": "^0.23.11", "socks": "^2.8.8", "stringify-object": "^5.0.0", "tsconfig-paths": "^4.2.0", "type-fest": "^4.41.0", "undici": "^7.29.0", "zod": "^3.24.1" } }, "sha512-82/OmKAVM9pChDHFVAsDP9PcimPGSKZGdbcdwdGGGcSI69ImpN4ZnqsfZ4hkOFEMal92t3y9djYJHMjO4PcVZA=="], + "@shadcn/registry": ["@shadcn/registry@0.2.0", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/plugin-transform-typescript": "^7.28.0", "@babel/preset-typescript": "^7.27.1", "@dotenvx/dotenvx": "^1.48.4", "cn": "^0.2.4", "code-block-writer": "^13.0.3", "deepmerge": "^4.3.1", "execa": "^9.6.0", "fast-glob": "^3.3.3", "fs-extra": "^11.3.1", "fuzzysort": "^3.1.0", "kleur": "^4.1.5", "ora": "^8.2.0", "postcss": "^8.5.23", "prompts": "^2.4.2", "recast": "^0.23.11", "socks": "^2.8.8", "stringify-object": "^5.0.0", "tsconfig-paths": "^4.2.0", "type-fest": "^4.41.0", "undici": "^7.29.1", "zod": "^4.2.0" } }, "sha512-m3TeqU/+av2kgOLfESHkWzsmhuQuY4NXZd5Y1Rd4lzy4IX3JJ5+k2mYfkq6OT8oMuk2W4GQPAkO7+CC7KlpSbw=="], "@simplewebauthn/browser": ["@simplewebauthn/browser@13.3.0", "", {}, "sha512-BE/UWv6FOToAdVk0EokzkqQQDOWtNydYlY6+OrmiZ5SCNmb41VehttboTetUM3T/fr6EAFYVXjz4My2wg230rQ=="], @@ -3042,7 +3045,7 @@ "sha.js": ["sha.js@2.4.12", "", { "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1", "to-buffer": "^1.2.0" }, "bin": { "sha.js": "bin.js" } }, "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w=="], - "shadcn": ["shadcn@4.21.4", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/plugin-transform-typescript": "^7.28.0", "@babel/preset-typescript": "^7.27.1", "@dotenvx/dotenvx": "^1.48.4", "@modelcontextprotocol/sdk": "^1.26.0", "@shadcn/registry": "0.1.3", "@types/validate-npm-package-name": "^4.0.2", "browserslist": "^4.26.2", "cn": "^0.2.4", "commander": "^14.0.0", "dedent": "^1.6.0", "deepmerge": "^4.3.1", "diff": "^8.0.2", "execa": "^9.6.0", "fast-glob": "^3.3.3", "fs-extra": "^11.3.1", "fuzzysort": "^3.1.0", "kleur": "^4.1.5", "open": "^11.0.0", "ora": "^8.2.0", "postcss": "^8.5.23", "postcss-selector-parser": "^7.1.3", "prompts": "^2.4.2", "recast": "^0.23.11", "socks": "^2.8.8", "stringify-object": "^5.0.0", "ts-morph": "^26.0.0", "tsconfig-paths": "^4.2.0", "undici": "^7.29.0", "validate-npm-package-name": "^7.0.1", "zod": "^3.24.1", "zod-to-json-schema": "^3.24.6" }, "bin": { "shadcn": "dist/index.js" } }, "sha512-YYfn/hsHbRH2mGwnKBx9tk+DjTQH+RUMS5iCxjKzwzuJ5uoHPqLOFUCJSeX0sXfrcBSfgQaXiOLGKNLjlIQxxw=="], + "shadcn": ["shadcn@4.22.1", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/plugin-transform-typescript": "^7.28.0", "@babel/preset-typescript": "^7.27.1", "@dotenvx/dotenvx": "^1.48.4", "@modelcontextprotocol/sdk": "^1.32.0", "@shadcn/registry": "0.2.0", "@types/validate-npm-package-name": "^4.0.2", "browserslist": "^4.29.3", "cn": "^0.2.4", "commander": "^14.0.0", "dedent": "^1.6.0", "deepmerge": "^4.3.1", "diff": "^8.0.2", "execa": "^9.6.0", "fast-glob": "^3.3.3", "fs-extra": "^11.3.1", "fuzzysort": "^3.1.0", "kleur": "^4.1.5", "open": "^11.0.4", "ora": "^8.2.0", "postcss": "^8.5.23", "postcss-selector-parser": "^7.1.6", "prompts": "^2.4.2", "recast": "^0.23.11", "socks": "^2.8.8", "stringify-object": "^5.0.0", "ts-morph": "^26.0.0", "tsconfig-paths": "^4.2.0", "undici": "^7.29.1", "validate-npm-package-name": "^7.0.1", "zod": "^4.2.0" }, "bin": { "shadcn": "dist/index.js" } }, "sha512-LbB4Lro+b0qSVki/tgL5edtKylEnXe1ppxMJC12d7NHPgaT+eSgJGMQULwP72V7X9tbiUq7xfx3VDAfB7jdGoA=="], "sharp": ["sharp@0.35.5", "", { "dependencies": { "@img/colour": "^1.1.0", "detect-libc": "^2.1.2", "semver": "^7.8.5" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.35.5", "@img/sharp-darwin-x64": "0.35.5", "@img/sharp-freebsd-wasm32": "0.35.5", "@img/sharp-libvips-darwin-arm64": "1.3.4", "@img/sharp-libvips-darwin-x64": "1.3.4", "@img/sharp-libvips-linux-arm": "1.3.4", "@img/sharp-libvips-linux-arm64": "1.3.4", "@img/sharp-libvips-linux-ppc64": "1.3.4", "@img/sharp-libvips-linux-riscv64": "1.3.4", "@img/sharp-libvips-linux-s390x": "1.3.4", "@img/sharp-libvips-linux-x64": "1.3.4", "@img/sharp-libvips-linuxmusl-arm64": "1.3.4", "@img/sharp-libvips-linuxmusl-x64": "1.3.4", "@img/sharp-linux-arm": "0.35.5", "@img/sharp-linux-arm64": "0.35.5", "@img/sharp-linux-ppc64": "0.35.5", "@img/sharp-linux-riscv64": "0.35.5", "@img/sharp-linux-s390x": "0.35.5", "@img/sharp-linux-x64": "0.35.5", "@img/sharp-linuxmusl-arm64": "0.35.5", "@img/sharp-linuxmusl-x64": "0.35.5", "@img/sharp-webcontainers-wasm32": "0.35.5", "@img/sharp-win32-arm64": "0.35.5", "@img/sharp-win32-ia32": "0.35.5", "@img/sharp-win32-x64": "0.35.5" }, "peerDependencies": { "@types/node": "*" }, "optionalPeers": ["@types/node"] }, "sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g=="], @@ -3378,7 +3381,7 @@ "zenscroll": ["zenscroll@4.0.2", "", {}, "sha512-jEA1znR7b4C/NnaycInCU6h/d15ZzCd1jmsruqOKnZP6WXQSMH3W2GL+OXbkruslU4h+Tzuos0HdswzRUk/Vgg=="], - "zod": ["zod@4.6.5", "", {}, "sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q=="], + "zod": ["zod@4.6.7", "", {}, "sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg=="], "zod-form-data": ["zod-form-data@3.0.3", "", { "dependencies": { "@rvf/set-get": "^7.0.3" }, "peerDependencies": { "zod": ">= 3.25.0" } }, "sha512-1qXJ6hayyUr3TqxfXqmm5qwCa8f/mnG/o8Itcny03iFyrwX/dZkCwfCcYoJDyQP8RxEkycw0c/ldCJXBeaCstg=="], @@ -3550,8 +3553,6 @@ "@shadcn/registry/undici": ["undici@7.30.0", "", {}, "sha512-dkrQXeHSaoamnItlYbmzG0wFYrM0ZwDxCIg0A7aKjTyyhh9svRzCNFEzV+Vm05/yehjCzjDZ31KXfGEjYSztDQ=="], - "@shadcn/registry/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "@swagger-api/apidom-parser-adapter-yaml-1-2/tree-sitter": ["tree-sitter@0.22.4", "", { "dependencies": { "node-addon-api": "^8.3.0", "node-gyp-build": "^4.8.4" } }, "sha512-usbHZP9/oxNsUY65MQUsduGRqDHQOou1cagUSwjhoSYAmSahjQDAVsh9s+SlZkn8X8+O1FULRGwHu7AFP3kjzg=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.3", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.3", "tslib": "^2.4.0" }, "bundled": true }, "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg=="], @@ -3658,8 +3659,6 @@ "import-in-the-middle/es-module-lexer": ["es-module-lexer@3.0.2", "", {}, "sha512-BuIB67FngDSyQ/dpQNOZybwdEBDUGJQvOqwWr4ha/ufYiqzuEwPkKO2zLhRAgay28tStRIHUeWmszZAJo3GCOg=="], - "inngest/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "listr2/wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], "log-symbols/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="], @@ -3712,8 +3711,6 @@ "shadcn/undici": ["undici@7.30.0", "", {}, "sha512-dkrQXeHSaoamnItlYbmzG0wFYrM0ZwDxCIg0A7aKjTyyhh9svRzCNFEzV+Vm05/yehjCzjDZ31KXfGEjYSztDQ=="], - "shadcn/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@4.0.0", "", {}, "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ=="], "string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], diff --git a/package.json b/package.json index a22d4be9930..dad04ae076b 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "@modelcontextprotocol/sdk": ">=1.32.1 <2.0.0", "ip-address": ">=10.7.4 <11.0.0", "@tailwindcss/typography>postcss-selector-parser": "7.1.6", - "remarkable>argparse": "2.0.1" + "remarkable>argparse": "2.0.1", + "inngest>zod": "^4.6.7" } } diff --git a/packages/server/package.json b/packages/server/package.json index 8c99959d8f6..1cc80461722 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -99,7 +99,7 @@ "undici": "8.11.2", "ws": "8.22.0", "yaml": "2.9.1", - "zod": "^4.6.5" + "zod": "^4.6.7" }, "devDependencies": { "@types/bcrypt": "5.0.2",