ai-world-sdk 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/dist/__tests__/example.test.js +120 -0
- package/dist/__tests__/minio.test.d.ts +8 -0
- package/dist/__tests__/minio.test.js +203 -0
- package/dist/__tests__/resource.test.d.ts +8 -0
- package/dist/__tests__/resource.test.js +208 -0
- package/dist/config.d.ts +3 -3
- package/dist/config.js +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +7 -1
- package/dist/minio.d.ts +156 -0
- package/dist/minio.js +322 -0
- package/dist/resource.d.ts +137 -0
- package/dist/resource.js +390 -0
- package/package.json +4 -2
|
@@ -1581,3 +1581,123 @@ describe("Langchain SDK Tests", () => {
|
|
|
1581
1581
|
}
|
|
1582
1582
|
}, 240000);
|
|
1583
1583
|
});
|
|
1584
|
+
// ==================== MinIO 存储测试 ====================
|
|
1585
|
+
describe("MinIO Storage Tests", () => {
|
|
1586
|
+
const PLUGIN_ID = "test-plugin";
|
|
1587
|
+
let storageClient;
|
|
1588
|
+
beforeAll(() => {
|
|
1589
|
+
index_1.sdkConfig.setPluginId(PLUGIN_ID);
|
|
1590
|
+
storageClient = new index_1.MinioStorageClient();
|
|
1591
|
+
});
|
|
1592
|
+
test("MinIO 存储 - 上传文件", async () => {
|
|
1593
|
+
const content = "Hello, MinIO! This is a test file.";
|
|
1594
|
+
const blob = new Blob([content], { type: "text/plain" });
|
|
1595
|
+
const file = new File([blob], "test-hello.txt", { type: "text/plain" });
|
|
1596
|
+
const result = await storageClient.upload("test/hello.txt", file);
|
|
1597
|
+
expect(result).toBeDefined();
|
|
1598
|
+
expect(result.path).toBe("test/hello.txt");
|
|
1599
|
+
expect(result.size).toBeGreaterThan(0);
|
|
1600
|
+
expect(result.etag).toBeDefined();
|
|
1601
|
+
console.log("上传成功:", result);
|
|
1602
|
+
}, 30000);
|
|
1603
|
+
test("MinIO 存储 - 列出文件", async () => {
|
|
1604
|
+
const files = await storageClient.list({ prefix: "test/" });
|
|
1605
|
+
expect(files).toBeDefined();
|
|
1606
|
+
expect(Array.isArray(files)).toBe(true);
|
|
1607
|
+
expect(files.length).toBeGreaterThan(0);
|
|
1608
|
+
const testFile = files.find((f) => f.name === "test/hello.txt");
|
|
1609
|
+
expect(testFile).toBeDefined();
|
|
1610
|
+
console.log("文件列表:", files);
|
|
1611
|
+
}, 30000);
|
|
1612
|
+
test("MinIO 存储 - 获取文件信息", async () => {
|
|
1613
|
+
const info = await storageClient.info("test/hello.txt");
|
|
1614
|
+
expect(info).toBeDefined();
|
|
1615
|
+
expect(info.name).toBe("test/hello.txt");
|
|
1616
|
+
expect(info.size).toBeGreaterThan(0);
|
|
1617
|
+
expect(info.content_type).toBe("text/plain");
|
|
1618
|
+
console.log("文件信息:", info);
|
|
1619
|
+
}, 30000);
|
|
1620
|
+
test("MinIO 存储 - 下载文件", async () => {
|
|
1621
|
+
const blob = await storageClient.download("test/hello.txt");
|
|
1622
|
+
expect(blob).toBeDefined();
|
|
1623
|
+
expect(blob.size).toBeGreaterThan(0);
|
|
1624
|
+
const text = await blob.text();
|
|
1625
|
+
expect(text).toBe("Hello, MinIO! This is a test file.");
|
|
1626
|
+
console.log("下载成功, 内容:", text);
|
|
1627
|
+
}, 30000);
|
|
1628
|
+
test("MinIO 存储 - 获取预签名下载 URL", async () => {
|
|
1629
|
+
const result = await storageClient.getPresignedUrl("test/hello.txt", 600);
|
|
1630
|
+
expect(result).toBeDefined();
|
|
1631
|
+
expect(result.url).toBeDefined();
|
|
1632
|
+
expect(result.url).toContain("http");
|
|
1633
|
+
expect(result.expires_in).toBe(600);
|
|
1634
|
+
console.log("预签名下载 URL:", result.url);
|
|
1635
|
+
}, 30000);
|
|
1636
|
+
test("MinIO 存储 - 获取预签名上传 URL", async () => {
|
|
1637
|
+
const result = await storageClient.getPresignedUploadUrl("test/upload-via-presigned.txt", 600);
|
|
1638
|
+
expect(result).toBeDefined();
|
|
1639
|
+
expect(result.url).toBeDefined();
|
|
1640
|
+
expect(result.url).toContain("http");
|
|
1641
|
+
expect(result.expires_in).toBe(600);
|
|
1642
|
+
console.log("预签名上传 URL:", result.url);
|
|
1643
|
+
}, 30000);
|
|
1644
|
+
test("MinIO 存储 - 删除文件", async () => {
|
|
1645
|
+
// 先上传一个用于删除测试的文件
|
|
1646
|
+
const blob = new Blob(["delete me"], { type: "text/plain" });
|
|
1647
|
+
const file = new File([blob], "to-delete.txt", { type: "text/plain" });
|
|
1648
|
+
await storageClient.upload("test/to-delete.txt", file);
|
|
1649
|
+
// 删除文件
|
|
1650
|
+
await storageClient.delete("test/to-delete.txt");
|
|
1651
|
+
console.log("删除成功: test/to-delete.txt");
|
|
1652
|
+
// 验证文件已删除(获取信息应该失败)
|
|
1653
|
+
try {
|
|
1654
|
+
await storageClient.info("test/to-delete.txt");
|
|
1655
|
+
// 如果没有抛出错误,说明文件还在
|
|
1656
|
+
console.warn("文件可能未被删除");
|
|
1657
|
+
}
|
|
1658
|
+
catch (error) {
|
|
1659
|
+
expect(error.message).toContain("404");
|
|
1660
|
+
console.log("验证: 文件已成功删除");
|
|
1661
|
+
}
|
|
1662
|
+
}, 30000);
|
|
1663
|
+
test("MinIO 存储 - 清理测试文件", async () => {
|
|
1664
|
+
// 清理上传的测试文件
|
|
1665
|
+
try {
|
|
1666
|
+
await storageClient.delete("test/hello.txt");
|
|
1667
|
+
console.log("清理完成: test/hello.txt");
|
|
1668
|
+
}
|
|
1669
|
+
catch {
|
|
1670
|
+
console.log("清理: test/hello.txt 已不存在");
|
|
1671
|
+
}
|
|
1672
|
+
}, 30000);
|
|
1673
|
+
test("MinIO 存储 - 无 Plugin ID 时应报错", async () => {
|
|
1674
|
+
// 创建一个没有 pluginId 的客户端
|
|
1675
|
+
const clientWithoutPlugin = new index_1.MinioStorageClient({
|
|
1676
|
+
baseUrl: "http://localhost:8000",
|
|
1677
|
+
token: index_1.sdkConfig.getToken() || "",
|
|
1678
|
+
});
|
|
1679
|
+
// 临时清除 pluginId
|
|
1680
|
+
const originalPluginId = index_1.sdkConfig.getPluginId();
|
|
1681
|
+
index_1.sdkConfig._pluginId = null;
|
|
1682
|
+
index_1.sdkConfig._headers = {
|
|
1683
|
+
...index_1.sdkConfig.getHeaders(),
|
|
1684
|
+
};
|
|
1685
|
+
delete index_1.sdkConfig._headers["X-Plugin-Id"];
|
|
1686
|
+
const clientNoPlugin = new index_1.MinioStorageClient({
|
|
1687
|
+
baseUrl: "http://localhost:8000",
|
|
1688
|
+
token: index_1.sdkConfig.getToken() || "",
|
|
1689
|
+
});
|
|
1690
|
+
try {
|
|
1691
|
+
await clientNoPlugin.list();
|
|
1692
|
+
fail("应该抛出错误");
|
|
1693
|
+
}
|
|
1694
|
+
catch (error) {
|
|
1695
|
+
expect(error.message).toContain("X-Plugin-Id");
|
|
1696
|
+
console.log("正确抛出错误:", error.message);
|
|
1697
|
+
}
|
|
1698
|
+
// 恢复 pluginId
|
|
1699
|
+
if (originalPluginId) {
|
|
1700
|
+
index_1.sdkConfig.setPluginId(originalPluginId);
|
|
1701
|
+
}
|
|
1702
|
+
}, 30000);
|
|
1703
|
+
});
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MinioStorageClient 测试
|
|
4
|
+
* 使用真实 SDK 调用后端 /api/minio 接口
|
|
5
|
+
* 需要后端运行 + MinIO 服务可用
|
|
6
|
+
*
|
|
7
|
+
* 运行: npm run test:minio
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
const dotenv = __importStar(require("dotenv"));
|
|
44
|
+
const index_1 = require("../index");
|
|
45
|
+
dotenv.config();
|
|
46
|
+
index_1.sdkConfig.setBaseUrl("http://localhost:8000");
|
|
47
|
+
index_1.sdkConfig.setToken(process.env.AUTH_TOKEN || process.env.TOKEN || "");
|
|
48
|
+
index_1.sdkConfig.setDebug(true);
|
|
49
|
+
const PLUGIN_ID = "test-plugin";
|
|
50
|
+
describe("MinioStorageClient 测试", () => {
|
|
51
|
+
let client;
|
|
52
|
+
beforeAll(() => {
|
|
53
|
+
index_1.sdkConfig.setPluginId(PLUGIN_ID);
|
|
54
|
+
client = new index_1.MinioStorageClient();
|
|
55
|
+
});
|
|
56
|
+
// ==================== 上传 ====================
|
|
57
|
+
test("上传文本文件", async () => {
|
|
58
|
+
const content = "Hello, MinIO! Timestamp: " + Date.now();
|
|
59
|
+
const blob = new Blob([content], { type: "text/plain" });
|
|
60
|
+
const file = new File([blob], "hello.txt", { type: "text/plain" });
|
|
61
|
+
const result = await client.upload("test/hello.txt", file);
|
|
62
|
+
expect(result).toBeDefined();
|
|
63
|
+
expect(result.path).toBe("test/hello.txt");
|
|
64
|
+
expect(result.size).toBeGreaterThan(0);
|
|
65
|
+
expect(result.etag).toBeDefined();
|
|
66
|
+
expect(result.bucket).toBeDefined();
|
|
67
|
+
console.log("上传成功:", result);
|
|
68
|
+
}, 30000);
|
|
69
|
+
test("上传不指定 path 时使用文件名", async () => {
|
|
70
|
+
const blob = new Blob(["auto-name-test"], { type: "text/plain" });
|
|
71
|
+
const file = new File([blob], "auto-name.txt", { type: "text/plain" });
|
|
72
|
+
const result = await client.upload("test/auto-name.txt", file);
|
|
73
|
+
expect(result).toBeDefined();
|
|
74
|
+
expect(result.size).toBe(14);
|
|
75
|
+
console.log("自动命名上传成功:", result);
|
|
76
|
+
}, 30000);
|
|
77
|
+
// ==================== 列表 ====================
|
|
78
|
+
test("列出文件", async () => {
|
|
79
|
+
const files = await client.list({ prefix: "test/" });
|
|
80
|
+
expect(files).toBeDefined();
|
|
81
|
+
expect(Array.isArray(files)).toBe(true);
|
|
82
|
+
expect(files.length).toBeGreaterThan(0);
|
|
83
|
+
const helloFile = files.find((f) => f.name === "test/hello.txt");
|
|
84
|
+
expect(helloFile).toBeDefined();
|
|
85
|
+
console.log(`文件列表 (${files.length} 个):`, files.map((f) => f.name));
|
|
86
|
+
}, 30000);
|
|
87
|
+
test("列出文件 - 无 prefix", async () => {
|
|
88
|
+
const files = await client.list();
|
|
89
|
+
expect(files).toBeDefined();
|
|
90
|
+
expect(Array.isArray(files)).toBe(true);
|
|
91
|
+
console.log(`全部文件 (${files.length} 个)`);
|
|
92
|
+
}, 30000);
|
|
93
|
+
test("列出文件 - 非递归", async () => {
|
|
94
|
+
const files = await client.list({ prefix: "test/", recursive: false });
|
|
95
|
+
expect(files).toBeDefined();
|
|
96
|
+
expect(Array.isArray(files)).toBe(true);
|
|
97
|
+
console.log(`非递归列表 (${files.length} 个):`, files.map((f) => ({ name: f.name, is_dir: f.is_dir })));
|
|
98
|
+
}, 30000);
|
|
99
|
+
// ==================== 文件信息 ====================
|
|
100
|
+
test("获取文件信息", async () => {
|
|
101
|
+
const info = await client.info("test/hello.txt");
|
|
102
|
+
expect(info).toBeDefined();
|
|
103
|
+
expect(info.name).toBe("test/hello.txt");
|
|
104
|
+
expect(info.size).toBeGreaterThan(0);
|
|
105
|
+
expect(info.content_type).toBe("text/plain");
|
|
106
|
+
expect(info.etag).toBeDefined();
|
|
107
|
+
expect(info.last_modified).toBeDefined();
|
|
108
|
+
console.log("文件信息:", info);
|
|
109
|
+
}, 30000);
|
|
110
|
+
// ==================== 下载 ====================
|
|
111
|
+
test("下载文件", async () => {
|
|
112
|
+
const blob = await client.download("test/hello.txt");
|
|
113
|
+
expect(blob).toBeDefined();
|
|
114
|
+
expect(blob.size).toBeGreaterThan(0);
|
|
115
|
+
const text = await blob.text();
|
|
116
|
+
expect(text).toContain("Hello, MinIO!");
|
|
117
|
+
console.log("下载成功, 大小:", blob.size, "内容:", text.substring(0, 50));
|
|
118
|
+
}, 30000);
|
|
119
|
+
// ==================== 预签名 URL ====================
|
|
120
|
+
test("获取预签名下载 URL", async () => {
|
|
121
|
+
const result = await client.getPresignedUrl("test/hello.txt", 600);
|
|
122
|
+
expect(result).toBeDefined();
|
|
123
|
+
expect(result.url).toBeDefined();
|
|
124
|
+
expect(result.url).toContain("http");
|
|
125
|
+
expect(result.expires_in).toBe(600);
|
|
126
|
+
console.log("预签名下载 URL:", result.url.substring(0, 100) + "...");
|
|
127
|
+
}, 30000);
|
|
128
|
+
test("获取预签名上传 URL", async () => {
|
|
129
|
+
const result = await client.getPresignedUploadUrl("test/presigned-upload.txt", 600);
|
|
130
|
+
expect(result).toBeDefined();
|
|
131
|
+
expect(result.url).toBeDefined();
|
|
132
|
+
expect(result.url).toContain("http");
|
|
133
|
+
expect(result.expires_in).toBe(600);
|
|
134
|
+
console.log("预签名上传 URL:", result.url.substring(0, 100) + "...");
|
|
135
|
+
}, 30000);
|
|
136
|
+
// ==================== 删除 ====================
|
|
137
|
+
test("删除文件", async () => {
|
|
138
|
+
// 上传一个用于删除的文件
|
|
139
|
+
const blob = new Blob(["delete me"], { type: "text/plain" });
|
|
140
|
+
const file = new File([blob], "to-delete.txt", { type: "text/plain" });
|
|
141
|
+
await client.upload("test/to-delete.txt", file);
|
|
142
|
+
// 删除
|
|
143
|
+
await client.delete("test/to-delete.txt");
|
|
144
|
+
console.log("删除成功: test/to-delete.txt");
|
|
145
|
+
// 验证文件已删除
|
|
146
|
+
try {
|
|
147
|
+
await client.info("test/to-delete.txt");
|
|
148
|
+
console.warn("文件可能未被删除");
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
expect(error.message).toMatch(/404|不存在/);
|
|
152
|
+
console.log("验证: 文件已成功删除");
|
|
153
|
+
}
|
|
154
|
+
}, 30000);
|
|
155
|
+
// ==================== 清理 ====================
|
|
156
|
+
test("清理测试文件", async () => {
|
|
157
|
+
const filesToClean = ["test/hello.txt", "test/auto-name.txt"];
|
|
158
|
+
for (const path of filesToClean) {
|
|
159
|
+
try {
|
|
160
|
+
await client.delete(path);
|
|
161
|
+
console.log("清理:", path);
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
console.log("清理跳过:", path, "(不存在)");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}, 30000);
|
|
168
|
+
// ==================== 错误处理 ====================
|
|
169
|
+
test("下载不存在的文件应返回 404", async () => {
|
|
170
|
+
try {
|
|
171
|
+
await client.download("nonexist/file-" + Date.now() + ".txt");
|
|
172
|
+
fail("应该抛出错误");
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
expect(error.message).toMatch(/404|不存在/);
|
|
176
|
+
console.log("正确返回 404:", error.message);
|
|
177
|
+
}
|
|
178
|
+
}, 30000);
|
|
179
|
+
test("无 Plugin ID 时应报错", async () => {
|
|
180
|
+
// 保存原始值
|
|
181
|
+
const originalPluginId = index_1.sdkConfig.getPluginId();
|
|
182
|
+
const originalHeaders = { ...index_1.sdkConfig.getHeaders() };
|
|
183
|
+
// 清除 pluginId
|
|
184
|
+
index_1.sdkConfig._pluginId = null;
|
|
185
|
+
delete index_1.sdkConfig._headers["X-Plugin-Id"];
|
|
186
|
+
const clientNoPlugin = new index_1.MinioStorageClient({
|
|
187
|
+
baseUrl: "http://localhost:8000",
|
|
188
|
+
token: index_1.sdkConfig.getToken() || "",
|
|
189
|
+
});
|
|
190
|
+
try {
|
|
191
|
+
await clientNoPlugin.list();
|
|
192
|
+
fail("应该抛出错误");
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
expect(error.message).toContain("X-Plugin-Id");
|
|
196
|
+
console.log("正确抛出错误:", error.message);
|
|
197
|
+
}
|
|
198
|
+
// 恢复
|
|
199
|
+
if (originalPluginId) {
|
|
200
|
+
index_1.sdkConfig.setPluginId(originalPluginId);
|
|
201
|
+
}
|
|
202
|
+
}, 30000);
|
|
203
|
+
});
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ResourceClient 集成测试
|
|
4
|
+
* 使用真实 SDK 调用后端 /api/resources 接口
|
|
5
|
+
* 需要后端运行 + MinIO 服务 + 数据库可用
|
|
6
|
+
*
|
|
7
|
+
* 运行: npx jest --testPathPattern=resource.test.ts
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
const dotenv = __importStar(require("dotenv"));
|
|
44
|
+
const index_1 = require("../index");
|
|
45
|
+
dotenv.config();
|
|
46
|
+
index_1.sdkConfig.setBaseUrl("http://localhost:8000");
|
|
47
|
+
index_1.sdkConfig.setToken(process.env.AUTH_TOKEN || process.env.TOKEN || "");
|
|
48
|
+
index_1.sdkConfig.setDebug(true);
|
|
49
|
+
const PLUGIN_ID = "test-plugin";
|
|
50
|
+
describe("ResourceClient 测试", () => {
|
|
51
|
+
let client;
|
|
52
|
+
let uploadedResourceId;
|
|
53
|
+
beforeAll(() => {
|
|
54
|
+
index_1.sdkConfig.setPluginId(PLUGIN_ID);
|
|
55
|
+
client = new index_1.ResourceClient();
|
|
56
|
+
});
|
|
57
|
+
// ==================== 上传 ====================
|
|
58
|
+
test("上传资源 - 默认 private", async () => {
|
|
59
|
+
const content = "Resource test content: " + Date.now();
|
|
60
|
+
const blob = new Blob([content], { type: "text/plain" });
|
|
61
|
+
const file = new File([blob], "resource-test.txt", { type: "text/plain" });
|
|
62
|
+
const result = await client.upload("test/resource-test.txt", file);
|
|
63
|
+
expect(result).toBeDefined();
|
|
64
|
+
expect(result.id).toBeDefined();
|
|
65
|
+
expect(result.path).toBe("test/resource-test.txt");
|
|
66
|
+
expect(result.access_level).toBe("private");
|
|
67
|
+
expect(result.owner_id).toBeDefined();
|
|
68
|
+
expect(result.plugin_id).toBe(PLUGIN_ID);
|
|
69
|
+
expect(result.size).toBeGreaterThan(0);
|
|
70
|
+
uploadedResourceId = result.id;
|
|
71
|
+
console.log("上传成功:", result);
|
|
72
|
+
}, 30000);
|
|
73
|
+
test("上传资源 - public 带描述", async () => {
|
|
74
|
+
const blob = new Blob(["public content"], { type: "text/plain" });
|
|
75
|
+
const file = new File([blob], "public-file.txt", { type: "text/plain" });
|
|
76
|
+
const result = await client.upload("test/public-file.txt", file, {
|
|
77
|
+
accessLevel: "public",
|
|
78
|
+
description: "公开测试文件",
|
|
79
|
+
});
|
|
80
|
+
expect(result).toBeDefined();
|
|
81
|
+
expect(result.access_level).toBe("public");
|
|
82
|
+
expect(result.description).toBe("公开测试文件");
|
|
83
|
+
console.log("公开资源上传成功:", result);
|
|
84
|
+
}, 30000);
|
|
85
|
+
// ==================== 列表 ====================
|
|
86
|
+
test("列出我的资源", async () => {
|
|
87
|
+
const resources = await client.listMy();
|
|
88
|
+
expect(resources).toBeDefined();
|
|
89
|
+
expect(Array.isArray(resources)).toBe(true);
|
|
90
|
+
expect(resources.length).toBeGreaterThan(0);
|
|
91
|
+
const testFile = resources.find((r) => r.path === "test/resource-test.txt");
|
|
92
|
+
expect(testFile).toBeDefined();
|
|
93
|
+
console.log(`我的资源 (${resources.length} 个):`, resources.map((r) => r.path));
|
|
94
|
+
}, 30000);
|
|
95
|
+
test("列出公开资源", async () => {
|
|
96
|
+
const resources = await client.listPublic();
|
|
97
|
+
expect(resources).toBeDefined();
|
|
98
|
+
expect(Array.isArray(resources)).toBe(true);
|
|
99
|
+
const publicFile = resources.find((r) => r.path === "test/public-file.txt");
|
|
100
|
+
expect(publicFile).toBeDefined();
|
|
101
|
+
console.log(`公开资源 (${resources.length} 个):`, resources.map((r) => r.path));
|
|
102
|
+
}, 30000);
|
|
103
|
+
// ==================== 获取详情 ====================
|
|
104
|
+
test("获取资源详情", async () => {
|
|
105
|
+
expect(uploadedResourceId).toBeDefined();
|
|
106
|
+
const info = await client.getInfo(uploadedResourceId);
|
|
107
|
+
expect(info).toBeDefined();
|
|
108
|
+
expect(info.id).toBe(uploadedResourceId);
|
|
109
|
+
expect(info.path).toBe("test/resource-test.txt");
|
|
110
|
+
expect(info.filename).toBe("resource-test.txt");
|
|
111
|
+
console.log("资源详情:", info);
|
|
112
|
+
}, 30000);
|
|
113
|
+
// ==================== 修改权限 ====================
|
|
114
|
+
test("修改访问级别为 public", async () => {
|
|
115
|
+
expect(uploadedResourceId).toBeDefined();
|
|
116
|
+
const updated = await client.updateAccess(uploadedResourceId, "public");
|
|
117
|
+
expect(updated).toBeDefined();
|
|
118
|
+
expect(updated.access_level).toBe("public");
|
|
119
|
+
console.log("访问级别已更新:", updated.access_level);
|
|
120
|
+
}, 30000);
|
|
121
|
+
test("修改访问级别为 specific_users", async () => {
|
|
122
|
+
expect(uploadedResourceId).toBeDefined();
|
|
123
|
+
const updated = await client.updateAccess(uploadedResourceId, "specific_users");
|
|
124
|
+
expect(updated).toBeDefined();
|
|
125
|
+
expect(updated.access_level).toBe("specific_users");
|
|
126
|
+
console.log("访问级别已更新:", updated.access_level);
|
|
127
|
+
}, 30000);
|
|
128
|
+
// ==================== 批量分享 ====================
|
|
129
|
+
test("批量添加分享 - 单个用户", async () => {
|
|
130
|
+
expect(uploadedResourceId).toBeDefined();
|
|
131
|
+
const result = await client.addShare(uploadedResourceId, 99);
|
|
132
|
+
expect(result).toBeDefined();
|
|
133
|
+
expect(result.resource_id).toBe(uploadedResourceId);
|
|
134
|
+
expect(result.total_requested).toBe(1);
|
|
135
|
+
console.log("批量添加分享(单个):", result);
|
|
136
|
+
}, 30000);
|
|
137
|
+
test("批量添加分享 - 多个用户", async () => {
|
|
138
|
+
expect(uploadedResourceId).toBeDefined();
|
|
139
|
+
const result = await client.addShare(uploadedResourceId, [100, 101]);
|
|
140
|
+
expect(result).toBeDefined();
|
|
141
|
+
expect(result.total_requested).toBe(2);
|
|
142
|
+
console.log("批量添加分享(多个):", result);
|
|
143
|
+
}, 30000);
|
|
144
|
+
test("批量移除分享 - 多个用户", async () => {
|
|
145
|
+
expect(uploadedResourceId).toBeDefined();
|
|
146
|
+
const result = await client.removeShare(uploadedResourceId, [99, 100, 101]);
|
|
147
|
+
expect(result).toBeDefined();
|
|
148
|
+
expect(result.total_requested).toBe(3);
|
|
149
|
+
console.log("批量移除分享:", result);
|
|
150
|
+
}, 30000);
|
|
151
|
+
// ==================== 下载 ====================
|
|
152
|
+
test("通过资源 ID 下载", async () => {
|
|
153
|
+
expect(uploadedResourceId).toBeDefined();
|
|
154
|
+
// 先改回 private 验证 owner 仍可下载
|
|
155
|
+
await client.updateAccess(uploadedResourceId, "private");
|
|
156
|
+
const blob = await client.download(uploadedResourceId);
|
|
157
|
+
expect(blob).toBeDefined();
|
|
158
|
+
expect(blob.size).toBeGreaterThan(0);
|
|
159
|
+
console.log("下载成功, 大小:", blob.size);
|
|
160
|
+
}, 30000);
|
|
161
|
+
// ==================== 列出被分享的 ====================
|
|
162
|
+
test("列出被分享给我的资源", async () => {
|
|
163
|
+
const resources = await client.listSharedWithMe();
|
|
164
|
+
expect(resources).toBeDefined();
|
|
165
|
+
expect(Array.isArray(resources)).toBe(true);
|
|
166
|
+
console.log(`被分享资源 (${resources.length} 个)`);
|
|
167
|
+
}, 30000);
|
|
168
|
+
// ==================== 跨插件 ====================
|
|
169
|
+
test("列出我的资源 - 跨插件", async () => {
|
|
170
|
+
const resources = await client.listMy({ crossPlugin: true });
|
|
171
|
+
expect(resources).toBeDefined();
|
|
172
|
+
expect(Array.isArray(resources)).toBe(true);
|
|
173
|
+
console.log(`跨插件资源 (${resources.length} 个)`);
|
|
174
|
+
}, 30000);
|
|
175
|
+
// ==================== 删除 ====================
|
|
176
|
+
test("删除资源", async () => {
|
|
177
|
+
expect(uploadedResourceId).toBeDefined();
|
|
178
|
+
await client.delete(uploadedResourceId);
|
|
179
|
+
console.log("资源已删除:", uploadedResourceId);
|
|
180
|
+
// 验证已删除
|
|
181
|
+
try {
|
|
182
|
+
await client.getInfo(uploadedResourceId);
|
|
183
|
+
fail("应该抛出错误");
|
|
184
|
+
}
|
|
185
|
+
catch (e) {
|
|
186
|
+
expect(e.message).toContain("404");
|
|
187
|
+
}
|
|
188
|
+
}, 30000);
|
|
189
|
+
// 清理 public-file
|
|
190
|
+
test("清理测试资源", async () => {
|
|
191
|
+
const resources = await client.listMy();
|
|
192
|
+
const publicFile = resources.find((r) => r.path === "test/public-file.txt");
|
|
193
|
+
if (publicFile) {
|
|
194
|
+
await client.delete(publicFile.id);
|
|
195
|
+
console.log("清理 public-file:", publicFile.id);
|
|
196
|
+
}
|
|
197
|
+
}, 30000);
|
|
198
|
+
// ==================== 插件 ID 验证 ====================
|
|
199
|
+
test("缺少 pluginId 时抛出错误", () => {
|
|
200
|
+
const originalPluginId = index_1.sdkConfig.getPluginId();
|
|
201
|
+
index_1.sdkConfig.setPluginId("");
|
|
202
|
+
const badClient = new index_1.ResourceClient();
|
|
203
|
+
expect(() => {
|
|
204
|
+
badClient.ensurePluginId();
|
|
205
|
+
}).toThrow("X-Plugin-Id is required");
|
|
206
|
+
index_1.sdkConfig.setPluginId(originalPluginId || PLUGIN_ID);
|
|
207
|
+
});
|
|
208
|
+
});
|
package/dist/config.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* 注意: {VERSION} 占位符会在构建时被替换为实际版本号
|
|
11
11
|
*/
|
|
12
|
-
export declare const SDK_SIGNATURE = "AI_WORLD_SDK_V:1.2.
|
|
12
|
+
export declare const SDK_SIGNATURE = "AI_WORLD_SDK_V:1.2.2";
|
|
13
13
|
/**
|
|
14
14
|
* 版本兼容性错误
|
|
15
15
|
*/
|
|
@@ -24,8 +24,8 @@ declare class SDKConfig {
|
|
|
24
24
|
private _pluginId;
|
|
25
25
|
private _versionCompatible;
|
|
26
26
|
private _versionCheckPromise;
|
|
27
|
-
readonly sdkSignature = "AI_WORLD_SDK_V:1.2.
|
|
28
|
-
readonly sdkVersion = "1.2.
|
|
27
|
+
readonly sdkSignature = "AI_WORLD_SDK_V:1.2.2";
|
|
28
|
+
readonly sdkVersion = "1.2.2";
|
|
29
29
|
constructor();
|
|
30
30
|
/**
|
|
31
31
|
* Set global base URL
|
package/dist/config.js
CHANGED
|
@@ -7,7 +7,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
exports.sdkConfig = exports.VersionCompatibilityError = exports.SDK_SIGNATURE = void 0;
|
|
8
8
|
// SDK 版本号(构建时自动从 package.json 更新)
|
|
9
9
|
// 此版本号会在运行 npm run build 时自动从 package.json 读取并更新
|
|
10
|
-
const SDK_VERSION = "1.2.
|
|
10
|
+
const SDK_VERSION = "1.2.2";
|
|
11
11
|
/**
|
|
12
12
|
* SDK 特征码 - 用于在构建后的 JS 文件中识别 SDK 版本
|
|
13
13
|
* 格式: AI_WORLD_SDK_V:版本号
|
|
@@ -15,7 +15,7 @@ const SDK_VERSION = "1.2.0";
|
|
|
15
15
|
*
|
|
16
16
|
* 注意: {VERSION} 占位符会在构建时被替换为实际版本号
|
|
17
17
|
*/
|
|
18
|
-
exports.SDK_SIGNATURE = "AI_WORLD_SDK_V:1.2.
|
|
18
|
+
exports.SDK_SIGNATURE = "AI_WORLD_SDK_V:1.2.2";
|
|
19
19
|
/**
|
|
20
20
|
* 版本兼容性错误
|
|
21
21
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -27,6 +27,8 @@ export { GeminiImageGenerationClient, type GeminiImageGenerationConfig, type Gem
|
|
|
27
27
|
export { VideoGenerationClient, type VideoGenerationConfig, type VideoGenerationRequest, type ContentGenerationTaskID, type ContentGenerationTask, };
|
|
28
28
|
export { OpenAIVideoGenerationClient, type OpenAIVideoGenerationConfig, type OpenAIVideoGenerationRequest, type OpenAIVideoTaskResponse, };
|
|
29
29
|
export { DownloadClient, type DownloadConfig, type DownloadOptions, type StreamDownloadOptions, };
|
|
30
|
+
export { MinioStorageClient, type MinioStorageConfig, type UploadResponse, type ObjectInfo, type PresignedUrlResponse, type UploadOptions, type ListOptions, } from "./minio";
|
|
31
|
+
export { ResourceClient, type ResourceClientConfig, type ResourceInfo, type AccessLevel, type UploadResourceOptions, type ListResourceOptions, } from "./resource";
|
|
30
32
|
export { AuthClient, getCurrentUserInfo, type AuthConfig, type UserInfo, };
|
|
31
33
|
export { sdkConfig, VersionCompatibilityError, SDK_SIGNATURE } from "./config";
|
|
32
34
|
/**
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
20
20
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
21
21
|
};
|
|
22
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
-
exports.SDK_SIGNATURE = exports.VersionCompatibilityError = exports.sdkConfig = exports.getCurrentUserInfo = exports.AuthClient = exports.DownloadClient = exports.OpenAIVideoGenerationClient = exports.VideoGenerationClient = exports.GeminiImageGenerationClient = exports.DoubaoImageGenerationClient = exports.ChatAnthropic = exports.ChatGoogleGenerativeAI = exports.ChatOpenAI = exports.BaseChatModel = exports.AIMessageChunk = exports.SystemMessage = exports.AIMessage = exports.HumanMessage = void 0;
|
|
23
|
+
exports.SDK_SIGNATURE = exports.VersionCompatibilityError = exports.sdkConfig = exports.getCurrentUserInfo = exports.AuthClient = exports.ResourceClient = exports.MinioStorageClient = exports.DownloadClient = exports.OpenAIVideoGenerationClient = exports.VideoGenerationClient = exports.GeminiImageGenerationClient = exports.DoubaoImageGenerationClient = exports.ChatAnthropic = exports.ChatGoogleGenerativeAI = exports.ChatOpenAI = exports.BaseChatModel = exports.AIMessageChunk = exports.SystemMessage = exports.AIMessage = exports.HumanMessage = void 0;
|
|
24
24
|
exports.createChatModel = createChatModel;
|
|
25
25
|
const openai_1 = require("./chat_models/openai");
|
|
26
26
|
const google_1 = require("./chat_models/google");
|
|
@@ -53,6 +53,12 @@ var google_2 = require("./chat_models/google");
|
|
|
53
53
|
Object.defineProperty(exports, "ChatGoogleGenerativeAI", { enumerable: true, get: function () { return google_2.ChatGoogleGenerativeAI; } });
|
|
54
54
|
var anthropic_1 = require("./chat_models/anthropic");
|
|
55
55
|
Object.defineProperty(exports, "ChatAnthropic", { enumerable: true, get: function () { return anthropic_1.ChatAnthropic; } });
|
|
56
|
+
// Export MinIO storage client
|
|
57
|
+
var minio_1 = require("./minio");
|
|
58
|
+
Object.defineProperty(exports, "MinioStorageClient", { enumerable: true, get: function () { return minio_1.MinioStorageClient; } });
|
|
59
|
+
// Export resource management client
|
|
60
|
+
var resource_1 = require("./resource");
|
|
61
|
+
Object.defineProperty(exports, "ResourceClient", { enumerable: true, get: function () { return resource_1.ResourceClient; } });
|
|
56
62
|
// Export global configuration
|
|
57
63
|
var config_2 = require("./config");
|
|
58
64
|
Object.defineProperty(exports, "sdkConfig", { enumerable: true, get: function () { return config_2.sdkConfig; } });
|