@samanhappy/mcphub 0.0.7 → 0.0.9
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/package.json +6 -3
- package/.env.example +0 -2
- package/.eslintrc.json +0 -25
- package/.github/workflows/build.yml +0 -51
- package/.github/workflows/release.yml +0 -19
- package/.prettierrc +0 -7
- package/Dockerfile +0 -51
- package/assets/amap-edit.png +0 -0
- package/assets/amap-result.png +0 -0
- package/assets/cherry-mcp.png +0 -0
- package/assets/cursor-mcp.png +0 -0
- package/assets/cursor-query.png +0 -0
- package/assets/cursor-tools.png +0 -0
- package/assets/dashboard.png +0 -0
- package/assets/dashboard.zh.png +0 -0
- package/assets/group.png +0 -0
- package/assets/group.zh.png +0 -0
- package/assets/market.zh.png +0 -0
- package/assets/wegroup.jpg +0 -0
- package/assets/wegroup.png +0 -0
- package/assets/wexin.png +0 -0
- package/doc/intro.md +0 -73
- package/doc/intro2.md +0 -232
- package/entrypoint.sh +0 -10
- package/frontend/favicon.ico +0 -0
- package/frontend/index.html +0 -13
- package/frontend/postcss.config.js +0 -6
- package/frontend/src/App.tsx +0 -44
- package/frontend/src/components/AddGroupForm.tsx +0 -132
- package/frontend/src/components/AddServerForm.tsx +0 -90
- package/frontend/src/components/ChangePasswordForm.tsx +0 -158
- package/frontend/src/components/EditGroupForm.tsx +0 -149
- package/frontend/src/components/EditServerForm.tsx +0 -76
- package/frontend/src/components/GroupCard.tsx +0 -143
- package/frontend/src/components/MarketServerCard.tsx +0 -153
- package/frontend/src/components/MarketServerDetail.tsx +0 -297
- package/frontend/src/components/ProtectedRoute.tsx +0 -27
- package/frontend/src/components/ServerCard.tsx +0 -230
- package/frontend/src/components/ServerForm.tsx +0 -276
- package/frontend/src/components/icons/LucideIcons.tsx +0 -14
- package/frontend/src/components/layout/Content.tsx +0 -17
- package/frontend/src/components/layout/Header.tsx +0 -61
- package/frontend/src/components/layout/Sidebar.tsx +0 -98
- package/frontend/src/components/ui/Badge.tsx +0 -33
- package/frontend/src/components/ui/Button.tsx +0 -0
- package/frontend/src/components/ui/DeleteDialog.tsx +0 -48
- package/frontend/src/components/ui/Pagination.tsx +0 -128
- package/frontend/src/components/ui/Toast.tsx +0 -96
- package/frontend/src/components/ui/ToggleGroup.tsx +0 -134
- package/frontend/src/components/ui/ToolCard.tsx +0 -38
- package/frontend/src/contexts/AuthContext.tsx +0 -159
- package/frontend/src/contexts/ToastContext.tsx +0 -60
- package/frontend/src/hooks/useGroupData.ts +0 -232
- package/frontend/src/hooks/useMarketData.ts +0 -410
- package/frontend/src/hooks/useServerData.ts +0 -306
- package/frontend/src/hooks/useSettingsData.ts +0 -131
- package/frontend/src/i18n.ts +0 -42
- package/frontend/src/index.css +0 -20
- package/frontend/src/layouts/MainLayout.tsx +0 -33
- package/frontend/src/locales/en.json +0 -214
- package/frontend/src/locales/zh.json +0 -214
- package/frontend/src/main.tsx +0 -12
- package/frontend/src/pages/Dashboard.tsx +0 -206
- package/frontend/src/pages/GroupsPage.tsx +0 -116
- package/frontend/src/pages/LoginPage.tsx +0 -104
- package/frontend/src/pages/MarketPage.tsx +0 -356
- package/frontend/src/pages/ServersPage.tsx +0 -144
- package/frontend/src/pages/SettingsPage.tsx +0 -149
- package/frontend/src/services/authService.ts +0 -141
- package/frontend/src/types/index.ts +0 -160
- package/frontend/src/utils/cn.ts +0 -10
- package/frontend/tsconfig.json +0 -31
- package/frontend/tsconfig.node.json +0 -10
- package/frontend/vite.config.ts +0 -26
- package/googled76ca578b6543fbc.html +0 -1
- package/jest.config.js +0 -10
- package/mcp_settings.json +0 -45
- package/servers.json +0 -74722
- package/src/config/index.ts +0 -46
- package/src/controllers/authController.ts +0 -179
- package/src/controllers/groupController.ts +0 -341
- package/src/controllers/marketController.ts +0 -154
- package/src/controllers/serverController.ts +0 -303
- package/src/index.ts +0 -18
- package/src/middlewares/auth.ts +0 -28
- package/src/middlewares/index.ts +0 -43
- package/src/models/User.ts +0 -103
- package/src/routes/index.ts +0 -96
- package/src/server.ts +0 -72
- package/src/services/groupService.ts +0 -232
- package/src/services/marketService.ts +0 -116
- package/src/services/mcpService.ts +0 -385
- package/src/services/sseService.ts +0 -119
- package/src/types/index.ts +0 -129
- package/src/utils/migration.ts +0 -52
- package/tsconfig.json +0 -17
package/src/config/index.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import dotenv from 'dotenv';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
import { McpSettings } from '../types/index.js';
|
|
5
|
-
|
|
6
|
-
dotenv.config();
|
|
7
|
-
|
|
8
|
-
const defaultConfig = {
|
|
9
|
-
port: process.env.PORT || 3000,
|
|
10
|
-
initTimeout: process.env.INIT_TIMEOUT || 300000,
|
|
11
|
-
timeout: process.env.REQUEST_TIMEOUT || 60000,
|
|
12
|
-
mcpHubName: 'mcphub',
|
|
13
|
-
mcpHubVersion: '0.0.1',
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export const getSettingsPath = (): string => {
|
|
17
|
-
return path.resolve(process.cwd(), 'mcp_settings.json');
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export const loadSettings = (): McpSettings => {
|
|
21
|
-
const settingsPath = getSettingsPath();
|
|
22
|
-
try {
|
|
23
|
-
const settingsData = fs.readFileSync(settingsPath, 'utf8');
|
|
24
|
-
return JSON.parse(settingsData);
|
|
25
|
-
} catch (error) {
|
|
26
|
-
console.error(`Failed to load settings from ${settingsPath}:`, error);
|
|
27
|
-
return { mcpServers: {}, users: [] };
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export const saveSettings = (settings: McpSettings): boolean => {
|
|
32
|
-
const settingsPath = getSettingsPath();
|
|
33
|
-
try {
|
|
34
|
-
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
|
|
35
|
-
return true;
|
|
36
|
-
} catch (error) {
|
|
37
|
-
console.error(`Failed to save settings to ${settingsPath}:`, error);
|
|
38
|
-
return false;
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export const expandEnvVars = (value: string): string => {
|
|
43
|
-
return value.replace(/\$\{([^}]+)\}/g, (_, key) => process.env[key] || '');
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export default defaultConfig;
|
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import { Request, Response } from 'express';
|
|
2
|
-
import jwt from 'jsonwebtoken';
|
|
3
|
-
import { validationResult } from 'express-validator';
|
|
4
|
-
import { findUserByUsername, verifyPassword, createUser, updateUserPassword } from '../models/User.js';
|
|
5
|
-
|
|
6
|
-
// Default secret key - in production, use an environment variable
|
|
7
|
-
const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-this';
|
|
8
|
-
const TOKEN_EXPIRY = '24h';
|
|
9
|
-
|
|
10
|
-
// Login user
|
|
11
|
-
export const login = async (req: Request, res: Response): Promise<void> => {
|
|
12
|
-
// Validate request
|
|
13
|
-
const errors = validationResult(req);
|
|
14
|
-
if (!errors.isEmpty()) {
|
|
15
|
-
res.status(400).json({ success: false, errors: errors.array() });
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const { username, password } = req.body;
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
// Find user by username
|
|
23
|
-
const user = findUserByUsername(username);
|
|
24
|
-
|
|
25
|
-
if (!user) {
|
|
26
|
-
res.status(401).json({ success: false, message: 'Invalid credentials' });
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Verify password
|
|
31
|
-
const isPasswordValid = await verifyPassword(password, user.password);
|
|
32
|
-
|
|
33
|
-
if (!isPasswordValid) {
|
|
34
|
-
res.status(401).json({ success: false, message: 'Invalid credentials' });
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Generate JWT token
|
|
39
|
-
const payload = {
|
|
40
|
-
user: {
|
|
41
|
-
username: user.username,
|
|
42
|
-
isAdmin: user.isAdmin || false
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
jwt.sign(
|
|
47
|
-
payload,
|
|
48
|
-
JWT_SECRET,
|
|
49
|
-
{ expiresIn: TOKEN_EXPIRY },
|
|
50
|
-
(err, token) => {
|
|
51
|
-
if (err) throw err;
|
|
52
|
-
res.json({
|
|
53
|
-
success: true,
|
|
54
|
-
token,
|
|
55
|
-
user: {
|
|
56
|
-
username: user.username,
|
|
57
|
-
isAdmin: user.isAdmin
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
);
|
|
62
|
-
} catch (error) {
|
|
63
|
-
console.error('Login error:', error);
|
|
64
|
-
res.status(500).json({ success: false, message: 'Server error' });
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
// Register new user
|
|
69
|
-
export const register = async (req: Request, res: Response): Promise<void> => {
|
|
70
|
-
// Validate request
|
|
71
|
-
const errors = validationResult(req);
|
|
72
|
-
if (!errors.isEmpty()) {
|
|
73
|
-
res.status(400).json({ success: false, errors: errors.array() });
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const { username, password, isAdmin } = req.body;
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
// Create new user
|
|
81
|
-
const newUser = await createUser({ username, password, isAdmin });
|
|
82
|
-
|
|
83
|
-
if (!newUser) {
|
|
84
|
-
res.status(400).json({ success: false, message: 'User already exists' });
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Generate JWT token
|
|
89
|
-
const payload = {
|
|
90
|
-
user: {
|
|
91
|
-
username: newUser.username,
|
|
92
|
-
isAdmin: newUser.isAdmin || false
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
jwt.sign(
|
|
97
|
-
payload,
|
|
98
|
-
JWT_SECRET,
|
|
99
|
-
{ expiresIn: TOKEN_EXPIRY },
|
|
100
|
-
(err, token) => {
|
|
101
|
-
if (err) throw err;
|
|
102
|
-
res.json({
|
|
103
|
-
success: true,
|
|
104
|
-
token,
|
|
105
|
-
user: {
|
|
106
|
-
username: newUser.username,
|
|
107
|
-
isAdmin: newUser.isAdmin
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
);
|
|
112
|
-
} catch (error) {
|
|
113
|
-
console.error('Registration error:', error);
|
|
114
|
-
res.status(500).json({ success: false, message: 'Server error' });
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
// Get current user
|
|
119
|
-
export const getCurrentUser = (req: Request, res: Response): void => {
|
|
120
|
-
try {
|
|
121
|
-
// User is already attached to request by auth middleware
|
|
122
|
-
const user = (req as any).user;
|
|
123
|
-
|
|
124
|
-
res.json({
|
|
125
|
-
success: true,
|
|
126
|
-
user: {
|
|
127
|
-
username: user.username,
|
|
128
|
-
isAdmin: user.isAdmin
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
} catch (error) {
|
|
132
|
-
console.error('Get current user error:', error);
|
|
133
|
-
res.status(500).json({ success: false, message: 'Server error' });
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
// Change password
|
|
138
|
-
export const changePassword = async (req: Request, res: Response): Promise<void> => {
|
|
139
|
-
// Validate request
|
|
140
|
-
const errors = validationResult(req);
|
|
141
|
-
if (!errors.isEmpty()) {
|
|
142
|
-
res.status(400).json({ success: false, errors: errors.array() });
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const { currentPassword, newPassword } = req.body;
|
|
147
|
-
const username = (req as any).user.username;
|
|
148
|
-
|
|
149
|
-
try {
|
|
150
|
-
// Find user by username
|
|
151
|
-
const user = findUserByUsername(username);
|
|
152
|
-
|
|
153
|
-
if (!user) {
|
|
154
|
-
res.status(404).json({ success: false, message: 'User not found' });
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Verify current password
|
|
159
|
-
const isPasswordValid = await verifyPassword(currentPassword, user.password);
|
|
160
|
-
|
|
161
|
-
if (!isPasswordValid) {
|
|
162
|
-
res.status(401).json({ success: false, message: 'Current password is incorrect' });
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Update the password
|
|
167
|
-
const updated = await updateUserPassword(username, newPassword);
|
|
168
|
-
|
|
169
|
-
if (!updated) {
|
|
170
|
-
res.status(500).json({ success: false, message: 'Failed to update password' });
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
res.json({ success: true, message: 'Password updated successfully' });
|
|
175
|
-
} catch (error) {
|
|
176
|
-
console.error('Change password error:', error);
|
|
177
|
-
res.status(500).json({ success: false, message: 'Server error' });
|
|
178
|
-
}
|
|
179
|
-
};
|
|
@@ -1,341 +0,0 @@
|
|
|
1
|
-
import { Request, Response } from 'express';
|
|
2
|
-
import { ApiResponse } from '../types/index.js';
|
|
3
|
-
import {
|
|
4
|
-
getAllGroups,
|
|
5
|
-
getGroupByIdOrName,
|
|
6
|
-
createGroup,
|
|
7
|
-
updateGroup,
|
|
8
|
-
updateGroupServers,
|
|
9
|
-
deleteGroup,
|
|
10
|
-
addServerToGroup,
|
|
11
|
-
removeServerFromGroup,
|
|
12
|
-
getServersInGroup
|
|
13
|
-
} from '../services/groupService.js';
|
|
14
|
-
|
|
15
|
-
// Get all groups
|
|
16
|
-
export const getGroups = (_: Request, res: Response): void => {
|
|
17
|
-
try {
|
|
18
|
-
const groups = getAllGroups();
|
|
19
|
-
const response: ApiResponse = {
|
|
20
|
-
success: true,
|
|
21
|
-
data: groups,
|
|
22
|
-
};
|
|
23
|
-
res.json(response);
|
|
24
|
-
} catch (error) {
|
|
25
|
-
res.status(500).json({
|
|
26
|
-
success: false,
|
|
27
|
-
message: 'Failed to get groups information',
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
// Get a specific group by ID
|
|
33
|
-
export const getGroup = (req: Request, res: Response): void => {
|
|
34
|
-
try {
|
|
35
|
-
const { id } = req.params;
|
|
36
|
-
if (!id) {
|
|
37
|
-
res.status(400).json({
|
|
38
|
-
success: false,
|
|
39
|
-
message: 'Group ID is required',
|
|
40
|
-
});
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const group = getGroupByIdOrName(id);
|
|
45
|
-
if (!group) {
|
|
46
|
-
res.status(404).json({
|
|
47
|
-
success: false,
|
|
48
|
-
message: 'Group not found',
|
|
49
|
-
});
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const response: ApiResponse = {
|
|
54
|
-
success: true,
|
|
55
|
-
data: group,
|
|
56
|
-
};
|
|
57
|
-
res.json(response);
|
|
58
|
-
} catch (error) {
|
|
59
|
-
res.status(500).json({
|
|
60
|
-
success: false,
|
|
61
|
-
message: 'Failed to get group information',
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
// Create a new group
|
|
67
|
-
export const createNewGroup = (req: Request, res: Response): void => {
|
|
68
|
-
try {
|
|
69
|
-
const { name, description, servers } = req.body;
|
|
70
|
-
if (!name) {
|
|
71
|
-
res.status(400).json({
|
|
72
|
-
success: false,
|
|
73
|
-
message: 'Group name is required',
|
|
74
|
-
});
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const serverList = Array.isArray(servers) ? servers : [];
|
|
79
|
-
const newGroup = createGroup(name, description, serverList);
|
|
80
|
-
if (!newGroup) {
|
|
81
|
-
res.status(400).json({
|
|
82
|
-
success: false,
|
|
83
|
-
message: 'Failed to create group or group name already exists',
|
|
84
|
-
});
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const response: ApiResponse = {
|
|
89
|
-
success: true,
|
|
90
|
-
data: newGroup,
|
|
91
|
-
message: 'Group created successfully',
|
|
92
|
-
};
|
|
93
|
-
res.status(201).json(response);
|
|
94
|
-
} catch (error) {
|
|
95
|
-
res.status(500).json({
|
|
96
|
-
success: false,
|
|
97
|
-
message: 'Internal server error',
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
// Update an existing group
|
|
103
|
-
export const updateExistingGroup = (req: Request, res: Response): void => {
|
|
104
|
-
try {
|
|
105
|
-
const { id } = req.params;
|
|
106
|
-
const { name, description, servers } = req.body;
|
|
107
|
-
if (!id) {
|
|
108
|
-
res.status(400).json({
|
|
109
|
-
success: false,
|
|
110
|
-
message: 'Group ID is required',
|
|
111
|
-
});
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Allow updating servers along with other fields
|
|
116
|
-
const updateData: any = {};
|
|
117
|
-
if (name !== undefined) updateData.name = name;
|
|
118
|
-
if (description !== undefined) updateData.description = description;
|
|
119
|
-
if (servers !== undefined) updateData.servers = servers;
|
|
120
|
-
|
|
121
|
-
if (Object.keys(updateData).length === 0) {
|
|
122
|
-
res.status(400).json({
|
|
123
|
-
success: false,
|
|
124
|
-
message: 'At least one field (name, description, or servers) is required to update',
|
|
125
|
-
});
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const updatedGroup = updateGroup(id, updateData);
|
|
130
|
-
if (!updatedGroup) {
|
|
131
|
-
res.status(404).json({
|
|
132
|
-
success: false,
|
|
133
|
-
message: 'Group not found or name already exists',
|
|
134
|
-
});
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const response: ApiResponse = {
|
|
139
|
-
success: true,
|
|
140
|
-
data: updatedGroup,
|
|
141
|
-
message: 'Group updated successfully',
|
|
142
|
-
};
|
|
143
|
-
res.json(response);
|
|
144
|
-
} catch (error) {
|
|
145
|
-
res.status(500).json({
|
|
146
|
-
success: false,
|
|
147
|
-
message: 'Internal server error',
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
// Update servers in a group (batch update)
|
|
153
|
-
export const updateGroupServersBatch = (req: Request, res: Response): void => {
|
|
154
|
-
try {
|
|
155
|
-
const { id } = req.params;
|
|
156
|
-
const { servers } = req.body;
|
|
157
|
-
|
|
158
|
-
if (!id) {
|
|
159
|
-
res.status(400).json({
|
|
160
|
-
success: false,
|
|
161
|
-
message: 'Group ID is required',
|
|
162
|
-
});
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (!Array.isArray(servers)) {
|
|
167
|
-
res.status(400).json({
|
|
168
|
-
success: false,
|
|
169
|
-
message: 'Servers must be an array of server names',
|
|
170
|
-
});
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const updatedGroup = updateGroupServers(id, servers);
|
|
175
|
-
if (!updatedGroup) {
|
|
176
|
-
res.status(404).json({
|
|
177
|
-
success: false,
|
|
178
|
-
message: 'Group not found',
|
|
179
|
-
});
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const response: ApiResponse = {
|
|
184
|
-
success: true,
|
|
185
|
-
data: updatedGroup,
|
|
186
|
-
message: 'Group servers updated successfully',
|
|
187
|
-
};
|
|
188
|
-
res.json(response);
|
|
189
|
-
} catch (error) {
|
|
190
|
-
res.status(500).json({
|
|
191
|
-
success: false,
|
|
192
|
-
message: 'Internal server error',
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
// Delete a group
|
|
198
|
-
export const deleteExistingGroup = (req: Request, res: Response): void => {
|
|
199
|
-
try {
|
|
200
|
-
const { id } = req.params;
|
|
201
|
-
if (!id) {
|
|
202
|
-
res.status(400).json({
|
|
203
|
-
success: false,
|
|
204
|
-
message: 'Group ID is required',
|
|
205
|
-
});
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const success = deleteGroup(id);
|
|
210
|
-
if (!success) {
|
|
211
|
-
res.status(404).json({
|
|
212
|
-
success: false,
|
|
213
|
-
message: 'Group not found or failed to delete',
|
|
214
|
-
});
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
res.json({
|
|
219
|
-
success: true,
|
|
220
|
-
message: 'Group deleted successfully',
|
|
221
|
-
});
|
|
222
|
-
} catch (error) {
|
|
223
|
-
res.status(500).json({
|
|
224
|
-
success: false,
|
|
225
|
-
message: 'Internal server error',
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
// Add server to a group
|
|
231
|
-
export const addServerToExistingGroup = (req: Request, res: Response): void => {
|
|
232
|
-
try {
|
|
233
|
-
const { id } = req.params;
|
|
234
|
-
const { serverName } = req.body;
|
|
235
|
-
if (!id) {
|
|
236
|
-
res.status(400).json({
|
|
237
|
-
success: false,
|
|
238
|
-
message: 'Group ID is required',
|
|
239
|
-
});
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
if (!serverName) {
|
|
244
|
-
res.status(400).json({
|
|
245
|
-
success: false,
|
|
246
|
-
message: 'Server name is required',
|
|
247
|
-
});
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const updatedGroup = addServerToGroup(id, serverName);
|
|
252
|
-
if (!updatedGroup) {
|
|
253
|
-
res.status(404).json({
|
|
254
|
-
success: false,
|
|
255
|
-
message: 'Group or server not found',
|
|
256
|
-
});
|
|
257
|
-
return;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
const response: ApiResponse = {
|
|
261
|
-
success: true,
|
|
262
|
-
data: updatedGroup,
|
|
263
|
-
message: 'Server added to group successfully',
|
|
264
|
-
};
|
|
265
|
-
res.json(response);
|
|
266
|
-
} catch (error) {
|
|
267
|
-
res.status(500).json({
|
|
268
|
-
success: false,
|
|
269
|
-
message: 'Internal server error',
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
};
|
|
273
|
-
|
|
274
|
-
// Remove server from a group
|
|
275
|
-
export const removeServerFromExistingGroup = (req: Request, res: Response): void => {
|
|
276
|
-
try {
|
|
277
|
-
const { id, serverName } = req.params;
|
|
278
|
-
if (!id || !serverName) {
|
|
279
|
-
res.status(400).json({
|
|
280
|
-
success: false,
|
|
281
|
-
message: 'Group ID and server name are required',
|
|
282
|
-
});
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const updatedGroup = removeServerFromGroup(id, serverName);
|
|
287
|
-
if (!updatedGroup) {
|
|
288
|
-
res.status(404).json({
|
|
289
|
-
success: false,
|
|
290
|
-
message: 'Group not found',
|
|
291
|
-
});
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
const response: ApiResponse = {
|
|
296
|
-
success: true,
|
|
297
|
-
data: updatedGroup,
|
|
298
|
-
message: 'Server removed from group successfully',
|
|
299
|
-
};
|
|
300
|
-
res.json(response);
|
|
301
|
-
} catch (error) {
|
|
302
|
-
res.status(500).json({
|
|
303
|
-
success: false,
|
|
304
|
-
message: 'Internal server error',
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
// Get servers in a group
|
|
310
|
-
export const getGroupServers = (req: Request, res: Response): void => {
|
|
311
|
-
try {
|
|
312
|
-
const { id } = req.params;
|
|
313
|
-
if (!id) {
|
|
314
|
-
res.status(400).json({
|
|
315
|
-
success: false,
|
|
316
|
-
message: 'Group ID is required',
|
|
317
|
-
});
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
const group = getGroupByIdOrName(id);
|
|
322
|
-
if (!group) {
|
|
323
|
-
res.status(404).json({
|
|
324
|
-
success: false,
|
|
325
|
-
message: 'Group not found',
|
|
326
|
-
});
|
|
327
|
-
return;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
const response: ApiResponse = {
|
|
331
|
-
success: true,
|
|
332
|
-
data: group.servers,
|
|
333
|
-
};
|
|
334
|
-
res.json(response);
|
|
335
|
-
} catch (error) {
|
|
336
|
-
res.status(500).json({
|
|
337
|
-
success: false,
|
|
338
|
-
message: 'Failed to get group servers',
|
|
339
|
-
});
|
|
340
|
-
}
|
|
341
|
-
};
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import { Request, Response } from 'express';
|
|
2
|
-
import { ApiResponse } from '../types/index.js';
|
|
3
|
-
import {
|
|
4
|
-
getMarketServers,
|
|
5
|
-
getMarketServerByName,
|
|
6
|
-
getMarketCategories,
|
|
7
|
-
getMarketTags,
|
|
8
|
-
searchMarketServers,
|
|
9
|
-
filterMarketServersByCategory,
|
|
10
|
-
filterMarketServersByTag
|
|
11
|
-
} from '../services/marketService.js';
|
|
12
|
-
|
|
13
|
-
// Get all market servers
|
|
14
|
-
export const getAllMarketServers = (_: Request, res: Response): void => {
|
|
15
|
-
try {
|
|
16
|
-
const marketServers = Object.values(getMarketServers());
|
|
17
|
-
const response: ApiResponse = {
|
|
18
|
-
success: true,
|
|
19
|
-
data: marketServers,
|
|
20
|
-
};
|
|
21
|
-
res.json(response);
|
|
22
|
-
} catch (error) {
|
|
23
|
-
res.status(500).json({
|
|
24
|
-
success: false,
|
|
25
|
-
message: 'Failed to get market servers information',
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
// Get a specific market server by name
|
|
31
|
-
export const getMarketServer = (req: Request, res: Response): void => {
|
|
32
|
-
try {
|
|
33
|
-
const { name } = req.params;
|
|
34
|
-
if (!name) {
|
|
35
|
-
res.status(400).json({
|
|
36
|
-
success: false,
|
|
37
|
-
message: 'Server name is required',
|
|
38
|
-
});
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const server = getMarketServerByName(name);
|
|
43
|
-
if (!server) {
|
|
44
|
-
res.status(404).json({
|
|
45
|
-
success: false,
|
|
46
|
-
message: 'Market server not found',
|
|
47
|
-
});
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const response: ApiResponse = {
|
|
52
|
-
success: true,
|
|
53
|
-
data: server,
|
|
54
|
-
};
|
|
55
|
-
res.json(response);
|
|
56
|
-
} catch (error) {
|
|
57
|
-
res.status(500).json({
|
|
58
|
-
success: false,
|
|
59
|
-
message: 'Failed to get market server information',
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
// Get all market categories
|
|
65
|
-
export const getAllMarketCategories = (_: Request, res: Response): void => {
|
|
66
|
-
try {
|
|
67
|
-
const categories = getMarketCategories();
|
|
68
|
-
const response: ApiResponse = {
|
|
69
|
-
success: true,
|
|
70
|
-
data: categories,
|
|
71
|
-
};
|
|
72
|
-
res.json(response);
|
|
73
|
-
} catch (error) {
|
|
74
|
-
res.status(500).json({
|
|
75
|
-
success: false,
|
|
76
|
-
message: 'Failed to get market categories',
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
// Get all market tags
|
|
82
|
-
export const getAllMarketTags = (_: Request, res: Response): void => {
|
|
83
|
-
try {
|
|
84
|
-
const tags = getMarketTags();
|
|
85
|
-
const response: ApiResponse = {
|
|
86
|
-
success: true,
|
|
87
|
-
data: tags,
|
|
88
|
-
};
|
|
89
|
-
res.json(response);
|
|
90
|
-
} catch (error) {
|
|
91
|
-
res.status(500).json({
|
|
92
|
-
success: false,
|
|
93
|
-
message: 'Failed to get market tags',
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
// Search market servers
|
|
99
|
-
export const searchMarketServersByQuery = (req: Request, res: Response): void => {
|
|
100
|
-
try {
|
|
101
|
-
const { query } = req.query;
|
|
102
|
-
const searchQuery = typeof query === 'string' ? query : '';
|
|
103
|
-
|
|
104
|
-
const servers = searchMarketServers(searchQuery);
|
|
105
|
-
const response: ApiResponse = {
|
|
106
|
-
success: true,
|
|
107
|
-
data: servers,
|
|
108
|
-
};
|
|
109
|
-
res.json(response);
|
|
110
|
-
} catch (error) {
|
|
111
|
-
res.status(500).json({
|
|
112
|
-
success: false,
|
|
113
|
-
message: 'Failed to search market servers',
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
// Filter market servers by category
|
|
119
|
-
export const getMarketServersByCategory = (req: Request, res: Response): void => {
|
|
120
|
-
try {
|
|
121
|
-
const { category } = req.params;
|
|
122
|
-
|
|
123
|
-
const servers = filterMarketServersByCategory(category);
|
|
124
|
-
const response: ApiResponse = {
|
|
125
|
-
success: true,
|
|
126
|
-
data: servers,
|
|
127
|
-
};
|
|
128
|
-
res.json(response);
|
|
129
|
-
} catch (error) {
|
|
130
|
-
res.status(500).json({
|
|
131
|
-
success: false,
|
|
132
|
-
message: 'Failed to filter market servers by category',
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
// Filter market servers by tag
|
|
138
|
-
export const getMarketServersByTag = (req: Request, res: Response): void => {
|
|
139
|
-
try {
|
|
140
|
-
const { tag } = req.params;
|
|
141
|
-
|
|
142
|
-
const servers = filterMarketServersByTag(tag);
|
|
143
|
-
const response: ApiResponse = {
|
|
144
|
-
success: true,
|
|
145
|
-
data: servers,
|
|
146
|
-
};
|
|
147
|
-
res.json(response);
|
|
148
|
-
} catch (error) {
|
|
149
|
-
res.status(500).json({
|
|
150
|
-
success: false,
|
|
151
|
-
message: 'Failed to filter market servers by tag',
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
};
|