@liangshanli/mcp-server-project-standards 1.2.2 → 2.0.1
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 +15 -0
- package/bin/cli.js +1 -1
- package/package.json +8 -4
- package/src/server-final.js +445 -268
- package/src/utils/api_common.js +137 -0
- package/src/utils/api_config.js +217 -0
- package/src/utils/api_debug.js +145 -604
- package/src/utils/api_login.js +165 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
const { getLoginUrl, getLoginMethod, getLoginBody, loadApiConfig, saveApiConfig } = require('./api_common');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* API 登录工具 - 直接执行登录请求(从环境变量获取登录信息)
|
|
5
|
+
* @param {Object} params - 参数
|
|
6
|
+
* @param {string} params.baseUrl - 基础URL(可选,会覆盖配置中的baseUrl)
|
|
7
|
+
* @param {Object} config - 服务器配置
|
|
8
|
+
* @param {Function} saveConfig - 保存配置函数
|
|
9
|
+
* @returns {Object} 登录结果
|
|
10
|
+
*/
|
|
11
|
+
async function api_login(params, config, saveConfig) {
|
|
12
|
+
const { baseUrl } = params || {};
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
// 加载当前配置
|
|
16
|
+
const apiDebugConfig = loadApiConfig();
|
|
17
|
+
|
|
18
|
+
// 使用传入的baseUrl或配置中的baseUrl
|
|
19
|
+
const finalBaseUrl = baseUrl || apiDebugConfig.baseUrl || '';
|
|
20
|
+
const loginUrl = getLoginUrl();
|
|
21
|
+
const loginMethod = getLoginMethod();
|
|
22
|
+
|
|
23
|
+
// 构建完整登录URL
|
|
24
|
+
let fullLoginUrl;
|
|
25
|
+
if (loginUrl.startsWith('http://') || loginUrl.startsWith('https://')) {
|
|
26
|
+
fullLoginUrl = loginUrl;
|
|
27
|
+
} else {
|
|
28
|
+
fullLoginUrl = finalBaseUrl + loginUrl;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// 从环境变量获取登录请求体
|
|
32
|
+
const loginBodyRaw = getLoginBody();
|
|
33
|
+
let loginBody;
|
|
34
|
+
|
|
35
|
+
// 处理不同格式的请求体
|
|
36
|
+
if (typeof loginBodyRaw === 'string') {
|
|
37
|
+
// 如果是字符串,直接使用
|
|
38
|
+
loginBody = loginBodyRaw;
|
|
39
|
+
} else if (typeof loginBodyRaw === 'object') {
|
|
40
|
+
// 如果是对象,转换为JSON字符串
|
|
41
|
+
loginBody = JSON.stringify(loginBodyRaw);
|
|
42
|
+
} else {
|
|
43
|
+
// 其他情况,使用默认格式
|
|
44
|
+
loginBody = '{"username":"","password":""}';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 准备请求头
|
|
48
|
+
const headers = {
|
|
49
|
+
...apiDebugConfig.headers,
|
|
50
|
+
'Content-Type': 'application/json'
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// 执行登录请求
|
|
54
|
+
let response;
|
|
55
|
+
let responseData;
|
|
56
|
+
let success = true;
|
|
57
|
+
let error = null;
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
response = await fetch(fullLoginUrl, {
|
|
61
|
+
method: loginMethod,
|
|
62
|
+
headers: headers,
|
|
63
|
+
body: loginBody
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// 获取响应数据
|
|
67
|
+
const contentType = response.headers.get('content-type');
|
|
68
|
+
|
|
69
|
+
if (contentType && contentType.includes('application/json')) {
|
|
70
|
+
responseData = await response.json();
|
|
71
|
+
} else {
|
|
72
|
+
responseData = await response.text();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 判断登录是否成功
|
|
76
|
+
const isHttpSuccess = response.status >= 200 && response.status < 300;
|
|
77
|
+
success = isHttpSuccess;
|
|
78
|
+
|
|
79
|
+
if (success) {
|
|
80
|
+
// 登录成功,尝试提取token并更新公共请求头
|
|
81
|
+
let token = null;
|
|
82
|
+
|
|
83
|
+
// 尝试从响应中提取token
|
|
84
|
+
if (responseData && typeof responseData === 'object') {
|
|
85
|
+
// 常见的token字段名
|
|
86
|
+
const tokenFields = ['token', 'access_token', 'accessToken', 'authToken', 'jwt'];
|
|
87
|
+
for (const field of tokenFields) {
|
|
88
|
+
if (responseData[field]) {
|
|
89
|
+
token = responseData[field];
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 如果找到token,自动更新Authorization头
|
|
96
|
+
if (token) {
|
|
97
|
+
apiDebugConfig.headers = {
|
|
98
|
+
...apiDebugConfig.headers,
|
|
99
|
+
'Authorization': `Bearer ${token}`
|
|
100
|
+
};
|
|
101
|
+
saveApiConfig(apiDebugConfig);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
success: true,
|
|
106
|
+
message: 'Login successful',
|
|
107
|
+
request: {
|
|
108
|
+
url: fullLoginUrl,
|
|
109
|
+
method: loginMethod,
|
|
110
|
+
headers: headers,
|
|
111
|
+
body: loginBody
|
|
112
|
+
},
|
|
113
|
+
response: {
|
|
114
|
+
status: response.status,
|
|
115
|
+
statusText: response.statusText,
|
|
116
|
+
headers: Object.fromEntries(response.headers.entries()),
|
|
117
|
+
data: responseData
|
|
118
|
+
},
|
|
119
|
+
token: token,
|
|
120
|
+
autoUpdatedHeaders: !!token,
|
|
121
|
+
timestamp: new Date().toISOString()
|
|
122
|
+
};
|
|
123
|
+
} else {
|
|
124
|
+
return {
|
|
125
|
+
success: false,
|
|
126
|
+
message: `Login failed: HTTP ${response.status}: ${response.statusText}`,
|
|
127
|
+
request: {
|
|
128
|
+
url: fullLoginUrl,
|
|
129
|
+
method: loginMethod,
|
|
130
|
+
headers: headers,
|
|
131
|
+
body: loginBody
|
|
132
|
+
},
|
|
133
|
+
response: {
|
|
134
|
+
status: response.status,
|
|
135
|
+
statusText: response.statusText,
|
|
136
|
+
headers: Object.fromEntries(response.headers.entries()),
|
|
137
|
+
data: responseData
|
|
138
|
+
},
|
|
139
|
+
error: `HTTP ${response.status}: ${response.statusText}`,
|
|
140
|
+
timestamp: new Date().toISOString()
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
} catch (fetchError) {
|
|
144
|
+
error = fetchError.message;
|
|
145
|
+
success = false;
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
success: false,
|
|
149
|
+
message: `Login request failed: ${error}`,
|
|
150
|
+
request: {
|
|
151
|
+
url: fullLoginUrl,
|
|
152
|
+
method: loginMethod,
|
|
153
|
+
headers: headers,
|
|
154
|
+
body: loginBody
|
|
155
|
+
},
|
|
156
|
+
error: error,
|
|
157
|
+
timestamp: new Date().toISOString()
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
} catch (err) {
|
|
161
|
+
throw new Error(`Failed to perform login: ${err.message}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
module.exports = api_login;
|