You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
374 lines
10 KiB
374 lines
10 KiB
'use strict' |
|
|
|
// A derivative work based on: |
|
// <https://github.com/browserify/path-browserify>. |
|
// Which is licensed: |
|
// |
|
// MIT License |
|
// |
|
// Copyright (c) 2013 James Halliday |
|
// |
|
// 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. |
|
// A derivative work based on: |
|
// |
|
// Parts of that are extracted from Node’s internal `path` module: |
|
// <https://github.com/nodejs/node/blob/master/lib/path.js>. |
|
// Which is licensed: |
|
// |
|
// 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. |
|
|
|
exports.basename = basename |
|
exports.dirname = dirname |
|
exports.extname = extname |
|
exports.join = join |
|
exports.sep = '/' |
|
|
|
function basename(path, ext) { |
|
var start = 0 |
|
var end = -1 |
|
var index |
|
var firstNonSlashEnd |
|
var seenNonSlash |
|
var extIndex |
|
|
|
if (ext !== undefined && typeof ext !== 'string') { |
|
throw new TypeError('"ext" argument must be a string') |
|
} |
|
|
|
assertPath(path) |
|
index = path.length |
|
|
|
if (ext === undefined || !ext.length || ext.length > path.length) { |
|
while (index--) { |
|
if (path.charCodeAt(index) === 47 /* `/` */) { |
|
// If we reached a path separator that was not part of a set of path |
|
// separators at the end of the string, stop now. |
|
if (seenNonSlash) { |
|
start = index + 1 |
|
break |
|
} |
|
} else if (end < 0) { |
|
// We saw the first non-path separator, mark this as the end of our |
|
// path component. |
|
seenNonSlash = true |
|
end = index + 1 |
|
} |
|
} |
|
|
|
return end < 0 ? '' : path.slice(start, end) |
|
} |
|
|
|
if (ext === path) { |
|
return '' |
|
} |
|
|
|
firstNonSlashEnd = -1 |
|
extIndex = ext.length - 1 |
|
|
|
while (index--) { |
|
if (path.charCodeAt(index) === 47 /* `/` */) { |
|
// If we reached a path separator that was not part of a set of path |
|
// separators at the end of the string, stop now. |
|
if (seenNonSlash) { |
|
start = index + 1 |
|
break |
|
} |
|
} else { |
|
if (firstNonSlashEnd < 0) { |
|
// We saw the first non-path separator, remember this index in case |
|
// we need it if the extension ends up not matching. |
|
seenNonSlash = true |
|
firstNonSlashEnd = index + 1 |
|
} |
|
|
|
if (extIndex > -1) { |
|
// Try to match the explicit extension. |
|
if (path.charCodeAt(index) === ext.charCodeAt(extIndex--)) { |
|
if (extIndex < 0) { |
|
// We matched the extension, so mark this as the end of our path |
|
// component |
|
end = index |
|
} |
|
} else { |
|
// Extension does not match, so our result is the entire path |
|
// component |
|
extIndex = -1 |
|
end = firstNonSlashEnd |
|
} |
|
} |
|
} |
|
} |
|
|
|
if (start === end) { |
|
end = firstNonSlashEnd |
|
} else if (end < 0) { |
|
end = path.length |
|
} |
|
|
|
return path.slice(start, end) |
|
} |
|
|
|
function dirname(path) { |
|
var end |
|
var unmatchedSlash |
|
var index |
|
|
|
assertPath(path) |
|
|
|
if (!path.length) { |
|
return '.' |
|
} |
|
|
|
end = -1 |
|
index = path.length |
|
|
|
// Prefix `--` is important to not run on `0`. |
|
while (--index) { |
|
if (path.charCodeAt(index) === 47 /* `/` */) { |
|
if (unmatchedSlash) { |
|
end = index |
|
break |
|
} |
|
} else if (!unmatchedSlash) { |
|
// We saw the first non-path separator |
|
unmatchedSlash = true |
|
} |
|
} |
|
|
|
return end < 0 |
|
? path.charCodeAt(0) === 47 /* `/` */ |
|
? '/' |
|
: '.' |
|
: end === 1 && path.charCodeAt(0) === 47 /* `/` */ |
|
? '//' |
|
: path.slice(0, end) |
|
} |
|
|
|
function extname(path) { |
|
var startDot = -1 |
|
var startPart = 0 |
|
var end = -1 |
|
// Track the state of characters (if any) we see before our first dot and |
|
// after any path separator we find. |
|
var preDotState = 0 |
|
var unmatchedSlash |
|
var code |
|
var index |
|
|
|
assertPath(path) |
|
|
|
index = path.length |
|
|
|
while (index--) { |
|
code = path.charCodeAt(index) |
|
|
|
if (code === 47 /* `/` */) { |
|
// If we reached a path separator that was not part of a set of path |
|
// separators at the end of the string, stop now. |
|
if (unmatchedSlash) { |
|
startPart = index + 1 |
|
break |
|
} |
|
|
|
continue |
|
} |
|
|
|
if (end < 0) { |
|
// We saw the first non-path separator, mark this as the end of our |
|
// extension. |
|
unmatchedSlash = true |
|
end = index + 1 |
|
} |
|
|
|
if (code === 46 /* `.` */) { |
|
// If this is our first dot, mark it as the start of our extension. |
|
if (startDot < 0) { |
|
startDot = index |
|
} else if (preDotState !== 1) { |
|
preDotState = 1 |
|
} |
|
} else if (startDot > -1) { |
|
// We saw a non-dot and non-path separator before our dot, so we should |
|
// have a good chance at having a non-empty extension. |
|
preDotState = -1 |
|
} |
|
} |
|
|
|
if ( |
|
startDot < 0 || |
|
end < 0 || |
|
// We saw a non-dot character immediately before the dot. |
|
preDotState === 0 || |
|
// The (right-most) trimmed path component is exactly `..`. |
|
(preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) |
|
) { |
|
return '' |
|
} |
|
|
|
return path.slice(startDot, end) |
|
} |
|
|
|
function join() { |
|
var index = -1 |
|
var joined |
|
|
|
while (++index < arguments.length) { |
|
assertPath(arguments[index]) |
|
|
|
if (arguments[index]) { |
|
joined = |
|
joined === undefined |
|
? arguments[index] |
|
: joined + '/' + arguments[index] |
|
} |
|
} |
|
|
|
return joined === undefined ? '.' : normalize(joined) |
|
} |
|
|
|
// Note: `normalize` is not exposed as `path.normalize`, so some code is |
|
// manually removed from it. |
|
function normalize(path) { |
|
var absolute |
|
var value |
|
|
|
assertPath(path) |
|
|
|
absolute = path.charCodeAt(0) === 47 /* `/` */ |
|
|
|
// Normalize the path according to POSIX rules. |
|
value = normalizeString(path, !absolute) |
|
|
|
if (!value.length && !absolute) { |
|
value = '.' |
|
} |
|
|
|
if (value.length && path.charCodeAt(path.length - 1) === 47 /* / */) { |
|
value += '/' |
|
} |
|
|
|
return absolute ? '/' + value : value |
|
} |
|
|
|
// Resolve `.` and `..` elements in a path with directory names. |
|
function normalizeString(path, allowAboveRoot) { |
|
var result = '' |
|
var lastSegmentLength = 0 |
|
var lastSlash = -1 |
|
var dots = 0 |
|
var index = -1 |
|
var code |
|
var lastSlashIndex |
|
|
|
while (++index <= path.length) { |
|
if (index < path.length) { |
|
code = path.charCodeAt(index) |
|
} else if (code === 47 /* `/` */) { |
|
break |
|
} else { |
|
code = 47 /* `/` */ |
|
} |
|
|
|
if (code === 47 /* `/` */) { |
|
if (lastSlash === index - 1 || dots === 1) { |
|
// Empty. |
|
} else if (lastSlash !== index - 1 && dots === 2) { |
|
if ( |
|
result.length < 2 || |
|
lastSegmentLength !== 2 || |
|
result.charCodeAt(result.length - 1) !== 46 /* `.` */ || |
|
result.charCodeAt(result.length - 2) !== 46 /* `.` */ |
|
) { |
|
if (result.length > 2) { |
|
lastSlashIndex = result.lastIndexOf('/') |
|
|
|
/* istanbul ignore else - No clue how to cover it. */ |
|
if (lastSlashIndex !== result.length - 1) { |
|
if (lastSlashIndex < 0) { |
|
result = '' |
|
lastSegmentLength = 0 |
|
} else { |
|
result = result.slice(0, lastSlashIndex) |
|
lastSegmentLength = result.length - 1 - result.lastIndexOf('/') |
|
} |
|
|
|
lastSlash = index |
|
dots = 0 |
|
continue |
|
} |
|
} else if (result.length) { |
|
result = '' |
|
lastSegmentLength = 0 |
|
lastSlash = index |
|
dots = 0 |
|
continue |
|
} |
|
} |
|
|
|
if (allowAboveRoot) { |
|
result = result.length ? result + '/..' : '..' |
|
lastSegmentLength = 2 |
|
} |
|
} else { |
|
if (result.length) { |
|
result += '/' + path.slice(lastSlash + 1, index) |
|
} else { |
|
result = path.slice(lastSlash + 1, index) |
|
} |
|
|
|
lastSegmentLength = index - lastSlash - 1 |
|
} |
|
|
|
lastSlash = index |
|
dots = 0 |
|
} else if (code === 46 /* `.` */ && dots > -1) { |
|
dots++ |
|
} else { |
|
dots = -1 |
|
} |
|
} |
|
|
|
return result |
|
} |
|
|
|
function assertPath(path) { |
|
if (typeof path !== 'string') { |
|
throw new TypeError( |
|
'Path must be a string. Received ' + JSON.stringify(path) |
|
) |
|
} |
|
}
|
|
|