npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@flow-conductor/adapter-node-fetch

v1.0.1

Published

node-fetch adapter for flow-conductor

Readme

@flow-conductor/adapter-node-fetch

node-fetch adapter for flow-conductor. This adapter uses node-fetch, making it ideal for Node.js environments where you need a reliable HTTP client.

Installation

npm install @flow-conductor/adapter-node-fetch @flow-conductor/core node-fetch

Note: @flow-conductor/core and node-fetch are peer dependencies and must be installed alongside this package.

Quick Start

import { begin } from "@flow-conductor/core";
import { NodeFetchRequestAdapter } from "@flow-conductor/adapter-node-fetch";

const adapter = new NodeFetchRequestAdapter();

const result = await begin(
  {
    config: {
      url: "https://api.example.com/users",
      method: "GET",
    },
  },
  adapter
).execute();

const data = await result.json();
console.log(data);

Usage

Basic GET Request

import { begin } from "@flow-conductor/core";
import { NodeFetchRequestAdapter } from "@flow-conductor/adapter-node-fetch";

const adapter = new NodeFetchRequestAdapter();

const result = await begin(
  {
    config: {
      url: "https://api.example.com/users/1",
      method: "GET",
    },
  },
  adapter
).execute();

const user = await result.json();
console.log(user);

POST Request with Data

import { begin } from "@flow-conductor/core";
import { NodeFetchRequestAdapter } from "@flow-conductor/adapter-node-fetch";

const adapter = new NodeFetchRequestAdapter();

const result = await begin(
  {
    config: {
      url: "https://api.example.com/users",
      method: "POST",
      data: {
        name: "John Doe",
        email: "[email protected]",
      },
    },
  },
  adapter
).execute();

const newUser = await result.json();
console.log(newUser);

Request with Custom Headers

import { begin } from "@flow-conductor/core";
import { NodeFetchRequestAdapter } from "@flow-conductor/adapter-node-fetch";

const adapter = new NodeFetchRequestAdapter();

const result = await begin(
  {
    config: {
      url: "https://api.example.com/users",
      method: "GET",
      headers: {
        Authorization: "Bearer your-token-here",
        "X-Custom-Header": "value",
      },
    },
  },
  adapter
).execute();

Chained Requests

import { begin } from "@flow-conductor/core";
import { NodeFetchRequestAdapter } from "@flow-conductor/adapter-node-fetch";

const adapter = new NodeFetchRequestAdapter();

const result = await begin(
  {
    config: {
      url: "https://api.example.com/users/1",
      method: "GET",
    },
  },
  adapter
)
  .next({
    config: async (previousResult) => {
      const user = await previousResult.json();
      return {
        url: `https://api.example.com/users/${user.id}/posts`,
        method: "GET",
      };
    },
  })
  .execute();

const posts = await result.json();
console.log(posts);

Configuration

The NodeFetchRequestAdapter accepts standard IRequestConfig objects compatible with node-fetch. The adapter automatically:

  • JSON stringifies data for non-GET requests
  • Sets Content-Type: application/json header when data is provided
  • Passes through all other node-fetch options

Request Config Interface

interface NodeFetchRequestConfig extends IRequestConfig {
  url: string;
  method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS";
  data?: any; // Will be JSON stringified for non-GET requests
  headers?: Record<string, string>;
  // ... other fetch options (redirect, timeout, etc.)
}

Supported Fetch Options

All standard node-fetch options are supported:

const result = await begin(
  {
    config: {
      url: "https://api.example.com/users",
      method: "GET",
      headers: {
        "Authorization": "Bearer token",
      },
      redirect: "follow", // Redirect handling
      timeout: 5000, // Request timeout
      // ... any other RequestInit options
    },
  },
  adapter
).execute();

Data Handling

The adapter automatically handles data serialization:

  • GET requests: Data is ignored (use query parameters in URL instead)
  • Other methods: Data is JSON stringified and sent as the request body
  • Content-Type: Automatically set to application/json when data is provided
  • String data: Passed through as-is
  • Buffer/Uint8Array: Passed through as binary data
// POST with JSON data
const result = await begin(
  {
    config: {
      url: "https://api.example.com/users",
      method: "POST",
      data: { name: "John", email: "[email protected]" },
      // Content-Type: application/json is automatically added
    },
  },
  adapter
).execute();

// POST with string data
const textResult = await begin(
  {
    config: {
      url: "https://api.example.com/data",
      method: "POST",
      data: "raw string data",
      // Content-Type will not be automatically set for string data
    },
  },
  adapter
).execute();

// PUT with JSON data
const updateResult = await begin(
  {
    config: {
      url: "https://api.example.com/users/1",
      method: "PUT",
      data: { name: "Jane" },
    },
  },
  adapter
).execute();

Custom Headers

You can provide custom headers, which will be merged with default headers:

