@lcap/wave-sandbox-sdk 0.0.5 → 0.0.6
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/client.js +15 -5
- package/dist/modules/agent.d.ts +2 -1
- package/dist/modules/agent.js +5 -3
- package/dist/modules/file-system.d.ts +2 -1
- package/dist/modules/file-system.js +8 -6
- package/dist/modules/project.d.ts +2 -1
- package/dist/modules/project.js +5 -3
- package/dist/types/index.d.ts +5 -0
- package/dist/utils/fetch-auth.d.ts +4 -0
- package/dist/utils/fetch-auth.js +11 -0
- package/package.json +12 -11
- package/src/client.ts +15 -5
- package/src/modules/agent.ts +5 -3
- package/src/modules/file-system.ts +8 -6
- package/src/modules/project.ts +5 -3
- package/src/types/index.ts +5 -0
- package/src/utils/fetch-auth.ts +11 -0
package/dist/client.js
CHANGED
|
@@ -13,14 +13,14 @@ export class WaveSandboxClient {
|
|
|
13
13
|
return this.fileSystem;
|
|
14
14
|
}
|
|
15
15
|
constructor(options) {
|
|
16
|
-
const { url, projectId, options: socketOptions } = options;
|
|
16
|
+
const { url, projectId, authToken, options: socketOptions } = options;
|
|
17
17
|
const uri = new URL(url);
|
|
18
18
|
let pathname = uri.pathname;
|
|
19
19
|
if (pathname.endsWith('/')) {
|
|
20
20
|
pathname = pathname.slice(0, pathname.length - 1);
|
|
21
21
|
}
|
|
22
22
|
pathname = pathname + '/socket.io/';
|
|
23
|
-
// 构建 Socket.IO
|
|
23
|
+
// 构建 Socket.IO 连接选项(Authorization 供服务端 auth 中间件校验)
|
|
24
24
|
const connectOptions = {
|
|
25
25
|
autoConnect: socketOptions?.autoConnect ?? true,
|
|
26
26
|
reconnection: socketOptions?.reconnection ?? true,
|
|
@@ -28,15 +28,25 @@ export class WaveSandboxClient {
|
|
|
28
28
|
reconnectionAttempts: socketOptions?.reconnectionAttempts ?? 5,
|
|
29
29
|
query: projectId ? { projectId } : undefined,
|
|
30
30
|
path: pathname,
|
|
31
|
+
...(authToken
|
|
32
|
+
? {
|
|
33
|
+
extraHeaders: { Authorization: authToken },
|
|
34
|
+
transportOptions: {
|
|
35
|
+
polling: {
|
|
36
|
+
extraHeaders: { Authorization: authToken },
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
}
|
|
40
|
+
: {}),
|
|
31
41
|
};
|
|
32
42
|
// 创建 Socket.IO 连接
|
|
33
43
|
this.socket = io(uri.host, connectOptions);
|
|
34
44
|
// 初始化各个模块
|
|
35
45
|
this.exec = new ExecModule(this.socket);
|
|
36
|
-
this.fileSystem = new FileSystemModule(this.socket, url, projectId);
|
|
46
|
+
this.fileSystem = new FileSystemModule(this.socket, url, projectId, authToken);
|
|
37
47
|
this.port = new PortModule(this.socket);
|
|
38
|
-
this.project = new ProjectModule(this.socket, url, projectId);
|
|
39
|
-
this.agent = new AgentModule(this.socket, url, projectId);
|
|
48
|
+
this.project = new ProjectModule(this.socket, url, projectId, authToken);
|
|
49
|
+
this.agent = new AgentModule(this.socket, url, projectId, authToken);
|
|
40
50
|
}
|
|
41
51
|
/**
|
|
42
52
|
* 连接到服务器
|
package/dist/modules/agent.d.ts
CHANGED
|
@@ -314,7 +314,8 @@ export declare class AgentModule {
|
|
|
314
314
|
private socket;
|
|
315
315
|
private baseUrl;
|
|
316
316
|
private projectId?;
|
|
317
|
-
|
|
317
|
+
private authToken?;
|
|
318
|
+
constructor(socket: Socket, baseUrl: string, projectId?: string | undefined, authToken?: string | undefined);
|
|
318
319
|
/**
|
|
319
320
|
* 获取查询参数
|
|
320
321
|
*/
|
package/dist/modules/agent.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { createSocketHandler, onSocketEvent } from '../utils/socket.js';
|
|
2
|
+
import { fetchWithAuth } from '../utils/fetch-auth.js';
|
|
2
3
|
/**
|
|
3
4
|
* Agent 模块
|
|
4
5
|
*/
|
|
5
6
|
export class AgentModule {
|
|
6
|
-
constructor(socket, baseUrl, projectId) {
|
|
7
|
+
constructor(socket, baseUrl, projectId, authToken) {
|
|
7
8
|
this.socket = socket;
|
|
8
9
|
this.baseUrl = baseUrl;
|
|
9
10
|
this.projectId = projectId;
|
|
11
|
+
this.authToken = authToken;
|
|
10
12
|
}
|
|
11
13
|
/**
|
|
12
14
|
* 获取查询参数
|
|
@@ -61,7 +63,7 @@ export class AgentModule {
|
|
|
61
63
|
async getCurrentState() {
|
|
62
64
|
const queryParams = this.getQueryParams();
|
|
63
65
|
const url = `${this.baseUrl}/api/agent/currentState${queryParams ? `?${queryParams}` : ''}`;
|
|
64
|
-
const response = await
|
|
66
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
65
67
|
const result = await response.json();
|
|
66
68
|
if (result.status === 'error') {
|
|
67
69
|
throw new Error(result.message);
|
|
@@ -78,7 +80,7 @@ export class AgentModule {
|
|
|
78
80
|
const sessionIdParam = `sessionId=${encodeURIComponent(sessionId)}`;
|
|
79
81
|
const params = queryParams ? `${queryParams}&${sessionIdParam}` : sessionIdParam;
|
|
80
82
|
const url = `${this.baseUrl}/api/agent/askInfo?${params}`;
|
|
81
|
-
const response = await
|
|
83
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
82
84
|
const result = await response.json();
|
|
83
85
|
if (result.status === 'error') {
|
|
84
86
|
throw new Error(result.message);
|
|
@@ -7,7 +7,8 @@ export declare class FileSystemModule {
|
|
|
7
7
|
private socket;
|
|
8
8
|
private baseUrl;
|
|
9
9
|
private projectId?;
|
|
10
|
-
|
|
10
|
+
private authToken?;
|
|
11
|
+
constructor(socket: Socket, baseUrl: string, projectId?: string | undefined, authToken?: string | undefined);
|
|
11
12
|
/**
|
|
12
13
|
* 获取查询参数
|
|
13
14
|
*/
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { createSocketHandler, onSocketEvent } from '../utils/socket.js';
|
|
2
|
+
import { fetchWithAuth } from '../utils/fetch-auth.js';
|
|
2
3
|
/**
|
|
3
4
|
* 文件系统模块
|
|
4
5
|
*/
|
|
5
6
|
export class FileSystemModule {
|
|
6
|
-
constructor(socket, baseUrl, projectId) {
|
|
7
|
+
constructor(socket, baseUrl, projectId, authToken) {
|
|
7
8
|
this.socket = socket;
|
|
8
9
|
this.baseUrl = baseUrl;
|
|
9
10
|
this.projectId = projectId;
|
|
11
|
+
this.authToken = authToken;
|
|
10
12
|
}
|
|
11
13
|
/**
|
|
12
14
|
* 获取查询参数
|
|
@@ -33,7 +35,7 @@ export class FileSystemModule {
|
|
|
33
35
|
*/
|
|
34
36
|
async stat(filePath) {
|
|
35
37
|
const url = `${this.baseUrl}/api/fs/stat?${this.getQueryParams(filePath)}`;
|
|
36
|
-
const response = await
|
|
38
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
37
39
|
const result = await response.json();
|
|
38
40
|
if (result.status === 'error') {
|
|
39
41
|
throw new Error(result.message);
|
|
@@ -44,7 +46,7 @@ export class FileSystemModule {
|
|
|
44
46
|
if (asText) {
|
|
45
47
|
// 使用 readFile 端点获取文本内容
|
|
46
48
|
const url = `${this.baseUrl}/api/fs/readFile?${this.getQueryParams(filePath)}`;
|
|
47
|
-
const response = await
|
|
49
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
48
50
|
const result = await response.json();
|
|
49
51
|
if (result.status === 'error') {
|
|
50
52
|
throw new Error(result.message);
|
|
@@ -54,7 +56,7 @@ export class FileSystemModule {
|
|
|
54
56
|
else {
|
|
55
57
|
// 使用 read 端点获取原始文件(支持二进制)
|
|
56
58
|
const url = `${this.baseUrl}/api/fs/read?${this.getQueryParams(filePath)}`;
|
|
57
|
-
const response = await
|
|
59
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
58
60
|
if (!response.ok) {
|
|
59
61
|
throw new Error(`Failed to read file: ${response.statusText}`);
|
|
60
62
|
}
|
|
@@ -74,7 +76,7 @@ export class FileSystemModule {
|
|
|
74
76
|
*/
|
|
75
77
|
async readdir(filePath) {
|
|
76
78
|
const url = `${this.baseUrl}/api/fs/readdir?${this.getQueryParams(filePath)}`;
|
|
77
|
-
const response = await
|
|
79
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
78
80
|
const result = await response.json();
|
|
79
81
|
if (result.status === 'error') {
|
|
80
82
|
throw new Error(result.message);
|
|
@@ -88,7 +90,7 @@ export class FileSystemModule {
|
|
|
88
90
|
*/
|
|
89
91
|
async files(dirPath) {
|
|
90
92
|
const url = `${this.baseUrl}/api/fs/files?${this.getDirQueryParams(dirPath)}`;
|
|
91
|
-
const response = await
|
|
93
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
92
94
|
const result = await response.json();
|
|
93
95
|
if (result.status === 'error') {
|
|
94
96
|
throw new Error(result.message);
|
|
@@ -7,7 +7,8 @@ export declare class ProjectModule {
|
|
|
7
7
|
private socket;
|
|
8
8
|
private baseUrl;
|
|
9
9
|
private projectId?;
|
|
10
|
-
|
|
10
|
+
private authToken?;
|
|
11
|
+
constructor(socket: Socket, baseUrl: string, projectId?: string | undefined, authToken?: string | undefined);
|
|
11
12
|
/**
|
|
12
13
|
* 获取查询参数
|
|
13
14
|
*/
|
package/dist/modules/project.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { createSocketHandler, onSocketEvent } from '../utils/socket.js';
|
|
2
|
+
import { fetchWithAuth } from '../utils/fetch-auth.js';
|
|
2
3
|
/**
|
|
3
4
|
* 项目模块
|
|
4
5
|
*/
|
|
5
6
|
export class ProjectModule {
|
|
6
|
-
constructor(socket, baseUrl, projectId) {
|
|
7
|
+
constructor(socket, baseUrl, projectId, authToken) {
|
|
7
8
|
this.socket = socket;
|
|
8
9
|
this.baseUrl = baseUrl;
|
|
9
10
|
this.projectId = projectId;
|
|
11
|
+
this.authToken = authToken;
|
|
10
12
|
}
|
|
11
13
|
/**
|
|
12
14
|
* 获取查询参数
|
|
@@ -22,7 +24,7 @@ export class ProjectModule {
|
|
|
22
24
|
*/
|
|
23
25
|
async getInfo() {
|
|
24
26
|
const url = `${this.baseUrl}/project/info${this.projectId ? `?${this.getQueryParams()}` : ''}`;
|
|
25
|
-
const response = await
|
|
27
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
26
28
|
const result = await response.json();
|
|
27
29
|
if (result.status === 'error') {
|
|
28
30
|
throw new Error(result.message);
|
|
@@ -34,7 +36,7 @@ export class ProjectModule {
|
|
|
34
36
|
*/
|
|
35
37
|
async getFiles() {
|
|
36
38
|
const url = `${this.baseUrl}/project/files${this.projectId ? `?${this.getQueryParams()}` : ''}`;
|
|
37
|
-
const response = await
|
|
39
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
38
40
|
const result = await response.json();
|
|
39
41
|
if (result.status === 'error') {
|
|
40
42
|
throw new Error(result.message);
|
package/dist/types/index.d.ts
CHANGED
|
@@ -99,6 +99,11 @@ export interface SDKOptions {
|
|
|
99
99
|
url: string;
|
|
100
100
|
/** 项目 ID(可选,用于工作空间模式) */
|
|
101
101
|
projectId?: string;
|
|
102
|
+
/**
|
|
103
|
+
* 与服务器 `authToken` 一致时启用;HTTP 与 Socket 握手会携带 `Authorization` 头
|
|
104
|
+
*(例如 spec-server:`[naslStorageAppId, SBX_SANDBOX_ID].join('|')`)
|
|
105
|
+
*/
|
|
106
|
+
authToken?: string;
|
|
102
107
|
/** 连接选项 */
|
|
103
108
|
options?: {
|
|
104
109
|
/** 自动连接 */
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 带可选 Authorization 的 fetch,与 wave-sandbox-server 的 authToken 鉴权一致
|
|
3
|
+
*/
|
|
4
|
+
export function fetchWithAuth(url, authToken, init) {
|
|
5
|
+
if (!authToken) {
|
|
6
|
+
return fetch(url, init);
|
|
7
|
+
}
|
|
8
|
+
const headers = new Headers(init?.headers);
|
|
9
|
+
headers.set('Authorization', authToken);
|
|
10
|
+
return fetch(url, { ...init, headers });
|
|
11
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lcap/wave-sandbox-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "SDK for Wave Sandbox Client",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,6 +10,15 @@
|
|
|
10
10
|
"src",
|
|
11
11
|
"README.md"
|
|
12
12
|
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "rimraf dist && tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
|
|
15
|
+
"type-check": "tsc --noEmit",
|
|
16
|
+
"dev": "tsc -p tsconfig.build.json --watch & tsc-alias -p tsconfig.build.json --watch",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"lint": "eslint --cache",
|
|
19
|
+
"format": "prettier --write .",
|
|
20
|
+
"prepublishOnly": "pnpm run build"
|
|
21
|
+
},
|
|
13
22
|
"dependencies": {
|
|
14
23
|
"socket.io-client": "^4.8.3"
|
|
15
24
|
},
|
|
@@ -22,13 +31,5 @@
|
|
|
22
31
|
"engines": {
|
|
23
32
|
"node": ">=16.0.0"
|
|
24
33
|
},
|
|
25
|
-
"license": "MIT"
|
|
26
|
-
|
|
27
|
-
"build": "rimraf dist && tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
|
|
28
|
-
"type-check": "tsc --noEmit",
|
|
29
|
-
"dev": "tsc -p tsconfig.build.json --watch & tsc-alias -p tsconfig.build.json --watch",
|
|
30
|
-
"test": "vitest run",
|
|
31
|
-
"lint": "eslint --cache",
|
|
32
|
-
"format": "prettier --write ."
|
|
33
|
-
}
|
|
34
|
-
}
|
|
34
|
+
"license": "MIT"
|
|
35
|
+
}
|
package/src/client.ts
CHANGED
|
@@ -22,7 +22,7 @@ export class WaveSandboxClient {
|
|
|
22
22
|
public readonly agent: AgentModule;
|
|
23
23
|
|
|
24
24
|
constructor(options: SDKOptions) {
|
|
25
|
-
const { url, projectId, options: socketOptions } = options;
|
|
25
|
+
const { url, projectId, authToken, options: socketOptions } = options;
|
|
26
26
|
|
|
27
27
|
const uri = new URL(url);
|
|
28
28
|
let pathname = uri.pathname;
|
|
@@ -33,7 +33,7 @@ export class WaveSandboxClient {
|
|
|
33
33
|
|
|
34
34
|
pathname = pathname + '/socket.io/';
|
|
35
35
|
|
|
36
|
-
// 构建 Socket.IO
|
|
36
|
+
// 构建 Socket.IO 连接选项(Authorization 供服务端 auth 中间件校验)
|
|
37
37
|
const connectOptions = {
|
|
38
38
|
autoConnect: socketOptions?.autoConnect ?? true,
|
|
39
39
|
reconnection: socketOptions?.reconnection ?? true,
|
|
@@ -41,6 +41,16 @@ export class WaveSandboxClient {
|
|
|
41
41
|
reconnectionAttempts: socketOptions?.reconnectionAttempts ?? 5,
|
|
42
42
|
query: projectId ? { projectId } : undefined,
|
|
43
43
|
path: pathname,
|
|
44
|
+
...(authToken
|
|
45
|
+
? {
|
|
46
|
+
extraHeaders: { Authorization: authToken },
|
|
47
|
+
transportOptions: {
|
|
48
|
+
polling: {
|
|
49
|
+
extraHeaders: { Authorization: authToken },
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
}
|
|
53
|
+
: {}),
|
|
44
54
|
};
|
|
45
55
|
|
|
46
56
|
// 创建 Socket.IO 连接
|
|
@@ -48,10 +58,10 @@ export class WaveSandboxClient {
|
|
|
48
58
|
|
|
49
59
|
// 初始化各个模块
|
|
50
60
|
this.exec = new ExecModule(this.socket);
|
|
51
|
-
this.fileSystem = new FileSystemModule(this.socket, url, projectId);
|
|
61
|
+
this.fileSystem = new FileSystemModule(this.socket, url, projectId, authToken);
|
|
52
62
|
this.port = new PortModule(this.socket);
|
|
53
|
-
this.project = new ProjectModule(this.socket, url, projectId);
|
|
54
|
-
this.agent = new AgentModule(this.socket, url, projectId);
|
|
63
|
+
this.project = new ProjectModule(this.socket, url, projectId, authToken);
|
|
64
|
+
this.agent = new AgentModule(this.socket, url, projectId, authToken);
|
|
55
65
|
}
|
|
56
66
|
|
|
57
67
|
/**
|
package/src/modules/agent.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
} from '../types/agent-types.js';
|
|
10
10
|
import type { HttpResponse } from '../types/index.js';
|
|
11
11
|
import { createSocketHandler, onSocketEvent } from '../utils/socket.js';
|
|
12
|
+
import { fetchWithAuth } from '../utils/fetch-auth.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* 附件接口
|
|
@@ -355,7 +356,8 @@ export class AgentModule {
|
|
|
355
356
|
constructor(
|
|
356
357
|
private socket: Socket,
|
|
357
358
|
private baseUrl: string,
|
|
358
|
-
private projectId?: string
|
|
359
|
+
private projectId?: string,
|
|
360
|
+
private authToken?: string
|
|
359
361
|
) {}
|
|
360
362
|
|
|
361
363
|
/**
|
|
@@ -424,7 +426,7 @@ export class AgentModule {
|
|
|
424
426
|
async getCurrentState(): Promise<MessageQueueChangedEvent | null> {
|
|
425
427
|
const queryParams = this.getQueryParams();
|
|
426
428
|
const url = `${this.baseUrl}/api/agent/currentState${queryParams ? `?${queryParams}` : ''}`;
|
|
427
|
-
const response = await
|
|
429
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
428
430
|
const result: HttpResponse<MessageQueueChangedEvent | null> = await response.json();
|
|
429
431
|
|
|
430
432
|
if (result.status === 'error') {
|
|
@@ -444,7 +446,7 @@ export class AgentModule {
|
|
|
444
446
|
const sessionIdParam = `sessionId=${encodeURIComponent(sessionId)}`;
|
|
445
447
|
const params = queryParams ? `${queryParams}&${sessionIdParam}` : sessionIdParam;
|
|
446
448
|
const url = `${this.baseUrl}/api/agent/askInfo?${params}`;
|
|
447
|
-
const response = await
|
|
449
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
448
450
|
const result: HttpResponse<AskInfo | null> = await response.json();
|
|
449
451
|
|
|
450
452
|
if (result.status === 'error') {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Socket } from 'socket.io-client';
|
|
2
2
|
import { createSocketHandler, onSocketEvent } from '../utils/socket.js';
|
|
3
|
+
import { fetchWithAuth } from '../utils/fetch-auth.js';
|
|
3
4
|
import type { FileStat, DirectoryItem, FileChangeEvent, HttpResponse, ProjectFile } from '../types/index.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -9,7 +10,8 @@ export class FileSystemModule {
|
|
|
9
10
|
constructor(
|
|
10
11
|
private socket: Socket,
|
|
11
12
|
private baseUrl: string,
|
|
12
|
-
private projectId?: string
|
|
13
|
+
private projectId?: string,
|
|
14
|
+
private authToken?: string
|
|
13
15
|
) {}
|
|
14
16
|
|
|
15
17
|
/**
|
|
@@ -39,7 +41,7 @@ export class FileSystemModule {
|
|
|
39
41
|
*/
|
|
40
42
|
async stat(filePath: string): Promise<FileStat> {
|
|
41
43
|
const url = `${this.baseUrl}/api/fs/stat?${this.getQueryParams(filePath)}`;
|
|
42
|
-
const response = await
|
|
44
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
43
45
|
const result: HttpResponse<FileStat> = await response.json();
|
|
44
46
|
|
|
45
47
|
if (result.status === 'error') {
|
|
@@ -61,7 +63,7 @@ export class FileSystemModule {
|
|
|
61
63
|
if (asText) {
|
|
62
64
|
// 使用 readFile 端点获取文本内容
|
|
63
65
|
const url = `${this.baseUrl}/api/fs/readFile?${this.getQueryParams(filePath)}`;
|
|
64
|
-
const response = await
|
|
66
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
65
67
|
const result: HttpResponse<string> = await response.json();
|
|
66
68
|
|
|
67
69
|
if (result.status === 'error') {
|
|
@@ -72,7 +74,7 @@ export class FileSystemModule {
|
|
|
72
74
|
} else {
|
|
73
75
|
// 使用 read 端点获取原始文件(支持二进制)
|
|
74
76
|
const url = `${this.baseUrl}/api/fs/read?${this.getQueryParams(filePath)}`;
|
|
75
|
-
const response = await
|
|
77
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
76
78
|
if (!response.ok) {
|
|
77
79
|
throw new Error(`Failed to read file: ${response.statusText}`);
|
|
78
80
|
}
|
|
@@ -94,7 +96,7 @@ export class FileSystemModule {
|
|
|
94
96
|
*/
|
|
95
97
|
async readdir(filePath: string): Promise<DirectoryItem[]> {
|
|
96
98
|
const url = `${this.baseUrl}/api/fs/readdir?${this.getQueryParams(filePath)}`;
|
|
97
|
-
const response = await
|
|
99
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
98
100
|
const result: HttpResponse<DirectoryItem[]> = await response.json();
|
|
99
101
|
|
|
100
102
|
if (result.status === 'error') {
|
|
@@ -111,7 +113,7 @@ export class FileSystemModule {
|
|
|
111
113
|
*/
|
|
112
114
|
async files(dirPath: string): Promise<Record<string, ProjectFile>> {
|
|
113
115
|
const url = `${this.baseUrl}/api/fs/files?${this.getDirQueryParams(dirPath)}`;
|
|
114
|
-
const response = await
|
|
116
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
115
117
|
const result: HttpResponse<Record<string, ProjectFile>> = await response.json();
|
|
116
118
|
|
|
117
119
|
if (result.status === 'error') {
|
package/src/modules/project.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Socket } from 'socket.io-client';
|
|
2
2
|
import { createSocketHandler, onSocketEvent } from '../utils/socket.js';
|
|
3
|
+
import { fetchWithAuth } from '../utils/fetch-auth.js';
|
|
3
4
|
import type { ProjectInfo, ProjectFile, HttpResponse, FileChangeEvent } from '../types/index.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -9,7 +10,8 @@ export class ProjectModule {
|
|
|
9
10
|
constructor(
|
|
10
11
|
private socket: Socket,
|
|
11
12
|
private baseUrl: string,
|
|
12
|
-
private projectId?: string
|
|
13
|
+
private projectId?: string,
|
|
14
|
+
private authToken?: string
|
|
13
15
|
) {}
|
|
14
16
|
|
|
15
17
|
/**
|
|
@@ -27,7 +29,7 @@ export class ProjectModule {
|
|
|
27
29
|
*/
|
|
28
30
|
async getInfo(): Promise<ProjectInfo> {
|
|
29
31
|
const url = `${this.baseUrl}/project/info${this.projectId ? `?${this.getQueryParams()}` : ''}`;
|
|
30
|
-
const response = await
|
|
32
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
31
33
|
const result: HttpResponse<ProjectInfo> = await response.json();
|
|
32
34
|
|
|
33
35
|
if (result.status === 'error') {
|
|
@@ -42,7 +44,7 @@ export class ProjectModule {
|
|
|
42
44
|
*/
|
|
43
45
|
async getFiles(): Promise<ProjectFile[]> {
|
|
44
46
|
const url = `${this.baseUrl}/project/files${this.projectId ? `?${this.getQueryParams()}` : ''}`;
|
|
45
|
-
const response = await
|
|
47
|
+
const response = await fetchWithAuth(url, this.authToken);
|
|
46
48
|
const result: HttpResponse<{ files: ProjectFile[] }> = await response.json();
|
|
47
49
|
|
|
48
50
|
if (result.status === 'error') {
|
package/src/types/index.ts
CHANGED
|
@@ -114,6 +114,11 @@ export interface SDKOptions {
|
|
|
114
114
|
url: string;
|
|
115
115
|
/** 项目 ID(可选,用于工作空间模式) */
|
|
116
116
|
projectId?: string;
|
|
117
|
+
/**
|
|
118
|
+
* 与服务器 `authToken` 一致时启用;HTTP 与 Socket 握手会携带 `Authorization` 头
|
|
119
|
+
*(例如 spec-server:`[naslStorageAppId, SBX_SANDBOX_ID].join('|')`)
|
|
120
|
+
*/
|
|
121
|
+
authToken?: string;
|
|
117
122
|
/** 连接选项 */
|
|
118
123
|
options?: {
|
|
119
124
|
/** 自动连接 */
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 带可选 Authorization 的 fetch,与 wave-sandbox-server 的 authToken 鉴权一致
|
|
3
|
+
*/
|
|
4
|
+
export function fetchWithAuth(url: string | URL, authToken: string | undefined, init?: RequestInit): Promise<Response> {
|
|
5
|
+
if (!authToken) {
|
|
6
|
+
return fetch(url, init);
|
|
7
|
+
}
|
|
8
|
+
const headers = new Headers(init?.headers);
|
|
9
|
+
headers.set('Authorization', authToken);
|
|
10
|
+
return fetch(url, { ...init, headers });
|
|
11
|
+
}
|