@lmcc-dev/mult-fetch-mcp-server 1.3.0 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -15
- package/README.zh.md +31 -0
- package/dist/src/client.js +118 -91
- package/dist/src/lib/fetchers/browser/BrowserFetcher.js +25 -10
- package/dist/src/lib/fetchers/browser/BrowserInstance.js +67 -64
- package/dist/src/lib/fetchers/common/BaseFetcher.js +106 -10
- package/dist/src/lib/fetchers/common/types.js +10 -1
- package/dist/src/lib/fetchers/common/utils.js +1 -1
- package/dist/src/lib/fetchers/node/HttpClient.js +41 -21
- package/dist/src/lib/fetchers/node/NodeFetcher.js +24 -8
- package/dist/src/lib/i18n/index.js +2 -2
- package/dist/src/lib/i18n/keys/client.js +1 -0
- package/dist/src/lib/i18n/keys/extractor.js +26 -0
- package/dist/src/lib/i18n/keys/fetcher.js +12 -1
- package/dist/src/lib/i18n/keys/index.js +1 -0
- package/dist/src/lib/i18n/keys/node.js +2 -0
- package/dist/src/lib/i18n/locales/en/client.js +1 -0
- package/dist/src/lib/i18n/locales/en/extractor.js +24 -0
- package/dist/src/lib/i18n/locales/en/fetcher.js +3 -1
- package/dist/src/lib/i18n/locales/en/index.js +2 -0
- package/dist/src/lib/i18n/locales/en/node.js +2 -0
- package/dist/src/lib/i18n/locales/zh/client.js +1 -0
- package/dist/src/lib/i18n/locales/zh/extractor.js +22 -0
- package/dist/src/lib/i18n/locales/zh/fetcher.js +13 -3
- package/dist/src/lib/i18n/locales/zh/index.js +2 -0
- package/dist/src/lib/i18n/locales/zh/node.js +2 -0
- package/dist/src/lib/i18n/logger.js +2 -2
- package/dist/src/lib/logger.js +38 -17
- package/dist/src/lib/server/browser.js +2 -2
- package/dist/src/lib/server/fetcher.js +0 -3
- package/dist/src/lib/server/index.js +2 -2
- package/dist/src/lib/server/prompts.js +4 -4
- package/dist/src/lib/server/tools.js +127 -354
- package/dist/src/lib/utils/ChunkManager.js +2 -2
- package/dist/src/lib/utils/ContentExtractor.js +141 -0
- package/dist/src/lib/utils/ContentProcessor.js +5 -11
- package/dist/src/lib/utils/ContentSizeManager.js +2 -2
- package/dist/src/lib/utils/ErrorHandler.js +1 -0
- package/dist/src/lib/utils/TemplateUtils.js +6 -2
- package/dist/tests/client.test.js +1 -1
- package/dist/tests/test-extract-single.js +389 -0
- package/dist/tests/utils/ContentExtractor.test.js +173 -0
- package/dist/tests/utils/ContentProcessor.test.js +136 -0
- package/dist/tests/utils/TemplateUtils.test.js +118 -0
- package/package.json +14 -3
- package/dist/i18n-test-report.json +0 -8
- package/dist/i18n-unused-keys-report.json +0 -8
- package/dist/src/lib/BrowserFetcher.js +0 -787
- package/dist/src/lib/NodeFetcher.js +0 -492
- package/dist/src/lib/i18n/keys.js +0 -529
- package/dist/src/test-i18n.js +0 -139
- package/dist/tests/BrowserFetcher.test.js +0 -951
- package/dist/tests/NodeFetcher.test.js +0 -263
- package/dist/tests/i18n-remove-unused-keys.js +0 -236
- package/dist/tests/i18n-test-report.json +0 -2004
- package/dist/tests/src/lib/i18n/index.js +0 -108
- package/dist/tests/src/lib/i18n/keys/base.js +0 -47
- package/dist/tests/src/lib/i18n/keys/browser.js +0 -93
- package/dist/tests/src/lib/i18n/keys/client.js +0 -70
- package/dist/tests/src/lib/i18n/keys/errors.js +0 -34
- package/dist/tests/src/lib/i18n/keys/fetcher.js +0 -84
- package/dist/tests/src/lib/i18n/keys/index.js +0 -31
- package/dist/tests/src/lib/i18n/keys/node.js +0 -56
- package/dist/tests/src/lib/i18n/keys/prompts.js +0 -82
- package/dist/tests/src/lib/i18n/keys/resources.js +0 -50
- package/dist/tests/src/lib/i18n/keys/server.js +0 -64
- package/dist/tests/src/lib/i18n/keys/tools.js +0 -34
- package/dist/tests/src/lib/i18n/locales/en/browser.js +0 -88
- package/dist/tests/src/lib/i18n/locales/en/client.js +0 -66
- package/dist/tests/src/lib/i18n/locales/en/errors.js +0 -28
- package/dist/tests/src/lib/i18n/locales/en/fetcher.js +0 -71
- package/dist/tests/src/lib/i18n/locales/en/index.js +0 -29
- package/dist/tests/src/lib/i18n/locales/en/node.js +0 -51
- package/dist/tests/src/lib/i18n/locales/en/prompts.js +0 -52
- package/dist/tests/src/lib/i18n/locales/en/resources.js +0 -50
- package/dist/tests/src/lib/i18n/locales/en/server.js +0 -56
- package/dist/tests/src/lib/i18n/locales/en/tools.js +0 -28
- package/dist/tests/src/lib/i18n/locales/zh/browser.js +0 -87
- package/dist/tests/src/lib/i18n/locales/zh/client.js +0 -66
- package/dist/tests/src/lib/i18n/locales/zh/errors.js +0 -28
- package/dist/tests/src/lib/i18n/locales/zh/fetcher.js +0 -71
- package/dist/tests/src/lib/i18n/locales/zh/index.js +0 -29
- package/dist/tests/src/lib/i18n/locales/zh/node.js +0 -51
- package/dist/tests/src/lib/i18n/locales/zh/prompts.js +0 -53
- package/dist/tests/src/lib/i18n/locales/zh/resources.js +0 -50
- package/dist/tests/src/lib/i18n/locales/zh/server.js +0 -57
- package/dist/tests/src/lib/i18n/locales/zh/tools.js +0 -28
- package/dist/tests/src/lib/i18n/logger.js +0 -114
- package/dist/tests/src/lib/logger.js +0 -181
- package/dist/tests/tests/test-i18n.js +0 -588
- package/dist/vitest.config.js +0 -29
|
@@ -1,588 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Author: Martin <lmccc.dev@gmail.com>
|
|
4
|
-
* Co-Author: AI Assistant (Claude)
|
|
5
|
-
* Description: This code was collaboratively developed by Martin and AI Assistant.
|
|
6
|
-
*/
|
|
7
|
-
var __assign = (this && this.__assign) || function () {
|
|
8
|
-
__assign = Object.assign || function(t) {
|
|
9
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
10
|
-
s = arguments[i];
|
|
11
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
12
|
-
t[p] = s[p];
|
|
13
|
-
}
|
|
14
|
-
return t;
|
|
15
|
-
};
|
|
16
|
-
return __assign.apply(this, arguments);
|
|
17
|
-
};
|
|
18
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
19
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
20
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
21
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
22
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
23
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
24
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
25
|
-
});
|
|
26
|
-
};
|
|
27
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
28
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
29
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
30
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
31
|
-
function step(op) {
|
|
32
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
33
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
34
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
35
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
36
|
-
switch (op[0]) {
|
|
37
|
-
case 0: case 1: t = op; break;
|
|
38
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
39
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
40
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
41
|
-
default:
|
|
42
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
43
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
44
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
45
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
46
|
-
if (t[2]) _.ops.pop();
|
|
47
|
-
_.trys.pop(); continue;
|
|
48
|
-
}
|
|
49
|
-
op = body.call(thisArg, _);
|
|
50
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
51
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
55
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
56
|
-
if (ar || !(i in from)) {
|
|
57
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
58
|
-
ar[i] = from[i];
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
62
|
-
};
|
|
63
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
64
|
-
// 测试国际化功能 (Test internationalization functionality)
|
|
65
|
-
var logger_js_1 = require("../src/lib/logger.js");
|
|
66
|
-
var index_js_1 = require("../src/lib/i18n/index.js");
|
|
67
|
-
var index_js_2 = require("../src/lib/i18n/locales/en/index.js");
|
|
68
|
-
var index_js_3 = require("../src/lib/i18n/locales/zh/index.js");
|
|
69
|
-
var fs = require("fs");
|
|
70
|
-
var path = require("path");
|
|
71
|
-
var url_1 = require("url");
|
|
72
|
-
// 获取当前文件的目录路径 (Get the directory path of the current file)
|
|
73
|
-
var __filename = (0, url_1.fileURLToPath)(import.meta.url);
|
|
74
|
-
var __dirname = path.dirname(__filename);
|
|
75
|
-
// 导入所有键模块 (Import all key modules)
|
|
76
|
-
var allKeys = require("../src/lib/i18n/keys/index.js");
|
|
77
|
-
// 默认测试配置 (Default test configuration)
|
|
78
|
-
var defaultConfig = {
|
|
79
|
-
generateReport: true,
|
|
80
|
-
reportPath: path.join(__dirname, '../i18n-test-report.json'),
|
|
81
|
-
checkEmptyValues: true,
|
|
82
|
-
checkPlaceholders: true,
|
|
83
|
-
verbose: false,
|
|
84
|
-
testCache: false,
|
|
85
|
-
testSampleKeys: false
|
|
86
|
-
};
|
|
87
|
-
// 解析命令行参数 (Parse command line arguments)
|
|
88
|
-
function parseCommandLineArgs() {
|
|
89
|
-
var config = __assign({}, defaultConfig);
|
|
90
|
-
var args = process.argv.slice(2);
|
|
91
|
-
for (var i = 0; i < args.length; i++) {
|
|
92
|
-
var arg = args[i];
|
|
93
|
-
switch (arg) {
|
|
94
|
-
case '--no-report':
|
|
95
|
-
config.generateReport = false;
|
|
96
|
-
break;
|
|
97
|
-
case '--report-path':
|
|
98
|
-
if (i + 1 < args.length) {
|
|
99
|
-
config.reportPath = args[++i];
|
|
100
|
-
}
|
|
101
|
-
break;
|
|
102
|
-
case '--no-check-empty':
|
|
103
|
-
config.checkEmptyValues = false;
|
|
104
|
-
break;
|
|
105
|
-
case '--no-check-placeholders':
|
|
106
|
-
config.checkPlaceholders = false;
|
|
107
|
-
break;
|
|
108
|
-
case '--verbose':
|
|
109
|
-
config.verbose = true;
|
|
110
|
-
break;
|
|
111
|
-
case '--test-cache':
|
|
112
|
-
config.testCache = true;
|
|
113
|
-
break;
|
|
114
|
-
case '--test-sample-keys':
|
|
115
|
-
config.testSampleKeys = true;
|
|
116
|
-
break;
|
|
117
|
-
case '--help':
|
|
118
|
-
printHelp();
|
|
119
|
-
process.exit(0);
|
|
120
|
-
break;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
return config;
|
|
124
|
-
}
|
|
125
|
-
// 打印帮助信息 (Print help information)
|
|
126
|
-
function printHelp() {
|
|
127
|
-
console.log("\n\u56FD\u9645\u5316\u6D4B\u8BD5\u5DE5\u5177 (Internationalization Test Tool)\n\n\u7528\u6CD5: node --loader ts-node/esm tests/test-i18n.ts [\u9009\u9879]\n\n\u9009\u9879:\n --no-report \u4E0D\u751F\u6210\u62A5\u544A\u6587\u4EF6 (Don't generate report file)\n --report-path <path> \u6307\u5B9A\u62A5\u544A\u6587\u4EF6\u8DEF\u5F84 (Specify report file path)\n --no-check-empty \u4E0D\u68C0\u67E5\u7A7A\u503C (Don't check empty values)\n --no-check-placeholders \u4E0D\u68C0\u67E5\u5360\u4F4D\u7B26 (Don't check placeholders)\n --verbose \u663E\u793A\u8BE6\u7EC6\u4FE1\u606F (Show verbose information)\n --test-cache \u6D4B\u8BD5\u7FFB\u8BD1\u7F13\u5B58 (Test translation cache)\n --test-sample-keys \u6D4B\u8BD5\u6837\u4F8B\u952E (Test sample keys)\n --help \u663E\u793A\u5E2E\u52A9\u4FE1\u606F (Show help information)\n ");
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* 递归获取对象中的所有键 (Recursively get all keys in an object)
|
|
131
|
-
* @param obj 要获取键的对象 (Object to get keys from)
|
|
132
|
-
* @param prefix 键前缀 (Key prefix)
|
|
133
|
-
* @returns 键数组 (Array of keys)
|
|
134
|
-
*/
|
|
135
|
-
function getAllKeysFromObject(obj, prefix) {
|
|
136
|
-
if (prefix === void 0) { prefix = ''; }
|
|
137
|
-
var keys = [];
|
|
138
|
-
for (var key in obj) {
|
|
139
|
-
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
|
140
|
-
// 递归获取嵌套对象的键 (Recursively get keys of nested objects)
|
|
141
|
-
keys = __spreadArray(__spreadArray([], keys, true), getAllKeysFromObject(obj[key], prefix ? "".concat(prefix, ".").concat(key) : key), true);
|
|
142
|
-
}
|
|
143
|
-
else if (typeof obj[key] === 'string') {
|
|
144
|
-
// 添加字符串键 (Add string keys)
|
|
145
|
-
keys.push(prefix ? "".concat(prefix, ".").concat(key) : key);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
return keys;
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* 从键模块中获取所有键 (Get all keys from key modules)
|
|
152
|
-
* @returns 键数组 (Array of keys)
|
|
153
|
-
*/
|
|
154
|
-
function getAllKeysFromModules() {
|
|
155
|
-
var allKeysSet = new Set();
|
|
156
|
-
// 遍历所有键模块 (Iterate through all key modules)
|
|
157
|
-
for (var moduleKey in allKeys) {
|
|
158
|
-
var keyModule = allKeys[moduleKey];
|
|
159
|
-
if (typeof keyModule === 'object' && keyModule !== null) {
|
|
160
|
-
// 获取模块中的所有键 (Get all keys in the module)
|
|
161
|
-
var keysInModule = getAllKeysFromObject(keyModule);
|
|
162
|
-
keysInModule.forEach(function (key) { return allKeysSet.add(key); });
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
return Array.from(allKeysSet);
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* 获取翻译值 (Get translation value)
|
|
169
|
-
* @param key 键 (Key)
|
|
170
|
-
* @param translations 翻译资源 (Translation resources)
|
|
171
|
-
* @returns 翻译值 (Translation value)
|
|
172
|
-
*/
|
|
173
|
-
function getTranslationValue(key, translations) {
|
|
174
|
-
var parts = key.split('.');
|
|
175
|
-
var current = translations;
|
|
176
|
-
for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) {
|
|
177
|
-
var part = parts_1[_i];
|
|
178
|
-
if (current === undefined || current === null || typeof current !== 'object') {
|
|
179
|
-
return undefined;
|
|
180
|
-
}
|
|
181
|
-
current = current[part];
|
|
182
|
-
}
|
|
183
|
-
return current;
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* 检查键是否存在于翻译资源中 (Check if a key exists in translation resources)
|
|
187
|
-
* @param key 要检查的键 (Key to check)
|
|
188
|
-
* @param translations 翻译资源 (Translation resources)
|
|
189
|
-
* @returns 键是否存在 (Whether the key exists)
|
|
190
|
-
*/
|
|
191
|
-
function keyExistsInTranslations(key, translations) {
|
|
192
|
-
return getTranslationValue(key, translations) !== undefined;
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* 检查翻译值是否为空 (Check if a translation value is empty)
|
|
196
|
-
* @param key 键 (Key)
|
|
197
|
-
* @param translations 翻译资源 (Translation resources)
|
|
198
|
-
* @returns 翻译值是否为空 (Whether the translation value is empty)
|
|
199
|
-
*/
|
|
200
|
-
function isTranslationEmpty(key, translations) {
|
|
201
|
-
var value = getTranslationValue(key, translations);
|
|
202
|
-
return value === '' || value === null || value === undefined;
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* 提取占位符 (Extract placeholders)
|
|
206
|
-
* @param text 文本 (Text)
|
|
207
|
-
* @returns 占位符数组 (Array of placeholders)
|
|
208
|
-
*/
|
|
209
|
-
function extractPlaceholders(text) {
|
|
210
|
-
if (!text)
|
|
211
|
-
return [];
|
|
212
|
-
// 匹配 {{xxx}} 和 {xxx} 格式的占位符 (Match {{xxx}} and {xxx} format placeholders)
|
|
213
|
-
var placeholders = [];
|
|
214
|
-
var regex1 = /\{\{([^{}]+)\}\}/g;
|
|
215
|
-
var regex2 = /\{([^{}]+)\}/g;
|
|
216
|
-
var match;
|
|
217
|
-
while ((match = regex1.exec(text)) !== null) {
|
|
218
|
-
placeholders.push(match[1]);
|
|
219
|
-
}
|
|
220
|
-
while ((match = regex2.exec(text)) !== null) {
|
|
221
|
-
placeholders.push(match[1]);
|
|
222
|
-
}
|
|
223
|
-
return placeholders;
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* 检查占位符是否匹配 (Check if placeholders match)
|
|
227
|
-
* @param key 键 (Key)
|
|
228
|
-
* @param enValue 英文值 (English value)
|
|
229
|
-
* @param zhValue 中文值 (Chinese value)
|
|
230
|
-
* @returns 占位符是否匹配 (Whether placeholders match)
|
|
231
|
-
*/
|
|
232
|
-
function checkPlaceholdersMatch(key, enValue, zhValue) {
|
|
233
|
-
var enPlaceholders = extractPlaceholders(enValue);
|
|
234
|
-
var zhPlaceholders = extractPlaceholders(zhValue);
|
|
235
|
-
// 检查占位符数量是否相同 (Check if the number of placeholders is the same)
|
|
236
|
-
if (enPlaceholders.length !== zhPlaceholders.length) {
|
|
237
|
-
return false;
|
|
238
|
-
}
|
|
239
|
-
// 检查占位符名称是否相同 (Check if placeholder names are the same)
|
|
240
|
-
var enSet = new Set(enPlaceholders);
|
|
241
|
-
for (var _i = 0, zhPlaceholders_1 = zhPlaceholders; _i < zhPlaceholders_1.length; _i++) {
|
|
242
|
-
var placeholder = zhPlaceholders_1[_i];
|
|
243
|
-
if (!enSet.has(placeholder)) {
|
|
244
|
-
return false;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
return true;
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* 测试翻译键 (Test translation keys)
|
|
251
|
-
* @param keys 要测试的键数组 (Array of keys to test)
|
|
252
|
-
* @param language 语言 (Language)
|
|
253
|
-
*/
|
|
254
|
-
function testKeys(keys, language) {
|
|
255
|
-
console.log("\n=== \u6D4B\u8BD5 ".concat(language, " \u7FFB\u8BD1 (Testing ").concat(language, " translation) ==="));
|
|
256
|
-
for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
|
|
257
|
-
var key = keys_1[_i];
|
|
258
|
-
try {
|
|
259
|
-
var translated = (0, index_js_1.t)(key);
|
|
260
|
-
console.log("Key: ".concat(key));
|
|
261
|
-
console.log("Translation: ".concat(translated));
|
|
262
|
-
console.log('---');
|
|
263
|
-
}
|
|
264
|
-
catch (error) {
|
|
265
|
-
console.error("Error translating key: ".concat(key));
|
|
266
|
-
console.error(error);
|
|
267
|
-
console.log('---');
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* 测试日志函数 (Test log function)
|
|
273
|
-
* @param keys 要测试的键数组 (Array of keys to test)
|
|
274
|
-
* @param component 组件名称 (Component name)
|
|
275
|
-
*/
|
|
276
|
-
function testLogFunction(keys, component) {
|
|
277
|
-
console.log("\n=== \u6D4B\u8BD5\u65E5\u5FD7\u51FD\u6570 (Testing log function) ===");
|
|
278
|
-
for (var _i = 0, keys_2 = keys; _i < keys_2.length; _i++) {
|
|
279
|
-
var key = keys_2[_i];
|
|
280
|
-
try {
|
|
281
|
-
(0, logger_js_1.log)(key, true, {}, component);
|
|
282
|
-
}
|
|
283
|
-
catch (error) {
|
|
284
|
-
console.error("Error logging key: ".concat(key));
|
|
285
|
-
console.error(error);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* 测试带参数的翻译 (Test translation with parameters)
|
|
291
|
-
* @param keys 要测试的键数组 (Array of keys to test)
|
|
292
|
-
* @param params 参数对象 (Parameters object)
|
|
293
|
-
*/
|
|
294
|
-
function testWithParams(keys, params) {
|
|
295
|
-
console.log("\n=== \u6D4B\u8BD5\u5E26\u53C2\u6570\u7684\u7FFB\u8BD1 (Testing translation with parameters) ===");
|
|
296
|
-
for (var _i = 0, keys_3 = keys; _i < keys_3.length; _i++) {
|
|
297
|
-
var key = keys_3[_i];
|
|
298
|
-
try {
|
|
299
|
-
var translated = (0, index_js_1.t)(key, params);
|
|
300
|
-
console.log("Key: ".concat(key));
|
|
301
|
-
console.log("Params: ".concat(JSON.stringify(params)));
|
|
302
|
-
console.log("Translation: ".concat(translated));
|
|
303
|
-
console.log('---');
|
|
304
|
-
}
|
|
305
|
-
catch (error) {
|
|
306
|
-
console.error("Error translating key with params: ".concat(key));
|
|
307
|
-
console.error(error);
|
|
308
|
-
console.log('---');
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* 测试翻译缓存 (Test translation cache)
|
|
314
|
-
* @param key 要测试的键 (Key to test)
|
|
315
|
-
* @param iterations 迭代次数 (Number of iterations)
|
|
316
|
-
*/
|
|
317
|
-
function testTranslationCache(key, iterations) {
|
|
318
|
-
console.log("\n=== \u6D4B\u8BD5\u7FFB\u8BD1\u7F13\u5B58 (Testing translation cache) ===");
|
|
319
|
-
console.log("Key: ".concat(key));
|
|
320
|
-
console.log("Iterations: ".concat(iterations));
|
|
321
|
-
try {
|
|
322
|
-
// 清除翻译缓存 (Clear translation cache)
|
|
323
|
-
(0, logger_js_1.clearTranslationCache)();
|
|
324
|
-
// 测试不使用缓存的性能 (Test performance without cache)
|
|
325
|
-
console.log('Without cache:');
|
|
326
|
-
var startWithoutCache = Date.now();
|
|
327
|
-
for (var i = 0; i < iterations; i++) {
|
|
328
|
-
(0, index_js_1.t)(key);
|
|
329
|
-
}
|
|
330
|
-
var endWithoutCache = Date.now();
|
|
331
|
-
console.log("Time: ".concat(endWithoutCache - startWithoutCache, "ms"));
|
|
332
|
-
// 测试使用缓存的性能 (Test performance with cache)
|
|
333
|
-
console.log('With cache:');
|
|
334
|
-
var startWithCache = Date.now();
|
|
335
|
-
for (var i = 0; i < iterations; i++) {
|
|
336
|
-
(0, logger_js_1.log)(key, true, {}, logger_js_1.COMPONENTS.SERVER);
|
|
337
|
-
}
|
|
338
|
-
var endWithCache = Date.now();
|
|
339
|
-
console.log("Time: ".concat(endWithCache - startWithCache, "ms"));
|
|
340
|
-
}
|
|
341
|
-
catch (error) {
|
|
342
|
-
console.error('Error testing translation cache:');
|
|
343
|
-
console.error(error);
|
|
344
|
-
}
|
|
345
|
-
console.log('---');
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* 设置环境变量 (Set environment variable)
|
|
349
|
-
* @param name 环境变量名称 (Environment variable name)
|
|
350
|
-
* @param value 环境变量值 (Environment variable value)
|
|
351
|
-
*/
|
|
352
|
-
function setEnv(name, value) {
|
|
353
|
-
process.env[name] = value;
|
|
354
|
-
console.log("Set environment variable ".concat(name, "=").concat(value));
|
|
355
|
-
}
|
|
356
|
-
/**
|
|
357
|
-
* 生成测试报告 (Generate test report)
|
|
358
|
-
* @param report 报告对象 (Report object)
|
|
359
|
-
* @param reportPath 报告文件路径 (Report file path)
|
|
360
|
-
*/
|
|
361
|
-
function generateReport(report, reportPath) {
|
|
362
|
-
try {
|
|
363
|
-
var reportDir = path.dirname(reportPath);
|
|
364
|
-
if (!fs.existsSync(reportDir)) {
|
|
365
|
-
fs.mkdirSync(reportDir, { recursive: true });
|
|
366
|
-
}
|
|
367
|
-
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2), 'utf8');
|
|
368
|
-
console.log("\n\u2705 \u6D4B\u8BD5\u62A5\u544A\u5DF2\u751F\u6210: ".concat(reportPath, " (Test report generated: ").concat(reportPath, ")"));
|
|
369
|
-
}
|
|
370
|
-
catch (error) {
|
|
371
|
-
console.error("\n\u274C \u751F\u6210\u6D4B\u8BD5\u62A5\u544A\u5931\u8D25 (Failed to generate test report):", error);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
/**
|
|
375
|
-
* 检查所有键是否都有中英文对应 (Check if all keys have both English and Chinese translations)
|
|
376
|
-
* @param config 测试配置 (Test configuration)
|
|
377
|
-
*/
|
|
378
|
-
function checkAllKeysHaveTranslations(config) {
|
|
379
|
-
console.log('\n=== 检查所有键是否都有中英文对应 (Check if all keys have both English and Chinese translations) ===');
|
|
380
|
-
try {
|
|
381
|
-
// 获取所有键 (Get all keys)
|
|
382
|
-
var allKeys_2 = getAllKeysFromModules();
|
|
383
|
-
console.log("\u603B\u8BA1\u627E\u5230 ".concat(allKeys_2.length, " \u4E2A\u952E (Total keys found: ").concat(allKeys_2.length, ")"));
|
|
384
|
-
// 检查结果 (Check results)
|
|
385
|
-
var missingTranslations = [];
|
|
386
|
-
var emptyTranslations = [];
|
|
387
|
-
var placeholderMismatches = [];
|
|
388
|
-
// 检查每个键 (Check each key)
|
|
389
|
-
for (var _i = 0, allKeys_1 = allKeys_2; _i < allKeys_1.length; _i++) {
|
|
390
|
-
var key = allKeys_1[_i];
|
|
391
|
-
// 检查缺失的翻译 (Check missing translations)
|
|
392
|
-
var missingLanguages = [];
|
|
393
|
-
// 获取翻译值 (Get translation values)
|
|
394
|
-
var enValue = getTranslationValue(key, index_js_2.enTranslation);
|
|
395
|
-
var zhValue = getTranslationValue(key, index_js_3.zhTranslation);
|
|
396
|
-
// 检查英文翻译 (Check English translation)
|
|
397
|
-
if (enValue === undefined) {
|
|
398
|
-
missingLanguages.push('en');
|
|
399
|
-
}
|
|
400
|
-
// 检查中文翻译 (Check Chinese translation)
|
|
401
|
-
if (zhValue === undefined) {
|
|
402
|
-
missingLanguages.push('zh');
|
|
403
|
-
}
|
|
404
|
-
if (missingLanguages.length > 0) {
|
|
405
|
-
missingTranslations.push({ key: key, languages: missingLanguages });
|
|
406
|
-
}
|
|
407
|
-
// 如果两种语言的翻译都存在,进行进一步检查 (If translations for both languages exist, perform further checks)
|
|
408
|
-
if (enValue !== undefined && zhValue !== undefined) {
|
|
409
|
-
// 检查空值 (Check empty values)
|
|
410
|
-
if (config.checkEmptyValues) {
|
|
411
|
-
var emptyLanguages = [];
|
|
412
|
-
if (enValue === '') {
|
|
413
|
-
emptyLanguages.push('en');
|
|
414
|
-
}
|
|
415
|
-
if (zhValue === '') {
|
|
416
|
-
emptyLanguages.push('zh');
|
|
417
|
-
}
|
|
418
|
-
if (emptyLanguages.length > 0) {
|
|
419
|
-
emptyTranslations.push({ key: key, languages: emptyLanguages });
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
// 检查占位符 (Check placeholders)
|
|
423
|
-
if (config.checkPlaceholders && typeof enValue === 'string' && typeof zhValue === 'string') {
|
|
424
|
-
if (!checkPlaceholdersMatch(key, enValue, zhValue)) {
|
|
425
|
-
placeholderMismatches.push({ key: key, enValue: enValue, zhValue: zhValue });
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
// 输出结果 (Output results)
|
|
431
|
-
var hasIssues = false;
|
|
432
|
-
// 输出缺失的翻译 (Output missing translations)
|
|
433
|
-
if (missingTranslations.length > 0) {
|
|
434
|
-
hasIssues = true;
|
|
435
|
-
console.log("\n\u274C \u53D1\u73B0 ".concat(missingTranslations.length, " \u4E2A\u952E\u7F3A\u5C11\u7FFB\u8BD1 (Found ").concat(missingTranslations.length, " keys missing translations)"));
|
|
436
|
-
if (config.verbose) {
|
|
437
|
-
for (var _a = 0, missingTranslations_1 = missingTranslations; _a < missingTranslations_1.length; _a++) {
|
|
438
|
-
var _b = missingTranslations_1[_a], key = _b.key, languages = _b.languages;
|
|
439
|
-
console.log("\u952E (Key): ".concat(key));
|
|
440
|
-
console.log("\u7F3A\u5C11\u7FFB\u8BD1 (Missing translations for): ".concat(languages.join(', ')));
|
|
441
|
-
console.log('---');
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
// 输出空值 (Output empty values)
|
|
446
|
-
if (config.checkEmptyValues && emptyTranslations.length > 0) {
|
|
447
|
-
hasIssues = true;
|
|
448
|
-
console.log("\n\u274C \u53D1\u73B0 ".concat(emptyTranslations.length, " \u4E2A\u952E\u7684\u7FFB\u8BD1\u4E3A\u7A7A (Found ").concat(emptyTranslations.length, " keys with empty translations)"));
|
|
449
|
-
if (config.verbose) {
|
|
450
|
-
for (var _c = 0, emptyTranslations_1 = emptyTranslations; _c < emptyTranslations_1.length; _c++) {
|
|
451
|
-
var _d = emptyTranslations_1[_c], key = _d.key, languages = _d.languages;
|
|
452
|
-
console.log("\u952E (Key): ".concat(key));
|
|
453
|
-
console.log("\u7A7A\u503C\u8BED\u8A00 (Empty value languages): ".concat(languages.join(', ')));
|
|
454
|
-
console.log('---');
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
// 输出占位符不匹配 (Output placeholder mismatches)
|
|
459
|
-
if (config.checkPlaceholders && placeholderMismatches.length > 0) {
|
|
460
|
-
hasIssues = true;
|
|
461
|
-
console.log("\n\u274C \u53D1\u73B0 ".concat(placeholderMismatches.length, " \u4E2A\u952E\u7684\u5360\u4F4D\u7B26\u4E0D\u5339\u914D (Found ").concat(placeholderMismatches.length, " keys with placeholder mismatches)"));
|
|
462
|
-
if (config.verbose) {
|
|
463
|
-
for (var _e = 0, placeholderMismatches_1 = placeholderMismatches; _e < placeholderMismatches_1.length; _e++) {
|
|
464
|
-
var _f = placeholderMismatches_1[_e], key = _f.key, enValue = _f.enValue, zhValue = _f.zhValue;
|
|
465
|
-
console.log("\u952E (Key): ".concat(key));
|
|
466
|
-
console.log("\u82F1\u6587\u503C (English value): ".concat(enValue));
|
|
467
|
-
console.log("\u4E2D\u6587\u503C (Chinese value): ".concat(zhValue));
|
|
468
|
-
console.log("\u82F1\u6587\u5360\u4F4D\u7B26 (English placeholders): ".concat(extractPlaceholders(enValue).join(', ')));
|
|
469
|
-
console.log("\u4E2D\u6587\u5360\u4F4D\u7B26 (Chinese placeholders): ".concat(extractPlaceholders(zhValue).join(', ')));
|
|
470
|
-
console.log('---');
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
// 如果没有问题,输出成功信息 (If no issues, output success message)
|
|
475
|
-
if (!hasIssues) {
|
|
476
|
-
console.log('\n✅ 所有键都有正确的中英文对应 (All keys have correct English and Chinese translations)');
|
|
477
|
-
}
|
|
478
|
-
// 生成报告 (Generate report)
|
|
479
|
-
if (config.generateReport) {
|
|
480
|
-
var report = {
|
|
481
|
-
timestamp: new Date().toISOString(),
|
|
482
|
-
totalKeys: allKeys_2.length,
|
|
483
|
-
missingTranslations: missingTranslations,
|
|
484
|
-
emptyTranslations: config.checkEmptyValues ? emptyTranslations : [],
|
|
485
|
-
placeholderMismatches: config.checkPlaceholders ? placeholderMismatches : [],
|
|
486
|
-
hasIssues: hasIssues
|
|
487
|
-
};
|
|
488
|
-
generateReport(report, config.reportPath);
|
|
489
|
-
}
|
|
490
|
-
return {
|
|
491
|
-
missingTranslations: missingTranslations,
|
|
492
|
-
emptyTranslations: emptyTranslations,
|
|
493
|
-
placeholderMismatches: placeholderMismatches,
|
|
494
|
-
hasIssues: hasIssues
|
|
495
|
-
};
|
|
496
|
-
}
|
|
497
|
-
catch (error) {
|
|
498
|
-
console.error('\n❌ 检查翻译时出错 (Error checking translations):');
|
|
499
|
-
console.error(error);
|
|
500
|
-
return {
|
|
501
|
-
missingTranslations: [],
|
|
502
|
-
emptyTranslations: [],
|
|
503
|
-
placeholderMismatches: [],
|
|
504
|
-
hasIssues: true
|
|
505
|
-
};
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
/**
|
|
509
|
-
* 主测试函数 (Main test function)
|
|
510
|
-
*/
|
|
511
|
-
function testI18n() {
|
|
512
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
513
|
-
var config, checkResult, simpleKeys, error_1;
|
|
514
|
-
return __generator(this, function (_a) {
|
|
515
|
-
switch (_a.label) {
|
|
516
|
-
case 0:
|
|
517
|
-
console.log('=== 测试国际化功能 (Testing internationalization functionality) ===');
|
|
518
|
-
_a.label = 1;
|
|
519
|
-
case 1:
|
|
520
|
-
_a.trys.push([1, 5, , 6]);
|
|
521
|
-
config = parseCommandLineArgs();
|
|
522
|
-
checkResult = checkAllKeysHaveTranslations(config);
|
|
523
|
-
// 如果不需要进行其他测试,直接返回 (If no other tests are needed, return directly)
|
|
524
|
-
if (!config.testSampleKeys && !config.testCache) {
|
|
525
|
-
return [2 /*return*/, checkResult];
|
|
526
|
-
}
|
|
527
|
-
if (!config.testSampleKeys) return [3 /*break*/, 4];
|
|
528
|
-
simpleKeys = [
|
|
529
|
-
'server.starting',
|
|
530
|
-
'server.started',
|
|
531
|
-
'server.stopping',
|
|
532
|
-
'server.stopped'
|
|
533
|
-
];
|
|
534
|
-
// 确保 MCP_LANG 环境变量设置为英文 (Ensure MCP_LANG environment variable is set to English)
|
|
535
|
-
setEnv('MCP_LANG', 'en');
|
|
536
|
-
// 测试英文翻译 (Test English translation)
|
|
537
|
-
return [4 /*yield*/, (0, index_js_1.changeLanguage)('en')];
|
|
538
|
-
case 2:
|
|
539
|
-
// 测试英文翻译 (Test English translation)
|
|
540
|
-
_a.sent();
|
|
541
|
-
console.log("Current language: ".concat((0, index_js_1.getCurrentLanguage)()));
|
|
542
|
-
testKeys(simpleKeys, 'English');
|
|
543
|
-
// 测试日志函数 (Test log function)
|
|
544
|
-
testLogFunction(simpleKeys, logger_js_1.COMPONENTS.SERVER);
|
|
545
|
-
// 测试带参数的翻译 (Test translation with parameters)
|
|
546
|
-
testWithParams(['server.listeningOn'], { port: 8080 });
|
|
547
|
-
// 确保 MCP_LANG 环境变量设置为中文 (Ensure MCP_LANG environment variable is set to Chinese)
|
|
548
|
-
setEnv('MCP_LANG', 'zh');
|
|
549
|
-
// 测试中文翻译 (Test Chinese translation)
|
|
550
|
-
return [4 /*yield*/, (0, index_js_1.changeLanguage)('zh')];
|
|
551
|
-
case 3:
|
|
552
|
-
// 测试中文翻译 (Test Chinese translation)
|
|
553
|
-
_a.sent();
|
|
554
|
-
console.log("Current language: ".concat((0, index_js_1.getCurrentLanguage)()));
|
|
555
|
-
testKeys(simpleKeys, 'Chinese');
|
|
556
|
-
// 测试日志函数 (Test log function)
|
|
557
|
-
testLogFunction(simpleKeys, logger_js_1.COMPONENTS.SERVER);
|
|
558
|
-
// 测试带参数的翻译 (Test translation with parameters)
|
|
559
|
-
testWithParams(['server.listeningOn'], { port: 8080 });
|
|
560
|
-
_a.label = 4;
|
|
561
|
-
case 4:
|
|
562
|
-
// 测试翻译缓存 (Test translation cache)
|
|
563
|
-
if (config.testCache) {
|
|
564
|
-
testTranslationCache('server.starting', 10);
|
|
565
|
-
}
|
|
566
|
-
// 返回检查结果 (Return check result)
|
|
567
|
-
return [2 /*return*/, checkResult];
|
|
568
|
-
case 5:
|
|
569
|
-
error_1 = _a.sent();
|
|
570
|
-
console.error('测试过程中出错 (Error during testing):');
|
|
571
|
-
console.error(error_1);
|
|
572
|
-
return [2 /*return*/, {
|
|
573
|
-
missingTranslations: [],
|
|
574
|
-
emptyTranslations: [],
|
|
575
|
-
placeholderMismatches: [],
|
|
576
|
-
hasIssues: true
|
|
577
|
-
}];
|
|
578
|
-
case 6: return [2 /*return*/];
|
|
579
|
-
}
|
|
580
|
-
});
|
|
581
|
-
});
|
|
582
|
-
}
|
|
583
|
-
// 运行测试 (Run test)
|
|
584
|
-
testI18n().catch(function (error) {
|
|
585
|
-
console.error('运行测试时出错 (Error running test):');
|
|
586
|
-
console.error(error);
|
|
587
|
-
process.exit(1);
|
|
588
|
-
});
|
package/dist/vitest.config.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Author: Martin <lmccc.dev@gmail.com>
|
|
3
|
-
* Co-Author: AI Assistant (Claude)
|
|
4
|
-
* Description: This code was collaboratively developed by Martin and AI Assistant.
|
|
5
|
-
*/
|
|
6
|
-
import { defineConfig } from 'vitest/config';
|
|
7
|
-
export default defineConfig({
|
|
8
|
-
test: {
|
|
9
|
-
environment: 'node',
|
|
10
|
-
include: ['tests/**/*.test.ts'],
|
|
11
|
-
exclude: ['node_modules', 'dist'],
|
|
12
|
-
globals: true, // 启用全局测试 API,如 describe, it, expect 等
|
|
13
|
-
setupFiles: ['./tests/setup.ts'], // 添加设置文件
|
|
14
|
-
coverage: {
|
|
15
|
-
provider: 'v8',
|
|
16
|
-
reporter: ['text', 'json', 'html'],
|
|
17
|
-
include: ['src/**/*.ts'],
|
|
18
|
-
exclude: ['src/**/*.d.ts', 'src/**/*.test.ts']
|
|
19
|
-
},
|
|
20
|
-
deps: {
|
|
21
|
-
// 处理 ESM 模块
|
|
22
|
-
interopDefault: true
|
|
23
|
-
},
|
|
24
|
-
// 模拟 Jest 的 transformIgnorePatterns
|
|
25
|
-
testTransformMode: {
|
|
26
|
-
web: ['node_modules/(?!(@modelcontextprotocol)/)']
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
});
|