import glob from 'globby' import { outdent } from 'outdent' import { join, relative, resolve } from 'pathe' import { HANDLER_FUNCTION_NAME } from '../constants' import { getDependenciesOfFile } from '../helpers/files' // Generate a file full of require.resolve() calls for all the pages in the // build. This is used by the nft bundler to find all the pages. export const getUniqueDependencies = async (sourceFiles: Array) => { const dependencies = await Promise.all(sourceFiles.map((sourceFile) => getDependenciesOfFile(sourceFile))) return [...new Set([...sourceFiles, ...dependencies.flat()])].sort() } export const getAllPageDependencies = async (publish: string) => { const root = resolve(publish, 'server') const pageFiles = await glob('{pages,app}/**/*.js', { cwd: root, dot: true, }) // We don't use `absolute: true` because that returns Windows paths on Windows. // Instead we use pathe to normalize the paths. return getUniqueDependencies(pageFiles.map((pageFile) => join(root, pageFile))) } export const getResolverForDependencies = ({ dependencies, functionDir, }: { dependencies: string[] functionDir: string }) => { const pageFiles = dependencies.map((file) => `require.resolve('${relative(functionDir, file)}')`) return outdent/* javascript */ ` // This file is purely to allow nft to know about these pages. exports.resolvePages = () => { try { ${pageFiles.join('\n ')} } catch {} } ` } export const getResolverForPages = async (publish: string) => { const functionDir = resolve('.netlify', 'functions', HANDLER_FUNCTION_NAME) const dependencies = await getAllPageDependencies(publish) return getResolverForDependencies({ dependencies, functionDir }) } export const getResolverForSourceFiles = async ({ functionsDir, sourceFiles, }: { functionsDir: string sourceFiles: Array }) => { // We don't need the actual name, just the relative path. const functionDir = resolve(functionsDir, 'functionName') const dependencies = await getUniqueDependencies(sourceFiles) return getResolverForDependencies({ dependencies, functionDir }) }