@zhin.js/client 1.0.10 → 1.0.12
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/client/router/index.tsx +0 -1
- package/client/websocket/hooks.ts +352 -7
- package/client/websocket/index.ts +5 -1
- package/client/websocket/manager.ts +100 -3
- package/client/websocket/types.ts +40 -0
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +0 -1
- package/dist/router/index.js.map +1 -1
- package/dist/websocket/hooks.d.ts +83 -2
- package/dist/websocket/hooks.d.ts.map +1 -1
- package/dist/websocket/hooks.js +336 -5
- package/dist/websocket/hooks.js.map +1 -1
- package/dist/websocket/index.d.ts +1 -1
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +1 -1
- package/dist/websocket/index.js.map +1 -1
- package/dist/websocket/manager.d.ts +70 -2
- package/dist/websocket/manager.d.ts.map +1 -1
- package/dist/websocket/manager.js +70 -1
- package/dist/websocket/manager.js.map +1 -1
- package/dist/websocket/types.d.ts +31 -0
- package/dist/websocket/types.d.ts.map +1 -1
- package/dist/websocket/types.js.map +1 -1
- package/package.json +1 -1
package/client/router/index.tsx
CHANGED
|
@@ -19,7 +19,6 @@ export const clearPages = () => store.dispatch(clearRoutes())
|
|
|
19
19
|
// 动态路由组件(从 Redux store 读取)
|
|
20
20
|
export function DynamicRouter() {
|
|
21
21
|
const storeRoutes = useSelector((state) => state.route.routes)
|
|
22
|
-
console.log(storeRoutes)
|
|
23
22
|
const router = useMemo(() => {
|
|
24
23
|
// 递归转换路由(支持多层嵌套)
|
|
25
24
|
const convertRoute = (route: RouteMenuItem): RouteObject => {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* 提供在 React 组件中使用 WebSocket 功能的便捷接口
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { useCallback, useEffect, useMemo } from 'react'
|
|
6
|
+
import { useCallback, useEffect, useMemo, useState } from 'react'
|
|
7
7
|
import {
|
|
8
8
|
useSelector,
|
|
9
9
|
useDispatch,
|
|
@@ -15,10 +15,12 @@ import {
|
|
|
15
15
|
selectAllConfigs,
|
|
16
16
|
selectAllSchemas,
|
|
17
17
|
setLoading,
|
|
18
|
-
setError
|
|
18
|
+
setError,
|
|
19
|
+
updateConfig,
|
|
20
|
+
updateSchema
|
|
19
21
|
} from '../store'
|
|
20
22
|
import { getWebSocketManager } from './instance'
|
|
21
|
-
import type { UseConfigOptions, UseWebSocketOptions } from './types'
|
|
23
|
+
import type { UseConfigOptions, UseWebSocketOptions, FileTreeNode, DatabaseInfo, TableInfo, SelectResult, KvEntry, DatabaseType } from './types'
|
|
22
24
|
|
|
23
25
|
// ============================================================================
|
|
24
26
|
// WebSocket 连接 Hook
|
|
@@ -119,6 +121,7 @@ export function useConfig(pluginName: string, options: UseConfigOptions = {}) {
|
|
|
119
121
|
|
|
120
122
|
try {
|
|
121
123
|
const result = await wsManager.getConfig(pluginName)
|
|
124
|
+
dispatch(updateConfig({ pluginName, config: result }))
|
|
122
125
|
return result
|
|
123
126
|
} catch (error) {
|
|
124
127
|
console.error('[useConfig] getConfig failed:', error)
|
|
@@ -130,12 +133,13 @@ export function useConfig(pluginName: string, options: UseConfigOptions = {}) {
|
|
|
130
133
|
}
|
|
131
134
|
}, [pluginName, wsManager, dispatch])
|
|
132
135
|
|
|
133
|
-
const setConfig = useCallback(async (newConfig: any) => {
|
|
136
|
+
const setConfig = useCallback(async (newConfig: any): Promise<{ reloaded?: boolean; message?: string }> => {
|
|
134
137
|
dispatch(setLoading({ pluginName, loading: true }))
|
|
135
138
|
dispatch(setError({ pluginName, error: null }))
|
|
136
139
|
|
|
137
140
|
try {
|
|
138
|
-
await wsManager.setConfig(pluginName, newConfig)
|
|
141
|
+
const result = await wsManager.setConfig(pluginName, newConfig)
|
|
142
|
+
return { reloaded: result?.reloaded, message: result?.message }
|
|
139
143
|
} catch (error) {
|
|
140
144
|
console.error('[useConfig] setConfig failed:', error)
|
|
141
145
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error'
|
|
@@ -148,12 +152,16 @@ export function useConfig(pluginName: string, options: UseConfigOptions = {}) {
|
|
|
148
152
|
|
|
149
153
|
const getSchema = useCallback(async () => {
|
|
150
154
|
try {
|
|
151
|
-
|
|
155
|
+
const result = await wsManager.getSchema(pluginName)
|
|
156
|
+
if (result) {
|
|
157
|
+
dispatch(updateSchema({ pluginName, schema: result }))
|
|
158
|
+
}
|
|
159
|
+
return result
|
|
152
160
|
} catch (error) {
|
|
153
161
|
console.error(`Failed to get schema for plugin ${pluginName}:`, error)
|
|
154
162
|
throw error
|
|
155
163
|
}
|
|
156
|
-
}, [pluginName, wsManager])
|
|
164
|
+
}, [pluginName, wsManager, dispatch])
|
|
157
165
|
|
|
158
166
|
// 重新加载配置和 Schema
|
|
159
167
|
const reload = useCallback(async () => {
|
|
@@ -234,3 +242,340 @@ export function useAllConfigs() {
|
|
|
234
242
|
refreshAll
|
|
235
243
|
}), [allConfigs, allSchemas, connected, refreshAll])
|
|
236
244
|
}
|
|
245
|
+
|
|
246
|
+
// ============================================================================
|
|
247
|
+
// 配置文件 YAML 读写 Hook
|
|
248
|
+
// ============================================================================
|
|
249
|
+
|
|
250
|
+
export function useConfigYaml() {
|
|
251
|
+
const wsManager = getWebSocketManager()
|
|
252
|
+
const connected = useSelector(selectConfigConnected)
|
|
253
|
+
|
|
254
|
+
const [yaml, setYaml] = useState('')
|
|
255
|
+
const [pluginKeys, setPluginKeys] = useState<string[]>([])
|
|
256
|
+
const [loading, setLoadingState] = useState(false)
|
|
257
|
+
const [error, setErrorState] = useState<string | null>(null)
|
|
258
|
+
|
|
259
|
+
const load = useCallback(async () => {
|
|
260
|
+
setLoadingState(true)
|
|
261
|
+
setErrorState(null)
|
|
262
|
+
try {
|
|
263
|
+
const result = await wsManager.getConfigYaml()
|
|
264
|
+
setYaml(result.yaml)
|
|
265
|
+
setPluginKeys(result.pluginKeys)
|
|
266
|
+
return result
|
|
267
|
+
} catch (err) {
|
|
268
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
269
|
+
setErrorState(msg)
|
|
270
|
+
throw err
|
|
271
|
+
} finally {
|
|
272
|
+
setLoadingState(false)
|
|
273
|
+
}
|
|
274
|
+
}, [wsManager])
|
|
275
|
+
|
|
276
|
+
const save = useCallback(async (content: string) => {
|
|
277
|
+
setLoadingState(true)
|
|
278
|
+
setErrorState(null)
|
|
279
|
+
try {
|
|
280
|
+
const result = await wsManager.saveConfigYaml(content)
|
|
281
|
+
setYaml(content)
|
|
282
|
+
return result
|
|
283
|
+
} catch (err) {
|
|
284
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
285
|
+
setErrorState(msg)
|
|
286
|
+
throw err
|
|
287
|
+
} finally {
|
|
288
|
+
setLoadingState(false)
|
|
289
|
+
}
|
|
290
|
+
}, [wsManager])
|
|
291
|
+
|
|
292
|
+
useEffect(() => {
|
|
293
|
+
if (connected && !yaml && !loading) {
|
|
294
|
+
load().catch(() => {})
|
|
295
|
+
}
|
|
296
|
+
}, [connected, yaml, loading, load])
|
|
297
|
+
|
|
298
|
+
return useMemo(() => ({
|
|
299
|
+
yaml, pluginKeys, loading, error, load, save
|
|
300
|
+
}), [yaml, pluginKeys, loading, error, load, save])
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// ============================================================================
|
|
304
|
+
// 环境变量文件管理 Hook
|
|
305
|
+
// ============================================================================
|
|
306
|
+
|
|
307
|
+
export function useEnvFiles() {
|
|
308
|
+
const wsManager = getWebSocketManager()
|
|
309
|
+
const connected = useSelector(selectConfigConnected)
|
|
310
|
+
|
|
311
|
+
const [files, setFiles] = useState<Array<{ name: string; exists: boolean }>>([])
|
|
312
|
+
const [loading, setLoadingState] = useState(false)
|
|
313
|
+
const [error, setErrorState] = useState<string | null>(null)
|
|
314
|
+
|
|
315
|
+
const listFiles = useCallback(async () => {
|
|
316
|
+
setLoadingState(true)
|
|
317
|
+
setErrorState(null)
|
|
318
|
+
try {
|
|
319
|
+
const result = await wsManager.getEnvList()
|
|
320
|
+
setFiles(result.files)
|
|
321
|
+
return result.files
|
|
322
|
+
} catch (err) {
|
|
323
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
324
|
+
setErrorState(msg)
|
|
325
|
+
throw err
|
|
326
|
+
} finally {
|
|
327
|
+
setLoadingState(false)
|
|
328
|
+
}
|
|
329
|
+
}, [wsManager])
|
|
330
|
+
|
|
331
|
+
const getFile = useCallback(async (filename: string) => {
|
|
332
|
+
try {
|
|
333
|
+
const result = await wsManager.getEnvFile(filename)
|
|
334
|
+
return result.content
|
|
335
|
+
} catch (err) {
|
|
336
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
337
|
+
setErrorState(msg)
|
|
338
|
+
throw err
|
|
339
|
+
}
|
|
340
|
+
}, [wsManager])
|
|
341
|
+
|
|
342
|
+
const saveFile = useCallback(async (filename: string, content: string) => {
|
|
343
|
+
setLoadingState(true)
|
|
344
|
+
setErrorState(null)
|
|
345
|
+
try {
|
|
346
|
+
return await wsManager.saveEnvFile(filename, content)
|
|
347
|
+
} catch (err) {
|
|
348
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
349
|
+
setErrorState(msg)
|
|
350
|
+
throw err
|
|
351
|
+
} finally {
|
|
352
|
+
setLoadingState(false)
|
|
353
|
+
}
|
|
354
|
+
}, [wsManager])
|
|
355
|
+
|
|
356
|
+
useEffect(() => {
|
|
357
|
+
if (connected && files.length === 0 && !loading) {
|
|
358
|
+
listFiles().catch(() => {})
|
|
359
|
+
}
|
|
360
|
+
}, [connected, files.length, loading, listFiles])
|
|
361
|
+
|
|
362
|
+
return useMemo(() => ({
|
|
363
|
+
files, loading, error, listFiles, getFile, saveFile
|
|
364
|
+
}), [files, loading, error, listFiles, getFile, saveFile])
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// ============================================================================
|
|
368
|
+
// 文件管理 Hook
|
|
369
|
+
// ============================================================================
|
|
370
|
+
|
|
371
|
+
export function useFiles() {
|
|
372
|
+
const wsManager = getWebSocketManager()
|
|
373
|
+
const connected = useSelector(selectConfigConnected)
|
|
374
|
+
|
|
375
|
+
const [tree, setTree] = useState<FileTreeNode[]>([])
|
|
376
|
+
const [loading, setLoadingState] = useState(false)
|
|
377
|
+
const [error, setErrorState] = useState<string | null>(null)
|
|
378
|
+
|
|
379
|
+
const loadTree = useCallback(async () => {
|
|
380
|
+
setLoadingState(true)
|
|
381
|
+
setErrorState(null)
|
|
382
|
+
try {
|
|
383
|
+
const result = await wsManager.getFileTree()
|
|
384
|
+
setTree(result.tree)
|
|
385
|
+
return result.tree
|
|
386
|
+
} catch (err) {
|
|
387
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
388
|
+
setErrorState(msg)
|
|
389
|
+
throw err
|
|
390
|
+
} finally {
|
|
391
|
+
setLoadingState(false)
|
|
392
|
+
}
|
|
393
|
+
}, [wsManager])
|
|
394
|
+
|
|
395
|
+
const readFile = useCallback(async (filePath: string) => {
|
|
396
|
+
try {
|
|
397
|
+
const result = await wsManager.readFile(filePath)
|
|
398
|
+
return result.content
|
|
399
|
+
} catch (err) {
|
|
400
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
401
|
+
setErrorState(msg)
|
|
402
|
+
throw err
|
|
403
|
+
}
|
|
404
|
+
}, [wsManager])
|
|
405
|
+
|
|
406
|
+
const saveFile = useCallback(async (filePath: string, content: string) => {
|
|
407
|
+
setLoadingState(true)
|
|
408
|
+
setErrorState(null)
|
|
409
|
+
try {
|
|
410
|
+
return await wsManager.saveFile(filePath, content)
|
|
411
|
+
} catch (err) {
|
|
412
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
413
|
+
setErrorState(msg)
|
|
414
|
+
throw err
|
|
415
|
+
} finally {
|
|
416
|
+
setLoadingState(false)
|
|
417
|
+
}
|
|
418
|
+
}, [wsManager])
|
|
419
|
+
|
|
420
|
+
useEffect(() => {
|
|
421
|
+
if (connected && tree.length === 0 && !loading) {
|
|
422
|
+
loadTree().catch(() => {})
|
|
423
|
+
}
|
|
424
|
+
}, [connected, tree.length, loading, loadTree])
|
|
425
|
+
|
|
426
|
+
return useMemo(() => ({
|
|
427
|
+
tree, loading, error, loadTree, readFile, saveFile
|
|
428
|
+
}), [tree, loading, error, loadTree, readFile, saveFile])
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// ============================================================================
|
|
432
|
+
// 数据库管理 Hook
|
|
433
|
+
// ============================================================================
|
|
434
|
+
|
|
435
|
+
export function useDatabase() {
|
|
436
|
+
const wsManager = getWebSocketManager()
|
|
437
|
+
const connected = useSelector(selectConfigConnected)
|
|
438
|
+
|
|
439
|
+
const [info, setInfo] = useState<DatabaseInfo | null>(null)
|
|
440
|
+
const [tables, setTables] = useState<TableInfo[]>([])
|
|
441
|
+
const [loading, setLoadingState] = useState(false)
|
|
442
|
+
const [error, setErrorState] = useState<string | null>(null)
|
|
443
|
+
|
|
444
|
+
const loadInfo = useCallback(async () => {
|
|
445
|
+
setLoadingState(true)
|
|
446
|
+
setErrorState(null)
|
|
447
|
+
try {
|
|
448
|
+
const result = await wsManager.getDbInfo()
|
|
449
|
+
setInfo(result)
|
|
450
|
+
return result
|
|
451
|
+
} catch (err) {
|
|
452
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
453
|
+
setErrorState(msg)
|
|
454
|
+
throw err
|
|
455
|
+
} finally {
|
|
456
|
+
setLoadingState(false)
|
|
457
|
+
}
|
|
458
|
+
}, [wsManager])
|
|
459
|
+
|
|
460
|
+
const loadTables = useCallback(async () => {
|
|
461
|
+
setLoadingState(true)
|
|
462
|
+
setErrorState(null)
|
|
463
|
+
try {
|
|
464
|
+
const result = await wsManager.getDbTables()
|
|
465
|
+
setTables(result.tables)
|
|
466
|
+
return result.tables
|
|
467
|
+
} catch (err) {
|
|
468
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
469
|
+
setErrorState(msg)
|
|
470
|
+
throw err
|
|
471
|
+
} finally {
|
|
472
|
+
setLoadingState(false)
|
|
473
|
+
}
|
|
474
|
+
}, [wsManager])
|
|
475
|
+
|
|
476
|
+
const select = useCallback(async (table: string, page?: number, pageSize?: number, where?: any) => {
|
|
477
|
+
try {
|
|
478
|
+
return await wsManager.dbSelect(table, page, pageSize, where)
|
|
479
|
+
} catch (err) {
|
|
480
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
481
|
+
setErrorState(msg)
|
|
482
|
+
throw err
|
|
483
|
+
}
|
|
484
|
+
}, [wsManager])
|
|
485
|
+
|
|
486
|
+
const insert = useCallback(async (table: string, row: any) => {
|
|
487
|
+
try {
|
|
488
|
+
return await wsManager.dbInsert(table, row)
|
|
489
|
+
} catch (err) {
|
|
490
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
491
|
+
setErrorState(msg)
|
|
492
|
+
throw err
|
|
493
|
+
}
|
|
494
|
+
}, [wsManager])
|
|
495
|
+
|
|
496
|
+
const update = useCallback(async (table: string, row: any, where: any) => {
|
|
497
|
+
try {
|
|
498
|
+
return await wsManager.dbUpdate(table, row, where)
|
|
499
|
+
} catch (err) {
|
|
500
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
501
|
+
setErrorState(msg)
|
|
502
|
+
throw err
|
|
503
|
+
}
|
|
504
|
+
}, [wsManager])
|
|
505
|
+
|
|
506
|
+
const remove = useCallback(async (table: string, where: any) => {
|
|
507
|
+
try {
|
|
508
|
+
return await wsManager.dbDelete(table, where)
|
|
509
|
+
} catch (err) {
|
|
510
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
511
|
+
setErrorState(msg)
|
|
512
|
+
throw err
|
|
513
|
+
}
|
|
514
|
+
}, [wsManager])
|
|
515
|
+
|
|
516
|
+
const dropTable = useCallback(async (table: string) => {
|
|
517
|
+
try {
|
|
518
|
+
const result = await wsManager.dbDropTable(table)
|
|
519
|
+
await loadTables()
|
|
520
|
+
return result
|
|
521
|
+
} catch (err) {
|
|
522
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
523
|
+
setErrorState(msg)
|
|
524
|
+
throw err
|
|
525
|
+
}
|
|
526
|
+
}, [wsManager, loadTables])
|
|
527
|
+
|
|
528
|
+
const kvGet = useCallback(async (table: string, key: string) => {
|
|
529
|
+
try {
|
|
530
|
+
return await wsManager.kvGet(table, key)
|
|
531
|
+
} catch (err) {
|
|
532
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
533
|
+
setErrorState(msg)
|
|
534
|
+
throw err
|
|
535
|
+
}
|
|
536
|
+
}, [wsManager])
|
|
537
|
+
|
|
538
|
+
const kvSet = useCallback(async (table: string, key: string, value: any, ttl?: number) => {
|
|
539
|
+
try {
|
|
540
|
+
return await wsManager.kvSet(table, key, value, ttl)
|
|
541
|
+
} catch (err) {
|
|
542
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
543
|
+
setErrorState(msg)
|
|
544
|
+
throw err
|
|
545
|
+
}
|
|
546
|
+
}, [wsManager])
|
|
547
|
+
|
|
548
|
+
const kvDelete = useCallback(async (table: string, key: string) => {
|
|
549
|
+
try {
|
|
550
|
+
return await wsManager.kvDelete(table, key)
|
|
551
|
+
} catch (err) {
|
|
552
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
553
|
+
setErrorState(msg)
|
|
554
|
+
throw err
|
|
555
|
+
}
|
|
556
|
+
}, [wsManager])
|
|
557
|
+
|
|
558
|
+
const kvEntries = useCallback(async (table: string) => {
|
|
559
|
+
try {
|
|
560
|
+
return await wsManager.kvGetEntries(table)
|
|
561
|
+
} catch (err) {
|
|
562
|
+
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
563
|
+
setErrorState(msg)
|
|
564
|
+
throw err
|
|
565
|
+
}
|
|
566
|
+
}, [wsManager])
|
|
567
|
+
|
|
568
|
+
useEffect(() => {
|
|
569
|
+
if (connected && !info && !loading) {
|
|
570
|
+
loadInfo().catch(() => {})
|
|
571
|
+
loadTables().catch(() => {})
|
|
572
|
+
}
|
|
573
|
+
}, [connected, info, loading, loadInfo, loadTables])
|
|
574
|
+
|
|
575
|
+
return useMemo(() => ({
|
|
576
|
+
info, tables, loading, error,
|
|
577
|
+
loadInfo, loadTables, dropTable,
|
|
578
|
+
select, insert, update, remove,
|
|
579
|
+
kvGet, kvSet, kvDelete, kvEntries,
|
|
580
|
+
}), [info, tables, loading, error, loadInfo, loadTables, dropTable, select, insert, update, remove, kvGet, kvSet, kvDelete, kvEntries])
|
|
581
|
+
}
|
|
@@ -29,7 +29,11 @@ export {
|
|
|
29
29
|
export {
|
|
30
30
|
useWebSocket,
|
|
31
31
|
useConfig,
|
|
32
|
-
useAllConfigs
|
|
32
|
+
useAllConfigs,
|
|
33
|
+
useConfigYaml,
|
|
34
|
+
useEnvFiles,
|
|
35
|
+
useFiles,
|
|
36
|
+
useDatabase
|
|
33
37
|
} from './hooks'
|
|
34
38
|
|
|
35
39
|
// ============================================================================
|
|
@@ -8,7 +8,12 @@ import { MessageHandler } from './messageHandler'
|
|
|
8
8
|
import type {
|
|
9
9
|
WebSocketMessage,
|
|
10
10
|
WebSocketConfig,
|
|
11
|
-
WebSocketCallbacks
|
|
11
|
+
WebSocketCallbacks,
|
|
12
|
+
FileTreeNode,
|
|
13
|
+
DatabaseInfo,
|
|
14
|
+
TableInfo,
|
|
15
|
+
SelectResult,
|
|
16
|
+
KvEntry
|
|
12
17
|
} from './types'
|
|
13
18
|
import {
|
|
14
19
|
ConnectionState,
|
|
@@ -169,8 +174,8 @@ export class WebSocketManager {
|
|
|
169
174
|
/**
|
|
170
175
|
* 设置插件配置
|
|
171
176
|
*/
|
|
172
|
-
async setConfig(pluginName: string, config: any): Promise<
|
|
173
|
-
|
|
177
|
+
async setConfig(pluginName: string, config: any): Promise<{ success?: boolean; reloaded?: boolean; message?: string }> {
|
|
178
|
+
return this.sendRequest({
|
|
174
179
|
type: 'config:set',
|
|
175
180
|
pluginName,
|
|
176
181
|
data: config
|
|
@@ -205,6 +210,98 @@ export class WebSocketManager {
|
|
|
205
210
|
})
|
|
206
211
|
}
|
|
207
212
|
|
|
213
|
+
// ============================================================================
|
|
214
|
+
// 配置文件原始 YAML 读写
|
|
215
|
+
// ============================================================================
|
|
216
|
+
|
|
217
|
+
async getConfigYaml(): Promise<{ yaml: string; pluginKeys: string[] }> {
|
|
218
|
+
return this.sendRequest({ type: 'config:get-yaml' })
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
async saveConfigYaml(yaml: string): Promise<{ success: boolean; message?: string }> {
|
|
222
|
+
return this.sendRequest({ type: 'config:save-yaml', yaml })
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// ============================================================================
|
|
226
|
+
// 环境变量文件管理
|
|
227
|
+
// ============================================================================
|
|
228
|
+
|
|
229
|
+
async getEnvList(): Promise<{ files: Array<{ name: string; exists: boolean }> }> {
|
|
230
|
+
return this.sendRequest({ type: 'env:list' })
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async getEnvFile(filename: string): Promise<{ content: string }> {
|
|
234
|
+
return this.sendRequest({ type: 'env:get', filename })
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async saveEnvFile(filename: string, content: string): Promise<{ success: boolean; message?: string }> {
|
|
238
|
+
return this.sendRequest({ type: 'env:save', filename, content })
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// ============================================================================
|
|
242
|
+
// 文件管理
|
|
243
|
+
// ============================================================================
|
|
244
|
+
|
|
245
|
+
async getFileTree(): Promise<{ tree: FileTreeNode[] }> {
|
|
246
|
+
return this.sendRequest({ type: 'files:tree' })
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async readFile(filePath: string): Promise<{ content: string; size: number }> {
|
|
250
|
+
return this.sendRequest({ type: 'files:read', filePath })
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
async saveFile(filePath: string, content: string): Promise<{ success: boolean; message?: string }> {
|
|
254
|
+
return this.sendRequest({ type: 'files:save', filePath, content })
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// ============================================================================
|
|
258
|
+
// 数据库管理
|
|
259
|
+
// ============================================================================
|
|
260
|
+
|
|
261
|
+
async getDbInfo(): Promise<DatabaseInfo> {
|
|
262
|
+
return this.sendRequest({ type: 'db:info' })
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
async getDbTables(): Promise<{ tables: TableInfo[] }> {
|
|
266
|
+
return this.sendRequest({ type: 'db:tables' })
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
async dbSelect(table: string, page?: number, pageSize?: number, where?: any): Promise<SelectResult> {
|
|
270
|
+
return this.sendRequest({ type: 'db:select', table, page, pageSize, where })
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
async dbInsert(table: string, row: any): Promise<{ success: boolean }> {
|
|
274
|
+
return this.sendRequest({ type: 'db:insert', table, row })
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
async dbUpdate(table: string, row: any, where: any): Promise<{ success: boolean; affected: number }> {
|
|
278
|
+
return this.sendRequest({ type: 'db:update', table, row, where })
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
async dbDelete(table: string, where: any): Promise<{ success: boolean; deleted: number }> {
|
|
282
|
+
return this.sendRequest({ type: 'db:delete', table, where })
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
async dbDropTable(table: string): Promise<{ success: boolean }> {
|
|
286
|
+
return this.sendRequest({ type: 'db:drop-table', table })
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
async kvGet(table: string, key: string): Promise<{ key: string; value: any }> {
|
|
290
|
+
return this.sendRequest({ type: 'db:kv:get', table, key })
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
async kvSet(table: string, key: string, value: any, ttl?: number): Promise<{ success: boolean }> {
|
|
294
|
+
return this.sendRequest({ type: 'db:kv:set', table, key, value, ttl })
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
async kvDelete(table: string, key: string): Promise<{ success: boolean }> {
|
|
298
|
+
return this.sendRequest({ type: 'db:kv:delete', table, key })
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
async kvGetEntries(table: string): Promise<{ entries: KvEntry[] }> {
|
|
302
|
+
return this.sendRequest({ type: 'db:kv:entries', table })
|
|
303
|
+
}
|
|
304
|
+
|
|
208
305
|
// ============================================================================
|
|
209
306
|
// 私有方法
|
|
210
307
|
// ============================================================================
|
|
@@ -106,6 +106,46 @@ export interface HmrReloadMessage extends BaseMessage {
|
|
|
106
106
|
data?: { file?: string }
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
// ============================================================================
|
|
110
|
+
// 文件管理类型
|
|
111
|
+
// ============================================================================
|
|
112
|
+
|
|
113
|
+
export interface FileTreeNode {
|
|
114
|
+
name: string
|
|
115
|
+
path: string
|
|
116
|
+
type: 'file' | 'directory'
|
|
117
|
+
children?: FileTreeNode[]
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ============================================================================
|
|
121
|
+
// 数据库管理类型
|
|
122
|
+
// ============================================================================
|
|
123
|
+
|
|
124
|
+
export type DatabaseType = 'related' | 'document' | 'keyvalue'
|
|
125
|
+
|
|
126
|
+
export interface DatabaseInfo {
|
|
127
|
+
dialect: string
|
|
128
|
+
type: DatabaseType
|
|
129
|
+
tables: string[]
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface TableInfo {
|
|
133
|
+
name: string
|
|
134
|
+
columns?: Record<string, { type: string; primary?: boolean; nullable?: boolean; default?: any }>
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface SelectResult {
|
|
138
|
+
rows: any[]
|
|
139
|
+
total: number
|
|
140
|
+
page: number
|
|
141
|
+
pageSize: number
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface KvEntry {
|
|
145
|
+
key: string
|
|
146
|
+
value: any
|
|
147
|
+
}
|
|
148
|
+
|
|
109
149
|
// ============================================================================
|
|
110
150
|
// 联合类型
|
|
111
151
|
// ============================================================================
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../client/router/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA0D,aAAa,EAAe,MAAM,UAAU,CAAA;AAC7G,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAK9E,eAAO,MAAM,OAAO,GAAI,OAAO,aAAa;;;CAAoC,CAAA;AAChF,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM;;;CAAsC,CAAA;AAC7E,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,EAAE,OAAO,aAAa;;;;;;CAG1D,CAAA;AACH,eAAO,MAAM,OAAO,GAAI,MAAM,MAAM,8BAAqE,CAAA;AACzG,eAAO,MAAM,WAAW,uBAAsC,CAAA;AAC9D,eAAO,MAAM,UAAU;;;CAAsC,CAAA;AAG7D,wBAAgB,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../client/router/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA0D,aAAa,EAAe,MAAM,UAAU,CAAA;AAC7G,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAK9E,eAAO,MAAM,OAAO,GAAI,OAAO,aAAa;;;CAAoC,CAAA;AAChF,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM;;;CAAsC,CAAA;AAC7E,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,EAAE,OAAO,aAAa;;;;;;CAG1D,CAAA;AACH,eAAO,MAAM,OAAO,GAAI,MAAM,MAAM,8BAAqE,CAAA;AACzG,eAAO,MAAM,WAAW,uBAAsC,CAAA;AAC9D,eAAO,MAAM,UAAU;;;CAAsC,CAAA;AAG7D,wBAAgB,aAAa,4CAkC5B"}
|
package/dist/router/index.js
CHANGED
|
@@ -15,7 +15,6 @@ export const clearPages = () => store.dispatch(clearRoutes());
|
|
|
15
15
|
// 动态路由组件(从 Redux store 读取)
|
|
16
16
|
export function DynamicRouter() {
|
|
17
17
|
const storeRoutes = useSelector((state) => state.route.routes);
|
|
18
|
-
console.log(storeRoutes);
|
|
19
18
|
const router = useMemo(() => {
|
|
20
19
|
// 递归转换路由(支持多层嵌套)
|
|
21
20
|
const convertRoute = (route) => {
|
package/dist/router/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../client/router/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,EAAE,mBAAmB,EAAE,cAAc,IAAI,mBAAmB,EAAe,MAAM,EAAC,MAAM,cAAc,CAAA;AAC7G,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAiB,WAAW,EAAE,MAAM,UAAU,CAAA;AAC7G,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAK9E,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;AAChF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAA;AAC7E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,KAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC;IAC3F,IAAI;IACJ,OAAO,EAAE,KAAK;CACf,CAAC,CAAC,CAAA;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;AACzG,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,CAAA;AAC9D,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;AAE7D,2BAA2B;AAC3B,MAAM,UAAU,aAAa;IAC3B,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC9D,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../client/router/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,EAAE,mBAAmB,EAAE,cAAc,IAAI,mBAAmB,EAAe,MAAM,EAAC,MAAM,cAAc,CAAA;AAC7G,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAiB,WAAW,EAAE,MAAM,UAAU,CAAA;AAC7G,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAK9E,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;AAChF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAA;AAC7E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,KAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC;IAC3F,IAAI;IACJ,OAAO,EAAE,KAAK;CACf,CAAC,CAAC,CAAA;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;AACzG,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,CAAA;AAC9D,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;AAE7D,2BAA2B;AAC3B,MAAM,UAAU,aAAa;IAC3B,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC9D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE;QAC1B,iBAAiB;QACjB,MAAM,YAAY,GAAG,CAAC,KAAoB,EAAe,EAAE;YACzD,MAAM,QAAQ,GAAgB;gBAC5B,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,SAAS,EAAE,KAAK,CAAC,SAAS;aAC3B,CAAA;YAED,UAAU;YACV,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChD,QAAQ,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAoB,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAA;YACvF,CAAC;YACD,OAAO,QAAQ,CAAA;QACjB,CAAC,CAAA;QACD,MAAM,YAAY,GAAkB,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QACjE,MAAM,aAAa,GAAkB;YACnC;gBACE,IAAI,EAAE,GAAG;gBACT,OAAO,EAAE,KAAC,MAAM,KAAG;gBACnB,QAAQ,EAAE,YAAY;aACvB;YACD;gBACE,IAAI,EAAE,GAAG;gBACT,OAAO,EAAE,iDAA+B;aACzC;SACF,CAAA;QAED,OAAO,mBAAmB,CAAC,aAAa,CAAC,CAAA;IAC3C,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEjB,OAAO,KAAC,mBAAmB,IAAC,MAAM,EAAE,MAAM,GAAI,CAAA;AAChD,CAAC"}
|