* @param {string} path * @returns {string}
(path)
| 348 | * @returns {string} |
| 349 | */ |
| 350 | normalize(path) { |
| 351 | validateString(path, 'path'); |
| 352 | const len = path.length; |
| 353 | if (len === 0) |
| 354 | return '.'; |
| 355 | let rootEnd = 0; |
| 356 | let device; |
| 357 | let isAbsolute = false; |
| 358 | const code = StringPrototypeCharCodeAt(path, 0); |
| 359 | |
| 360 | // Try to match a root |
| 361 | if (len === 1) { |
| 362 | // `path` contains just a single char, exit early to avoid |
| 363 | // unnecessary work |
| 364 | return isPosixPathSeparator(code) ? '\\' : path; |
| 365 | } |
| 366 | if (isPathSeparator(code)) { |
| 367 | // Possible UNC root |
| 368 | |
| 369 | // If we started with a separator, we know we at least have an absolute |
| 370 | // path of some kind (UNC or otherwise) |
| 371 | isAbsolute = true; |
| 372 | |
| 373 | if (isPathSeparator(StringPrototypeCharCodeAt(path, 1))) { |
| 374 | // Matched double path separator at beginning |
| 375 | let j = 2; |
| 376 | let last = j; |
| 377 | // Match 1 or more non-path separators |
| 378 | while (j < len && |
| 379 | !isPathSeparator(StringPrototypeCharCodeAt(path, j))) { |
| 380 | j++; |
| 381 | } |
| 382 | if (j < len && j !== last) { |
| 383 | const firstPart = StringPrototypeSlice(path, last, j); |
| 384 | // Matched! |
| 385 | last = j; |
| 386 | // Match 1 or more path separators |
| 387 | while (j < len && |
| 388 | isPathSeparator(StringPrototypeCharCodeAt(path, j))) { |
| 389 | j++; |
| 390 | } |
| 391 | if (j < len && j !== last) { |
| 392 | // Matched! |
| 393 | last = j; |
| 394 | // Match 1 or more non-path separators |
| 395 | while (j < len && |
| 396 | !isPathSeparator(StringPrototypeCharCodeAt(path, j))) { |
| 397 | j++; |
| 398 | } |
| 399 | if (j === len || j !== last) { |
| 400 | if (firstPart === '.' || firstPart === '?') { |
| 401 | // We matched a device root (e.g. \\\\.\\PHYSICALDRIVE0) |
| 402 | device = `\\\\${firstPart}`; |
| 403 | rootEnd = 4; |
| 404 | const colonIndex = StringPrototypeIndexOf(path, ':'); |
| 405 | // Special case: handle \\?\COM1: or similar reserved device paths |
| 406 | const possibleDevice = StringPrototypeSlice(path, 4, colonIndex + 1); |
| 407 | if (isWindowsReservedName(possibleDevice, possibleDevice.length - 1)) { |
no test coverage detected
searching dependent graphs…