one
Version:
One is a new React Framework that makes Vite serve both native and web.
139 lines (127 loc) • 4.26 kB
text/typescript
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// https://github.com/browserify/path-browserify/blob/master/index.js
function assertPath(path: string) {
if (typeof path !== 'string') {
throw new TypeError('Path must be a string. Received ' + JSON.stringify(path))
}
}
// Resolves . and .. elements in a path with directory names
function normalizeStringPosix(path: string, allowAboveRoot?: boolean) {
let res = ''
let lastSegmentLength = 0
let lastSlash = -1
let dots = 0
let code
for (let i = 0; i <= path.length; ++i) {
if (i < path.length) {
code = path.charCodeAt(i)
} else if (code === 47 /*/*/) {
break
} else {
code = 47 /*/*/
}
if (code === 47 /*/*/) {
if (lastSlash === i - 1 || dots === 1) {
// NOOP
} else if (lastSlash !== i - 1 && dots === 2) {
if (
res.length < 2 ||
lastSegmentLength !== 2 ||
res.charCodeAt(res.length - 1) !== 46 /*.*/ ||
res.charCodeAt(res.length - 2) !== 46 /*.*/
) {
if (res.length > 2) {
const lastSlashIndex = res.lastIndexOf('/')
if (lastSlashIndex !== res.length - 1) {
if (lastSlashIndex === -1) {
res = ''
lastSegmentLength = 0
} else {
res = res.slice(0, lastSlashIndex)
lastSegmentLength = res.length - 1 - res.lastIndexOf('/')
}
lastSlash = i
dots = 0
continue
}
} else if (res.length === 2 || res.length === 1) {
res = ''
lastSegmentLength = 0
lastSlash = i
dots = 0
continue
}
}
if (allowAboveRoot) {
if (res.length > 0) res += '/..'
else res = '..'
lastSegmentLength = 2
}
} else {
if (res.length > 0) res += '/' + path.slice(lastSlash + 1, i)
else res = path.slice(lastSlash + 1, i)
lastSegmentLength = i - lastSlash - 1
}
lastSlash = i
dots = 0
} else if (code === 46 /*.*/ && dots !== -1) {
++dots
} else {
dots = -1
}
}
return res
}
// path.resolve([from ...], to)
export function resolve(...segments: string[]) {
let resolvedPath = ''
let resolvedAbsolute = false
for (let i = segments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
let path
if (i >= 0) {
path = segments[i]
} else {
path = '/'
}
assertPath(path)
// Skip empty entries
if (path.length === 0) {
continue
}
resolvedPath = path + '/' + resolvedPath
resolvedAbsolute = path.charCodeAt(0) === 47 /*/*/
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute)
if (resolvedAbsolute) {
if (resolvedPath.length > 0) {
return '/' + resolvedPath
}
return '/'
}
if (resolvedPath.length > 0) {
return resolvedPath
}
return '.'
}