boostr
Version:
Build and deploy your Layr apps
132 lines • 4.78 kB
JavaScript
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