diff options
author | 2022-10-10 12:37:03 -0300 | |
---|---|---|
committer | 2022-10-10 11:37:03 -0400 | |
commit | c1f991408b817217dbd4035dcc4ac0a2fecd08b8 (patch) | |
tree | 0d5520a0dd438edfb22feafc5f9cc1fb41106072 /packages/integrations/vercel/src/lib/nft.ts | |
parent | 2d9d42216722334db03adb14e59773db8389b7f9 (diff) | |
download | astro-c1f991408b817217dbd4035dcc4ac0a2fecd08b8.tar.gz astro-c1f991408b817217dbd4035dcc4ac0a2fecd08b8.tar.zst astro-c1f991408b817217dbd4035dcc4ac0a2fecd08b8.zip |
fix(vercel): now works with monorepos (#5033)
* Upgraded nft
* Handle monorepo better
* Changeset
* Fixed common ancestor
* Fixed outdir
Diffstat (limited to 'packages/integrations/vercel/src/lib/nft.ts')
-rw-r--r-- | packages/integrations/vercel/src/lib/nft.ts | 84 |
1 files changed, 68 insertions, 16 deletions
diff --git a/packages/integrations/vercel/src/lib/nft.ts b/packages/integrations/vercel/src/lib/nft.ts index b18cb73ef..ba3677583 100644 --- a/packages/integrations/vercel/src/lib/nft.ts +++ b/packages/integrations/vercel/src/lib/nft.ts @@ -1,38 +1,90 @@ import { nodeFileTrace } from '@vercel/nft'; import * as fs from 'node:fs/promises'; +import nodePath from 'node:path'; import { fileURLToPath } from 'node:url'; export async function copyDependenciesToFunction( - root: URL, - functionFolder: URL, - serverEntry: string -) { - const entryPath = fileURLToPath(new URL(`./${serverEntry}`, functionFolder)); + entry: URL, + outDir: URL +): Promise<{ handler: string }> { + const entryPath = fileURLToPath(entry); + + // Get root of folder of the system (like C:\ on Windows or / on Linux) + let base = entry; + while (fileURLToPath(base) !== fileURLToPath(new URL('../', base))) { + base = new URL('../', base); + } const result = await nodeFileTrace([entryPath], { - base: fileURLToPath(root), + base: fileURLToPath(base), }); - for (const file of result.fileList) { - if (file.startsWith('.vercel/')) continue; - const origin = new URL(file, root); - const dest = new URL(file, functionFolder); + if (result.fileList.size === 0) throw new Error('[@astrojs/vercel] No files found'); + + for (const error of result.warnings) { + if (error.message.startsWith('Failed to resolve dependency')) { + const [, module, file] = /Cannot find module '(.+?)' loaded from (.+)/.exec(error.message)!; + + // The import(astroRemark) sometimes fails to resolve, but it's not a problem + if (module === '@astrojs/') continue; + + if (entryPath === file) { + console.warn( + `[@astrojs/vercel] The module "${module}" couldn't be resolved. This may not be a problem, but it's worth checking.` + ); + } else { + console.warn( + `[@astrojs/vercel] The module "${module}" inside the file "${file}" couldn't be resolved. This may not be a problem, but it's worth checking.` + ); + } + } else { + throw error; + } + } - const meta = await fs.stat(origin); - const isSymlink = (await fs.lstat(origin)).isSymbolicLink(); + const fileList = [...result.fileList]; + + let commonAncestor = nodePath.dirname(fileList[0]); + for (const file of fileList.slice(1)) { + while (!file.startsWith(commonAncestor)) { + commonAncestor = nodePath.dirname(commonAncestor); + } + } + + for (const file of fileList) { + const origin = new URL(file, base); + const dest = new URL(nodePath.relative(commonAncestor, file), outDir); + + const realpath = await fs.realpath(origin); + const isSymlink = realpath !== fileURLToPath(origin); + const isDir = (await fs.stat(origin)).isDirectory(); // Create directories recursively - if (meta.isDirectory() && !isSymlink) { + if (isDir && !isSymlink) { await fs.mkdir(new URL('..', dest), { recursive: true }); } else { await fs.mkdir(new URL('.', dest), { recursive: true }); } if (isSymlink) { - const link = await fs.readlink(origin); - await fs.symlink(link, dest, meta.isDirectory() ? 'dir' : 'file'); - } else { + const realdest = fileURLToPath( + new URL( + nodePath.relative(nodePath.join(fileURLToPath(base), commonAncestor), realpath), + outDir + ) + ); + await fs.symlink( + nodePath.relative(fileURLToPath(new URL('.', dest)), realdest), + dest, + isDir ? 'dir' : 'file' + ); + } else if (!isDir) { await fs.copyFile(origin, dest); } } + + return { + // serverEntry location inside the outDir + handler: nodePath.relative(nodePath.join(fileURLToPath(base), commonAncestor), entryPath), + }; } |