@netlify/config
Version:
Netlify config module
54 lines (53 loc) • 2.33 kB
JavaScript
import { existsSync, promises as fs } from 'fs';
import { dirname, relative, sep } from 'path';
// 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 explicitly overridden, `baseRelDir: true` makes more sense
// since we want `publish`, `functions` and `edge_functions` 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 (!existsSync(path)) {
return;
}
return path;
};