80 lines
2.3 KiB
TypeScript
80 lines
2.3 KiB
TypeScript
/**
|
|
* Build query string from URL parameters
|
|
*
|
|
* Generic, type-safe function to build properly encoded query strings
|
|
* from URL parameters. Supports primitives, arrays, and optional values.
|
|
*
|
|
* @param params - Object containing query parameters
|
|
* @returns Encoded query string (empty string if no parameters)
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* buildQueryString({ category: 'serif', subsets: ['latin', 'latin-ext'] })
|
|
* // Returns: "category=serif&subsets=latin&subsets=latin-ext"
|
|
*
|
|
* buildQueryString({ limit: 50, page: 1 })
|
|
* // Returns: "limit=50&page=1"
|
|
*
|
|
* buildQueryString({})
|
|
* // Returns: ""
|
|
*
|
|
* buildQueryString({ search: 'hello world', active: true })
|
|
* // Returns: "search=hello%20world&active=true"
|
|
* ```
|
|
*/
|
|
|
|
/**
|
|
* Query parameter value type
|
|
* Supports primitives, arrays, and excludes null/undefined
|
|
*/
|
|
export type QueryParamValue = string | number | boolean | string[] | number[];
|
|
|
|
/**
|
|
* Query parameters object
|
|
*/
|
|
export type QueryParams = Record<string, QueryParamValue | undefined | null>;
|
|
|
|
/**
|
|
* Build query string from URL parameters
|
|
*
|
|
* Handles:
|
|
* - Primitive values (string, number, boolean)
|
|
* - Arrays (multiple values with same key)
|
|
* - Optional values (excludes undefined/null)
|
|
* - Proper URL encoding
|
|
*
|
|
* Edge cases:
|
|
* - Empty object → empty string
|
|
* - No parameters → empty string
|
|
* - Nested objects → flattens to string representation
|
|
* - Special characters → proper encoding
|
|
*
|
|
* @param params - Object containing query parameters
|
|
* @returns Encoded query string (with "?" prefix if non-empty)
|
|
*/
|
|
export function buildQueryString(params: QueryParams): string {
|
|
const searchParams = new URLSearchParams();
|
|
|
|
for (const [key, value] of Object.entries(params)) {
|
|
// Skip undefined/null values
|
|
if (value === undefined || value === null) {
|
|
continue;
|
|
}
|
|
|
|
// Handle arrays (multiple values with same key)
|
|
if (Array.isArray(value)) {
|
|
for (const item of value) {
|
|
if (item !== undefined && item !== null) {
|
|
searchParams.append(key, String(item));
|
|
}
|
|
}
|
|
} else {
|
|
// Handle primitives
|
|
searchParams.append(key, String(value));
|
|
}
|
|
}
|
|
|
|
const queryString = searchParams.toString();
|
|
return queryString ? `?${queryString}` : '';
|
|
}
|