123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071 |
- import { Buffer } from 'buffer';
- import path from 'path';
- import childProcess from 'child_process';
- import process$1 from 'process';
- import { m as mergeStream, g as getStream, c as crossSpawn } from './vendor-index.2ae8040a.mjs';
- import url from 'url';
- import require$$0, { constants } from 'os';
- import { s as signalExit } from './vendor-index.29636037.mjs';
- function stripFinalNewline(input) {
- const LF = typeof input === 'string' ? '\n' : '\n'.charCodeAt();
- const CR = typeof input === 'string' ? '\r' : '\r'.charCodeAt();
- if (input[input.length - 1] === LF) {
- input = input.slice(0, -1);
- }
- if (input[input.length - 1] === CR) {
- input = input.slice(0, -1);
- }
- return input;
- }
- function pathKey(options = {}) {
- const {
- env = process.env,
- platform = process.platform
- } = options;
- if (platform !== 'win32') {
- return 'PATH';
- }
- return Object.keys(env).reverse().find(key => key.toUpperCase() === 'PATH') || 'Path';
- }
- function npmRunPath(options = {}) {
- const {
- cwd = process$1.cwd(),
- path: path_ = process$1.env[pathKey()],
- execPath = process$1.execPath,
- } = options;
- let previous;
- const cwdString = cwd instanceof URL ? url.fileURLToPath(cwd) : cwd;
- let cwdPath = path.resolve(cwdString);
- const result = [];
- while (previous !== cwdPath) {
- result.push(path.join(cwdPath, 'node_modules/.bin'));
- previous = cwdPath;
- cwdPath = path.resolve(cwdPath, '..');
- }
- // Ensure the running `node` binary is used.
- result.push(path.resolve(cwdString, execPath, '..'));
- return [...result, path_].join(path.delimiter);
- }
- function npmRunPathEnv({env = process$1.env, ...options} = {}) {
- env = {...env};
- const path = pathKey({env});
- options.path = env[path];
- env[path] = npmRunPath(options);
- return env;
- }
- const copyProperty = (to, from, property, ignoreNonConfigurable) => {
- // `Function#length` should reflect the parameters of `to` not `from` since we keep its body.
- // `Function#prototype` is non-writable and non-configurable so can never be modified.
- if (property === 'length' || property === 'prototype') {
- return;
- }
- // `Function#arguments` and `Function#caller` should not be copied. They were reported to be present in `Reflect.ownKeys` for some devices in React Native (#41), so we explicitly ignore them here.
- if (property === 'arguments' || property === 'caller') {
- return;
- }
- const toDescriptor = Object.getOwnPropertyDescriptor(to, property);
- const fromDescriptor = Object.getOwnPropertyDescriptor(from, property);
- if (!canCopyProperty(toDescriptor, fromDescriptor) && ignoreNonConfigurable) {
- return;
- }
- Object.defineProperty(to, property, fromDescriptor);
- };
- // `Object.defineProperty()` throws if the property exists, is not configurable and either:
- // - one its descriptors is changed
- // - it is non-writable and its value is changed
- const canCopyProperty = function (toDescriptor, fromDescriptor) {
- return toDescriptor === undefined || toDescriptor.configurable || (
- toDescriptor.writable === fromDescriptor.writable &&
- toDescriptor.enumerable === fromDescriptor.enumerable &&
- toDescriptor.configurable === fromDescriptor.configurable &&
- (toDescriptor.writable || toDescriptor.value === fromDescriptor.value)
- );
- };
- const changePrototype = (to, from) => {
- const fromPrototype = Object.getPrototypeOf(from);
- if (fromPrototype === Object.getPrototypeOf(to)) {
- return;
- }
- Object.setPrototypeOf(to, fromPrototype);
- };
- const wrappedToString = (withName, fromBody) => `/* Wrapped ${withName}*/\n${fromBody}`;
- const toStringDescriptor = Object.getOwnPropertyDescriptor(Function.prototype, 'toString');
- const toStringName = Object.getOwnPropertyDescriptor(Function.prototype.toString, 'name');
- // We call `from.toString()` early (not lazily) to ensure `from` can be garbage collected.
- // We use `bind()` instead of a closure for the same reason.
- // Calling `from.toString()` early also allows caching it in case `to.toString()` is called several times.
- const changeToString = (to, from, name) => {
- const withName = name === '' ? '' : `with ${name.trim()}() `;
- const newToString = wrappedToString.bind(null, withName, from.toString());
- // Ensure `to.toString.toString` is non-enumerable and has the same `same`
- Object.defineProperty(newToString, 'name', toStringName);
- Object.defineProperty(to, 'toString', {...toStringDescriptor, value: newToString});
- };
- function mimicFunction(to, from, {ignoreNonConfigurable = false} = {}) {
- const {name} = to;
- for (const property of Reflect.ownKeys(from)) {
- copyProperty(to, from, property, ignoreNonConfigurable);
- }
- changePrototype(to, from);
- changeToString(to, from, name);
- return to;
- }
- const calledFunctions = new WeakMap();
- const onetime = (function_, options = {}) => {
- if (typeof function_ !== 'function') {
- throw new TypeError('Expected a function');
- }
- let returnValue;
- let callCount = 0;
- const functionName = function_.displayName || function_.name || '<anonymous>';
- const onetime = function (...arguments_) {
- calledFunctions.set(onetime, ++callCount);
- if (callCount === 1) {
- returnValue = function_.apply(this, arguments_);
- function_ = null;
- } else if (options.throw === true) {
- throw new Error(`Function \`${functionName}\` can only be called once`);
- }
- return returnValue;
- };
- mimicFunction(onetime, function_);
- calledFunctions.set(onetime, callCount);
- return onetime;
- };
- onetime.callCount = function_ => {
- if (!calledFunctions.has(function_)) {
- throw new Error(`The given function \`${function_.name}\` is not wrapped by the \`onetime\` package`);
- }
- return calledFunctions.get(function_);
- };
- const getRealtimeSignals=function(){
- const length=SIGRTMAX-SIGRTMIN+1;
- return Array.from({length},getRealtimeSignal);
- };
- const getRealtimeSignal=function(value,index){
- return {
- name:`SIGRT${index+1}`,
- number:SIGRTMIN+index,
- action:"terminate",
- description:"Application-specific signal (realtime)",
- standard:"posix"};
- };
- const SIGRTMIN=34;
- const SIGRTMAX=64;
- const SIGNALS=[
- {
- name:"SIGHUP",
- number:1,
- action:"terminate",
- description:"Terminal closed",
- standard:"posix"},
- {
- name:"SIGINT",
- number:2,
- action:"terminate",
- description:"User interruption with CTRL-C",
- standard:"ansi"},
- {
- name:"SIGQUIT",
- number:3,
- action:"core",
- description:"User interruption with CTRL-\\",
- standard:"posix"},
- {
- name:"SIGILL",
- number:4,
- action:"core",
- description:"Invalid machine instruction",
- standard:"ansi"},
- {
- name:"SIGTRAP",
- number:5,
- action:"core",
- description:"Debugger breakpoint",
- standard:"posix"},
- {
- name:"SIGABRT",
- number:6,
- action:"core",
- description:"Aborted",
- standard:"ansi"},
- {
- name:"SIGIOT",
- number:6,
- action:"core",
- description:"Aborted",
- standard:"bsd"},
- {
- name:"SIGBUS",
- number:7,
- action:"core",
- description:
- "Bus error due to misaligned, non-existing address or paging error",
- standard:"bsd"},
- {
- name:"SIGEMT",
- number:7,
- action:"terminate",
- description:"Command should be emulated but is not implemented",
- standard:"other"},
- {
- name:"SIGFPE",
- number:8,
- action:"core",
- description:"Floating point arithmetic error",
- standard:"ansi"},
- {
- name:"SIGKILL",
- number:9,
- action:"terminate",
- description:"Forced termination",
- standard:"posix",
- forced:true},
- {
- name:"SIGUSR1",
- number:10,
- action:"terminate",
- description:"Application-specific signal",
- standard:"posix"},
- {
- name:"SIGSEGV",
- number:11,
- action:"core",
- description:"Segmentation fault",
- standard:"ansi"},
- {
- name:"SIGUSR2",
- number:12,
- action:"terminate",
- description:"Application-specific signal",
- standard:"posix"},
- {
- name:"SIGPIPE",
- number:13,
- action:"terminate",
- description:"Broken pipe or socket",
- standard:"posix"},
- {
- name:"SIGALRM",
- number:14,
- action:"terminate",
- description:"Timeout or timer",
- standard:"posix"},
- {
- name:"SIGTERM",
- number:15,
- action:"terminate",
- description:"Termination",
- standard:"ansi"},
- {
- name:"SIGSTKFLT",
- number:16,
- action:"terminate",
- description:"Stack is empty or overflowed",
- standard:"other"},
- {
- name:"SIGCHLD",
- number:17,
- action:"ignore",
- description:"Child process terminated, paused or unpaused",
- standard:"posix"},
- {
- name:"SIGCLD",
- number:17,
- action:"ignore",
- description:"Child process terminated, paused or unpaused",
- standard:"other"},
- {
- name:"SIGCONT",
- number:18,
- action:"unpause",
- description:"Unpaused",
- standard:"posix",
- forced:true},
- {
- name:"SIGSTOP",
- number:19,
- action:"pause",
- description:"Paused",
- standard:"posix",
- forced:true},
- {
- name:"SIGTSTP",
- number:20,
- action:"pause",
- description:"Paused using CTRL-Z or \"suspend\"",
- standard:"posix"},
- {
- name:"SIGTTIN",
- number:21,
- action:"pause",
- description:"Background process cannot read terminal input",
- standard:"posix"},
- {
- name:"SIGBREAK",
- number:21,
- action:"terminate",
- description:"User interruption with CTRL-BREAK",
- standard:"other"},
- {
- name:"SIGTTOU",
- number:22,
- action:"pause",
- description:"Background process cannot write to terminal output",
- standard:"posix"},
- {
- name:"SIGURG",
- number:23,
- action:"ignore",
- description:"Socket received out-of-band data",
- standard:"bsd"},
- {
- name:"SIGXCPU",
- number:24,
- action:"core",
- description:"Process timed out",
- standard:"bsd"},
- {
- name:"SIGXFSZ",
- number:25,
- action:"core",
- description:"File too big",
- standard:"bsd"},
- {
- name:"SIGVTALRM",
- number:26,
- action:"terminate",
- description:"Timeout or timer",
- standard:"bsd"},
- {
- name:"SIGPROF",
- number:27,
- action:"terminate",
- description:"Timeout or timer",
- standard:"bsd"},
- {
- name:"SIGWINCH",
- number:28,
- action:"ignore",
- description:"Terminal window size changed",
- standard:"bsd"},
- {
- name:"SIGIO",
- number:29,
- action:"terminate",
- description:"I/O is available",
- standard:"other"},
- {
- name:"SIGPOLL",
- number:29,
- action:"terminate",
- description:"Watched event",
- standard:"other"},
- {
- name:"SIGINFO",
- number:29,
- action:"ignore",
- description:"Request for process information",
- standard:"other"},
- {
- name:"SIGPWR",
- number:30,
- action:"terminate",
- description:"Device running out of power",
- standard:"systemv"},
- {
- name:"SIGSYS",
- number:31,
- action:"core",
- description:"Invalid system call",
- standard:"other"},
- {
- name:"SIGUNUSED",
- number:31,
- action:"terminate",
- description:"Invalid system call",
- standard:"other"}];
- const getSignals=function(){
- const realtimeSignals=getRealtimeSignals();
- const signals=[...SIGNALS,...realtimeSignals].map(normalizeSignal);
- return signals;
- };
- const normalizeSignal=function({
- name,
- number:defaultNumber,
- description,
- action,
- forced=false,
- standard})
- {
- const{
- signals:{[name]:constantSignal}}=
- constants;
- const supported=constantSignal!==undefined;
- const number=supported?constantSignal:defaultNumber;
- return {name,number,description,supported,action,forced,standard};
- };
- const getSignalsByName=function(){
- const signals=getSignals();
- return signals.reduce(getSignalByName,{});
- };
- const getSignalByName=function(
- signalByNameMemo,
- {name,number,description,supported,action,forced,standard})
- {
- return {
- ...signalByNameMemo,
- [name]:{name,number,description,supported,action,forced,standard}};
- };
- const signalsByName=getSignalsByName();
- const getSignalsByNumber=function(){
- const signals=getSignals();
- const length=SIGRTMAX+1;
- const signalsA=Array.from({length},(value,number)=>
- getSignalByNumber(number,signals));
- return Object.assign({},...signalsA);
- };
- const getSignalByNumber=function(number,signals){
- const signal=findSignalByNumber(number,signals);
- if(signal===undefined){
- return {};
- }
- const{name,description,supported,action,forced,standard}=signal;
- return {
- [number]:{
- name,
- number,
- description,
- supported,
- action,
- forced,
- standard}};
- };
- const findSignalByNumber=function(number,signals){
- const signal=signals.find(({name})=>constants.signals[name]===number);
- if(signal!==undefined){
- return signal;
- }
- return signals.find((signalA)=>signalA.number===number);
- };
- getSignalsByNumber();
- const getErrorPrefix = ({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}) => {
- if (timedOut) {
- return `timed out after ${timeout} milliseconds`;
- }
- if (isCanceled) {
- return 'was canceled';
- }
- if (errorCode !== undefined) {
- return `failed with ${errorCode}`;
- }
- if (signal !== undefined) {
- return `was killed with ${signal} (${signalDescription})`;
- }
- if (exitCode !== undefined) {
- return `failed with exit code ${exitCode}`;
- }
- return 'failed';
- };
- const makeError = ({
- stdout,
- stderr,
- all,
- error,
- signal,
- exitCode,
- command,
- escapedCommand,
- timedOut,
- isCanceled,
- killed,
- parsed: {options: {timeout}},
- }) => {
- // `signal` and `exitCode` emitted on `spawned.on('exit')` event can be `null`.
- // We normalize them to `undefined`
- exitCode = exitCode === null ? undefined : exitCode;
- signal = signal === null ? undefined : signal;
- const signalDescription = signal === undefined ? undefined : signalsByName[signal].description;
- const errorCode = error && error.code;
- const prefix = getErrorPrefix({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled});
- const execaMessage = `Command ${prefix}: ${command}`;
- const isError = Object.prototype.toString.call(error) === '[object Error]';
- const shortMessage = isError ? `${execaMessage}\n${error.message}` : execaMessage;
- const message = [shortMessage, stderr, stdout].filter(Boolean).join('\n');
- if (isError) {
- error.originalMessage = error.message;
- error.message = message;
- } else {
- error = new Error(message);
- }
- error.shortMessage = shortMessage;
- error.command = command;
- error.escapedCommand = escapedCommand;
- error.exitCode = exitCode;
- error.signal = signal;
- error.signalDescription = signalDescription;
- error.stdout = stdout;
- error.stderr = stderr;
- if (all !== undefined) {
- error.all = all;
- }
- if ('bufferedData' in error) {
- delete error.bufferedData;
- }
- error.failed = true;
- error.timedOut = Boolean(timedOut);
- error.isCanceled = isCanceled;
- error.killed = killed && !timedOut;
- return error;
- };
- const aliases = ['stdin', 'stdout', 'stderr'];
- const hasAlias = options => aliases.some(alias => options[alias] !== undefined);
- const normalizeStdio = options => {
- if (!options) {
- return;
- }
- const {stdio} = options;
- if (stdio === undefined) {
- return aliases.map(alias => options[alias]);
- }
- if (hasAlias(options)) {
- throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${aliases.map(alias => `\`${alias}\``).join(', ')}`);
- }
- if (typeof stdio === 'string') {
- return stdio;
- }
- if (!Array.isArray(stdio)) {
- throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof stdio}\``);
- }
- const length = Math.max(stdio.length, aliases.length);
- return Array.from({length}, (value, index) => stdio[index]);
- };
- const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5;
- // Monkey-patches `childProcess.kill()` to add `forceKillAfterTimeout` behavior
- const spawnedKill = (kill, signal = 'SIGTERM', options = {}) => {
- const killResult = kill(signal);
- setKillTimeout(kill, signal, options, killResult);
- return killResult;
- };
- const setKillTimeout = (kill, signal, options, killResult) => {
- if (!shouldForceKill(signal, options, killResult)) {
- return;
- }
- const timeout = getForceKillAfterTimeout(options);
- const t = setTimeout(() => {
- kill('SIGKILL');
- }, timeout);
- // Guarded because there's no `.unref()` when `execa` is used in the renderer
- // process in Electron. This cannot be tested since we don't run tests in
- // Electron.
- // istanbul ignore else
- if (t.unref) {
- t.unref();
- }
- };
- const shouldForceKill = (signal, {forceKillAfterTimeout}, killResult) => isSigterm(signal) && forceKillAfterTimeout !== false && killResult;
- const isSigterm = signal => signal === require$$0.constants.signals.SIGTERM
- || (typeof signal === 'string' && signal.toUpperCase() === 'SIGTERM');
- const getForceKillAfterTimeout = ({forceKillAfterTimeout = true}) => {
- if (forceKillAfterTimeout === true) {
- return DEFAULT_FORCE_KILL_TIMEOUT;
- }
- if (!Number.isFinite(forceKillAfterTimeout) || forceKillAfterTimeout < 0) {
- throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${forceKillAfterTimeout}\` (${typeof forceKillAfterTimeout})`);
- }
- return forceKillAfterTimeout;
- };
- // `childProcess.cancel()`
- const spawnedCancel = (spawned, context) => {
- const killResult = spawned.kill();
- if (killResult) {
- context.isCanceled = true;
- }
- };
- const timeoutKill = (spawned, signal, reject) => {
- spawned.kill(signal);
- reject(Object.assign(new Error('Timed out'), {timedOut: true, signal}));
- };
- // `timeout` option handling
- const setupTimeout = (spawned, {timeout, killSignal = 'SIGTERM'}, spawnedPromise) => {
- if (timeout === 0 || timeout === undefined) {
- return spawnedPromise;
- }
- let timeoutId;
- const timeoutPromise = new Promise((resolve, reject) => {
- timeoutId = setTimeout(() => {
- timeoutKill(spawned, killSignal, reject);
- }, timeout);
- });
- const safeSpawnedPromise = spawnedPromise.finally(() => {
- clearTimeout(timeoutId);
- });
- return Promise.race([timeoutPromise, safeSpawnedPromise]);
- };
- const validateTimeout = ({timeout}) => {
- if (timeout !== undefined && (!Number.isFinite(timeout) || timeout < 0)) {
- throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${timeout}\` (${typeof timeout})`);
- }
- };
- // `cleanup` option handling
- const setExitHandler = async (spawned, {cleanup, detached}, timedPromise) => {
- if (!cleanup || detached) {
- return timedPromise;
- }
- const removeExitHandler = signalExit.exports(() => {
- spawned.kill();
- });
- return timedPromise.finally(() => {
- removeExitHandler();
- });
- };
- function isStream(stream) {
- return stream !== null
- && typeof stream === 'object'
- && typeof stream.pipe === 'function';
- }
- // `input` option
- const handleInput = (spawned, input) => {
- // Checking for stdin is workaround for https://github.com/nodejs/node/issues/26852
- // @todo remove `|| spawned.stdin === undefined` once we drop support for Node.js <=12.2.0
- if (input === undefined || spawned.stdin === undefined) {
- return;
- }
- if (isStream(input)) {
- input.pipe(spawned.stdin);
- } else {
- spawned.stdin.end(input);
- }
- };
- // `all` interleaves `stdout` and `stderr`
- const makeAllStream = (spawned, {all}) => {
- if (!all || (!spawned.stdout && !spawned.stderr)) {
- return;
- }
- const mixed = mergeStream();
- if (spawned.stdout) {
- mixed.add(spawned.stdout);
- }
- if (spawned.stderr) {
- mixed.add(spawned.stderr);
- }
- return mixed;
- };
- // On failure, `result.stdout|stderr|all` should contain the currently buffered stream
- const getBufferedData = async (stream, streamPromise) => {
- if (!stream) {
- return;
- }
- stream.destroy();
- try {
- return await streamPromise;
- } catch (error) {
- return error.bufferedData;
- }
- };
- const getStreamPromise = (stream, {encoding, buffer, maxBuffer}) => {
- if (!stream || !buffer) {
- return;
- }
- if (encoding) {
- return getStream.exports(stream, {encoding, maxBuffer});
- }
- return getStream.exports.buffer(stream, {maxBuffer});
- };
- // Retrieve result of child process: exit code, signal, error, streams (stdout/stderr/all)
- const getSpawnedResult = async ({stdout, stderr, all}, {encoding, buffer, maxBuffer}, processDone) => {
- const stdoutPromise = getStreamPromise(stdout, {encoding, buffer, maxBuffer});
- const stderrPromise = getStreamPromise(stderr, {encoding, buffer, maxBuffer});
- const allPromise = getStreamPromise(all, {encoding, buffer, maxBuffer: maxBuffer * 2});
- try {
- return await Promise.all([processDone, stdoutPromise, stderrPromise, allPromise]);
- } catch (error) {
- return Promise.all([
- {error, signal: error.signal, timedOut: error.timedOut},
- getBufferedData(stdout, stdoutPromise),
- getBufferedData(stderr, stderrPromise),
- getBufferedData(all, allPromise),
- ]);
- }
- };
- const nativePromisePrototype = (async () => {})().constructor.prototype;
- const descriptors = ['then', 'catch', 'finally'].map(property => [
- property,
- Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property),
- ]);
- // The return value is a mixin of `childProcess` and `Promise`
- const mergePromise = (spawned, promise) => {
- for (const [property, descriptor] of descriptors) {
- // Starting the main `promise` is deferred to avoid consuming streams
- const value = typeof promise === 'function'
- ? (...args) => Reflect.apply(descriptor.value, promise(), args)
- : descriptor.value.bind(promise);
- Reflect.defineProperty(spawned, property, {...descriptor, value});
- }
- return spawned;
- };
- // Use promises instead of `child_process` events
- const getSpawnedPromise = spawned => new Promise((resolve, reject) => {
- spawned.on('exit', (exitCode, signal) => {
- resolve({exitCode, signal});
- });
- spawned.on('error', error => {
- reject(error);
- });
- if (spawned.stdin) {
- spawned.stdin.on('error', error => {
- reject(error);
- });
- }
- });
- const normalizeArgs = (file, args = []) => {
- if (!Array.isArray(args)) {
- return [file];
- }
- return [file, ...args];
- };
- const NO_ESCAPE_REGEXP = /^[\w.-]+$/;
- const DOUBLE_QUOTES_REGEXP = /"/g;
- const escapeArg = arg => {
- if (typeof arg !== 'string' || NO_ESCAPE_REGEXP.test(arg)) {
- return arg;
- }
- return `"${arg.replace(DOUBLE_QUOTES_REGEXP, '\\"')}"`;
- };
- const joinCommand = (file, args) => normalizeArgs(file, args).join(' ');
- const getEscapedCommand = (file, args) => normalizeArgs(file, args).map(arg => escapeArg(arg)).join(' ');
- const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100;
- const getEnv = ({env: envOption, extendEnv, preferLocal, localDir, execPath}) => {
- const env = extendEnv ? {...process$1.env, ...envOption} : envOption;
- if (preferLocal) {
- return npmRunPathEnv({env, cwd: localDir, execPath});
- }
- return env;
- };
- const handleArguments = (file, args, options = {}) => {
- const parsed = crossSpawn.exports._parse(file, args, options);
- file = parsed.command;
- args = parsed.args;
- options = parsed.options;
- options = {
- maxBuffer: DEFAULT_MAX_BUFFER,
- buffer: true,
- stripFinalNewline: true,
- extendEnv: true,
- preferLocal: false,
- localDir: options.cwd || process$1.cwd(),
- execPath: process$1.execPath,
- encoding: 'utf8',
- reject: true,
- cleanup: true,
- all: false,
- windowsHide: true,
- ...options,
- };
- options.env = getEnv(options);
- options.stdio = normalizeStdio(options);
- if (process$1.platform === 'win32' && path.basename(file, '.exe') === 'cmd') {
- // #116
- args.unshift('/q');
- }
- return {file, args, options, parsed};
- };
- const handleOutput = (options, value, error) => {
- if (typeof value !== 'string' && !Buffer.isBuffer(value)) {
- // When `execaSync()` errors, we normalize it to '' to mimic `execa()`
- return error === undefined ? undefined : '';
- }
- if (options.stripFinalNewline) {
- return stripFinalNewline(value);
- }
- return value;
- };
- function execa(file, args, options) {
- const parsed = handleArguments(file, args, options);
- const command = joinCommand(file, args);
- const escapedCommand = getEscapedCommand(file, args);
- validateTimeout(parsed.options);
- let spawned;
- try {
- spawned = childProcess.spawn(parsed.file, parsed.args, parsed.options);
- } catch (error) {
- // Ensure the returned error is always both a promise and a child process
- const dummySpawned = new childProcess.ChildProcess();
- const errorPromise = Promise.reject(makeError({
- error,
- stdout: '',
- stderr: '',
- all: '',
- command,
- escapedCommand,
- parsed,
- timedOut: false,
- isCanceled: false,
- killed: false,
- }));
- return mergePromise(dummySpawned, errorPromise);
- }
- const spawnedPromise = getSpawnedPromise(spawned);
- const timedPromise = setupTimeout(spawned, parsed.options, spawnedPromise);
- const processDone = setExitHandler(spawned, parsed.options, timedPromise);
- const context = {isCanceled: false};
- spawned.kill = spawnedKill.bind(null, spawned.kill.bind(spawned));
- spawned.cancel = spawnedCancel.bind(null, spawned, context);
- const handlePromise = async () => {
- const [{error, exitCode, signal, timedOut}, stdoutResult, stderrResult, allResult] = await getSpawnedResult(spawned, parsed.options, processDone);
- const stdout = handleOutput(parsed.options, stdoutResult);
- const stderr = handleOutput(parsed.options, stderrResult);
- const all = handleOutput(parsed.options, allResult);
- if (error || exitCode !== 0 || signal !== null) {
- const returnedError = makeError({
- error,
- exitCode,
- signal,
- stdout,
- stderr,
- all,
- command,
- escapedCommand,
- parsed,
- timedOut,
- isCanceled: context.isCanceled || (parsed.options.signal ? parsed.options.signal.aborted : false),
- killed: spawned.killed,
- });
- if (!parsed.options.reject) {
- return returnedError;
- }
- throw returnedError;
- }
- return {
- command,
- escapedCommand,
- exitCode: 0,
- stdout,
- stderr,
- all,
- failed: false,
- timedOut: false,
- isCanceled: false,
- killed: false,
- };
- };
- const handlePromiseOnce = onetime(handlePromise);
- handleInput(spawned, parsed.options.input);
- spawned.all = makeAllStream(spawned, parsed.options);
- return mergePromise(spawned, handlePromiseOnce);
- }
- export { execa as e };
|