| 222 | * The no cache version of the normalize() function. Used for benchmarking and testing. |
| 223 | */ |
| 224 | export function noCacheNormalize(path: string): Path { |
| 225 | if (path == '' || path == '.') { |
| 226 | return '' as Path; |
| 227 | } else if (path == NormalizedRoot) { |
| 228 | return NormalizedRoot; |
| 229 | } |
| 230 | |
| 231 | // Match absolute windows path. |
| 232 | const original = path; |
| 233 | if (path.match(/^[A-Z]:[/\\]/i)) { |
| 234 | path = '\\' + path[0].toUpperCase() + '\\' + path.slice(3); |
| 235 | } |
| 236 | |
| 237 | // We convert Windows paths as well here. |
| 238 | const p = path.split(/[/\\]/g); |
| 239 | let relative = false; |
| 240 | let i = 1; |
| 241 | |
| 242 | // Special case the first one. |
| 243 | if (p[0] != '') { |
| 244 | p.unshift('.'); |
| 245 | relative = true; |
| 246 | } |
| 247 | |
| 248 | while (i < p.length) { |
| 249 | if (p[i] == '.') { |
| 250 | p.splice(i, 1); |
| 251 | } else if (p[i] == '..') { |
| 252 | if (i < 2 && !relative) { |
| 253 | throw new InvalidPathException(original); |
| 254 | } else if (i >= 2 && p[i - 1] != '..') { |
| 255 | p.splice(i - 1, 2); |
| 256 | i--; |
| 257 | } else { |
| 258 | i++; |
| 259 | } |
| 260 | } else if (p[i] == '') { |
| 261 | p.splice(i, 1); |
| 262 | } else { |
| 263 | i++; |
| 264 | } |
| 265 | } |
| 266 | |
| 267 | if (p.length == 1) { |
| 268 | return p[0] == '' ? NormalizedSep : ('' as Path); |
| 269 | } else { |
| 270 | if (p[0] == '.') { |
| 271 | p.shift(); |
| 272 | } |
| 273 | |
| 274 | return p.join(NormalizedSep) as Path; |
| 275 | } |
| 276 | } |
| 277 | |
| 278 | export const path: TemplateTag<Path> = (strings, ...values) => { |
| 279 | return normalize(String.raw(strings, ...values)); |