aboutsummaryrefslogtreecommitdiff
path: root/node_modules/execa/lib
diff options
context:
space:
mode:
authorJoel Kronqvist <work.joelkronqvist@pm.me>2022-03-11 20:46:06 +0200
committerJoel Kronqvist <work.joelkronqvist@pm.me>2022-03-11 20:46:06 +0200
commit080c5819d87b933816d724a83f3bf4f1686770a7 (patch)
tree4a2ccc68b27edf7d4cbc586c932cc7542b655e19 /node_modules/execa/lib
parent5ac7049a9d30733165cc212dee308163c2a14644 (diff)
parentd003b82235a9329f912522a2f70aa950dfce4998 (diff)
downloadLYLLRuoka-080c5819d87b933816d724a83f3bf4f1686770a7.tar.gz
LYLLRuoka-080c5819d87b933816d724a83f3bf4f1686770a7.zip
Merge branch 'master' of https://github.com/JoelHMikael/FoodJS
Updating remote changes
Diffstat (limited to 'node_modules/execa/lib')
-rw-r--r--node_modules/execa/lib/command.js52
-rw-r--r--node_modules/execa/lib/error.js88
-rw-r--r--node_modules/execa/lib/kill.js115
-rw-r--r--node_modules/execa/lib/promise.js46
-rw-r--r--node_modules/execa/lib/stdio.js52
-rw-r--r--node_modules/execa/lib/stream.js97
6 files changed, 450 insertions, 0 deletions
diff --git a/node_modules/execa/lib/command.js b/node_modules/execa/lib/command.js
new file mode 100644
index 0000000..859b006
--- /dev/null
+++ b/node_modules/execa/lib/command.js
@@ -0,0 +1,52 @@
+'use strict';
+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) => {
+ return normalizeArgs(file, args).join(' ');
+};
+
+const getEscapedCommand = (file, args) => {
+ return normalizeArgs(file, args).map(arg => escapeArg(arg)).join(' ');
+};
+
+const SPACES_REGEXP = / +/g;
+
+// Handle `execa.command()`
+const parseCommand = command => {
+ const tokens = [];
+ for (const token of command.trim().split(SPACES_REGEXP)) {
+ // Allow spaces to be escaped by a backslash if not meant as a delimiter
+ const previousToken = tokens[tokens.length - 1];
+ if (previousToken && previousToken.endsWith('\\')) {
+ // Merge previous token with current one
+ tokens[tokens.length - 1] = `${previousToken.slice(0, -1)} ${token}`;
+ } else {
+ tokens.push(token);
+ }
+ }
+
+ return tokens;
+};
+
+module.exports = {
+ joinCommand,
+ getEscapedCommand,
+ parseCommand
+};
diff --git a/node_modules/execa/lib/error.js b/node_modules/execa/lib/error.js
new file mode 100644
index 0000000..4214467
--- /dev/null
+++ b/node_modules/execa/lib/error.js
@@ -0,0 +1,88 @@
+'use strict';
+const {signalsByName} = require('human-signals');
+
+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;
+};
+
+module.exports = makeError;
diff --git a/node_modules/execa/lib/kill.js b/node_modules/execa/lib/kill.js
new file mode 100644
index 0000000..287a142
--- /dev/null
+++ b/node_modules/execa/lib/kill.js
@@ -0,0 +1,115 @@
+'use strict';
+const os = require('os');
+const onExit = require('signal-exit');
+
+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) => {
+ return isSigterm(signal) && forceKillAfterTimeout !== false && killResult;
+};
+
+const isSigterm = signal => {
+ return signal === os.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 = onExit(() => {
+ spawned.kill();
+ });
+
+ return timedPromise.finally(() => {
+ removeExitHandler();
+ });
+};
+
+module.exports = {
+ spawnedKill,
+ spawnedCancel,
+ setupTimeout,
+ validateTimeout,
+ setExitHandler
+};
diff --git a/node_modules/execa/lib/promise.js b/node_modules/execa/lib/promise.js
new file mode 100644
index 0000000..bd9d523
--- /dev/null
+++ b/node_modules/execa/lib/promise.js
@@ -0,0 +1,46 @@
+'use strict';
+
+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 => {
+ return 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);
+ });
+ }
+ });
+};
+
+module.exports = {
+ mergePromise,
+ getSpawnedPromise
+};
+
diff --git a/node_modules/execa/lib/stdio.js b/node_modules/execa/lib/stdio.js
new file mode 100644
index 0000000..45129ed
--- /dev/null
+++ b/node_modules/execa/lib/stdio.js
@@ -0,0 +1,52 @@
+'use strict';
+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]);
+};
+
+module.exports = normalizeStdio;
+
+// `ipc` is pushed unless it is already present
+module.exports.node = options => {
+ const stdio = normalizeStdio(options);
+
+ if (stdio === 'ipc') {
+ return 'ipc';
+ }
+
+ if (stdio === undefined || typeof stdio === 'string') {
+ return [stdio, stdio, stdio, 'ipc'];
+ }
+
+ if (stdio.includes('ipc')) {
+ return stdio;
+ }
+
+ return [...stdio, 'ipc'];
+};
diff --git a/node_modules/execa/lib/stream.js b/node_modules/execa/lib/stream.js
new file mode 100644
index 0000000..d445dd4
--- /dev/null
+++ b/node_modules/execa/lib/stream.js
@@ -0,0 +1,97 @@
+'use strict';
+const isStream = require('is-stream');
+const getStream = require('get-stream');
+const mergeStream = require('merge-stream');
+
+// `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(stream, {encoding, maxBuffer});
+ }
+
+ return getStream.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 validateInputSync = ({input}) => {
+ if (isStream(input)) {
+ throw new TypeError('The `input` option cannot be a stream in sync mode');
+ }
+};
+
+module.exports = {
+ handleInput,
+ makeAllStream,
+ getSpawnedResult,
+ validateInputSync
+};
+