@netlify/config
Version:
Netlify config module
67 lines (54 loc) • 2.29 kB
JavaScript
import { promises as fs } from 'fs'
import { dirname, relative, sep } from 'path'
import { pathExists } from 'path-exists'
// Retrieve `base` override.
// This uses any directory below `repositoryRoot` and above (or equal to)
// `cwd` that has a `.netlify` or `netlify.toml`. This allows Netlify CLI users
// to `cd` into monorepo directories to change their base and build directories.
// Do all checks in parallel for speed
export const getBaseOverride = async function ({ repositoryRoot, cwd }) {
// Performance optimization
if (repositoryRoot === cwd) {
return {}
}
const [repositoryRootA, cwdA] = await Promise.all([fs.realpath(repositoryRoot), fs.realpath(cwd)])
const basePaths = getBasePaths(repositoryRootA, cwdA)
const basePath = await locatePath(basePaths)
if (basePath === undefined) {
return {}
}
// `base` starting with a `/` are relative to `repositoryRoot`, so we cannot
// return an absolute path
const base = relative(repositoryRoot, dirname(basePath))
// When `base` is explicitely overridden, `baseRelDir: true` makes more sense
// since we want `publish`, `functions` and `edge_handlers` to be relative to it.
return { base, baseRelDir: true }
}
// Returns list of files to check for the existence of a `base`
const getBasePaths = function (repositoryRoot, cwd) {
const subdirs = getSubdirs(repositoryRoot, cwd)
const basePaths = subdirs.flatMap((subdir) => BASE_FILENAMES.map((filename) => `${subdir}/${filename}`))
return basePaths
}
// Retrieves list of directories between `repositoryRoot` and `cwd`, including
// `cwd` but excluding `repositoryRoot`
const getSubdirs = function (repositoryRoot, dir, subdirs = []) {
if (!dir.startsWith(`${repositoryRoot}${sep}`)) {
return subdirs
}
return getSubdirs(repositoryRoot, dirname(dir), [...subdirs, dir])
}
const BASE_FILENAMES = ['.netlify', 'netlify.toml', 'package.json']
// Returns the first path that exists.
// Like `locate-path` library but works with mixed files/directories
const locatePath = async function (paths) {
const results = await Promise.all(paths.map(returnIfExists))
const path = results.find(Boolean)
return path
}
const returnIfExists = async function (path) {
if (!(await pathExists(path))) {
return
}
return path
}