skills/zap-studio/monorepo/zap-fetch-typed-http

zap-fetch-typed-http

SKILL.md

@zap-studio/fetch — Typed HTTP Client

Setup

import { createFetch } from '@zap-studio/fetch';
import { z } from 'zod';

const UserSchema = z.object({
  id: z.number(),
  name: z.string(),
  email: z.string().email(),
});

const { api } = createFetch({
  baseURL: 'https://api.example.com',
  headers: { Authorization: 'Bearer token' },
  searchParams: { locale: 'en' },
});

const user = await api.get('/users/1', UserSchema);

Core Patterns

Return raw Response when no schema is provided

import { $fetch } from '@zap-studio/fetch';

const response = await $fetch('https://api.example.com/health');
const data = await response.json();

Request validated payload via schema

import { api } from '@zap-studio/fetch';
import { z } from 'zod';

const PostSchema = z.object({ id: z.number(), title: z.string() });
const post = await api.get('https://api.example.com/posts/1', PostSchema);

Handle non-throw validation mode explicitly

import { $fetch } from '@zap-studio/fetch';
import { z } from 'zod';

const UserSchema = z.object({ id: z.number() });

const result = await $fetch('/users/1', UserSchema, {
  throwOnValidationError: false,
});

if (result.issues) {
  throw new Error('Invalid response payload');
}

console.log(result.value.id);

Common Mistakes

HIGH Assuming api.get returns raw Response

Wrong:

const res = await api.get('/users/1', { headers: { Authorization: token } });
const body = await res.json();

Correct:

const user = await api.get('/users/1', UserSchema, {
  headers: { Authorization: token },
});
console.log(user.id);

api.* overloads are schema-based helpers; they return validated payloads, not a Response.

Source: zap-studio/monorepo:packages/fetch/src/index.ts

HIGH Ignoring validation result branch

Wrong:

const user = await $fetch('/users/1', UserSchema, {
  throwOnValidationError: false,
});
console.log(user.id);

Correct:

const result = await $fetch('/users/1', UserSchema, {
  throwOnValidationError: false,
});

if (result.issues) throw new Error('Invalid payload');
console.log(result.value.id);

With throwOnValidationError: false, return type is { value?, issues? } and must be narrowed.

Source: zap-studio/monorepo:packages/fetch/src/index.ts

MEDIUM Relying on implicit body semantics for non-JSON inputs

Wrong:

await api.post('/users', UserSchema, {
  body: new URLSearchParams({ name: 'Ada' }),
});

Correct:

await api.post('/users', UserSchema, {
  body: { name: 'Ada' },
  headers: { 'Content-Type': 'application/json' },
});

Only plain object bodies are auto-JSON-stringified; other BodyInit forms keep their native encoding behavior.

Source: zap-studio/monorepo:packages/fetch/src/utils.ts

See also: zap-validation-standard-schema/SKILL.md — response validation result handling.

Weekly Installs
1
GitHub Stars
155
First Seen
11 days ago
Installed on
amp1
cline1
opencode1
cursor1
kimi-cli1
codex1