({
base,
to,
trailingSlash = 'never',
cache,
}: ResolvePathOptions)
| 107 | * and supporting relative segments (`.`/`..`) and absolute `to` values. |
| 108 | */ |
| 109 | export function resolvePath({ |
| 110 | base, |
| 111 | to, |
| 112 | trailingSlash = 'never', |
| 113 | cache, |
| 114 | }: ResolvePathOptions) { |
| 115 | const isAbsolute = to.startsWith('/') |
| 116 | const isBase = !isAbsolute && to === '.' |
| 117 | |
| 118 | let key |
| 119 | if (cache) { |
| 120 | // `trailingSlash` is static per router, so it doesn't need to be part of the cache key |
| 121 | key = isAbsolute ? to : isBase ? base : base + '\0' + to |
| 122 | const cached = cache.get(key) |
| 123 | if (cached) return cached |
| 124 | } |
| 125 | |
| 126 | let baseSegments: Array<string> |
| 127 | if (isBase) { |
| 128 | baseSegments = base.split('/') |
| 129 | } else if (isAbsolute) { |
| 130 | baseSegments = to.split('/') |
| 131 | } else { |
| 132 | baseSegments = base.split('/') |
| 133 | while (baseSegments.length > 1 && last(baseSegments) === '') { |
| 134 | baseSegments.pop() |
| 135 | } |
| 136 | |
| 137 | const toSegments = to.split('/') |
| 138 | for (let index = 0, length = toSegments.length; index < length; index++) { |
| 139 | const value = toSegments[index]! |
| 140 | if (value === '') { |
| 141 | if (!index) { |
| 142 | // Leading slash |
| 143 | baseSegments = [value] |
| 144 | } else if (index === length - 1) { |
| 145 | // Trailing Slash |
| 146 | baseSegments.push(value) |
| 147 | } else { |
| 148 | // ignore inter-slashes |
| 149 | } |
| 150 | } else if (value === '..') { |
| 151 | baseSegments.pop() |
| 152 | } else if (value === '.') { |
| 153 | // ignore |
| 154 | } else { |
| 155 | baseSegments.push(value) |
| 156 | } |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | if (baseSegments.length > 1) { |
| 161 | if (last(baseSegments) === '') { |
| 162 | if (trailingSlash === 'never') { |
| 163 | baseSegments.pop() |
| 164 | } |
| 165 | } else if (trailingSlash === 'always') { |
| 166 | baseSegments.push('') |
no test coverage detected