fastmcp 4.24.4 → 4.24.5
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/FastMCP.cjs +2 -2
- package/dist/FastMCP.js +1 -1
- package/dist/{chunk-XPGMRMMN.cjs → chunk-P56ABHAK.cjs} +10 -5
- package/dist/chunk-P56ABHAK.cjs.map +1 -0
- package/dist/{chunk-D2CVYAA5.js → chunk-UYV7MFKA.js} +10 -5
- package/dist/chunk-UYV7MFKA.js.map +1 -0
- package/dist/edge/index.cjs +12 -4
- package/dist/edge/index.cjs.map +1 -1
- package/dist/edge/index.js +12 -4
- package/dist/edge/index.js.map +1 -1
- package/dist/examples/custom-routes.cjs +2 -2
- package/dist/examples/custom-routes.js +1 -1
- package/dist/openapi/index.cjs +631 -534
- package/dist/openapi/index.cjs.map +1 -1
- package/dist/openapi/index.js +626 -529
- package/dist/openapi/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-D2CVYAA5.js.map +0 -1
- package/dist/chunk-XPGMRMMN.cjs.map +0 -1
package/dist/openapi/index.cjs
CHANGED
|
@@ -2,630 +2,727 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkP56ABHAKcjs = require('../chunk-P56ABHAK.cjs');
|
|
6
6
|
require('../chunk-BV4PWTT6.cjs');
|
|
7
7
|
require('../chunk-6TDYSPLC.cjs');
|
|
8
8
|
|
|
9
9
|
// src/openapi/loadSpec.ts
|
|
10
10
|
var _swaggerparser = require('@apidevtools/swagger-parser'); var _swaggerparser2 = _interopRequireDefault(_swaggerparser);
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
|
|
12
|
+
// src/openapi/schemas.ts
|
|
13
|
+
var SCHEMA_MAP_KEYS = /* @__PURE__ */ new Set([
|
|
14
|
+
"$defs",
|
|
15
|
+
"definitions",
|
|
16
|
+
"dependentSchemas",
|
|
17
|
+
"patternProperties",
|
|
18
|
+
"properties"
|
|
19
|
+
]);
|
|
20
|
+
var DATA_KEYS = /* @__PURE__ */ new Set([
|
|
21
|
+
"const",
|
|
22
|
+
"default",
|
|
23
|
+
"enum",
|
|
24
|
+
"example",
|
|
25
|
+
"examples"
|
|
26
|
+
]);
|
|
27
|
+
var STRIP_KEYS = /* @__PURE__ */ new Set(["example", "examples"]);
|
|
28
|
+
function buildFlatSchema(route, sharedDefs) {
|
|
29
|
+
const byName = /* @__PURE__ */ new Map();
|
|
30
|
+
for (const param of route.parameters) {
|
|
31
|
+
const list = _nullishCoalesce(byName.get(param.name), () => ( []));
|
|
32
|
+
list.push(param);
|
|
33
|
+
byName.set(param.name, list);
|
|
34
|
+
}
|
|
35
|
+
const {
|
|
36
|
+
bodyEncoding,
|
|
37
|
+
properties: bodyProperties,
|
|
38
|
+
unsupportedBodyContentType,
|
|
39
|
+
wholeBodyKey
|
|
40
|
+
} = extractBodyProperties(
|
|
41
|
+
route.method === "get" ? void 0 : route.requestBody,
|
|
42
|
+
sharedDefs
|
|
14
43
|
);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
44
|
+
const properties = /* @__PURE__ */ Object.create(null);
|
|
45
|
+
const required = [];
|
|
46
|
+
const parameterMap = /* @__PURE__ */ Object.create(null);
|
|
47
|
+
const used = new Set(bodyProperties.keys());
|
|
48
|
+
for (const [name, occurrences] of byName) {
|
|
49
|
+
if (occurrences.length === 1 && !bodyProperties.has(name)) {
|
|
50
|
+
used.add(name);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const allocateAlias = (base) => {
|
|
54
|
+
let key = base;
|
|
55
|
+
let suffix = 1;
|
|
56
|
+
while (used.has(key)) {
|
|
57
|
+
suffix += 1;
|
|
58
|
+
key = `${base}_${suffix}`;
|
|
59
|
+
}
|
|
60
|
+
used.add(key);
|
|
61
|
+
return key;
|
|
62
|
+
};
|
|
63
|
+
for (const [name, occurrences] of byName) {
|
|
64
|
+
const collides = name === "__proto__" || occurrences.length > 1 || bodyProperties.has(name);
|
|
65
|
+
for (const param of occurrences) {
|
|
66
|
+
const base = collides ? `${name}__${param.in}` : name;
|
|
67
|
+
const key = collides ? allocateAlias(base) : name;
|
|
68
|
+
properties[key] = rewriteComponentRefs(
|
|
69
|
+
_nullishCoalesce(param.schema, () => ( { type: "string" }))
|
|
70
|
+
);
|
|
71
|
+
parameterMap[key] = {
|
|
72
|
+
allowReserved: param.allowReserved,
|
|
73
|
+
explode: param.explode,
|
|
74
|
+
in: param.in,
|
|
75
|
+
name,
|
|
76
|
+
style: param.style
|
|
77
|
+
};
|
|
78
|
+
if (param.in === "path" || param.required) {
|
|
79
|
+
required.push(key);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
for (const [name, { required: isRequired, schema }] of bodyProperties) {
|
|
84
|
+
const key = name === "__proto__" ? allocateAlias(`${name}__body`) : name;
|
|
85
|
+
properties[key] = rewriteComponentRefs(schema);
|
|
86
|
+
parameterMap[key] = { in: "body", name };
|
|
87
|
+
if (isRequired) {
|
|
88
|
+
required.push(key);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const flatSchema = {
|
|
92
|
+
additionalProperties: false,
|
|
93
|
+
properties,
|
|
94
|
+
type: "object",
|
|
95
|
+
...required.length > 0 ? { required } : {}
|
|
96
|
+
};
|
|
97
|
+
const usedDefs = sharedDefs && filterReferencedDefs(properties, sharedDefs);
|
|
98
|
+
if (usedDefs) {
|
|
99
|
+
flatSchema.$defs = usedDefs;
|
|
19
100
|
}
|
|
20
101
|
return {
|
|
21
|
-
|
|
22
|
-
|
|
102
|
+
bodyEncoding,
|
|
103
|
+
flatSchema,
|
|
104
|
+
parameterMap,
|
|
105
|
+
unsupportedBodyContentType,
|
|
106
|
+
wholeBodyKey
|
|
23
107
|
};
|
|
24
108
|
}
|
|
25
|
-
function
|
|
26
|
-
|
|
109
|
+
function buildSharedDefs(document) {
|
|
110
|
+
const schemas = _optionalChain([document, 'access', _ => _.components, 'optionalAccess', _2 => _2.schemas]);
|
|
111
|
+
if (!schemas || Object.keys(schemas).length === 0) {
|
|
112
|
+
return void 0;
|
|
113
|
+
}
|
|
114
|
+
return rewriteNode(schemas, "schemaMap");
|
|
27
115
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
116
|
+
var SUCCESS_STATUS_PATTERN = /^2\d\d$/;
|
|
117
|
+
var MAX_OUTPUT_SCHEMA_DEFS = 50;
|
|
118
|
+
function buildOutputSchema(route, sharedDefs) {
|
|
119
|
+
const successEntry = Object.entries(_nullishCoalesce(route.responses, () => ( {}))).find(
|
|
120
|
+
([code]) => SUCCESS_STATUS_PATTERN.test(code)
|
|
121
|
+
);
|
|
122
|
+
const declaredSchema = _optionalChain([findMediaType, 'call', _3 => _3(
|
|
123
|
+
_optionalChain([successEntry, 'optionalAccess', _4 => _4[1], 'access', _5 => _5.content]),
|
|
124
|
+
"application/json"
|
|
125
|
+
), 'optionalAccess', _6 => _6.schema]);
|
|
126
|
+
if (!declaredSchema) {
|
|
127
|
+
return void 0;
|
|
128
|
+
}
|
|
129
|
+
const schema = resolveComponentRef(declaredSchema, sharedDefs);
|
|
130
|
+
const rewritten = rewriteComponentRefs(schema, true);
|
|
131
|
+
const { type } = rewritten;
|
|
132
|
+
const isObjectShaped = type === "object" || Array.isArray(type) && type.includes("object");
|
|
133
|
+
if (!isObjectShaped) {
|
|
134
|
+
return void 0;
|
|
135
|
+
}
|
|
136
|
+
const normalized = { ...rewritten, type: "object" };
|
|
137
|
+
const usedDefs = sharedDefs && filterReferencedDefs(normalized, sharedDefs);
|
|
138
|
+
if (usedDefs && Object.keys(usedDefs).length > MAX_OUTPUT_SCHEMA_DEFS) {
|
|
139
|
+
return void 0;
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
...normalized,
|
|
143
|
+
...usedDefs ? {
|
|
144
|
+
$defs: rewriteNode(usedDefs, "schemaMap", true)
|
|
145
|
+
} : {}
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function resolveComponentRef(schema, sharedDefs) {
|
|
149
|
+
const seen = /* @__PURE__ */ new Set();
|
|
150
|
+
let current = schema;
|
|
151
|
+
let ref = current.$ref;
|
|
152
|
+
while (typeof ref === "string") {
|
|
153
|
+
const name = componentSchemaName(ref);
|
|
154
|
+
const target = name === void 0 ? void 0 : _optionalChain([sharedDefs, 'optionalAccess', _7 => _7[name]]);
|
|
155
|
+
if (name === void 0 || target === void 0 || seen.has(name)) {
|
|
156
|
+
break;
|
|
42
157
|
}
|
|
43
|
-
|
|
44
|
-
|
|
158
|
+
seen.add(name);
|
|
159
|
+
current = target;
|
|
160
|
+
ref = current.$ref;
|
|
45
161
|
}
|
|
46
|
-
return
|
|
162
|
+
return current;
|
|
47
163
|
}
|
|
48
|
-
function
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
164
|
+
function rewriteComponentRefs(value, stripExamples = false) {
|
|
165
|
+
return rewriteNode(value, "schema", stripExamples);
|
|
166
|
+
}
|
|
167
|
+
function childMode(key) {
|
|
168
|
+
if (DATA_KEYS.has(key)) {
|
|
169
|
+
return "data";
|
|
52
170
|
}
|
|
53
|
-
return
|
|
171
|
+
return SCHEMA_MAP_KEYS.has(key) ? "schemaMap" : "schema";
|
|
54
172
|
}
|
|
55
|
-
function
|
|
56
|
-
const
|
|
57
|
-
|
|
173
|
+
function componentSchemaName(ref) {
|
|
174
|
+
for (const prefix of ["#/components/schemas/", "#/$defs/"]) {
|
|
175
|
+
if (ref.startsWith(prefix)) {
|
|
176
|
+
return ref.slice(prefix.length).replaceAll("~1", "/").replaceAll("~0", "~");
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return void 0;
|
|
58
180
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
181
|
+
function extractBodyProperties(requestBody, sharedDefs) {
|
|
182
|
+
const properties = /* @__PURE__ */ new Map();
|
|
183
|
+
const content = _optionalChain([requestBody, 'optionalAccess', _8 => _8.content]);
|
|
184
|
+
if (!content) {
|
|
185
|
+
return { properties };
|
|
186
|
+
}
|
|
187
|
+
const json = findMediaType(content, "application/json");
|
|
188
|
+
const form = findMediaType(content, "application/x-www-form-urlencoded");
|
|
189
|
+
if (json === void 0 && form === void 0) {
|
|
190
|
+
const contentTypes = Object.keys(content);
|
|
191
|
+
return contentTypes.length > 0 ? { properties, unsupportedBodyContentType: contentTypes[0] } : { properties };
|
|
192
|
+
}
|
|
193
|
+
const bodyEncoding = json === void 0 ? "form" : "json";
|
|
194
|
+
const declaredSchema = bodyEncoding === "json" ? _optionalChain([json, 'optionalAccess', _9 => _9.schema]) : _optionalChain([form, 'optionalAccess', _10 => _10.schema]);
|
|
195
|
+
if (!declaredSchema) {
|
|
196
|
+
return { bodyEncoding, properties };
|
|
197
|
+
}
|
|
198
|
+
const schema = bodyEncoding === "form" ? resolveComponentRef(declaredSchema, sharedDefs) : declaredSchema;
|
|
199
|
+
const schemaProperties = schema.properties;
|
|
200
|
+
if (schema.type === "object" && schemaProperties && (bodyEncoding === "form" || schema.additionalProperties === false || Object.keys(schemaProperties).length > 0)) {
|
|
201
|
+
const requiredNames = new Set(
|
|
202
|
+
_nullishCoalesce(schema.required, () => ( []))
|
|
203
|
+
);
|
|
204
|
+
for (const [name, propertySchema] of Object.entries(schemaProperties)) {
|
|
205
|
+
properties.set(name, {
|
|
206
|
+
required: requiredNames.has(name),
|
|
207
|
+
schema: propertySchema
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
return { bodyEncoding, properties };
|
|
211
|
+
}
|
|
212
|
+
if (bodyEncoding === "form") {
|
|
213
|
+
return {
|
|
214
|
+
properties,
|
|
215
|
+
unsupportedBodyContentType: "application/x-www-form-urlencoded"
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
properties.set("body", {
|
|
219
|
+
required: _nullishCoalesce(_optionalChain([requestBody, 'optionalAccess', _11 => _11.required]), () => ( false)),
|
|
220
|
+
schema
|
|
221
|
+
});
|
|
222
|
+
return { bodyEncoding, properties, wholeBodyKey: "body" };
|
|
223
|
+
}
|
|
224
|
+
function filterReferencedDefs(node, allDefs) {
|
|
225
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
226
|
+
const stack = [node];
|
|
227
|
+
while (stack.length > 0) {
|
|
228
|
+
const current = stack.pop();
|
|
229
|
+
if (Array.isArray(current)) {
|
|
230
|
+
stack.push(...current);
|
|
74
231
|
continue;
|
|
75
232
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
break;
|
|
89
|
-
case "path":
|
|
90
|
-
pathParams[mapping.name] = encodePathValue(
|
|
91
|
-
value,
|
|
92
|
-
mapping.style,
|
|
93
|
-
mapping.explode
|
|
94
|
-
);
|
|
95
|
-
break;
|
|
96
|
-
case "query": {
|
|
97
|
-
const query = new URLSearchParams();
|
|
98
|
-
appendQueryValue(
|
|
99
|
-
query,
|
|
100
|
-
mapping.name,
|
|
101
|
-
mapping.style,
|
|
102
|
-
value,
|
|
103
|
-
mapping.explode
|
|
104
|
-
);
|
|
105
|
-
if (query.size > 0) {
|
|
106
|
-
queryParts.push(serializeQuery(query, mapping.allowReserved));
|
|
233
|
+
if (!current || typeof current !== "object") {
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
for (const [key, value] of Object.entries(
|
|
237
|
+
current
|
|
238
|
+
)) {
|
|
239
|
+
if (key === "$ref" && typeof value === "string" && value.startsWith("#/$defs/")) {
|
|
240
|
+
const [first = ""] = value.slice("#/$defs/".length).split("/");
|
|
241
|
+
const name = first.replaceAll("~1", "/").replaceAll("~0", "~");
|
|
242
|
+
if (allDefs[name] && !referenced.has(name)) {
|
|
243
|
+
referenced.add(name);
|
|
244
|
+
stack.push(allDefs[name]);
|
|
107
245
|
}
|
|
108
|
-
|
|
246
|
+
continue;
|
|
109
247
|
}
|
|
248
|
+
stack.push(value);
|
|
110
249
|
}
|
|
111
250
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
path = path.replaceAll(`{${name}}`, value);
|
|
251
|
+
if (referenced.size === 0) {
|
|
252
|
+
return void 0;
|
|
115
253
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
if (options.bodyEncoding === "form") {
|
|
124
|
-
if (!headers.has("content-type")) {
|
|
125
|
-
headers.set("content-type", "application/x-www-form-urlencoded");
|
|
126
|
-
}
|
|
127
|
-
body = encodeFormBody(payload);
|
|
128
|
-
} else {
|
|
129
|
-
if (!headers.has("content-type")) {
|
|
130
|
-
headers.set("content-type", "application/json");
|
|
131
|
-
}
|
|
132
|
-
body = JSON.stringify(payload);
|
|
133
|
-
}
|
|
254
|
+
return Object.fromEntries(
|
|
255
|
+
[...referenced].map((name) => [name, allDefs[name]])
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
function findMediaType(content, mediaType) {
|
|
259
|
+
if (!content) {
|
|
260
|
+
return void 0;
|
|
134
261
|
}
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
if (
|
|
143
|
-
|
|
144
|
-
`${options.route.method.toUpperCase()} ${path} failed with ${response.status}: ${text.slice(0, 2e3)}`
|
|
145
|
-
);
|
|
262
|
+
const key = Object.hasOwn(content, mediaType) ? mediaType : Object.keys(content).find(
|
|
263
|
+
(candidate) => candidate.split(";")[0].trim().toLowerCase() === mediaType
|
|
264
|
+
);
|
|
265
|
+
return key === void 0 ? void 0 : content[key];
|
|
266
|
+
}
|
|
267
|
+
function normalizeExclusiveBound(schema, exclusiveKey, boundKey) {
|
|
268
|
+
const { [exclusiveKey]: exclusive, ...rest } = schema;
|
|
269
|
+
if (typeof exclusive !== "boolean") {
|
|
270
|
+
return schema;
|
|
146
271
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
try {
|
|
150
|
-
const json = JSON.parse(text);
|
|
151
|
-
return { json, text: JSON.stringify(json, null, 2) };
|
|
152
|
-
} catch (e) {
|
|
153
|
-
return { text };
|
|
154
|
-
}
|
|
272
|
+
if (!exclusive || typeof rest[boundKey] !== "number") {
|
|
273
|
+
return rest;
|
|
155
274
|
}
|
|
156
|
-
|
|
275
|
+
const { [boundKey]: bound, ...unbounded } = rest;
|
|
276
|
+
return { ...unbounded, [exclusiveKey]: bound };
|
|
157
277
|
}
|
|
158
|
-
function
|
|
159
|
-
|
|
160
|
-
|
|
278
|
+
function normalizeExclusiveBounds(schema) {
|
|
279
|
+
return normalizeExclusiveBound(
|
|
280
|
+
normalizeExclusiveBound(schema, "exclusiveMinimum", "minimum"),
|
|
281
|
+
"exclusiveMaximum",
|
|
282
|
+
"maximum"
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
function normalizeNullable(schema) {
|
|
286
|
+
if (!("nullable" in schema)) {
|
|
287
|
+
return schema;
|
|
161
288
|
}
|
|
162
|
-
const
|
|
163
|
-
if (
|
|
164
|
-
|
|
165
|
-
"The OpenAPI document has no `servers` entry. Pass `baseUrl` to fromOpenAPI() explicitly."
|
|
166
|
-
);
|
|
289
|
+
const { nullable, ...rest } = schema;
|
|
290
|
+
if (nullable !== true) {
|
|
291
|
+
return rest;
|
|
167
292
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
293
|
+
const { type } = rest;
|
|
294
|
+
if (typeof type === "string") {
|
|
295
|
+
return { ...rest, type: [type, "null"] };
|
|
171
296
|
}
|
|
172
|
-
|
|
173
|
-
return new
|
|
174
|
-
} catch (e2) {
|
|
175
|
-
if (!origin) {
|
|
176
|
-
throw new Error(
|
|
177
|
-
`The OpenAPI document's servers[0].url ("${url}") is relative, and the spec was not loaded from an http(s) URL, so it cannot be resolved to an absolute address. Pass \`baseUrl\` to fromOpenAPI() explicitly.`
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
return new URL(url, origin).toString().replace(/\/$/, "");
|
|
297
|
+
if (Array.isArray(type)) {
|
|
298
|
+
return { ...rest, type: [.../* @__PURE__ */ new Set(["null", ...type])] };
|
|
181
299
|
}
|
|
300
|
+
return rest;
|
|
182
301
|
}
|
|
183
|
-
function
|
|
184
|
-
if (
|
|
185
|
-
|
|
186
|
-
if (item !== null && typeof item === "object") {
|
|
187
|
-
appendBracketPairs(params, `${key}[]`, item);
|
|
188
|
-
} else {
|
|
189
|
-
params.append(key, String(item));
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
if (value !== null && typeof value === "object") {
|
|
195
|
-
for (const [subKey, subValue] of Object.entries(
|
|
196
|
-
value
|
|
197
|
-
)) {
|
|
198
|
-
if (subValue !== void 0) {
|
|
199
|
-
appendBracketPairs(params, `${key}[${subKey}]`, subValue);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
return;
|
|
302
|
+
function rewriteNode(value, mode, stripExamples = false) {
|
|
303
|
+
if (mode === "data") {
|
|
304
|
+
return value;
|
|
203
305
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
function appendQueryValue(query, name, style, value, explode) {
|
|
207
|
-
if (style === "deepObject") {
|
|
208
|
-
appendBracketPairs(query, name, value);
|
|
209
|
-
return;
|
|
306
|
+
if (Array.isArray(value)) {
|
|
307
|
+
return value.map((item) => rewriteNode(item, "schema", stripExamples));
|
|
210
308
|
}
|
|
211
|
-
if (
|
|
212
|
-
|
|
213
|
-
const separator = style === "spaceDelimited" ? " " : "|";
|
|
214
|
-
query.append(name, items.map(String).join(separator));
|
|
215
|
-
return;
|
|
309
|
+
if (!value || typeof value !== "object") {
|
|
310
|
+
return value;
|
|
216
311
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
name,
|
|
223
|
-
entries.flatMap(([key, item]) => [key, String(item)]).join(",")
|
|
224
|
-
);
|
|
225
|
-
}
|
|
226
|
-
} else {
|
|
227
|
-
for (const [key, item] of entries) {
|
|
228
|
-
query.append(key, String(item));
|
|
229
|
-
}
|
|
312
|
+
const entries = Object.entries(value).filter(
|
|
313
|
+
([key]) => !stripExamples || mode !== "schema" || !STRIP_KEYS.has(key)
|
|
314
|
+
).map(([key, entryValue]) => {
|
|
315
|
+
if (mode === "schemaMap") {
|
|
316
|
+
return [key, rewriteNode(entryValue, "schema", stripExamples)];
|
|
230
317
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
318
|
+
if (key === "$ref" && typeof entryValue === "string" && entryValue.startsWith("#/components/schemas/")) {
|
|
319
|
+
return [key, entryValue.replace("#/components/schemas/", "#/$defs/")];
|
|
320
|
+
}
|
|
321
|
+
return [key, rewriteNode(entryValue, childMode(key), stripExamples)];
|
|
322
|
+
});
|
|
323
|
+
const rewritten = Object.fromEntries(entries);
|
|
324
|
+
return mode === "schemaMap" ? rewritten : normalizeExclusiveBounds(normalizeNullable(rewritten));
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// src/openapi/loadSpec.ts
|
|
328
|
+
async function loadSpec(spec) {
|
|
329
|
+
const document = await _swaggerparser2.default.bundle(
|
|
330
|
+
spec
|
|
331
|
+
);
|
|
332
|
+
if (!_optionalChain([document, 'access', _12 => _12.openapi, 'optionalAccess', _13 => _13.startsWith, 'call', _14 => _14("3.")])) {
|
|
333
|
+
throw new Error(
|
|
334
|
+
`fromOpenAPI only supports OpenAPI 3.x documents (found ${_nullishCoalesce(_nullishCoalesce(document.openapi, () => ( document.swagger)), () => ( "an unrecognized version"))}). Swagger 2.0 is not supported.`
|
|
335
|
+
);
|
|
239
336
|
}
|
|
337
|
+
resolveBundledPointerRefs(document);
|
|
338
|
+
return {
|
|
339
|
+
document,
|
|
340
|
+
origin: typeof spec === "string" && isHttpUrl(spec) ? spec : void 0
|
|
341
|
+
};
|
|
240
342
|
}
|
|
241
|
-
function
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
343
|
+
function isHttpUrl(value) {
|
|
344
|
+
return /^https?:\/\//i.test(value);
|
|
345
|
+
}
|
|
346
|
+
function resolveBundledPointerRefs(document) {
|
|
347
|
+
const hoisted = /* @__PURE__ */ new Map();
|
|
348
|
+
let counter = 0;
|
|
349
|
+
const resolvePointer = (pointer) => {
|
|
350
|
+
let segments;
|
|
351
|
+
try {
|
|
352
|
+
segments = pointer.slice(2).split("/").map(
|
|
353
|
+
(segment) => decodeURIComponent(
|
|
354
|
+
segment.replaceAll("~1", "/").replaceAll("~0", "~")
|
|
355
|
+
)
|
|
247
356
|
);
|
|
357
|
+
} catch (e) {
|
|
358
|
+
return void 0;
|
|
248
359
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
return encodePathComponent(text);
|
|
360
|
+
let node = document;
|
|
361
|
+
for (const segment of segments) {
|
|
362
|
+
if (!node || typeof node !== "object" || !Object.hasOwn(node, segment)) {
|
|
363
|
+
return void 0;
|
|
364
|
+
}
|
|
365
|
+
node = node[segment];
|
|
256
366
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
367
|
+
return node;
|
|
368
|
+
};
|
|
369
|
+
const hoist = (ref) => {
|
|
370
|
+
const existing = hoisted.get(ref);
|
|
371
|
+
if (existing !== void 0) {
|
|
372
|
+
return existing;
|
|
261
373
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
))
|
|
271
|
-
|
|
272
|
-
|
|
374
|
+
const target = resolvePointer(ref);
|
|
375
|
+
if (!target || typeof target !== "object") {
|
|
376
|
+
return void 0;
|
|
377
|
+
}
|
|
378
|
+
const schemas = (document.components ??= {}).schemas ??= {};
|
|
379
|
+
let name;
|
|
380
|
+
do {
|
|
381
|
+
name = `__bundle_${counter++}`;
|
|
382
|
+
} while (Object.hasOwn(schemas, name));
|
|
383
|
+
hoisted.set(ref, name);
|
|
384
|
+
schemas[name] = target;
|
|
385
|
+
walk(target, "schema");
|
|
386
|
+
return name;
|
|
387
|
+
};
|
|
388
|
+
const rewriteRef = (record) => {
|
|
389
|
+
const ref = record.$ref;
|
|
390
|
+
if (typeof ref !== "string" || !ref.startsWith("#/") || ref.startsWith("#/components/schemas/") || ref.startsWith("#/$defs/")) {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
const name = hoist(ref);
|
|
394
|
+
if (name !== void 0) {
|
|
395
|
+
record.$ref = `#/components/schemas/${name}`;
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
const childMode2 = (key, mode) => {
|
|
399
|
+
if (mode === "schemaMap") {
|
|
400
|
+
return "schema";
|
|
401
|
+
}
|
|
402
|
+
if (mode === "schema") {
|
|
403
|
+
return SCHEMA_MAP_KEYS.has(key) ? "schemaMap" : "schema";
|
|
404
|
+
}
|
|
405
|
+
if (key === "schema") {
|
|
406
|
+
return "schema";
|
|
407
|
+
}
|
|
408
|
+
if (mode === "document" && key === "components") {
|
|
409
|
+
return "components";
|
|
410
|
+
}
|
|
411
|
+
return mode === "components" && key === "schemas" ? "schemaMap" : "document";
|
|
412
|
+
};
|
|
413
|
+
const walk = (value, mode) => {
|
|
414
|
+
if (Array.isArray(value)) {
|
|
415
|
+
for (const item of value) {
|
|
416
|
+
walk(item, mode);
|
|
273
417
|
}
|
|
274
|
-
|
|
418
|
+
return;
|
|
275
419
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
420
|
+
if (!value || typeof value !== "object") {
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
const record = value;
|
|
424
|
+
for (const [key, entryValue] of Object.entries(record)) {
|
|
425
|
+
if (mode === "schema" && key === "$ref") {
|
|
426
|
+
rewriteRef(record);
|
|
427
|
+
} else if (mode !== "schema" || !DATA_KEYS.has(key)) {
|
|
428
|
+
walk(entryValue, childMode2(key, mode));
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
walk(document, "document");
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// src/openapi/naming.ts
|
|
436
|
+
var MAX_NAME_LENGTH = 56;
|
|
437
|
+
var MAX_BASE_LENGTH = MAX_NAME_LENGTH - 5;
|
|
438
|
+
function generateNames(routes, mcpNames) {
|
|
439
|
+
const names = /* @__PURE__ */ new Map();
|
|
440
|
+
const used = /* @__PURE__ */ new Set();
|
|
441
|
+
for (const route of routes) {
|
|
442
|
+
const base = slugify(baseNameFor(route, mcpNames));
|
|
443
|
+
let candidate = base;
|
|
444
|
+
let suffix = 1;
|
|
445
|
+
while (used.has(candidate)) {
|
|
446
|
+
suffix += 1;
|
|
447
|
+
candidate = `${base}_${suffix}`;
|
|
297
448
|
}
|
|
449
|
+
used.add(candidate);
|
|
450
|
+
names.set(route, candidate);
|
|
298
451
|
}
|
|
299
|
-
return
|
|
452
|
+
return names;
|
|
300
453
|
}
|
|
301
|
-
|
|
302
|
-
if (
|
|
303
|
-
|
|
454
|
+
function baseNameFor(route, mcpNames) {
|
|
455
|
+
if (route.operationId) {
|
|
456
|
+
const override = mcpNames && Object.hasOwn(mcpNames, route.operationId) ? mcpNames[route.operationId] : void 0;
|
|
457
|
+
return _nullishCoalesce(override, () => ( route.operationId.split("__")[0]));
|
|
304
458
|
}
|
|
305
|
-
return
|
|
459
|
+
return route.summary || `${route.method}_${route.path}`;
|
|
306
460
|
}
|
|
307
|
-
function
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
return encoded;
|
|
311
|
-
}
|
|
312
|
-
return encoded.split("&").map((pair) => {
|
|
313
|
-
const [name, value] = pair.split("=");
|
|
314
|
-
const expanded = value.replace(
|
|
315
|
-
/\+|%25([\da-f]{2})|%(21|24|27|28|29|2c|2f|3a|3b|3f|40|7e)/gi,
|
|
316
|
-
(match, triple) => triple ? `%${triple}` : match === "+" ? "%20" : decodeURIComponent(match)
|
|
317
|
-
);
|
|
318
|
-
return `${name}=${expanded}`;
|
|
319
|
-
}).join("&");
|
|
461
|
+
function slugify(value) {
|
|
462
|
+
const slug = value.replace(/[^a-zA-Z0-9_]+/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").slice(0, MAX_BASE_LENGTH);
|
|
463
|
+
return slug || "operation";
|
|
320
464
|
}
|
|
321
465
|
|
|
322
|
-
// src/openapi/
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
"properties"
|
|
329
|
-
]);
|
|
330
|
-
var DATA_KEYS = /* @__PURE__ */ new Set(["const", "default", "enum", "example", "examples"]);
|
|
331
|
-
var STRIP_KEYS = /* @__PURE__ */ new Set(["example", "examples"]);
|
|
332
|
-
function buildFlatSchema(route, sharedDefs) {
|
|
333
|
-
const byName = /* @__PURE__ */ new Map();
|
|
334
|
-
for (const param of route.parameters) {
|
|
335
|
-
const list = _nullishCoalesce(byName.get(param.name), () => ( []));
|
|
336
|
-
list.push(param);
|
|
337
|
-
byName.set(param.name, list);
|
|
338
|
-
}
|
|
339
|
-
const {
|
|
340
|
-
bodyEncoding,
|
|
341
|
-
properties: bodyProperties,
|
|
342
|
-
unsupportedBodyContentType,
|
|
343
|
-
wholeBodyKey
|
|
344
|
-
} = extractBodyProperties(
|
|
345
|
-
route.method === "get" ? void 0 : route.requestBody,
|
|
346
|
-
sharedDefs
|
|
466
|
+
// src/openapi/requestBuilder.ts
|
|
467
|
+
async function executeRequest(options) {
|
|
468
|
+
const baseUrl = resolveBaseUrl(
|
|
469
|
+
options.servers,
|
|
470
|
+
options.origin,
|
|
471
|
+
options.baseUrlOverride
|
|
347
472
|
);
|
|
348
|
-
const
|
|
349
|
-
const
|
|
350
|
-
const
|
|
351
|
-
const
|
|
352
|
-
for (const [
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
const allocateAlias = (base) => {
|
|
358
|
-
let key = base;
|
|
359
|
-
let suffix = 1;
|
|
360
|
-
while (used.has(key)) {
|
|
361
|
-
suffix += 1;
|
|
362
|
-
key = `${base}_${suffix}`;
|
|
473
|
+
const pathParams = /* @__PURE__ */ Object.create(null);
|
|
474
|
+
const queryParts = [];
|
|
475
|
+
const headers = new Headers(await resolveHeaders(options.headers));
|
|
476
|
+
const bodyProps = /* @__PURE__ */ Object.create(null);
|
|
477
|
+
for (const [key, value] of Object.entries(options.args)) {
|
|
478
|
+
const mapping = options.parameterMap[key];
|
|
479
|
+
if (!mapping || value === void 0) {
|
|
480
|
+
continue;
|
|
363
481
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
482
|
+
switch (mapping.in) {
|
|
483
|
+
case "body":
|
|
484
|
+
bodyProps[mapping.name] = value;
|
|
485
|
+
break;
|
|
486
|
+
case "cookie": {
|
|
487
|
+
const pair = `${mapping.name}=${encodeCookieValue(mapping, value)}`;
|
|
488
|
+
const existing = headers.get("cookie");
|
|
489
|
+
headers.set("cookie", existing ? `${existing}; ${pair}` : pair);
|
|
490
|
+
break;
|
|
491
|
+
}
|
|
492
|
+
case "header":
|
|
493
|
+
headers.set(mapping.name, String(value));
|
|
494
|
+
break;
|
|
495
|
+
case "path":
|
|
496
|
+
pathParams[mapping.name] = encodePathValue(
|
|
497
|
+
value,
|
|
498
|
+
mapping.style,
|
|
499
|
+
mapping.explode
|
|
500
|
+
);
|
|
501
|
+
break;
|
|
502
|
+
case "query": {
|
|
503
|
+
const query = new URLSearchParams();
|
|
504
|
+
appendQueryValue(
|
|
505
|
+
query,
|
|
506
|
+
mapping.name,
|
|
507
|
+
mapping.style,
|
|
508
|
+
value,
|
|
509
|
+
mapping.explode
|
|
510
|
+
);
|
|
511
|
+
if (query.size > 0) {
|
|
512
|
+
queryParts.push(serializeQuery(query, mapping.allowReserved));
|
|
513
|
+
}
|
|
514
|
+
break;
|
|
384
515
|
}
|
|
385
516
|
}
|
|
386
517
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
518
|
+
let path = options.route.path;
|
|
519
|
+
for (const [name, value] of Object.entries(pathParams)) {
|
|
520
|
+
path = path.replaceAll(`{${name}}`, value);
|
|
521
|
+
}
|
|
522
|
+
assertNoSubstitutedDotSegments(options.route, path);
|
|
523
|
+
const url = new URL(baseUrl.replace(/\/$/, "") + path);
|
|
524
|
+
url.search = queryParts.join("&");
|
|
525
|
+
let body;
|
|
526
|
+
const requiredJsonBody = options.bodyEncoding === "json" && _optionalChain([options, 'access', _15 => _15.route, 'access', _16 => _16.requestBody, 'optionalAccess', _17 => _17.required]) === true && !options.wholeBodyKey;
|
|
527
|
+
if (Object.keys(bodyProps).length > 0 || requiredJsonBody) {
|
|
528
|
+
const payload = options.wholeBodyKey ? bodyProps[options.wholeBodyKey] : bodyProps;
|
|
529
|
+
if (options.bodyEncoding === "form") {
|
|
530
|
+
if (!headers.has("content-type")) {
|
|
531
|
+
headers.set("content-type", "application/x-www-form-urlencoded");
|
|
532
|
+
}
|
|
533
|
+
body = encodeFormBody(payload);
|
|
534
|
+
} else {
|
|
535
|
+
if (!headers.has("content-type")) {
|
|
536
|
+
headers.set("content-type", "application/json");
|
|
537
|
+
}
|
|
538
|
+
body = JSON.stringify(payload);
|
|
393
539
|
}
|
|
394
540
|
}
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
};
|
|
401
|
-
const
|
|
402
|
-
if (
|
|
403
|
-
|
|
541
|
+
const response = await options.fetchImpl(url.toString(), {
|
|
542
|
+
body,
|
|
543
|
+
headers,
|
|
544
|
+
method: options.route.method.toUpperCase(),
|
|
545
|
+
signal: options.signal
|
|
546
|
+
});
|
|
547
|
+
const text = await response.text();
|
|
548
|
+
if (!response.ok) {
|
|
549
|
+
throw new (0, _chunkP56ABHAKcjs.UserError)(
|
|
550
|
+
`${options.route.method.toUpperCase()} ${path} failed with ${response.status}: ${text.slice(0, 2e3)}`
|
|
551
|
+
);
|
|
404
552
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
}
|
|
413
|
-
function buildSharedDefs(document) {
|
|
414
|
-
const schemas = _optionalChain([document, 'access', _18 => _18.components, 'optionalAccess', _19 => _19.schemas]);
|
|
415
|
-
if (!schemas || Object.keys(schemas).length === 0) {
|
|
416
|
-
return void 0;
|
|
553
|
+
const mediaType = _optionalChain([response, 'access', _18 => _18.headers, 'access', _19 => _19.get, 'call', _20 => _20("content-type"), 'optionalAccess', _21 => _21.split, 'call', _22 => _22(";"), 'access', _23 => _23[0]]);
|
|
554
|
+
if (_optionalChain([mediaType, 'optionalAccess', _24 => _24.toLowerCase, 'call', _25 => _25(), 'access', _26 => _26.includes, 'call', _27 => _27("json")])) {
|
|
555
|
+
try {
|
|
556
|
+
const json = JSON.parse(text);
|
|
557
|
+
return { json, text: JSON.stringify(json, null, 2) };
|
|
558
|
+
} catch (e2) {
|
|
559
|
+
return { text };
|
|
560
|
+
}
|
|
417
561
|
}
|
|
418
|
-
return
|
|
562
|
+
return { text };
|
|
419
563
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
const successEntry = Object.entries(_nullishCoalesce(route.responses, () => ( {}))).find(
|
|
424
|
-
([code]) => SUCCESS_STATUS_PATTERN.test(code)
|
|
425
|
-
);
|
|
426
|
-
const declaredSchema = _optionalChain([findMediaType, 'call', _20 => _20(
|
|
427
|
-
_optionalChain([successEntry, 'optionalAccess', _21 => _21[1], 'access', _22 => _22.content]),
|
|
428
|
-
"application/json"
|
|
429
|
-
), 'optionalAccess', _23 => _23.schema]);
|
|
430
|
-
if (!declaredSchema) {
|
|
431
|
-
return void 0;
|
|
432
|
-
}
|
|
433
|
-
const schema = resolveComponentRef(declaredSchema, sharedDefs);
|
|
434
|
-
const rewritten = rewriteComponentRefs(schema, true);
|
|
435
|
-
const { type } = rewritten;
|
|
436
|
-
const isObjectShaped = type === "object" || Array.isArray(type) && type.includes("object");
|
|
437
|
-
if (!isObjectShaped) {
|
|
438
|
-
return void 0;
|
|
564
|
+
function resolveBaseUrl(servers, origin, overrideUrl) {
|
|
565
|
+
if (overrideUrl) {
|
|
566
|
+
return overrideUrl.replace(/\/$/, "");
|
|
439
567
|
}
|
|
440
|
-
const
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
568
|
+
const server = _optionalChain([servers, 'optionalAccess', _28 => _28[0]]);
|
|
569
|
+
if (!server) {
|
|
570
|
+
throw new Error(
|
|
571
|
+
"The OpenAPI document has no `servers` entry. Pass `baseUrl` to fromOpenAPI() explicitly."
|
|
572
|
+
);
|
|
444
573
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
while (typeof ref === "string") {
|
|
457
|
-
const name = componentSchemaName(ref);
|
|
458
|
-
const target = name === void 0 ? void 0 : _optionalChain([sharedDefs, 'optionalAccess', _24 => _24[name]]);
|
|
459
|
-
if (name === void 0 || target === void 0 || seen.has(name)) {
|
|
460
|
-
break;
|
|
574
|
+
let url = server.url;
|
|
575
|
+
for (const [name, variable] of Object.entries(_nullishCoalesce(server.variables, () => ( {})))) {
|
|
576
|
+
url = url.replaceAll(`{${name}}`, () => variable.default);
|
|
577
|
+
}
|
|
578
|
+
try {
|
|
579
|
+
return new URL(url).toString().replace(/\/$/, "");
|
|
580
|
+
} catch (e3) {
|
|
581
|
+
if (!origin) {
|
|
582
|
+
throw new Error(
|
|
583
|
+
`The OpenAPI document's servers[0].url ("${url}") is relative, and the spec was not loaded from an http(s) URL, so it cannot be resolved to an absolute address. Pass \`baseUrl\` to fromOpenAPI() explicitly.`
|
|
584
|
+
);
|
|
461
585
|
}
|
|
462
|
-
|
|
463
|
-
current = target;
|
|
464
|
-
ref = current.$ref;
|
|
586
|
+
return new URL(url, origin).toString().replace(/\/$/, "");
|
|
465
587
|
}
|
|
466
|
-
return current;
|
|
467
588
|
}
|
|
468
|
-
function
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
589
|
+
function appendBracketPairs(params, key, value) {
|
|
590
|
+
if (Array.isArray(value)) {
|
|
591
|
+
for (const item of value) {
|
|
592
|
+
if (item !== null && typeof item === "object") {
|
|
593
|
+
appendBracketPairs(params, `${key}[]`, item);
|
|
594
|
+
} else {
|
|
595
|
+
params.append(key, String(item));
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
return;
|
|
474
599
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
600
|
+
if (value !== null && typeof value === "object") {
|
|
601
|
+
for (const [subKey, subValue] of Object.entries(
|
|
602
|
+
value
|
|
603
|
+
)) {
|
|
604
|
+
if (subValue !== void 0) {
|
|
605
|
+
appendBracketPairs(params, `${key}[${subKey}]`, subValue);
|
|
606
|
+
}
|
|
481
607
|
}
|
|
608
|
+
return;
|
|
482
609
|
}
|
|
483
|
-
|
|
610
|
+
params.append(key, String(value));
|
|
484
611
|
}
|
|
485
|
-
function
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
return { properties };
|
|
490
|
-
}
|
|
491
|
-
const json = findMediaType(content, "application/json");
|
|
492
|
-
const form = findMediaType(content, "application/x-www-form-urlencoded");
|
|
493
|
-
if (json === void 0 && form === void 0) {
|
|
494
|
-
const contentTypes = Object.keys(content);
|
|
495
|
-
return contentTypes.length > 0 ? { properties, unsupportedBodyContentType: contentTypes[0] } : { properties };
|
|
612
|
+
function appendQueryValue(query, name, style, value, explode) {
|
|
613
|
+
if (style === "deepObject") {
|
|
614
|
+
appendBracketPairs(query, name, value);
|
|
615
|
+
return;
|
|
496
616
|
}
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
617
|
+
if (style === "spaceDelimited" || style === "pipeDelimited") {
|
|
618
|
+
const items = Array.isArray(value) ? value : [value];
|
|
619
|
+
const separator = style === "spaceDelimited" ? " " : "|";
|
|
620
|
+
query.append(name, items.map(String).join(separator));
|
|
621
|
+
return;
|
|
501
622
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
623
|
+
if ((style === void 0 || style === "form") && value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
624
|
+
const entries = Object.entries(value);
|
|
625
|
+
if (explode === false) {
|
|
626
|
+
if (entries.length > 0) {
|
|
627
|
+
query.append(
|
|
628
|
+
name,
|
|
629
|
+
entries.flatMap(([key, item]) => [key, String(item)]).join(",")
|
|
630
|
+
);
|
|
631
|
+
}
|
|
632
|
+
} else {
|
|
633
|
+
for (const [key, item] of entries) {
|
|
634
|
+
query.append(key, String(item));
|
|
635
|
+
}
|
|
513
636
|
}
|
|
514
|
-
return
|
|
637
|
+
return;
|
|
515
638
|
}
|
|
516
|
-
if (
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
639
|
+
if ((style === void 0 || style === "form") && explode === false && Array.isArray(value) && value.length > 0) {
|
|
640
|
+
query.append(name, value.map(String).join(","));
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
for (const item of Array.isArray(value) ? value : [value]) {
|
|
644
|
+
query.append(name, String(item));
|
|
521
645
|
}
|
|
522
|
-
properties.set("body", {
|
|
523
|
-
required: _nullishCoalesce(_optionalChain([requestBody, 'optionalAccess', _28 => _28.required]), () => ( false)),
|
|
524
|
-
schema
|
|
525
|
-
});
|
|
526
|
-
return { bodyEncoding, properties, wholeBodyKey: "body" };
|
|
527
646
|
}
|
|
528
|
-
function
|
|
529
|
-
const
|
|
530
|
-
const
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
continue;
|
|
647
|
+
function assertNoSubstitutedDotSegments(route, resolvedPath) {
|
|
648
|
+
const templateSegments = new Set(route.path.split("/"));
|
|
649
|
+
for (const segment of resolvedPath.split("/")) {
|
|
650
|
+
if ((segment === "." || segment === "..") && !templateSegments.has(segment)) {
|
|
651
|
+
throw new (0, _chunkP56ABHAKcjs.UserError)(
|
|
652
|
+
`${route.method.toUpperCase()} ${route.path}: path parameter values must not produce a "${segment}" path segment.`
|
|
653
|
+
);
|
|
536
654
|
}
|
|
537
|
-
|
|
538
|
-
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
function encodeCookieValue(mapping, value) {
|
|
658
|
+
return (Array.isArray(value) ? value : [value]).map((item) => {
|
|
659
|
+
const text = String(item);
|
|
660
|
+
if (mapping.style !== "cookie") {
|
|
661
|
+
return encodePathComponent(text);
|
|
662
|
+
}
|
|
663
|
+
if (/[;,]/.test(text)) {
|
|
664
|
+
throw new (0, _chunkP56ABHAKcjs.UserError)(
|
|
665
|
+
`Cookie parameter "${mapping.name}" uses style "cookie" and its value contains ";" or ","`
|
|
666
|
+
);
|
|
539
667
|
}
|
|
668
|
+
return text;
|
|
669
|
+
}).join(",");
|
|
670
|
+
}
|
|
671
|
+
function encodeFormBody(payload) {
|
|
672
|
+
const params = new URLSearchParams();
|
|
673
|
+
if (payload && typeof payload === "object" && !Array.isArray(payload)) {
|
|
540
674
|
for (const [key, value] of Object.entries(
|
|
541
|
-
|
|
675
|
+
payload
|
|
542
676
|
)) {
|
|
543
|
-
if (
|
|
544
|
-
const [first = ""] = value.slice("#/$defs/".length).split("/");
|
|
545
|
-
const name = first.replaceAll("~1", "/").replaceAll("~0", "~");
|
|
546
|
-
if (allDefs[name] && !referenced.has(name)) {
|
|
547
|
-
referenced.add(name);
|
|
548
|
-
stack.push(allDefs[name]);
|
|
549
|
-
}
|
|
677
|
+
if (value === void 0) {
|
|
550
678
|
continue;
|
|
551
679
|
}
|
|
552
|
-
|
|
680
|
+
appendBracketPairs(params, key, value);
|
|
553
681
|
}
|
|
554
682
|
}
|
|
555
|
-
|
|
556
|
-
return void 0;
|
|
557
|
-
}
|
|
558
|
-
return Object.fromEntries(
|
|
559
|
-
[...referenced].map((name) => [name, allDefs[name]])
|
|
560
|
-
);
|
|
683
|
+
return params.toString();
|
|
561
684
|
}
|
|
562
|
-
function
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
const key = Object.hasOwn(content, mediaType) ? mediaType : Object.keys(content).find(
|
|
567
|
-
(candidate) => candidate.split(";")[0].trim().toLowerCase() === mediaType
|
|
685
|
+
function encodePathComponent(value) {
|
|
686
|
+
return encodeURIComponent(value).replace(
|
|
687
|
+
/[!'()*]/g,
|
|
688
|
+
(character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`
|
|
568
689
|
);
|
|
569
|
-
return key === void 0 ? void 0 : content[key];
|
|
570
690
|
}
|
|
571
|
-
function
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
return schema;
|
|
691
|
+
function encodePathValue(value, style, explode) {
|
|
692
|
+
if ((style === void 0 || style === "simple") && Array.isArray(value) && value.every((item) => item === null || typeof item !== "object")) {
|
|
693
|
+
return value.map((item) => encodePathComponent(String(item))).join(",");
|
|
575
694
|
}
|
|
576
|
-
if (
|
|
577
|
-
|
|
695
|
+
if ((style === void 0 || style === "simple") && value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
696
|
+
const entries = Object.entries(value);
|
|
697
|
+
if (entries.every(([, item]) => item === null || typeof item !== "object")) {
|
|
698
|
+
return entries.map(([key, item]) => {
|
|
699
|
+
const encodedKey = encodePathComponent(key);
|
|
700
|
+
const encodedValue = encodePathComponent(String(item));
|
|
701
|
+
return explode === true ? `${encodedKey}=${encodedValue}` : `${encodedKey},${encodedValue}`;
|
|
702
|
+
}).join(",");
|
|
703
|
+
}
|
|
578
704
|
}
|
|
579
|
-
|
|
580
|
-
return { ...unbounded, [exclusiveKey]: bound };
|
|
581
|
-
}
|
|
582
|
-
function normalizeExclusiveBounds(schema) {
|
|
583
|
-
return normalizeExclusiveBound(
|
|
584
|
-
normalizeExclusiveBound(schema, "exclusiveMinimum", "minimum"),
|
|
585
|
-
"exclusiveMaximum",
|
|
586
|
-
"maximum"
|
|
587
|
-
);
|
|
705
|
+
return encodeURIComponent(String(value));
|
|
588
706
|
}
|
|
589
|
-
function
|
|
590
|
-
if (!
|
|
591
|
-
return
|
|
592
|
-
}
|
|
593
|
-
const { nullable, ...rest } = schema;
|
|
594
|
-
if (nullable !== true) {
|
|
595
|
-
return rest;
|
|
596
|
-
}
|
|
597
|
-
const { type } = rest;
|
|
598
|
-
if (typeof type === "string") {
|
|
599
|
-
return { ...rest, type: [type, "null"] };
|
|
600
|
-
}
|
|
601
|
-
if (Array.isArray(type)) {
|
|
602
|
-
return { ...rest, type: [.../* @__PURE__ */ new Set(["null", ...type])] };
|
|
707
|
+
async function resolveHeaders(headers) {
|
|
708
|
+
if (!headers) {
|
|
709
|
+
return {};
|
|
603
710
|
}
|
|
604
|
-
return
|
|
711
|
+
return typeof headers === "function" ? await headers() : { ...headers };
|
|
605
712
|
}
|
|
606
|
-
function
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
if (Array.isArray(value)) {
|
|
611
|
-
return value.map((item) => rewriteNode(item, "schema", stripExamples));
|
|
612
|
-
}
|
|
613
|
-
if (!value || typeof value !== "object") {
|
|
614
|
-
return value;
|
|
713
|
+
function serializeQuery(query, allowReserved) {
|
|
714
|
+
const encoded = query.toString();
|
|
715
|
+
if (!allowReserved) {
|
|
716
|
+
return encoded;
|
|
615
717
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
}
|
|
625
|
-
return [key, rewriteNode(entryValue, childMode(key), stripExamples)];
|
|
626
|
-
});
|
|
627
|
-
const rewritten = Object.fromEntries(entries);
|
|
628
|
-
return mode === "schemaMap" ? rewritten : normalizeExclusiveBounds(normalizeNullable(rewritten));
|
|
718
|
+
return encoded.split("&").map((pair) => {
|
|
719
|
+
const [name, value] = pair.split("=");
|
|
720
|
+
const expanded = value.replace(
|
|
721
|
+
/\+|%25([\da-f]{2})|%(21|24|27|28|29|2c|2f|3a|3b|3f|40|7e)/gi,
|
|
722
|
+
(match, triple) => triple ? `%${triple}` : match === "+" ? "%20" : decodeURIComponent(match)
|
|
723
|
+
);
|
|
724
|
+
return `${name}=${expanded}`;
|
|
725
|
+
}).join("&");
|
|
629
726
|
}
|
|
630
727
|
|
|
631
728
|
// src/openapi/resourceMapping.ts
|
|
@@ -808,7 +905,7 @@ async function fromOpenAPI(options) {
|
|
|
808
905
|
const selected = selectRoutes(routes, options);
|
|
809
906
|
const names = generateNames(selected, options.mcpNames);
|
|
810
907
|
const sharedDefs = buildSharedDefs(document);
|
|
811
|
-
const server = _nullishCoalesce(options.server, () => ( new (0,
|
|
908
|
+
const server = _nullishCoalesce(options.server, () => ( new (0, _chunkP56ABHAKcjs.FastMCP)({
|
|
812
909
|
name: _nullishCoalesce(_nullishCoalesce(options.name, () => ( _optionalChain([document, 'access', _31 => _31.info, 'optionalAccess', _32 => _32.title]))), () => ( "OpenAPI Server")),
|
|
813
910
|
version: _nullishCoalesce(options.version, () => ( "1.0.0"))
|
|
814
911
|
})));
|
|
@@ -854,7 +951,7 @@ async function fromOpenAPI(options) {
|
|
|
854
951
|
continue;
|
|
855
952
|
}
|
|
856
953
|
const outputSchemaJson = buildOutputSchema(route, sharedDefs);
|
|
857
|
-
const outputSchema = outputSchemaJson ?
|
|
954
|
+
const outputSchema = outputSchemaJson ? _chunkP56ABHAKcjs.jsonSchemaAdapter.call(void 0, outputSchemaJson) : void 0;
|
|
858
955
|
server.addTool({
|
|
859
956
|
description: _nullishCoalesce(route.summary, () => ( `${route.method.toUpperCase()} ${route.path}`)),
|
|
860
957
|
execute: async (args, { signal }) => {
|
|
@@ -868,7 +965,7 @@ async function fromOpenAPI(options) {
|
|
|
868
965
|
return resolveToolResult(result, outputSchema);
|
|
869
966
|
},
|
|
870
967
|
name,
|
|
871
|
-
parameters:
|
|
968
|
+
parameters: _chunkP56ABHAKcjs.jsonSchemaAdapter.call(void 0, flatSchema),
|
|
872
969
|
...outputSchema ? { outputSchema } : {}
|
|
873
970
|
});
|
|
874
971
|
}
|
|
@@ -925,7 +1022,7 @@ function wrapAsResourceResult({ text }) {
|
|
|
925
1022
|
try {
|
|
926
1023
|
JSON.parse(text);
|
|
927
1024
|
return { mimeType: "application/json", text };
|
|
928
|
-
} catch (
|
|
1025
|
+
} catch (e4) {
|
|
929
1026
|
return { mimeType: "text/plain", text };
|
|
930
1027
|
}
|
|
931
1028
|
}
|