CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ufo

URL utils for humans with comprehensive parsing, manipulation, encoding, and normalization functions.

Pending
Overview
Eval results
Files

utilities.mddocs/

URL Utilities

Extensive collection of utility functions for URL manipulation including path joining, protocol management, slash handling, base URL operations, and URL comparison. These functions provide the building blocks for complex URL manipulation workflows.

Capabilities

URL Joining & Resolution

Functions for combining URL segments and resolving complex URL structures.

/**
 * Joins multiple URL segments into a single URL
 * @param base - Base URL or path
 * @param input - Additional URL segments to join
 * @returns Combined URL string
 */
function joinURL(base: string, ...input: string[]): string;

/**
 * Joins URL segments with relative path support (./ and ../)
 * @param input - URL segments to join with relative path resolution
 * @returns Resolved URL string
 */
function joinRelativeURL(...input: string[]): string;

/**
 * Resolves multiple URL segments into a single URL with query merging
 * @param base - Base URL (defaults to empty string)
 * @param inputs - URL segments to resolve
 * @returns Resolved URL with merged queries and paths
 */
function resolveURL(base?: string, ...inputs: string[]): string;

Usage Examples:

import { joinURL, joinRelativeURL, resolveURL } from "ufo";

// Basic URL joining
const api = joinURL("https://api.example.com", "v1", "users", "123");
// "https://api.example.com/v1/users/123"

const path = joinURL("/app", "dashboard", "settings");
// "/app/dashboard/settings"

// Relative path resolution
const relative = joinRelativeURL("/app", "../home", "./profile");
// "/home/profile"

const complex = joinRelativeURL("https://example.com/app", "../../api", "./v1/users");
// "https://example.com/api/v1/users"

// URL resolution with query merging
const resolved = resolveURL(
  "https://api.example.com/search?sort=date",
  "users?active=true",
  "profiles#section"
);
// "https://api.example.com/search/users/profiles?sort=date&active=true#section"

Protocol Management

Functions for detecting, adding, removing, and changing URL protocols.

/**
 * Checks if the input has a protocol
 * @param inputString - String to check for protocol
 * @param opts - Options for protocol detection
 * @returns True if protocol is present
 */
function hasProtocol(inputString: string, opts?: HasProtocolOptions): boolean;

/**
 * Adds or replaces protocol of the input URL
 * @param input - URL string
 * @param protocol - Protocol to set (e.g., "https://")
 * @returns URL with specified protocol
 */
function withProtocol(input: string, protocol: string): string;

/**
 * Adds or replaces the URL protocol to https://
 * @param input - URL string
 * @returns URL with https protocol
 */
function withHttps(input: string): string;

/**
 * Adds or replaces the URL protocol to http://
 * @param input - URL string
 * @returns URL with http protocol
 */
function withHttp(input: string): string;

/**
 * Removes the protocol from the input
 * @param input - URL string
 * @returns URL without protocol
 */
function withoutProtocol(input: string): string;

/**
 * Checks for dangerous script protocols
 * @param protocol - Protocol to check
 * @returns True if protocol is potentially dangerous
 */
function isScriptProtocol(protocol?: string): boolean;

interface HasProtocolOptions {
  acceptRelative?: boolean;
  strict?: boolean;
}

Usage Examples:

import { hasProtocol, withHttps, withHttp, withoutProtocol, isScriptProtocol } from "ufo";

// Protocol detection
const hasProto = hasProtocol("https://example.com");
// true

const relative = hasProtocol("//example.com", { acceptRelative: true });
// true

// Protocol manipulation
const secure = withHttps("http://example.com/path");
// "https://example.com/path"

const insecure = withHttp("https://example.com/path");
// "http://example.com/path"

const noProto = withoutProtocol("https://example.com/path");
// "example.com/path"

// Security check
const dangerous = isScriptProtocol("javascript:");
// true

const safe = isScriptProtocol("https:");
// false

Slash Management

Functions for controlling leading and trailing slashes in URLs and paths.

/**
 * Checks if the input has a trailing slash
 * @param input - String to check
 * @param respectQueryAndFragment - Consider query/fragment in check
 * @returns True if trailing slash is present
 */
function hasTrailingSlash(input?: string, respectQueryAndFragment?: boolean): boolean;

/**
 * Removes the trailing slash from URL or pathname
 * @param input - String to process
 * @param respectQueryAndFragment - Respect query/fragment boundaries
 * @returns String without trailing slash
 */
