item-wms-public-api-tool 2.0.6 → 2.0.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/AI_INTEGRATION_GUIDE.md +13 -13
- package/HELP.md +14 -14
- package/README.md +5 -5
- package/api/openapi.apifox.yaml +3652 -4045
- package/dist/openapi-tools.d.ts.map +1 -1
- package/dist/openapi-tools.js +24 -6
- package/dist/openapi-tools.js.map +1 -1
- package/llms.txt +2 -2
- package/mcp.json +139 -139
- package/openapi.yaml +0 -307
- package/package.json +1 -1
- package/scripts/sync-openapi.js +47 -6
- package/src/openapi-tools.ts +23 -6
- package/test-ai-integration.js +2 -2
package/package.json
CHANGED
package/scripts/sync-openapi.js
CHANGED
|
@@ -32,9 +32,22 @@ function isJsonLike(raw) {
|
|
|
32
32
|
return trimmed.startsWith('{') || trimmed.startsWith('[');
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
function normalizeToolName(
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
function normalizeToolName(pathName, prefix) {
|
|
36
|
+
let trimmedPath = pathName;
|
|
37
|
+
if (prefix) {
|
|
38
|
+
const normalizedPrefix = prefix.startsWith('/') ? prefix : `/${prefix}`;
|
|
39
|
+
const prefixWithSlash = normalizedPrefix.endsWith('/') ? normalizedPrefix : `${normalizedPrefix}/`;
|
|
40
|
+
if (trimmedPath.startsWith(prefixWithSlash)) {
|
|
41
|
+
trimmedPath = trimmedPath.slice(prefixWithSlash.length);
|
|
42
|
+
} else if (trimmedPath.startsWith(normalizedPrefix)) {
|
|
43
|
+
trimmedPath = trimmedPath.slice(normalizedPrefix.length);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (!trimmedPath) {
|
|
47
|
+
trimmedPath = pathName;
|
|
48
|
+
}
|
|
49
|
+
const normalizedPath = trimmedPath.replace(/[^a-zA-Z0-9]+/g, '_').replace(/^_+|_+$/g, '');
|
|
50
|
+
return normalizedPath.toLowerCase();
|
|
38
51
|
}
|
|
39
52
|
|
|
40
53
|
function fetchText(url, redirects = 0) {
|
|
@@ -70,6 +83,27 @@ function ensureDir(dirPath) {
|
|
|
70
83
|
}
|
|
71
84
|
}
|
|
72
85
|
|
|
86
|
+
function stripDefaultParamRequired(node) {
|
|
87
|
+
if (!node || typeof node !== 'object') {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (Array.isArray(node)) {
|
|
91
|
+
node.forEach(stripDefaultParamRequired);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (Array.isArray(node.required)) {
|
|
95
|
+
const next = node.required.filter((key) => !DEFAULT_PARAM_KEYS.includes(key));
|
|
96
|
+
if (next.length > 0) {
|
|
97
|
+
node.required = next;
|
|
98
|
+
} else {
|
|
99
|
+
delete node.required;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
for (const value of Object.values(node)) {
|
|
103
|
+
stripDefaultParamRequired(value);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
73
107
|
function parseOpenApi(raw) {
|
|
74
108
|
if (!raw || !raw.trim()) {
|
|
75
109
|
throw new Error('OpenAPI content is empty.');
|
|
@@ -215,6 +249,7 @@ function buildInputSchema(operation, parameters, components) {
|
|
|
215
249
|
|
|
216
250
|
function buildTools(openapi) {
|
|
217
251
|
const tools = [];
|
|
252
|
+
const usedNames = new Set();
|
|
218
253
|
const operations = openapi.paths || {};
|
|
219
254
|
for (const [pathName, pathItem] of Object.entries(operations)) {
|
|
220
255
|
if (PATH_PREFIX && !pathName.startsWith(PATH_PREFIX)) {
|
|
@@ -226,13 +261,18 @@ function buildTools(openapi) {
|
|
|
226
261
|
if (!operation) {
|
|
227
262
|
continue;
|
|
228
263
|
}
|
|
229
|
-
const baseName = normalizeToolName(
|
|
264
|
+
const baseName = normalizeToolName(pathName, PATH_PREFIX);
|
|
230
265
|
let name = baseName;
|
|
266
|
+
const methodSuffix = method.toLowerCase();
|
|
267
|
+
if (usedNames.has(name)) {
|
|
268
|
+
name = `${baseName}_${methodSuffix}`;
|
|
269
|
+
}
|
|
231
270
|
let counter = 2;
|
|
232
|
-
while (
|
|
233
|
-
name = `${baseName}_${counter}`;
|
|
271
|
+
while (usedNames.has(name)) {
|
|
272
|
+
name = `${baseName}_${methodSuffix}_${counter}`;
|
|
234
273
|
counter += 1;
|
|
235
274
|
}
|
|
275
|
+
usedNames.add(name);
|
|
236
276
|
const parameters = [
|
|
237
277
|
...commonParams,
|
|
238
278
|
...(Array.isArray(operation.parameters) ? operation.parameters : [])
|
|
@@ -259,6 +299,7 @@ async function main() {
|
|
|
259
299
|
fs.writeFileSync(SNAPSHOT_PATH, raw.endsWith('\n') ? raw : `${raw}\n`);
|
|
260
300
|
|
|
261
301
|
const openapi = parseOpenApi(raw);
|
|
302
|
+
stripDefaultParamRequired(openapi);
|
|
262
303
|
if (!openapi || !openapi.paths) {
|
|
263
304
|
throw new Error('Invalid OpenAPI content: missing "paths".');
|
|
264
305
|
}
|
package/src/openapi-tools.ts
CHANGED
|
@@ -107,9 +107,22 @@ function applyDefaultParams(
|
|
|
107
107
|
return nextArgs;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
function normalizeToolName(
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
function normalizeToolName(pathName: string, prefix?: string): string {
|
|
111
|
+
let trimmedPath = pathName;
|
|
112
|
+
if (prefix) {
|
|
113
|
+
const normalizedPrefix = prefix.startsWith('/') ? prefix : `/${prefix}`;
|
|
114
|
+
const prefixWithSlash = normalizedPrefix.endsWith('/') ? normalizedPrefix : `${normalizedPrefix}/`;
|
|
115
|
+
if (trimmedPath.startsWith(prefixWithSlash)) {
|
|
116
|
+
trimmedPath = trimmedPath.slice(prefixWithSlash.length);
|
|
117
|
+
} else if (trimmedPath.startsWith(normalizedPrefix)) {
|
|
118
|
+
trimmedPath = trimmedPath.slice(normalizedPrefix.length);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (!trimmedPath) {
|
|
122
|
+
trimmedPath = pathName;
|
|
123
|
+
}
|
|
124
|
+
const normalizedPath = trimmedPath.replace(/[^a-zA-Z0-9]+/g, '_').replace(/^_+|_+$/g, '');
|
|
125
|
+
return normalizedPath.toLowerCase();
|
|
113
126
|
}
|
|
114
127
|
|
|
115
128
|
function mergeSchema(base: Record<string, any>, extra?: Record<string, any>): Record<string, any> {
|
|
@@ -264,7 +277,7 @@ export function buildOpenApiIndex(spec: any, options?: { pathPrefix?: string }):
|
|
|
264
277
|
if (!operation) {
|
|
265
278
|
continue;
|
|
266
279
|
}
|
|
267
|
-
const
|
|
280
|
+
const baseName = normalizeToolName(pathName, prefix);
|
|
268
281
|
const parameters = [
|
|
269
282
|
...commonParams,
|
|
270
283
|
...(Array.isArray(operation.parameters) ? operation.parameters : [])
|
|
@@ -272,10 +285,14 @@ export function buildOpenApiIndex(spec: any, options?: { pathPrefix?: string }):
|
|
|
272
285
|
const description = operation.summary || operation.description || `${method.toUpperCase()} ${pathName}`;
|
|
273
286
|
const inputSchema = buildInputSchema(operation, parameters, spec.components);
|
|
274
287
|
|
|
275
|
-
let finalName =
|
|
288
|
+
let finalName = baseName;
|
|
289
|
+
const methodSuffix = method.toLowerCase();
|
|
290
|
+
if (operations[finalName]) {
|
|
291
|
+
finalName = `${baseName}_${methodSuffix}`;
|
|
292
|
+
}
|
|
276
293
|
let counter = 2;
|
|
277
294
|
while (operations[finalName]) {
|
|
278
|
-
finalName = `${
|
|
295
|
+
finalName = `${baseName}_${methodSuffix}_${counter}`;
|
|
279
296
|
counter += 1;
|
|
280
297
|
}
|
|
281
298
|
|
package/test-ai-integration.js
CHANGED
|
@@ -101,11 +101,11 @@ console.log(' // AI工具代码示例');
|
|
|
101
101
|
console.log(' const mcpConfig = JSON.parse(fs.readFileSync("mcp.json", "utf8"));');
|
|
102
102
|
console.log(' ');
|
|
103
103
|
console.log(' // 发现工具');
|
|
104
|
-
console.log(' const loginTool = mcpConfig.tools.find(tool => tool.name === "
|
|
104
|
+
console.log(' const loginTool = mcpConfig.tools.find(tool => tool.name === "user_login");');
|
|
105
105
|
console.log(' ');
|
|
106
106
|
console.log(' // 调用工具');
|
|
107
107
|
console.log(' const result = await executeMCPCommand(');
|
|
108
|
-
console.log(' JSON.stringify({ jsonrpc: "2.0", id: 1, method: "tools/call", params: { name: "
|
|
108
|
+
console.log(' JSON.stringify({ jsonrpc: "2.0", id: 1, method: "tools/call", params: { name: "user_login", arguments: { username: "testuser", password: "testpass" }, options: { baseUrl: "https://wms-staging.item.com/api/public" } } })');
|
|
109
109
|
console.log(' );');
|
|
110
110
|
console.log(' ');
|
|
111
111
|
console.log(' // 解析结果');
|