mirror of
https://github.com/nodejs/node.git
synced 2024-12-01 16:10:02 +01:00
9996b459e1
1. Express desired path.join behavior in tests. 2. Update fs.realpath to reflect new path.join behavior 3. Update url.resolve() to use new path.join behavior.
153 lines
4.4 KiB
JavaScript
153 lines
4.4 KiB
JavaScript
|
|
function validPathPart (p, keepBlanks) {
|
|
return typeof p === "string" && (p || keepBlanks);
|
|
}
|
|
|
|
exports.join = function () {
|
|
var args = Array.prototype.slice.call(arguments);
|
|
// edge case flag to switch into url-resolve-mode
|
|
var keepBlanks = false;
|
|
if (args[ args.length - 1 ] === true) {
|
|
keepBlanks = args.pop();
|
|
}
|
|
// return exports.split(args.join("/"), keepBlanks).join("/");
|
|
var joined = exports.normalizeArray(args, keepBlanks).join("/");
|
|
return joined;
|
|
};
|
|
exports.split = function (path, keepBlanks) {
|
|
// split based on /, but only if that / is not at the start or end.
|
|
return exports.normalizeArray(path.split(/^|\/(?!$)/), keepBlanks);
|
|
};
|
|
function cleanArray (parts, keepBlanks) {
|
|
var i = 0;
|
|
var l = parts.length - 1;
|
|
var stripped = false;
|
|
// strip leading empty args
|
|
while (i < l && !validPathPart(parts[i], keepBlanks)) {
|
|
stripped = true;
|
|
i ++;
|
|
}
|
|
// strip tailing empty args
|
|
while (l >= i && !validPathPart(parts[l], keepBlanks)) {
|
|
stripped = true;
|
|
l --;
|
|
}
|
|
if (stripped) {
|
|
// if l chopped all the way back to i, then this is empty
|
|
parts = Array.prototype.slice.call(parts, i, l + 1);
|
|
}
|
|
return parts.filter(function (p) { return validPathPart(p, keepBlanks) })
|
|
.join('/')
|
|
.split(/^|\/(?!$)/);
|
|
}
|
|
exports.normalizeArray = function (original, keepBlanks) {
|
|
var parts = cleanArray(original, keepBlanks);
|
|
if (!parts.length || (parts.length === 1 && !parts[0])) return ["."];
|
|
|
|
// now we're fully ready to rock.
|
|
// leading/trailing invalids have been stripped off.
|
|
// if it comes in starting with a slash, or ending with a slash,
|
|
var leadingSlash = (parts[0].charAt(0) === "/");
|
|
if (leadingSlash) parts[0] = parts[0].substr(1);
|
|
var last = parts.slice(-1)[0];
|
|
var tailingSlash = (last.substr(-1) === "/");
|
|
if (tailingSlash) parts[parts.length - 1] = last.slice(0, -1);
|
|
var directories = [];
|
|
var prev;
|
|
for (var i = 0, l = parts.length - 1 ; i <= l ; i ++) {
|
|
var directory = parts[i];
|
|
|
|
// if it's blank, and we're not keeping blanks, then skip it.
|
|
if (directory === "" && !keepBlanks) continue;
|
|
|
|
// if it's a dot, then skip it
|
|
if (directory === "." && (
|
|
directories.length
|
|
|| (i === 0 && !(tailingSlash && i === l))
|
|
|| (i === 0 && leadingSlash)
|
|
)) continue;
|
|
|
|
// if we're dealing with an absolute path, then discard ..s that go
|
|
// above that the base.
|
|
if (leadingSlash && directories.length === 0 && directory === "..") {
|
|
continue;
|
|
}
|
|
// trying to go up a dir
|
|
if (
|
|
directory === ".."
|
|
&& directories.length
|
|
&& prev !== ".."
|
|
&& prev !== undefined
|
|
) {
|
|
directories.pop();
|
|
prev = directories.slice(-1)[0];
|
|
} else {
|
|
directories.push(directory);
|
|
prev = directory;
|
|
}
|
|
}
|
|
if (!directories.length) {
|
|
directories = [ leadingSlash || tailingSlash ? "" : "." ];
|
|
}
|
|
var last = directories.slice(-1)[0];
|
|
if (tailingSlash && last.substr(-1) !== "/") {
|
|
directories[directories.length-1] += "/";
|
|
}
|
|
if (leadingSlash && directories[0].charAt(0) !== "/") {
|
|
if (directories[0] === ".") directories[0] = "";
|
|
directories[0] = "/" + directories[0];
|
|
}
|
|
return directories;
|
|
};
|
|
|
|
exports.normalize = function (path, keepBlanks) {
|
|
return exports.join(path, keepBlanks || false);
|
|
};
|
|
|
|
exports.dirname = function (path) {
|
|
if (path.length > 1 && '/' === path[path.length-1]) {
|
|
path = path.replace(/\/+$/, '');
|
|
}
|
|
var lastSlash = path.lastIndexOf('/');
|
|
switch (lastSlash) {
|
|
case -1:
|
|
return '.';
|
|
case 0:
|
|
return '/';
|
|
default:
|
|
return path.substring(0, lastSlash);
|
|
}
|
|
};
|
|
|
|
exports.basename = function (path, ext) {
|
|
var f = path.substr(path.lastIndexOf("/") + 1);
|
|
if (ext && f.substr(-1 * ext.length) === ext) {
|
|
f = f.substr(0, f.length - ext.length);
|
|
}
|
|
return f;
|
|
};
|
|
|
|
exports.extname = function (path) {
|
|
var dot = path.lastIndexOf('.'),
|
|
slash = path.lastIndexOf('/');
|
|
// The last dot must be in the last path component, and it (the last dot) must
|
|
// not start the last path component (i.e. be a dot that signifies a hidden
|
|
// file in UNIX).
|
|
return dot <= slash + 1 ? '' : path.substring(dot);
|
|
};
|
|
|
|
exports.exists = function (path, callback) {
|
|
process.binding('fs').stat(path, function (err, stats) {
|
|
if (callback) callback(err ? false : true);
|
|
});
|
|
};
|
|
|
|
exports.existsSync = function (path) {
|
|
try {
|
|
process.binding('fs').stat(path);
|
|
return true;
|
|
} catch(e){
|
|
return false;
|
|
}
|
|
};
|