function withoutTrailingSlash(input?: string, respectQueryAndFragment?: boolean): string;

/**
 * Ensures the URL ends with a trailing slash
 * @param input - String to process
 * @param respectQueryAndFragment - Respect query/fragment boundaries
 * @returns String with trailing slash
 */
function withTrailingSlash(input?: string, respectQueryAndFragment?: boolean): string;

/**
 * Checks if the input has a leading slash
 * @param input - String to check
 * @returns True if leading slash is present
 */
function hasLeadingSlash(input?: string): boolean;

/**
 * Removes leading slash from URL or pathname
 * @param input - String to process
 * @returns String without leading slash
 */
function withoutLeadingSlash(input?: string): string;

/**
 * Ensures the URL or pathname has a leading slash
 * @param input - String to process
 * @returns String with leading slash
 */
function withLeadingSlash(input?: string): string;

/**
 * Removes double slashes from the URL
 * @param input - String to clean
 * @returns String without double slashes
 */
function cleanDoubleSlashes(input?: string): string;

Usage Examples:

import { 
  withTrailingSlash, 
  withoutTrailingSlash, 
  withLeadingSlash, 
  withoutLeadingSlash,
  cleanDoubleSlashes 
} from "ufo";

// Trailing slash management
const withSlash = withTrailingSlash("/path");
// "/path/"

const withoutSlash = withoutTrailingSlash("/path/");
// "/path"

// Respecting query parameters
const querySlash = withoutTrailingSlash("/path/?query=true", true);
// "/path?query=true"

// Leading slash management
const leadingSlash = withLeadingSlash("path/to/resource");
// "/path/to/resource"

const noLeadingSlash = withoutLeadingSlash("/path/to/resource");
// "path/to/resource"

// Clean double slashes
const cleaned = cleanDoubleSlashes("//example.com//path//to//resource");
// "//example.com/path/to/resource"

const protocol = cleanDoubleSlashes("http://example.com//api//v1");
// "http://example.com/api/v1"

Base URL Operations

Functions for working with base URLs and relative paths.

/**
 * Ensures the URL or pathname starts with base
 * @param input - URL to modify
 * @param base - Base URL to ensure
 * @returns URL with base prefix
 */
function withBase(input: string, base: string): string;

/**
 * Removes the base from the URL or pathname
 * @param input - URL to modify
 * @param base - Base URL to remove
 * @returns URL without base prefix
 */
function withoutBase(input: string, base: string): string;

/**
 * Checks if a path starts with ./ or ../
 * @param inputString - Path to check
 * @returns True if path is relative
 */
function isRelative(inputString: string): boolean;

Usage Examples:

import { withBase, withoutBase, isRelative } from "ufo";

// Add base to URL
const withBasePath = withBase("/api/users", "/v1");
// "/v1/api/users"

const withBaseUrl = withBase("users/123", "https://api.example.com");
// "https://api.example.com/users/123"

// Remove base from URL
const withoutBasePath = withoutBase("/v1/api/users", "/v1");
// "/api/users"

// Relative path detection
const isRel1 = isRelative("./path/to/file");
// true

const isRel2 = isRelative("../parent/file");
// true

const isRel3 = isRelative("/absolute/path");
// false

Query and Fragment Management

Functions for manipulating query parameters and URL fragments.

/**
 * Add/Replace the query section of the URL
 * @param input - URL string
 * @param query - Query object to merge
 * @returns URL with merged query parameters
 */
function withQuery(input: string, query: QueryObject): string;

/**
 * Filters query parameters based on a predicate function
 * @param input - URL string
 * @param predicate - Function to test each query parameter
 * @returns URL with filtered query parameters
 */
function filterQuery(
  input: string, 
  predicate: (key: string, value: string | string[]) => boolean
): string;

/**
 * Parses and decodes the query object from a URL string
 * @param input - Complete URL string
 * @returns Parsed query object
 */
function getQuery<T extends ParsedQuery = ParsedQuery>(input: string): T;

/**
 * Adds or replaces the fragment section of the URL
 * @param input - URL string
 * @param hash - Fragment/hash to set
 * @returns URL with specified fragment
 */
function withFragment(input: string, hash: string): string;

/**
 * Removes the fragment section from the URL
 * @param input - URL string
 * @returns URL without fragment
 */
function withoutFragment(input: string): string;

