UNPKG

boostr

Version:
132 lines 4.78 kB
import { existsSync, readFileSync } from 'fs'; import fsExtra from 'fs-extra'; import { join, sep } from 'path'; import { homedir } from 'os'; import { execFileSync } from 'child_process'; import { createRequire } from 'module'; import memoize from 'lodash/memoize.js'; import { logMessage, throwError } from './utilities.js'; export function loadNPMPackage(directory) { const packageFile = join(directory, 'package.json'); if (!existsSync(packageFile)) { throwError(`Couldn't find a 'package.json' file in the following directory: ${directory}`); } const json = readFileSync(packageFile, 'utf-8'); let pkg; try { pkg = JSON.parse(json); } catch { throwError(`An error occurred while parsing the following file: ${packageFile}`); } return pkg; } export async function installNPMPackages(directory, packages) { const generatedPackageFile = join(directory, 'package.json'); fsExtra.outputJSONSync(generatedPackageFile, { private: true, dependencies: packages }); try { await runNPM(directory, ['install'], { silent: true }); } finally { fsExtra.removeSync(generatedPackageFile); } } export function findInstalledNPMPackage(directory, packageName) { const packageDirectory = join(directory, 'node_modules', ...packageName.split('/')); if (!existsSync(packageDirectory)) { return undefined; } return loadNPMPackage(packageDirectory); } export async function runNPM(directory, args = [], { environment, silent = false } = {}) { try { execFileSync('npm', args, { cwd: directory, env: environment, stdio: silent ? 'pipe' : 'inherit' }); } catch (error) { if (silent) { console.error(error.stderr.toString()); } else { console.log(); } throwError(`An error occurred while executing npm`); } } export async function runNPMInstallIfThereIsAPackage(directory, { serviceName } = {}) { const packageFile = join(directory, 'package.json'); if (!existsSync(packageFile)) { return; } logMessage('Installing npm dependencies...', { serviceName }); await runNPM(directory, ['install']); } export async function runNPMUpdateIfThereIsAPackage(directory, { serviceName, save = false } = {}) { const packageFile = join(directory, 'package.json'); if (!existsSync(packageFile)) { return; } logMessage('Updating npm dependencies...', { serviceName }); const args = ['update']; if (save) { args.push('--save'); } await runNPM(directory, args); } export async function runNPMTestIfThereIsAPackage(directory, { serviceName, beforeTest, environment } = {}) { const packageFile = join(directory, 'package.json'); if (!existsSync(packageFile)) { return; } const pkg = loadNPMPackage(directory); if (pkg.scripts?.test === undefined) { logMessage('No test specified', { serviceName }); return; } if (beforeTest !== undefined) { await beforeTest(); } logMessage('Running tests...', { serviceName }); await runNPM(directory, ['test'], { environment }); } // A way to lazily install npm packages while turning around an issue where packages // containing binary (e.g. esbuild) cannot be installed with `npm --global` export async function installGlobalNPMPackage(packageName, packageVersion, { serviceName } = {}) { const packageDirectory = join(homedir(), '.cache', 'boostr', 'dependencies', packageName, packageVersion); if (!existsSync(packageDirectory)) { logMessage(`Installing '${packageName}@${packageVersion}'...`, { serviceName }); try { fsExtra.outputJsonSync(join(packageDirectory, 'package.json'), { private: true, dependencies: { [packageName]: packageVersion } }); await runNPM(packageDirectory, ['install']); } catch (error) { fsExtra.removeSync(packageDirectory); throw error; } } return packageDirectory; } const memoizedCreateRequire = memoize(createRequire); export async function requireGlobalNPMPackage(packageName, packageVersion, { serviceName } = {}) { const packageDirectory = await installGlobalNPMPackage(packageName, packageVersion, { serviceName }); const require = memoizedCreateRequire(packageDirectory + sep); return require(packageName); } export function resolveInternalNPMPackage(packageName) { const require = memoizedCreateRequire(import.meta.url.toString()); return require.resolve(packageName); } //# sourceMappingURL=npm.js.map