aws-runtime-bridge 1.1.6 → 1.1.8
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/dist/routes/file-browser.js +82 -72
- package/package.json +1 -1
|
@@ -12,6 +12,71 @@ import { createLogger } from '../utils/logger.js';
|
|
|
12
12
|
import { createWorkspaceEntry, deleteWorkspaceEntry, listWorkspaceDirectory, readWorkspaceFile, renameWorkspaceEntry, writeWorkspaceFile, } from '../services/workspace-files.js';
|
|
13
13
|
const log = createLogger('file-browser');
|
|
14
14
|
export const fileBrowserRouter = Router();
|
|
15
|
+
async function listHostDirectories(requestPath = '') {
|
|
16
|
+
const platform = process.platform;
|
|
17
|
+
const isWindows = platform === 'win32';
|
|
18
|
+
if (!requestPath || requestPath === '') {
|
|
19
|
+
if (isWindows) {
|
|
20
|
+
const drives = [];
|
|
21
|
+
for (let i = 67; i <= 90; i++) { // C to Z
|
|
22
|
+
const drive = String.fromCharCode(i) + ':\\';
|
|
23
|
+
try {
|
|
24
|
+
await fs.access(drive);
|
|
25
|
+
drives.push({
|
|
26
|
+
name: drive,
|
|
27
|
+
path: drive,
|
|
28
|
+
isDirectory: true
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Drive not accessible, skip
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
isWindows: true,
|
|
37
|
+
currentPath: '',
|
|
38
|
+
items: drives
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const entries = await fs.readdir('/', { withFileTypes: true });
|
|
42
|
+
const items = entries
|
|
43
|
+
.filter(entry => entry.isDirectory())
|
|
44
|
+
.map(entry => ({
|
|
45
|
+
name: entry.name,
|
|
46
|
+
path: '/' + entry.name,
|
|
47
|
+
isDirectory: true
|
|
48
|
+
}));
|
|
49
|
+
return {
|
|
50
|
+
isWindows: false,
|
|
51
|
+
currentPath: '/',
|
|
52
|
+
items
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const normalizedPath = path.normalize(requestPath);
|
|
56
|
+
let stat;
|
|
57
|
+
try {
|
|
58
|
+
stat = await fs.stat(normalizedPath);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
throw new Error('Path not found: ' + normalizedPath);
|
|
62
|
+
}
|
|
63
|
+
if (!stat.isDirectory()) {
|
|
64
|
+
throw new Error('Path is not a directory: ' + normalizedPath);
|
|
65
|
+
}
|
|
66
|
+
const entries = await fs.readdir(normalizedPath, { withFileTypes: true });
|
|
67
|
+
const items = entries
|
|
68
|
+
.filter(entry => entry.isDirectory())
|
|
69
|
+
.map(entry => ({
|
|
70
|
+
name: entry.name,
|
|
71
|
+
path: path.join(normalizedPath, entry.name),
|
|
72
|
+
isDirectory: true
|
|
73
|
+
}));
|
|
74
|
+
return {
|
|
75
|
+
isWindows,
|
|
76
|
+
currentPath: normalizedPath,
|
|
77
|
+
items
|
|
78
|
+
};
|
|
79
|
+
}
|
|
15
80
|
/**
|
|
16
81
|
* 列出目录内容
|
|
17
82
|
* POST /api/file-browser/list
|
|
@@ -24,84 +89,29 @@ fileBrowserRouter.post('/list', validateToken, async (req, res) => {
|
|
|
24
89
|
});
|
|
25
90
|
}
|
|
26
91
|
const { path: requestPath = '' } = req.body || {};
|
|
27
|
-
|
|
28
|
-
const isWindows = platform === 'win32';
|
|
29
|
-
// 如果路径为空,返回根目录
|
|
30
|
-
if (!requestPath || requestPath === '') {
|
|
31
|
-
if (isWindows) {
|
|
32
|
-
// Windows: 返回驱动器列表
|
|
33
|
-
const drives = [];
|
|
34
|
-
for (let i = 67; i <= 90; i++) { // C to Z
|
|
35
|
-
const drive = String.fromCharCode(i) + ':\\';
|
|
36
|
-
try {
|
|
37
|
-
await fs.access(drive);
|
|
38
|
-
drives.push({
|
|
39
|
-
name: drive,
|
|
40
|
-
path: drive,
|
|
41
|
-
isDirectory: true
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
catch {
|
|
45
|
-
// Drive not accessible, skip
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return res.json({
|
|
49
|
-
isWindows: true,
|
|
50
|
-
currentPath: '',
|
|
51
|
-
items: drives
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
// Unix: 返回根目录
|
|
56
|
-
const entries = await fs.readdir('/', { withFileTypes: true });
|
|
57
|
-
const items = entries
|
|
58
|
-
.filter(entry => entry.isDirectory())
|
|
59
|
-
.map(entry => ({
|
|
60
|
-
name: entry.name,
|
|
61
|
-
path: '/' + entry.name,
|
|
62
|
-
isDirectory: true
|
|
63
|
-
}));
|
|
64
|
-
return res.json({
|
|
65
|
-
isWindows: false,
|
|
66
|
-
currentPath: '/',
|
|
67
|
-
items
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
// 标准化路径
|
|
72
|
-
const normalizedPath = path.normalize(requestPath);
|
|
73
|
-
// 检查路径是否存在且为目录
|
|
74
|
-
let stat;
|
|
75
|
-
try {
|
|
76
|
-
stat = await fs.stat(normalizedPath);
|
|
77
|
-
}
|
|
78
|
-
catch (err) {
|
|
79
|
-
return res.status(404).json({ error: 'Path not found: ' + normalizedPath });
|
|
80
|
-
}
|
|
81
|
-
if (!stat.isDirectory()) {
|
|
82
|
-
return res.status(400).json({ error: 'Path is not a directory: ' + normalizedPath });
|
|
83
|
-
}
|
|
84
|
-
// 读取目录内容
|
|
85
|
-
const entries = await fs.readdir(normalizedPath, { withFileTypes: true });
|
|
86
|
-
const items = entries.map(entry => {
|
|
87
|
-
const itemPath = path.join(normalizedPath, entry.name);
|
|
88
|
-
return {
|
|
89
|
-
name: entry.name,
|
|
90
|
-
path: itemPath,
|
|
91
|
-
isDirectory: entry.isDirectory()
|
|
92
|
-
};
|
|
93
|
-
});
|
|
94
|
-
res.json({
|
|
95
|
-
isWindows,
|
|
96
|
-
currentPath: normalizedPath,
|
|
97
|
-
items
|
|
98
|
-
});
|
|
92
|
+
res.json(await listHostDirectories(String(requestPath || '')));
|
|
99
93
|
}
|
|
100
94
|
catch (error) {
|
|
101
95
|
const err = error;
|
|
102
96
|
res.status(500).json({ error: err.message });
|
|
103
97
|
}
|
|
104
98
|
});
|
|
99
|
+
/**
|
|
100
|
+
* 列出目录选择器内容。
|
|
101
|
+
* POST /api/file-browser/directory-picker/list
|
|
102
|
+
*
|
|
103
|
+
* 该接口只返回目录,用于选择工作目录;不同于 /list,它不暴露文件条目。
|
|
104
|
+
*/
|
|
105
|
+
fileBrowserRouter.post('/directory-picker/list', validateToken, async (req, res) => {
|
|
106
|
+
try {
|
|
107
|
+
const { path: requestPath = '' } = req.body || {};
|
|
108
|
+
res.json(await listHostDirectories(String(requestPath || '')));
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
const err = error;
|
|
112
|
+
res.status(400).json({ error: err.message });
|
|
113
|
+
}
|
|
114
|
+
});
|
|
105
115
|
/**
|
|
106
116
|
* 列出工作区目录内容
|
|
107
117
|
* POST /api/file-browser/workspace/list
|