A stand-alone types package for Undici HTTP client library
—
Helper functions and utilities for HTTP operations, header manipulation, content processing, and various supporting functionality for Undici operations.
Functions for parsing and manipulating HTTP headers.
namespace util {
/**
* Parse raw headers array into headers object
* @param headers - Raw headers array [name, value, name, value, ...]
* @param obj - Optional object to assign parsed values to
* @returns Parsed headers object
*/
function parseHeaders(
headers: (Buffer | string | (Buffer | string)[])[],
obj?: Record<string, string | string[]>
): Record<string, string | string[]>;
/**
* Convert header name to proper string format and lowercase it
* @param value - Header name buffer or string
* @returns Header name as lowercase string
*/
function headerNameToString(value: string | Buffer): string;
}
/**
* Convert header value to proper string format
* @param value - Header value buffer or string
* @returns Header value as string
*/
function headerValueToString(value: string | Buffer): string;
/**
* Check if header name is valid
* @param name - Header name to validate
* @returns True if valid header name
*/
function isValidHeaderName(name: string): boolean;
/**
* Check if header value is valid
* @param value - Header value to validate
* @returns True if valid header value
*/
function isValidHeaderValue(value: string): boolean;Usage Examples:
import { util } from "undici-types";
// Parse raw headers from HTTP response
const rawHeaders = [
"content-type", "application/json",
"content-length", "1024",
"set-cookie", "session=abc123",
"set-cookie", "theme=dark",
"cache-control", "no-cache"
];
const parsed = util.parseHeaders(rawHeaders);
console.log(parsed);
// {
// "content-type": "application/json",
// "content-length": "1024",
// "set-cookie": ["session=abc123", "theme=dark"],
// "cache-control": "no-cache"
// }
// Convert header names/values from buffers
const headerName = util.headerNameToString(Buffer.from("Content-Type"));
const headerValue = headerValueToString(Buffer.from("application/json"));
// Validate header components
console.log(isValidHeaderName("Content-Type")); // true
console.log(isValidHeaderName("Content\nType")); // false - contains newline
console.log(isValidHeaderValue("application/json")); // true
console.log(isValidHeaderValue("value\r\n")); // false - contains CRLF
// Safe header construction
function setHeader(headers: Record<string, string>, name: string, value: string) {
if (!isValidHeaderName(name)) {
throw new Error(`Invalid header name: ${name}`);
}
if (!isValidHeaderValue(value)) {
throw new Error(`Invalid header value for ${name}: ${value}`);
}
headers[name.toLowerCase()] = value;
}MIME type parsing and manipulation utilities.
/**
* Parse MIME type string into structured format
* @param input - MIME type string to parse
* @returns Parsed MIME type object or 'failure' if invalid
*/
function parseMIMEType(input: string): MIMEType | 'failure';
/**
* Serialize MIME type object back to string
* @param mimeType - MIME type object to serialize
* @returns MIME type string
*/
function serializeAMimeType(mimeType: MIMEType): string;
interface MIMEType {
type: string;
subtype: string;
parameters: Map<string, string>;
essence: string;
}Usage Examples:
import { parseMIMEType, serializeAMimeType } from "undici-types";
// Parse Content-Type header
const contentType = "application/json; charset=utf-8; boundary=something";
const parsed = parseMIMEType(contentType);
if (parsed !== 'failure') {
console.log(parsed.type); // "application"
console.log(parsed.subtype); // "json"
console.log(parsed.essence); // "application/json"
console.log(parsed.parameters.get("charset")); // "utf-8"
console.log(parsed.parameters.get("boundary")); // "something"
}
// Create MIME type programmatically
const mimeType: MIMEType = {
type: "text",
subtype: "html",
essence: "text/html",
parameters: new Map([
["charset", "utf-8"],
["boundary", "----WebKitFormBoundary7MA4YWxkTrZu0gW"]
])
};
const serialized = serializeAMimeType(mimeType);
console.log(serialized); // "text/html; charset=utf-8; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
// Content type validation helper
function isJsonContentType(contentTypeHeader: string): boolean {
const parsed = parseMIMEType(contentTypeHeader);
return parsed !== 'failure' && parsed.essence === "application/json";
}
// Usage in request handling
const response = await fetch("/api/data");
const contentType = response.headers.get("content-type");
if (contentType && isJsonContentType(contentType)) {
const data = await response.json();
console.log("JSON data:", data);
} else {
const text = await response.text();
console.log("Text data:", text);
}Cookie parsing and serialization functions.
/**
* Parse cookie header string into cookie objects
* @param header - Cookie header string
* @returns Array of parsed cookie objects
*/
function parseCookies(header: string): Cookie[];
/**
* Serialize cookie object into Set-Cookie header string
* @param cookie - Cookie object to serialize
* @returns Set-Cookie header string
*/
function serializeCookie(cookie: Cookie): string;
interface Cookie {
name: string;
value: string;
expires?: Date;
maxAge?: number;
domain?: string;
path?: string;
secure?: boolean;
httpOnly?: boolean;
sameSite?: "Strict" | "Lax" | "None";
}Usage Examples:
import { parseCookies, serializeCookie } from "undici-types";
// Parse Cookie header from request
const cookieHeader = "session=abc123; theme=dark; lang=en-US";
const cookies = parseCookies(cookieHeader);
cookies.forEach(cookie => {
console.log(`${cookie.name}: ${cookie.value}`);
});
// session: abc123
// theme: dark
// lang: en-US
// Create and serialize cookies
const sessionCookie: Cookie = {
name: "session",
value: "xyz789",
expires: new Date(Date.now() + 86400000), // 24 hours
path: "/",
secure: true,
httpOnly: true,
sameSite: "Strict"
};
const cookieString = serializeCookie(sessionCookie);
console.log(cookieString);
// "session=xyz789; Expires=...; Path=/; Secure; HttpOnly; SameSite=Strict"
// Cookie management helper
class CookieManager {
private cookies = new Map<string, Cookie>();
setCookie(cookie: Cookie) {
this.cookies.set(cookie.name, cookie);
}
getCookie(name: string): Cookie | undefined {
return this.cookies.get(name);
}
getSetCookieHeaders(): string[] {
return Array.from(this.cookies.values()).map(serializeCookie);
}
parseCookieHeader(header: string) {
const cookies = parseCookies(header);
cookies.forEach(cookie => this.cookies.set(cookie.name, cookie));
}
}
// Usage
const manager = new CookieManager();
manager.setCookie({
name: "auth_token",
value: "bearer_token_here",
maxAge: 3600,
secure: true,
httpOnly: true
});
const headers = manager.getSetCookieHeaders();
// Use headers in responseURL manipulation and query string processing utilities.
/**
* Build query string from parameters object
* @param params - Parameters object
* @returns Query string
*/
function buildQueryString(params: Record<string, any>): string;
/**
* Parse query string into parameters object
* @param query - Query string to parse
* @returns Parameters object
*/
function parseQueryString(query: string): Record<string, string | string[]>;
/**
* Resolve relative URL against base URL
* @param base - Base URL
* @param relative - Relative URL
* @returns Resolved absolute URL
*/
function resolveURL(base: string | URL, relative: string): string;
/**
* Normalize URL by removing redundant components
* @param url - URL to normalize
* @returns Normalized URL
*/
function normalizeURL(url: string | URL): string;Usage Examples:
import {
buildQueryString,
parseQueryString,
resolveURL,
normalizeURL
} from "undici-types";
// Build query strings
const params = {
q: "search term",
page: 2,
filters: ["active", "recent"],
sort: "date"
};
const queryString = buildQueryString(params);
console.log(queryString); // "q=search%20term&page=2&filters=active&filters=recent&sort=date"
// Parse query strings
const parsed = parseQueryString("q=hello&page=1&tags=js&tags=web");
console.log(parsed);
// {
// q: "hello",
// page: "1",
// tags: ["js", "web"]
// }
// URL resolution
const baseURL = "https://api.example.com/v1/";
const resolved = resolveURL(baseURL, "../v2/users");
console.log(resolved); // "https://api.example.com/v2/users"
// URL normalization
const normalized = normalizeURL("https://example.com:443/api//users/../posts/./123");
console.log(normalized); // "https://example.com/api/posts/123"
// Request helper with query building
async function apiRequest(endpoint: string, params?: Record<string, any>) {
let url = `https://api.example.com${endpoint}`;
if (params) {
const queryString = buildQueryString(params);
url += `?${queryString}`;
}
return fetch(url);
}
// Usage
const response = await apiRequest("/users", {
page: 1,
limit: 20,
active: true
});Utilities for working with Node.js streams and web streams.
/**
* Convert Node.js Readable to web ReadableStream
* @param nodeStream - Node.js readable stream
* @returns Web ReadableStream
*/
function nodeStreamToWebStream(nodeStream: NodeJS.ReadableStream): ReadableStream<Uint8Array>;
/**
* Convert web ReadableStream to Node.js Readable
* @param webStream - Web ReadableStream
* @returns Node.js Readable stream
*/
function webStreamToNodeStream(webStream: ReadableStream<Uint8Array>): NodeJS.ReadableStream;
/**
* Create readable stream from async iterator
* @param iterator - Async iterator
* @returns Readable stream
*/
function iteratorToStream<T>(iterator: AsyncIterable<T>): ReadableStream<T>;
/**
* Collect all chunks from a stream into buffer
* @param stream - Stream to collect from
* @returns Buffer with all data
*/
function collectStream(stream: NodeJS.ReadableStream): Promise<Buffer>;Usage Examples:
import {
nodeStreamToWebStream,
webStreamToNodeStream,
iteratorToStream,
collectStream
} from "undici-types";
import { createReadStream, createWriteStream } from "fs";
// Convert between stream types
const fileStream = createReadStream("./data.txt");
const webStream = nodeStreamToWebStream(fileStream);
// Use web stream with fetch
const response = await fetch("https://api.example.com/upload", {
method: "POST",
body: webStream,
duplex: "half"
});
// Convert web stream back to Node.js stream
const responseWebStream = response.body;
if (responseWebStream) {
const nodeStream = webStreamToNodeStream(responseWebStream);
nodeStream.pipe(createWriteStream("./response.txt"));
}
// Create stream from async generator
async function* generateData() {
for (let i = 0; i < 1000; i++) {
yield new TextEncoder().encode(`data chunk ${i}\n`);
await new Promise(resolve => setTimeout(resolve, 10));
}
}
const generatedStream = iteratorToStream(generateData());
// Collect stream data
const nodeReadStream = createReadStream("./small-file.txt");
const buffer = await collectStream(nodeReadStream);
console.log("File contents:", buffer.toString());
// Stream transformation pipeline
const transformedStream = nodeStreamToWebStream(createReadStream("./input.json"))
.pipeThrough(new TransformStream({
transform(chunk, controller) {
// Process each chunk
const text = new TextDecoder().decode(chunk);
const processed = text.toUpperCase();
controller.enqueue(new TextEncoder().encode(processed));
}
}));
// Send transformed stream in request
await fetch("https://api.example.com/process", {
method: "POST",
body: transformedStream,
duplex: "half"
});Text and binary encoding/decoding utilities.
/**
* Encode string to UTF-8 bytes
* @param text - String to encode
* @returns UTF-8 byte array
*/
function encodeUTF8(text: string): Uint8Array;
/**
* Decode UTF-8 bytes to string
* @param bytes - UTF-8 byte array
* @returns Decoded string
*/
function decodeUTF8(bytes: Uint8Array): string;
/**
* Encode string to base64
* @param text - String to encode
* @returns Base64 encoded string
*/
function encodeBase64(text: string): string;
/**
* Decode base64 string
* @param base64 - Base64 string to decode
* @returns Decoded string
*/
function decodeBase64(base64: string): string;
/**
* URL-safe base64 encoding
* @param text - String to encode
* @returns URL-safe base64 string
*/
function encodeBase64URL(text: string): string;
/**
* URL-safe base64 decoding
* @param base64url - URL-safe base64 string
* @returns Decoded string
*/
function decodeBase64URL(base64url: string): string;Usage Examples:
import {
encodeUTF8,
decodeUTF8,
encodeBase64,
decodeBase64,
encodeBase64URL,
decodeBase64URL
} from "undici-types";
// UTF-8 encoding/decoding
const text = "Hello, 世界! 🌍";
const utf8Bytes = encodeUTF8(text);
console.log(utf8Bytes); // Uint8Array with UTF-8 bytes
const decoded = decodeUTF8(utf8Bytes);
console.log(decoded); // "Hello, 世界! 🌍"
// Base64 encoding/decoding
const message = "Secret message";
const base64 = encodeBase64(message);
console.log(base64); // "U2VjcmV0IG1lc3NhZ2U="
const original = decodeBase64(base64);
console.log(original); // "Secret message"
// URL-safe base64 (useful for tokens, IDs)
const token = "user:1234/session=active";
const urlSafeToken = encodeBase64URL(token);
console.log(urlSafeToken); // "dXNlcjoxMjM0L3Nlc3Npb249YWN0aXZl" (no +/= chars)
const originalToken = decodeBase64URL(urlSafeToken);
console.log(originalToken); // "user:1234/session=active"
// Authorization header helper
function createBasicAuth(username: string, password: string): string {
const credentials = `${username}:${password}`;
const encoded = encodeBase64(credentials);
return `Basic ${encoded}`;
}
// JWT token parsing helper (decode payload only, no verification)
function parseJWTPayload(token: string): any {
const [, payload] = token.split(".");
const decoded = decodeBase64URL(payload);
return JSON.parse(decoded);
}
// Usage
const authHeader = createBasicAuth("user", "pass123");
console.log(authHeader); // "Basic dXNlcjpwYXNzMTIz"
const jwtToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
const payload = parseJWTPayload(jwtToken);
console.log(payload); // { sub: "1234567890", name: "John Doe", iat: 1516239022 }Common validation functions for HTTP-related data.
/**
* Check if string is valid URL
* @param url - String to validate
* @returns True if valid URL
*/
function isValidURL(url: string): boolean;
/**
* Check if string is valid HTTP method
* @param method - String to validate
* @returns True if valid HTTP method
*/
function isValidHTTPMethod(method: string): boolean;
/**
* Check if number is valid HTTP status code
* @param status - Number to validate
* @returns True if valid status code
*/
function isValidStatusCode(status: number): boolean;
/**
* Check if string contains only ASCII characters
* @param text - String to validate
* @returns True if ASCII only
*/
function isASCII(text: string): boolean;
/**
* Sanitize header value by removing invalid characters
* @param value - Header value to sanitize
* @returns Sanitized header value
*/
function sanitizeHeaderValue(value: string): string;Usage Examples:
import {
isValidURL,
isValidHTTPMethod,
isValidStatusCode,
isASCII,
sanitizeHeaderValue
} from "undici-types";
// URL validation
console.log(isValidURL("https://example.com")); // true
console.log(isValidURL("not-a-url")); // false
console.log(isValidURL("ftp://files.example.com")); // true
// HTTP method validation
console.log(isValidHTTPMethod("GET")); // true
console.log(isValidHTTPMethod("PATCH")); // true
console.log(isValidHTTPMethod("INVALID")); // false
// Status code validation
console.log(isValidStatusCode(200)); // true
console.log(isValidStatusCode(404)); // true
console.log(isValidStatusCode(999)); // false
// ASCII validation
console.log(isASCII("Hello World")); // true
console.log(isASCII("Hello 世界")); // false
// Header sanitization
const unsafeValue = "value\r\nInjected-Header: malicious";
const safeValue = sanitizeHeaderValue(unsafeValue);
console.log(safeValue); // "value Injected-Header: malicious" (CRLF removed)
// Request builder with validation
function buildRequest(url: string, method: string, headers: Record<string, string>) {
if (!isValidURL(url)) {
throw new Error(`Invalid URL: ${url}`);
}
if (!isValidHTTPMethod(method)) {
throw new Error(`Invalid HTTP method: ${method}`);
}
// Sanitize all header values
const sanitizedHeaders: Record<string, string> = {};
for (const [name, value] of Object.entries(headers)) {
if (!isValidHeaderName(name)) {
throw new Error(`Invalid header name: ${name}`);
}
sanitizedHeaders[name] = sanitizeHeaderValue(value);
}
return {
url,
method: method.toUpperCase(),
headers: sanitizedHeaders
};
}
// Usage
const request = buildRequest("https://api.example.com/users", "post", {
"Content-Type": "application/json",
"User-Agent": "MyApp/1.0\r\nX-Injected: hack" // Will be sanitized
});Install with Tessl CLI
npx tessl i tessl/npm-undici-types