@forklaunch/core 0.8.6 → 0.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/src/http/index.d.mts +13 -1
- package/lib/src/http/index.d.ts +13 -1
- package/lib/src/http/index.js +38 -37
- package/lib/src/http/index.js.map +1 -1
- package/lib/src/http/index.mjs +24 -25
- package/lib/src/http/index.mjs.map +1 -1
- package/lib/src/services/index.d.mts +2 -2
- package/lib/src/services/index.d.ts +2 -2
- package/lib/src/services/index.js +6 -6
- package/lib/src/services/index.js.map +1 -1
- package/lib/src/services/index.mjs +6 -6
- package/lib/src/services/index.mjs.map +1 -1
- package/package.json +17 -17
package/lib/src/http/index.d.mts
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import { AnySchemaValidator, UnboxedObjectSchema, IdiomaticSchema, Schema } from '@forklaunch/validator';
|
2
|
+
import { CorsOptions } from 'cors';
|
2
3
|
import { Counter, Gauge, Histogram, UpDownCounter, ObservableCounter, ObservableGauge, ObservableUpDownCounter, Span } from '@opentelemetry/api';
|
3
4
|
import { LevelWithSilentOrString, LevelWithSilent, Logger } from 'pino';
|
4
5
|
import { UnionToIntersection, MimeType, Prettify, ExclusiveRecord, RemoveTrailingSlash, MakePropertyOptionalIfChildrenOptional } from '@forklaunch/common';
|
@@ -491,6 +492,12 @@ interface ForklaunchResponse<BaseResponse, ResBodyMap extends Record<number, unk
|
|
491
492
|
* @returns {Omit<ResHeaders, keyof ForklaunchResHeaders> & ForklaunchResHeaders} - The headers of the response.
|
492
493
|
*/
|
493
494
|
getHeaders: () => Omit<ResHeaders, keyof ForklaunchResHeaders> & ForklaunchResHeaders;
|
495
|
+
/**
|
496
|
+
* Gets a header for the response.
|
497
|
+
* @param {string} key - The header key.
|
498
|
+
* @returns {string | string[] | undefined} The header value.
|
499
|
+
*/
|
500
|
+
getHeader: (key: string) => string | string[] | undefined;
|
494
501
|
/**
|
495
502
|
* Sets a header for the response.
|
496
503
|
* @param {string} key - The header key.
|
@@ -946,12 +953,17 @@ declare abstract class ForklaunchExpressLikeApplication<SV extends AnySchemaVali
|
|
946
953
|
readonly internal: Server;
|
947
954
|
readonly postEnrichMiddleware: RouterHandler[];
|
948
955
|
readonly openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>;
|
956
|
+
readonly appOptions?: {
|
957
|
+
cors?: CorsOptions;
|
958
|
+
} | undefined;
|
949
959
|
/**
|
950
960
|
* Creates an instance of the Application class.
|
951
961
|
*
|
952
962
|
* @param {SV} schemaValidator - The schema validator.
|
953
963
|
*/
|
954
|
-
constructor(schemaValidator: SV, internal: Server, postEnrichMiddleware: RouterHandler[], openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition
|
964
|
+
constructor(schemaValidator: SV, internal: Server, postEnrichMiddleware: RouterHandler[], openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>, appOptions?: {
|
965
|
+
cors?: CorsOptions;
|
966
|
+
} | undefined);
|
955
967
|
abstract listen(...args: unknown[]): void;
|
956
968
|
}
|
957
969
|
|
package/lib/src/http/index.d.ts
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import { AnySchemaValidator, UnboxedObjectSchema, IdiomaticSchema, Schema } from '@forklaunch/validator';
|
2
|
+
import { CorsOptions } from 'cors';
|
2
3
|
import { Counter, Gauge, Histogram, UpDownCounter, ObservableCounter, ObservableGauge, ObservableUpDownCounter, Span } from '@opentelemetry/api';
|
3
4
|
import { LevelWithSilentOrString, LevelWithSilent, Logger } from 'pino';
|
4
5
|
import { UnionToIntersection, MimeType, Prettify, ExclusiveRecord, RemoveTrailingSlash, MakePropertyOptionalIfChildrenOptional } from '@forklaunch/common';
|
@@ -491,6 +492,12 @@ interface ForklaunchResponse<BaseResponse, ResBodyMap extends Record<number, unk
|
|
491
492
|
* @returns {Omit<ResHeaders, keyof ForklaunchResHeaders> & ForklaunchResHeaders} - The headers of the response.
|
492
493
|
*/
|
493
494
|
getHeaders: () => Omit<ResHeaders, keyof ForklaunchResHeaders> & ForklaunchResHeaders;
|
495
|
+
/**
|
496
|
+
* Gets a header for the response.
|
497
|
+
* @param {string} key - The header key.
|
498
|
+
* @returns {string | string[] | undefined} The header value.
|
499
|
+
*/
|
500
|
+
getHeader: (key: string) => string | string[] | undefined;
|
494
501
|
/**
|
495
502
|
* Sets a header for the response.
|
496
503
|
* @param {string} key - The header key.
|
@@ -946,12 +953,17 @@ declare abstract class ForklaunchExpressLikeApplication<SV extends AnySchemaVali
|
|
946
953
|
readonly internal: Server;
|
947
954
|
readonly postEnrichMiddleware: RouterHandler[];
|
948
955
|
readonly openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>;
|
956
|
+
readonly appOptions?: {
|
957
|
+
cors?: CorsOptions;
|
958
|
+
} | undefined;
|
949
959
|
/**
|
950
960
|
* Creates an instance of the Application class.
|
951
961
|
*
|
952
962
|
* @param {SV} schemaValidator - The schema validator.
|
953
963
|
*/
|
954
|
-
constructor(schemaValidator: SV, internal: Server, postEnrichMiddleware: RouterHandler[], openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition
|
964
|
+
constructor(schemaValidator: SV, internal: Server, postEnrichMiddleware: RouterHandler[], openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>, appOptions?: {
|
965
|
+
cors?: CorsOptions;
|
966
|
+
} | undefined);
|
955
967
|
abstract listen(...args: unknown[]): void;
|
956
968
|
}
|
957
969
|
|
package/lib/src/http/index.js
CHANGED
@@ -75,12 +75,19 @@ module.exports = __toCommonJS(http_exports);
|
|
75
75
|
|
76
76
|
// src/http/middleware/request/cors.middleware.ts
|
77
77
|
var import_cors = __toESM(require("cors"));
|
78
|
-
function cors(
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
78
|
+
function cors(corsOptions) {
|
79
|
+
return (req, res, next) => {
|
80
|
+
if (req.method === "OPTIONS") {
|
81
|
+
res.cors = true;
|
82
|
+
}
|
83
|
+
if (!res.getHeader) {
|
84
|
+
res.getHeader = (key) => {
|
85
|
+
return res.getHeaders()[key];
|
86
|
+
};
|
87
|
+
}
|
88
|
+
(0, import_cors.default)(corsOptions)(req, res, next ?? (() => {
|
89
|
+
}));
|
90
|
+
};
|
84
91
|
}
|
85
92
|
|
86
93
|
// src/http/middleware/request/createContext.middleware.ts
|
@@ -288,13 +295,11 @@ async function parseRequestAuth(req, res, next) {
|
|
288
295
|
next?.();
|
289
296
|
}
|
290
297
|
|
291
|
-
// src/
|
292
|
-
|
293
|
-
const value = process.env[name];
|
294
|
-
return value;
|
295
|
-
}
|
298
|
+
// src/http/middleware/request/enrichDetails.middleware.ts
|
299
|
+
var import_common4 = require("@forklaunch/common");
|
296
300
|
|
297
301
|
// src/http/telemetry/openTelemetryCollector.ts
|
302
|
+
var import_common3 = require("@forklaunch/common");
|
298
303
|
var import_opentelemetry_instrumentation_hyper_express = require("@forklaunch/opentelemetry-instrumentation-hyper-express");
|
299
304
|
var import_api3 = require("@opentelemetry/api");
|
300
305
|
var import_exporter_logs_otlp_http = require("@opentelemetry/exporter-logs-otlp-http");
|
@@ -488,24 +493,24 @@ var OpenTelemetryCollector = class {
|
|
488
493
|
return this.metrics[metricId];
|
489
494
|
}
|
490
495
|
};
|
491
|
-
import_dotenv.default.config({ path: getEnvVar("ENV_FILE_PATH") });
|
496
|
+
import_dotenv.default.config({ path: (0, import_common3.getEnvVar)("ENV_FILE_PATH") });
|
492
497
|
new import_sdk_node.NodeSDK({
|
493
498
|
resource: (0, import_resources.resourceFromAttributes)({
|
494
|
-
[import_semantic_conventions2.ATTR_SERVICE_NAME]: getEnvVar("OTEL_SERVICE_NAME")
|
499
|
+
[import_semantic_conventions2.ATTR_SERVICE_NAME]: (0, import_common3.getEnvVar)("OTEL_SERVICE_NAME")
|
495
500
|
}),
|
496
501
|
traceExporter: new import_exporter_trace_otlp_http.OTLPTraceExporter({
|
497
|
-
url: `${getEnvVar("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/traces`
|
502
|
+
url: `${(0, import_common3.getEnvVar)("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/traces`
|
498
503
|
}),
|
499
504
|
metricReader: new import_sdk_metrics.PeriodicExportingMetricReader({
|
500
505
|
exporter: new import_exporter_metrics_otlp_http.OTLPMetricExporter({
|
501
|
-
url: `${getEnvVar("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/metrics`
|
506
|
+
url: `${(0, import_common3.getEnvVar)("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/metrics`
|
502
507
|
}),
|
503
508
|
exportIntervalMillis: 5e3
|
504
509
|
}),
|
505
510
|
logRecordProcessors: [
|
506
511
|
new import_sdk_logs.BatchLogRecordProcessor(
|
507
512
|
new import_exporter_logs_otlp_http.OTLPLogExporter({
|
508
|
-
url: `${getEnvVar("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/logs`
|
513
|
+
url: `${(0, import_common3.getEnvVar)("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/logs`
|
509
514
|
})
|
510
515
|
)
|
511
516
|
],
|
@@ -514,7 +519,7 @@ new import_sdk_node.NodeSDK({
|
|
514
519
|
applyCustomAttributesOnSpan: (span, request) => {
|
515
520
|
span.setAttribute(
|
516
521
|
"service.name",
|
517
|
-
getEnvVar("OTEL_SERVICE_NAME") ?? "unknown"
|
522
|
+
(0, import_common3.getEnvVar)("OTEL_SERVICE_NAME") ?? "unknown"
|
518
523
|
);
|
519
524
|
if (isForklaunchRequest(request)) {
|
520
525
|
span.setAttribute("api.name", request.contractDetails?.name);
|
@@ -525,10 +530,10 @@ new import_sdk_node.NodeSDK({
|
|
525
530
|
new import_opentelemetry_instrumentation_hyper_express.HyperExpressInstrumentation()
|
526
531
|
]
|
527
532
|
}).start();
|
528
|
-
var httpRequestsTotalCounter = import_api3.metrics.getMeter(getEnvVar("OTEL_SERVICE_NAME") || "unknown").createCounter("http_requests_total", {
|
533
|
+
var httpRequestsTotalCounter = import_api3.metrics.getMeter((0, import_common3.getEnvVar)("OTEL_SERVICE_NAME") || "unknown").createCounter("http_requests_total", {
|
529
534
|
description: "Number of HTTP requests"
|
530
535
|
});
|
531
|
-
var httpServerDurationHistogram = import_api3.metrics.getMeter(getEnvVar("OTEL_SERVICE_NAME") || "unknown").createHistogram("http_server_duration", {
|
536
|
+
var httpServerDurationHistogram = import_api3.metrics.getMeter((0, import_common3.getEnvVar)("OTEL_SERVICE_NAME") || "unknown").createHistogram("http_server_duration", {
|
532
537
|
description: "Duration of HTTP server requests",
|
533
538
|
unit: "s"
|
534
539
|
});
|
@@ -547,7 +552,7 @@ function enrichDetails(path, contractDetails, requestSchema, responseSchemas, op
|
|
547
552
|
const [seconds, nanoseconds] = process.hrtime(startTime);
|
548
553
|
const durationMs = seconds + nanoseconds / 1e9;
|
549
554
|
httpServerDurationHistogram.record(durationMs, {
|
550
|
-
[import_semantic_conventions.ATTR_SERVICE_NAME]: getEnvVar("OTEL_SERVICE_NAME") || "unknown",
|
555
|
+
[import_semantic_conventions.ATTR_SERVICE_NAME]: (0, import_common4.getEnvVar)("OTEL_SERVICE_NAME") || "unknown",
|
551
556
|
[ATTR_API_NAME]: req.contractDetails?.name || "unknown",
|
552
557
|
[import_semantic_conventions.ATTR_HTTP_REQUEST_METHOD]: req.method,
|
553
558
|
[import_semantic_conventions.ATTR_HTTP_ROUTE]: req.originalPath || "unknown",
|
@@ -1365,7 +1370,7 @@ var ForklaunchExpressLikeApplication = class extends ForklaunchExpressLikeRouter
|
|
1365
1370
|
*
|
1366
1371
|
* @param {SV} schemaValidator - The schema validator.
|
1367
1372
|
*/
|
1368
|
-
constructor(schemaValidator, internal, postEnrichMiddleware, openTelemetryCollector) {
|
1373
|
+
constructor(schemaValidator, internal, postEnrichMiddleware, openTelemetryCollector, appOptions) {
|
1369
1374
|
super(
|
1370
1375
|
"/",
|
1371
1376
|
schemaValidator,
|
@@ -1377,8 +1382,9 @@ var ForklaunchExpressLikeApplication = class extends ForklaunchExpressLikeRouter
|
|
1377
1382
|
this.internal = internal;
|
1378
1383
|
this.postEnrichMiddleware = postEnrichMiddleware;
|
1379
1384
|
this.openTelemetryCollector = openTelemetryCollector;
|
1385
|
+
this.appOptions = appOptions;
|
1380
1386
|
this.internal.use(createContext(this.schemaValidator));
|
1381
|
-
this.internal.use(cors);
|
1387
|
+
this.internal.use(cors(this.appOptions?.cors ?? {}));
|
1382
1388
|
}
|
1383
1389
|
};
|
1384
1390
|
|
@@ -2504,23 +2510,18 @@ ${parseErrors.join("\n\n")}`
|
|
2504
2510
|
}
|
2505
2511
|
|
2506
2512
|
// src/http/middleware/response/enrichExpressLikeSend.middleware.ts
|
2507
|
-
var
|
2513
|
+
var import_common6 = require("@forklaunch/common");
|
2508
2514
|
var import_stream = require("stream");
|
2509
2515
|
|
2510
2516
|
// src/http/telemetry/recordMetric.ts
|
2517
|
+
var import_common5 = require("@forklaunch/common");
|
2511
2518
|
var import_semantic_conventions3 = require("@opentelemetry/semantic-conventions");
|
2512
|
-
|
2513
|
-
// src/services/configInjector.ts
|
2514
|
-
var import_common3 = require("@forklaunch/common");
|
2515
|
-
var import_validator3 = require("@forklaunch/validator");
|
2516
|
-
|
2517
|
-
// src/http/telemetry/recordMetric.ts
|
2518
2519
|
function recordMetric(req, res) {
|
2519
2520
|
if (res.metricRecorded) {
|
2520
2521
|
return;
|
2521
2522
|
}
|
2522
2523
|
httpRequestsTotalCounter.add(1, {
|
2523
|
-
[import_semantic_conventions3.ATTR_SERVICE_NAME]: getEnvVar("OTEL_SERVICE_NAME"),
|
2524
|
+
[import_semantic_conventions3.ATTR_SERVICE_NAME]: (0, import_common5.getEnvVar)("OTEL_SERVICE_NAME"),
|
2524
2525
|
[ATTR_API_NAME]: req.contractDetails?.name,
|
2525
2526
|
[ATTR_CORRELATION_ID]: req.context.correlationId,
|
2526
2527
|
[import_semantic_conventions3.ATTR_HTTP_REQUEST_METHOD]: req.method,
|
@@ -2558,8 +2559,8 @@ function enrichExpressLikeSend(instance, req, res, originalOperation, originalSe
|
|
2558
2559
|
`attachment; filename="${data.name}"`
|
2559
2560
|
);
|
2560
2561
|
}
|
2561
|
-
if ((0,
|
2562
|
-
import_stream.Readable.from((0,
|
2562
|
+
if ((0, import_common6.isNodeJsWriteableStream)(res)) {
|
2563
|
+
import_stream.Readable.from((0, import_common6.readableStreamToAsyncIterable)(data.stream())).pipe(
|
2563
2564
|
res
|
2564
2565
|
);
|
2565
2566
|
} else {
|
@@ -2568,7 +2569,7 @@ function enrichExpressLikeSend(instance, req, res, originalOperation, originalSe
|
|
2568
2569
|
originalSend.call(instance, "Not a NodeJS WritableStream");
|
2569
2570
|
errorSent = true;
|
2570
2571
|
}
|
2571
|
-
} else if ((0,
|
2572
|
+
} else if ((0, import_common6.isAsyncGenerator)(data)) {
|
2572
2573
|
let firstPass = true;
|
2573
2574
|
const transformer = new import_stream.Transform({
|
2574
2575
|
objectMode: true,
|
@@ -2596,7 +2597,7 @@ ${res.locals.errorMessage}`;
|
|
2596
2597
|
if (!errorSent) {
|
2597
2598
|
let data2 = "";
|
2598
2599
|
for (const [key, value] of Object.entries(chunk)) {
|
2599
|
-
data2 += `${key}: ${typeof value === "string" ? value : (0,
|
2600
|
+
data2 += `${key}: ${typeof value === "string" ? value : (0, import_common6.safeStringify)(value)}
|
2600
2601
|
`;
|
2601
2602
|
}
|
2602
2603
|
data2 += "\n";
|
@@ -2604,7 +2605,7 @@ ${res.locals.errorMessage}`;
|
|
2604
2605
|
}
|
2605
2606
|
}
|
2606
2607
|
});
|
2607
|
-
if ((0,
|
2608
|
+
if ((0, import_common6.isNodeJsWriteableStream)(res)) {
|
2608
2609
|
import_stream.Readable.from(data).pipe(transformer).pipe(res);
|
2609
2610
|
} else {
|
2610
2611
|
res.type("text/plain");
|
@@ -2615,7 +2616,7 @@ ${res.locals.errorMessage}`;
|
|
2615
2616
|
} else {
|
2616
2617
|
const parserType = responseBodies?.[Number(res.statusCode)]?.parserType;
|
2617
2618
|
res.bodyData = data;
|
2618
|
-
if ((0,
|
2619
|
+
if ((0, import_common6.isRecord)(data)) {
|
2619
2620
|
switch (parserType) {
|
2620
2621
|
case "json":
|
2621
2622
|
res.bodyData = "json" in data ? data.json : data;
|
@@ -2636,7 +2637,7 @@ ${res.locals.errorMessage}`;
|
|
2636
2637
|
res.bodyData = data;
|
2637
2638
|
break;
|
2638
2639
|
default:
|
2639
|
-
(0,
|
2640
|
+
(0, import_common6.isNever)(parserType);
|
2640
2641
|
res.bodyData = data;
|
2641
2642
|
break;
|
2642
2643
|
}
|