summaryrefslogtreecommitdiff
path: root/packages/integrations/vercel/src/lib/nft.ts
blob: 46604db902ac0ed7a8595963b4883c04243efca9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { nodeFileTrace } from '@vercel/nft';
import { relative as relativePath } from 'node:path';
import { fileURLToPath } from 'node:url';

import { copyFilesToFunction } from './fs.js';

export async function copyDependenciesToFunction({
	entry,
	outDir,
	includeFiles,
	excludeFiles,
}: {
	entry: URL;
	outDir: URL;
	includeFiles: URL[];
	excludeFiles: 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(base),
	});

	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.`
				);
			}
		}
		// parse errors are likely not js and can safely be ignored,
		// such as this html file in "main" meant for nw instead of node:
		// https://github.com/vercel/nft/issues/311
		else if (error.message.startsWith('Failed to parse')) {
			continue;
		} else {
			throw error;
		}
	}

	const commonAncestor = await copyFilesToFunction(
		[...result.fileList].map((file) => new URL(file, base)).concat(includeFiles),
		outDir,
		excludeFiles
	);

	return {
		// serverEntry location inside the outDir
		handler: relativePath(commonAncestor, entryPath),
	};
}