UNPKG

t-comm

Version:

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

406 lines (399 loc) 16.8 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _slicedToArray = require('@babel/runtime/helpers/slicedToArray'); var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray'); var fs = require('fs'); var path = require('path'); var string_random = require('../string/random.js'); var string_string = require('../string/string.js'); var thirdParty_glob = require('../third-party/glob.js'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray); var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray); var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs); var path__default = /*#__PURE__*/_interopDefaultLegacy(path); function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } /** * 生成 PascalCase 匹配正则(前后必须是非单词字符) * @param {string} value - kebab-case 名称 * @returns {RegExp} * @example * ```ts * const reg = getComponentPascalReg('press-icon'); * 'use <PressIcon/>'.match(reg); // ['PressIcon'] * ``` */ function getComponentPascalReg(value) { return new RegExp("(?<=\\W)(".concat(string_string.pascalCase(value), ")(?=\\W)"), 'g'); } /** * 生成三阶段重命名配置(plus -> temp, key -> plus, temp -> key) * @param {string[]} rawList - 组件名列表,如 ['dialog', 'icon'] * @param {string[]} [extraList=[]] - 额外需要重命名的组件名列表 * @returns {{ renameConfig: Object, renameConfig2: Object, renameConfig3: Object }} * @example * ```ts * const { renameConfig, renameConfig2, renameConfig3 } = getThreeStageRenameConfig(['dialog', 'icon']); * // renameConfig: { 'press-dialog-plus': '<random>', 'press-icon-plus': '<random>' } * // renameConfig2: { 'press-dialog': 'press-dialog-plus', 'press-icon': 'press-icon-plus' } * // renameConfig3: { '<random>': 'press-dialog', '<random>': 'press-icon' } * ``` */ function getThreeStageRenameConfig(rawList) { var extraList = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; var renameConfig = {}; var renameConfig2 = {}; var renameConfig3 = {}; var iRawList = [].concat(_toConsumableArray__default["default"](rawList), _toConsumableArray__default["default"](extraList)); var _iterator = _createForOfIteratorHelper(iRawList), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var item = _step.value; var plusKey = "press-".concat(item, "-plus"); var key = "press-".concat(item); var tempKey = string_random.randomString(6); renameConfig[plusKey] = tempKey; renameConfig2[key] = plusKey; renameConfig3[tempKey] = key; } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return { renameConfig: renameConfig, renameConfig2: renameConfig2, renameConfig3: renameConfig3 }; } /** * 生成 meta config(如 component-config.json)的 PascalCase 替换规则 * @param {string[]} rawList - 组件名列表 * @param {string[]} dirList - 目标文件 glob 列表 * @returns {Array<{ list: Array, dirList: string[] }>} * @example * ```ts * const rules = getMetaConfigPascalReplaceRules( * ['dialog', 'icon'], * ['src/component-config.json'], * ); * // rules 为三阶段替换规则数组,供 batchReplaceFileContent 使用 * ``` */ function getMetaConfigPascalReplaceRules(rawList, dirList) { var list = []; var list2 = []; var list3 = []; var _iterator2 = _createForOfIteratorHelper(rawList), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var item = _step2.value; var plusKey = "".concat(item, "-plus"); var key = "".concat(item); var tempKey = string_random.randomString(6); var preAndPostfixList = [['"', '"'], [' ', ' ']]; for (var _i = 0, _preAndPostfixList = preAndPostfixList; _i < _preAndPostfixList.length; _i++) { var prefix = _preAndPostfixList[_i]; list.push(["".concat(prefix[0]).concat(string_string.pascalCase(plusKey)).concat(prefix[1]), "".concat(prefix[0]).concat(tempKey).concat(prefix[1])]); list2.push(["".concat(prefix[0]).concat(string_string.pascalCase(key)).concat(prefix[1]), "".concat(prefix[0]).concat(string_string.pascalCase(plusKey)).concat(prefix[1])]); list3.push(["".concat(prefix[0]).concat(tempKey).concat(prefix[1]), "".concat(prefix[0]).concat(string_string.pascalCase(key)).concat(prefix[1])]); } } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } return [{ list: list, dirList: dirList }, { list: list2, dirList: dirList }, { list: list3, dirList: dirList }]; } /** * 生成文件内容的三阶段替换规则(kebab-case + PascalCase + 类名) * @param {string[]} rawList - 组件名列表 * @param {string[]} dirList - 目标文件 glob 列表 * @param {Object} [options={}] - 可选配置 * @param {string[]} [options.needClassReplaceList=[]] - 需要额外替换类名的组件列表 * @returns {Array<{ list: Array, dirList: string[] }>} * @example * ```ts * const rules = getComponentContentReplaceRules( * ['dialog', 'icon'], * ['src/**\/*.{ts,vue,less}'], * { needClassReplaceList: ['icon'] }, * ); * batchReplaceFileContent(rules); * ``` */ function getComponentContentReplaceRules(rawList, dirList) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var _options$needClassRep = options.needClassReplaceList, needClassReplaceList = _options$needClassRep === void 0 ? [] : _options$needClassRep; var list = []; var list2 = []; var list3 = []; // kebab-case 前后缀匹配规则 var preAndPostfixList = [['/', '/'], ['/', '\''], ['/', '"'], ['/', '.vue'], ['<', ''], ['</', '>']]; var _iterator3 = _createForOfIteratorHelper(rawList), _step3; try { for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { var item = _step3.value; var plusKey = "press-".concat(item, "-plus"); var key = "press-".concat(item); var tempKey = string_random.randomString(6); var tempKey2 = string_random.randomString(6); // kebab-case 替换 var _iterator5 = _createForOfIteratorHelper(preAndPostfixList), _step5; try { for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) { var prefix = _step5.value; list.push(["".concat(prefix[0]).concat(plusKey).concat(prefix[1]), "".concat(prefix[0]).concat(tempKey).concat(prefix[1])]); list2.push(["".concat(prefix[0]).concat(key).concat(prefix[1]), "".concat(prefix[0]).concat(plusKey).concat(prefix[1])]); list3.push(["".concat(prefix[0]).concat(tempKey).concat(prefix[1]), "".concat(prefix[0]).concat(key).concat(prefix[1])]); } // PascalCase 替换(使用正则) } catch (err) { _iterator5.e(err); } finally { _iterator5.f(); } list.push([getComponentPascalReg(plusKey), string_string.pascalCase(tempKey2)]); list.push([getComponentPascalReg(key), string_string.pascalCase(plusKey)]); list.push([getComponentPascalReg(tempKey2), string_string.pascalCase(key)]); } // CSS 类名替换规则 } catch (err) { _iterator3.e(err); } finally { _iterator3.f(); } var classPrefixList = [['.', ' '], ['.', ','], ['.', '-'], ['', ';'], ['', '__'], ['', '--'], ['\'', '\''] // press-icon-plus (iconPrefix) ]; var _iterator4 = _createForOfIteratorHelper(needClassReplaceList), _step4; try { for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) { var _item = _step4.value; var _plusKey = "press-".concat(_item, "-plus"); var _key = "press-".concat(_item); var _tempKey = string_random.randomString(6); var _iterator6 = _createForOfIteratorHelper(classPrefixList), _step6; try { for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) { var _prefix = _step6.value; list.push(["".concat(_prefix[0]).concat(_plusKey).concat(_prefix[1]), "".concat(_prefix[0]).concat(_tempKey).concat(_prefix[1])]); list2.push(["".concat(_prefix[0]).concat(_key).concat(_prefix[1]), "".concat(_prefix[0]).concat(_plusKey).concat(_prefix[1])]); list3.push(["".concat(_prefix[0]).concat(_tempKey).concat(_prefix[1]), "".concat(_prefix[0]).concat(_key).concat(_prefix[1])]); } } catch (err) { _iterator6.e(err); } finally { _iterator6.f(); } } } catch (err) { _iterator4.e(err); } finally { _iterator4.f(); } return [{ list: list, dirList: dirList }, { list: list2, dirList: dirList }, { list: list3, dirList: dirList }]; } /** * 批量替换文件内容(性能优化版) * 将同 dirList 的规则合并,每个文件只读写一次 * @param {Array<{ list: Array, dirList: string|string[] }>} replaceList - 替换规则列表 * @example * ```ts * batchReplaceFileContent([ * { * list: [ * ['<PressIconPlus', '<PressIcon'], * [/press-icon-plus/g, 'press-icon'], * ], * dirList: ['src/**\/*.vue'], * }, * ]); * // 同 dirList 的规则会被合并,避免重复读写 * ``` */ function batchReplaceFileContent(replaceList) { // 按 dirList 分组,将相同 dirList 的规则合并 var groupMap = new Map(); var _iterator7 = _createForOfIteratorHelper(replaceList), _step7; try { for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) { var _groupMap$get$rules; var item = _step7.value; var dirList = item.dirList, list = item.list; if (!(list === null || list === void 0 ? void 0 : list.length)) continue; var newDir = Array.isArray(dirList) ? dirList : [dirList]; var dirKey = JSON.stringify(newDir.sort()); if (!groupMap.has(dirKey)) { groupMap.set(dirKey, { dirList: newDir, rules: [] }); } (_groupMap$get$rules = groupMap.get(dirKey).rules).push.apply(_groupMap$get$rules, _toConsumableArray__default["default"](list)); } } catch (err) { _iterator7.e(err); } finally { _iterator7.f(); } var glob = thirdParty_glob.getGlob(); var _iterator8 = _createForOfIteratorHelper(groupMap), _step8; try { for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) { var _step8$value = _slicedToArray__default["default"](_step8.value, 2), _step8$value$ = _step8$value[1], _dirList = _step8$value$.dirList, rules = _step8$value$.rules; var files = _toConsumableArray__default["default"](new Set(_dirList.flatMap(function (pattern) { return glob.sync(pattern); }))); var _iterator9 = _createForOfIteratorHelper(files), _step9; try { for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) { var file = _step9.value; if (fs__default["default"].statSync(file).isDirectory()) continue; var content = fs__default["default"].readFileSync(file, 'utf-8'); var changed = false; var _iterator0 = _createForOfIteratorHelper(rules), _step0; try { for (_iterator0.s(); !(_step0 = _iterator0.n()).done;) { var _step0$value = _slicedToArray__default["default"](_step0.value, 2), from = _step0$value[0], to = _step0$value[1]; var newContent = typeof from === 'string' ? content.replaceAll(from, to) : content.replace(from, to); if (newContent !== content) { content = newContent; changed = true; } } } catch (err) { _iterator0.e(err); } finally { _iterator0.f(); } if (changed) { fs__default["default"].writeFileSync(file, content); console.log("[batchReplaceFileContent]: \u6587\u4EF6: ".concat(file)); } } } catch (err) { _iterator9.e(err); } finally { _iterator9.f(); } } } catch (err) { _iterator8.e(err); } finally { _iterator8.f(); } } /** * 批量重命名文件和文件夹(同步版本) * @param {string} dirPath - 要处理的目录路径 * @param {Object} renameConfig - 重命名配置对象 { 旧名称: 新名称 } * @param {boolean} [recursive=true] - 是否递归处理子目录 * @example * ```ts * batchRenameDirEntries('src/components', { * 'press-icon-plus': 'press-icon', * 'press-dialog-plus': 'press-dialog', * }); * // 递归将 src/components 下名为 press-icon-plus、press-dialog-plus 的文件/文件夹重命名 * * // 只重命名当前层、不递归 * batchRenameDirEntries('src/components', { 'a': 'b' }, false); * ``` */ function batchRenameDirEntries(dirPath, renameConfig) { var recursive = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; try { var items = fs__default["default"].readdirSync(dirPath, { withFileTypes: true }); var _iterator1 = _createForOfIteratorHelper(items), _step1; try { for (_iterator1.s(); !(_step1 = _iterator1.n()).done;) { var item = _step1.value; var oldPath = path__default["default"].join(dirPath, item.name); var newName = item.name; var _loop = function _loop() { var _Object$entries$_i = _slicedToArray__default["default"](_Object$entries[_i2], 2), oldName = _Object$entries$_i[0], newNamePart = _Object$entries$_i[1]; var oldNameReg = new RegExp("^".concat(oldName, "(\\.\\w+)$")); if (item.name === oldName) { newName = newNamePart; return 0; // break } else if (oldNameReg.test(item.name)) { newName = item.name.replace(oldNameReg, function (_, postfix) { return newNamePart + postfix; }); return 0; // break } }, _ret; for (var _i2 = 0, _Object$entries = Object.entries(renameConfig); _i2 < _Object$entries.length; _i2++) { _ret = _loop(); if (_ret === 0) break; } if (newName !== item.name) { var newPath = path__default["default"].join(dirPath, newName); console.log("[batchRenameDirEntries]: ".concat(oldPath, " -> ").concat(newPath)); fs__default["default"].renameSync(oldPath, newPath); } if (recursive && item.isDirectory()) { var currentPath = newName !== item.name ? path__default["default"].join(dirPath, newName) : oldPath; batchRenameDirEntries(currentPath, renameConfig, recursive); } } } catch (err) { _iterator1.e(err); } finally { _iterator1.f(); } } catch (error) { console.error("[batchRenameDirEntries] Error processing directory ".concat(dirPath, ":"), error); } } exports.batchRenameDirEntries = batchRenameDirEntries; exports.batchReplaceFileContent = batchReplaceFileContent; exports.getComponentContentReplaceRules = getComponentContentReplaceRules; exports.getComponentPascalReg = getComponentPascalReg; exports.getMetaConfigPascalReplaceRules = getMetaConfigPascalReplaceRules; exports.getThreeStageRenameConfig = getThreeStageRenameConfig;