Packages

@prood/api-client

Typed OpenAPI fetch client for the Commerce API.

@prood/api-client provides a type-safe HTTP client generated from the Commerce API OpenAPI specification.

Installation

@prood/api-client isn't published to npm yet. Available from the source repo for now: in this monorepo, depend on it with "@prood/api-client": "workspace:*".

Basic usage

ts
import { createCommerceApiClient } from '@prood/api-client'

const api = createCommerceApiClient({
  baseUrl: process.env.COMMERCE_API_URL!, // http://localhost:3005/v1
})

// List products
const { data, error } = await api.GET('/products', {
  params: { query: { query: 'shirt', perPage: 10 } },
})

// Get product by ID
const { data: product } = await api.GET('/products/{id}', {
  params: { path: { id: 'prod_abc' } },
})

With authentication

ts
const api = createCommerceApiClient({
  baseUrl: COMMERCE_API_URL,
  cookie: (await headers()).get('cookie') ?? '',
})

Store host (storefront)

The client sends host as the x-storefront-host header.

ts
const api = createCommerceApiClient({
  baseUrl: COMMERCE_API_URL,
  cookie: (await headers()).get('cookie') ?? '',
  host: (await headers()).get('host') ?? '',
})

API key

ts
const api = createCommerceApiClient({
  baseUrl: COMMERCE_API_URL,
  apiKey: 'pkAbC123...',
})

Agent Auth Bearer token

ts
const api = createCommerceApiClient({
  baseUrl: COMMERCE_API_URL,
  bearerToken: agentJwt,
})

Admin operations

ts
// Create product
await api.POST('/admin/products', { body: createProductInput })

// List orders
const { data: orders } = await api.GET('/admin/orders')

// Fulfill order
await api.POST('/admin/orders/{id}/fulfill', {
  params: { path: { id: orderId } },
  body: { trackingNumber: 'TRK123' },
})

// Dashboard stats
const { data: stats } = await api.GET('/admin/dashboard')

Cart operations

ts
// Create cart
const { data: cart } = await api.POST('/carts')

// Add item
await api.POST('/carts/{id}/items', {
  params: { path: { id: cart.id } },
  body: { productId, variantId, quantity: 1 },
})

// Place order
const { data: order } = await api.POST('/carts/{id}/place-order', {
  params: { path: { id: cart.id } },
})

Type safety

The client is generated from OpenAPI and provides full TypeScript inference:

ts
import type { paths } from '@prood/api-client'

// paths['/products']['get']['parameters']['query'] is typed
// paths['/admin/products']['post']['requestBody'] is typed

Regenerate types when the API spec changes:

zsh
pnpm --filter @prood/api-client codegen
pnpm --filter @prood/api-client codegen:check

Error handling

ts
const { data, error, response } = await api.GET('/products/{id}', {
  params: { path: { id: 'nonexistent' } },
})

if (error) {
  console.log(error.code)    // 'NOT_FOUND'
  console.log(response.status) // 404
}