@forklaunch/core 0.9.21 → 0.10.0
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/http/index.d.mts +296 -102
- package/lib/http/index.d.ts +296 -102
- package/lib/http/index.js +452 -191
- package/lib/http/index.js.map +1 -1
- package/lib/http/index.mjs +455 -191
- package/lib/http/index.mjs.map +1 -1
- package/package.json +13 -12
package/lib/http/index.mjs
CHANGED
@@ -15,40 +15,12 @@ function cors(corsOptions) {
|
|
15
15
|
};
|
16
16
|
}
|
17
17
|
|
18
|
-
// src/http/
|
19
|
-
import { trace } from "@opentelemetry/api";
|
20
|
-
import { v4 } from "uuid";
|
21
|
-
|
22
|
-
// src/http/telemetry/constants.ts
|
18
|
+
// src/http/router/expressLikeRouter.ts
|
23
19
|
import {
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
} from "@opentelemetry/semantic-conventions";
|
29
|
-
var ATTR_API_NAME = "api.name";
|
30
|
-
var ATTR_CORRELATION_ID = "correlation.id";
|
31
|
-
|
32
|
-
// src/http/middleware/request/createContext.middleware.ts
|
33
|
-
function createContext(schemaValidator) {
|
34
|
-
return function setContext(req, res, next) {
|
35
|
-
req.schemaValidator = schemaValidator;
|
36
|
-
let correlationId = v4();
|
37
|
-
if (req.headers["x-correlation-id"]) {
|
38
|
-
correlationId = req.headers["x-correlation-id"];
|
39
|
-
}
|
40
|
-
res.setHeader("x-correlation-id", correlationId);
|
41
|
-
req.context = {
|
42
|
-
correlationId
|
43
|
-
};
|
44
|
-
const span = trace.getActiveSpan();
|
45
|
-
if (span != null) {
|
46
|
-
req.context.span = span;
|
47
|
-
req.context.span?.setAttribute(ATTR_CORRELATION_ID, correlationId);
|
48
|
-
}
|
49
|
-
next?.();
|
50
|
-
};
|
51
|
-
}
|
20
|
+
sanitizePathSlashes,
|
21
|
+
toPrettyCamelCase,
|
22
|
+
toRecord
|
23
|
+
} from "@forklaunch/common";
|
52
24
|
|
53
25
|
// src/http/guards/isForklaunchRouter.ts
|
54
26
|
function isForklaunchRouter(maybeForklaunchRouter) {
|
@@ -68,7 +40,7 @@ function isExpressLikeSchemaHandler(middleware2) {
|
|
68
40
|
(argumentName) => argumentName.toLowerCase()
|
69
41
|
)
|
70
42
|
);
|
71
|
-
return extractedArgumentNames && extractedArgumentNames.size <=
|
43
|
+
return extractedArgumentNames && extractedArgumentNames.size <= 4;
|
72
44
|
}
|
73
45
|
|
74
46
|
// src/http/guards/isForklaunchExpressLikeRouter.ts
|
@@ -225,6 +197,41 @@ async function parseRequestAuth(req, res, next) {
|
|
225
197
|
next?.();
|
226
198
|
}
|
227
199
|
|
200
|
+
// src/http/middleware/request/createContext.middleware.ts
|
201
|
+
import { trace } from "@opentelemetry/api";
|
202
|
+
import { v4 } from "uuid";
|
203
|
+
|
204
|
+
// src/http/telemetry/constants.ts
|
205
|
+
import {
|
206
|
+
ATTR_HTTP_REQUEST_METHOD,
|
207
|
+
ATTR_HTTP_RESPONSE_STATUS_CODE,
|
208
|
+
ATTR_HTTP_ROUTE,
|
209
|
+
ATTR_SERVICE_NAME
|
210
|
+
} from "@opentelemetry/semantic-conventions";
|
211
|
+
var ATTR_API_NAME = "api.name";
|
212
|
+
var ATTR_CORRELATION_ID = "correlation.id";
|
213
|
+
|
214
|
+
// src/http/middleware/request/createContext.middleware.ts
|
215
|
+
function createContext(schemaValidator) {
|
216
|
+
return function setContext(req, res, next) {
|
217
|
+
req.schemaValidator = schemaValidator;
|
218
|
+
let correlationId = v4();
|
219
|
+
if (req.headers["x-correlation-id"]) {
|
220
|
+
correlationId = req.headers["x-correlation-id"];
|
221
|
+
}
|
222
|
+
res.setHeader("x-correlation-id", correlationId);
|
223
|
+
req.context = {
|
224
|
+
correlationId
|
225
|
+
};
|
226
|
+
const span = trace.getActiveSpan();
|
227
|
+
if (span != null) {
|
228
|
+
req.context.span = span;
|
229
|
+
req.context.span?.setAttribute(ATTR_CORRELATION_ID, correlationId);
|
230
|
+
}
|
231
|
+
next?.();
|
232
|
+
};
|
233
|
+
}
|
234
|
+
|
228
235
|
// src/http/middleware/request/enrichDetails.middleware.ts
|
229
236
|
import { getEnvVar as getEnvVar2 } from "@forklaunch/common";
|
230
237
|
|
@@ -480,7 +487,7 @@ function enrichDetails(path, contractDetails, requestSchema, responseSchemas, op
|
|
480
487
|
req.requestSchema = requestSchema;
|
481
488
|
res.responseSchemas = responseSchemas;
|
482
489
|
req.openTelemetryCollector = openTelemetryCollector;
|
483
|
-
req.context
|
490
|
+
req.context?.span?.setAttribute(ATTR_API_NAME, req.contractDetails?.name);
|
484
491
|
const startTime = process.hrtime();
|
485
492
|
res.on("finish", () => {
|
486
493
|
const [seconds, nanoseconds] = process.hrtime(startTime);
|
@@ -617,6 +624,12 @@ function discriminateBody(schemaValidator, body) {
|
|
617
624
|
parserType: "text",
|
618
625
|
schema: maybeTypedBody
|
619
626
|
};
|
627
|
+
} else if (schemaValidator.openapi(maybeTypedBody).format === "binary") {
|
628
|
+
return {
|
629
|
+
contentType: "application/octet-stream",
|
630
|
+
parserType: "file",
|
631
|
+
schema: maybeTypedBody
|
632
|
+
};
|
620
633
|
} else {
|
621
634
|
return {
|
622
635
|
contentType: "application/json",
|
@@ -668,6 +681,12 @@ function discriminateResponseBodies(schemaValidator, responses) {
|
|
668
681
|
parserType: "text",
|
669
682
|
schema: response
|
670
683
|
};
|
684
|
+
} else if (schemaValidator.openapi(response).format === "binary") {
|
685
|
+
discriminatedResponses[Number(statusCode)] = {
|
686
|
+
contentType: "application/octet-stream",
|
687
|
+
parserType: "file",
|
688
|
+
schema: response
|
689
|
+
};
|
671
690
|
} else {
|
672
691
|
discriminatedResponses[Number(statusCode)] = {
|
673
692
|
contentType: "application/json",
|
@@ -687,18 +706,38 @@ function discriminateResponseBodies(schemaValidator, responses) {
|
|
687
706
|
}
|
688
707
|
|
689
708
|
// src/http/router/expressLikeRouter.ts
|
690
|
-
var ForklaunchExpressLikeRouter = class {
|
691
|
-
constructor(basePath, schemaValidator, internal, postEnrichMiddleware, openTelemetryCollector) {
|
709
|
+
var ForklaunchExpressLikeRouter = class _ForklaunchExpressLikeRouter {
|
710
|
+
constructor(basePath, schemaValidator, internal, postEnrichMiddleware, openTelemetryCollector, sdkName) {
|
711
|
+
this.basePath = basePath;
|
692
712
|
this.schemaValidator = schemaValidator;
|
693
713
|
this.internal = internal;
|
694
714
|
this.postEnrichMiddleware = postEnrichMiddleware;
|
695
715
|
this.openTelemetryCollector = openTelemetryCollector;
|
696
|
-
this.
|
716
|
+
this.sdkName = sdkName;
|
717
|
+
if (process.env.NODE_ENV !== "test" && !process.env.VITEST) {
|
718
|
+
process.on("uncaughtException", (err) => {
|
719
|
+
this.openTelemetryCollector.error(`Uncaught exception: ${err}`);
|
720
|
+
process.exit(1);
|
721
|
+
});
|
722
|
+
process.on("unhandledRejection", (reason) => {
|
723
|
+
this.openTelemetryCollector.error(`Unhandled rejection: ${reason}`);
|
724
|
+
process.exit(1);
|
725
|
+
});
|
726
|
+
process.on("exit", () => {
|
727
|
+
this.openTelemetryCollector.info("Shutting down application");
|
728
|
+
});
|
729
|
+
process.on("SIGINT", () => {
|
730
|
+
this.openTelemetryCollector.info("Shutting down application");
|
731
|
+
process.exit(0);
|
732
|
+
});
|
733
|
+
}
|
734
|
+
this.internal.use(createContext(this.schemaValidator));
|
697
735
|
}
|
698
736
|
requestHandler;
|
699
737
|
routers = [];
|
700
738
|
routes = [];
|
701
|
-
|
739
|
+
fetchMap = {};
|
740
|
+
sdk = {};
|
702
741
|
/**
|
703
742
|
* Resolves middlewares based on the contract details.
|
704
743
|
*
|
@@ -817,6 +856,20 @@ var ForklaunchExpressLikeRouter = class {
|
|
817
856
|
responseSchemas
|
818
857
|
};
|
819
858
|
}
|
859
|
+
/**
|
860
|
+
* Fetches a route from the route map and executes it with the given parameters.
|
861
|
+
*
|
862
|
+
* @template Path - The path type that extends keyof fetchMap and string.
|
863
|
+
* @param {Path} path - The route path
|
864
|
+
* @param {Parameters<fetchMap[Path]>[1]} [requestInit] - Optional request initialization parameters.
|
865
|
+
* @returns {Promise<ReturnType<fetchMap[Path]>>} - The result of executing the route handler.
|
866
|
+
*/
|
867
|
+
fetch = async (path, ...reqInit) => {
|
868
|
+
return this.fetchMap[path](
|
869
|
+
path,
|
870
|
+
reqInit[0]
|
871
|
+
);
|
872
|
+
};
|
820
873
|
/**
|
821
874
|
* Executes request locally, applying parameters
|
822
875
|
*
|
@@ -836,24 +889,6 @@ var ForklaunchExpressLikeRouter = class {
|
|
836
889
|
body: discriminateBody(this.schemaValidator, request?.body)?.schema ?? {},
|
837
890
|
path: route
|
838
891
|
};
|
839
|
-
function remapFileBody(body) {
|
840
|
-
if (body instanceof File) {
|
841
|
-
return (name, contentType) => {
|
842
|
-
return new File([body], name, { type: contentType });
|
843
|
-
};
|
844
|
-
}
|
845
|
-
Object.entries(body).forEach(([key, value]) => {
|
846
|
-
if (value instanceof File) {
|
847
|
-
body[key] = (name, contentType) => {
|
848
|
-
return new File([value], name, { type: contentType });
|
849
|
-
};
|
850
|
-
} else if (typeof value === "object") {
|
851
|
-
body[key] = remapFileBody(value);
|
852
|
-
}
|
853
|
-
});
|
854
|
-
return body;
|
855
|
-
}
|
856
|
-
req.body = remapFileBody(req.body);
|
857
892
|
const res = {
|
858
893
|
status: (code) => {
|
859
894
|
statusCode = code;
|
@@ -907,24 +942,20 @@ var ForklaunchExpressLikeRouter = class {
|
|
907
942
|
registerRoute(method, path, registrationMethod, contractDetailsOrMiddlewareOrTypedHandler, ...middlewareOrMiddlewareAndTypedHandler) {
|
908
943
|
if (isTypedHandler(contractDetailsOrMiddlewareOrTypedHandler)) {
|
909
944
|
const { contractDetails, handlers } = contractDetailsOrMiddlewareOrTypedHandler;
|
910
|
-
|
911
|
-
|
912
|
-
path,
|
913
|
-
registrationMethod,
|
914
|
-
contractDetails,
|
915
|
-
...handlers
|
916
|
-
);
|
945
|
+
this.registerRoute(method, path, registrationMethod, contractDetails, ...handlers);
|
946
|
+
return this;
|
917
947
|
} else {
|
918
948
|
const maybeTypedHandler = middlewareOrMiddlewareAndTypedHandler[middlewareOrMiddlewareAndTypedHandler.length - 1];
|
919
949
|
if (isTypedHandler(maybeTypedHandler)) {
|
920
950
|
const { contractDetails, handlers } = maybeTypedHandler;
|
921
|
-
|
951
|
+
this.registerRoute(
|
922
952
|
method,
|
923
953
|
path,
|
924
954
|
registrationMethod,
|
925
955
|
contractDetails,
|
926
956
|
...middlewareOrMiddlewareAndTypedHandler.concat(handlers)
|
927
957
|
);
|
958
|
+
return this;
|
928
959
|
} else {
|
929
960
|
if (isExpressLikeSchemaHandler(contractDetailsOrMiddlewareOrTypedHandler) || isTypedHandler(contractDetailsOrMiddlewareOrTypedHandler)) {
|
930
961
|
throw new Error("Contract details are not defined");
|
@@ -956,10 +987,13 @@ var ForklaunchExpressLikeRouter = class {
|
|
956
987
|
).concat(handlers),
|
957
988
|
this.#parseAndRunControllerHandler(controllerHandler)
|
958
989
|
);
|
959
|
-
|
990
|
+
const localParamRequest = this.#localParamRequest(
|
960
991
|
handlers,
|
961
992
|
controllerHandler
|
962
993
|
);
|
994
|
+
toRecord(this.fetchMap)[sanitizePathSlashes(`${this.basePath}${path}`)] = localParamRequest;
|
995
|
+
toRecord(this.sdk)[toPrettyCamelCase(contractDetails.name ?? this.basePath)] = (req) => localParamRequest(`${this.basePath}${path}`, req);
|
996
|
+
return this;
|
963
997
|
}
|
964
998
|
}
|
965
999
|
}
|
@@ -983,10 +1017,13 @@ var ForklaunchExpressLikeRouter = class {
|
|
983
1017
|
return this.#extractHandlers(handlers);
|
984
1018
|
}
|
985
1019
|
#extractNestableMiddlewareFromEnrichedTypedHandlerArray(handlers) {
|
986
|
-
return this.#extractHandlers(
|
987
|
-
|
988
|
-
|
989
|
-
|
1020
|
+
return this.#extractHandlers(handlers, (handler) => {
|
1021
|
+
if (isForklaunchExpressLikeRouter(handler)) {
|
1022
|
+
this.addRouterToSdk(handler);
|
1023
|
+
return handler.internal;
|
1024
|
+
}
|
1025
|
+
return handler;
|
1026
|
+
});
|
990
1027
|
}
|
991
1028
|
#processTypedHandlerOrMiddleware(handler, middleware2) {
|
992
1029
|
if (isTypedHandler(handler)) {
|
@@ -1010,6 +1047,7 @@ var ForklaunchExpressLikeRouter = class {
|
|
1010
1047
|
middleware2
|
1011
1048
|
);
|
1012
1049
|
if (isForklaunchExpressLikeRouter(contractDetailsOrMiddlewareOrTypedHandler)) {
|
1050
|
+
this.addRouterToSdk(contractDetailsOrMiddlewareOrTypedHandler);
|
1013
1051
|
middleware2.push(contractDetailsOrMiddlewareOrTypedHandler.internal);
|
1014
1052
|
}
|
1015
1053
|
middleware2.push(
|
@@ -1039,6 +1077,16 @@ var ForklaunchExpressLikeRouter = class {
|
|
1039
1077
|
}
|
1040
1078
|
return this;
|
1041
1079
|
}
|
1080
|
+
addRouterToSdk(router) {
|
1081
|
+
Object.entries(router.fetchMap).map(
|
1082
|
+
([key, value]) => toRecord(this.fetchMap)[sanitizePathSlashes(`${this.basePath}${key}`)] = value
|
1083
|
+
);
|
1084
|
+
const existingSdk = this.sdk[router.sdkName ?? toPrettyCamelCase(router.basePath)];
|
1085
|
+
toRecord(this.sdk)[router.sdkName ?? toPrettyCamelCase(router.basePath)] = {
|
1086
|
+
...typeof existingSdk === "object" ? existingSdk : {},
|
1087
|
+
...router.sdk
|
1088
|
+
};
|
1089
|
+
}
|
1042
1090
|
registerNestableMiddlewareHandler(registrationMethod, pathOrContractDetailsOrMiddlewareOrTypedHandler, contractDetailsOrMiddlewareOrTypedHandler, ...middlewareOrMiddlewareWithTypedHandler) {
|
1043
1091
|
const middleware2 = [];
|
1044
1092
|
let path;
|
@@ -1054,7 +1102,9 @@ var ForklaunchExpressLikeRouter = class {
|
|
1054
1102
|
if (isConstrainedForklaunchRouter(
|
1055
1103
|
pathOrContractDetailsOrMiddlewareOrTypedHandler
|
1056
1104
|
)) {
|
1057
|
-
|
1105
|
+
const router = pathOrContractDetailsOrMiddlewareOrTypedHandler;
|
1106
|
+
this.addRouterToSdk(router);
|
1107
|
+
path = router.basePath;
|
1058
1108
|
}
|
1059
1109
|
middleware2.push(
|
1060
1110
|
...this.#extractNestableMiddlewareAsRouterHandlers(
|
@@ -1065,6 +1115,11 @@ var ForklaunchExpressLikeRouter = class {
|
|
1065
1115
|
)
|
1066
1116
|
);
|
1067
1117
|
}
|
1118
|
+
if (!path) {
|
1119
|
+
path = middleware2.filter(
|
1120
|
+
(m) => isForklaunchExpressLikeRouter(m)
|
1121
|
+
)[0]?.basePath;
|
1122
|
+
}
|
1068
1123
|
if (path) {
|
1069
1124
|
registrationMethod.bind(this.internal)(path, ...middleware2);
|
1070
1125
|
} else {
|
@@ -1119,15 +1174,13 @@ var ForklaunchExpressLikeRouter = class {
|
|
1119
1174
|
* @returns {ExpressRouter} - The Express router.
|
1120
1175
|
*/
|
1121
1176
|
get = (path, contractDetailsOrMiddlewareOrTypedHandler, ...middlewareOrMiddlewareWithTypedHandler) => {
|
1122
|
-
return
|
1123
|
-
get
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
)
|
1130
|
-
};
|
1177
|
+
return this.registerRoute(
|
1178
|
+
"get",
|
1179
|
+
path,
|
1180
|
+
this.internal.get,
|
1181
|
+
contractDetailsOrMiddlewareOrTypedHandler,
|
1182
|
+
...middlewareOrMiddlewareWithTypedHandler
|
1183
|
+
);
|
1131
1184
|
};
|
1132
1185
|
/**
|
1133
1186
|
* Registers a POST route with the specified contract details and handler handlers.
|
@@ -1143,15 +1196,13 @@ var ForklaunchExpressLikeRouter = class {
|
|
1143
1196
|
* @returns {ExpressRouter} - The Expxwress router.
|
1144
1197
|
*/
|
1145
1198
|
post = (path, contractDetailsOrMiddlewareOrTypedHandler, ...middlewareOrMiddlewareWithTypedHandler) => {
|
1146
|
-
return
|
1147
|
-
post
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
)
|
1154
|
-
};
|
1199
|
+
return this.registerRoute(
|
1200
|
+
"post",
|
1201
|
+
path,
|
1202
|
+
this.internal.post,
|
1203
|
+
contractDetailsOrMiddlewareOrTypedHandler,
|
1204
|
+
...middlewareOrMiddlewareWithTypedHandler
|
1205
|
+
);
|
1155
1206
|
};
|
1156
1207
|
/**
|
1157
1208
|
* Registers a PUT route with the specified contract details and handler handlers.
|
@@ -1167,15 +1218,13 @@ var ForklaunchExpressLikeRouter = class {
|
|
1167
1218
|
* @returns {ExpressRouter} - The Express router.
|
1168
1219
|
*/
|
1169
1220
|
put = (path, contractDetailsOrMiddlewareOrTypedHandler, ...middlewareOrMiddlewareWithTypedHandler) => {
|
1170
|
-
return
|
1171
|
-
put
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
)
|
1178
|
-
};
|
1221
|
+
return this.registerRoute(
|
1222
|
+
"put",
|
1223
|
+
path,
|
1224
|
+
this.internal.put,
|
1225
|
+
contractDetailsOrMiddlewareOrTypedHandler,
|
1226
|
+
...middlewareOrMiddlewareWithTypedHandler
|
1227
|
+
);
|
1179
1228
|
};
|
1180
1229
|
/**
|
1181
1230
|
* Registers a PATCH route with the specified contract details and handler handlers.
|
@@ -1191,15 +1240,13 @@ var ForklaunchExpressLikeRouter = class {
|
|
1191
1240
|
* @returns {ExpressRouter} - The Express router.
|
1192
1241
|
*/
|
1193
1242
|
patch = (path, contractDetailsOrMiddlewareOrTypedHandler, ...middlewareOrMiddlewareWithTypedHandler) => {
|
1194
|
-
return
|
1195
|
-
patch
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
)
|
1202
|
-
};
|
1243
|
+
return this.registerRoute(
|
1244
|
+
"patch",
|
1245
|
+
path,
|
1246
|
+
this.internal.patch,
|
1247
|
+
contractDetailsOrMiddlewareOrTypedHandler,
|
1248
|
+
...middlewareOrMiddlewareWithTypedHandler
|
1249
|
+
);
|
1203
1250
|
};
|
1204
1251
|
/**
|
1205
1252
|
* Registers a DELETE route with the specified contract details and handler handlers.
|
@@ -1215,15 +1262,13 @@ var ForklaunchExpressLikeRouter = class {
|
|
1215
1262
|
* @returns {ExpressRouter} - The Express router.
|
1216
1263
|
*/
|
1217
1264
|
delete = (path, contractDetailsOrMiddlewareOrTypedHandler, ...middlewareOrMiddlewareWithTypedHandler) => {
|
1218
|
-
return
|
1219
|
-
delete
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
)
|
1226
|
-
};
|
1265
|
+
return this.registerRoute(
|
1266
|
+
"delete",
|
1267
|
+
path,
|
1268
|
+
this.internal.delete,
|
1269
|
+
contractDetailsOrMiddlewareOrTypedHandler,
|
1270
|
+
...middlewareOrMiddlewareWithTypedHandler
|
1271
|
+
);
|
1227
1272
|
};
|
1228
1273
|
/**
|
1229
1274
|
* Registers a OPTIONS route with the specified contract details and handler handlers.
|
@@ -1239,15 +1284,13 @@ var ForklaunchExpressLikeRouter = class {
|
|
1239
1284
|
* @returns {ExpressRouter} - The Express router.
|
1240
1285
|
*/
|
1241
1286
|
options = (path, contractDetailsOrMiddlewareOrTypedHandler, ...middlewareOrMiddlewareWithTypedHandler) => {
|
1242
|
-
return
|
1243
|
-
options
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1249
|
-
)
|
1250
|
-
};
|
1287
|
+
return this.registerRoute(
|
1288
|
+
"options",
|
1289
|
+
path,
|
1290
|
+
this.internal.options,
|
1291
|
+
contractDetailsOrMiddlewareOrTypedHandler,
|
1292
|
+
...middlewareOrMiddlewareWithTypedHandler
|
1293
|
+
);
|
1251
1294
|
};
|
1252
1295
|
/**
|
1253
1296
|
* Registers a HEAD route with the specified contract details and handler handlers.
|
@@ -1263,15 +1306,13 @@ var ForklaunchExpressLikeRouter = class {
|
|
1263
1306
|
* @returns {ExpressRouter} - The Express router.
|
1264
1307
|
*/
|
1265
1308
|
head = (path, contractDetailsOrMiddlewareOrTypedHandler, ...middlewareOrMiddlewareWithTypedHandler) => {
|
1266
|
-
return
|
1267
|
-
head
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
)
|
1274
|
-
};
|
1309
|
+
return this.registerRoute(
|
1310
|
+
"head",
|
1311
|
+
path,
|
1312
|
+
this.internal.head,
|
1313
|
+
contractDetailsOrMiddlewareOrTypedHandler,
|
1314
|
+
...middlewareOrMiddlewareWithTypedHandler
|
1315
|
+
);
|
1275
1316
|
};
|
1276
1317
|
/**
|
1277
1318
|
* Registers a TRACE route with the specified contract details and handler handlers.
|
@@ -1287,16 +1328,32 @@ var ForklaunchExpressLikeRouter = class {
|
|
1287
1328
|
* @returns {ExpressRouter} - The Express router.
|
1288
1329
|
*/
|
1289
1330
|
trace = (path, contractDetailsOrMiddlewareOrTypedHandler, ...middlewareOrMiddlewareWithTypedHandler) => {
|
1290
|
-
return
|
1291
|
-
trace
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1297
|
-
)
|
1298
|
-
};
|
1331
|
+
return this.registerRoute(
|
1332
|
+
"trace",
|
1333
|
+
path,
|
1334
|
+
this.internal.trace,
|
1335
|
+
contractDetailsOrMiddlewareOrTypedHandler,
|
1336
|
+
...middlewareOrMiddlewareWithTypedHandler
|
1337
|
+
);
|
1299
1338
|
};
|
1339
|
+
cloneInternals(clone) {
|
1340
|
+
clone.routers = [...this.routers];
|
1341
|
+
clone.routes = [...this.routes];
|
1342
|
+
clone.fetchMap = { ...this.fetchMap };
|
1343
|
+
clone.sdk = { ...this.sdk };
|
1344
|
+
}
|
1345
|
+
clone() {
|
1346
|
+
const clone = new _ForklaunchExpressLikeRouter(
|
1347
|
+
this.basePath,
|
1348
|
+
this.schemaValidator,
|
1349
|
+
this.internal,
|
1350
|
+
this.postEnrichMiddleware,
|
1351
|
+
this.openTelemetryCollector,
|
1352
|
+
this.sdkName
|
1353
|
+
);
|
1354
|
+
this.cloneInternals(clone);
|
1355
|
+
return clone;
|
1356
|
+
}
|
1300
1357
|
};
|
1301
1358
|
|
1302
1359
|
// src/http/application/expressLikeApplication.ts
|
@@ -1319,25 +1376,6 @@ var ForklaunchExpressLikeApplication = class extends ForklaunchExpressLikeRouter
|
|
1319
1376
|
this.postEnrichMiddleware = postEnrichMiddleware;
|
1320
1377
|
this.openTelemetryCollector = openTelemetryCollector;
|
1321
1378
|
this.appOptions = appOptions;
|
1322
|
-
process.on("uncaughtException", (err) => {
|
1323
|
-
this.openTelemetryCollector.log("error", `Uncaught exception: ${err}`);
|
1324
|
-
process.exit(1);
|
1325
|
-
});
|
1326
|
-
process.on("unhandledRejection", (reason) => {
|
1327
|
-
this.openTelemetryCollector.log(
|
1328
|
-
"error",
|
1329
|
-
`Unhandled rejection: ${reason}`
|
1330
|
-
);
|
1331
|
-
process.exit(1);
|
1332
|
-
});
|
1333
|
-
process.on("exit", () => {
|
1334
|
-
this.openTelemetryCollector.log("info", "Shutting down application");
|
1335
|
-
});
|
1336
|
-
process.on("SIGINT", () => {
|
1337
|
-
this.openTelemetryCollector.log("info", "Shutting down application");
|
1338
|
-
process.exit(0);
|
1339
|
-
});
|
1340
|
-
this.internal.use(createContext(this.schemaValidator));
|
1341
1379
|
this.internal.use(cors(this.appOptions?.cors ?? {}));
|
1342
1380
|
}
|
1343
1381
|
};
|
@@ -2402,6 +2440,218 @@ var getCodeForStatus = (status) => {
|
|
2402
2440
|
};
|
2403
2441
|
var httpStatusCodes_default = HTTPStatuses;
|
2404
2442
|
|
2443
|
+
// src/http/mcpGenerator/mcpGenerator.ts
|
2444
|
+
import { isNever as isNever2, isRecord, safeStringify as safeStringify2 } from "@forklaunch/common";
|
2445
|
+
import { ZodSchemaValidator } from "@forklaunch/validator/zod";
|
2446
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
2447
|
+
|
2448
|
+
// src/http/router/unpackRouters.ts
|
2449
|
+
import { toPrettyCamelCase as toPrettyCamelCase2 } from "@forklaunch/common";
|
2450
|
+
function unpackRouters(routers, recursiveBasePath = [], recursiveSdkPath = []) {
|
2451
|
+
return routers.reduce((acc, router) => {
|
2452
|
+
acc.push({
|
2453
|
+
fullPath: [...recursiveBasePath, router.basePath].join(""),
|
2454
|
+
sdkPath: [
|
2455
|
+
...recursiveSdkPath,
|
2456
|
+
toPrettyCamelCase2(router.sdkName ?? router.basePath)
|
2457
|
+
].join("."),
|
2458
|
+
router
|
2459
|
+
});
|
2460
|
+
acc.push(
|
2461
|
+
...unpackRouters(
|
2462
|
+
router.routers,
|
2463
|
+
[...recursiveBasePath, router.basePath],
|
2464
|
+
[
|
2465
|
+
...recursiveSdkPath,
|
2466
|
+
toPrettyCamelCase2(router.sdkName ?? router.basePath)
|
2467
|
+
]
|
2468
|
+
)
|
2469
|
+
);
|
2470
|
+
return acc;
|
2471
|
+
}, []);
|
2472
|
+
}
|
2473
|
+
|
2474
|
+
// src/http/mcpGenerator/mcpGenerator.ts
|
2475
|
+
function generateMcpServer(schemaValidator, protocol, host, port, version, routers, contentTypeMap) {
|
2476
|
+
if (!(schemaValidator instanceof ZodSchemaValidator)) {
|
2477
|
+
throw new Error(
|
2478
|
+
"Schema validator must be an instance of ZodSchemaValidator"
|
2479
|
+
);
|
2480
|
+
}
|
2481
|
+
const mcpServer = new McpServer({
|
2482
|
+
name: "example-server",
|
2483
|
+
version
|
2484
|
+
});
|
2485
|
+
unpackRouters(routers).forEach(({ fullPath, router }) => {
|
2486
|
+
router.routes.forEach((route) => {
|
2487
|
+
let discriminatedBody;
|
2488
|
+
if ("body" in route.contractDetails) {
|
2489
|
+
discriminatedBody = discriminateBody(
|
2490
|
+
schemaValidator,
|
2491
|
+
route.contractDetails.body
|
2492
|
+
);
|
2493
|
+
}
|
2494
|
+
const inputSchema = {
|
2495
|
+
...discriminatedBody && "body" in route.contractDetails ? {
|
2496
|
+
..."contentType" in route.contractDetails.body ? { contentType: route.contractDetails.body.contentType } : {},
|
2497
|
+
body: schemaValidator.schemify(discriminatedBody.schema)
|
2498
|
+
} : {},
|
2499
|
+
...route.contractDetails.params ? { params: schemaValidator.schemify(route.contractDetails.params) } : {},
|
2500
|
+
...route.contractDetails.query ? { query: schemaValidator.schemify(route.contractDetails.query) } : {},
|
2501
|
+
...route.contractDetails.requestHeaders ? {
|
2502
|
+
headers: schemaValidator.schemify(
|
2503
|
+
route.contractDetails.requestHeaders
|
2504
|
+
)
|
2505
|
+
} : {}
|
2506
|
+
// TODO: support auth
|
2507
|
+
// ...(route.contractDetails.auth
|
2508
|
+
// ? { auth: route.contractDetails.auth }
|
2509
|
+
// : {})
|
2510
|
+
};
|
2511
|
+
mcpServer.tool(
|
2512
|
+
route.contractDetails.name,
|
2513
|
+
route.contractDetails.summary,
|
2514
|
+
inputSchema,
|
2515
|
+
async (args) => {
|
2516
|
+
const { contentType, body, params, query, headers } = args;
|
2517
|
+
let url = `${protocol}://${host}:${port}${fullPath}${route.path}`;
|
2518
|
+
if (params) {
|
2519
|
+
for (const key in params) {
|
2520
|
+
url = url.replace(
|
2521
|
+
`:${key}`,
|
2522
|
+
encodeURIComponent(params[key])
|
2523
|
+
);
|
2524
|
+
}
|
2525
|
+
}
|
2526
|
+
let parsedBody;
|
2527
|
+
if (discriminatedBody) {
|
2528
|
+
switch (discriminatedBody.parserType) {
|
2529
|
+
case "json": {
|
2530
|
+
parsedBody = safeStringify2(body);
|
2531
|
+
break;
|
2532
|
+
}
|
2533
|
+
case "text": {
|
2534
|
+
parsedBody = body;
|
2535
|
+
break;
|
2536
|
+
}
|
2537
|
+
case "file": {
|
2538
|
+
parsedBody = body;
|
2539
|
+
break;
|
2540
|
+
}
|
2541
|
+
case "multipart": {
|
2542
|
+
const formData = new FormData();
|
2543
|
+
if (isRecord(body)) {
|
2544
|
+
for (const key in body) {
|
2545
|
+
if (typeof body[key] === "string" || body[key] instanceof Blob) {
|
2546
|
+
formData.append(key, body[key]);
|
2547
|
+
} else {
|
2548
|
+
throw new Error("Body is not a valid multipart object");
|
2549
|
+
}
|
2550
|
+
}
|
2551
|
+
} else {
|
2552
|
+
throw new Error("Body is not a valid multipart object");
|
2553
|
+
}
|
2554
|
+
parsedBody = formData;
|
2555
|
+
break;
|
2556
|
+
}
|
2557
|
+
case "urlEncoded": {
|
2558
|
+
if (isRecord(body)) {
|
2559
|
+
parsedBody = new URLSearchParams(
|
2560
|
+
Object.entries(body).map(([key, value]) => [
|
2561
|
+
key,
|
2562
|
+
safeStringify2(value)
|
2563
|
+
])
|
2564
|
+
);
|
2565
|
+
} else {
|
2566
|
+
throw new Error("Body is not a valid url encoded object");
|
2567
|
+
}
|
2568
|
+
break;
|
2569
|
+
}
|
2570
|
+
default: {
|
2571
|
+
isNever2(discriminatedBody.parserType);
|
2572
|
+
parsedBody = safeStringify2(body);
|
2573
|
+
break;
|
2574
|
+
}
|
2575
|
+
}
|
2576
|
+
}
|
2577
|
+
if (query) {
|
2578
|
+
const queryString = new URLSearchParams(
|
2579
|
+
Object.entries(query).map(([key, value]) => [
|
2580
|
+
key,
|
2581
|
+
safeStringify2(value)
|
2582
|
+
])
|
2583
|
+
).toString();
|
2584
|
+
url += queryString ? `?${queryString}` : "";
|
2585
|
+
}
|
2586
|
+
const response = await fetch(encodeURI(url), {
|
2587
|
+
method: route.method.toUpperCase(),
|
2588
|
+
headers: {
|
2589
|
+
...headers,
|
2590
|
+
...discriminatedBody?.contentType != "multipart/form-data" ? {
|
2591
|
+
"Content-Type": contentType ?? discriminatedBody?.contentType
|
2592
|
+
} : {}
|
2593
|
+
},
|
2594
|
+
body: parsedBody
|
2595
|
+
});
|
2596
|
+
if (response.status >= 300) {
|
2597
|
+
throw new Error(
|
2598
|
+
`Error received while proxying request to ${url}: ${await response.text()}`
|
2599
|
+
);
|
2600
|
+
}
|
2601
|
+
const contractContentType = discriminateResponseBodies(
|
2602
|
+
schemaValidator,
|
2603
|
+
route.contractDetails.responses
|
2604
|
+
)[response.status].contentType;
|
2605
|
+
switch (contentTypeMap && contentTypeMap[contractContentType] ? contentTypeMap[contractContentType] : contractContentType) {
|
2606
|
+
case "application/json":
|
2607
|
+
return {
|
2608
|
+
content: [
|
2609
|
+
{
|
2610
|
+
type: "text",
|
2611
|
+
text: safeStringify2(await response.json())
|
2612
|
+
}
|
2613
|
+
]
|
2614
|
+
};
|
2615
|
+
case "text/plain":
|
2616
|
+
return {
|
2617
|
+
content: [
|
2618
|
+
{ type: "text", text: await response.text() }
|
2619
|
+
]
|
2620
|
+
};
|
2621
|
+
case "application/octet-stream":
|
2622
|
+
return {
|
2623
|
+
content: [
|
2624
|
+
{
|
2625
|
+
type: "resource",
|
2626
|
+
resource: {
|
2627
|
+
uri: response.url,
|
2628
|
+
blob: Buffer.from(
|
2629
|
+
await (await response.blob()).arrayBuffer()
|
2630
|
+
).toString("base64")
|
2631
|
+
}
|
2632
|
+
}
|
2633
|
+
]
|
2634
|
+
};
|
2635
|
+
case "text/event-stream":
|
2636
|
+
return {
|
2637
|
+
content: [
|
2638
|
+
{ type: "text", text: await response.text() }
|
2639
|
+
]
|
2640
|
+
};
|
2641
|
+
default:
|
2642
|
+
return {
|
2643
|
+
content: [
|
2644
|
+
{ type: "text", text: await response.text() }
|
2645
|
+
]
|
2646
|
+
};
|
2647
|
+
}
|
2648
|
+
}
|
2649
|
+
);
|
2650
|
+
});
|
2651
|
+
});
|
2652
|
+
return mcpServer;
|
2653
|
+
}
|
2654
|
+
|
2405
2655
|
// src/http/middleware/response/parse.middleware.ts
|
2406
2656
|
import {
|
2407
2657
|
prettyPrintParseErrors as prettyPrintParseErrors2
|
@@ -2468,11 +2718,11 @@ ${parseErrors.join("\n\n")}`
|
|
2468
2718
|
// src/http/middleware/response/enrichExpressLikeSend.middleware.ts
|
2469
2719
|
import {
|
2470
2720
|
isAsyncGenerator,
|
2471
|
-
isNever as
|
2721
|
+
isNever as isNever3,
|
2472
2722
|
isNodeJsWriteableStream,
|
2473
|
-
isRecord,
|
2723
|
+
isRecord as isRecord2,
|
2474
2724
|
readableStreamToAsyncIterable,
|
2475
|
-
safeStringify as
|
2725
|
+
safeStringify as safeStringify3
|
2476
2726
|
} from "@forklaunch/common";
|
2477
2727
|
import { Readable, Transform } from "stream";
|
2478
2728
|
|
@@ -2509,7 +2759,7 @@ function enrichExpressLikeSend(instance, req, res, originalOperation, originalSe
|
|
2509
2759
|
if (res.statusCode === 404) {
|
2510
2760
|
res.type("text/plain");
|
2511
2761
|
res.status(404);
|
2512
|
-
|
2762
|
+
req.openTelemetryCollector.error("Not Found");
|
2513
2763
|
originalSend.call(instance, "Not Found");
|
2514
2764
|
errorSent = true;
|
2515
2765
|
}
|
@@ -2552,7 +2802,7 @@ function enrichExpressLikeSend(instance, req, res, originalOperation, originalSe
|
|
2552
2802
|
------------------
|
2553
2803
|
${res.locals.errorMessage}`;
|
2554
2804
|
}
|
2555
|
-
|
2805
|
+
req.openTelemetryCollector.error(errorString);
|
2556
2806
|
res.type("text/plain");
|
2557
2807
|
res.status(500);
|
2558
2808
|
originalSend.call(instance, errorString);
|
@@ -2565,7 +2815,7 @@ ${res.locals.errorMessage}`;
|
|
2565
2815
|
if (!errorSent) {
|
2566
2816
|
let data2 = "";
|
2567
2817
|
for (const [key, value] of Object.entries(chunk)) {
|
2568
|
-
data2 += `${key}: ${typeof value === "string" ? value :
|
2818
|
+
data2 += `${key}: ${typeof value === "string" ? value : safeStringify3(value)}
|
2569
2819
|
`;
|
2570
2820
|
}
|
2571
2821
|
data2 += "\n";
|
@@ -2584,7 +2834,7 @@ ${res.locals.errorMessage}`;
|
|
2584
2834
|
} else {
|
2585
2835
|
const parserType = responseBodies?.[Number(res.statusCode)]?.parserType;
|
2586
2836
|
res.bodyData = data;
|
2587
|
-
if (
|
2837
|
+
if (isRecord2(data)) {
|
2588
2838
|
switch (parserType) {
|
2589
2839
|
case "json":
|
2590
2840
|
res.bodyData = "json" in data ? data.json : data;
|
@@ -2605,7 +2855,7 @@ ${res.locals.errorMessage}`;
|
|
2605
2855
|
res.bodyData = data;
|
2606
2856
|
break;
|
2607
2857
|
default:
|
2608
|
-
|
2858
|
+
isNever3(parserType);
|
2609
2859
|
res.bodyData = data;
|
2610
2860
|
break;
|
2611
2861
|
}
|
@@ -2618,7 +2868,7 @@ ${res.locals.errorMessage}`;
|
|
2618
2868
|
------------------
|
2619
2869
|
${res.locals.errorMessage}`;
|
2620
2870
|
}
|
2621
|
-
|
2871
|
+
req.openTelemetryCollector.error(errorString);
|
2622
2872
|
res.type("text/plain");
|
2623
2873
|
res.status(500);
|
2624
2874
|
originalSend.call(instance, errorString);
|
@@ -2641,16 +2891,17 @@ ${res.locals.errorMessage}`;
|
|
2641
2891
|
}
|
2642
2892
|
|
2643
2893
|
// src/http/openApiV3Generator/openApiV3Generator.ts
|
2894
|
+
import { openApiCompliantPath, toPrettyCamelCase as toPrettyCamelCase3 } from "@forklaunch/common";
|
2644
2895
|
function toUpperCase(str) {
|
2645
2896
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
2646
2897
|
}
|
2647
2898
|
function transformBasePath(basePath) {
|
2648
2899
|
if (basePath.startsWith("/")) {
|
2649
|
-
return
|
2900
|
+
return basePath.slice(1);
|
2650
2901
|
}
|
2651
2902
|
return `/${basePath}`;
|
2652
2903
|
}
|
2653
|
-
function generateOpenApiDocument(port, tags, paths) {
|
2904
|
+
function generateOpenApiDocument(protocol, host, port, tags, paths, otherServers) {
|
2654
2905
|
return {
|
2655
2906
|
openapi: "3.1.0",
|
2656
2907
|
info: {
|
@@ -2669,8 +2920,10 @@ function generateOpenApiDocument(port, tags, paths) {
|
|
2669
2920
|
tags,
|
2670
2921
|
servers: [
|
2671
2922
|
{
|
2672
|
-
url:
|
2673
|
-
|
2923
|
+
url: `${protocol}://${host}:${port}`,
|
2924
|
+
description: "Main Server"
|
2925
|
+
},
|
2926
|
+
...otherServers || []
|
2674
2927
|
],
|
2675
2928
|
paths
|
2676
2929
|
};
|
@@ -2691,19 +2944,21 @@ function contentResolver(schemaValidator, body, contentType) {
|
|
2691
2944
|
}
|
2692
2945
|
};
|
2693
2946
|
}
|
2694
|
-
function generateSwaggerDocument(schemaValidator, port, routers) {
|
2947
|
+
function generateSwaggerDocument(schemaValidator, protocol, host, port, routers, otherServers) {
|
2695
2948
|
const tags = [];
|
2696
2949
|
const paths = {};
|
2697
|
-
routers
|
2698
|
-
const controllerName = transformBasePath(
|
2950
|
+
unpackRouters(routers).forEach(({ fullPath, router, sdkPath }) => {
|
2951
|
+
const controllerName = transformBasePath(fullPath);
|
2699
2952
|
tags.push({
|
2700
2953
|
name: controllerName,
|
2701
|
-
description: `${controllerName} Operations`
|
2954
|
+
description: `${toUpperCase(controllerName)} Operations`
|
2702
2955
|
});
|
2703
2956
|
router.routes.forEach((route) => {
|
2704
|
-
const
|
2705
|
-
|
2706
|
-
|
2957
|
+
const openApiPath = openApiCompliantPath(
|
2958
|
+
`${fullPath}${route.path === "/" ? "" : route.path}`
|
2959
|
+
);
|
2960
|
+
if (!paths[openApiPath]) {
|
2961
|
+
paths[openApiPath] = {};
|
2707
2962
|
}
|
2708
2963
|
const { name, summary, query, requestHeaders } = route.contractDetails;
|
2709
2964
|
const responses = {};
|
@@ -2730,15 +2985,16 @@ function generateSwaggerDocument(schemaValidator, port, routers) {
|
|
2730
2985
|
};
|
2731
2986
|
}
|
2732
2987
|
}
|
2733
|
-
const
|
2988
|
+
const operationObject = {
|
2734
2989
|
tags: [controllerName],
|
2735
2990
|
summary: `${name}: ${summary}`,
|
2736
2991
|
parameters: [],
|
2737
|
-
responses
|
2992
|
+
responses,
|
2993
|
+
operationId: `${sdkPath}.${toPrettyCamelCase3(name)}`
|
2738
2994
|
};
|
2739
2995
|
if (route.contractDetails.params) {
|
2740
2996
|
for (const key in route.contractDetails.params) {
|
2741
|
-
|
2997
|
+
operationObject.parameters?.push({
|
2742
2998
|
name: key,
|
2743
2999
|
in: "path",
|
2744
3000
|
schema: schemaValidator.openapi(
|
@@ -2749,7 +3005,7 @@ function generateSwaggerDocument(schemaValidator, port, routers) {
|
|
2749
3005
|
}
|
2750
3006
|
const discriminatedBodyResult = "body" in route.contractDetails ? discriminateBody(schemaValidator, route.contractDetails.body) : null;
|
2751
3007
|
if (discriminatedBodyResult) {
|
2752
|
-
|
3008
|
+
operationObject.requestBody = {
|
2753
3009
|
required: true,
|
2754
3010
|
content: contentResolver(
|
2755
3011
|
schemaValidator,
|
@@ -2760,7 +3016,7 @@ function generateSwaggerDocument(schemaValidator, port, routers) {
|
|
2760
3016
|
}
|
2761
3017
|
if (requestHeaders) {
|
2762
3018
|
for (const key in requestHeaders) {
|
2763
|
-
|
3019
|
+
operationObject.parameters?.push({
|
2764
3020
|
name: key,
|
2765
3021
|
in: "header",
|
2766
3022
|
schema: schemaValidator.openapi(
|
@@ -2771,7 +3027,7 @@ function generateSwaggerDocument(schemaValidator, port, routers) {
|
|
2771
3027
|
}
|
2772
3028
|
if (query) {
|
2773
3029
|
for (const key in query) {
|
2774
|
-
|
3030
|
+
operationObject.parameters?.push({
|
2775
3031
|
name: key,
|
2776
3032
|
in: "query",
|
2777
3033
|
schema: schemaValidator.openapi(query[key])
|
@@ -2788,7 +3044,7 @@ function generateSwaggerDocument(schemaValidator, port, routers) {
|
|
2788
3044
|
content: contentResolver(schemaValidator, schemaValidator.string)
|
2789
3045
|
};
|
2790
3046
|
if (route.contractDetails.auth.method === "jwt") {
|
2791
|
-
|
3047
|
+
operationObject.security = [
|
2792
3048
|
{
|
2793
3049
|
bearer: Array.from(
|
2794
3050
|
route.contractDetails.auth.allowedPermissions?.values() || []
|
@@ -2798,11 +3054,18 @@ function generateSwaggerDocument(schemaValidator, port, routers) {
|
|
2798
3054
|
}
|
2799
3055
|
}
|
2800
3056
|
if (route.method !== "middleware") {
|
2801
|
-
paths[
|
3057
|
+
paths[openApiPath][route.method] = operationObject;
|
2802
3058
|
}
|
2803
3059
|
});
|
2804
3060
|
});
|
2805
|
-
return generateOpenApiDocument(
|
3061
|
+
return generateOpenApiDocument(
|
3062
|
+
protocol,
|
3063
|
+
host,
|
3064
|
+
port,
|
3065
|
+
tags,
|
3066
|
+
paths,
|
3067
|
+
otherServers
|
3068
|
+
);
|
2806
3069
|
}
|
2807
3070
|
|
2808
3071
|
// src/http/telemetry/evaluateTelemetryOptions.ts
|
@@ -2841,6 +3104,7 @@ export {
|
|
2841
3104
|
discriminateResponseBodies,
|
2842
3105
|
enrichExpressLikeSend,
|
2843
3106
|
evaluateTelemetryOptions,
|
3107
|
+
generateMcpServer,
|
2844
3108
|
generateSwaggerDocument,
|
2845
3109
|
get,
|
2846
3110
|
getCodeForStatus,
|