mirror of
https://github.com/nodejs/node.git
synced 2024-11-30 15:30:56 +01:00
170 lines
4.4 KiB
JavaScript
170 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;
|
|
}
|
|
};
|