UNPKG

t-comm

Version:

专业、稳定、纯粹的工具库

416 lines (409 loc) 12.9 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray'); var fs_fs = require('./fs.js'); var nodejs_fs = require('../nodejs/fs.js'); var nodejs_path = require('../nodejs/path.js'); var time_time = require('../time/time.js'); require('../nodejs/crypto.js'); require('../nodejs/os.js'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray); var LOG_DIR = 'log'; /** * 内部复制函数,用于复制文件和目录 * @param src - 源路径 * @param dist - 目标路径 * @private */ function innerCopy(src, dist) { // statSync 的结果除了 isFile() 和 isDirectory(),还可能是 // 符号链接(symlink)、块设备、字符设备、FIFO 等 if (!nodejs_fs.getFs().statSync(src).isDirectory()) { return; } var paths = nodejs_fs.getFs().readdirSync(src); paths.forEach(function (p) { var tSrc = "".concat(src, "/").concat(p); var tDist = "".concat(dist, "/").concat(p); var stat = nodejs_fs.getFs().statSync(tSrc); if (stat.isFile()) { // 判断是文件还是目录 fs_fs.writeFileSync(tDist, fs_fs.readFileSync(tSrc)); } else if (stat.isDirectory()) { innerCopyDir(tSrc, tDist); // 当是目录时,递归复制 } }); } /** * 内部递归复制目录函数 * 复制目录、子目录,及其中的文件 * @param src - 要复制的源目录路径 * @param dist - 复制到的目标目录路径 * @private */ function innerCopyDir(src, dist) { var b = nodejs_fs.getFs().existsSync(dist); if (!b) { mkDirsSync(dist); // 创建目录 } innerCopy(src, dist); } /** * 递归创建目录(同步方法) * 如果目录已存在则直接返回,否则递归创建父目录 * @param dirname - 要创建的目录路径 * @returns 创建成功返回 true * @example * ```ts * mkDirsSync('/path/to/new/directory'); * ``` */ function mkDirsSync(dirname) { if (nodejs_fs.getFs().existsSync(dirname)) { return true; } if (mkDirsSync(nodejs_path.getPath().dirname(dirname))) { nodejs_fs.getFs().mkdirSync(dirname); return true; } return false; } /** * 拷贝目录以及子文件 * 递归复制整个目录结构,包括所有子目录和文件 * @param src - 源目录路径 * @param dist - 目标目录路径 * @param callback - 可选的回调函数,复制完成后执行 * @example * ```ts * copyDir('/source/path', '/target/path', () => { * console.log('复制完成'); * }); * ``` */ function copyDir(src, dist, callback) { innerCopyDir(src, dist); if (callback) { callback(); } } /** * 删除目录及其所有内容 * 递归删除目录下的所有文件和子目录 * @param tPath - 要删除的目录路径 * @example * ```ts * deleteFolder('/path/to/folder'); * ``` */ function deleteFolder(tPath) { var files = []; if (nodejs_fs.getFs().existsSync(tPath)) { files = nodejs_fs.getFs().readdirSync(tPath); files.forEach(function (file) { var curPath = "".concat(tPath, "/").concat(file); if (nodejs_fs.getFs().statSync(curPath).isDirectory()) { deleteFolder(curPath); } else { nodejs_fs.getFs().unlinkSync(curPath); } }); nodejs_fs.getFs().rmdirSync(tPath); } } /** * 递归删除空目录 * 从指定路径开始,递归删除所有空目录(不删除包含文件的目录) * @param tPath - 要检查和删除的目录路径 * @param level - 当前递归层级,默认为 0(根层级不会被删除) * @example * ```ts * rmEmptyDir('/path/to/check'); * ``` */ function rmEmptyDir(tPath) { var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var files = nodejs_fs.getFs().readdirSync(tPath); if (files.length > 0) { var tempFile = 0; files.forEach(function (file) { tempFile += 1; rmEmptyDir("".concat(tPath, "/").concat(file), level + 1); }); if (tempFile === files.length && level !== 0) { nodejs_fs.getFs().rmdirSync(tPath); } } else { level !== 0 && nodejs_fs.getFs().rmdirSync(tPath); } } /** * 递归删除文件夹(可配置是否删除文件) * 递归遍历目录,根据配置决定是否删除文件,并删除空目录 * @param path - 要处理的目录路径 * @param options - 配置选项 * @param options.deleteFile - 是否删除文件,默认为 false * @param options.log - 是否输出日志,默认为 false * @example * ```ts * // 只删除空目录 * deleteFolderRecursive('/path/to/folder'); * * // 删除所有文件和目录 * deleteFolderRecursive('/path/to/folder', { deleteFile: true, log: true }); * ``` */ function deleteFolderRecursive(path) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { deleteFile: false, log: false }; var _a, _b; var deleteFile = (_a = options.deleteFile) !== null && _a !== void 0 ? _a : false; var log = (_b = options.log) !== null && _b !== void 0 ? _b : false; if (nodejs_fs.getFs().existsSync(path)) { var list = nodejs_fs.getFs().readdirSync(path); list.forEach(function (file) { var curPath = "".concat(path, "/").concat(file); if (nodejs_fs.getFs().statSync(curPath).isDirectory()) { // recurse deleteFolderRecursive(curPath, options); } else { // delete file if (deleteFile) { nodejs_fs.getFs().unlinkSync(curPath); } } }); var remaining = nodejs_fs.getFs().readdirSync(path); if (!remaining.length) { if (log) { console.log('>>> delete: ', path); } nodejs_fs.getFs().rmdirSync(path); } } } /** * 拷贝单个文件 * 将文件从源路径复制到目标路径 * @param from - 源文件路径 * @param to - 目标文件路径 * @returns 写入操作的结果 * @example * ```ts * copyFile('/source/file.txt', '/target/file.txt'); * ``` */ function copyFile(from, to) { return fs_fs.writeFileSync(to, fs_fs.readFileSync(from)); } /** * 递归遍历文件夹,并对每个文件执行回调函数 * 遍历目录树,对每个文件(非目录)执行指定的回调函数 * @param cb - 回调函数,接收文件路径作为参数 * @param tPath - 要遍历的文件夹或文件路径 * @example * ```ts * traverseFolder((filePath) => { * console.log('处理文件:', filePath); * }, '/path/to/folder'); * ``` */ function traverseFolder(cb, tPath) { if (nodejs_fs.getFs().statSync(tPath).isDirectory()) { var files = nodejs_fs.getFs().readdirSync(tPath); files.forEach(function (file) { var curPath = nodejs_path.getPath().resolve(tPath, file); // `${tPath}/${file}`; traverseFolder(cb, curPath); }); } else { cb(tPath); } } /** * 从日志目录读取 JSON 文件 * 读取 ./log 目录下的 JSON 文件内容 * @param file - 文件名(相对于 log 目录) * @param defaultContent - 文件不存在时返回的默认内容,默认为 '{}' * @returns JSON 文件内容字符串 * @example * ```ts * const content = readJsonLog('data.json', '[]'); * ``` */ function readJsonLog(file) { var defaultContent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '{}'; var filePath = "./".concat(LOG_DIR, "/").concat(file); if (!nodejs_fs.getFs().existsSync(filePath)) { createLogDir(); return defaultContent; } return fs_fs.readFileSync(filePath) || defaultContent; } /** * 获取 JSON 日志目录的绝对路径 * @returns 日志目录的绝对路径 * @example * ```ts * const logDir = getJsonLogDir(); * console.log(logDir); // /path/to/project/log * ``` */ function getJsonLogDir() { return nodejs_path.getPath().resolve(process.cwd(), './log'); } /** * 将 JSON 对象保存到日志文件 * 将对象序列化为 JSON 并保存到 ./log 目录下 * @param content - 要保存的对象内容 * @param file - 文件名(相对于 log 目录) * @param needLog - 是否需要保存日志,默认为 true * @example * ```ts * saveJsonToLog({ status: 'success', data: [1, 2, 3] }, 'result.json'); * ``` */ function saveJsonToLog(content, file) { var needLog = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; if (!needLog) return; createLogDir(); fs_fs.writeFileSync("./".concat(LOG_DIR, "/").concat(file), content, true); } /** * 将内容追加保存到日志文件(支持保留历史记录) * 以数组形式保存多条日志记录,每条记录包含时间戳和数据,支持限制最大记录数 * @param content - 要保存的内容 * @param file - 文件名(相对于 log 目录) * @param options - 配置选项 * @param options.needLog - 是否需要保存日志,默认为 true * @param options.max - 最大保留记录数,默认为 10 * @example * ```ts * saveJsonToLogMore({ action: 'upload', status: 'success' }, 'history.json', { * needLog: true, * max: 20 * }); * ``` */ function saveJsonToLogMore(content, file, options) { var _a, _b; var needLog = (_a = options === null || options === void 0 ? void 0 : options.needLog) !== null && _a !== void 0 ? _a : true; var max = (_b = options === null || options === void 0 ? void 0 : options.max) !== null && _b !== void 0 ? _b : 10; if (!needLog) return; createLogDir(); var filePath = "./log/".concat(file); var beforeContent = []; var newContent = [{ logTime: time_time.timeStampFormat(Date.now(), 'yyyy-MM-dd hh:mm:ss'), data: content }]; if (nodejs_fs.getFs().existsSync(filePath)) { try { beforeContent = fs_fs.readFileSync(filePath, true).logList || []; } catch (err) { beforeContent = []; } } if (beforeContent && Array.isArray(beforeContent)) { var _newContent; (_newContent = newContent).push.apply(_newContent, _toConsumableArray__default["default"](beforeContent)); } newContent = newContent.slice(0, max); try { nodejs_fs.getFs().writeFile(filePath, JSON.stringify({ logList: newContent }, null, 2), { encoding: 'utf-8' }, function () {}); } catch (err) {} } /** * 从日志目录读取并解析 JSON 文件 * 读取 ./log 目录下的 JSON 文件并解析为对象 * @param file - 文件名(相对于 log 目录) * @returns 解析后的 JSON 对象,解析失败或文件不存在时返回空对象 * @example * ```ts * const data = getJsonFromLog('config.json'); * console.log(data); * ``` */ function getJsonFromLog(file) { var filePath = "./".concat(LOG_DIR, "/").concat(file); var data = {}; if (!nodejs_fs.getFs().existsSync(filePath)) { console.log('[getJsonFromLog] no exist'); } else { var originFile = nodejs_fs.getFs().readFileSync(filePath, { encoding: 'utf-8' }); try { data = JSON.parse(originFile); } catch (err) {} } return data; } /** * 创建日志目录 * 如果 ./log 目录不存在则创建 * @private */ function createLogDir() { if (!nodejs_fs.getFs().existsSync("./".concat(LOG_DIR))) { nodejs_fs.getFs().mkdirSync("./".concat(LOG_DIR)); } } /** * 从文件路径中提取文件名(不含扩展名) * @param file - 文件路径 * @returns 不含扩展名的文件名 * @example * ```ts * const name = getFileName('/path/to/file.txt'); * console.log(name); // 'file' * ``` */ function getFileName(file) { var basename = nodejs_path.getPath().basename(file); var extname = nodejs_path.getPath().extname(file); var fileName = basename.replace(new RegExp("".concat(extname, "$")), ''); return fileName; } /** * 解析 JSON 字符串为对象 * 安全地解析 JSON 字符串,解析失败时输出错误信息并返回空对象 * @param content - JSON 字符串内容 * @param file - 文件路径(用于错误日志) * @returns 解析后的对象,解析失败时返回空对象 * @example * ```ts * const data = readJson('{"name":"test"}', 'config.json'); * console.log(data); // { name: 'test' } * ``` */ function readJson(content, file) { var data = {}; try { data = JSON.parse(content); } catch (e) { console.error('>>> read json error: ', file); } return data; } exports.copyDir = copyDir; exports.copyFile = copyFile; exports.deleteFolder = deleteFolder; exports.deleteFolderRecursive = deleteFolderRecursive; exports.getFileName = getFileName; exports.getJsonFromLog = getJsonFromLog; exports.getJsonLogDir = getJsonLogDir; exports.mkDirsSync = mkDirsSync; exports.readJson = readJson; exports.readJsonLog = readJsonLog; exports.rmEmptyDir = rmEmptyDir; exports.saveJsonToLog = saveJsonToLog; exports.saveJsonToLogMore = saveJsonToLogMore; exports.traverseFolder = traverseFolder;