(input: string, query?: QueryObject)
| 62 | * Returns the URL with the given query parameters. If a query parameter is undefined, it is omitted. |
| 63 | */ |
| 64 | export function withQuery(input: string, query?: QueryObject): string { |
| 65 | if (!query || Object.keys(query).length === 0) { |
| 66 | return input; |
| 67 | } |
| 68 | |
| 69 | const searchIndex = input.indexOf("?"); |
| 70 | |
| 71 | if (searchIndex === -1) { |
| 72 | const normalizedQuery = Object.entries(query) |
| 73 | .filter(([, value]) => value !== undefined) |
| 74 | .flatMap(([key, value]) => { |
| 75 | if (Array.isArray(value)) { |
| 76 | return value.map((item) => [key, normalizeQueryValue(item)]); |
| 77 | } |
| 78 | |
| 79 | return [[key, normalizeQueryValue(value)]]; |
| 80 | }); |
| 81 | const searchParams = new URLSearchParams(normalizedQuery); |
| 82 | const queryString = searchParams.toString(); |
| 83 | return queryString ? `${input}?${queryString}` : input; |
| 84 | } |
| 85 | |
| 86 | const searchParams = new URLSearchParams(input.slice(searchIndex + 1)); |
| 87 | const base = input.slice(0, searchIndex); |
| 88 | |
| 89 | for (const [key, value] of Object.entries(query)) { |
| 90 | if (value === undefined) { |
| 91 | searchParams.delete(key); |
| 92 | } else if (Array.isArray(value)) { |
| 93 | for (const item of value) { |
| 94 | searchParams.append(key, normalizeQueryValue(item)); |
| 95 | } |
| 96 | } else { |
| 97 | searchParams.set(key, normalizeQueryValue(value)); |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | const queryString = searchParams.toString(); |
| 102 | return queryString ? `${base}?${queryString}` : base; |
| 103 | } |
| 104 | |
| 105 | function normalizeQueryValue(value: QueryValue): string { |
| 106 | if (value === null) { |
no test coverage detected
searching dependent graphs…