* Split path into components (OS-aware)
(filePath: string)
| 66 | * Split path into components (OS-aware) |
| 67 | */ |
| 68 | static parse(filePath: string): PathComponents { |
| 69 | if (!filePath || typeof filePath !== "string") { |
| 70 | return { root: "", segments: [], basename: filePath }; |
| 71 | } |
| 72 | |
| 73 | const original = filePath; |
| 74 | let root = ""; |
| 75 | let dir = ""; |
| 76 | let base = ""; |
| 77 | |
| 78 | // Determine basename and directory |
| 79 | const lastSlash = isWindowsPlatform() |
| 80 | ? Math.max(original.lastIndexOf("/"), original.lastIndexOf("\\")) |
| 81 | : original.lastIndexOf("/"); |
| 82 | if (lastSlash === -1) { |
| 83 | base = original; |
| 84 | dir = ""; |
| 85 | } else { |
| 86 | base = original.slice(lastSlash + 1); |
| 87 | dir = original.slice(0, lastSlash); |
| 88 | } |
| 89 | |
| 90 | // Determine root |
| 91 | if (isWindowsPlatform()) { |
| 92 | const driveMatch = /^[A-Za-z]:[\\/]/.exec(original); |
| 93 | if (driveMatch) { |
| 94 | root = driveMatch[0]; |
| 95 | // Ensure dir does not include root |
| 96 | if (dir.startsWith(root)) { |
| 97 | dir = dir.slice(root.length); |
| 98 | } |
| 99 | } else if (original.startsWith("\\\\")) { |
| 100 | // UNC paths - treat leading double-backslash as root |
| 101 | root = "\\\\"; |
| 102 | if (dir.startsWith(root)) { |
| 103 | dir = dir.slice(root.length); |
| 104 | } |
| 105 | } |
| 106 | // Also treat Unix-style absolute paths as absolute even on Windows |
| 107 | if (!root && original.startsWith("/")) { |
| 108 | root = "/"; |
| 109 | if (dir.startsWith(root)) { |
| 110 | dir = dir.slice(root.length); |
| 111 | } |
| 112 | } |
| 113 | } else if (original.startsWith("/")) { |
| 114 | root = "/"; |
| 115 | if (dir.startsWith(root)) { |
| 116 | dir = dir.slice(root.length); |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | const separatorRegex = isWindowsPlatform() ? /[\\/]+/ : /\/+/; |
| 121 | const segments = dir ? dir.split(separatorRegex).filter(Boolean) : []; |
| 122 | |
| 123 | return { |
| 124 | root, |
| 125 | segments, |