UNPKG

@dbs-portal/tool-mock

Version:

API mocking toolkit using MSW for DBS Portal development workflows

227 lines 5.94 kB
/** * URL utilities for mock handlers */ /** * Parse URL parameters from a path pattern */ export function parseUrlParams(url, pattern) { const params = {}; // Convert pattern to regex const regexPattern = pattern .replace(/:[^/]+/g, '([^/]+)') .replace(/\*/g, '(.*)'); const regex = new RegExp(`^${regexPattern}$`); const match = url.match(regex); if (!match) { return params; } // Extract parameter names from pattern const paramNames = pattern.match(/:[^/]+/g) || []; // Map captured groups to parameter names for (let i = 0; i < paramNames.length; i++) { const paramName = paramNames[i]?.substring(1); // Remove ':' if (!paramName) continue; const paramValue = match[i + 1]; if (paramValue !== undefined) { params[paramName] = decodeURIComponent(paramValue); } } return params; } /** * Parse query parameters from URL */ export function parseQueryParams(url) { const urlObj = new URL(url); const params = {}; for (const [key, value] of urlObj.searchParams.entries()) { params[key] = value; } return params; } /** * Check if URL matches a pattern */ export function matchesUrl(url, options) { const { pattern, caseSensitive = false } = options; let urlToMatch = caseSensitive ? url : url.toLowerCase(); if (typeof pattern === 'string') { let patternToMatch = caseSensitive ? pattern : pattern.toLowerCase(); // Convert simple pattern to regex if (pattern.includes(':') || pattern.includes('*')) { const regexPattern = patternToMatch .replace(/:[^/]+/g, '[^/]+') .replace(/\*/g, '.*'); const regex = new RegExp(`^${regexPattern}$`); return regex.test(urlToMatch); } return urlToMatch.includes(patternToMatch); } return pattern.test(url); } /** * Extract path from URL */ export function extractPath(url) { try { const urlObj = new URL(url); return urlObj.pathname; } catch { // If URL is invalid, assume it's already a path return url.split('?')[0] || ''; } } /** * Build URL with parameters */ export function buildUrl(baseUrl, path, params, query) { let url = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl; let finalPath = path.startsWith('/') ? path : `/${path}`; // Replace path parameters if (params) { for (const [key, value] of Object.entries(params)) { finalPath = finalPath.replace(`:${key}`, encodeURIComponent(value)); } } url += finalPath; // Add query parameters if (query && Object.keys(query).length > 0) { const searchParams = new URLSearchParams(); for (const [key, value] of Object.entries(query)) { searchParams.append(key, value); } url += `?${searchParams.toString()}`; } return url; } /** * Normalize URL for comparison */ export function normalizeUrl(url) { try { const urlObj = new URL(url); // Remove trailing slash from pathname if (urlObj.pathname.endsWith('/') && urlObj.pathname.length > 1) { urlObj.pathname = urlObj.pathname.slice(0, -1); } // Sort query parameters const sortedParams = new URLSearchParams(); const params = Array.from(urlObj.searchParams.entries()).sort(); for (const [key, value] of params) { sortedParams.append(key, value); } urlObj.search = sortedParams.toString(); return urlObj.toString(); } catch { return url; } } /** * Check if URL is absolute */ export function isAbsoluteUrl(url) { try { new URL(url); return true; } catch { return false; } } /** * Join URL paths */ export function joinPaths(...paths) { return paths .map((path, index) => { if (index === 0) { return path.replace(/\/+$/, ''); } return path.replace(/^\/+/, '').replace(/\/+$/, ''); }) .filter(Boolean) .join('/'); } /** * Get base URL from full URL */ export function getBaseUrl(url) { try { const urlObj = new URL(url); return `${urlObj.protocol}//${urlObj.host}`; } catch { return ''; } } /** * Parse URL into components */ export function parseUrl(url) { try { const urlObj = new URL(url); return { protocol: urlObj.protocol, host: urlObj.host, hostname: urlObj.hostname, port: urlObj.port, pathname: urlObj.pathname, search: urlObj.search, hash: urlObj.hash, params: parseQueryParams(url), }; } catch { const [pathname, search = ''] = url.split('?'); const [pathOnly, hash = ''] = (pathname || '').split('#'); return { pathname: pathOnly || '', search: search ? `?${search}` : '', hash: hash ? `#${hash}` : '', params: parseQueryParams(url), }; } } /** * Create URL matcher function */ export function createUrlMatcher(patterns) { return (url) => { return patterns.some(pattern => { if (typeof pattern === 'string') { return matchesUrl(url, { pattern }); } return pattern.test(url); }); }; } /** * Validate URL format */ export function isValidUrl(url) { try { new URL(url); return true; } catch { return false; } } /** * Convert relative URL to absolute */ export function toAbsoluteUrl(url, baseUrl) { if (isAbsoluteUrl(url)) { return url; } try { return new URL(url, baseUrl).toString(); } catch { return url; } } //# sourceMappingURL=url.js.map