Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | 4x 65x 65x 37x 68x 28x 39x 28x 28x 39x 39x 41x 39x 107x 42x 42x 85x 85x 82x 18x 71x 42x 42x 42x 4x 107x | import type { ParamValue, QueryValue } from './types'
type UrlBuilder = (params?: Record<string, ParamValue>, query?: Record<string, QueryValue>, hash?: ParamValue) => string
const PARAM = /\[([^\]]+)\]/
/** Prepares the base URL and path, then returns a URL builder. Does not validate values. */
export function compileUrl(baseUrl: string | undefined, path: string): UrlBuilder {
const base = baseUrl?.endsWith('/') && path.startsWith('/') ? baseUrl.slice(0, -1) : (baseUrl ?? '')
if (!path.includes('[')) {
const url = base + path
return (_params, query, hash) => url + stringifyQuery(query) + stringifyHash(hash)
}
// パスの分割は最初の呼び出しまで遅らせる(ルート定義を軽くするため)。
// [静的, 名前, 静的, 名前, …, 静的]。baseUrl の [ ] は分割しない
let parts: string[] | undefined
return (params, query, hash) => {
if (parts === undefined) {
parts = path.split(PARAM)
parts[0] = base + parts[0]
}
let url = parts[0]
for (let i = 1; i < parts.length; i += 2) {
// encodeURIComponent は値を自分で文字列化する(String() と同じ結果)
url += encodeURIComponent(params?.[parts[i]] as ParamValue) + parts[i + 1]
}
return url + stringifyQuery(query) + stringifyHash(hash)
}
}
function stringifyQuery(query: Record<string, QueryValue> | undefined) {
if (query == null) return ''
const search = new URLSearchParams()
for (const key in query) {
const value = query[key]
if (value === undefined) continue
if (Array.isArray(value)) {
// append は値を自分で文字列化する(String() と同じ結果)
for (const v of value) search.append(key, v as string)
} else {
search.append(key, value as string)
}
}
// キー順を揃えて同じクエリなら同じ URL にする(型の返り値もキー順)。sort は安定なので配列の順は保たれる
search.sort()
const s = search.toString()
// URLSearchParams は空白を + にする。+ という文字自体は %2B になるので置き換えてよい
return s && `?${s.replaceAll('+', '%20')}`
}
const stringifyHash = (hash: ParamValue | undefined) =>
hash === undefined || hash === '' ? '' : `#${encodeURIComponent(hash)}`
|