@forklaunch/core 0.12.0 → 0.12.2
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 +3 -3
- package/lib/http/index.d.ts +3 -3
- package/lib/http/index.js +113 -75
- package/lib/http/index.js.map +1 -1
- package/lib/http/index.mjs +87 -49
- package/lib/http/index.mjs.map +1 -1
- package/lib/services/index.d.mts +1 -6
- package/lib/services/index.d.ts +1 -6
- package/package.json +2 -2
package/lib/http/index.d.mts
CHANGED
@@ -8,8 +8,8 @@ import { LevelWithSilentOrString, LevelWithSilent, Logger } from 'pino';
|
|
8
8
|
export { LevelWithSilent, LevelWithSilentOrString, Logger } from 'pino';
|
9
9
|
import { JWTPayload } from 'jose';
|
10
10
|
import { Readable } from 'stream';
|
11
|
+
import { FastMCP } from '@forklaunch/fastmcp-fork';
|
11
12
|
import { ZodSchemaValidator } from '@forklaunch/validator/zod';
|
12
|
-
import { FastMCP } from 'fastmcp';
|
13
13
|
import { OpenAPIObject } from 'openapi3-ts/oas31';
|
14
14
|
import { AnyValueMap } from '@opentelemetry/api-logs';
|
15
15
|
import { ApiReferenceConfiguration } from '@scalar/express-api-reference';
|
@@ -1661,7 +1661,7 @@ declare const getCodeForStatus: (status: string) => null | StatusCode;
|
|
1661
1661
|
* @param {ForklaunchRouter<SV>[]} routers - The routers to include in the server.
|
1662
1662
|
* @returns {McpServer} - The generated ModelContextProtocol server.
|
1663
1663
|
*/
|
1664
|
-
declare function generateMcpServer<T extends Record<string, unknown> | undefined = Record<string, unknown> | undefined>(schemaValidator: ZodSchemaValidator, protocol: 'http' | 'https', host: string, port: number, version: `${number}.${number}.${number}`,
|
1664
|
+
declare function generateMcpServer<T extends Record<string, unknown> | undefined = Record<string, unknown> | undefined>(schemaValidator: ZodSchemaValidator, protocol: 'http' | 'https', host: string, port: number, version: `${number}.${number}.${number}`, application: ForklaunchRouter<ZodSchemaValidator>, options?: ConstructorParameters<typeof FastMCP<T>>[0], contentTypeMap?: Record<string, string>): FastMCP<T>;
|
1665
1665
|
|
1666
1666
|
/**
|
1667
1667
|
* Enhances the Express-like `send` method with additional logic for response handling and validation.
|
@@ -1701,7 +1701,7 @@ declare const OPENAPI_DEFAULT_VERSION: unique symbol;
|
|
1701
1701
|
* @param {ForklaunchRouter<SV>[]} routers - The routers to include in the Swagger document.
|
1702
1702
|
* @returns {OpenAPIObject} - The generated Swagger document.
|
1703
1703
|
*/
|
1704
|
-
declare function generateOpenApiSpecs<SV extends AnySchemaValidator>(schemaValidator: SV,
|
1704
|
+
declare function generateOpenApiSpecs<SV extends AnySchemaValidator>(schemaValidator: SV, serverUrls: string[], serverDescriptions: string[], application: ForklaunchRouter<SV>, otherServers?: {
|
1705
1705
|
url: string;
|
1706
1706
|
description: string;
|
1707
1707
|
}[]): Record<string | symbol, OpenAPIObject>;
|
package/lib/http/index.d.ts
CHANGED
@@ -8,8 +8,8 @@ import { LevelWithSilentOrString, LevelWithSilent, Logger } from 'pino';
|
|
8
8
|
export { LevelWithSilent, LevelWithSilentOrString, Logger } from 'pino';
|
9
9
|
import { JWTPayload } from 'jose';
|
10
10
|
import { Readable } from 'stream';
|
11
|
+
import { FastMCP } from '@forklaunch/fastmcp-fork';
|
11
12
|
import { ZodSchemaValidator } from '@forklaunch/validator/zod';
|
12
|
-
import { FastMCP } from 'fastmcp';
|
13
13
|
import { OpenAPIObject } from 'openapi3-ts/oas31';
|
14
14
|
import { AnyValueMap } from '@opentelemetry/api-logs';
|
15
15
|
import { ApiReferenceConfiguration } from '@scalar/express-api-reference';
|
@@ -1661,7 +1661,7 @@ declare const getCodeForStatus: (status: string) => null | StatusCode;
|
|
1661
1661
|
* @param {ForklaunchRouter<SV>[]} routers - The routers to include in the server.
|
1662
1662
|
* @returns {McpServer} - The generated ModelContextProtocol server.
|
1663
1663
|
*/
|
1664
|
-
declare function generateMcpServer<T extends Record<string, unknown> | undefined = Record<string, unknown> | undefined>(schemaValidator: ZodSchemaValidator, protocol: 'http' | 'https', host: string, port: number, version: `${number}.${number}.${number}`,
|
1664
|
+
declare function generateMcpServer<T extends Record<string, unknown> | undefined = Record<string, unknown> | undefined>(schemaValidator: ZodSchemaValidator, protocol: 'http' | 'https', host: string, port: number, version: `${number}.${number}.${number}`, application: ForklaunchRouter<ZodSchemaValidator>, options?: ConstructorParameters<typeof FastMCP<T>>[0], contentTypeMap?: Record<string, string>): FastMCP<T>;
|
1665
1665
|
|
1666
1666
|
/**
|
1667
1667
|
* Enhances the Express-like `send` method with additional logic for response handling and validation.
|
@@ -1701,7 +1701,7 @@ declare const OPENAPI_DEFAULT_VERSION: unique symbol;
|
|
1701
1701
|
* @param {ForklaunchRouter<SV>[]} routers - The routers to include in the Swagger document.
|
1702
1702
|
* @returns {OpenAPIObject} - The generated Swagger document.
|
1703
1703
|
*/
|
1704
|
-
declare function generateOpenApiSpecs<SV extends AnySchemaValidator>(schemaValidator: SV,
|
1704
|
+
declare function generateOpenApiSpecs<SV extends AnySchemaValidator>(schemaValidator: SV, serverUrls: string[], serverDescriptions: string[], application: ForklaunchRouter<SV>, otherServers?: {
|
1705
1705
|
url: string;
|
1706
1706
|
description: string;
|
1707
1707
|
}[]): Record<string | symbol, OpenAPIObject>;
|
package/lib/http/index.js
CHANGED
@@ -100,7 +100,7 @@ function cors(corsOptions) {
|
|
100
100
|
}
|
101
101
|
|
102
102
|
// src/http/router/expressLikeRouter.ts
|
103
|
-
var
|
103
|
+
var import_common8 = require("@forklaunch/common");
|
104
104
|
|
105
105
|
// src/http/guards/hasVersionedSchema.ts
|
106
106
|
function hasVersionedSchema(contractDetails) {
|
@@ -332,6 +332,7 @@ async function parseRequestAuth(req, res, next) {
|
|
332
332
|
}
|
333
333
|
|
334
334
|
// src/http/middleware/request/createContext.middleware.ts
|
335
|
+
var import_common3 = require("@forklaunch/common");
|
335
336
|
var import_api = require("@opentelemetry/api");
|
336
337
|
var import_uuid = require("uuid");
|
337
338
|
|
@@ -352,20 +353,24 @@ function createContext(schemaValidator) {
|
|
352
353
|
req.context = {
|
353
354
|
correlationId
|
354
355
|
};
|
355
|
-
const span = import_api.trace.
|
356
|
+
const span = import_api.trace.getSpan(import_api.context.active());
|
356
357
|
if (span != null) {
|
357
358
|
req.context.span = span;
|
358
359
|
req.context.span?.setAttribute(ATTR_CORRELATION_ID, correlationId);
|
360
|
+
req.context.span?.setAttribute(
|
361
|
+
import_semantic_conventions.ATTR_SERVICE_NAME,
|
362
|
+
(0, import_common3.getEnvVar)("OTEL_SERVICE_NAME")
|
363
|
+
);
|
359
364
|
}
|
360
365
|
next?.();
|
361
366
|
};
|
362
367
|
}
|
363
368
|
|
364
369
|
// src/http/middleware/request/enrichDetails.middleware.ts
|
365
|
-
var
|
370
|
+
var import_common6 = require("@forklaunch/common");
|
366
371
|
|
367
372
|
// src/http/telemetry/openTelemetryCollector.ts
|
368
|
-
var
|
373
|
+
var import_common5 = require("@forklaunch/common");
|
369
374
|
var import_opentelemetry_instrumentation_hyper_express = require("@forklaunch/opentelemetry-instrumentation-hyper-express");
|
370
375
|
var import_api3 = require("@opentelemetry/api");
|
371
376
|
var import_exporter_logs_otlp_http = require("@opentelemetry/exporter-logs-otlp-http");
|
@@ -387,7 +392,7 @@ function isForklaunchRequest(request) {
|
|
387
392
|
}
|
388
393
|
|
389
394
|
// src/http/telemetry/pinoLogger.ts
|
390
|
-
var
|
395
|
+
var import_common4 = require("@forklaunch/common");
|
391
396
|
var import_api2 = require("@opentelemetry/api");
|
392
397
|
var import_api_logs = require("@opentelemetry/api-logs");
|
393
398
|
var import_pino = __toESM(require("pino"));
|
@@ -419,10 +424,25 @@ function mapSeverity(level) {
|
|
419
424
|
case "fatal":
|
420
425
|
return 21;
|
421
426
|
default:
|
422
|
-
(0,
|
427
|
+
(0, import_common4.isNever)(level);
|
423
428
|
return 0;
|
424
429
|
}
|
425
430
|
}
|
431
|
+
function normalizeLogArgs(args) {
|
432
|
+
let message = "";
|
433
|
+
const metaObjects = [];
|
434
|
+
for (const arg of args) {
|
435
|
+
if (typeof arg === "string" && message === "") {
|
436
|
+
message = arg;
|
437
|
+
} else if (arg && typeof arg === "object" && !Array.isArray(arg)) {
|
438
|
+
metaObjects.push(arg);
|
439
|
+
} else {
|
440
|
+
message += ` ${String(arg)}`;
|
441
|
+
}
|
442
|
+
}
|
443
|
+
const metadata = Object.assign({}, ...metaObjects);
|
444
|
+
return [metadata, message.trim()];
|
445
|
+
}
|
426
446
|
var PinoLogger = class _PinoLogger {
|
427
447
|
pinoLogger;
|
428
448
|
meta;
|
@@ -453,7 +473,7 @@ var PinoLogger = class _PinoLogger {
|
|
453
473
|
return false;
|
454
474
|
}
|
455
475
|
return true;
|
456
|
-
})
|
476
|
+
});
|
457
477
|
const activeSpan = import_api2.trace.getActiveSpan();
|
458
478
|
if (activeSpan) {
|
459
479
|
const activeSpanContext = activeSpan.spanContext();
|
@@ -471,7 +491,7 @@ var PinoLogger = class _PinoLogger {
|
|
471
491
|
"correlation.id": "none",
|
472
492
|
...meta2
|
473
493
|
};
|
474
|
-
this.pinoLogger[level](...filteredArgs);
|
494
|
+
this.pinoLogger[level](...normalizeLogArgs(filteredArgs));
|
475
495
|
import_api_logs.logs.getLogger(process.env.OTEL_SERVICE_NAME ?? "unknown").emit({
|
476
496
|
severityText: level,
|
477
497
|
severityNumber: mapSeverity(level),
|
@@ -559,24 +579,24 @@ var OpenTelemetryCollector = class {
|
|
559
579
|
return this.metrics[metricId];
|
560
580
|
}
|
561
581
|
};
|
562
|
-
import_dotenv.default.config({ path: (0,
|
582
|
+
import_dotenv.default.config({ path: (0, import_common5.getEnvVar)("DOTENV_FILE_PATH") });
|
563
583
|
new import_sdk_node.NodeSDK({
|
564
584
|
resource: (0, import_resources.resourceFromAttributes)({
|
565
|
-
[import_semantic_conventions2.ATTR_SERVICE_NAME]: (0,
|
585
|
+
[import_semantic_conventions2.ATTR_SERVICE_NAME]: (0, import_common5.getEnvVar)("OTEL_SERVICE_NAME")
|
566
586
|
}),
|
567
587
|
traceExporter: new import_exporter_trace_otlp_http.OTLPTraceExporter({
|
568
|
-
url: `${(0,
|
588
|
+
url: `${(0, import_common5.getEnvVar)("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/traces`
|
569
589
|
}),
|
570
590
|
metricReader: new import_sdk_metrics.PeriodicExportingMetricReader({
|
571
591
|
exporter: new import_exporter_metrics_otlp_http.OTLPMetricExporter({
|
572
|
-
url: `${(0,
|
592
|
+
url: `${(0, import_common5.getEnvVar)("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/metrics`
|
573
593
|
}),
|
574
594
|
exportIntervalMillis: 5e3
|
575
595
|
}),
|
576
596
|
logRecordProcessors: [
|
577
597
|
new import_sdk_logs.BatchLogRecordProcessor(
|
578
598
|
new import_exporter_logs_otlp_http.OTLPLogExporter({
|
579
|
-
url: `${(0,
|
599
|
+
url: `${(0, import_common5.getEnvVar)("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/logs`
|
580
600
|
})
|
581
601
|
)
|
582
602
|
],
|
@@ -584,11 +604,12 @@ new import_sdk_node.NodeSDK({
|
|
584
604
|
new import_instrumentation_http.HttpInstrumentation({
|
585
605
|
applyCustomAttributesOnSpan: (span, request) => {
|
586
606
|
span.setAttribute(
|
587
|
-
|
588
|
-
(0,
|
607
|
+
import_semantic_conventions2.ATTR_SERVICE_NAME,
|
608
|
+
(0, import_common5.getEnvVar)("OTEL_SERVICE_NAME") ?? "unknown"
|
589
609
|
);
|
590
610
|
if (isForklaunchRequest(request)) {
|
591
|
-
span.setAttribute(
|
611
|
+
span.setAttribute(ATTR_API_NAME, request.contractDetails?.name);
|
612
|
+
span.setAttribute(ATTR_CORRELATION_ID, request.context.correlationId);
|
592
613
|
}
|
593
614
|
}
|
594
615
|
}),
|
@@ -596,10 +617,10 @@ new import_sdk_node.NodeSDK({
|
|
596
617
|
new import_opentelemetry_instrumentation_hyper_express.HyperExpressInstrumentation()
|
597
618
|
]
|
598
619
|
}).start();
|
599
|
-
var httpRequestsTotalCounter = import_api3.metrics.getMeter((0,
|
620
|
+
var httpRequestsTotalCounter = import_api3.metrics.getMeter((0, import_common5.getEnvVar)("OTEL_SERVICE_NAME") || "unknown").createCounter("http_requests_total", {
|
600
621
|
description: "Number of HTTP requests"
|
601
622
|
});
|
602
|
-
var httpServerDurationHistogram = import_api3.metrics.getMeter((0,
|
623
|
+
var httpServerDurationHistogram = import_api3.metrics.getMeter((0, import_common5.getEnvVar)("OTEL_SERVICE_NAME") || "unknown").createHistogram("http_server_duration", {
|
603
624
|
description: "Duration of HTTP server requests",
|
604
625
|
unit: "s"
|
605
626
|
});
|
@@ -618,7 +639,7 @@ function enrichDetails(path, contractDetails, requestSchema, responseSchemas, op
|
|
618
639
|
const [seconds, nanoseconds] = process.hrtime(startTime);
|
619
640
|
const durationMs = seconds + nanoseconds / 1e9;
|
620
641
|
httpServerDurationHistogram.record(durationMs, {
|
621
|
-
[import_semantic_conventions.ATTR_SERVICE_NAME]: (0,
|
642
|
+
[import_semantic_conventions.ATTR_SERVICE_NAME]: (0, import_common6.getEnvVar)("OTEL_SERVICE_NAME") || "unknown",
|
622
643
|
[ATTR_API_NAME]: req.contractDetails?.name || "unknown",
|
623
644
|
[import_semantic_conventions.ATTR_HTTP_REQUEST_METHOD]: req.method,
|
624
645
|
[import_semantic_conventions.ATTR_HTTP_ROUTE]: req.originalPath || "unknown",
|
@@ -630,7 +651,7 @@ function enrichDetails(path, contractDetails, requestSchema, responseSchemas, op
|
|
630
651
|
}
|
631
652
|
|
632
653
|
// src/http/middleware/request/parse.middleware.ts
|
633
|
-
var
|
654
|
+
var import_common7 = require("@forklaunch/common");
|
634
655
|
var import_validator = require("@forklaunch/validator");
|
635
656
|
|
636
657
|
// src/http/guards/hasSend.ts
|
@@ -656,7 +677,7 @@ function parse(req, res, next) {
|
|
656
677
|
let parsedRequest;
|
657
678
|
let collectedParseErrors;
|
658
679
|
if (req.contractDetails.versions) {
|
659
|
-
if ((0,
|
680
|
+
if ((0, import_common7.isRecord)(req.requestSchema)) {
|
660
681
|
let runningParseErrors = "";
|
661
682
|
matchedVersions = [];
|
662
683
|
Object.entries(req.requestSchema).forEach(([version, schema]) => {
|
@@ -1045,13 +1066,13 @@ var ForklaunchExpressLikeRouter = class _ForklaunchExpressLikeRouter {
|
|
1045
1066
|
versionedContractDetails,
|
1046
1067
|
contractDetails.params
|
1047
1068
|
);
|
1048
|
-
if ((0,
|
1069
|
+
if ((0, import_common8.isRecord)(requestSchema)) {
|
1049
1070
|
requestSchema = {
|
1050
1071
|
...requestSchema,
|
1051
1072
|
[version]: versionedRequestSchema
|
1052
1073
|
};
|
1053
1074
|
}
|
1054
|
-
if ((0,
|
1075
|
+
if ((0, import_common8.isRecord)(responseSchemas)) {
|
1055
1076
|
responseSchemas = {
|
1056
1077
|
...responseSchemas,
|
1057
1078
|
[version]: versionedResponseSchemas
|
@@ -1238,8 +1259,8 @@ var ForklaunchExpressLikeRouter = class _ForklaunchExpressLikeRouter {
|
|
1238
1259
|
...resolvedMiddlewares,
|
1239
1260
|
this.#parseAndRunControllerHandler(controllerHandler)
|
1240
1261
|
);
|
1241
|
-
(0,
|
1242
|
-
...this._fetchMap[(0,
|
1262
|
+
(0, import_common8.toRecord)(this._fetchMap)[(0, import_common8.sanitizePathSlashes)(`${this.basePath}${path}`)] = {
|
1263
|
+
...this._fetchMap[(0, import_common8.sanitizePathSlashes)(`${this.basePath}${path}`)] ?? {},
|
1243
1264
|
[method.toUpperCase()]: contractDetails.versions ? Object.fromEntries(
|
1244
1265
|
Object.keys(contractDetails.versions).map((version) => [
|
1245
1266
|
version,
|
@@ -1247,7 +1268,7 @@ var ForklaunchExpressLikeRouter = class _ForklaunchExpressLikeRouter {
|
|
1247
1268
|
])
|
1248
1269
|
) : this.#localParamRequest(handlers, controllerHandler)
|
1249
1270
|
};
|
1250
|
-
(0,
|
1271
|
+
(0, import_common8.toRecord)(this.sdk)[(0, import_common8.toPrettyCamelCase)(contractDetails.name)] = contractDetails.versions ? Object.fromEntries(
|
1251
1272
|
Object.keys(contractDetails.versions).map((version) => [
|
1252
1273
|
version,
|
1253
1274
|
(req) => this.#localParamRequest(
|
@@ -1346,10 +1367,10 @@ var ForklaunchExpressLikeRouter = class _ForklaunchExpressLikeRouter {
|
|
1346
1367
|
}
|
1347
1368
|
addRouterToSdk(router) {
|
1348
1369
|
Object.entries(router._fetchMap).map(
|
1349
|
-
([key, value]) => (0,
|
1370
|
+
([key, value]) => (0, import_common8.toRecord)(this._fetchMap)[(0, import_common8.sanitizePathSlashes)(`${this.basePath}${key}`)] = value
|
1350
1371
|
);
|
1351
|
-
const existingSdk = this.sdk[router.sdkName ?? (0,
|
1352
|
-
(0,
|
1372
|
+
const existingSdk = this.sdk[router.sdkName ?? (0, import_common8.toPrettyCamelCase)(router.basePath)];
|
1373
|
+
(0, import_common8.toRecord)(this.sdk)[router.sdkName ?? (0, import_common8.toPrettyCamelCase)(router.basePath)] = {
|
1353
1374
|
...typeof existingSdk === "object" ? existingSdk : {},
|
1354
1375
|
...router.sdk
|
1355
1376
|
};
|
@@ -2717,9 +2738,9 @@ var getCodeForStatus = (status) => {
|
|
2717
2738
|
var httpStatusCodes_default = HTTPStatuses;
|
2718
2739
|
|
2719
2740
|
// src/http/mcpGenerator/mcpGenerator.ts
|
2720
|
-
var
|
2741
|
+
var import_common9 = require("@forklaunch/common");
|
2742
|
+
var import_fastmcp_fork = require("@forklaunch/fastmcp-fork");
|
2721
2743
|
var import_zod = require("@forklaunch/validator/zod");
|
2722
|
-
var import_fastmcp = require("fastmcp");
|
2723
2744
|
|
2724
2745
|
// src/http/guards/isVersionedInputSchema.ts
|
2725
2746
|
function isUnionable(schema) {
|
@@ -2729,8 +2750,9 @@ function isUnionable(schema) {
|
|
2729
2750
|
// src/http/router/unpackRouters.ts
|
2730
2751
|
function unpackRouters(routers, recursiveBasePath = []) {
|
2731
2752
|
return routers.reduce((acc, router) => {
|
2753
|
+
const fullPath = [...recursiveBasePath, router.basePath].join("");
|
2732
2754
|
acc.push({
|
2733
|
-
fullPath
|
2755
|
+
fullPath,
|
2734
2756
|
router
|
2735
2757
|
});
|
2736
2758
|
acc.push(
|
@@ -2768,18 +2790,26 @@ function generateInputSchema(schemaValidator, body, params, query, requestHeader
|
|
2768
2790
|
} : {}
|
2769
2791
|
});
|
2770
2792
|
}
|
2771
|
-
function generateMcpServer(schemaValidator, protocol, host, port, version,
|
2793
|
+
function generateMcpServer(schemaValidator, protocol, host, port, version, application, options2, contentTypeMap) {
|
2772
2794
|
if (!(schemaValidator instanceof import_zod.ZodSchemaValidator)) {
|
2773
2795
|
throw new Error(
|
2774
2796
|
"Schema validator must be an instance of ZodSchemaValidator"
|
2775
2797
|
);
|
2776
2798
|
}
|
2777
|
-
const mcpServer = new
|
2799
|
+
const mcpServer = new import_fastmcp_fork.FastMCP({
|
2778
2800
|
...options2,
|
2779
2801
|
name: options2?.name ?? "mcp-server",
|
2780
2802
|
version
|
2781
2803
|
});
|
2782
|
-
|
2804
|
+
[
|
2805
|
+
{
|
2806
|
+
fullPath: application.basePath === "/" ? "" : application.basePath,
|
2807
|
+
router: application
|
2808
|
+
},
|
2809
|
+
...unpackRouters(application.routers, [
|
2810
|
+
application.basePath === "/" ? "" : application.basePath
|
2811
|
+
])
|
2812
|
+
].forEach(({ fullPath, router }) => {
|
2783
2813
|
router.routes.forEach((route) => {
|
2784
2814
|
const inputSchemas = [];
|
2785
2815
|
if (route.contractDetails.versions) {
|
@@ -2842,7 +2872,7 @@ function generateMcpServer(schemaValidator, protocol, host, port, version, route
|
|
2842
2872
|
if (discriminatedBody) {
|
2843
2873
|
switch (discriminatedBody.parserType) {
|
2844
2874
|
case "json": {
|
2845
|
-
parsedBody = (0,
|
2875
|
+
parsedBody = (0, import_common9.safeStringify)(body);
|
2846
2876
|
break;
|
2847
2877
|
}
|
2848
2878
|
case "text": {
|
@@ -2855,7 +2885,7 @@ function generateMcpServer(schemaValidator, protocol, host, port, version, route
|
|
2855
2885
|
}
|
2856
2886
|
case "multipart": {
|
2857
2887
|
const formData = new FormData();
|
2858
|
-
if ((0,
|
2888
|
+
if ((0, import_common9.isRecord)(body)) {
|
2859
2889
|
for (const key in body) {
|
2860
2890
|
if (typeof body[key] === "string" || body[key] instanceof Blob) {
|
2861
2891
|
formData.append(key, body[key]);
|
@@ -2870,11 +2900,11 @@ function generateMcpServer(schemaValidator, protocol, host, port, version, route
|
|
2870
2900
|
break;
|
2871
2901
|
}
|
2872
2902
|
case "urlEncoded": {
|
2873
|
-
if ((0,
|
2903
|
+
if ((0, import_common9.isRecord)(body)) {
|
2874
2904
|
parsedBody = new URLSearchParams(
|
2875
2905
|
Object.entries(body).map(([key, value]) => [
|
2876
2906
|
key,
|
2877
|
-
(0,
|
2907
|
+
(0, import_common9.safeStringify)(value)
|
2878
2908
|
])
|
2879
2909
|
);
|
2880
2910
|
} else {
|
@@ -2883,8 +2913,8 @@ function generateMcpServer(schemaValidator, protocol, host, port, version, route
|
|
2883
2913
|
break;
|
2884
2914
|
}
|
2885
2915
|
default: {
|
2886
|
-
(0,
|
2887
|
-
parsedBody = (0,
|
2916
|
+
(0, import_common9.isNever)(discriminatedBody.parserType);
|
2917
|
+
parsedBody = (0, import_common9.safeStringify)(body);
|
2888
2918
|
break;
|
2889
2919
|
}
|
2890
2920
|
}
|
@@ -2893,7 +2923,7 @@ function generateMcpServer(schemaValidator, protocol, host, port, version, route
|
|
2893
2923
|
const queryString = new URLSearchParams(
|
2894
2924
|
Object.entries(query).map(([key, value]) => [
|
2895
2925
|
key,
|
2896
|
-
(0,
|
2926
|
+
(0, import_common9.safeStringify)(value)
|
2897
2927
|
])
|
2898
2928
|
).toString();
|
2899
2929
|
url += queryString ? `?${queryString}` : "";
|
@@ -2926,7 +2956,7 @@ function generateMcpServer(schemaValidator, protocol, host, port, version, route
|
|
2926
2956
|
content: [
|
2927
2957
|
{
|
2928
2958
|
type: "text",
|
2929
|
-
text: (0,
|
2959
|
+
text: (0, import_common9.safeStringify)(await response.json())
|
2930
2960
|
}
|
2931
2961
|
]
|
2932
2962
|
};
|
@@ -3073,18 +3103,18 @@ ${parseErrors.join("\n\n")}`
|
|
3073
3103
|
}
|
3074
3104
|
|
3075
3105
|
// src/http/middleware/response/enrichExpressLikeSend.middleware.ts
|
3076
|
-
var
|
3106
|
+
var import_common11 = require("@forklaunch/common");
|
3077
3107
|
var import_stream = require("stream");
|
3078
3108
|
|
3079
3109
|
// src/http/telemetry/recordMetric.ts
|
3080
|
-
var
|
3110
|
+
var import_common10 = require("@forklaunch/common");
|
3081
3111
|
var import_semantic_conventions3 = require("@opentelemetry/semantic-conventions");
|
3082
3112
|
function recordMetric(req, res) {
|
3083
3113
|
if (res.metricRecorded) {
|
3084
3114
|
return;
|
3085
3115
|
}
|
3086
3116
|
httpRequestsTotalCounter.add(1, {
|
3087
|
-
[import_semantic_conventions3.ATTR_SERVICE_NAME]: (0,
|
3117
|
+
[import_semantic_conventions3.ATTR_SERVICE_NAME]: (0, import_common10.getEnvVar)("OTEL_SERVICE_NAME"),
|
3088
3118
|
[ATTR_API_NAME]: req.contractDetails?.name,
|
3089
3119
|
[ATTR_CORRELATION_ID]: req.context.correlationId,
|
3090
3120
|
[import_semantic_conventions3.ATTR_HTTP_REQUEST_METHOD]: req.method,
|
@@ -3134,8 +3164,8 @@ function enrichExpressLikeSend(instance, req, res, originalOperation, originalSe
|
|
3134
3164
|
`attachment; filename="${data.name}"`
|
3135
3165
|
);
|
3136
3166
|
}
|
3137
|
-
if ((0,
|
3138
|
-
import_stream.Readable.from((0,
|
3167
|
+
if ((0, import_common11.isNodeJsWriteableStream)(res)) {
|
3168
|
+
import_stream.Readable.from((0, import_common11.readableStreamToAsyncIterable)(data.stream())).pipe(
|
3139
3169
|
res
|
3140
3170
|
);
|
3141
3171
|
} else {
|
@@ -3144,7 +3174,7 @@ function enrichExpressLikeSend(instance, req, res, originalOperation, originalSe
|
|
3144
3174
|
originalSend.call(instance, "Not a NodeJS WritableStream");
|
3145
3175
|
errorSent = true;
|
3146
3176
|
}
|
3147
|
-
} else if ((0,
|
3177
|
+
} else if ((0, import_common11.isAsyncGenerator)(data)) {
|
3148
3178
|
let firstPass = true;
|
3149
3179
|
const transformer = new import_stream.Transform({
|
3150
3180
|
objectMode: true,
|
@@ -3172,7 +3202,7 @@ ${res.locals.errorMessage}`;
|
|
3172
3202
|
if (!errorSent) {
|
3173
3203
|
let data2 = "";
|
3174
3204
|
for (const [key, value] of Object.entries(chunk)) {
|
3175
|
-
data2 += `${key}: ${typeof value === "string" ? value : (0,
|
3205
|
+
data2 += `${key}: ${typeof value === "string" ? value : (0, import_common11.safeStringify)(value)}
|
3176
3206
|
`;
|
3177
3207
|
}
|
3178
3208
|
data2 += "\n";
|
@@ -3180,7 +3210,7 @@ ${res.locals.errorMessage}`;
|
|
3180
3210
|
}
|
3181
3211
|
}
|
3182
3212
|
});
|
3183
|
-
if ((0,
|
3213
|
+
if ((0, import_common11.isNodeJsWriteableStream)(res)) {
|
3184
3214
|
import_stream.Readable.from(data).pipe(transformer).pipe(res);
|
3185
3215
|
} else {
|
3186
3216
|
res.type("text/plain");
|
@@ -3191,7 +3221,7 @@ ${res.locals.errorMessage}`;
|
|
3191
3221
|
} else {
|
3192
3222
|
const parserType = responseBodies?.[Number(res.statusCode)]?.parserType;
|
3193
3223
|
res.bodyData = data;
|
3194
|
-
if ((0,
|
3224
|
+
if ((0, import_common11.isRecord)(data)) {
|
3195
3225
|
switch (parserType) {
|
3196
3226
|
case "json":
|
3197
3227
|
res.bodyData = "json" in data ? data.json : data;
|
@@ -3212,7 +3242,7 @@ ${res.locals.errorMessage}`;
|
|
3212
3242
|
res.bodyData = data;
|
3213
3243
|
break;
|
3214
3244
|
default:
|
3215
|
-
(0,
|
3245
|
+
(0, import_common11.isNever)(parserType);
|
3216
3246
|
res.bodyData = data;
|
3217
3247
|
break;
|
3218
3248
|
}
|
@@ -3248,7 +3278,7 @@ ${res.locals.errorMessage}`;
|
|
3248
3278
|
}
|
3249
3279
|
|
3250
3280
|
// src/http/openApiV3Generator/openApiV3Generator.ts
|
3251
|
-
var
|
3281
|
+
var import_common12 = require("@forklaunch/common");
|
3252
3282
|
var OPENAPI_DEFAULT_VERSION = Symbol("default");
|
3253
3283
|
function toUpperCase(str) {
|
3254
3284
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
@@ -3259,7 +3289,7 @@ function transformBasePath(basePath) {
|
|
3259
3289
|
}
|
3260
3290
|
return `/${basePath}`;
|
3261
3291
|
}
|
3262
|
-
function generateOpenApiDocument(
|
3292
|
+
function generateOpenApiDocument(serverUrls, serverDescriptions, versionedTags, versionedPaths, versionedSecuritySchemes, otherServers) {
|
3263
3293
|
return {
|
3264
3294
|
[OPENAPI_DEFAULT_VERSION]: {
|
3265
3295
|
openapi: "3.1.0",
|
@@ -3272,10 +3302,10 @@ function generateOpenApiDocument(protocol, host, port, versionedTags, versionedP
|
|
3272
3302
|
},
|
3273
3303
|
tags: versionedTags[OPENAPI_DEFAULT_VERSION],
|
3274
3304
|
servers: [
|
3275
|
-
{
|
3276
|
-
url
|
3277
|
-
description:
|
3278
|
-
},
|
3305
|
+
...serverUrls.map((url, index) => ({
|
3306
|
+
url,
|
3307
|
+
description: serverDescriptions?.[index]
|
3308
|
+
})),
|
3279
3309
|
...otherServers || []
|
3280
3310
|
],
|
3281
3311
|
paths: versionedPaths[OPENAPI_DEFAULT_VERSION]
|
@@ -3294,10 +3324,11 @@ function generateOpenApiDocument(protocol, host, port, versionedTags, versionedP
|
|
3294
3324
|
},
|
3295
3325
|
tags: versionedTags[version],
|
3296
3326
|
servers: [
|
3297
|
-
{
|
3298
|
-
url
|
3299
|
-
description:
|
3300
|
-
}
|
3327
|
+
...serverUrls.map((url, index) => ({
|
3328
|
+
url,
|
3329
|
+
description: serverDescriptions?.[index]
|
3330
|
+
})),
|
3331
|
+
...otherServers || []
|
3301
3332
|
],
|
3302
3333
|
paths
|
3303
3334
|
}
|
@@ -3446,7 +3477,7 @@ function generateOperationObject(schemaValidator, path, method, controllerName,
|
|
3446
3477
|
}
|
3447
3478
|
return operationObject;
|
3448
3479
|
}
|
3449
|
-
function generateOpenApiSpecs(schemaValidator,
|
3480
|
+
function generateOpenApiSpecs(schemaValidator, serverUrls, serverDescriptions, application, otherServers) {
|
3450
3481
|
const versionedPaths = {
|
3451
3482
|
[OPENAPI_DEFAULT_VERSION]: {}
|
3452
3483
|
};
|
@@ -3456,10 +3487,18 @@ function generateOpenApiSpecs(schemaValidator, protocol, host, port, routers, ot
|
|
3456
3487
|
const versionedSecuritySchemes = {
|
3457
3488
|
[OPENAPI_DEFAULT_VERSION]: {}
|
3458
3489
|
};
|
3459
|
-
|
3490
|
+
[
|
3491
|
+
{
|
3492
|
+
fullPath: application.basePath === "/" ? "" : application.basePath,
|
3493
|
+
router: application
|
3494
|
+
},
|
3495
|
+
...unpackRouters(application.routers, [
|
3496
|
+
application.basePath === "/" ? "" : application.basePath
|
3497
|
+
])
|
3498
|
+
].forEach(({ fullPath, router }) => {
|
3460
3499
|
const controllerName = transformBasePath(fullPath);
|
3461
3500
|
router.routes.forEach((route) => {
|
3462
|
-
const openApiPath = (0,
|
3501
|
+
const openApiPath = (0, import_common12.openApiCompliantPath)(
|
3463
3502
|
`${fullPath}${route.path === "/" ? "" : route.path}`
|
3464
3503
|
);
|
3465
3504
|
const { name, summary, params, versions, auth } = route.contractDetails;
|
@@ -3551,9 +3590,8 @@ function generateOpenApiSpecs(schemaValidator, protocol, host, port, routers, ot
|
|
3551
3590
|
});
|
3552
3591
|
});
|
3553
3592
|
return generateOpenApiDocument(
|
3554
|
-
|
3555
|
-
|
3556
|
-
port,
|
3593
|
+
serverUrls,
|
3594
|
+
serverDescriptions,
|
3557
3595
|
versionedTags,
|
3558
3596
|
versionedPaths,
|
3559
3597
|
versionedSecuritySchemes,
|
@@ -3562,7 +3600,7 @@ function generateOpenApiSpecs(schemaValidator, protocol, host, port, routers, ot
|
|
3562
3600
|
}
|
3563
3601
|
|
3564
3602
|
// src/http/sdk/sdkClient.ts
|
3565
|
-
var
|
3603
|
+
var import_common13 = require("@forklaunch/common");
|
3566
3604
|
|
3567
3605
|
// src/http/guards/isSdkRouter.ts
|
3568
3606
|
function isSdkRouter(value) {
|
@@ -3574,12 +3612,12 @@ function mapToSdk(schemaValidator, routerMap, runningPath = void 0) {
|
|
3574
3612
|
const routerUniquenessCache = /* @__PURE__ */ new Set();
|
3575
3613
|
return Object.fromEntries(
|
3576
3614
|
Object.entries(routerMap).map(([key, value]) => {
|
3577
|
-
if (routerUniquenessCache.has((0,
|
3615
|
+
if (routerUniquenessCache.has((0, import_common13.hashString)((0, import_common13.safeStringify)(value)))) {
|
3578
3616
|
throw new Error(
|
3579
3617
|
`SdkClient: Cannot use the same router pointer twice. Please clone the duplicate router with .clone() or only use the router once.`
|
3580
3618
|
);
|
3581
3619
|
}
|
3582
|
-
routerUniquenessCache.add((0,
|
3620
|
+
routerUniquenessCache.add((0, import_common13.hashString)((0, import_common13.safeStringify)(value)));
|
3583
3621
|
const currentPath = runningPath ? [runningPath, key].join(".") : key;
|
3584
3622
|
if (isSdkRouter(value)) {
|
3585
3623
|
Object.entries(value.sdkPaths).forEach(([routePath, sdkKey]) => {
|
@@ -3628,7 +3666,7 @@ function mapToFetch(schemaValidator, routerMap) {
|
|
3628
3666
|
return (path, ...reqInit) => {
|
3629
3667
|
const method = reqInit[0]?.method;
|
3630
3668
|
const version = reqInit[0] != null && "version" in reqInit[0] ? reqInit[0].version : void 0;
|
3631
|
-
return (version ? (0,
|
3669
|
+
return (version ? (0, import_common13.toRecord)((0, import_common13.toRecord)(flattenedFetchMap[path])[method ?? "GET"])[version] : (0, import_common13.toRecord)(flattenedFetchMap[path])[method ?? "GET"])(path, reqInit[0]);
|
3632
3670
|
};
|
3633
3671
|
}
|
3634
3672
|
function sdkClient(schemaValidator, routerMap) {
|
@@ -3640,7 +3678,7 @@ function sdkClient(schemaValidator, routerMap) {
|
|
3640
3678
|
}
|
3641
3679
|
|
3642
3680
|
// src/http/sdk/sdkRouter.ts
|
3643
|
-
var
|
3681
|
+
var import_common14 = require("@forklaunch/common");
|
3644
3682
|
function sdkRouter(schemaValidator, controller, router) {
|
3645
3683
|
const controllerSdkPaths = [];
|
3646
3684
|
const mappedSdk = Object.fromEntries(
|
@@ -3650,7 +3688,7 @@ function sdkRouter(schemaValidator, controller, router) {
|
|
3650
3688
|
router.sdkPaths[sdkPath] = key;
|
3651
3689
|
return [
|
3652
3690
|
key,
|
3653
|
-
router.sdk[(0,
|
3691
|
+
router.sdk[(0, import_common14.toPrettyCamelCase)(value.contractDetails.name)]
|
3654
3692
|
];
|
3655
3693
|
})
|
3656
3694
|
);
|