Skip to content

Tutitoos/util-http

Repository files navigation

util-http

util-http es un módulo de utilidades para realizar solicitudes HTTP con diversas opciones y clientes.



ADVERTENCIA: Asegúrate de configurar correctamente las opciones del cliente antes de realizar solicitudes.

Indice


Instalacion

npm install util-http
# o
pnpm add util-http

Clientes disponibles

Cliente Descripcion
AxiosClient Basado en axios
FetchClient Basado en la Fetch API nativa
UndiciClient Basado en undici (alto rendimiento)
SuperAgentClient Basado en superagent (isomorphic: Node.js + browser)
HttpClient Agrupador que expone los cuatro clientes y utilidades estaticas

Configuracion del cliente — ClientConfig

Se pasa al constructor de cada cliente para establecer valores por defecto que se aplican a todas las solicitudes.

interface ClientConfig {
  baseURL?: string;
  timeout?: number;
  headers?: Record<string, string>;
  contentTypes?: Record<string, "json" | "urlencoded" | "formData" | "text" | "buffer">;
  onError?: (error: CustomError) => CustomError;
}
Opcion Tipo Descripcion
baseURL string URL base que se antepone a todas las rutas relativas
timeout number Tiempo de espera en ms (por defecto 15000)
headers Record<string, string> Cabeceras globales para todas las solicitudes
contentTypes Record<string, ContentTypeHandlerKey> Extiende el mapa de Content-Type para parsear respuestas personalizadas
onError (error: CustomError) => CustomError Hook que intercepta y transforma el error antes de lanzarlo
import { AxiosClient } from "util-http";

const client = new AxiosClient({
  baseURL: "https://api.example.com",
  timeout: 5000,
  headers: { Authorization: "Bearer token" },
  onError: (err) => {
    console.error("Request failed:", err.message);
    return err;
  }
});

Opciones por solicitud — ClientOptions

Se pasan a cada llamada individual y tienen prioridad sobre la configuracion del cliente.

interface ClientOptions {
  url: string;
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
  headers?: Record<string, string>;
  data?: string | FormData | URLSearchParams | Record<string, unknown>;
  params?: Record<string, string | number | boolean>;
  timeout?: number;
  responseType?: "json" | "urlencoded" | "formData" | "text" | "buffer";
}
Opcion Tipo Descripcion
url string URL de la solicitud (absoluta o relativa si hay baseURL)
method Method Metodo HTTP
headers Record<string, string> Cabeceras adicionales (se mezclan con las globales; estas tienen prioridad)
data varios Cuerpo. FormData y URLSearchParams se envian tal cual; los objetos se serializan como JSON
params Record<string, string | number | boolean> Parametros de query string que se adjuntan a la URL
timeout number Sobreescribe el timeout del cliente para esta solicitud
responseType ContentTypeHandlerKey Fuerza un parser concreto independientemente del Content-Type de la respuesta

Manejo de errores — CustomError

Todos los clientes lanzan instancias de CustomError en caso de fallo.

import { CustomError } from "util-http";

client.get({ url: "/users" }).catch((err: CustomError) => {
  console.log(err.message);    // mensaje de error
  console.log(err.statusCode); // codigo HTTP (ej. 404, 503)
  console.log(err.client);     // "axios" | "fetch" | "undici"
  console.log(err.timestamp);  // ISO string del momento del error
  console.log(err.extra);      // datos adicionales de la respuesta
  console.log(err.toJSON());   // representacion completa como objeto plano
  err.log();                   // imprime el error formateado en consola
});

Mapeos automaticos:

Condicion statusCode message
ECONNREFUSED o respuesta HTML 503 "Unavailable Service"
ENOTFOUND o mensaje vacio 404 "Resource Not Found"
Resto de errores el del servidor el del servidor

AxiosClient

Cliente basado en axios. Soporta todos los formatos de respuesta de axios incluido arraybuffer.

Metodos

client.get<T>(options)
client.post<T>(options)
client.put<T>(options)
client.patch<T>(options)
client.delete<T>(options)
client.head(options)         // devuelve Record<string, string> con las cabeceras
client.options<T>(options)
client.request<T>(options)  // incluye "method" en las opciones

Ejemplo

import { AxiosClient } from "util-http";

const client = new AxiosClient({
  baseURL: "https://api.example.com",
  headers: { Authorization: "Bearer token" }
});

// GET con parametros de query
const users = await client.get<User[]>({
  url: "/users",
  params: { page: 1, limit: 20 }
});

// POST con cuerpo JSON
const user = await client.post<User>({
  url: "/users",
  data: { name: "Alice", email: "alice@example.com" }
});

// GET de un archivo binario
const file = await client.get<ArrayBuffer>({
  url: "/files/report.pdf",
  responseType: "buffer"
});

// Usando request() directamente
const result = await client.request<User>({ url: "/users/1", method: "GET" });

FetchClient

