From b90cd1b752490970a5aa33c8a31214710bdfa20e Mon Sep 17 00:00:00 2001 From: Andrew Barba Date: Tue, 28 Jul 2026 12:50:00 -0400 Subject: [PATCH] fix(vercel): preserve relative function symlinks Signed-off-by: Andrew Barba --- src/presets/vercel/utils.ts | 1 + test/presets/vercel.test.ts | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/presets/vercel/utils.ts b/src/presets/vercel/utils.ts index 4f6d3158e3..aa9b49f09e 100644 --- a/src/presets/vercel/utils.ts +++ b/src/presets/vercel/utils.ts @@ -642,6 +642,7 @@ async function createFunctionDirWithCustomConfig( await fsp.cp(serverDir, funcDir, { recursive: true, mode: constants.COPYFILE_FICLONE, + verbatimSymlinks: true, filter: (src) => basename(src) !== ".vc-config.json", }); const mergedConfig = defu(overrides, baseFunctionConfig); diff --git a/test/presets/vercel.test.ts b/test/presets/vercel.test.ts index ae4d31e71a..b48261c0eb 100644 --- a/test/presets/vercel.test.ts +++ b/test/presets/vercel.test.ts @@ -593,6 +593,17 @@ describe("nitro:preset:vercel:web", async () => { expect(indexStat.isFile()).toBe(true); }); + it("should preserve dependency symlink targets inside functionRules directories", async () => { + const dependencyPath = "node_modules/@fixture/nitro-lib"; + const serverTarget = await fsp.readlink( + resolve(ctx.outDir, "functions/__server.func", dependencyPath) + ); + const functionTarget = await fsp.readlink( + resolve(ctx.outDir, "functions/api/hello.func", dependencyPath) + ); + expect(functionTarget).toBe(serverTarget); + }); + it("should keep base __server.func without functionRules overrides", async () => { const config = await fsp .readFile(resolve(ctx.outDir, "functions/__server.func/.vc-config.json"), "utf8")