Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
@expo/spawn-async
Advanced tools
A Promise-based interface into processes created by child_process.spawn
The @expo/spawn-async npm package is a utility for spawning child processes asynchronously in Node.js. It is designed to make it easier to work with child processes by providing a promise-based API. This allows developers to use async/await syntax for cleaner and more readable code when dealing with processes that need to be executed outside of the main Node.js process.
Executing shell commands
This feature allows you to execute shell commands asynchronously. The code sample demonstrates how to use @expo/spawn-async to run the 'echo' command with 'hello world' as an argument. The output of the command is then logged to the console.
const spawnAsync = require('@expo/spawn-async');
async function runCommand() {
try {
const result = await spawnAsync('echo', ['hello world']);
console.log(result.stdout); // Output: hello world
} catch (error) {
console.error(error.stderr);
}
}
runCommand();
Handling errors
This feature demonstrates error handling when executing commands that might fail or do not exist. The code sample attempts to run a non-existent command, which results in an error being caught and logged.
const spawnAsync = require('@expo/spawn-async');
async function runCommand() {
try {
await spawnAsync('some-nonexistent-command');
} catch (error) {
console.error('Failed to execute command:', error.stderr);
}
}
runCommand();
The 'child_process' module is a core Node.js module that provides the ability to spawn child processes. While it offers more control and flexibility compared to @expo/spawn-async, it does not provide a promise-based API out of the box, making @expo/spawn-async more convenient for use with async/await syntax.
Execa is a popular npm package that provides a similar functionality to @expo/spawn-async. It offers a promise-based API for executing shell commands, making it easy to use with async/await. Execa also provides additional features such as better Windows support and the ability to run shell scripts, which might make it a more suitable choice for certain projects.
A cross-platform version of Node's child_process.spawn
as an async function that returns a promise. Supports Node 12 LTS and up.
import spawnAsync from '@expo/spawn-async';
(async function () {
let resultPromise = spawnAsync('echo', ['hello', 'world']);
let spawnedChildProcess = resultPromise.child;
try {
let {
pid,
output: [stdout, stderr],
stdout,
stderr,
status,
signal,
} = await resultPromise;
} catch (e) {
console.error(e.stack);
// The error object also has the same properties as the result object
}
})();
spawnAsync
takes the same arguments as child_process.spawn
. Its options are the same as those of child_process.spawn
plus:
ignoreStdio
: whether to ignore waiting for the child process's stdio streams to close before resolving the result promise. When ignoring stdio, the returned values for stdout
and stderr
will be empty strings. The default value of this option is false
.It returns a promise whose result is an object with these properties:
pid
: the process ID of the spawned child processoutput
: an array with stdout and stderr's outputstdout
: a string of what the child process wrote to stdoutstderr
: a string of what the child process wrote to stderrstatus
: the exit code of the child processsignal
: the signal (ex: SIGTERM
) used to stop the child process if it did not exit on its ownIf there's an error running the child process or it exits with a non-zero status code, spawnAsync
rejects the returned promise. The Error object also has the properties listed above.
Sometimes you may want to access the child process object--for example, if you wanted to attach event handlers to stdio
or stderr
and process data as it is available instead of waiting for the process to be resolved.
You can do this by accessing .child
on the Promise that is returned by spawnAsync
.
Here is an example:
(async () => {
let ffmpeg$ = spawnAsync('ffmpeg', ['-i', 'path/to/source.flac', '-codec:a', 'libmp3lame', '-b:a', '320k', '-ar', '44100', 'path/to/output.mp3']);
let childProcess = ffmpeg$.child;
childProcess.stdout.on('data', (data) => {
console.log(`ffmpeg stdout: ${data}`);
});
childProcess.stderr.on('data', (data) => {
console.error(`ffmpeg stderr: ${data}`);
});
let result = await ffmpeg$;
console.log(`ffmpeg pid ${result.pid} exited with code ${result.code}`);
})();
FAQs
A Promise-based interface into processes created by child_process.spawn
The npm package @expo/spawn-async receives a total of 1,044,579 weekly downloads. As such, @expo/spawn-async popularity was classified as popular.
We found that @expo/spawn-async demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 21 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.