-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjoin.mts
115 lines (100 loc) · 2.89 KB
/
join.mts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/**
* @file join
* @module pathe/lib/join
*/
import validateString from '#internal/validate-string'
import dot from '#lib/dot'
import isSep from '#lib/is-sep'
import normalize from '#lib/normalize'
import sep from '#lib/sep'
/**
* Join all path segments in `paths` using {@linkcode sep} as the delimiter and
* normalize the result.
*
* Zero-length path segments are ignored.
* If the joined path string is a zero-length string, {@linkcode dot} is
* returned, representing the current working directory.
*
* @category
* core
*
* @this {void}
*
* @param {string[]} paths
* The path segment sequence
* @return {string}
* Path segment sequence as one path
*/
function join(this: void, ...paths: string[]): string {
if (!paths.length) return dot
/**
* First path segment in {@linkcode paths}.
*
* @var {string} firstSegment
*/
let firstSegment: string = ''
/**
* Joined path string.
*
* @var {string} joined
*/
let joined: string = ''
for (const path of paths) {
validateString(path, 'path')
if (path.length) {
if (!firstSegment) firstSegment = path
joined += `${joined ? sep : ''}${path}`
}
}
if (!joined) return dot
/**
* Path separator deduplication check.
*
* This check ensures {@linkcode joined} does not start with two path
* separator characters. If it does, {@linkcode normalize} will mistake it for
* a UNC path.
*
* This check is skipped when it is clear that the user intended to point at a
* UNC path. This is assumed when the first non-empty string argument starts
* with exactly two separator characters, followed by at least one more
* non-separator character.
*
* > 👉 **Note**: In order for {@linkcode normalize} to recognize a UNC path,
* > the path must have at least 2 components, so this check does not take
* > that into account. This means that the user can use {@linkcode join} to
* > construct UNC paths from a server name and a share name.
*
* @example
* pathe.join('//server', 'share') // '//server/share/'
* @example
* pathe.join('\\\\server', 'share') // '//server/share/'
*
* @var {boolean} dedupe
*/
let dedupe: boolean = true
/**
* Path separator count.
*
* @var {number} separators
*/
let separators: number = 0
if (isSep(firstSegment[0])) {
++separators
if (firstSegment.length > 1 && isSep(firstSegment[1])) {
++separators
if (firstSegment.length > 2) {
if (isSep(firstSegment[2])) ++separators
// matched unc path component in first segment
else dedupe = false
}
}
}
if (dedupe) {
// find any more consecutive slashes that need to be replaced
while (separators < joined.length && isSep(joined[separators])) separators++
// replace separators
if (separators >= 2) joined = `${sep}${joined.slice(separators)}`
}
return normalize(joined)
}
export default join