@puls-atlas/cli
Version:
The Puls Atlas CLI tool for managing Atlas projects
105 lines • 3.66 kB
JavaScript
import fs from 'fs';
import path from 'path';
import inquirer from 'inquirer';
import { omit } from 'es-toolkit/object';
import { resolveFunctionsTarget } from '../../utils/firebase.js';
import { logger } from '../../utils/logger.js';
import { cleanInstallNodeDependencies, installNodeDependencies } from '../../utils/npm.js';
import { confirmDependencyInstall, LOCKFILE_INSTALL_SOURCE, MANIFEST_INSTALL_SOURCE, outputInstallSummary, selectInstallSource } from './utils.js';
const resolveFunctionsInstallTarget = async ({
allYes = false,
codebaseOrPath,
rootDir
}, dependencies = {}) => {
const {
existsSyncImpl = fs.existsSync,
loggerImpl = logger,
promptImpl = inquirer.prompt,
readFileSyncImpl = fs.readFileSync
} = dependencies;
return resolveFunctionsTarget({
allYes,
codebaseOrPath,
promptMessage: 'Select the Cloud Functions codebase to install:',
rootDir
}, {
existsSyncImpl,
loggerImpl,
promptImpl,
readFileSyncImpl
});
};
export default async (commandOptions = {}, dependencies = {}) => {
const {
cleanInstallNodeDependenciesImpl = cleanInstallNodeDependencies,
cwd = process.cwd(),
existsSyncImpl = fs.existsSync,
installNodeDependenciesImpl = installNodeDependencies,
loggerImpl = logger,
promptImpl = inquirer.prompt,
readFileSyncImpl = fs.readFileSync
} = dependencies;
const rootDir = cwd;
const resolvedTarget = await resolveFunctionsInstallTarget({
allYes: commandOptions.allYes === true,
codebaseOrPath: commandOptions.codebase,
rootDir
}, {
existsSyncImpl,
loggerImpl,
promptImpl,
readFileSyncImpl
});
if (!resolvedTarget) {
return null;
}
if (!existsSyncImpl(resolvedTarget.targetDir)) {
loggerImpl.error(`The Cloud Functions directory ${resolvedTarget.targetLabel} does not exist. ` + 'Make sure your firebase.json source or --codebase option points to an existing directory.', {
exit: true,
exitCode: 1
});
return null;
}
const shouldInstall = await confirmDependencyInstall({
allYes: commandOptions.allYes === true,
dependencyLabel: 'NPM',
promptImpl,
subjectLabel: 'Cloud Functions',
targetLabel: resolvedTarget.targetLabel
});
if (!shouldInstall) {
loggerImpl.info(`Skipped NPM dependency installation for ${resolvedTarget.targetLabel}.`);
return null;
}
const hasLockfile = existsSyncImpl(path.join(resolvedTarget.targetDir, 'package-lock.json'));
const npmOptions = omit(commandOptions, ['allYes', 'codebase']);
let installSource = MANIFEST_INSTALL_SOURCE;
if (hasLockfile) {
loggerImpl.info('package-lock.json detected.');
installSource = await selectInstallSource({
allYes: commandOptions.allYes === true,
dependencyLabel: 'NPM',
lockfileChoiceLabel: 'Use package-lock.json (recommended)',
manifestChoiceLabel: 'Install from package.json',
promptImpl,
targetLabel: resolvedTarget.targetLabel
});
} else {
loggerImpl.warning('No package-lock.json detected. Installing from package.json.');
}
outputInstallSummary({
dependencyLabel: 'NPM',
extraRows: resolvedTarget.codebase ? [{
label: 'Codebase',
value: resolvedTarget.codebase,
tone: 'warning'
}] : [],
loggerImpl,
sourceLabel: installSource === LOCKFILE_INSTALL_SOURCE ? 'package-lock.json' : 'package.json',
targetLabel: resolvedTarget.targetLabel
});
if (installSource === LOCKFILE_INSTALL_SOURCE) {
return cleanInstallNodeDependenciesImpl(resolvedTarget.targetDir, npmOptions);
}
return installNodeDependenciesImpl(resolvedTarget.targetDir, npmOptions);
};