Seed CLISeed CLI

HTTP

HTTP client with retry support and OpenAPI typed client.

bun add @seedcli/http

The HTTP module provides a simple fetch-based HTTP client and an OpenAPI-typed client via openapi-fetch.

Simple Requests

// GET
const { data, status } = await seed.http.get<User>('https://api.example.com/users/1')

// POST
const { data } = await seed.http.post<User>('https://api.example.com/users', {
  name: 'Alice',
  email: 'alice@example.com',
})

// PUT
await seed.http.put('https://api.example.com/users/1', { name: 'Alice Updated' })

// PATCH
await seed.http.patch('https://api.example.com/users/1', { name: 'Alice' })

// DELETE
await seed.http.delete('https://api.example.com/users/1')

// HEAD
const { headers } = await seed.http.head('https://api.example.com/health')

Request Options

OptionTypeDescription
headersRecord<string, string>Request headers
paramsRecord<string, string | number>URL query parameters
timeoutnumberTimeout in milliseconds
retrynumber | RetryConfigRetry configuration
signalAbortSignalAbort signal
const { data } = await seed.http.get<SearchResult>('https://api.example.com/search', {
  params: { q: 'seed cli', page: 1 },
  headers: { Authorization: 'Bearer token123' },
  timeout: 5000,
  retry: 3,
})

Response

PropertyTypeDescription
dataTParsed response body
statusnumberHTTP status code
statusTextstringStatus text
headersHeadersResponse headers
okbooleantrue if status is 2xx
rawResponseOriginal fetch Response

Retry Configuration

await seed.http.get('https://api.example.com/data', {
  retry: {
    count: 3,
    delay: 1000,
    backoff: 'exponential',  // 1s, 2s, 4s
    retryOn: [503, 429],     // Only retry these status codes
  },
})
OptionTypeDefaultDescription
countnumberNumber of retries
delaynumber1000Initial delay in ms
backoff'linear' | 'exponential''linear'Backoff strategy
retryOnnumber[][408, 429, 500, 502, 503, 504]Status codes to retry
onRetry(error: Error, attempt: number) => voidCallback on each retry

HTTP Client Factory

Create a preconfigured client for an API:

const api = seed.http.create({
  baseURL: 'https://api.example.com',
  headers: {
    Authorization: `Bearer ${token}`,
    'Content-Type': 'application/json',
  },
  timeout: 10000,
  retry: 2,
})

// All requests use the base config
const { data: users } = await api.get<User[]>('/users')
const { data: user } = await api.post<User>('/users', { name: 'Alice' })

Client Config

OptionTypeDescription
baseURLstringBase URL for all requests
headersRecord<string, string>Default headers
timeoutnumberDefault timeout
retrynumber | RetryConfigDefault retry config
interceptorsobjectRequest/response interceptors

Interceptors

const api = seed.http.create({
  baseURL: 'https://api.example.com',
  interceptors: {
    request: async (url, init) => {
      // Add timestamp to every request
      init.headers = { ...init.headers, 'X-Request-Time': Date.now().toString() }
      return init
    },
    response: async (response) => {
      // Log all responses
      seed.print.debug(`${response.status} ${response.statusText}`)
      return response
    },
  },
})

File Download

Download files with progress tracking:

await seed.http.download('https://example.com/archive.zip', './downloads/archive.zip', {
  onProgress: (progress) => {
    console.log(`${progress.percent}% - ${progress.speed} bytes/s`)
  },
})

Download Options

OptionTypeDescription
headersRecord<string, string>Request headers
onProgress(progress) => voidProgress callback
signalAbortSignalAbort signal

Download Progress

PropertyTypeDescription
percentnumberPercentage complete (0-100)
transferrednumberBytes transferred
totalnumber | nullTotal bytes (null if unknown)
speednumberBytes per second

OpenAPI Typed Client

For APIs with an OpenAPI schema, get full type safety:

import type { paths } from './api-schema'  // Generated from OpenAPI spec

const api = seed.http.createOpenAPIClient<paths>({
  baseUrl: 'https://api.example.com',
  headers: { Authorization: `Bearer ${token}` },
})

// Fully typed request and response
const { data, error } = await api.GET('/users/{id}', {
  params: { path: { id: '123' } },
})

const { data } = await api.POST('/users', {
  body: { name: 'Alice', email: 'alice@example.com' },
})

Generate types from an OpenAPI spec using openapi-typescript:

bunx openapi-typescript https://api.example.com/openapi.json -o src/api-schema.ts

Error Types

import { HttpError, HttpTimeoutError } from '@seedcli/http'
ErrorDescription
HttpErrorNon-2xx response (includes status, statusText, data)
HttpTimeoutErrorRequest exceeded timeout

On this page