Skip to main content
The Fetch module provides utilities for parsing curl-style arguments, building Web API Request objects, and parsing Response objects. It’s designed for implementing HTTP gateways and REST API integrations.

Functions

parseArgv

Parses curl-style argv into a structured fetch input.
function parseArgv(argv: string[]): FetchInput
argv
string[]
required
Array of command-line arguments in curl style
return
FetchInput
Structured input object with path, method, headers, body, and query parameters

Example

import { Fetch } from 'incur'

const input = Fetch.parseArgv([
  'users',
  '123',
  '--method', 'POST',
  '--data', '{"name":"Alice"}',
  '--header', 'Authorization: Bearer token',
  '--limit', '10'
])

// Returns:
// {
//   path: '/users/123',
//   method: 'POST',
//   headers: Headers { 'authorization': 'Bearer token' },
//   body: '{"name":"Alice"}',
//   query: URLSearchParams { 'limit': '10' }
// }

Reserved Flags

  • --method / -X - HTTP method (GET, POST, etc.)
  • --data / -d - Request body
  • --body - Request body (alternative)
  • --header / -H - HTTP header (format: Name: Value)
All other flags become query parameters.

buildRequest

Constructs a standard Web API Request from a FetchInput.
function buildRequest(input: FetchInput): Request
input
FetchInput
required
Structured fetch input object
return
Request
Standard Web API Request object

Example

import { Fetch } from 'incur'

const input: Fetch.FetchInput = {
  path: '/api/users',
  method: 'GET',
  headers: new Headers(),
  body: undefined,
  query: new URLSearchParams({ limit: '10' })
}

const request = Fetch.buildRequest(input)
// Standard Request with URL: http://localhost/api/users?limit=10

parseResponse

Parses a fetch Response into structured output.
async function parseResponse(response: Response): Promise<FetchOutput>
response
Response
required
Web API Response object
return
Promise<FetchOutput>
Structured output with status, headers, and parsed data

Example

import { Fetch } from 'incur'

const response = await fetch('https://api.example.com/users')
const output = await Fetch.parseResponse(response)

// Returns:
// {
//   ok: true,
//   status: 200,
//   data: { users: [...] },  // Parsed JSON or text
//   headers: response.headers
// }

isStreamingResponse

Returns true if the response body is a stream that should be consumed incrementally.
function isStreamingResponse(response: Response): boolean
response
Response
required
Web API Response object
return
boolean
true if the response is NDJSON streaming, false otherwise

Example

import { Fetch } from 'incur'

const response = await fetch('https://api.example.com/stream')

if (Fetch.isStreamingResponse(response)) {
  for await (const chunk of Fetch.parseStreamingResponse(response)) {
    console.log(chunk)
  }
} else {
  const output = await Fetch.parseResponse(response)
  console.log(output.data)
}

parseStreamingResponse

Parses a streaming response body as an async generator of parsed NDJSON chunks.
async function* parseStreamingResponse(
  response: Response
): AsyncGenerator<unknown, void, unknown>
response
Response
required
Web API Response object with content-type: application/x-ndjson
return
AsyncGenerator<unknown, void, unknown>
Async generator yielding parsed NDJSON chunks

Example

import { Fetch } from 'incur'

const response = await fetch('https://api.example.com/events')

for await (const event of Fetch.parseStreamingResponse(response)) {
  console.log('Event:', event)
  // Each event is a parsed JSON object from an NDJSON line
}

Types

FetchInput

Structured input parsed from curl-style argv.
type FetchInput = {
  body: string | undefined
  headers: Headers
  method: string
  path: string
  query: URLSearchParams
}
body
string | undefined
required
Request body string
headers
Headers
required
Web API Headers object
method
string
required
HTTP method (uppercase)
path
string
required
Request path (starts with /)
query
URLSearchParams
required
Query parameters

FetchOutput

Structured output from a fetch Response.
type FetchOutput = {
  data: unknown
  headers: Headers
  ok: boolean
  status: number
}
data
unknown
required
Parsed response data (JSON object or text string)
headers
Headers
required
Response headers
ok
boolean
required
true for 2xx status codes
status
number
required
HTTP status code

Usage Patterns

Building an HTTP Gateway

import { Cli, Fetch } from 'incur'

const cli = Cli.create({
  name: 'api',
  version: '1.0.0',
  commands: {
    call: Cli.command({
      description: 'Call API endpoint',
      run: async ({ argv }) => {
        const input = Fetch.parseArgv(argv)
        const request = Fetch.buildRequest(input)
        
        // Rewrite URL to actual API
        const url = new URL(request.url)
        url.host = 'api.example.com'
        url.protocol = 'https:'
        
        const response = await fetch(new Request(url, request))
        const output = await Fetch.parseResponse(response)
        
        return output.data
      }
    })
  }
})

Handling Streaming Responses

import { Cli, Fetch } from 'incur'

const cli = Cli.create({
  name: 'stream',
  version: '1.0.0',
  commands: {
    events: Cli.command({
      run: async function* () {
        const response = await fetch('https://api.example.com/events')
        
        if (Fetch.isStreamingResponse(response)) {
          for await (const event of Fetch.parseStreamingResponse(response)) {
            yield event
          }
        }
      }
    })
  }
})

Build docs developers (and LLMs) love