@forklaunch/core 0.15.3 → 0.15.4
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/lib/environment/index.d.mts +24 -0
- package/lib/environment/index.d.ts +24 -0
- package/lib/environment/index.js +151 -0
- package/lib/environment/index.js.map +1 -0
- package/lib/environment/index.mjs +113 -0
- package/lib/environment/index.mjs.map +1 -0
- package/lib/http/index.js +162 -154
- package/lib/http/index.js.map +1 -1
- package/lib/http/index.mjs +162 -154
- package/lib/http/index.mjs.map +1 -1
- package/lib/persistence/index.js +1 -1
- package/lib/persistence/index.js.map +1 -1
- package/lib/persistence/index.mjs +1 -1
- package/lib/persistence/index.mjs.map +1 -1
- package/lib/services/index.d.mts +10 -0
- package/lib/services/index.d.ts +10 -0
- package/lib/services/index.js +125 -2
- package/lib/services/index.js.map +1 -1
- package/lib/services/index.mjs +112 -1
- package/lib/services/index.mjs.map +1 -1
- package/package.json +18 -11
package/lib/http/index.js
CHANGED
@@ -3100,11 +3100,6 @@ var import_common10 = require("@forklaunch/common");
|
|
3100
3100
|
var import_fastmcp_fork = require("@forklaunch/fastmcp-fork");
|
3101
3101
|
var import_zod = require("@forklaunch/validator/zod");
|
3102
3102
|
|
3103
|
-
// src/http/guards/isVersionedInputSchema.ts
|
3104
|
-
function isUnionable(schema) {
|
3105
|
-
return schema.length > 1;
|
3106
|
-
}
|
3107
|
-
|
3108
3103
|
// src/http/router/unpackRouters.ts
|
3109
3104
|
function unpackRouters(routers, recursiveBasePath = []) {
|
3110
3105
|
return routers.reduce((acc, router) => {
|
@@ -3134,8 +3129,12 @@ function generateInputSchema(schemaValidator, body, params, query, requestHeader
|
|
3134
3129
|
..."contentType" in body ? { contentType: body.contentType } : {},
|
3135
3130
|
body: schemaValidator.schemify(discriminatedBody.schema)
|
3136
3131
|
} : {},
|
3137
|
-
...params ? {
|
3138
|
-
|
3132
|
+
...params ? {
|
3133
|
+
params: schemaValidator.schemify(params)
|
3134
|
+
} : {},
|
3135
|
+
...query ? {
|
3136
|
+
query: schemaValidator.schemify(query)
|
3137
|
+
} : {},
|
3139
3138
|
...requestHeaders ? {
|
3140
3139
|
headers: schemaValidator.schemify({
|
3141
3140
|
...requestHeaders,
|
@@ -3198,163 +3197,172 @@ function generateMcpServer(schemaValidator, protocol, host, port, version, appli
|
|
3198
3197
|
)
|
3199
3198
|
);
|
3200
3199
|
}
|
3201
|
-
|
3202
|
-
|
3203
|
-
|
3204
|
-
|
3205
|
-
|
3206
|
-
|
3207
|
-
|
3208
|
-
|
3209
|
-
|
3210
|
-
|
3211
|
-
|
3212
|
-
|
3213
|
-
|
3214
|
-
|
3215
|
-
}
|
3216
|
-
let bodySchema;
|
3217
|
-
let responsesSchemas;
|
3218
|
-
if (route.contractDetails.versions) {
|
3219
|
-
Object.values(route.contractDetails.versions).forEach(
|
3220
|
-
(version2, index) => {
|
3221
|
-
if (version2.body && schemaValidator.parse(inputSchemas[index], args).ok) {
|
3222
|
-
bodySchema = version2.body;
|
3223
|
-
responsesSchemas = version2.responses;
|
3224
|
-
}
|
3225
|
-
}
|
3226
|
-
);
|
3227
|
-
} else {
|
3228
|
-
bodySchema = route.contractDetails.body;
|
3229
|
-
responsesSchemas = route.contractDetails.responses;
|
3230
|
-
}
|
3231
|
-
const discriminatedBody = bodySchema ? discriminateBody(schemaValidator, bodySchema) : void 0;
|
3232
|
-
let parsedBody;
|
3233
|
-
if (discriminatedBody) {
|
3234
|
-
switch (discriminatedBody.parserType) {
|
3235
|
-
case "json": {
|
3236
|
-
parsedBody = (0, import_common10.safeStringify)(body);
|
3237
|
-
break;
|
3200
|
+
inputSchemas.forEach((inputSchema, index) => {
|
3201
|
+
mcpServer.addTool({
|
3202
|
+
name: route.contractDetails.name + (Object.keys(route.contractDetails.versions ?? {}).length > 1 ? ` [v${Object.keys(route.contractDetails.versions ?? {})[index]}]` : ""),
|
3203
|
+
description: route.contractDetails.summary,
|
3204
|
+
parameters: inputSchema,
|
3205
|
+
execute: async (args) => {
|
3206
|
+
const { contentType, body, params, query, headers } = args;
|
3207
|
+
let url = `${protocol}://${host}:${port}${fullPath}${route.path}`;
|
3208
|
+
if (params) {
|
3209
|
+
for (const key in params) {
|
3210
|
+
url = url.replace(
|
3211
|
+
`:${key}`,
|
3212
|
+
encodeURIComponent(params[key])
|
3213
|
+
);
|
3238
3214
|
}
|
3239
|
-
|
3240
|
-
|
3241
|
-
|
3242
|
-
|
3243
|
-
|
3244
|
-
|
3245
|
-
|
3215
|
+
}
|
3216
|
+
let bodySchema;
|
3217
|
+
let responsesSchemas;
|
3218
|
+
if (route.contractDetails.versions) {
|
3219
|
+
const version2 = route.contractDetails.versions[index];
|
3220
|
+
if (version2.body && schemaValidator.parse(inputSchema, args).ok) {
|
3221
|
+
bodySchema = version2.body;
|
3222
|
+
responsesSchemas = version2.responses;
|
3246
3223
|
}
|
3247
|
-
|
3248
|
-
|
3249
|
-
|
3250
|
-
|
3251
|
-
|
3252
|
-
|
3253
|
-
|
3254
|
-
|
3224
|
+
} else {
|
3225
|
+
bodySchema = route.contractDetails.body;
|
3226
|
+
responsesSchemas = route.contractDetails.responses;
|
3227
|
+
}
|
3228
|
+
const discriminatedBody = bodySchema ? discriminateBody(schemaValidator, bodySchema) : void 0;
|
3229
|
+
let parsedBody;
|
3230
|
+
if (discriminatedBody) {
|
3231
|
+
switch (discriminatedBody.parserType) {
|
3232
|
+
case "json": {
|
3233
|
+
parsedBody = (0, import_common10.safeStringify)(body);
|
3234
|
+
break;
|
3235
|
+
}
|
3236
|
+
case "text": {
|
3237
|
+
parsedBody = body;
|
3238
|
+
break;
|
3239
|
+
}
|
3240
|
+
case "file": {
|
3241
|
+
parsedBody = Buffer.from((0, import_common10.safeStringify)(body));
|
3242
|
+
break;
|
3243
|
+
}
|
3244
|
+
case "multipart": {
|
3245
|
+
const formData = new FormData();
|
3246
|
+
if ((0, import_common10.isRecord)(body)) {
|
3247
|
+
for (const key in body) {
|
3248
|
+
if (typeof body[key] === "string") {
|
3249
|
+
if (schemaValidator.isInstanceOf(
|
3250
|
+
body[key],
|
3251
|
+
schemaValidator.file
|
3252
|
+
)) {
|
3253
|
+
formData.append(
|
3254
|
+
key,
|
3255
|
+
new Blob([Buffer.from(body[key])])
|
3256
|
+
);
|
3257
|
+
} else {
|
3258
|
+
formData.append(key, body[key]);
|
3259
|
+
}
|
3260
|
+
} else {
|
3261
|
+
throw new Error("Body is not a valid multipart object");
|
3262
|
+
}
|
3255
3263
|
}
|
3264
|
+
} else {
|
3265
|
+
throw new Error("Body is not a valid multipart object");
|
3256
3266
|
}
|
3257
|
-
|
3258
|
-
|
3267
|
+
parsedBody = formData;
|
3268
|
+
break;
|
3259
3269
|
}
|
3260
|
-
|
3261
|
-
|
3262
|
-
|
3263
|
-
|
3264
|
-
|
3265
|
-
|
3266
|
-
|
3267
|
-
|
3268
|
-
|
3269
|
-
|
3270
|
-
|
3271
|
-
|
3272
|
-
|
3270
|
+
case "urlEncoded": {
|
3271
|
+
if ((0, import_common10.isRecord)(body)) {
|
3272
|
+
parsedBody = new URLSearchParams(
|
3273
|
+
Object.entries(body).map(([key, value]) => [
|
3274
|
+
key,
|
3275
|
+
(0, import_common10.safeStringify)(value)
|
3276
|
+
])
|
3277
|
+
);
|
3278
|
+
} else {
|
3279
|
+
throw new Error("Body is not a valid url encoded object");
|
3280
|
+
}
|
3281
|
+
break;
|
3282
|
+
}
|
3283
|
+
default: {
|
3284
|
+
(0, import_common10.isNever)(discriminatedBody.parserType);
|
3285
|
+
parsedBody = (0, import_common10.safeStringify)(body);
|
3286
|
+
break;
|
3273
3287
|
}
|
3274
|
-
break;
|
3275
|
-
}
|
3276
|
-
default: {
|
3277
|
-
(0, import_common10.isNever)(discriminatedBody.parserType);
|
3278
|
-
parsedBody = (0, import_common10.safeStringify)(body);
|
3279
|
-
break;
|
3280
3288
|
}
|
3281
3289
|
}
|
3282
|
-
|
3283
|
-
|
3284
|
-
|
3285
|
-
|
3286
|
-
|
3287
|
-
|
3288
|
-
|
3289
|
-
|
3290
|
-
|
3291
|
-
|
3292
|
-
|
3293
|
-
|
3294
|
-
|
3295
|
-
|
3296
|
-
|
3297
|
-
|
3298
|
-
}
|
3299
|
-
|
3300
|
-
|
3301
|
-
|
3302
|
-
|
3303
|
-
|
3304
|
-
|
3305
|
-
|
3306
|
-
|
3307
|
-
|
3308
|
-
|
3309
|
-
|
3310
|
-
|
3311
|
-
|
3312
|
-
|
3313
|
-
|
3314
|
-
|
3315
|
-
|
3316
|
-
|
3317
|
-
|
3318
|
-
|
3319
|
-
|
3320
|
-
text: (0, import_common10.safeStringify)(await response.json())
|
3321
|
-
}
|
3322
|
-
]
|
3323
|
-
};
|
3324
|
-
case "text/plain":
|
3325
|
-
return {
|
3326
|
-
content: [
|
3327
|
-
{ type: "text", text: await response.text() }
|
3328
|
-
]
|
3329
|
-
};
|
3330
|
-
case "application/octet-stream":
|
3331
|
-
return {
|
3332
|
-
content: [
|
3333
|
-
{
|
3334
|
-
type: "resource",
|
3335
|
-
resource: {
|
3336
|
-
uri: response.url,
|
3337
|
-
blob: Buffer.from(
|
3338
|
-
await (await response.blob()).arrayBuffer()
|
3339
|
-
).toString("base64")
|
3290
|
+
if (query) {
|
3291
|
+
const queryString = new URLSearchParams(
|
3292
|
+
Object.entries(query).map(([key, value]) => [
|
3293
|
+
key,
|
3294
|
+
(0, import_common10.safeStringify)(value)
|
3295
|
+
])
|
3296
|
+
).toString();
|
3297
|
+
url += queryString ? `?${queryString}` : "";
|
3298
|
+
}
|
3299
|
+
const response = await fetch(encodeURI(url), {
|
3300
|
+
method: route.method.toUpperCase(),
|
3301
|
+
headers: {
|
3302
|
+
...headers,
|
3303
|
+
...discriminatedBody?.contentType != "multipart/form-data" ? {
|
3304
|
+
"Content-Type": contentType ?? discriminatedBody?.contentType
|
3305
|
+
} : {}
|
3306
|
+
},
|
3307
|
+
body: parsedBody
|
3308
|
+
});
|
3309
|
+
if (response.status >= 300) {
|
3310
|
+
throw new Error(
|
3311
|
+
`Error received while proxying request to ${url}: ${await response.text()}`
|
3312
|
+
);
|
3313
|
+
}
|
3314
|
+
if (!responsesSchemas) {
|
3315
|
+
throw new Error("No responses schemas found");
|
3316
|
+
}
|
3317
|
+
const contractContentType = discriminateResponseBodies(
|
3318
|
+
schemaValidator,
|
3319
|
+
responsesSchemas
|
3320
|
+
)[response.status].contentType;
|
3321
|
+
switch (contentTypeMap && contentTypeMap[contractContentType] ? contentTypeMap[contractContentType] : contractContentType) {
|
3322
|
+
case "application/json":
|
3323
|
+
return {
|
3324
|
+
content: [
|
3325
|
+
{
|
3326
|
+
type: "text",
|
3327
|
+
text: (0, import_common10.safeStringify)(await response.json())
|
3340
3328
|
}
|
3341
|
-
|
3342
|
-
|
3343
|
-
|
3344
|
-
|
3345
|
-
|
3346
|
-
|
3347
|
-
|
3348
|
-
|
3349
|
-
|
3350
|
-
|
3351
|
-
|
3352
|
-
|
3353
|
-
|
3354
|
-
|
3355
|
-
|
3329
|
+
]
|
3330
|
+
};
|
3331
|
+
case "text/plain":
|
3332
|
+
return {
|
3333
|
+
content: [
|
3334
|
+
{ type: "text", text: await response.text() }
|
3335
|
+
]
|
3336
|
+
};
|
3337
|
+
case "application/octet-stream":
|
3338
|
+
return {
|
3339
|
+
content: [
|
3340
|
+
{
|
3341
|
+
type: "resource",
|
3342
|
+
resource: {
|
3343
|
+
uri: response.url,
|
3344
|
+
blob: Buffer.from(
|
3345
|
+
await (await response.blob()).arrayBuffer()
|
3346
|
+
).toString("base64")
|
3347
|
+
}
|
3348
|
+
}
|
3349
|
+
]
|
3350
|
+
};
|
3351
|
+
case "text/event-stream":
|
3352
|
+
return {
|
3353
|
+
content: [
|
3354
|
+
{ type: "text", text: await response.text() }
|
3355
|
+
]
|
3356
|
+
};
|
3357
|
+
default:
|
3358
|
+
return {
|
3359
|
+
content: [
|
3360
|
+
{ type: "text", text: await response.text() }
|
3361
|
+
]
|
3362
|
+
};
|
3363
|
+
}
|
3356
3364
|
}
|
3357
|
-
}
|
3365
|
+
});
|
3358
3366
|
});
|
3359
3367
|
});
|
3360
3368
|
});
|