@loop_ouroboros/mcp-hub-lite 1.2.0 → 1.2.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/CHANGELOG.md +23 -4
- package/README.md +12 -8
- package/dist/client/assets/{HomeView-BBwvy1oj.js → HomeView-V1fKvWQ8.js} +1 -1
- package/dist/client/assets/{ResourceDetailView-CZ2aB73w.js → ResourceDetailView-DHGHssrh.js} +1 -1
- package/dist/client/assets/{ResourcesView-CN1NlhWs.js → ResourcesView-B1bvkmQD.js} +1 -1
- package/dist/client/assets/{ServerDashboard-k652Vw4Z.js → ServerDashboard-CZCByd7y.js} +1 -1
- package/dist/client/assets/{ServerDetail-BLQ-a4cO.js → ServerDetail-CI5UD8gj.js} +1 -1
- package/dist/client/assets/{ServerListView-BHrsFD5i.js → ServerListView-D8qv-xYg.js} +1 -1
- package/dist/client/assets/SettingsView-C-ae0-zz.js +1 -0
- package/dist/client/assets/{ToolCallDialog-BfPjLxfV.js → ToolCallDialog-BudOyGvS.js} +1 -1
- package/dist/client/assets/{ToolsView-CyuhYAE2.js → ToolsView-CbQkgTAu.js} +1 -1
- package/dist/client/assets/{_baseClone-DO5qfalW.js → _baseClone-e9R6V78L.js} +1 -1
- package/dist/client/assets/{el-form-item-CcGsD2K_.js → el-form-item-Dyx5MiWB.js} +1 -1
- package/dist/client/assets/{el-input-tYgeiaCT.js → el-input-CL9HPfdW.js} +1 -1
- package/dist/client/assets/{el-loading-Dwl9E_Vr.js → el-loading-2TW6JdfY.js} +1 -1
- package/dist/client/assets/{el-overlay-kqX_BABo.js → el-overlay-B5ZGCmXY.js} +1 -1
- package/dist/client/assets/{el-radio-group-D8aWBVOT.js → el-radio-group-Cr2ScjjJ.js} +1 -1
- package/dist/client/assets/{el-skeleton-item-BRwIFspE.js → el-skeleton-item-CdAfEgVR.js} +1 -1
- package/dist/client/assets/{el-switch-BF8c-xeU.js → el-switch-DnN1s0Wb.js} +1 -1
- package/dist/client/assets/{el-tab-pane-C4Ep94cd.js → el-tab-pane-BebZh0XF.js} +1 -1
- package/dist/client/assets/{el-table-column-Cog6uCh-.js → el-table-column-CV2zp3yI.js} +1 -1
- package/dist/client/assets/{index-ByNBhPAR.js → index-Ci5n5dA9.js} +1 -1
- package/dist/client/assets/index-DTZ9o3XO.js +2 -0
- package/dist/client/assets/{omit-CUnDT6sS.js → omit-DlmW8Yd6.js} +1 -1
- package/dist/client/assets/{raf-CmzeRPMd.js → raf-CeCd08aN.js} +1 -1
- package/dist/client/index.html +1 -1
- package/dist/server/shared/models/server.model.d.ts +22 -0
- package/dist/server/shared/models/server.model.d.ts.map +1 -1
- package/dist/server/shared/models/server.model.js +41 -5
- package/dist/server/src/api/mcp/gateway.d.ts.map +1 -1
- package/dist/server/src/api/mcp/gateway.js +13 -5
- package/dist/server/src/api/web/resources.d.ts.map +1 -1
- package/dist/server/src/api/web/resources.js +26 -2
- package/dist/server/src/cli/index.js +1 -1
- package/dist/server/src/config/config-loader.js +1 -1
- package/dist/server/src/config/config-migrator.d.ts.map +1 -1
- package/dist/server/src/config/config-migrator.js +1 -0
- package/dist/server/src/index.js +2 -7
- package/dist/server/src/server/dev-server.js +9 -48
- package/dist/server/src/server/runner.d.ts +12 -24
- package/dist/server/src/server/runner.d.ts.map +1 -1
- package/dist/server/src/server/runner.js +29 -109
- package/dist/server/src/server/startup.d.ts +43 -0
- package/dist/server/src/server/startup.d.ts.map +1 -0
- package/dist/server/src/server/startup.js +89 -0
- package/dist/server/src/services/connection/connection-manager.d.ts +52 -0
- package/dist/server/src/services/connection/connection-manager.d.ts.map +1 -1
- package/dist/server/src/services/connection/connection-manager.js +283 -193
- package/dist/server/src/services/gateway/gateway.service.d.ts.map +1 -1
- package/dist/server/src/services/gateway/gateway.service.js +31 -10
- package/dist/server/src/services/gateway/global-transport.d.ts.map +1 -1
- package/dist/server/src/services/gateway/global-transport.js +11 -5
- package/dist/server/src/services/hub-manager.service.d.ts +2 -0
- package/dist/server/src/services/hub-manager.service.d.ts.map +1 -1
- package/dist/server/src/services/hub-manager.service.js +3 -16
- package/dist/server/src/utils/json-utils.d.ts +7 -0
- package/dist/server/src/utils/json-utils.d.ts.map +1 -1
- package/dist/server/src/utils/json-utils.js +17 -0
- package/dist/server/src/utils/logger/log-modules.d.ts +3 -0
- package/dist/server/src/utils/logger/log-modules.d.ts.map +1 -1
- package/dist/server/src/utils/logger/log-modules.js +2 -0
- package/dist/server/src/utils/port-checker.d.ts +18 -0
- package/dist/server/src/utils/port-checker.d.ts.map +1 -1
- package/dist/server/src/utils/port-checker.js +38 -0
- package/dist/server/src/utils/transports/stdio-transport.d.ts +12 -0
- package/dist/server/src/utils/transports/stdio-transport.d.ts.map +1 -1
- package/dist/server/src/utils/transports/stdio-transport.js +51 -2
- package/dist/server/src/utils/transports/transport-factory.d.ts +5 -1
- package/dist/server/src/utils/transports/transport-factory.d.ts.map +1 -1
- package/dist/server/src/utils/transports/transport-factory.js +5 -2
- package/dist/server/tests/integration/gateway/fault-tolerance.test.js +13 -2
- package/dist/server/tests/integration/gateway/mcp-connection.test.js +13 -2
- package/dist/server/tests/unit/config/config-migrator.test.js +4 -2
- package/dist/server/tests/unit/config/config.schema.test.js +2 -1
- package/dist/server/tests/unit/server/runner.test.js +77 -92
- package/dist/server/tests/unit/services/hub-manager-service.test.js +3 -2
- package/dist/server/tests/unit/utils/config.test.js +14 -7
- package/dist/server/tests/unit/utils/json-utils.test.js +28 -14
- package/dist/server/vite.config.d.ts.map +1 -1
- package/dist/server/vite.config.js +1 -0
- package/package.json +1 -1
- package/dist/client/assets/SettingsView-CUOFNXrz.js +0 -1
- package/dist/client/assets/index-CTB6oe-9.js +0 -2
|
@@ -4,9 +4,8 @@ import { buildApp } from '../../../src/app.js';
|
|
|
4
4
|
import { configManager } from '../../../src/config/config-manager.js';
|
|
5
5
|
import { logger } from '../../../src/utils/logger.js';
|
|
6
6
|
import { mcpConnectionManager } from '../../../src/services/mcp-connection-manager.js';
|
|
7
|
-
import { gateway } from '../../../src/services/gateway.service.js';
|
|
8
7
|
import { PidManager } from '../../../src/pid/manager.js';
|
|
9
|
-
import { checkPort } from '../../../src/utils/port-checker.js';
|
|
8
|
+
import { checkPort, checkPortWithExit } from '../../../src/utils/port-checker.js';
|
|
10
9
|
// Mock resolveInstanceConfig to return a valid resolved config
|
|
11
10
|
vi.mock('@config/config-migrator.js', () => ({
|
|
12
11
|
resolveInstanceConfig: vi.fn(() => ({
|
|
@@ -46,15 +45,10 @@ vi.mock('@utils/logger.js', () => ({
|
|
|
46
45
|
}));
|
|
47
46
|
vi.mock('@services/mcp-connection-manager.js', () => ({
|
|
48
47
|
mcpConnectionManager: {
|
|
49
|
-
connect: vi.fn(),
|
|
48
|
+
connect: vi.fn(() => Promise.resolve(true)),
|
|
50
49
|
disconnectAll: vi.fn()
|
|
51
50
|
}
|
|
52
51
|
}));
|
|
53
|
-
vi.mock('@services/gateway.service.js', () => ({
|
|
54
|
-
gateway: {
|
|
55
|
-
start: vi.fn()
|
|
56
|
-
}
|
|
57
|
-
}));
|
|
58
52
|
vi.mock('@pid/manager.js', () => ({
|
|
59
53
|
PidManager: {
|
|
60
54
|
writePid: vi.fn(),
|
|
@@ -62,7 +56,8 @@ vi.mock('@pid/manager.js', () => ({
|
|
|
62
56
|
}
|
|
63
57
|
}));
|
|
64
58
|
vi.mock('@utils/port-checker.js', () => ({
|
|
65
|
-
checkPort: vi.fn()
|
|
59
|
+
checkPort: vi.fn(),
|
|
60
|
+
checkPortWithExit: vi.fn().mockResolvedValue(undefined)
|
|
66
61
|
}));
|
|
67
62
|
describe('Server Runner', () => {
|
|
68
63
|
beforeEach(() => {
|
|
@@ -75,9 +70,13 @@ describe('Server Runner', () => {
|
|
|
75
70
|
// Clean up any remaining listeners
|
|
76
71
|
process.removeAllListeners('SIGTERM');
|
|
77
72
|
process.removeAllListeners('SIGINT');
|
|
73
|
+
// Reset mock implementations that might persist between tests
|
|
74
|
+
vi.mocked(checkPortWithExit).mockReset();
|
|
75
|
+
vi.mocked(configManager.addServerInstance).mockReset();
|
|
76
|
+
vi.mocked(configManager.getServerInstancesByName).mockReset();
|
|
78
77
|
});
|
|
79
78
|
describe('runServer function', () => {
|
|
80
|
-
it('should start server
|
|
79
|
+
it('should start server successfully', async () => {
|
|
81
80
|
// Setup mocks
|
|
82
81
|
const mockApp = {
|
|
83
82
|
listen: vi.fn().mockResolvedValue(undefined),
|
|
@@ -96,7 +95,8 @@ describe('Server Runner', () => {
|
|
|
96
95
|
rotationAge: '7d',
|
|
97
96
|
jsonPretty: true,
|
|
98
97
|
mcpCommDebug: false,
|
|
99
|
-
apiDebug: false
|
|
98
|
+
apiDebug: false,
|
|
99
|
+
gatewayDebug: false
|
|
100
100
|
}
|
|
101
101
|
},
|
|
102
102
|
security: {
|
|
@@ -113,51 +113,13 @@ describe('Server Runner', () => {
|
|
|
113
113
|
vi.mocked(configManager.getServers).mockReturnValue([]);
|
|
114
114
|
vi.mocked(checkPort).mockResolvedValue({ inUse: false });
|
|
115
115
|
// Execute
|
|
116
|
-
await runServer({
|
|
116
|
+
await runServer({ port: 3000, host: 'localhost' });
|
|
117
117
|
// Verify
|
|
118
118
|
expect(buildApp).toHaveBeenCalled();
|
|
119
119
|
expect(mockApp.listen).toHaveBeenCalledWith({ port: 3000, host: 'localhost' });
|
|
120
120
|
expect(PidManager.writePid).toHaveBeenCalled();
|
|
121
121
|
expect(logger.info).toHaveBeenCalledWith('MCP Hub Lite Server running at http://localhost:3000', expect.any(Object));
|
|
122
122
|
});
|
|
123
|
-
it('should start server in stdio mode successfully', async () => {
|
|
124
|
-
// Setup mocks
|
|
125
|
-
const mockConfig = {
|
|
126
|
-
version: '1.1.0',
|
|
127
|
-
system: {
|
|
128
|
-
host: 'localhost',
|
|
129
|
-
port: 3000,
|
|
130
|
-
language: 'zh',
|
|
131
|
-
theme: 'system',
|
|
132
|
-
logging: {
|
|
133
|
-
level: 'info',
|
|
134
|
-
rotationAge: '7d',
|
|
135
|
-
jsonPretty: true,
|
|
136
|
-
mcpCommDebug: false,
|
|
137
|
-
apiDebug: false
|
|
138
|
-
}
|
|
139
|
-
},
|
|
140
|
-
security: {
|
|
141
|
-
allowedNetworks: ['127.0.0.1'],
|
|
142
|
-
maxConcurrentConnections: 50,
|
|
143
|
-
connectionTimeout: 30000,
|
|
144
|
-
idleConnectionTimeout: 300000,
|
|
145
|
-
maxConnections: 50
|
|
146
|
-
},
|
|
147
|
-
servers: {},
|
|
148
|
-
tagDefinitions: []
|
|
149
|
-
};
|
|
150
|
-
vi.mocked(configManager.getConfig).mockReturnValue(mockConfig);
|
|
151
|
-
vi.mocked(configManager.getServers).mockReturnValue([]);
|
|
152
|
-
// Execute
|
|
153
|
-
await runServer({ stdio: true });
|
|
154
|
-
// Verify
|
|
155
|
-
expect(buildApp).not.toHaveBeenCalled();
|
|
156
|
-
expect(gateway.start).toHaveBeenCalled();
|
|
157
|
-
expect(PidManager.writePid).toHaveBeenCalled();
|
|
158
|
-
expect(logger.setUseStderr).toHaveBeenCalledWith(true);
|
|
159
|
-
expect(logger.info).toHaveBeenCalledWith('Starting in MCP Gateway mode (stdio)...', expect.any(Object));
|
|
160
|
-
});
|
|
161
123
|
it('should handle port already in use by self project', async () => {
|
|
162
124
|
// Setup mocks
|
|
163
125
|
const mockApp = { listen: vi.fn(), close: vi.fn() };
|
|
@@ -174,7 +136,8 @@ describe('Server Runner', () => {
|
|
|
174
136
|
rotationAge: '7d',
|
|
175
137
|
jsonPretty: true,
|
|
176
138
|
mcpCommDebug: false,
|
|
177
|
-
apiDebug: false
|
|
139
|
+
apiDebug: false,
|
|
140
|
+
gatewayDebug: false
|
|
178
141
|
}
|
|
179
142
|
},
|
|
180
143
|
security: {
|
|
@@ -189,20 +152,20 @@ describe('Server Runner', () => {
|
|
|
189
152
|
};
|
|
190
153
|
vi.mocked(configManager.getConfig).mockReturnValue(mockConfig);
|
|
191
154
|
vi.mocked(configManager.getServers).mockReturnValue([]);
|
|
192
|
-
|
|
193
|
-
inUse: true,
|
|
194
|
-
isSelfProject: true,
|
|
195
|
-
pid: 1234
|
|
196
|
-
});
|
|
197
|
-
// Spy on process.exit
|
|
155
|
+
// Spy on process.exit before setting up checkPortWithExit mock
|
|
198
156
|
const exitSpy = vi.spyOn(process, 'exit').mockImplementation((() => {
|
|
199
157
|
throw new Error('process.exit called');
|
|
200
158
|
}));
|
|
159
|
+
// Mock checkPortWithExit to call process.exit(1)
|
|
160
|
+
vi.mocked(checkPortWithExit).mockImplementation(() => {
|
|
161
|
+
// Call the real implementation's exit behavior
|
|
162
|
+
logger.error('MCP Hub Lite is already running on port 3000 (PID: 1234)', expect.any(Object));
|
|
163
|
+
logger.error("Use 'npm run stop' or 'mcp-hub-lite stop' to stop the running instance.", expect.any(Object));
|
|
164
|
+
process.exit(1);
|
|
165
|
+
});
|
|
201
166
|
// Execute and expect error
|
|
202
|
-
await expect(runServer({
|
|
167
|
+
await expect(runServer({ port: 3000, host: 'localhost' })).rejects.toThrow('process.exit called');
|
|
203
168
|
// Verify
|
|
204
|
-
expect(logger.error).toHaveBeenCalledWith('MCP Hub Lite is already running on port 3000 (PID: 1234)', expect.any(Object));
|
|
205
|
-
expect(logger.error).toHaveBeenCalledWith("Use 'npm run stop' or 'mcp-hub-lite stop' to stop the running instance.", expect.any(Object));
|
|
206
169
|
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
207
170
|
// Restore
|
|
208
171
|
exitSpy.mockRestore();
|
|
@@ -223,7 +186,8 @@ describe('Server Runner', () => {
|
|
|
223
186
|
rotationAge: '7d',
|
|
224
187
|
jsonPretty: true,
|
|
225
188
|
mcpCommDebug: false,
|
|
226
|
-
apiDebug: false
|
|
189
|
+
apiDebug: false,
|
|
190
|
+
gatewayDebug: false
|
|
227
191
|
}
|
|
228
192
|
},
|
|
229
193
|
security: {
|
|
@@ -238,24 +202,22 @@ describe('Server Runner', () => {
|
|
|
238
202
|
};
|
|
239
203
|
vi.mocked(configManager.getConfig).mockReturnValue(mockConfig);
|
|
240
204
|
vi.mocked(configManager.getServers).mockReturnValue([]);
|
|
241
|
-
|
|
242
|
-
inUse: true,
|
|
243
|
-
isSelfProject: false,
|
|
244
|
-
pid: 5678,
|
|
245
|
-
processName: 'other-app',
|
|
246
|
-
commandLine: 'node other-app.js'
|
|
247
|
-
});
|
|
248
|
-
// Spy on process.exit
|
|
205
|
+
// Spy on process.exit before setting up checkPortWithExit mock
|
|
249
206
|
const exitSpy = vi.spyOn(process, 'exit').mockImplementation((() => {
|
|
250
207
|
throw new Error('process.exit called');
|
|
251
208
|
}));
|
|
209
|
+
// Mock checkPortWithExit to call process.exit(1)
|
|
210
|
+
vi.mocked(checkPortWithExit).mockImplementation(() => {
|
|
211
|
+
// Call the real implementation's exit behavior
|
|
212
|
+
logger.error('Port 3000 is already in use by another application:', expect.any(Object));
|
|
213
|
+
logger.error(' Process: other-app (PID: 5678)', expect.any(Object));
|
|
214
|
+
logger.error(' Command: node other-app.js', expect.any(Object));
|
|
215
|
+
logger.error('Please stop the conflicting application or use a different port.', expect.any(Object));
|
|
216
|
+
process.exit(1);
|
|
217
|
+
});
|
|
252
218
|
// Execute and expect error
|
|
253
|
-
await expect(runServer({
|
|
219
|
+
await expect(runServer({ port: 3000, host: 'localhost' })).rejects.toThrow('process.exit called');
|
|
254
220
|
// Verify
|
|
255
|
-
expect(logger.error).toHaveBeenCalledWith('Port 3000 is already in use by another application:', expect.any(Object));
|
|
256
|
-
expect(logger.error).toHaveBeenCalledWith(' Process: other-app (PID: 5678)', expect.any(Object));
|
|
257
|
-
expect(logger.error).toHaveBeenCalledWith(' Command: node other-app.js', expect.any(Object));
|
|
258
|
-
expect(logger.error).toHaveBeenCalledWith('Please stop the conflicting application or use a different port.', expect.any(Object));
|
|
259
221
|
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
260
222
|
// Restore
|
|
261
223
|
exitSpy.mockRestore();
|
|
@@ -279,7 +241,8 @@ describe('Server Runner', () => {
|
|
|
279
241
|
rotationAge: '7d',
|
|
280
242
|
jsonPretty: true,
|
|
281
243
|
mcpCommDebug: false,
|
|
282
|
-
apiDebug: false
|
|
244
|
+
apiDebug: false,
|
|
245
|
+
gatewayDebug: false
|
|
283
246
|
}
|
|
284
247
|
},
|
|
285
248
|
security: {
|
|
@@ -333,21 +296,40 @@ describe('Server Runner', () => {
|
|
|
333
296
|
}
|
|
334
297
|
];
|
|
335
298
|
vi.mocked(configManager.getServers).mockReturnValue(mockServers);
|
|
299
|
+
// Track if addServerInstance was called for enabled-server
|
|
300
|
+
let addServerInstanceCalled = false;
|
|
301
|
+
vi.mocked(configManager.addServerInstance).mockImplementation(async (name) => {
|
|
302
|
+
if (name === 'enabled-server') {
|
|
303
|
+
addServerInstanceCalled = true;
|
|
304
|
+
return {
|
|
305
|
+
id: 'new-instance',
|
|
306
|
+
enabled: true,
|
|
307
|
+
args: [],
|
|
308
|
+
env: {},
|
|
309
|
+
headers: {},
|
|
310
|
+
tags: {}
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
return {
|
|
314
|
+
id: 'instance-1',
|
|
315
|
+
enabled: false,
|
|
316
|
+
args: [],
|
|
317
|
+
env: {},
|
|
318
|
+
headers: {},
|
|
319
|
+
tags: {}
|
|
320
|
+
};
|
|
321
|
+
});
|
|
322
|
+
// Make getServerInstancesByName return the new instance after addServerInstance is called
|
|
336
323
|
vi.mocked(configManager.getServerInstancesByName).mockImplementation((name) => {
|
|
337
|
-
if (name === 'enabled-server')
|
|
338
|
-
return
|
|
324
|
+
if (name === 'enabled-server') {
|
|
325
|
+
return addServerInstanceCalled
|
|
326
|
+
? [{ id: 'new-instance', enabled: true, args: [], env: {}, headers: {}, tags: {} }]
|
|
327
|
+
: [];
|
|
328
|
+
}
|
|
339
329
|
return [{ id: 'instance-1', enabled: false, args: [], env: {}, headers: {}, tags: {} }];
|
|
340
330
|
});
|
|
341
|
-
vi.mocked(configManager.addServerInstance).mockResolvedValue({
|
|
342
|
-
id: 'new-instance',
|
|
343
|
-
enabled: true,
|
|
344
|
-
args: [],
|
|
345
|
-
env: {},
|
|
346
|
-
headers: {},
|
|
347
|
-
tags: {}
|
|
348
|
-
});
|
|
349
331
|
// Execute
|
|
350
|
-
await runServer({
|
|
332
|
+
await runServer({ port: 3000, host: 'localhost' });
|
|
351
333
|
// Verify
|
|
352
334
|
// Only enabled server should be connected (1 call expected)
|
|
353
335
|
expect(mcpConnectionManager.connect).toHaveBeenCalledTimes(1);
|
|
@@ -377,7 +359,8 @@ describe('Server Runner', () => {
|
|
|
377
359
|
rotationAge: '7d',
|
|
378
360
|
jsonPretty: true,
|
|
379
361
|
mcpCommDebug: false,
|
|
380
|
-
apiDebug: false
|
|
362
|
+
apiDebug: false,
|
|
363
|
+
gatewayDebug: false
|
|
381
364
|
}
|
|
382
365
|
},
|
|
383
366
|
security: {
|
|
@@ -398,7 +381,7 @@ describe('Server Runner', () => {
|
|
|
398
381
|
.spyOn(process, 'exit')
|
|
399
382
|
.mockImplementation((() => { }));
|
|
400
383
|
// Start server
|
|
401
|
-
await runServer({
|
|
384
|
+
await runServer({ port: 3000, host: 'localhost' });
|
|
402
385
|
// Trigger SIGTERM
|
|
403
386
|
process.emit('SIGTERM');
|
|
404
387
|
// Wait for async operations
|
|
@@ -431,7 +414,8 @@ describe('Server Runner', () => {
|
|
|
431
414
|
rotationAge: '7d',
|
|
432
415
|
jsonPretty: true,
|
|
433
416
|
mcpCommDebug: false,
|
|
434
|
-
apiDebug: false
|
|
417
|
+
apiDebug: false,
|
|
418
|
+
gatewayDebug: false
|
|
435
419
|
}
|
|
436
420
|
},
|
|
437
421
|
security: {
|
|
@@ -452,7 +436,7 @@ describe('Server Runner', () => {
|
|
|
452
436
|
.spyOn(process, 'exit')
|
|
453
437
|
.mockImplementation((() => { }));
|
|
454
438
|
// Start server
|
|
455
|
-
await runServer({
|
|
439
|
+
await runServer({ port: 3000, host: 'localhost' });
|
|
456
440
|
// Trigger SIGINT
|
|
457
441
|
process.emit('SIGINT');
|
|
458
442
|
// Wait for async operations
|
|
@@ -481,7 +465,8 @@ describe('Server Runner', () => {
|
|
|
481
465
|
rotationAge: '7d',
|
|
482
466
|
jsonPretty: true,
|
|
483
467
|
mcpCommDebug: false,
|
|
484
|
-
apiDebug: false
|
|
468
|
+
apiDebug: false,
|
|
469
|
+
gatewayDebug: false
|
|
485
470
|
}
|
|
486
471
|
},
|
|
487
472
|
security: {
|
|
@@ -500,7 +485,7 @@ describe('Server Runner', () => {
|
|
|
500
485
|
throw new Error('process.exit called');
|
|
501
486
|
}));
|
|
502
487
|
// Execute and expect error
|
|
503
|
-
await expect(runServer({
|
|
488
|
+
await expect(runServer({ port: 3000, host: 'localhost' })).rejects.toThrow('process.exit called');
|
|
504
489
|
// Verify
|
|
505
490
|
expect(logger.error).toHaveBeenCalledWith('Failed to start server:', expect.any(Error), expect.any(Object));
|
|
506
491
|
expect(PidManager.removePid).toHaveBeenCalled();
|
|
@@ -49,7 +49,7 @@ describe('HubManagerService', () => {
|
|
|
49
49
|
vi.clearAllMocks();
|
|
50
50
|
service = new HubManagerService(configManager);
|
|
51
51
|
});
|
|
52
|
-
it('should
|
|
52
|
+
it('should add server instance without auto-connect', async () => {
|
|
53
53
|
// Import the mocked module
|
|
54
54
|
const { resolveInstanceConfig } = await import('../../../src/config/config-migrator.js');
|
|
55
55
|
const serverName = 'Test Server';
|
|
@@ -91,7 +91,8 @@ describe('HubManagerService', () => {
|
|
|
91
91
|
await service.addServerInstance(serverName, serverInstanceConfig);
|
|
92
92
|
expect(configManager.addServer).toHaveBeenCalled();
|
|
93
93
|
expect(configManager.addServerInstance).toHaveBeenCalled();
|
|
94
|
-
|
|
94
|
+
// Note: addServerInstance no longer auto-connects - explicit connection via connectServerInstances is required
|
|
95
|
+
expect(mcpConnectionManager.connect).not.toHaveBeenCalled();
|
|
95
96
|
});
|
|
96
97
|
it('should NOT auto-connect when adding a disabled server instance', async () => {
|
|
97
98
|
// Import the mocked module
|
|
@@ -80,7 +80,8 @@ describe('ConfigManager', () => {
|
|
|
80
80
|
rotationAge: '30d',
|
|
81
81
|
jsonPretty: true,
|
|
82
82
|
mcpCommDebug: false,
|
|
83
|
-
apiDebug: false
|
|
83
|
+
apiDebug: false,
|
|
84
|
+
gatewayDebug: false
|
|
84
85
|
}
|
|
85
86
|
},
|
|
86
87
|
security: {
|
|
@@ -149,7 +150,8 @@ describe('ConfigManager', () => {
|
|
|
149
150
|
rotationAge: '7d',
|
|
150
151
|
jsonPretty: true,
|
|
151
152
|
mcpCommDebug: false,
|
|
152
|
-
apiDebug: false
|
|
153
|
+
apiDebug: false,
|
|
154
|
+
gatewayDebug: false
|
|
153
155
|
}
|
|
154
156
|
}
|
|
155
157
|
});
|
|
@@ -193,7 +195,8 @@ describe('ConfigManager', () => {
|
|
|
193
195
|
rotationAge: '7d',
|
|
194
196
|
jsonPretty: true,
|
|
195
197
|
mcpCommDebug: false,
|
|
196
|
-
apiDebug: false
|
|
198
|
+
apiDebug: false,
|
|
199
|
+
gatewayDebug: false
|
|
197
200
|
}
|
|
198
201
|
}
|
|
199
202
|
});
|
|
@@ -235,7 +238,8 @@ describe('ConfigManager', () => {
|
|
|
235
238
|
rotationAge: '7d',
|
|
236
239
|
jsonPretty: true,
|
|
237
240
|
mcpCommDebug: false,
|
|
238
|
-
apiDebug: false
|
|
241
|
+
apiDebug: false,
|
|
242
|
+
gatewayDebug: false
|
|
239
243
|
}
|
|
240
244
|
}
|
|
241
245
|
};
|
|
@@ -404,7 +408,8 @@ describe('ConfigManager', () => {
|
|
|
404
408
|
rotationAge: '7d',
|
|
405
409
|
jsonPretty: true,
|
|
406
410
|
mcpCommDebug: false,
|
|
407
|
-
apiDebug: false
|
|
411
|
+
apiDebug: false,
|
|
412
|
+
gatewayDebug: false
|
|
408
413
|
}
|
|
409
414
|
},
|
|
410
415
|
security: {
|
|
@@ -457,7 +462,8 @@ describe('ConfigManager', () => {
|
|
|
457
462
|
rotationAge: '7d',
|
|
458
463
|
jsonPretty: true,
|
|
459
464
|
mcpCommDebug: false,
|
|
460
|
-
apiDebug: false
|
|
465
|
+
apiDebug: false,
|
|
466
|
+
gatewayDebug: false
|
|
461
467
|
}
|
|
462
468
|
}
|
|
463
469
|
});
|
|
@@ -474,7 +480,8 @@ describe('ConfigManager', () => {
|
|
|
474
480
|
rotationAge: '7d',
|
|
475
481
|
jsonPretty: true,
|
|
476
482
|
mcpCommDebug: false,
|
|
477
|
-
apiDebug: false
|
|
483
|
+
apiDebug: false,
|
|
484
|
+
gatewayDebug: false
|
|
478
485
|
}
|
|
479
486
|
},
|
|
480
487
|
security: {
|
|
@@ -13,7 +13,8 @@ describe('json-utils', () => {
|
|
|
13
13
|
logging: {
|
|
14
14
|
jsonPretty: true,
|
|
15
15
|
mcpCommDebug: false,
|
|
16
|
-
apiDebug: false
|
|
16
|
+
apiDebug: false,
|
|
17
|
+
gatewayDebug: false
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
}));
|
|
@@ -35,7 +36,8 @@ describe('json-utils', () => {
|
|
|
35
36
|
logging: {
|
|
36
37
|
jsonPretty: true,
|
|
37
38
|
mcpCommDebug: false,
|
|
38
|
-
apiDebug: false
|
|
39
|
+
apiDebug: false,
|
|
40
|
+
gatewayDebug: false
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
43
|
}));
|
|
@@ -53,7 +55,8 @@ describe('json-utils', () => {
|
|
|
53
55
|
logging: {
|
|
54
56
|
jsonPretty: true,
|
|
55
57
|
mcpCommDebug: false,
|
|
56
|
-
apiDebug: false
|
|
58
|
+
apiDebug: false,
|
|
59
|
+
gatewayDebug: false
|
|
57
60
|
}
|
|
58
61
|
}
|
|
59
62
|
}));
|
|
@@ -72,7 +75,8 @@ describe('json-utils', () => {
|
|
|
72
75
|
logging: {
|
|
73
76
|
jsonPretty: true,
|
|
74
77
|
mcpCommDebug: false,
|
|
75
|
-
apiDebug: false
|
|
78
|
+
apiDebug: false,
|
|
79
|
+
gatewayDebug: false
|
|
76
80
|
}
|
|
77
81
|
}
|
|
78
82
|
}));
|
|
@@ -102,7 +106,8 @@ describe('json-utils', () => {
|
|
|
102
106
|
logging: {
|
|
103
107
|
jsonPretty: false,
|
|
104
108
|
mcpCommDebug: false,
|
|
105
|
-
apiDebug: false
|
|
109
|
+
apiDebug: false,
|
|
110
|
+
gatewayDebug: false
|
|
106
111
|
}
|
|
107
112
|
}
|
|
108
113
|
}));
|
|
@@ -182,7 +187,8 @@ describe('json-utils', () => {
|
|
|
182
187
|
logging: {
|
|
183
188
|
jsonPretty: false,
|
|
184
189
|
mcpCommDebug: false,
|
|
185
|
-
apiDebug: false
|
|
190
|
+
apiDebug: false,
|
|
191
|
+
gatewayDebug: false
|
|
186
192
|
}
|
|
187
193
|
}
|
|
188
194
|
}));
|
|
@@ -192,7 +198,8 @@ describe('json-utils', () => {
|
|
|
192
198
|
logging: {
|
|
193
199
|
jsonPretty: true,
|
|
194
200
|
mcpCommDebug: false,
|
|
195
|
-
apiDebug: false
|
|
201
|
+
apiDebug: false,
|
|
202
|
+
gatewayDebug: false
|
|
196
203
|
}
|
|
197
204
|
}
|
|
198
205
|
}));
|
|
@@ -212,7 +219,8 @@ describe('json-utils', () => {
|
|
|
212
219
|
logging: {
|
|
213
220
|
jsonPretty: false, // Config says false, but env should override
|
|
214
221
|
mcpCommDebug: false,
|
|
215
|
-
apiDebug: false
|
|
222
|
+
apiDebug: false,
|
|
223
|
+
gatewayDebug: false
|
|
216
224
|
}
|
|
217
225
|
}
|
|
218
226
|
}));
|
|
@@ -231,7 +239,8 @@ describe('json-utils', () => {
|
|
|
231
239
|
logging: {
|
|
232
240
|
jsonPretty: false, // Config says false, but env should override
|
|
233
241
|
mcpCommDebug: false,
|
|
234
|
-
apiDebug: false
|
|
242
|
+
apiDebug: false,
|
|
243
|
+
gatewayDebug: false
|
|
235
244
|
}
|
|
236
245
|
}
|
|
237
246
|
}));
|
|
@@ -250,7 +259,8 @@ describe('json-utils', () => {
|
|
|
250
259
|
logging: {
|
|
251
260
|
jsonPretty: true, // Config says true, but env should override
|
|
252
261
|
mcpCommDebug: false,
|
|
253
|
-
apiDebug: false
|
|
262
|
+
apiDebug: false,
|
|
263
|
+
gatewayDebug: false
|
|
254
264
|
}
|
|
255
265
|
}
|
|
256
266
|
}));
|
|
@@ -269,7 +279,8 @@ describe('json-utils', () => {
|
|
|
269
279
|
logging: {
|
|
270
280
|
jsonPretty: true, // Config says true, but env should override
|
|
271
281
|
mcpCommDebug: false,
|
|
272
|
-
apiDebug: false
|
|
282
|
+
apiDebug: false,
|
|
283
|
+
gatewayDebug: false
|
|
273
284
|
}
|
|
274
285
|
}
|
|
275
286
|
}));
|
|
@@ -288,7 +299,8 @@ describe('json-utils', () => {
|
|
|
288
299
|
logging: {
|
|
289
300
|
jsonPretty: false,
|
|
290
301
|
mcpCommDebug: false,
|
|
291
|
-
apiDebug: false
|
|
302
|
+
apiDebug: false,
|
|
303
|
+
gatewayDebug: false
|
|
292
304
|
}
|
|
293
305
|
}
|
|
294
306
|
}));
|
|
@@ -311,7 +323,8 @@ describe('json-utils', () => {
|
|
|
311
323
|
logging: {
|
|
312
324
|
jsonPretty: false,
|
|
313
325
|
mcpCommDebug: true,
|
|
314
|
-
apiDebug: true
|
|
326
|
+
apiDebug: true,
|
|
327
|
+
gatewayDebug: false
|
|
315
328
|
}
|
|
316
329
|
}
|
|
317
330
|
}));
|
|
@@ -364,7 +377,8 @@ describe('json-utils', () => {
|
|
|
364
377
|
logging: {
|
|
365
378
|
jsonPretty: true,
|
|
366
379
|
mcpCommDebug: false,
|
|
367
|
-
apiDebug: false
|
|
380
|
+
apiDebug: false,
|
|
381
|
+
gatewayDebug: false
|
|
368
382
|
}
|
|
369
383
|
}
|
|
370
384
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.config.d.ts","sourceRoot":"","sources":["../../vite.config.ts"],"names":[],"mappings":";AAwFA,
|
|
1
|
+
{"version":3,"file":"vite.config.d.ts","sourceRoot":"","sources":["../../vite.config.ts"],"names":[],"mappings":";AAwFA,wBAoFG"}
|
|
@@ -107,6 +107,7 @@ export default defineConfig({
|
|
|
107
107
|
'@i18n': fileURLToPath(new URL('./frontend/src/i18n', import.meta.url)),
|
|
108
108
|
'@locales': fileURLToPath(new URL('./frontend/src/locales', import.meta.url)),
|
|
109
109
|
'@composables': fileURLToPath(new URL('./frontend/src/composables', import.meta.url)),
|
|
110
|
+
'@frontend-types': fileURLToPath(new URL('./frontend/src/types', import.meta.url)),
|
|
110
111
|
'@utils': fileURLToPath(new URL('./frontend/src/utils', import.meta.url)),
|
|
111
112
|
// Shared code aliases
|
|
112
113
|
'@shared': fileURLToPath(new URL('./shared', import.meta.url)),
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{h as J,E as Q,p as ae,L as ne,j as oe,P as ue,aL as ie,aM as de,aN as re,aO as me,s as ge,J as pe,aP as ce,aQ as fe}from"./index-CTB6oe-9.js";import{v as ve}from"./el-loading-Dwl9E_Vr.js";import{E as ye,a as _e}from"./el-tab-pane-C4Ep94cd.js";import{E as be,a as Ve}from"./el-switch-BF8c-xeU.js";import{a as W,E as X}from"./el-form-item-CcGsD2K_.js";import{a as he,E as Y}from"./el-input-tYgeiaCT.js";import{E as $e,a as ee,b as le}from"./el-overlay-kqX_BABo.js";import{t as te,a6 as se,c as O,r as k,A as h,C as n,$ as m,O as e,G as t,u as o,a9 as E,P as M,af as q,V as j,y as A,x as f,al as ke,h as H,j as xe,H as we}from"./vue-vendor-CbgVSHIh.js";import{E as R}from"./index-ByNBhPAR.js";import"./raf-CmzeRPMd.js";import"./typescript-Bp3YSIOJ.js";import"./event-BB_Ol6Sd.js";import"./omit-CUnDT6sS.js";import"./_baseClone-DO5qfalW.js";const Ce={class:"tag-manager"},Te={class:"flex items-center justify-between mb-4"},Ue={class:"text-lg font-semibold text-gray-900 dark:text-white"},Ee={key:0,class:"text-center py-8 text-gray-500 dark:text-gray-400"},De={key:1,class:"space-y-3"},Ne={class:"flex-1"},Pe={class:"flex items-center gap-2"},Se={class:"font-medium text-gray-900 dark:text-white"},je={key:0,class:"text-sm text-gray-500 dark:text-gray-400 mt-1"},Ae={key:1,class:"mt-2"},Ie={class:"flex flex-wrap gap-1"},Me={class:"flex items-center gap-2 ml-4"},Re={class:"flex justify-end gap-2"},ze={class:"text-gray-600 dark:text-gray-300"},Be={class:"flex justify-end gap-2"},Fe=te({__name:"TagManager",props:{modelValue:{}},emits:["update:modelValue"],setup(G,{emit:z}){const I=G,a=z,{t:B}=se(),b=O({get:()=>I.modelValue||[],set:d=>a("update:modelValue",d)}),T=k(!1),y=k(!1),U=k(!1),V=k(!1),N=k(),_=k(null),p=k({key:"",description:"",type:"string",values:[]}),D={key:[{required:!0,message:"Tag key is required",trigger:"blur"},{pattern:/^[a-zA-Z][a-zA-Z0-9-]*$/,message:"Key must start with a letter and contain only letters, numbers, and hyphens",trigger:"blur"}],type:[{required:!0,message:"Tag type is required",trigger:"change"}],values:[{validator:(d,i,v)=>{p.value.type==="enum"&&(!i||i.length===0)?v(new Error("At least one value is required for enum type")):v()},trigger:"change"}]};function P(){U.value=!1,_.value=null,p.value={key:"",description:"",type:"string",values:[]},T.value=!0}function K(d){U.value=!0,_.value=d,p.value={...d},T.value=!0}function l(){T.value=!1,N.value?.resetFields(),p.value={key:"",description:"",type:"string",values:[]},U.value=!1,_.value=null}function s(){N.value?.validate(d=>{if(d){V.value=!0;try{if(U.value&&_.value){const i=b.value.findIndex(v=>v.key===_.value.key);if(i!==-1){const v=[...b.value];v[i]={...p.value},b.value=v}}else{if(b.value.some(i=>i.key===p.value.key)){R.error("Tag key already exists"),V.value=!1;return}b.value=[...b.value,{...p.value}]}R.success(B("action.saved")),l()}finally{V.value=!1}}})}function c(d){_.value=d,y.value=!0}function $(){if(_.value){V.value=!0;try{b.value=b.value.filter(d=>d.key!==_.value.key),R.success(B("action.saved")),y.value=!1,_.value=null}finally{V.value=!1}}}return(d,i)=>{const v=Q,g=J,x=he,S=Y,w=X,C=le,F=ee,Z=W,u=$e;return f(),h("div",Ce,[n("div",Te,[n("h3",Ue,m(d.$t("settings.tagDefinitions")),1),e(g,{type:"primary",onClick:P},{default:t(()=>[e(v,{class:"mr-1"},{default:t(()=>[e(o(ae))]),_:1}),E(" "+m(d.$t("common.addTag")),1)]),_:1})]),b.value.length===0?(f(),h("div",Ee,m(d.$t("settings.noTagsDefined")),1)):(f(),h("div",De,[(f(!0),h(M,null,q(b.value,r=>(f(),h("div",{key:r.key,class:"flex items-center justify-between p-4 border rounded-lg dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"},[n("div",Ne,[n("div",Pe,[n("span",Se,m(r.key),1),e(x,{size:"small",type:"info"},{default:t(()=>[E(m(r.type),1)]),_:2},1024)]),r.description?(f(),h("div",je,m(r.description),1)):j("",!0),r.type==="enum"&&r.values&&r.values.length>0?(f(),h("div",Ae,[n("div",Ie,[(f(!0),h(M,null,q(r.values,L=>(f(),A(x,{key:L,size:"small",type:"success"},{default:t(()=>[E(m(L),1)]),_:2},1024))),128))])])):j("",!0)]),n("div",Me,[e(g,{size:"small",onClick:L=>K(r)},{default:t(()=>[e(v,null,{default:t(()=>[e(o(ne))]),_:1})]),_:1},8,["onClick"]),e(g,{size:"small",type:"danger",onClick:L=>c(r)},{default:t(()=>[e(v,null,{default:t(()=>[e(o(oe))]),_:1})]),_:1},8,["onClick"])])]))),128))])),e(u,{modelValue:T.value,"onUpdate:modelValue":i[4]||(i[4]=r=>T.value=r),title:U.value?d.$t("common.editTag"):d.$t("common.addTag"),width:"500px",class:"custom-dialog","before-close":l},{footer:t(()=>[n("div",Re,[e(g,{onClick:l},{default:t(()=>[E(m(d.$t("action.cancel")),1)]),_:1}),e(g,{type:"primary",onClick:s,loading:V.value},{default:t(()=>[E(m(d.$t("action.save")),1)]),_:1},8,["loading"])])]),default:t(()=>[e(Z,{model:p.value,rules:D,ref_key:"formRef",ref:N,"label-position":"top"},{default:t(()=>[e(w,{label:d.$t("settings.tagKey"),prop:"key"},{default:t(()=>[e(S,{modelValue:p.value.key,"onUpdate:modelValue":i[0]||(i[0]=r=>p.value.key=r),placeholder:d.$t("settings.tagKeyPlaceholder"),disabled:U.value},null,8,["modelValue","placeholder","disabled"])]),_:1},8,["label"]),e(w,{label:d.$t("settings.tagDescription"),prop:"description"},{default:t(()=>[e(S,{modelValue:p.value.description,"onUpdate:modelValue":i[1]||(i[1]=r=>p.value.description=r),type:"textarea",rows:2,placeholder:d.$t("settings.tagDescriptionPlaceholder")},null,8,["modelValue","placeholder"])]),_:1},8,["label"]),e(w,{label:d.$t("settings.tagType"),prop:"type"},{default:t(()=>[e(F,{modelValue:p.value.type,"onUpdate:modelValue":i[2]||(i[2]=r=>p.value.type=r),class:"w-full"},{default:t(()=>[e(C,{label:"String",value:"string"}),e(C,{label:"Number",value:"number"}),e(C,{label:"Boolean",value:"boolean"}),e(C,{label:"Enum",value:"enum"})]),_:1},8,["modelValue"])]),_:1},8,["label"]),p.value.type==="enum"?(f(),A(w,{key:0,label:d.$t("settings.tagValues"),prop:"values"},{default:t(()=>[e(F,{modelValue:p.value.values,"onUpdate:modelValue":i[3]||(i[3]=r=>p.value.values=r),multiple:"",filterable:"","allow-create":"","default-first-option":"","reserve-keyword":!1,placeholder:d.$t("settings.tagValuesPlaceholder"),class:"w-full"},{default:t(()=>[(f(!0),h(M,null,q(p.value.values,r=>(f(),A(C,{key:r,label:r,value:r},null,8,["label","value"]))),128))]),_:1},8,["modelValue","placeholder"])]),_:1},8,["label"])):j("",!0)]),_:1},8,["model"])]),_:1},8,["modelValue","title"]),e(u,{modelValue:y.value,"onUpdate:modelValue":i[6]||(i[6]=r=>y.value=r),title:d.$t("common.deleteTag"),width:"400px",class:"custom-dialog"},{footer:t(()=>[n("div",Be,[e(g,{onClick:i[5]||(i[5]=r=>y.value=!1)},{default:t(()=>[E(m(d.$t("action.cancel")),1)]),_:1}),e(g,{type:"danger",onClick:$,loading:V.value},{default:t(()=>[E(m(d.$t("action.delete")),1)]),_:1},8,["loading"])])]),default:t(()=>[n("p",ze,m(d.$t("settings.deleteTagConfirm")),1)]),_:1},8,["modelValue","title"])])}}}),Le={class:"h-full w-full overflow-y-auto"},Oe={class:"py-6 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto w-full"},qe={class:"mb-6 flex items-center justify-between"},Ke={class:"text-2xl font-bold text-gray-900 dark:text-white"},Ze={class:"pb-10"},Ge={class:"flex items-center gap-2"},He={class:"pt-4"},Je={class:"flex flex-col gap-2"},Qe={class:"flex items-center my-4"},We={class:"text-sm font-medium text-gray-900 dark:text-gray-100 mr-4"},Xe={class:"flex items-center gap-2"},Ye={class:"flex items-center gap-2"},el={class:"flex items-center gap-2"},ll={class:"flex items-center gap-2"},tl={class:"pt-4"},sl={class:"flex items-center my-4"},al={class:"text-sm font-medium text-gray-900 dark:text-gray-100 mr-4"},nl={class:"flex items-center gap-2"},ol={class:"pt-4"},ul={class:"text-xs text-gray-500 mt-1"},il={class:"space-y-4"},dl={class:"flex items-center gap-4"},rl={class:"w-[260px] text-sm font-medium text-gray-700 dark:text-gray-300"},ml={class:"flex items-center gap-4"},gl={class:"w-[260px] text-sm font-medium text-gray-700 dark:text-gray-300"},pl={class:"flex items-center gap-4"},cl={class:"w-[260px] text-sm font-medium text-gray-700 dark:text-gray-300"},fl={class:"flex items-center gap-2"},vl={class:"flex items-center gap-4"},yl={class:"w-[260px] text-sm font-medium text-gray-700 dark:text-gray-300"},_l={class:"flex items-center gap-2"},bl={class:"flex items-center gap-2"},Vl={class:"pt-4"},Al=te({__name:"SettingsView",setup(G){const{t:z}=se(),I=ue(),{config:a,loading:B}=ke(I),b=k(!1),T=k("system"),y={seconds:1,minutes:60,hours:3600,days:86400},U=["days","hours","minutes","seconds"],V=l=>{for(const s of U){const c=y[s];if(l>=c)return s}return"seconds"},N=O({get:()=>{const l=a.value?.system?.logging?.rotationAge||"7d",s=parseInt(l.replace(/[^\d]/g,""))||7;return Number(Math.round(s))},set:l=>{a.value?.system?.logging&&l!==void 0&&l!==null&&(a.value.system.logging.rotationAge=`${l}d`)}}),_=k(V((a.value?.security?.connectionTimeout||3e4)/1e3)),p=O({get:()=>{const s=(a.value?.security?.connectionTimeout||3e4)/1e3,c=V(s),$=s/y[c];return Number(Math.round($))},set:l=>{a.value?.security&&l!==void 0&&l!==null&&(a.value.security.connectionTimeout=Number(l)*y[_.value]*1e3)}}),D=k(V((a.value?.security?.idleConnectionTimeout||3e5)/1e3)),P=O({get:()=>{const s=(a.value?.security?.idleConnectionTimeout||3e5)/1e3,c=V(s),$=s/y[c];return Number(Math.round($))},set:l=>{a.value?.security&&l!==void 0&&l!==null&&(a.value.security.idleConnectionTimeout=Number(l)*y[D.value]*1e3)}});H(_,(l,s)=>{if(s&&l!==s){const c=y[l]/y[s],$=p.value;p.value=Math.round($/c)}}),H(D,(l,s)=>{if(s&&l!==s){const c=y[l]/y[s],$=P.value;P.value=Math.round($/c)}}),xe(async()=>{a.value.host||await I.fetchConfig(),a.value?.security&&(_.value=V((a.value.security.connectionTimeout||3e4)/1e3),D.value=V((a.value.security.idleConnectionTimeout||3e5)/1e3))});async function K(){b.value=!0;try{await I.updateConfig(a.value),R.success(z("settings.saveSuccess"))}catch(l){R.error(z("settings.saveError")+": "+l.message)}finally{b.value=!1}}return(l,s)=>{const c=Q,$=J,d=Y,i=X,v=be,g=le,x=ee,S=W,w=_e,C=Ve,F=ye,Z=ve;return f(),h("div",Le,[n("div",Oe,[n("div",qe,[n("h1",Ke,m(l.$t("settings.title")),1),e($,{type:"primary",onClick:K,loading:b.value},{default:t(()=>[e(c,{class:"mr-1"},{default:t(()=>[e(o(ie))]),_:1}),E(" "+m(l.$t("settings.save")),1)]),_:1},8,["loading"])]),we((f(),h("div",Ze,[e(F,{modelValue:T.value,"onUpdate:modelValue":s[17]||(s[17]=u=>T.value=u),class:"demo-tabs"},{default:t(()=>[e(w,{name:"system"},{label:t(()=>[n("span",Ge,[e(c,null,{default:t(()=>[e(o(ge))]),_:1}),n("span",null,m(l.$t("settings.systemTab")),1)])]),default:t(()=>[n("div",He,[e(S,{model:o(a),"label-position":"left","label-width":"260px"},{default:t(()=>[n("div",Je,[e(i,{label:l.$t("settings.host")},{default:t(()=>[e(d,{modelValue:o(a).system.host,"onUpdate:modelValue":s[0]||(s[0]=u=>o(a).system.host=u),class:"w-[200px]"},null,8,["modelValue"])]),_:1},8,["label"]),e(i,{label:l.$t("settings.port")},{default:t(()=>[e(v,{modelValue:o(a).system.port,"onUpdate:modelValue":s[1]||(s[1]=u=>o(a).system.port=u),min:1,max:65535,class:"w-[200px]"},null,8,["modelValue"])]),_:1},8,["label"])]),n("div",Qe,[n("span",We,m(l.$t("settings.appearance")),1),s[18]||(s[18]=n("div",{class:"h-px bg-gray-200 dark:bg-gray-700 flex-1"},null,-1))]),e(i,{label:l.$t("settings.theme")},{default:t(()=>[e(x,{modelValue:o(a).system.theme,"onUpdate:modelValue":s[2]||(s[2]=u=>o(a).system.theme=u),class:"w-[200px]"},{default:t(()=>[e(g,{label:l.$t("settings.themeLight"),value:"light"},{default:t(()=>[n("span",Xe,[e(c,null,{default:t(()=>[e(o(de))]),_:1}),n("span",null,m(l.$t("settings.themeLight")),1)])]),_:1},8,["label"]),e(g,{label:l.$t("settings.themeDark"),value:"dark"},{default:t(()=>[n("span",Ye,[e(c,null,{default:t(()=>[e(o(re))]),_:1}),n("span",null,m(l.$t("settings.themeDark")),1)])]),_:1},8,["label"]),e(g,{label:l.$t("settings.themeSystem"),value:"system"},{default:t(()=>[n("span",el,[e(c,null,{default:t(()=>[e(o(me))]),_:1}),n("span",null,m(l.$t("settings.themeSystem")),1)])]),_:1},8,["label"])]),_:1},8,["modelValue"])]),_:1},8,["label"]),e(i,{label:l.$t("settings.language")},{default:t(()=>[e(x,{modelValue:o(a).system.language,"onUpdate:modelValue":s[3]||(s[3]=u=>o(a).system.language=u),class:"w-[200px]"},{default:t(()=>[e(g,{label:l.$t("settings.langEn"),value:"en"},null,8,["label"]),e(g,{label:l.$t("settings.langZh"),value:"zh"},null,8,["label"])]),_:1},8,["modelValue"])]),_:1},8,["label"])]),_:1},8,["model"])])]),_:1}),e(w,{name:"logging"},{label:t(()=>[n("span",ll,[e(c,null,{default:t(()=>[e(o(pe))]),_:1}),n("span",null,m(l.$t("settings.logging")),1)])]),default:t(()=>[n("div",tl,[o(a).system.logging?(f(),A(S,{key:0,model:o(a).system.logging,"label-position":"left","label-width":"260px"},{default:t(()=>[e(i,{label:l.$t("settings.logLevel")},{default:t(()=>[e(x,{modelValue:o(a).system.logging.level,"onUpdate:modelValue":s[4]||(s[4]=u=>o(a).system.logging.level=u),class:"w-full md:w-64"},{default:t(()=>[e(g,{label:"DEBUG",value:"debug"}),e(g,{label:"INFO",value:"info"}),e(g,{label:"WARN",value:"warn"}),e(g,{label:"ERROR",value:"error"})]),_:1},8,["modelValue"])]),_:1},8,["label"]),e(i,{label:l.$t("settings.maxAge")},{default:t(()=>[e(v,{modelValue:N.value,"onUpdate:modelValue":s[5]||(s[5]=u=>N.value=u),min:1,class:"w-[150px]"},null,8,["modelValue"])]),_:1},8,["label"]),n("div",sl,[n("span",al,m(l.$t("settings.debugOptions")),1),s[19]||(s[19]=n("div",{class:"h-px bg-gray-200 dark:bg-gray-700 flex-1"},null,-1))]),o(a).system.logging.level==="debug"||o(a).isDevMode?(f(),h(M,{key:0},[e(i,{label:l.$t("settings.jsonPretty")},{default:t(()=>[e(C,{modelValue:o(a).system.logging.jsonPretty,"onUpdate:modelValue":s[6]||(s[6]=u=>o(a).system.logging.jsonPretty=u)},null,8,["modelValue"])]),_:1},8,["label"]),e(i,{label:l.$t("settings.mcpCommDebug")},{default:t(()=>[e(C,{modelValue:o(a).system.logging.mcpCommDebug,"onUpdate:modelValue":s[7]||(s[7]=u=>o(a).system.logging.mcpCommDebug=u)},null,8,["modelValue"])]),_:1},8,["label"]),e(i,{label:l.$t("settings.apiDebug")},{default:t(()=>[e(C,{modelValue:o(a).system.logging.apiDebug,"onUpdate:modelValue":s[8]||(s[8]=u=>o(a).system.logging.apiDebug=u)},null,8,["modelValue"])]),_:1},8,["label"])],64)):j("",!0)]),_:1},8,["model"])):j("",!0)])]),_:1}),e(w,{name:"security"},{label:t(()=>[n("span",nl,[e(c,null,{default:t(()=>[e(o(ce))]),_:1}),n("span",null,m(l.$t("settings.security")),1)])]),default:t(()=>[n("div",ol,[o(a).security?(f(),A(S,{key:0,model:o(a).security,"label-position":"left","label-width":"260px"},{default:t(()=>[e(i,{label:l.$t("settings.allowedNetworks")},{default:t(()=>[e(x,{modelValue:o(a).security.allowedNetworks,"onUpdate:modelValue":s[9]||(s[9]=u=>o(a).security.allowedNetworks=u),multiple:"",filterable:"","allow-create":"","default-first-option":"","reserve-keyword":!1,placeholder:"Enter IP CIDR",class:"w-full"},{default:t(()=>[(f(!0),h(M,null,q(o(a).security.allowedNetworks,u=>(f(),A(g,{key:u,label:u,value:u},null,8,["label","value"]))),128))]),_:1},8,["modelValue"]),n("div",ul,m(l.$t("settings.allowedNetworksHint")),1)]),_:1},8,["label"]),n("div",il,[n("div",dl,[n("span",rl,m(l.$t("settings.maxConcurrentConnections")),1),e(v,{modelValue:o(a).security.maxConcurrentConnections,"onUpdate:modelValue":s[10]||(s[10]=u=>o(a).security.maxConcurrentConnections=u),min:1,max:1e3,style:{width:"128px","flex-shrink":"0"}},null,8,["modelValue"])]),n("div",ml,[n("span",gl,m(l.$t("settings.maxConnections")),1),e(v,{modelValue:o(a).security.maxConnections,"onUpdate:modelValue":s[11]||(s[11]=u=>o(a).security.maxConnections=u),min:1,max:1e3,style:{width:"128px","flex-shrink":"0"}},null,8,["modelValue"])]),n("div",pl,[n("span",cl,m(l.$t("settings.connectionTimeout")),1),n("div",fl,[e(v,{modelValue:p.value,"onUpdate:modelValue":s[12]||(s[12]=u=>p.value=u),min:1,step:1,style:{width:"128px","flex-shrink":"0"}},null,8,["modelValue"]),e(x,{modelValue:_.value,"onUpdate:modelValue":s[13]||(s[13]=u=>_.value=u),style:{width:"128px","flex-shrink":"0"}},{default:t(()=>[e(g,{label:l.$t("settings.timeUnits.seconds"),value:"seconds"},null,8,["label"]),e(g,{label:l.$t("settings.timeUnits.minutes"),value:"minutes"},null,8,["label"]),e(g,{label:l.$t("settings.timeUnits.hours"),value:"hours"},null,8,["label"]),e(g,{label:l.$t("settings.timeUnits.days"),value:"days"},null,8,["label"])]),_:1},8,["modelValue"])])]),n("div",vl,[n("span",yl,m(l.$t("settings.idleConnectionTimeout")),1),n("div",_l,[e(v,{modelValue:P.value,"onUpdate:modelValue":s[14]||(s[14]=u=>P.value=u),min:1,step:1,style:{width:"128px","flex-shrink":"0"}},null,8,["modelValue"]),e(x,{modelValue:D.value,"onUpdate:modelValue":s[15]||(s[15]=u=>D.value=u),style:{width:"128px","flex-shrink":"0"}},{default:t(()=>[e(g,{label:l.$t("settings.timeUnits.seconds"),value:"seconds"},null,8,["label"]),e(g,{label:l.$t("settings.timeUnits.minutes"),value:"minutes"},null,8,["label"]),e(g,{label:l.$t("settings.timeUnits.hours"),value:"hours"},null,8,["label"]),e(g,{label:l.$t("settings.timeUnits.days"),value:"days"},null,8,["label"])]),_:1},8,["modelValue"])])])])]),_:1},8,["model"])):j("",!0)])]),_:1}),e(w,{name:"tags"},{label:t(()=>[n("span",bl,[e(c,null,{default:t(()=>[e(o(fe))]),_:1}),n("span",null,m(l.$t("settings.tagsTab")),1)])]),default:t(()=>[n("div",Vl,[e(Fe,{modelValue:o(a).tagDefinitions,"onUpdate:modelValue":s[16]||(s[16]=u=>o(a).tagDefinitions=u)},null,8,["modelValue"])])]),_:1})]),_:1},8,["modelValue"])])),[[Z,o(B)]])])])}}});export{Al as default};
|