const result = await begin(
  {
    config: {
      url: "https://api.example.com/users",
      method: "POST",
      data: { name: "John" },
      headers: {
        "Authorization": "Bearer token",
        "X-Custom-Header": "value",
        // Content-Type will be automatically added if not specified
      },
    },
  },
  adapter
).execute();

Response Handling

The adapter returns a standard Response object from node-fetch. You can use all standard Response methods:

const result = await begin(
  {
    config: {
      url: "https://api.example.com/users",
      method: "GET",
    },
  },
  adapter
).execute();

// Standard Response methods
const json = await result.json();
const text = await result.text();
const blob = await result.blob();
const arrayBuffer = await result.arrayBuffer();

// Response properties
console.log(result.status); // HTTP status code
console.log(result.statusText); // Status text
console.log(result.ok); // true if status 200-299
console.log(result.headers); // Headers object

Error Handling

node-fetch throws errors for network failures and rejects on HTTP error statuses (depending on configuration). You can handle errors using flow-conductor's error handling:

import { begin } from "@flow-conductor/core";
import { NodeFetchRequestAdapter } from "@flow-conductor/adapter-node-fetch";

const adapter = new NodeFetchRequestAdapter();

try {
  const result = await begin(
    {
      config: {
        url: "https://api.example.com/users",
        method: "GET",
      },
    },
    adapter
  )
    .withErrorHandler((error) => {
      console.error("Request failed:", error);
    })
    .execute();

  if (!result.ok) {
    throw new Error(`HTTP error! status: ${result.status}`);
  }

  const data = await result.json();
  console.log(data);
} catch (error) {
  console.error("Error:", error);
}

Node.js Environment

This adapter is specifically designed for Node.js environments and uses node-fetch v3, which is ESM-only. Make sure your project is configured for ESM:

{
  "type": "module"
}

Requirements

  • Node.js 18+ (for native ESM support)
  • node-fetch v3.x

Examples

Authentication Flow

import { begin } from "@flow-conductor/core";
import { NodeFetchRequestAdapter } from "@flow-conductor/adapter-node-fetch";

const adapter = new NodeFetchRequestAdapter();

// Login and use token
const userData = await begin(
  {
    config: {
      url: "https://api.example.com/auth/login",
      method: "POST",
      data: { username: "user", password: "pass" },
    },
  },
  adapter
)
  .next({
    config: async (previousResult) => {
      const auth = await previousResult.json();
      return {
        url: "https://api.example.com/user/profile",
        method: "GET",
        headers: { Authorization: `Bearer ${auth.token}` },
      };
    },
  })
  .execute();

const profile = await userData.json();
console.log(profile);

File Upload

import { begin } from "@flow-conductor/core";
import { NodeFetchRequestAdapter } from "@flow-conductor/adapter-node-fetch";
import { readFileSync } from "fs";

const adapter = new NodeFetchRequestAdapter();

// Upload file as Buffer
const fileBuffer = readFileSync("./file.pdf");

const result = await begin(
  {
    config: {
      url: "https://api.example.com/upload",
      method: "POST",
      data: fileBuffer,
      headers: {
        "Content-Type": "application/pdf",
      },
    },
  },
  adapter
).execute();

Request with Timeout

import { begin } from "@flow-conductor/core";
import { NodeFetchRequestAdapter } from "@flow-conductor/adapter-node-fetch";

const adapter = new NodeFetchRequestAdapter();

const result = await begin(
  {
    config: {
      url: "https://api.example.com/users",
      method: "GET",
      timeout: 5000, // 5 second timeout
    },
  },
  adapter
).execute();

API Reference

NodeFetchRequestAdapter

class NodeFetchRequestAdapter extends RequestAdapter<Response, NodeFetchRequestConfig> {
  createRequest(requestConfig: IRequestConfig): Promise<Response>;
}

NodeFetchRequestConfig

type NodeFetchRequestConfig = IRequestConfig;

Extends IRequestConfig with all standard node-fetch options.

Differences from Native Fetch Adapter

The @flow-conductor/adapter-node-fetch adapter is similar to @flow-conductor/adapter-fetch, but:

  • Node.js only: Designed specifically for Node.js environments
  • node-fetch dependency: Uses the node-fetch package instead of native fetch
  • Better Node.js support: May have better support for Node.js-specific features
  • Consistent API: Provides a consistent API across different Node.js versions

Choose @flow-conductor/adapter-node-fetch if:

  • You're building a Node.js-only application
  • You need features specific to node-fetch
  • You want explicit control over the fetch implementation

Choose @flow-conductor/adapter-fetch if:

  • You want to use the native Fetch API (Node.js 18+)
  • You want to avoid additional dependencies
  • You're building for both browser and Node.js

Requirements

  • @flow-conductor/core (peer dependency)
  • node-fetch v3.x (peer dependency)
  • Node.js 18+ (for native ESM support)
  • TypeScript 5.0+

License

MIT