Cliente basado en la Fetch API nativa. Usa AbortSignal.timeout() para el control de tiempo de espera.

Metodos

client.get<T>(options)
client.post<T>(options)
client.put<T>(options)
client.patch<T>(options)
client.delete<T>(options)
client.request<T>(options)

Ejemplo

import { FetchClient } from "util-http";

const client = new FetchClient({
  baseURL: "https://api.example.com",
  timeout: 8000,
  contentTypes: { "application/vnd.api+json": "json" } // Content-Types personalizados
});

// Subir un fichero con FormData (no se serializa como JSON)
const formData = new FormData();
formData.append("avatar", file);
await client.post({ url: "/users/1/avatar", data: formData });

// Forzar lectura como texto independientemente del Content-Type
const html = await client.get<string>({
  url: "/page",
  responseType: "text"
});

UndiciClient

Cliente basado en undici, el cliente HTTP de alto rendimiento de Node.js. Usa bodyTimeout y headersTimeout para el control de tiempo de espera.

Metodos

client.get<T>(options)
client.post<T>(options)
client.put<T>(options)
client.patch<T>(options)
client.delete<T>(options)
client.request<T>(options)

Ejemplo

import { UndiciClient } from "util-http";

const client = new UndiciClient({
  baseURL: "https://api.example.com",
  timeout: 10000
});

// POST con URLSearchParams (se convierte a string automaticamente)
const params = new URLSearchParams({ grant_type: "client_credentials" });
const token = await client.post<TokenResponse>({
  url: "/oauth/token",
  data: params
});

// GET con query string
const results = await client.get<SearchResult[]>({
  url: "/search",
  params: { q: "typescript", sort: "stars" }
});

SuperAgentClient

Cliente basado en superagent. Funciona tanto en Node.js como en el browser (isomorphic), lo que lo hace util para librerias universales.

Metodos

client.get<T>(options)
client.post<T>(options)
client.put<T>(options)
client.patch<T>(options)
client.delete<T>(options)
client.request<T>(options)

Ejemplo

import { SuperAgentClient } from "util-http";

const client = new SuperAgentClient({
  baseURL: "https://api.example.com",
  timeout: 5000,
  headers: { Authorization: "Bearer token" }
});

// GET con parametros de query
const users = await client.get<User[]>({
  url: "/users",
  params: { page: 1, active: true }
});

// POST con cuerpo JSON
const user = await client.post<User>({
  url: "/users",
  data: { name: "Alice", email: "alice@example.com" }
});

// POST con FormData (los campos se envian via .field())
const formData = new FormData();
formData.append("avatar", file);
await client.post({ url: "/users/1/avatar", data: formData });

// GET de un archivo binario
const file = await client.get<ArrayBuffer>({
  url: "/files/report.pdf",
  responseType: "buffer"
});

HttpClient

Agrupador que instancia los cuatro clientes con la misma configuracion. Tambien expone utilidades estaticas para construir URLs y parsear respuestas.

Uso como agrupador

import { HttpClient } from "util-http";

// Con configuracion compartida para los tres clientes
const http = new HttpClient({
  baseURL: "https://api.example.com",
  timeout: 5000
});

await http.axios.get({ url: "/users" });
await http.fetch.post({ url: "/users", data: { name: "Bob" } });
await http.undici.get({ url: "/health" });
await http.superagent.get({ url: "/status" });

// Instancia singleton (sin configuracion)
const singleton = HttpClient.getInstance();

Utilidades estaticas

// Construye una URL completa concatenando baseURL y path
HttpClient.buildUrl("https://api.example.com", "/users");
// => "https://api.example.com/users"

// Construye URL con query string a partir de un objeto
HttpClient.buildUrlWithParams("https://api.example.com", "/search", { q: "ts", page: 1 });
// => "https://api.example.com/search?q=ts&page=1"

// Crea un mapa de handlers para parsear el body de la respuesta
const handlers = HttpClient.createContentHandlers();
// handlers.json(body)   => body.json()
// handlers.text(body)   => body.text()
// handlers.buffer(body) => body.arrayBuffer()

// Normaliza cualquier error a una instancia de CustomError
const err = HttpClient.handleErrors(rawError, 500, "fetch");

TypeScript

Todos los tipos publicos se pueden importar directamente:

import type { ClientConfig, ClientOptions, ContentTypeHandlerKey, Client, Method } from "util-http";
import { CustomError, Constants } from "util-http";

ContentTypeHandlerKey

type ContentTypeHandlerKey = "json" | "urlencoded" | "formData" | "text" | "buffer";

Constants.contentTypes

Mapa completo de tipos MIME a ContentTypeHandlerKey incluido por defecto:

import { Constants } from "util-http";

console.log(Constants.contentTypes["application/json"]);         // "json"
console.log(Constants.contentTypes["multipart/form-data"]);      // "formData"
console.log(Constants.contentTypes["application/octet-stream"]); // "buffer"

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors