@douyinfe/semi-mcp 1.0.8 → 1.0.9
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/browser.d.ts +47 -0
- package/dist/browser.js +345 -0
- package/dist/index.js +43 -43
- package/dist/utils/get-component-documents.d.ts +17 -0
- package/package.json +14 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semi MCP Browser Entry
|
|
3
|
+
*
|
|
4
|
+
* 这个入口导出所有可以在浏览器环境中运行的原子功能
|
|
5
|
+
* 这些功能只使用 fetch API,不依赖 Node.js 特有的模块
|
|
6
|
+
*/
|
|
7
|
+
export { fetchDirectoryList, fetchDirectoryListFromSource, UNPKG_BASE_URL, NPMMIRROR_BASE_URL, } from './utils/fetch-directory-list.js';
|
|
8
|
+
export { fetchFileContent, fetchFileContentFromSource, UNPKG_BASE_URL as FILE_UNPKG_BASE_URL, NPMMIRROR_BASE_URL as FILE_NPMMIRROR_BASE_URL, } from './utils/fetch-file-content.js';
|
|
9
|
+
export { getComponentList } from './utils/get-component-list.js';
|
|
10
|
+
export { getComponentDocuments, type ComponentDocument, type ComponentDocumentsResult, } from './utils/get-component-documents.js';
|
|
11
|
+
/**
|
|
12
|
+
* 获取 Semi Design 组件文档
|
|
13
|
+
* 这是一个便捷的高级 API,封装了获取文档的完整流程
|
|
14
|
+
*
|
|
15
|
+
* @param componentName - 组件名称,如 'Button', 'Table' 等。如果不提供,返回组件列表
|
|
16
|
+
* @param version - 版本号,如 '2.89.1'。默认为 'latest'
|
|
17
|
+
* @returns 文档内容或组件列表
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* // 获取组件列表
|
|
21
|
+
* const components = await getSemiDocument();
|
|
22
|
+
* console.log(components.components); // ['button', 'table', ...]
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* // 获取特定组件文档
|
|
26
|
+
* const doc = await getSemiDocument('Button');
|
|
27
|
+
* console.log(doc.documents[0].content); // 文档内容
|
|
28
|
+
*/
|
|
29
|
+
export declare function getSemiDocument(componentName?: string, version?: string): Promise<{
|
|
30
|
+
type: 'list';
|
|
31
|
+
version: string;
|
|
32
|
+
components: string[];
|
|
33
|
+
count: number;
|
|
34
|
+
} | {
|
|
35
|
+
type: 'document';
|
|
36
|
+
componentName: string;
|
|
37
|
+
version: string;
|
|
38
|
+
category: string;
|
|
39
|
+
documents: Array<{
|
|
40
|
+
name: string;
|
|
41
|
+
path: string;
|
|
42
|
+
content: string;
|
|
43
|
+
}>;
|
|
44
|
+
} | {
|
|
45
|
+
type: 'error';
|
|
46
|
+
message: string;
|
|
47
|
+
}>;
|
package/dist/browser.js
ADDED
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
var __webpack_modules__ = {
|
|
2
|
+
"./src/utils/fetch-directory-list.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
3
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
4
|
+
Bg: ()=>NPMMIRROR_BASE_URL,
|
|
5
|
+
EY: ()=>UNPKG_BASE_URL,
|
|
6
|
+
aF: ()=>fetchDirectoryList,
|
|
7
|
+
b_: ()=>fetchDirectoryListFromSource
|
|
8
|
+
});
|
|
9
|
+
const UNPKG_BASE_URL = 'https://unpkg.com';
|
|
10
|
+
const NPMMIRROR_BASE_URL = 'https://registry.npmmirror.com';
|
|
11
|
+
function flattenDirectoryStructure(item, result = []) {
|
|
12
|
+
result.push({
|
|
13
|
+
path: item.path,
|
|
14
|
+
type: item.type,
|
|
15
|
+
size: item.size
|
|
16
|
+
});
|
|
17
|
+
if (item.files && Array.isArray(item.files)) for (const file of item.files)flattenDirectoryStructure(file, result);
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
async function fetchNpmMirrorDirectoryRecursive(baseUrl, packageName, version, path, maxDepth = 10) {
|
|
21
|
+
if (maxDepth <= 0) return [];
|
|
22
|
+
const url = `${baseUrl}/${packageName}/${version}/files/${path}/?meta`;
|
|
23
|
+
const response = await fetch(url, {
|
|
24
|
+
headers: {
|
|
25
|
+
Accept: 'application/json'
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
if (!response.ok) throw new Error(`获取目录列表失败: ${response.status} ${response.statusText}`);
|
|
29
|
+
const contentType = response.headers.get('content-type') || '';
|
|
30
|
+
if (!contentType.includes('application/json')) throw new Error(`API 返回了非 JSON 格式: ${contentType}`);
|
|
31
|
+
const data = await response.json();
|
|
32
|
+
const normalizeType = (item)=>{
|
|
33
|
+
const path = item.path;
|
|
34
|
+
if (path.endsWith('/')) return {
|
|
35
|
+
path,
|
|
36
|
+
type: 'directory'
|
|
37
|
+
};
|
|
38
|
+
if (item.type && item.type.includes('/')) return {
|
|
39
|
+
path,
|
|
40
|
+
type: 'file'
|
|
41
|
+
};
|
|
42
|
+
if ('directory' === item.type) return {
|
|
43
|
+
path,
|
|
44
|
+
type: 'directory'
|
|
45
|
+
};
|
|
46
|
+
return {
|
|
47
|
+
path,
|
|
48
|
+
type: 'file'
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
const result = [];
|
|
52
|
+
if (data && 'object' == typeof data && 'files' in data && Array.isArray(data.files)) {
|
|
53
|
+
const promises = [];
|
|
54
|
+
for (const item of data.files){
|
|
55
|
+
const normalized = normalizeType(item);
|
|
56
|
+
result.push(normalized);
|
|
57
|
+
if ('directory' !== normalized.type || item.files && 0 !== item.files.length) {
|
|
58
|
+
if (item.files && Array.isArray(item.files) && item.files.length > 0) {
|
|
59
|
+
const flattened = [];
|
|
60
|
+
flattenDirectoryStructure(item, flattened);
|
|
61
|
+
const subFiles = flattened.filter((f)=>f.path !== normalized.path).map(normalizeType);
|
|
62
|
+
result.push(...subFiles);
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
const subPath = normalized.path.startsWith('/') ? normalized.path.slice(1) : normalized.path;
|
|
66
|
+
promises.push(fetchNpmMirrorDirectoryRecursive(baseUrl, packageName, version, subPath, maxDepth - 1).then((subFiles)=>subFiles.filter((f)=>f.path !== normalized.path)).catch(()=>[]));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (promises.length > 0) {
|
|
70
|
+
const subResults = await Promise.all(promises);
|
|
71
|
+
for (const subFiles of subResults)result.push(...subFiles);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
async function fetchDirectoryListFromSource(baseUrl, packageName, version, path, isNpmMirror = false) {
|
|
77
|
+
if (isNpmMirror) return fetchNpmMirrorDirectoryRecursive(baseUrl, packageName, version, path);
|
|
78
|
+
const url = `${baseUrl}/${packageName}@${version}/${path}/?meta`;
|
|
79
|
+
const response = await fetch(url, {
|
|
80
|
+
headers: {
|
|
81
|
+
Accept: 'application/json'
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
if (!response.ok) throw new Error(`获取目录列表失败: ${response.status} ${response.statusText}`);
|
|
85
|
+
const contentType = response.headers.get('content-type') || '';
|
|
86
|
+
if (!contentType.includes('application/json')) throw new Error(`API 返回了非 JSON 格式: ${contentType}`);
|
|
87
|
+
const data = await response.json();
|
|
88
|
+
const normalizeType = (item)=>{
|
|
89
|
+
const path = item.path;
|
|
90
|
+
if (path.endsWith('/')) return {
|
|
91
|
+
path,
|
|
92
|
+
type: 'directory'
|
|
93
|
+
};
|
|
94
|
+
if (item.type && item.type.includes('/')) return {
|
|
95
|
+
path,
|
|
96
|
+
type: 'file'
|
|
97
|
+
};
|
|
98
|
+
if ('directory' === item.type) return {
|
|
99
|
+
path,
|
|
100
|
+
type: 'directory'
|
|
101
|
+
};
|
|
102
|
+
return {
|
|
103
|
+
path,
|
|
104
|
+
type: 'file'
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
if (Array.isArray(data)) return data.map(normalizeType);
|
|
108
|
+
if (data && 'object' == typeof data && 'files' in data) {
|
|
109
|
+
const filesData = data;
|
|
110
|
+
if (Array.isArray(filesData.files)) return filesData.files.map(normalizeType);
|
|
111
|
+
}
|
|
112
|
+
if (data && 'object' == typeof data && 'path' in data) {
|
|
113
|
+
const singleItem = data;
|
|
114
|
+
if (singleItem.files && Array.isArray(singleItem.files)) {
|
|
115
|
+
const flattened = [];
|
|
116
|
+
flattenDirectoryStructure(singleItem, flattened);
|
|
117
|
+
return flattened.map(normalizeType);
|
|
118
|
+
}
|
|
119
|
+
return [
|
|
120
|
+
normalizeType(singleItem)
|
|
121
|
+
];
|
|
122
|
+
}
|
|
123
|
+
throw new Error('无法解析目录列表数据格式');
|
|
124
|
+
}
|
|
125
|
+
async function fetchDirectoryList(packageName, version, path) {
|
|
126
|
+
const unpkgPromise = fetchDirectoryListFromSource(UNPKG_BASE_URL, packageName, version, path, false);
|
|
127
|
+
const npmmirrorPromise = fetchDirectoryListFromSource(NPMMIRROR_BASE_URL, packageName, version, path, true);
|
|
128
|
+
const results = await Promise.allSettled([
|
|
129
|
+
unpkgPromise,
|
|
130
|
+
npmmirrorPromise
|
|
131
|
+
]);
|
|
132
|
+
const successfulResults = [];
|
|
133
|
+
const errors = [];
|
|
134
|
+
if ('fulfilled' === results[0].status) successfulResults.push({
|
|
135
|
+
source: 'unpkg',
|
|
136
|
+
files: results[0].value
|
|
137
|
+
});
|
|
138
|
+
else errors.push(results[0].reason instanceof Error ? results[0].reason : new Error(String(results[0].reason)));
|
|
139
|
+
if ('fulfilled' === results[1].status) successfulResults.push({
|
|
140
|
+
source: 'npmmirror',
|
|
141
|
+
files: results[1].value
|
|
142
|
+
});
|
|
143
|
+
else errors.push(results[1].reason instanceof Error ? results[1].reason : new Error(String(results[1].reason)));
|
|
144
|
+
if (0 === successfulResults.length) throw new Error(`所有数据源都失败了: ${errors.map((e)=>e.message).join('; ')}`);
|
|
145
|
+
successfulResults.sort((a, b)=>{
|
|
146
|
+
if (b.files.length !== a.files.length) return b.files.length - a.files.length;
|
|
147
|
+
return 'unpkg' === a.source ? -1 : 1;
|
|
148
|
+
});
|
|
149
|
+
return successfulResults[0].files;
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
"./src/utils/fetch-file-content.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
153
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
154
|
+
Bg: ()=>NPMMIRROR_BASE_URL,
|
|
155
|
+
EW: ()=>fetchFileContent,
|
|
156
|
+
EY: ()=>UNPKG_BASE_URL,
|
|
157
|
+
Ts: ()=>fetchFileContentFromSource
|
|
158
|
+
});
|
|
159
|
+
const UNPKG_BASE_URL = 'https://unpkg.com';
|
|
160
|
+
const NPMMIRROR_BASE_URL = 'https://registry.npmmirror.com';
|
|
161
|
+
async function fetchFileContentFromSource(baseUrl, packageName, version, filePath, isNpmMirror = false) {
|
|
162
|
+
const url = isNpmMirror ? `${baseUrl}/${packageName}/${version}/files/${filePath}` : `${baseUrl}/${packageName}@${version}/${filePath}`;
|
|
163
|
+
const response = await fetch(url, {
|
|
164
|
+
headers: {
|
|
165
|
+
Accept: 'text/plain, application/json, */*'
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
if (!response.ok) throw new Error(`获取文件失败: ${response.status} ${response.statusText}`);
|
|
169
|
+
const content = await response.text();
|
|
170
|
+
if (content.trim().startsWith('<!DOCTYPE html>') || content.includes('npmmirror 镜像站')) throw new Error('返回了 HTML 错误页面');
|
|
171
|
+
return content;
|
|
172
|
+
}
|
|
173
|
+
async function fetchFileContent(packageName, version, filePath) {
|
|
174
|
+
const unpkgPromise = fetchFileContentFromSource(UNPKG_BASE_URL, packageName, version, filePath, false);
|
|
175
|
+
const npmmirrorPromise = fetchFileContentFromSource(NPMMIRROR_BASE_URL, packageName, version, filePath, true);
|
|
176
|
+
const unpkgWithFallback = unpkgPromise.catch(()=>new Promise(()=>{}));
|
|
177
|
+
const npmmirrorWithFallback = npmmirrorPromise.catch(()=>new Promise(()=>{}));
|
|
178
|
+
const raceResult = await Promise.race([
|
|
179
|
+
unpkgWithFallback,
|
|
180
|
+
npmmirrorWithFallback
|
|
181
|
+
]).catch(()=>null);
|
|
182
|
+
if (raceResult) return raceResult;
|
|
183
|
+
const results = await Promise.allSettled([
|
|
184
|
+
unpkgPromise,
|
|
185
|
+
npmmirrorPromise
|
|
186
|
+
]);
|
|
187
|
+
const errors = [];
|
|
188
|
+
for (const result of results)if ('rejected' === result.status) errors.push(result.reason instanceof Error ? result.reason : new Error(String(result.reason)));
|
|
189
|
+
throw new Error(`所有数据源都失败了: ${errors.map((e)=>e.message).join('; ')}`);
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
"./src/utils/get-component-documents.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
193
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
194
|
+
getComponentDocuments: ()=>getComponentDocuments
|
|
195
|
+
});
|
|
196
|
+
var fetch_directory_list = __webpack_require__("./src/utils/fetch-directory-list.ts");
|
|
197
|
+
var fetch_file_content = __webpack_require__("./src/utils/fetch-file-content.ts");
|
|
198
|
+
async function getComponentDocuments(componentName, version = 'latest') {
|
|
199
|
+
const packageName = '@douyinfe/semi-ui';
|
|
200
|
+
const componentNameLower = componentName.toLowerCase();
|
|
201
|
+
const contentFiles = await (0, fetch_directory_list.aF)(packageName, version, 'content');
|
|
202
|
+
if (!contentFiles || 0 === contentFiles.length) return null;
|
|
203
|
+
const componentFiles = contentFiles.filter((file)=>{
|
|
204
|
+
if ('file' !== file.type) return false;
|
|
205
|
+
const path = file.path.toLowerCase();
|
|
206
|
+
const pathPattern = new RegExp(`/content/[^/]+/${componentNameLower}/index\\.md$`);
|
|
207
|
+
return pathPattern.test(path);
|
|
208
|
+
});
|
|
209
|
+
if (0 === componentFiles.length) return null;
|
|
210
|
+
const firstPath = componentFiles[0].path;
|
|
211
|
+
const pathParts = firstPath.split('/');
|
|
212
|
+
let categoryIndex = -1;
|
|
213
|
+
for(let i = 0; i < pathParts.length; i++)if ('content' === pathParts[i].toLowerCase()) {
|
|
214
|
+
categoryIndex = i + 1;
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
if (-1 === categoryIndex || categoryIndex >= pathParts.length) return null;
|
|
218
|
+
const category = pathParts[categoryIndex];
|
|
219
|
+
const documentPromises = componentFiles.map(async (file)=>{
|
|
220
|
+
const filePath = file.path.startsWith('/') ? file.path.slice(1) : file.path;
|
|
221
|
+
const parts = file.path.split('/');
|
|
222
|
+
const fileName = parts[parts.length - 1];
|
|
223
|
+
try {
|
|
224
|
+
const content = await (0, fetch_file_content.EW)(packageName, version, filePath);
|
|
225
|
+
return {
|
|
226
|
+
name: fileName,
|
|
227
|
+
path: file.path,
|
|
228
|
+
content: content
|
|
229
|
+
};
|
|
230
|
+
} catch (error) {
|
|
231
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
232
|
+
return {
|
|
233
|
+
name: fileName,
|
|
234
|
+
path: file.path,
|
|
235
|
+
content: `获取文档内容失败: ${errorMessage}`
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
const documents = await Promise.all(documentPromises);
|
|
240
|
+
return {
|
|
241
|
+
category,
|
|
242
|
+
documents: documents.sort((a, b)=>a.name.localeCompare(b.name))
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
"./src/utils/get-component-list.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
247
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
248
|
+
getComponentList: ()=>getComponentList
|
|
249
|
+
});
|
|
250
|
+
var fetch_directory_list = __webpack_require__("./src/utils/fetch-directory-list.ts");
|
|
251
|
+
async function getComponentList(version) {
|
|
252
|
+
const packageName = '@douyinfe/semi-ui';
|
|
253
|
+
const files = await (0, fetch_directory_list.aF)(packageName, version, 'lib');
|
|
254
|
+
if (!files || 0 === files.length) return [];
|
|
255
|
+
const componentSet = new Set();
|
|
256
|
+
for (const file of files){
|
|
257
|
+
const path = file.path;
|
|
258
|
+
const pathWithoutLib = path.replace(/^\/lib\//, '').replace(/^lib\//, '');
|
|
259
|
+
const parts = pathWithoutLib.split('/');
|
|
260
|
+
if (parts.length >= 2 && ('cjs' === parts[0] || 'es' === parts[0])) {
|
|
261
|
+
const componentName = parts[1];
|
|
262
|
+
if (componentName && 'lib' !== componentName) componentSet.add(componentName.toLowerCase());
|
|
263
|
+
} else if (parts.length >= 1) {
|
|
264
|
+
const componentName = parts[0];
|
|
265
|
+
if (componentName && 'lib' !== componentName && 'cjs' !== componentName && 'es' !== componentName) componentSet.add(componentName.toLowerCase());
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return Array.from(componentSet).sort();
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
var __webpack_module_cache__ = {};
|
|
273
|
+
function __webpack_require__(moduleId) {
|
|
274
|
+
var cachedModule = __webpack_module_cache__[moduleId];
|
|
275
|
+
if (void 0 !== cachedModule) return cachedModule.exports;
|
|
276
|
+
var module = __webpack_module_cache__[moduleId] = {
|
|
277
|
+
exports: {}
|
|
278
|
+
};
|
|
279
|
+
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
280
|
+
return module.exports;
|
|
281
|
+
}
|
|
282
|
+
(()=>{
|
|
283
|
+
__webpack_require__.d = (exports, definition)=>{
|
|
284
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, {
|
|
285
|
+
enumerable: true,
|
|
286
|
+
get: definition[key]
|
|
287
|
+
});
|
|
288
|
+
};
|
|
289
|
+
})();
|
|
290
|
+
(()=>{
|
|
291
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
292
|
+
})();
|
|
293
|
+
var fetch_directory_list = __webpack_require__("./src/utils/fetch-directory-list.ts");
|
|
294
|
+
var fetch_file_content = __webpack_require__("./src/utils/fetch-file-content.ts");
|
|
295
|
+
var get_component_list = __webpack_require__("./src/utils/get-component-list.ts");
|
|
296
|
+
var get_component_documents = __webpack_require__("./src/utils/get-component-documents.ts");
|
|
297
|
+
async function getSemiDocument(componentName, version = 'latest') {
|
|
298
|
+
const { getComponentList } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/utils/get-component-list.ts"));
|
|
299
|
+
const { getComponentDocuments } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/utils/get-component-documents.ts"));
|
|
300
|
+
try {
|
|
301
|
+
if (componentName) {
|
|
302
|
+
const result = await getComponentDocuments(componentName, version);
|
|
303
|
+
if (!result) {
|
|
304
|
+
const allComponents = await getComponentList(version);
|
|
305
|
+
return {
|
|
306
|
+
type: 'error',
|
|
307
|
+
message: `未找到组件 "${componentName}" 的文档 (版本 ${version})。可用组件列表:${allComponents.join(', ')}`
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
return {
|
|
311
|
+
type: 'document',
|
|
312
|
+
componentName,
|
|
313
|
+
version,
|
|
314
|
+
category: result.category,
|
|
315
|
+
documents: result.documents
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
{
|
|
319
|
+
const components = await getComponentList(version);
|
|
320
|
+
return {
|
|
321
|
+
type: 'list',
|
|
322
|
+
version,
|
|
323
|
+
components,
|
|
324
|
+
count: components.length
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
} catch (error) {
|
|
328
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
329
|
+
return {
|
|
330
|
+
type: 'error',
|
|
331
|
+
message: `获取文档失败: ${errorMessage}`
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
var __webpack_exports__FILE_NPMMIRROR_BASE_URL = fetch_file_content.Bg;
|
|
336
|
+
var __webpack_exports__FILE_UNPKG_BASE_URL = fetch_file_content.EY;
|
|
337
|
+
var __webpack_exports__NPMMIRROR_BASE_URL = fetch_directory_list.Bg;
|
|
338
|
+
var __webpack_exports__UNPKG_BASE_URL = fetch_directory_list.EY;
|
|
339
|
+
var __webpack_exports__fetchDirectoryList = fetch_directory_list.aF;
|
|
340
|
+
var __webpack_exports__fetchDirectoryListFromSource = fetch_directory_list.b_;
|
|
341
|
+
var __webpack_exports__fetchFileContent = fetch_file_content.EW;
|
|
342
|
+
var __webpack_exports__fetchFileContentFromSource = fetch_file_content.Ts;
|
|
343
|
+
var __webpack_exports__getComponentDocuments = get_component_documents.getComponentDocuments;
|
|
344
|
+
var __webpack_exports__getComponentList = get_component_list.getComponentList;
|
|
345
|
+
export { getSemiDocument, __webpack_exports__FILE_NPMMIRROR_BASE_URL as FILE_NPMMIRROR_BASE_URL, __webpack_exports__FILE_UNPKG_BASE_URL as FILE_UNPKG_BASE_URL, __webpack_exports__NPMMIRROR_BASE_URL as NPMMIRROR_BASE_URL, __webpack_exports__UNPKG_BASE_URL as UNPKG_BASE_URL, __webpack_exports__fetchDirectoryList as fetchDirectoryList, __webpack_exports__fetchDirectoryListFromSource as fetchDirectoryListFromSource, __webpack_exports__fetchFileContent as fetchFileContent, __webpack_exports__fetchFileContentFromSource as fetchFileContentFromSource, __webpack_exports__getComponentDocuments as getComponentDocuments, __webpack_exports__getComponentList as getComponentList };
|
package/dist/index.js
CHANGED
|
@@ -149,6 +149,25 @@ async function fetchDirectoryList(packageName, version, path) {
|
|
|
149
149
|
});
|
|
150
150
|
return successfulResults[0].files;
|
|
151
151
|
}
|
|
152
|
+
async function getComponentList(version) {
|
|
153
|
+
const packageName = '@douyinfe/semi-ui';
|
|
154
|
+
const files = await fetchDirectoryList(packageName, version, 'lib');
|
|
155
|
+
if (!files || 0 === files.length) return [];
|
|
156
|
+
const componentSet = new Set();
|
|
157
|
+
for (const file of files){
|
|
158
|
+
const path = file.path;
|
|
159
|
+
const pathWithoutLib = path.replace(/^\/lib\//, '').replace(/^lib\//, '');
|
|
160
|
+
const parts = pathWithoutLib.split('/');
|
|
161
|
+
if (parts.length >= 2 && ('cjs' === parts[0] || 'es' === parts[0])) {
|
|
162
|
+
const componentName = parts[1];
|
|
163
|
+
if (componentName && 'lib' !== componentName) componentSet.add(componentName.toLowerCase());
|
|
164
|
+
} else if (parts.length >= 1) {
|
|
165
|
+
const componentName = parts[0];
|
|
166
|
+
if (componentName && 'lib' !== componentName && 'cjs' !== componentName && 'es' !== componentName) componentSet.add(componentName.toLowerCase());
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return Array.from(componentSet).sort();
|
|
170
|
+
}
|
|
152
171
|
const fetch_file_content_UNPKG_BASE_URL = 'https://unpkg.com';
|
|
153
172
|
const fetch_file_content_NPMMIRROR_BASE_URL = 'https://registry.npmmirror.com';
|
|
154
173
|
async function fetchFileContentFromSource(baseUrl, packageName, version, filePath, isNpmMirror = false) {
|
|
@@ -181,49 +200,7 @@ async function fetchFileContent(packageName, version, filePath) {
|
|
|
181
200
|
for (const result of results)if ('rejected' === result.status) errors.push(result.reason instanceof Error ? result.reason : new Error(String(result.reason)));
|
|
182
201
|
throw new Error(`所有数据源都失败了: ${errors.map((e)=>e.message).join('; ')}`);
|
|
183
202
|
}
|
|
184
|
-
async function
|
|
185
|
-
const packageName = '@douyinfe/semi-ui';
|
|
186
|
-
const files = await fetchDirectoryList(packageName, version, 'lib');
|
|
187
|
-
if (!files || 0 === files.length) return [];
|
|
188
|
-
const componentSet = new Set();
|
|
189
|
-
for (const file of files){
|
|
190
|
-
const path = file.path;
|
|
191
|
-
const pathWithoutLib = path.replace(/^\/lib\//, '').replace(/^lib\//, '');
|
|
192
|
-
const parts = pathWithoutLib.split('/');
|
|
193
|
-
if (parts.length >= 2 && ('cjs' === parts[0] || 'es' === parts[0])) {
|
|
194
|
-
const componentName = parts[1];
|
|
195
|
-
if (componentName && 'lib' !== componentName) componentSet.add(componentName.toLowerCase());
|
|
196
|
-
} else if (parts.length >= 1) {
|
|
197
|
-
const componentName = parts[0];
|
|
198
|
-
if (componentName && 'lib' !== componentName && 'cjs' !== componentName && 'es' !== componentName) componentSet.add(componentName.toLowerCase());
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
return Array.from(componentSet).sort();
|
|
202
|
-
}
|
|
203
|
-
const getSemiDocumentTool = {
|
|
204
|
-
name: 'get_semi_document',
|
|
205
|
-
description: '获取 Semi Design 组件文档或组件列表',
|
|
206
|
-
inputSchema: {
|
|
207
|
-
type: 'object',
|
|
208
|
-
properties: {
|
|
209
|
-
componentName: {
|
|
210
|
-
type: 'string',
|
|
211
|
-
description: '组件名称,例如 Button、Input 等。如果不提供,则返回组件列表'
|
|
212
|
-
},
|
|
213
|
-
version: {
|
|
214
|
-
type: 'string',
|
|
215
|
-
description: '版本号,例如 2.89.1。如果不提供,默认使用 latest'
|
|
216
|
-
},
|
|
217
|
-
get_path: {
|
|
218
|
-
type: 'boolean',
|
|
219
|
-
description: '如果为 true,将文档写入操作系统临时目录并返回路径,而不是在响应中返回文档内容。默认为 false',
|
|
220
|
-
default: false
|
|
221
|
-
}
|
|
222
|
-
},
|
|
223
|
-
required: []
|
|
224
|
-
}
|
|
225
|
-
};
|
|
226
|
-
async function getComponentDocuments(componentName, version) {
|
|
203
|
+
async function getComponentDocuments(componentName, version = 'latest') {
|
|
227
204
|
const packageName = '@douyinfe/semi-ui';
|
|
228
205
|
const componentNameLower = componentName.toLowerCase();
|
|
229
206
|
const contentFiles = await fetchDirectoryList(packageName, version, 'content');
|
|
@@ -270,6 +247,29 @@ async function getComponentDocuments(componentName, version) {
|
|
|
270
247
|
documents: documents.sort((a, b)=>a.name.localeCompare(b.name))
|
|
271
248
|
};
|
|
272
249
|
}
|
|
250
|
+
const getSemiDocumentTool = {
|
|
251
|
+
name: 'get_semi_document',
|
|
252
|
+
description: '获取 Semi Design 组件文档或组件列表',
|
|
253
|
+
inputSchema: {
|
|
254
|
+
type: 'object',
|
|
255
|
+
properties: {
|
|
256
|
+
componentName: {
|
|
257
|
+
type: 'string',
|
|
258
|
+
description: '组件名称,例如 Button、Input 等。如果不提供,则返回组件列表'
|
|
259
|
+
},
|
|
260
|
+
version: {
|
|
261
|
+
type: 'string',
|
|
262
|
+
description: '版本号,例如 2.89.1。如果不提供,默认使用 latest'
|
|
263
|
+
},
|
|
264
|
+
get_path: {
|
|
265
|
+
type: 'boolean',
|
|
266
|
+
description: '如果为 true,将文档写入操作系统临时目录并返回路径,而不是在响应中返回文档内容。默认为 false',
|
|
267
|
+
default: false
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
required: []
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
273
|
async function handleGetSemiDocument(args) {
|
|
274
274
|
const componentName = args?.componentName;
|
|
275
275
|
const version = args?.version || 'latest';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ComponentDocument {
|
|
2
|
+
name: string;
|
|
3
|
+
path: string;
|
|
4
|
+
content: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ComponentDocumentsResult {
|
|
7
|
+
category: string;
|
|
8
|
+
documents: ComponentDocument[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 获取组件文档内容(从 content 文件夹)
|
|
12
|
+
* content 文件夹结构:content/{category}/{componentName}/index.md, index-en-US.md
|
|
13
|
+
* unpkg 返回的是扁平的文件列表,需要从文件路径中提取信息
|
|
14
|
+
*
|
|
15
|
+
* 这个函数可以在浏览器和 Node.js 环境中运行
|
|
16
|
+
*/
|
|
17
|
+
export declare function getComponentDocuments(componentName: string, version?: string): Promise<ComponentDocumentsResult | null>;
|
package/package.json
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@douyinfe/semi-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Semi Design MCP Server - Model Context Protocol server for Semi Design components and documentation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/browser.js",
|
|
8
|
+
"browser": "./dist/browser.js",
|
|
7
9
|
"bin": {
|
|
8
10
|
"semi-mcp": "./dist/index.js"
|
|
9
11
|
},
|
|
@@ -11,6 +13,16 @@
|
|
|
11
13
|
".": {
|
|
12
14
|
"types": "./dist/index.d.ts",
|
|
13
15
|
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./browser": {
|
|
18
|
+
"types": "./dist/browser.d.ts",
|
|
19
|
+
"browser": "./dist/browser.js",
|
|
20
|
+
"import": "./dist/browser.js"
|
|
21
|
+
},
|
|
22
|
+
"./utils": {
|
|
23
|
+
"types": "./dist/browser.d.ts",
|
|
24
|
+
"browser": "./dist/browser.js",
|
|
25
|
+
"import": "./dist/browser.js"
|
|
14
26
|
}
|
|
15
27
|
},
|
|
16
28
|
"types": "./dist/index.d.ts",
|
|
@@ -20,6 +32,7 @@
|
|
|
20
32
|
"engines": {
|
|
21
33
|
"node": ">=18.0.0"
|
|
22
34
|
},
|
|
35
|
+
"sideEffects": false,
|
|
23
36
|
"keywords": [
|
|
24
37
|
"semi",
|
|
25
38
|
"semi-design",
|