New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

child-process-utilities

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

child-process-utilities

Utilities to deal with child_process native Node.js package.

latest
Source
npmnpm
Version
0.1.8
Version published
Maintainers
1
Created
Source

child-process-utilities

Memory-efficient utilities to deal with child_process native Node.js package.

Installation

npm i child-process-utilities

Usage

Iterate over the output streams of a process using async iterators

This method does not use any sort of buffering. Which means that we do not cache the entire output into memory.

stdout/stderr

The values returned by stdout and stderr can be iterated directly by default.

import { spawn } from "child-process-utilities";

const childProcess = spawn(/* ... */, /* ... */, /* ... */);

for await (const chunk of childProcess.output().stdout()) {
  //             ^ Uint8Array
  console.log("Chunk: %s", chunk);
}

split

In the example below, the output is streamed line by line, since we're using the \n character, but any other character can be passed to split.

import { spawn } from "child-process-utilities";

const lines = spawn
  .pipe(bin.curl, ["-L", project.license.url])
  .output()
  .stdout()
  .split("\n"); // Returns an AsyncIterableIterator<string>
for await (const line of lines) {
  console.log("This is a line: %s", line);
}

// Or
const chunks = spawn
  .pipe(bin.curl, ["-L", project.license.url])
  .output()
  .stdout(); // `IReadableHelper` is an async iterator by itself
for await (const chunk of chunks) {
  //             ^ Uint8Array
  console.log("Chunk: %s", line);
}

Please note that for performance reasons any decisive output functions can only be called once.

const childProcess = spawn(/* ... */, /* ... */, /* ... */);

childProcess.output().stderr().raw() // Do
childProcess.output().stderr().raw() // Don't
//             stderr ^^^^^^

// stdout
childProcess.output().stdout().raw() // Do
childProcess.output().stdout().raw() // Don't
//             stdout ^^^^^^

Wait for a process to finish

import { spawn } from "child-process-utilities";

export default async function () {
  await spawn("npx", ["ts-node", "src"]).wait();
}

Wait for a process to finish without consuming stdout

import { spawn } from "child-process-utilities";

export default async function () {
  await spawn.pipe("npx", ["ts-node", "src"]).wait();
}

Get the output of a process

String

import { spawn } from "child-process-utilities";

export default async function () {
  const { stdout, stderr } = await spawn("npx", ["ts-node", "src"]).output();
  console.log(await stdout().decode("UTF-8")); // Returns a string
  console.error(await stderr().decode("UTF-8")); // Returns a string
}

Uint8Array

import { spawn } from "child-process-utilities";

export default async function () {
  const { stdout, stderr } = await spawn("npx", ["ts-node", "src"]).output();
  console.log(await stdout().raw()); // Returns an Uint8Array
  console.error(await stderr().raw()); // Returns an Uint8Array
}

JSON

import { spawn } from "child-process-utilities";

export default async function () {
  const { stdout, stderr } = await spawn("npx", ["ts-node", "src"]).output();
  console.log(await stdout().json()); // Parses the stdout as JSON
  console.error(await stderr().json()); // Parses the stderr as JSON
}
JSON property type inference

You can pass a type to the spawn function to infer the return type of the output method. Currently, we only support defining a type for the json output property.

// (method) IReadableHelper<{ json: number; }>.json<number>(): Promise<number>
spawn</* Using TypeScript inline types */ { json: number }>("x")
  .output()
  .stdout()
  .json(); // Promise<number>

interface IVideoMetadata {
  duration: number;
  fileName: string;
}

interface IGetVideoMetadataTypes {
  json: IVideoMetadata;
}

// (method) IReadableHelper<IVideoMetadata>.json<IVideoMetadata>(): Promise<IVideoMetadata>
spawn<IGetVideoMetadataTypes>("/home/user/get-video-metadata.sh", [
  "video.mp4" /* ... */,
])
  .output()
  .stdout()
  .json(); // Promise<IVideoMetadata>

// (method) IReadableHelper<{ json: unknown; }>.json<unknown>(): Promise<unknown>
spawn("x").output().stdout().json(); // Promise<unknown>

Advantages on this approach is that you can define a spawn method that returns a predefined type:

import { spawn } from "child-process-utilities";

export interface IVideoMetadata {
  duration: number;
  fileName: string;
}

export interface IGetVideoMetadataTypes {
  json: IVideoMetadata;
}

const getVideoMetadata = (url: string) =>
  spawn<IGetVideoMetadataTypes>("/home/user/get-video-metadata.sh", [url]);

export default getVideoMetadata;
import getVideoMetadata from "./getVideoMetadata";

export default async function askForVideoMetadata() {
  const pendingVideoMetadata = getVideoMetadata("video.mp4");
  const error = await pendingVideoMetadata.output().stderr().raw();

  try {
    const videoMetadata = await pendingVideoMetadata.output().stdout().json();
  } catch (error) {
    process.stderr.write(error);
  }
}

FAQs

Package last updated on 02 Oct 2024

Did you know?

Socket

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.

Install

Related posts