Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

mtong-tools

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mtong-tools - npm Package Compare versions

Comparing version
2.0.4
to
3.0.6
+14
-1
bin/index.js

@@ -34,3 +34,5 @@ #!/usr/bin/env node

.description('输出多语言配置')
.option('-file, --path <url>', '自定义多语言路径')
.option('-x, --xlsx', '反向输出xlsx文件')
.option('-n, --noKey', '关闭多语言key-map功能')
.option('-f, --file <url>', '自定义多语言路径')
.action((options) => {

@@ -40,3 +42,14 @@ require('./lang')(options)

program.command('help')
.description('查看帮助')
.action(() => {
console.log(`
mt create <app-name> 创建一个新的项目
mt download 更新公用代码到业务仓库
mt lang 输出多语言配置
`)
})
program.version(require('../package.json').version, '-v, --version')
program.parse(process.argv)
+188
-66

@@ -1,75 +0,197 @@

const {error} = require('../utils')
const fs = require('fs-extra');
const path = require('path')
const jsonFile = require('jsonfile')
const xlsx = require('node-xlsx')
const Path = require('path')
const chalk = require('chalk')
const { error } = require("../utils");
const fs = require("fs-extra");
const path = require("path");
const jsonFile = require("jsonfile");
const xlsx = require("node-xlsx");
const Path = require("path");
const chalk = require("chalk");
const _ = require("lodash");
async function createLang(options) {
try {
const cwd = options.cwd || process.cwd()
let file = options.path
const json = path.join(cwd, './package.json');
const jsonData = jsonFile.readFileSync(json);
if (!file) {
file = path.join(cwd, jsonData.lang.path)
// 🔧 工具:展开嵌套 key(用于 isMap=true)
function flattenKeys(obj, prefix = "") {
let keys = [];
for (const k in obj) {
const path = prefix ? `${prefix}.${k}` : k;
if (_.isObject(obj[k]) && !Array.isArray(obj[k])) {
keys = keys.concat(flattenKeys(obj[k], path));
} else {
keys.push(path);
}
const outPath = Path.join(cwd, jsonData.lang.outPath || 'lang')
const suffix = jsonData.lang.suffix || 'js'
}
return keys;
}
if (file) {
const sheets = xlsx.parse(file)
const sheet = sheets[0].data
const data = {}, keys = sheet[0].map(item => item.toLocaleLowerCase());
const enumMap = {}
for (let i = 1; i < keys.length; i++) {
const key = keys[i]
if (key) data[key] = {
message: {}
}
const xlsxToJson = async (params) => {
const { filePath, isMap = true, outPath, suffix } = params;
const enumKey = key.toLocaleUpperCase()
enumMap[enumKey] = key
}
for (let i = 1; i < sheet.length; i++) {
const lang = sheet[i]
const key = lang[0]
for (let j = 1; j < lang.length; j++) {
if (keys[j] && key) {
data[keys[j]].message[key] = lang[j] || ''
if (filePath) {
const sheets = xlsx.parse(filePath);
const sheet = sheets[0].data;
const data = {},
keys = sheet[0].map((item) => item.toLocaleLowerCase());
const enumMap = {};
for (let i = 1; i < keys.length; i++) {
const key = keys[i];
if (!key) continue;
data[key] = {
message: {},
};
const enumKey = key.toLocaleUpperCase();
enumMap[enumKey] = key;
}
for (let i = 1; i < sheet.length; i++) {
const lang = sheet[i];
const key = lang[0];
for (let j = 1; j < lang.length; j++) {
if (keys[j] && key && lang[j]) {
if (isMap) {
_.set(data[keys[j]].message, key, lang[j]);
} else {
data[keys[j]].message[key] = lang[j];
}
}
}
}
Object.entries(data).forEach(([key, data]) => {
let str = `const ${key} = `
str += JSON.stringify(data, "", "\t")
str += '\n\n'
str += `export default ${key}`
if (!fs.existsSync(outPath)) {
fs.mkdirSync(outPath)
}
const file = Path.join(outPath, `${key}.${suffix}`)
fs.outputFileSync(file, str)
})
Object.entries(data).forEach(([key, data]) => {
let str = `const ${key} = `;
str += JSON.stringify(data, "", "\t");
str += "\n\n";
str += `export default ${key}`;
if (!fs.existsSync(outPath)) {
fs.mkdirSync(outPath);
}
const file = Path.join(outPath, `${key}.${suffix}`);
fs.outputFileSync(file, str);
});
let str = suffix === 'ts' ? 'enum I18nMessageType {\n' : 'export default {\n'
Object.entries(enumMap).forEach(([key, value]) => {
str += ` ${key} = '${value}',\n`
})
str += `}`
const isTs = suffix === "ts";
if(suffix === 'ts') {
str += '\nexport default I18nMessageType'
}
let str = isTs ? "enum I18nMessageType {\n" : "export default {\n";
const connector = isTs ? " = " : ": ";
Object.entries(enumMap).forEach(([key, value]) => {
str += ` ${key} ${connector} '${value}',\n`;
});
str += `}`;
const fileEnmu = Path.join(outPath, `index.${suffix}`)
fs.outputFileSync(fileEnmu, str)
if (isTs) {
str += "\nexport default I18nMessageType";
}
console.log(`多语言生成成功:${chalk.blue(file)}-${chalk.yellow(outPath)}`)
process.exit(0)
const fileEnmu = Path.join(outPath, `index.${suffix}`);
fs.outputFileSync(fileEnmu, str);
}
console.log(
`多语言生成成功:${chalk.blue(filePath)}-${chalk.yellow(outPath)}`
);
};
const jsonToXlsx = async (params) => {
const { outPath, suffix } = params;
// 1️⃣ 读取所有语言文件
const files = fs
.readdirSync(outPath)
.filter(
(file) => file.endsWith(`.${suffix}`) && file !== `index.${suffix}`
);
if (files.length === 0) {
console.log(chalk.yellow(`No ${suffix} files found in the directory`));
return;
}
const langs = files.map((file) => Path.basename(file, `.${suffix}`));
const messagesMap = {};
const prefix = ["en", "EN", "cn", "CN", "zh", "ZH"];
prefix.forEach((lang) => {
const index = langs.indexOf(lang);
if (index !== -1) {
langs.unshift(...langs.splice(index, 1)); // 将匹配的语言移到第一个位置
}
});
langs.forEach((lang) => {
const file = Path.join(outPath, `${lang}.${suffix}`);
const content = fs.readFileSync(file, "utf-8").trim();
const formula = content
.replace(/export\s+default\s+/, "return ") // 去掉 export default
.replace(/;$/, "") // 去掉末尾 ;
.trim();
const contentMap = new Function(formula)();
messagesMap[lang] = contentMap.message;
});
// 2️⃣ 生成完整 key 列表
const keysSet = new Set();
langs.forEach((lang) => {
const messages = messagesMap[lang];
const flatKeys = flattenKeys(messages);
flatKeys.forEach((key) => keysSet.add(key));
});
const keys = Array.from(keysSet);
// 3️⃣ 生成 Excel 二维数组
const sheet = [];
const header = ["STRID", ...langs].map((lang) => lang.toLocaleUpperCase());
sheet.push(header);
keys.forEach((key) => {
const row = [key];
langs.forEach((lang) => {
const messages = messagesMap[lang];
const value = _.get(messages, key, "");
row.push(value);
});
sheet.push(row);
});
// 4️⃣ 写入 Excel 文件
const buffer = xlsx.build([{ name: "Sheet1", data: sheet }]);
const outputFile = Path.join(outPath, "lang_new.xlsx");
fs.writeFileSync(outputFile, buffer);
console.log(`多语言 xlsx 生成成功:${chalk.blue(outputFile)}`);
};
async function createLang(options) {
const { xlsx, noKey, file } = options;
try {
const cwd = options.cwd || process.cwd();
let filePath = file;
const json = path.join(cwd, "./package.json");
const jsonData = jsonFile.readFileSync(json);
if (!filePath) {
filePath = path.join(cwd, jsonData.lang.path);
}
const outPath = Path.join(cwd, jsonData.lang.outPath || "lang");
const outXlsxPath = Path.join(cwd, jsonData.lang.outXlsxPath || "lang");
const suffix = jsonData.lang.suffix || "js";
if (xlsx) {
await jsonToXlsx({
filePath: filePath,
outPath: outXlsxPath,
suffix,
});
} else {
await xlsxToJson({
filePath: filePath,
isMap: !noKey,
outPath: outPath,
suffix,
});
}
process.exit(0);
} catch (e) {
error(e)
process.exit(1)
error(e);
process.exit(1);
}

@@ -79,6 +201,6 @@ }

module.exports = (...args) => {
return createLang(...args).catch(err => {
error(err)
process.exit(1)
})
}
return createLang(...args).catch((err) => {
error(err);
process.exit(1);
});
};
{
"name": "mtong-tools",
"version": "2.0.4",
"version": "3.0.6",
"description": "mt cli",

@@ -26,2 +26,3 @@ "bin": {

"jsonfile": "^6.1.0",
"loadsh": "^0.0.4",
"node-xlsx": "^0.17.1",

@@ -34,3 +35,4 @@ "semver": "^7.3.5",

"outPath": "test/lang",
"suffix": "ts"
"outXlsxPath": "test/lang",
"suffix": "js"
},

@@ -37,0 +39,0 @@ "framework": {

@@ -14,7 +14,14 @@ # MOONTON 常用工具

```shell
# 编译多语言
# 编译多语言 配置在 package.json 中的lang 具体参考底部
mt lang
# 忽略多级对象配置输出
mt lang -n
# 反向多语言配置 转 xlsx
mt lang -x
```
项目根目录下执行,同步公用代码到业务项目,同步公用依赖到业务依赖
```shell

@@ -24,5 +31,7 @@ # 同步指定公用代码

```
业务项目中公用代码指定方式
package.json
```text

@@ -33,4 +42,10 @@ ...

"branch": "master"
},
"lang": {
"path": "test/lang.xlsx", // 多语言文件路径
"outPath": "test/lang", // 输出路径
"outXlsxPath": "test/lang", // 输出xlsx路径
"suffix": "ts" // 输出文件后缀
}
...
```
```