@lmcc-dev/mult-fetch-mcp-server 1.0.3 → 1.2.0
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 +11 -9
- package/README.zh.md +19 -10
- package/dist/i18n-test-report.json +8 -0
- package/dist/i18n-unused-keys-report.json +8 -0
- package/dist/src/client.js +75 -62
- package/dist/src/index.js +0 -0
- package/dist/src/lib/BrowserFetcher.js +12 -12
- package/dist/src/lib/NodeFetcher.js +165 -106
- package/dist/src/lib/fetch.js +40 -0
- package/dist/src/lib/fetchers/FetcherFactory.js +43 -0
- package/dist/src/lib/fetchers/browser/BrowserFetcher.js +381 -0
- package/dist/src/lib/fetchers/browser/BrowserInstance.js +180 -0
- package/dist/src/lib/fetchers/browser/PageOperations.js +168 -0
- package/dist/src/lib/fetchers/common/types.js +41 -0
- package/dist/src/lib/fetchers/common/utils.js +141 -0
- package/dist/src/lib/fetchers/index.js +62 -0
- package/dist/src/lib/fetchers/node/HttpClient.js +239 -0
- package/dist/src/lib/fetchers/node/NodeFetcher.js +180 -0
- package/dist/src/lib/i18n/index.js +105 -17
- package/dist/src/lib/i18n/keys/base.js +41 -0
- package/dist/src/lib/i18n/keys/browser.js +91 -0
- package/dist/src/lib/i18n/keys/client.js +68 -0
- package/dist/src/lib/i18n/keys/errors.js +49 -0
- package/dist/src/lib/i18n/keys/factory.js +46 -0
- package/dist/src/lib/i18n/keys/fetcher.js +87 -0
- package/dist/src/lib/i18n/keys/index.js +16 -0
- package/dist/src/lib/i18n/keys/node.js +69 -0
- package/dist/src/lib/i18n/keys/prompts.js +79 -0
- package/dist/src/lib/i18n/keys/resources.js +53 -0
- package/dist/src/lib/i18n/keys/server.js +67 -0
- package/dist/src/lib/i18n/keys/tools.js +39 -0
- package/dist/src/lib/i18n/keys.js +504 -0
- package/dist/src/lib/i18n/locales/en/browser.js +79 -55
- package/dist/src/lib/i18n/locales/en/client.js +57 -33
- package/dist/src/lib/i18n/locales/en/errors.js +36 -12
- package/dist/src/lib/i18n/locales/en/factory.js +38 -0
- package/dist/src/lib/i18n/locales/en/fetcher.js +67 -60
- package/dist/src/lib/i18n/locales/en/index.js +9 -7
- package/dist/src/lib/i18n/locales/en/node.js +57 -35
- package/dist/src/lib/i18n/locales/en/prompts.js +42 -65
- package/dist/src/lib/i18n/locales/en/resources.js +52 -40
- package/dist/src/lib/i18n/locales/en/server.js +49 -24
- package/dist/src/lib/i18n/locales/en/tools.js +27 -19
- package/dist/src/lib/i18n/locales/zh/browser.js +79 -56
- package/dist/src/lib/i18n/locales/zh/client.js +57 -32
- package/dist/src/lib/i18n/locales/zh/errors.js +36 -12
- package/dist/src/lib/i18n/locales/zh/factory.js +38 -0
- package/dist/src/lib/i18n/locales/zh/fetcher.js +67 -60
- package/dist/src/lib/i18n/locales/zh/index.js +9 -7
- package/dist/src/lib/i18n/locales/zh/node.js +61 -36
- package/dist/src/lib/i18n/locales/zh/prompts.js +35 -57
- package/dist/src/lib/i18n/locales/zh/resources.js +51 -39
- package/dist/src/lib/i18n/locales/zh/server.js +51 -25
- package/dist/src/lib/i18n/locales/zh/tools.js +27 -19
- package/dist/src/lib/i18n/logger.js +90 -19
- package/dist/src/lib/logger.js +135 -14
- package/dist/src/lib/server/browser.js +12 -18
- package/dist/src/lib/server/fetcher.js +13 -34
- package/dist/src/lib/server/index.js +2 -2
- package/dist/src/lib/server/prompts.js +1 -1
- package/dist/src/lib/server/resources.js +1 -1
- package/dist/src/lib/server/tools.js +404 -308
- package/dist/src/lib/utils/ErrorHandler.js +125 -0
- package/dist/src/lib/utils/errorDetection.js +41 -0
- package/dist/src/lib/utils/errors.js +279 -0
- package/dist/src/mcp-server.js +0 -0
- package/dist/src/test-i18n.js +139 -0
- package/dist/tests/BrowserFetcher.test.js +951 -0
- package/dist/tests/NodeFetcher.test.js +263 -0
- package/dist/tests/client.test.js +211 -0
- package/dist/tests/fetch.test.js +70 -0
- package/dist/tests/fetchers/Fetcher.test.js +108 -0
- package/dist/tests/fetchers/browser/BrowserFetcher.test.js +195 -0
- package/dist/tests/fetchers/browser/BrowserInstance.test.js +163 -0
- package/dist/tests/fetchers/node/NodeFetcher.test.js +211 -0
- package/dist/tests/i18n-missing-keys.js +364 -0
- package/dist/tests/i18n-remove-unused-keys.js +236 -0
- package/dist/tests/i18n-test-report.json +2004 -0
- package/dist/tests/i18n-unused-keys.js +425 -0
- package/dist/tests/i18n.test.js +178 -0
- package/dist/tests/logger.test.js +100 -0
- package/dist/tests/mcp-server.test.js +113 -0
- package/dist/tests/server/browser.test.js +201 -0
- package/dist/tests/server/fetcher.test.js +173 -0
- package/dist/tests/server/index.test.js +122 -0
- package/dist/tests/server/prompts.test.js +246 -0
- package/dist/tests/server/resources.test.js +395 -0
- package/dist/tests/server/tools.test.js +223 -0
- package/dist/tests/setup.js +36 -0
- package/dist/tests/src/lib/i18n/index.js +108 -0
- package/dist/tests/src/lib/i18n/keys/base.js +47 -0
- package/dist/tests/src/lib/i18n/keys/browser.js +93 -0
- package/dist/tests/src/lib/i18n/keys/client.js +70 -0
- package/dist/tests/src/lib/i18n/keys/errors.js +34 -0
- package/dist/tests/src/lib/i18n/keys/fetcher.js +84 -0
- package/dist/tests/src/lib/i18n/keys/index.js +31 -0
- package/dist/tests/src/lib/i18n/keys/node.js +56 -0
- package/dist/tests/src/lib/i18n/keys/prompts.js +82 -0
- package/dist/tests/src/lib/i18n/keys/resources.js +50 -0
- package/dist/tests/src/lib/i18n/keys/server.js +64 -0
- package/dist/tests/src/lib/i18n/keys/tools.js +34 -0
- package/dist/tests/src/lib/i18n/locales/en/browser.js +88 -0
- package/dist/tests/src/lib/i18n/locales/en/client.js +66 -0
- package/dist/tests/src/lib/i18n/locales/en/errors.js +28 -0
- package/dist/tests/src/lib/i18n/locales/en/fetcher.js +71 -0
- package/dist/tests/src/lib/i18n/locales/en/index.js +29 -0
- package/dist/tests/src/lib/i18n/locales/en/node.js +51 -0
- package/dist/tests/src/lib/i18n/locales/en/prompts.js +52 -0
- package/dist/tests/src/lib/i18n/locales/en/resources.js +50 -0
- package/dist/tests/src/lib/i18n/locales/en/server.js +56 -0
- package/dist/tests/src/lib/i18n/locales/en/tools.js +28 -0
- package/dist/tests/src/lib/i18n/locales/zh/browser.js +87 -0
- package/dist/tests/src/lib/i18n/locales/zh/client.js +66 -0
- package/dist/tests/src/lib/i18n/locales/zh/errors.js +28 -0
- package/dist/tests/src/lib/i18n/locales/zh/fetcher.js +71 -0
- package/dist/tests/src/lib/i18n/locales/zh/index.js +29 -0
- package/dist/tests/src/lib/i18n/locales/zh/node.js +51 -0
- package/dist/tests/src/lib/i18n/locales/zh/prompts.js +53 -0
- package/dist/tests/src/lib/i18n/locales/zh/resources.js +50 -0
- package/dist/tests/src/lib/i18n/locales/zh/server.js +57 -0
- package/dist/tests/src/lib/i18n/locales/zh/tools.js +28 -0
- package/dist/tests/src/lib/i18n/logger.js +114 -0
- package/dist/tests/src/lib/logger.js +181 -0
- package/dist/tests/test-direct-client.js +0 -0
- package/dist/tests/test-i18n.js +530 -0
- package/dist/tests/test-mcp-methods.js +1 -1
- package/dist/tests/test-mcp.js +0 -0
- package/dist/tests/test-mini4k.js +0 -0
- package/dist/tests/tests/test-i18n.js +588 -0
- package/dist/tests/types.test.js +57 -0
- package/dist/tests/utils/ErrorHandler.test.js +144 -0
- package/dist/vitest.config.js +29 -0
- package/package.json +32 -19
- package/dist/src/cli-language.js +0 -78
- package/dist/src/lib/example.js +0 -93
- package/dist/src/lib/server/logger.js +0 -23
|
@@ -0,0 +1,144 @@
|
|
|
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 { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
7
|
+
import { ErrorHandler, ErrorType } from '../../src/lib/utils/ErrorHandler.js';
|
|
8
|
+
import * as logger from '../../src/lib/logger.js';
|
|
9
|
+
// 模拟logger模块
|
|
10
|
+
vi.mock('../../src/lib/logger.js', () => ({
|
|
11
|
+
log: vi.fn(),
|
|
12
|
+
COMPONENTS: {
|
|
13
|
+
SERVER: 'MCP-SERVER',
|
|
14
|
+
NODE_FETCH: 'NODE-FETCH',
|
|
15
|
+
BROWSER_FETCH: 'BROWSER-FETCH',
|
|
16
|
+
CLIENT: 'CLIENT'
|
|
17
|
+
}
|
|
18
|
+
}));
|
|
19
|
+
describe('ErrorHandler 类测试 (ErrorHandler Class Tests)', () => {
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
vi.clearAllMocks();
|
|
22
|
+
});
|
|
23
|
+
describe('getErrorMessage 方法测试 (getErrorMessage Method Tests)', () => {
|
|
24
|
+
it('应该正确处理 Error 对象 (Should correctly handle Error objects)', () => {
|
|
25
|
+
const error = new Error('测试错误');
|
|
26
|
+
const message = ErrorHandler.getErrorMessage(error);
|
|
27
|
+
expect(message).toBe('测试错误');
|
|
28
|
+
});
|
|
29
|
+
it('应该正确处理字符串错误 (Should correctly handle string errors)', () => {
|
|
30
|
+
const error = '测试错误字符串';
|
|
31
|
+
const message = ErrorHandler.getErrorMessage(error);
|
|
32
|
+
expect(message).toBe('测试错误字符串');
|
|
33
|
+
});
|
|
34
|
+
it('应该正确处理带有 message 属性的对象 (Should correctly handle objects with message property)', () => {
|
|
35
|
+
const error = { message: '对象中的错误消息' };
|
|
36
|
+
const message = ErrorHandler.getErrorMessage(error);
|
|
37
|
+
expect(message).toBe('对象中的错误消息');
|
|
38
|
+
});
|
|
39
|
+
it('应该正确处理普通对象 (Should correctly handle plain objects)', () => {
|
|
40
|
+
const error = { code: 404, status: 'Not Found' };
|
|
41
|
+
const message = ErrorHandler.getErrorMessage(error);
|
|
42
|
+
expect(message).toBe('{"code":404,"status":"Not Found"}');
|
|
43
|
+
});
|
|
44
|
+
it('应该正确处理 null 和 undefined (Should correctly handle null and undefined)', () => {
|
|
45
|
+
expect(ErrorHandler.getErrorMessage(null)).toBe('null');
|
|
46
|
+
expect(ErrorHandler.getErrorMessage(undefined)).toBe('undefined');
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
describe('classifyError 方法测试 (classifyError Method Tests)', () => {
|
|
50
|
+
it('应该正确分类网络错误 (Should correctly classify network errors)', () => {
|
|
51
|
+
const networkErrors = [
|
|
52
|
+
'network error',
|
|
53
|
+
'connection refused',
|
|
54
|
+
'host unreachable',
|
|
55
|
+
'ECONNREFUSED'
|
|
56
|
+
];
|
|
57
|
+
networkErrors.forEach(error => {
|
|
58
|
+
expect(ErrorHandler.classifyError(error)).toBe(ErrorType.NETWORK);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
it('应该正确分类访问被拒绝错误 (Should correctly classify access denied errors)', () => {
|
|
62
|
+
const accessDeniedErrors = [
|
|
63
|
+
'403 Forbidden',
|
|
64
|
+
'access denied',
|
|
65
|
+
'cloudflare protection',
|
|
66
|
+
'captcha required',
|
|
67
|
+
'security check'
|
|
68
|
+
];
|
|
69
|
+
accessDeniedErrors.forEach(error => {
|
|
70
|
+
expect(ErrorHandler.classifyError(error)).toBe(ErrorType.ACCESS_DENIED);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
it('应该正确分类超时错误 (Should correctly classify timeout errors)', () => {
|
|
74
|
+
expect(ErrorHandler.classifyError('request timeout')).toBe(ErrorType.TIMEOUT);
|
|
75
|
+
});
|
|
76
|
+
it('应该正确分类解析错误 (Should correctly classify parse errors)', () => {
|
|
77
|
+
const parseErrors = [
|
|
78
|
+
'parse error',
|
|
79
|
+
'JSON syntax error',
|
|
80
|
+
'invalid syntax'
|
|
81
|
+
];
|
|
82
|
+
parseErrors.forEach(error => {
|
|
83
|
+
expect(ErrorHandler.classifyError(error)).toBe(ErrorType.PARSE);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
it('应该正确分类浏览器错误 (Should correctly classify browser errors)', () => {
|
|
87
|
+
const browserErrors = [
|
|
88
|
+
'browser crashed',
|
|
89
|
+
'puppeteer error',
|
|
90
|
+
'page load failed',
|
|
91
|
+
'chrome not found'
|
|
92
|
+
];
|
|
93
|
+
browserErrors.forEach(error => {
|
|
94
|
+
expect(ErrorHandler.classifyError(error)).toBe(ErrorType.BROWSER);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
it('应该正确分类验证错误 (Should correctly classify validation errors)', () => {
|
|
98
|
+
const validationErrors = [
|
|
99
|
+
'invalid url',
|
|
100
|
+
'schema validation failed',
|
|
101
|
+
'type error'
|
|
102
|
+
];
|
|
103
|
+
validationErrors.forEach(error => {
|
|
104
|
+
expect(ErrorHandler.classifyError(error)).toBe(ErrorType.VALIDATION);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
it('应该将未知错误分类为 UNKNOWN (Should classify unknown errors as UNKNOWN)', () => {
|
|
108
|
+
expect(ErrorHandler.classifyError('some random error')).toBe(ErrorType.UNKNOWN);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
describe('handleError 方法测试 (handleError Method Tests)', () => {
|
|
112
|
+
it('应该调用 log 函数并返回错误消息 (Should call log function and return error message)', () => {
|
|
113
|
+
const error = new Error('测试错误');
|
|
114
|
+
const component = 'TEST-COMPONENT';
|
|
115
|
+
const debug = true;
|
|
116
|
+
const context = { url: 'https://example.com' };
|
|
117
|
+
const result = ErrorHandler.handleError(error, component, debug, context);
|
|
118
|
+
expect(logger.log).toHaveBeenCalledWith('errors.unknown_error', debug, { error: '测试错误', ...context }, component);
|
|
119
|
+
expect(result).toBe('测试错误');
|
|
120
|
+
});
|
|
121
|
+
it('应该使用默认组件和调试值 (Should use default component and debug values)', () => {
|
|
122
|
+
const error = new Error('测试错误');
|
|
123
|
+
ErrorHandler.handleError(error);
|
|
124
|
+
expect(logger.log).toHaveBeenCalledWith('errors.unknown_error', false, { error: '测试错误' }, logger.COMPONENTS.SERVER);
|
|
125
|
+
});
|
|
126
|
+
it('应该根据错误类型使用正确的日志键 (Should use correct log key based on error type)', () => {
|
|
127
|
+
const networkError = 'network error occurred';
|
|
128
|
+
ErrorHandler.handleError(networkError, logger.COMPONENTS.NODE_FETCH, true);
|
|
129
|
+
expect(logger.log).toHaveBeenCalledWith('errors.network_error', true, { error: 'network error occurred' }, logger.COMPONENTS.NODE_FETCH);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
describe('createError 方法测试 (createError Method Tests)', () => {
|
|
133
|
+
it('应该创建带有类型的错误对象 (Should create error object with type)', () => {
|
|
134
|
+
const error = ErrorHandler.createError('自定义错误', ErrorType.NETWORK);
|
|
135
|
+
expect(error instanceof Error).toBe(true);
|
|
136
|
+
expect(error.message).toBe('自定义错误');
|
|
137
|
+
expect(error.type).toBe(ErrorType.NETWORK);
|
|
138
|
+
});
|
|
139
|
+
it('应该使用默认错误类型 (Should use default error type)', () => {
|
|
140
|
+
const error = ErrorHandler.createError('自定义错误');
|
|
141
|
+
expect(error.type).toBe(ErrorType.UNKNOWN);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmcc-dev/mult-fetch-mcp-server",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "An MCP protocol-based web content fetching tool that supports multiple modes and formats, can be integrated with AI assistants like Claude",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -18,20 +18,7 @@
|
|
|
18
18
|
"url": "https://github.com/lmcc-dev/mult-fetch-mcp-server/issues"
|
|
19
19
|
},
|
|
20
20
|
"engines": {
|
|
21
|
-
"node": ">=18
|
|
22
|
-
},
|
|
23
|
-
"scripts": {
|
|
24
|
-
"build": "tsc && shx chmod +x dist/src/*.js dist/tests/*.js || true && shx chmod +x dist/*.js || true",
|
|
25
|
-
"prepare": "npm run build",
|
|
26
|
-
"dev": "tsc --watch",
|
|
27
|
-
"start": "node dist/index.js",
|
|
28
|
-
"test:mcp": "node dist/tests/test-mcp.js",
|
|
29
|
-
"test:mini4k": "node dist/tests/test-mini4k.js",
|
|
30
|
-
"test:direct": "node dist/tests/test-direct-client.js",
|
|
31
|
-
"client": "node dist/src/client.js",
|
|
32
|
-
"server": "node dist/index.js",
|
|
33
|
-
"prepublishOnly": "npm run build",
|
|
34
|
-
"release": "npm publish --access public"
|
|
21
|
+
"node": ">=18"
|
|
35
22
|
},
|
|
36
23
|
"keywords": [
|
|
37
24
|
"mcp",
|
|
@@ -49,7 +36,7 @@
|
|
|
49
36
|
"proxy"
|
|
50
37
|
],
|
|
51
38
|
"dependencies": {
|
|
52
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
39
|
+
"@modelcontextprotocol/sdk": "^1.7.0",
|
|
53
40
|
"http-proxy-agent": "^7.0.2",
|
|
54
41
|
"https-proxy-agent": "^7.0.6",
|
|
55
42
|
"i18next": "^24.2.2",
|
|
@@ -62,13 +49,19 @@
|
|
|
62
49
|
"zod": "^3.24.2"
|
|
63
50
|
},
|
|
64
51
|
"devDependencies": {
|
|
52
|
+
"@types/glob": "^8.1.0",
|
|
65
53
|
"@types/jsdom": "^21.1.7",
|
|
66
54
|
"@types/node": "^22.10.2",
|
|
67
55
|
"@types/node-fetch": "^2.6.12",
|
|
68
56
|
"@types/puppeteer": "^5.4.7",
|
|
69
57
|
"@types/turndown": "^5.0.5",
|
|
58
|
+
"@vitest/coverage-v8": "^3.0.8",
|
|
59
|
+
"codecov": "^3.8.2",
|
|
60
|
+
"glob": "^11.0.1",
|
|
70
61
|
"shx": "^0.3.4",
|
|
71
|
-
"
|
|
62
|
+
"ts-node": "^10.9.2",
|
|
63
|
+
"typescript": "^5.7.2",
|
|
64
|
+
"vitest": "^3.0.8"
|
|
72
65
|
},
|
|
73
66
|
"files": [
|
|
74
67
|
"dist",
|
|
@@ -76,5 +69,25 @@
|
|
|
76
69
|
"README.zh.md",
|
|
77
70
|
"LICENSE",
|
|
78
71
|
"images"
|
|
79
|
-
]
|
|
80
|
-
|
|
72
|
+
],
|
|
73
|
+
"scripts": {
|
|
74
|
+
"build": "tsc && shx chmod +x dist/src/*.js dist/tests/*.js || true && shx chmod +x dist/*.js || true",
|
|
75
|
+
"dev": "tsc --watch",
|
|
76
|
+
"start": "node dist/index.js",
|
|
77
|
+
"test:mcp": "node dist/tests/test-mcp.js",
|
|
78
|
+
"test:mini4k": "node dist/tests/test-mini4k.js",
|
|
79
|
+
"test:direct": "node dist/tests/test-direct-client.js",
|
|
80
|
+
"test:methods": "node dist/tests/test-mcp-methods.js",
|
|
81
|
+
"test:i18n": "pnpm run build && node dist/tests/test-i18n.js",
|
|
82
|
+
"test:i18n:unused": "pnpm run build && node dist/tests/i18n-unused-keys.js",
|
|
83
|
+
"test:i18n:missing": "pnpm run build && node --loader ts-node/esm tests/i18n-missing-keys.ts",
|
|
84
|
+
"test": "vitest run",
|
|
85
|
+
"test:watch": "vitest",
|
|
86
|
+
"test:coverage": "vitest run --coverage",
|
|
87
|
+
"client": "node dist/src/client.js",
|
|
88
|
+
"server": "node dist/index.js",
|
|
89
|
+
"release": "pnpm publish --access public",
|
|
90
|
+
"codecov": "vitest run --coverage && codecov",
|
|
91
|
+
"test:ci": "vitest run --coverage && codecov"
|
|
92
|
+
}
|
|
93
|
+
}
|
package/dist/src/cli-language.js
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
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
|
-
import { getCurrentLanguage, changeLanguage } from './lib/i18n/index.js';
|
|
8
|
-
import { createLogger } from './lib/i18n/logger.js';
|
|
9
|
-
// 创建日志记录器 (Create logger)
|
|
10
|
-
const logger = createLogger('LANGUAGE');
|
|
11
|
-
/**
|
|
12
|
-
* 显示帮助信息 (Show help information)
|
|
13
|
-
*/
|
|
14
|
-
function showHelp() {
|
|
15
|
-
console.error(`
|
|
16
|
-
语言设置工具 (Language Setting Tool)
|
|
17
|
-
|
|
18
|
-
用法 (Usage):
|
|
19
|
-
node dist/cli-language.js [命令] (node dist/cli-language.js [command])
|
|
20
|
-
|
|
21
|
-
命令 (Commands):
|
|
22
|
-
get 获取当前语言设置 (Get current language setting)
|
|
23
|
-
set <lang> 设置语言 (Set language)
|
|
24
|
-
<lang> 可以是 'en' 或 'zh' (<lang> can be 'en' or 'zh')
|
|
25
|
-
help 显示此帮助信息 (Show this help information)
|
|
26
|
-
|
|
27
|
-
示例 (Examples):
|
|
28
|
-
node dist/cli-language.js get
|
|
29
|
-
node dist/cli-language.js set en
|
|
30
|
-
node dist/cli-language.js set zh
|
|
31
|
-
|
|
32
|
-
注意 (Note):
|
|
33
|
-
此工具只会影响当前进程的语言设置,不会影响已经运行的服务器进程。
|
|
34
|
-
对于服务器进程,建议使用 MCP_LANG 环境变量来设置语言。
|
|
35
|
-
(This tool only affects the language setting of the current process, not running server processes.
|
|
36
|
-
For server processes, it is recommended to use the MCP_LANG environment variable to set the language.)
|
|
37
|
-
|
|
38
|
-
例如 (Example):
|
|
39
|
-
MCP_LANG=zh node dist/index.js
|
|
40
|
-
`);
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* 主函数 (Main function)
|
|
44
|
-
*/
|
|
45
|
-
async function main() {
|
|
46
|
-
const args = process.argv.slice(2);
|
|
47
|
-
const command = args[0];
|
|
48
|
-
if (!command || command === 'help') {
|
|
49
|
-
showHelp();
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
switch (command) {
|
|
53
|
-
case 'get':
|
|
54
|
-
console.error(`当前语言 (Current language): ${getCurrentLanguage()}`);
|
|
55
|
-
break;
|
|
56
|
-
case 'set':
|
|
57
|
-
const lang = args[1];
|
|
58
|
-
if (lang !== 'en' && lang !== 'zh') {
|
|
59
|
-
console.error('错误: 语言必须是 "en" 或 "zh" (Error: Language must be "en" or "zh")');
|
|
60
|
-
process.exit(1);
|
|
61
|
-
}
|
|
62
|
-
changeLanguage(lang);
|
|
63
|
-
console.error(`语言已设置为 (Language set to): ${lang}`);
|
|
64
|
-
// 测试翻译 (Test translation)
|
|
65
|
-
logger.info('server.starting');
|
|
66
|
-
logger.info('server.started');
|
|
67
|
-
break;
|
|
68
|
-
default:
|
|
69
|
-
console.error(`未知命令: ${command} (Unknown command: ${command})`);
|
|
70
|
-
showHelp();
|
|
71
|
-
process.exit(1);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
// 执行主函数 (Execute main function)
|
|
75
|
-
main().catch(error => {
|
|
76
|
-
console.error('错误 (Error):', error);
|
|
77
|
-
process.exit(1);
|
|
78
|
-
});
|
package/dist/src/lib/example.js
DELETED
|
@@ -1,93 +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
|
-
/**
|
|
7
|
-
* 示例工具类,展示双语注释风格 (Example utility class, demonstrating bilingual comment style)
|
|
8
|
-
* 包含各种实用函数和示例 (Contains various utility functions and examples)
|
|
9
|
-
*/
|
|
10
|
-
export class ExampleUtils {
|
|
11
|
-
/**
|
|
12
|
-
* 缓存存储 (Cache storage)
|
|
13
|
-
* 用于存储临时数据 (Used to store temporary data)
|
|
14
|
-
*/
|
|
15
|
-
static cache = new Map();
|
|
16
|
-
/**
|
|
17
|
-
* 获取用户信息 (Get user information)
|
|
18
|
-
* @param userId 用户唯一标识 (Unique identifier of the user)
|
|
19
|
-
* @param includeDetails 是否包含详细信息 (Whether to include detailed information)
|
|
20
|
-
* @returns 用户详细信息 (Detailed user information)
|
|
21
|
-
*/
|
|
22
|
-
static async getUserInfo(userId, includeDetails = false) {
|
|
23
|
-
// 检查缓存中是否存在用户信息 (Check if user information exists in cache)
|
|
24
|
-
const cacheKey = `user_${userId}_${includeDetails ? 'detailed' : 'basic'}`;
|
|
25
|
-
if (this.cache.has(cacheKey)) {
|
|
26
|
-
return this.cache.get(cacheKey);
|
|
27
|
-
}
|
|
28
|
-
// 从数据库中查询用户 (Fetch user from the database)
|
|
29
|
-
const user = await this.fetchUserFromDB(userId);
|
|
30
|
-
// 如果需要详细信息,则获取额外数据 (If detailed information is needed, get additional data)
|
|
31
|
-
if (includeDetails && user) {
|
|
32
|
-
// 获取用户的额外信息 (Get additional information of the user)
|
|
33
|
-
user.details = await this.fetchUserDetails(userId);
|
|
34
|
-
}
|
|
35
|
-
// 将结果存入缓存 (Store the result in cache)
|
|
36
|
-
this.cache.set(cacheKey, user);
|
|
37
|
-
return user;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* 从数据库获取用户基本信息 (Fetch basic user information from database)
|
|
41
|
-
* @param userId 用户ID (User ID)
|
|
42
|
-
* @returns 用户基本信息 (Basic user information)
|
|
43
|
-
*/
|
|
44
|
-
static async fetchUserFromDB(userId) {
|
|
45
|
-
try {
|
|
46
|
-
// 这里是模拟的数据库查询 (This is a simulated database query)
|
|
47
|
-
console.log(`从数据库获取用户 ${userId} 的信息 (Fetching information of user ${userId} from database)`);
|
|
48
|
-
// 模拟网络延迟 (Simulate network delay)
|
|
49
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
50
|
-
// 返回模拟数据 (Return simulated data)
|
|
51
|
-
return {
|
|
52
|
-
id: userId,
|
|
53
|
-
name: `User ${userId}`,
|
|
54
|
-
email: `user${userId}@example.com`,
|
|
55
|
-
createdAt: new Date().toISOString()
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
// 记录错误并返回null (Log error and return null)
|
|
60
|
-
console.error(`获取用户信息失败: ${error.message} (Failed to get user information: ${error.message})`);
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* 获取用户详细信息 (Get detailed user information)
|
|
66
|
-
* @param userId 用户ID (User ID)
|
|
67
|
-
* @returns 用户详细信息 (Detailed user information)
|
|
68
|
-
*/
|
|
69
|
-
static async fetchUserDetails(userId) {
|
|
70
|
-
// 模拟获取用户详细信息 (Simulate getting detailed user information)
|
|
71
|
-
console.log(`获取用户 ${userId} 的详细信息 (Getting detailed information of user ${userId})`);
|
|
72
|
-
// 模拟网络延迟 (Simulate network delay)
|
|
73
|
-
await new Promise(resolve => setTimeout(resolve, 150));
|
|
74
|
-
// 返回模拟的详细信息 (Return simulated detailed information)
|
|
75
|
-
return {
|
|
76
|
-
address: '123 Example St, City, Country',
|
|
77
|
-
phone: '+1234567890',
|
|
78
|
-
preferences: {
|
|
79
|
-
theme: 'dark',
|
|
80
|
-
notifications: true
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* 清除缓存 (Clear cache)
|
|
86
|
-
* 删除所有缓存的数据 (Delete all cached data)
|
|
87
|
-
*/
|
|
88
|
-
static clearCache() {
|
|
89
|
-
// 清空缓存映射 (Empty the cache map)
|
|
90
|
-
this.cache.clear();
|
|
91
|
-
console.log('缓存已清空 (Cache has been cleared)');
|
|
92
|
-
}
|
|
93
|
-
}
|
|
@@ -1,23 +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 { createLogger } from '../i18n/logger.js';
|
|
7
|
-
// 创建服务器日志记录器 (Create server logger)
|
|
8
|
-
const logger = createLogger('MCP-SERVER');
|
|
9
|
-
/**
|
|
10
|
-
* 日志函数 (Log function)
|
|
11
|
-
* 输出调试信息到标准错误流 (Output debug information to standard error stream)
|
|
12
|
-
* @param key 翻译键或消息 (Translation key or message)
|
|
13
|
-
* @param debug 是否为调试模式 (Whether in debug mode)
|
|
14
|
-
* @param options 翻译选项 (Translation options)
|
|
15
|
-
*/
|
|
16
|
-
export function log(key, debug = false, options) {
|
|
17
|
-
// 只有在明确设置 debug 为 true 时才输出日志 (Only output logs when debug is explicitly set to true)
|
|
18
|
-
if (!debug) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
// 所有日志消息都使用翻译键 (All log messages use translation keys)
|
|
22
|
-
logger.debug(key, options, debug);
|
|
23
|
-
}
|