/**
 * Removes the host from the URL while preserving everything else
 * @param input - URL string
 * @returns Path with query and fragment only
 */
function withoutHost(input: string): string;

type QueryObject = Record<string, QueryValue | QueryValue[]>;
type QueryValue = string | number | undefined | null | boolean | Array<QueryValue> | Record<string, any>;
type ParsedQuery = Record<string, string | string[]>;

Usage Examples:

import { withQuery, filterQuery, getQuery, withFragment, withoutFragment, withoutHost } from "ufo";

// Add query parameters
const withParams = withQuery("/search", { q: "javascript", limit: 10 });
// "/search?q=javascript&limit=10"

// Merge with existing query
const merged = withQuery("/search?sort=date", { q: "javascript", limit: 10 });
// "/search?sort=date&q=javascript&limit=10"

// Filter query parameters
const filtered = filterQuery("/search?a=1&b=2&c=3", (key) => key !== "b");
// "/search?a=1&c=3"

// Extract query from URL
const query = getQuery("https://api.example.com/search?q=javascript&limit=10&sort=date");
// { q: 'javascript', limit: '10', sort: 'date' }

// Works with relative URLs
const relative = getQuery("/search?category=web&tags=js&tags=api");
// { category: 'web', tags: ['js', 'api'] }

// Fragment management
const withHash = withFragment("/page", "section1");
// "/page#section1"

const noHash = withoutFragment("/page#section1");
// "/page"

// Remove host
const pathOnly = withoutHost("https://example.com/api/users?active=true#list");
// "/api/users?active=true#list"

URL Validation and Comparison

Functions for validating and comparing URLs.

/**
 * Checks if the input URL is empty or just "/"
 * @param url - URL to check
 * @returns True if URL is empty
 */
function isEmptyURL(url: string): boolean;

/**
 * Checks if the input URL is neither empty nor "/"
 * @param url - URL to check
 * @returns True if URL is non-empty
 */
function isNonEmptyURL(url: string): boolean;

/**
 * Check if two paths are equal ignoring trailing slash and encoding
 * @param p1 - First path
 * @param p2 - Second path
 * @returns True if paths are equivalent
 */
function isSamePath(p1: string, p2: string): boolean;

/**
 * Flexible URL comparison with configurable options
 * @param a - First URL
 * @param b - Second URL
 * @param options - Comparison options
 * @returns True if URLs are equivalent under given options
 */
function isEqual(a: string, b: string, options?: CompareURLOptions): boolean;

interface CompareURLOptions {
  trailingSlash?: boolean;
  leadingSlash?: boolean;
  encoding?: boolean;
}

Usage Examples:

import { isEmptyURL, isNonEmptyURL, isSamePath, isEqual } from "ufo";

// URL emptiness checks
const empty1 = isEmptyURL("");
// true

const empty2 = isEmptyURL("/");
// true

const nonEmpty = isNonEmptyURL("/home");
// true

// Path comparison
const samePath = isSamePath("/foo", "/foo/");
// true (ignores trailing slash)

const sameEncoded = isSamePath("/foo bar", "/foo%20bar");
// true (ignores encoding differences)

// Flexible URL comparison
const flexible = isEqual("/foo", "foo");
// true (ignores leading slash by default)

const strict = isEqual("/foo", "foo", { leadingSlash: true });
// false (strict leading slash comparison)

const encodingStrict = isEqual("/foo bar", "/foo%20bar", { encoding: true });
// false (strict encoding comparison)

URL Normalization

Function for normalizing URLs to a consistent format.

/**
 * Normalizes the input URL by ensuring proper encoding and format
 * @param input - URL string to normalize
 * @returns Normalized URL string
 */
function normalizeURL(input: string): string;

Usage Examples:

import { normalizeURL } from "ufo";

// Normalize encoding and format
const normalized = normalizeURL("test?query=123 123#hash, test");
// "test?query=123%20123#hash,%20test"

// Clean up double slashes while preserving protocol
const cleaned = normalizeURL("http://example.com//path//to//resource");
// "http://example.com/path/to/resource"

// Normalize international domains
const international = normalizeURL("https://пример.рф/путь");
// "https://xn--e1afmkfd.xn--p1ai/%D0%BF%D1%83%D1%82%D1%8C"

Install with Tessl CLI

npx tessl i tessl/npm-ufo

docs

encoding.md

index.md

parsing.md

query.md

url-class.md

utilities.md

tile.json