hzengine-core
Version:
An Visual Novel Engine for Zepp OS
338 lines (293 loc) • 9.23 kB
JavaScript
// path utils for ZeppOS
// @CuberQAQ
// Generated by GPT-4o mini
;
var util = {
isString: (x) => typeof x === "string", // 检查是否为字符串
isObject: (x) => typeof x === "object", // 检查是否为对象
};
/**
* 检查路径是否包含协议
* @param {string} path - 路径字符串
* @returns {boolean} - 如果路径包含协议,则返回 true
*/
function isProtocolPath(path) {
return /^[a-zA-Z][a-zA-Z\d+\-.]*:\/\//.test(path);
}
/**
* 提取协议和路径部分
* @param {string} path - 路径字符串
* @returns {{protocol: string, filepath: string}} - 包含协议和文件路径的对象
*/
function extractProtocol(path) {
const match = path.match(/^([a-zA-Z][a-zA-Z\d+\-.]*):\/\/(.*)$/);
if (match) {
return {
protocol: match[1], // 获取协议
filepath: match[2], // 获取文件路径
};
}
return { protocol: null, filepath: path }; // 如果没有协议,返回原路径
}
/**
* 解析路径数组并规范化
* @param {string[]} parts - 路径组成部分
* @param {boolean} allowAboveRoot - 是否允许上级目录
* @returns {string[]} - 规范化后的路径部分
*/
function normalizeArray(parts, allowAboveRoot) {
var res = [];
for (var i = 0; i < parts.length; i++) {
var p = parts[i];
// 忽略空部分和当前目录(.)
if (!p || p === ".") continue;
// 处理上级目录(..)
if (p === "..") {
if (res.length && res[res.length - 1] !== "..") {
res.pop(); // 移除最后一个部分
} else if (allowAboveRoot) {
res.push(".."); // 允许上级目录
}
} else {
res.push(p); // 添加有效部分
}
}
return res;
}
/**
* 移除数组两端的空元素
* @param {string[]} arr - 输入数组
* @returns {string[]} - 去除空元素后的数组
*/
function trimArray(arr) {
var lastIndex = arr.length - 1;
var start = 0;
for (; start <= lastIndex; start++) {
if (arr[start]) break;
}
var end = lastIndex;
for (; end >= 0; end--) {
if (arr[end]) break;
}
if (start === 0 && end === lastIndex) return arr;
if (start > end) return [];
return arr.slice(start, end + 1);
}
// 使用正则表达式分割路径
var splitPathRe =
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
var posix = {};
/**
* 分割路径
* @param {string} filename - 输入的路径字符串
* @returns {string[]} - 分割后的路径组成部分
*/
function posixSplitPath(filename) {
return splitPathRe.exec(filename).slice(1);
}
/**
* 解析路径,将相对路径转换为绝对路径
* @param {...string} paths - 要解析的路径
* @returns {string} - 解析后的绝对路径
*/
posix.resolve = function () {
var resolvedPath = "",
resolvedAbsolute = false;
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
var path = i >= 0 ? arguments[i] : process.cwd();
// 跳过空和无效的条目
if (!util.isString(path)) {
throw new TypeError("Arguments to path.resolve must be strings");
} else if (!path) {
continue;
}
// 检查路径是否包含协议
if (isProtocolPath(path)) {
const { protocol, filepath } = extractProtocol(path);
resolvedPath = filepath + "/" + resolvedPath;
resolvedAbsolute = true; // 将协议路径视为绝对路径
} else {
resolvedPath = path + "/" + resolvedPath;
resolvedAbsolute = path[0] === "/";
}
}
// 规范化路径
resolvedPath = normalizeArray(
resolvedPath.split("/"),
!resolvedAbsolute
).join("/");
return (resolvedAbsolute ? "/" : "") + resolvedPath || ".";
};
/**
* 规范化路径,去除多余的斜杠和当前目录
* @param {string} path - 输入的路径字符串
* @returns {string} - 规范化后的路径
*/
posix.normalize = function (path) {
// 检查路径是否包含协议
if (isProtocolPath(path)) {
const { protocol, filepath } = extractProtocol(path);
return protocol + "://" + normalizeArray(filepath.split("/")).join("/");
}
var isAbsolute = posix.isAbsolute(path),
trailingSlash = path && path[path.length - 1] === "/";
// 规范化路径
path = normalizeArray(path.split("/"), !isAbsolute).join("/");
if (!path && !isAbsolute) {
path = ".";
}
if (path && trailingSlash) {
path += "/";
}
return (isAbsolute ? "/" : "") + path;
};
/**
* 检查路径是否为绝对路径
* @param {string} path - 输入的路径字符串
* @returns {boolean} - 如果路径为绝对路径,则返回 true
*/
posix.isAbsolute = function (path) {
return path.charAt(0) === "/";
};
/**
* 连接多个路径段为一个路径
* @param {...string} segments - 要连接的路径段
* @returns {string} - 连接后的路径
*/
posix.join = function () {
var path = "";
for (var i = 0; i < arguments.length; i++) {
var segment = arguments[i];
if (!util.isString(segment)) {
throw new TypeError("Arguments to path.join must be strings");
}
if (segment) {
if (!path) {
path += segment;
} else {
path += "/" + segment;
}
}
}
return posix.normalize(path);
};
/**
* 计算相对路径
* @param {string} from - 起始路径
* @param {string} to - 目标路径
* @returns {string} - 相对路径
*/
posix.relative = function (from, to) {
from = posix.resolve(from).substr(1);
to = posix.resolve(to).substr(1);
var fromParts = trimArray(from.split("/"));
var toParts = trimArray(to.split("/"));
var length = Math.min(fromParts.length, toParts.length);
var samePartsLength = length;
for (var i = 0; i < length; i++) {
if (fromParts[i] !== toParts[i]) {
samePartsLength = i;
break;
}
}
var outputParts = [];
for (var i = samePartsLength; i < fromParts.length; i++) {
outputParts.push("..");
}
outputParts = outputParts.concat(toParts.slice(samePartsLength));
return outputParts.join("/");
};
/**
* 获取路径的目录名
* @param {string} path - 输入的路径字符串
* @returns {string} - 目录名
*/
posix.dirname = function (path) {
var result = posixSplitPath(path),
root = result[0],
dir = result[1];
if (!root && !dir) {
return ".";
}
if (dir) {
dir = dir.substr(0, dir.length - 1); // 去掉尾部斜杠
}
return root + dir;
};
/**
* 获取路径的基本名
* @param {string} path - 输入的路径字符串
* @param {string} [ext] - 可选的扩展名,如果提供则将其从基本名中去除
* @returns {string} - 基本名
*/
posix.basename = function (path, ext) {
var f = posixSplitPath(path)[2];
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
};
/**
* 获取路径的扩展名
* @param {string} path - 输入的路径字符串
* @returns {string} - 扩展名
*/
posix.extname = function (path) {
return posixSplitPath(path)[3];
};
/**
* 格式化路径对象为路径字符串
* @param {Object} pathObject - 路径对象
* @param {string} pathObject.root - 根路径
* @param {string} pathObject.dir - 目录路径
* @param {string} pathObject.base - 基本文件名
* @param {string} pathObject.ext - 扩展名
* @param {string} pathObject.name - 文件名(不包含扩展名)
* @returns {string} - 格式化后的路径字符串
*/
posix.format = function (pathObject) {
if (!util.isObject(pathObject)) {
throw new TypeError(
"Parameter 'pathObject' must be an object, not " + typeof pathObject
);
}
var root = pathObject.root || "";
if (!util.isString(root)) {
throw new TypeError(
"'pathObject.root' must be a string or undefined, not " +
typeof pathObject.root
);
}
var dir = pathObject.dir ? pathObject.dir + posix.sep : "";
var base = pathObject.base || "";
return dir + base;
};
/**
* 解析路径字符串为路径对象
* @param {string} pathString - 输入的路径字符串
* @returns {{root: string, dir: string, base: string, ext: string, name: string}} - 路径对象
*/
posix.parse = function (pathString) {
if (!util.isString(pathString)) {
throw new TypeError(
"Parameter 'pathString' must be a string, not " + typeof pathString
);
}
var allParts = posixSplitPath(pathString);
if (!allParts || allParts.length !== 4) {
throw new TypeError("Invalid path '" + pathString + "'");
}
allParts[1] = allParts[1] || "";
allParts[2] = allParts[2] || "";
allParts[3] = allParts[3] || "";
return {
root: allParts[0],
dir: allParts[0] + allParts[1].slice(0, -1),
base: allParts[2],
ext: allParts[3],
name: allParts[2].slice(0, allParts[2].length - allParts[3].length),
};
};
posix.sep = "/"; // POSIX 路径分隔符
posix.delimiter = ":"; // POSIX 路径分隔符(用于环境变量)
export default posix; // 导出 posix 模块