(path?: URL | string, ...paths: string[])
| 23 | * @returns The joined path. |
| 24 | */ |
| 25 | export function join(path?: URL | string, ...paths: string[]): string { |
| 26 | if (path instanceof URL) { |
| 27 | path = fromFileUrl(path); |
| 28 | } |
| 29 | paths = path ? [path, ...paths] : paths; |
| 30 | paths.forEach((path) => assertPath(path)); |
| 31 | paths = paths.filter((path) => path.length > 0); |
| 32 | if (paths.length === 0) return "."; |
| 33 | |
| 34 | // Make sure that the joined path doesn't start with two slashes, because |
| 35 | // normalize() will mistake it for an UNC path then. |
| 36 | // |
| 37 | // This step is skipped when it is very clear that the user actually |
| 38 | // intended to point at an UNC path. This is assumed when the first |
| 39 | // non-empty string arguments starts with exactly two slashes followed by |
| 40 | // at least one more non-slash character. |
| 41 | // |
| 42 | // Note that for normalize() to treat a path as an UNC path it needs to |
| 43 | // have at least 2 components, so we don't filter for that here. |
| 44 | // This means that the user can use join to construct UNC paths from |
| 45 | // a server name and a share name; for example: |
| 46 | // path.join('//server', 'share') -> '\\\\server\\share\\' |
| 47 | let needsReplace = true; |
| 48 | let slashCount = 0; |
| 49 | const firstPart = paths[0]!; |
| 50 | if (isPathSeparator(firstPart.charCodeAt(0))) { |
| 51 | ++slashCount; |
| 52 | const firstLen = firstPart.length; |
| 53 | if (firstLen > 1) { |
| 54 | if (isPathSeparator(firstPart.charCodeAt(1))) { |
| 55 | ++slashCount; |
| 56 | if (firstLen > 2) { |
| 57 | if (isPathSeparator(firstPart.charCodeAt(2))) ++slashCount; |
| 58 | else { |
| 59 | // We matched a UNC path in the first part |
| 60 | needsReplace = false; |
| 61 | } |
| 62 | } |
| 63 | } |
| 64 | } |
| 65 | } |
| 66 | let joined = paths.join("\\"); |
| 67 | if (needsReplace) { |
| 68 | // Find any more consecutive slashes we need to replace |
| 69 | for (; slashCount < joined.length; ++slashCount) { |
| 70 | if (!isPathSeparator(joined.charCodeAt(slashCount))) break; |
| 71 | } |
| 72 | |
| 73 | // Replace the slashes if needed |
| 74 | if (slashCount >= 2) joined = `\\${joined.slice(slashCount)}`; |
| 75 | } |
| 76 | |
| 77 | return normalize(joined); |
| 78 | } |
no test coverage detected