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
Repository
zap-studio/monorepoGitHub Stars
155
First Seen
11 days ago
Security Audits
Installed on
amp1
cline1
opencode1
cursor1
kimi-cli1
codex1