UNPKG

@jsdevtools/npm-publish

Version:
91 lines 3.15 kB
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