@jsdevtools/npm-publish
Version:
Fast, easy publishing to NPM
91 lines • 3.15 kB
JavaScript
import childProcess from "node:child_process";
import os from "node:os";
import * as errors from "../errors.js";
export const VIEW = "view";
export const PUBLISH = "publish";
export const E404 = "E404";
export const E409 = "E409";
export const EPUBLISHCONFLICT = "EPUBLISHCONFLICT";
const IS_WINDOWS = os.platform() === "win32";
const NPM = IS_WINDOWS ? "npm.cmd" : "npm";
const JSON_MATCH_RE = /(\{[\s\S]*\})/mu;
const baseArguments = (options) => options.ignoreScripts ? ["--ignore-scripts", "--json"] : ["--json"];
/**
* Call the NPM CLI in JSON mode.
*
* @param command The command of the NPM CLI to call
* @param cliArguments Any arguments to send to the command
* @param options Customize environment variables or add an error handler.
* @returns The parsed JSON, or stdout if unparsable.
*/
export async function callNpmCli(command, cliArguments, options) {
const { stdout, stderr, exitCode } = await execNpm([command, ...baseArguments(options), ...cliArguments], options.environment, options.logger);
let successData;
let errorCode;
let error;
if (exitCode === 0) {
successData = parseJson(stdout);
}
else {
const errorPayload = parseJson(stdout, stderr);
if (typeof errorPayload?.error?.code === "string") {
errorCode = errorPayload.error.code.toUpperCase();
}
error = new errors.NpmCallError(command, exitCode, stderr);
}
return { successData, errorCode, error };
}
/**
* Execute the npm CLI.
*
* @param commandArguments Npm subcommand and arguments.
* @param environment Environment variables.
* @param logger Optional logger.
* @returns Stdout, stderr, and the exit code.
*/
async function execNpm(commandArguments, environment, logger) {
logger?.debug?.(`Running command: ${NPM} ${commandArguments.join(" ")}`);
return new Promise((resolve) => {
let stdout = "";
let stderr = "";
const npm = childProcess.spawn(NPM, commandArguments, {
env: { ...process.env, ...environment },
shell: IS_WINDOWS,
});
npm.stdout.on("data", (data) => (stdout += data));
npm.stderr.on("data", (data) => (stderr += data));
npm.on("close", (code) => {
logger?.debug?.(`Received stdout: ${stdout}`);
logger?.debug?.(`Received stderr: ${stderr}`);
resolve({
stdout: stdout.trim(),
stderr: stderr.trim(),
exitCode: code ?? 0,
});
});
});
}
/**
* Parse CLI outputs for JSON data.
*
* Certain versions of the npm CLI may intersperse JSON with human-readable
* output, which this function accounts for.
*
* @param values CLI outputs to check
* @returns Parsed JSON, if able to parse.
*/
function parseJson(...values) {
for (const value of values) {
const jsonValue = JSON_MATCH_RE.exec(value)?.[1];
if (jsonValue) {
try {
return JSON.parse(jsonValue);
}
catch {
return undefined;
}
}
}
return undefined;
}
//# sourceMappingURL=call-npm-cli.js.map