Skip to content

Bharathi4real/safe-fetch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

21 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ›‘οΈ SafeFetch

SafeFetch is a TypeScript-first HTTP client with built-in retry logic, timeout handling, and Next.js App Router support.

✨ Features

  • βš™οΈ Retry logic for safe HTTP methods (GET, PUT)
  • ⏱️ Timeout protection with AbortController
  • 🧾 Full TypeScript support with excellent IntelliSense & JSDoc
  • πŸ”„ Type inference logging for development
  • πŸ” JSON & FormData support
  • 🧠 Next.js App Router compatible - revalidate, cache, tags
  • πŸ” Optional Basic Auth from environment variables
  • πŸ“Š Query parameters with automatic URL encoding
  • 🎯 Consistent error handling with typed responses

βš™οΈ Setup

Environment Variables (Optional)

# .env.local
BASE_URL=https://api.your-domain.com
AUTH_USERNAME=your_username
AUTH_PASSWORD=your_password

Installation

Simply copy the SafeFetch code into your project (e.g., lib/api.ts or utils/safe-fetch.ts).

πŸ“– Usage

Basic Example

import apiRequest from './lib/api';

interface User {
  id: number;
  name: string;
  email: string;
}

// GET request
const result = await apiRequest<User[]>('GET', '/users');
if (result.success) {
  console.log(result.data); // Full TypeScript intellisense
} else {
  console.error(result.error);
}

POST with Data

const newUser = await apiRequest<User>('POST', '/users', {
  data: {
    name: 'John Doe',
    email: 'john@example.com'
  }
});

Advanced Options

const result = await apiRequest<Product[]>('GET', '/products', {
  params: { category: 'electronics', limit: 10 },
  retries: 3,
  timeout: 15000,
  cache: 'force-cache',
  revalidate: 3600,
  tags: ['products']
});

File Upload

const formData = new FormData();
formData.append('file', file);
const result = await apiRequest<{url: string}>('POST', '/upload', {
  data: formData,
  timeout: 60000
});

🧠 TypeScript Support

SafeFetch provides excellent IntelliSense & JSDoc support with:

  • Response type inference - result.data is automatically typed
  • Request body validation - TypeScript validates your data structure
  • Options autocomplete - Full IDE support for configuration options
  • JSDoc documentation - Hover tooltips with parameter descriptions
// TypeScript knows result.data is User[] when success is true
const users = await apiRequest<User[]>('GET', '/users');

πŸ”§ API Reference

apiRequest<ResponseType, RequestType>(method, endpoint, options?)

Options

interface RequestOptions<TBody> {
  data?: TBody;                       // Request body
  params?: Record<string, string | number | boolean | null | undefined>; // Query parameters
  retries?: number;                   // Default: 1
  timeout?: number;                   // Default: 30000ms
  cache?: RequestCache;               // Fetch cache strategy
  revalidate?: number | false;        // Next.js ISR revalidation time
  tags?: string[];                    // Next.js cache tags
  headers?: Record<string, string>;   // Custom headers
  logTypes?: boolean;                 // Log inferred types (dev only)
  transform?<T>(data: T): T;        // Transform response data before returning
  onError?: (error: ApiError, attempt: number) => void; // Custom error handler
  shouldRetry?: (error: ApiError, attempt: number) => boolean; // Custom retry condition
  allowedHosts?: string[];            // Allowed hosts for SSRF protection
  maxResponseSize?: number;           // Maximum response size in bytes
}

Returns

type ApiResponse<T> =
  | { success: true; status: number; data: T; headers: Headers }
  | { success: false; status: number; error: ApiError; data: null };

πŸ—οΈ Next.js Integration

// Server Component
export default async function Page() {
  const products = await apiRequest<Product[]>('GET', '/products', {
    revalidate: 300,
    tags: ['products']
  });

  return <div>{/* render products */}</div>;
}

// Server Action
'use server';
export async function createProduct(formData: FormData) {
  const result = await apiRequest('POST', '/products', {
    data: Object.fromEntries(formData)
  });

  if (result.success) {
    revalidateTag('products');
  }

  return result;
}

πŸ“š Detailed Usage Examples

For comprehensive examples including CRUD operations, authentication, error handling, and advanced patterns, see Examples.

🌍 Browser Compatibility

Works in all modern environments that support:

  • Fetch API
  • AbortController
  • Promises
  • URL constructor

Compatible with:

  • βœ… Next.js 13+ (App Router)
  • βœ… React 18+
  • βœ… Node.js 18+
  • βœ… All modern browsers

πŸ“„ License

This project is licensed under the BSD 3-Clause License. Attribution to Bharathi4real is required. See LICENSE for details.


SafeFetch - Simple, typed, reliable HTTP requests for modern TypeScript applications.

About

A lightweight, fully typed fetch wrapper with built-in retries, timeouts, and Next.js support.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published