@forklaunch/core 1.5.2 → 1.5.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/cache/{index.d.mts → cacheKey.d.ts} +2 -6
- package/lib/cache/cacheKey.d.ts.map +1 -0
- package/lib/cache/index.d.ts +4 -15
- package/lib/cache/index.d.ts.map +1 -0
- package/lib/{ttlCache.interface-B3xaLT00.d.ts → cache/interfaces/ttlCache.interface.d.ts} +3 -5
- package/lib/cache/interfaces/ttlCache.interface.d.ts.map +1 -0
- package/lib/{ttlCacheRecord.types-oX0ti5SP.d.mts → cache/types/ttlCacheRecord.types.d.ts} +3 -4
- package/lib/cache/types/ttlCacheRecord.types.d.ts.map +1 -0
- package/lib/controllers/index.d.ts +2 -13
- package/lib/controllers/index.d.ts.map +1 -0
- package/lib/controllers/{index.d.mts → interfaces/controller.interface.d.ts} +2 -3
- package/lib/controllers/interfaces/controller.interface.d.ts.map +1 -0
- package/lib/environment/index.d.ts +2 -28
- package/lib/environment/index.d.ts.map +1 -0
- package/lib/environment/{index.d.mts → loadCascadingEnv.d.ts} +4 -5
- package/lib/environment/loadCascadingEnv.d.ts.map +1 -0
- package/lib/http/application/expressLikeApplication.d.ts +34 -0
- package/lib/http/application/expressLikeApplication.d.ts.map +1 -0
- package/lib/http/bootstrap/listen.d.ts +2 -0
- package/lib/http/bootstrap/listen.d.ts.map +1 -0
- package/lib/http/cluster/cluster.types.d.ts +17 -0
- package/lib/http/cluster/cluster.types.d.ts.map +1 -0
- package/lib/http/cluster/isPortBound.d.ts +2 -0
- package/lib/http/cluster/isPortBound.d.ts.map +1 -0
- package/lib/http/createHmacToken.d.ts +19 -0
- package/lib/http/createHmacToken.d.ts.map +1 -0
- package/lib/http/discriminateAuthMethod.d.ts +85 -0
- package/lib/http/discriminateAuthMethod.d.ts.map +1 -0
- package/lib/http/generateHmacAuthHeaders.d.ts +31 -0
- package/lib/http/generateHmacAuthHeaders.d.ts.map +1 -0
- package/lib/http/guards/hasFeatureChecks.d.ts +2 -0
- package/lib/http/guards/hasFeatureChecks.d.ts.map +1 -0
- package/lib/http/guards/hasPermissionChecks.d.ts +2 -0
- package/lib/http/guards/hasPermissionChecks.d.ts.map +1 -0
- package/lib/http/guards/hasRoleChecks.d.ts +2 -0
- package/lib/http/guards/hasRoleChecks.d.ts.map +1 -0
- package/lib/http/guards/hasScopeChecks.d.ts +2 -0
- package/lib/http/guards/hasScopeChecks.d.ts.map +1 -0
- package/lib/http/guards/hasSend.d.ts +17 -0
- package/lib/http/guards/hasSend.d.ts.map +1 -0
- package/lib/http/guards/hasSubscriptionChecks.d.ts +2 -0
- package/lib/http/guards/hasSubscriptionChecks.d.ts.map +1 -0
- package/lib/http/guards/hasVersionedSchema.d.ts +2 -0
- package/lib/http/guards/hasVersionedSchema.d.ts.map +1 -0
- package/lib/http/guards/isBasicAuthMethod.d.ts +3 -0
- package/lib/http/guards/isBasicAuthMethod.d.ts.map +1 -0
- package/lib/http/guards/isConstrainedForklaunchRouter.d.ts +21 -0
- package/lib/http/guards/isConstrainedForklaunchRouter.d.ts.map +1 -0
- package/lib/http/guards/isExpressLikeSchemaHandler.d.ts +32 -0
- package/lib/http/guards/isExpressLikeSchemaHandler.d.ts.map +1 -0
- package/lib/http/guards/isForklaunchExpressLikeRouter.d.ts +28 -0
- package/lib/http/guards/isForklaunchExpressLikeRouter.d.ts.map +1 -0
- package/lib/http/guards/isForklaunchRequest.d.ts +26 -0
- package/lib/http/guards/isForklaunchRequest.d.ts.map +1 -0
- package/lib/http/guards/isForklaunchResponse.d.ts +23 -0
- package/lib/http/guards/isForklaunchResponse.d.ts.map +1 -0
- package/lib/http/guards/isForklaunchRouter.d.ts +21 -0
- package/lib/http/guards/isForklaunchRouter.d.ts.map +1 -0
- package/lib/http/guards/isHmacMethod.d.ts +9 -0
- package/lib/http/guards/isHmacMethod.d.ts.map +1 -0
- package/lib/http/guards/isHttpContractDetails.d.ts +29 -0
- package/lib/http/guards/isHttpContractDetails.d.ts.map +1 -0
- package/lib/http/guards/isJwtAuthMethod.d.ts +3 -0
- package/lib/http/guards/isJwtAuthMethod.d.ts.map +1 -0
- package/lib/http/guards/isLoggerMeta.d.ts +3 -0
- package/lib/http/guards/isLoggerMeta.d.ts.map +1 -0
- package/lib/http/guards/isPath.d.ts +2 -0
- package/lib/http/guards/isPath.d.ts.map +1 -0
- package/lib/http/guards/isPathParamContractDetails.d.ts +4 -0
- package/lib/http/guards/isPathParamContractDetails.d.ts.map +1 -0
- package/lib/http/guards/isRequestShape.d.ts +3 -0
- package/lib/http/guards/isRequestShape.d.ts.map +1 -0
- package/lib/http/guards/isResponseCompiledSchema.d.ts +3 -0
- package/lib/http/guards/isResponseCompiledSchema.d.ts.map +1 -0
- package/lib/http/guards/isSdkHandler.d.ts +9 -0
- package/lib/http/guards/isSdkHandler.d.ts.map +1 -0
- package/lib/http/guards/isSdkRouter.d.ts +9 -0
- package/lib/http/guards/isSdkRouter.d.ts.map +1 -0
- package/lib/http/guards/isTypedHandler.d.ts +5 -0
- package/lib/http/guards/isTypedHandler.d.ts.map +1 -0
- package/lib/http/guards/isVersionedInputSchema.d.ts +3 -0
- package/lib/http/guards/isVersionedInputSchema.d.ts.map +1 -0
- package/lib/http/handlers/delete.d.ts +5 -0
- package/lib/http/handlers/delete.d.ts.map +1 -0
- package/lib/http/handlers/get.d.ts +5 -0
- package/lib/http/handlers/get.d.ts.map +1 -0
- package/lib/http/handlers/head.d.ts +5 -0
- package/lib/http/handlers/head.d.ts.map +1 -0
- package/lib/http/handlers/middleware.d.ts +10 -0
- package/lib/http/handlers/middleware.d.ts.map +1 -0
- package/lib/http/handlers/options.d.ts +5 -0
- package/lib/http/handlers/options.d.ts.map +1 -0
- package/lib/http/handlers/patch.d.ts +5 -0
- package/lib/http/handlers/patch.d.ts.map +1 -0
- package/lib/http/handlers/post.d.ts +5 -0
- package/lib/http/handlers/post.d.ts.map +1 -0
- package/lib/http/handlers/put.d.ts +5 -0
- package/lib/http/handlers/put.d.ts.map +1 -0
- package/lib/http/handlers/trace.d.ts +5 -0
- package/lib/http/handlers/trace.d.ts.map +1 -0
- package/lib/http/handlers/typedAuthHandler.d.ts +5 -0
- package/lib/http/handlers/typedAuthHandler.d.ts.map +1 -0
- package/lib/http/handlers/typedHandler.d.ts +14 -0
- package/lib/http/handlers/typedHandler.d.ts.map +1 -0
- package/lib/http/httpStatusCodes.d.ts +75 -0
- package/lib/http/httpStatusCodes.d.ts.map +1 -0
- package/lib/http/index.d.ts +47 -1244
- package/lib/http/index.d.ts.map +1 -0
- package/lib/http/index.js +445 -410
- package/lib/http/index.js.map +1 -1
- package/lib/http/index.mjs +439 -407
- package/lib/http/index.mjs.map +1 -1
- package/lib/http/interfaces/expressLikeRouter.interface.d.ts +25 -0
- package/lib/http/interfaces/expressLikeRouter.interface.d.ts.map +1 -0
- package/lib/http/mcpGenerator/mcpGenerator.d.ts +17 -0
- package/lib/http/mcpGenerator/mcpGenerator.d.ts.map +1 -0
- package/lib/http/middleware/request/auth.middleware.d.ts +16 -0
- package/lib/http/middleware/request/auth.middleware.d.ts.map +1 -0
- package/lib/http/middleware/request/cors.middleware.d.ts +13 -0
- package/lib/http/middleware/request/cors.middleware.d.ts.map +1 -0
- package/lib/http/middleware/request/createContext.middleware.d.ts +15 -0
- package/lib/http/middleware/request/createContext.middleware.d.ts.map +1 -0
- package/lib/http/middleware/request/enrichDetails.middleware.d.ts +18 -0
- package/lib/http/middleware/request/enrichDetails.middleware.d.ts.map +1 -0
- package/lib/http/middleware/request/parse.middleware.d.ts +17 -0
- package/lib/http/middleware/request/parse.middleware.d.ts.map +1 -0
- package/lib/http/middleware/request/tenantContext.middleware.d.ts +41 -0
- package/lib/http/middleware/request/tenantContext.middleware.d.ts.map +1 -0
- package/lib/http/middleware/response/enrichExpressLikeSend.middleware.d.ts +32 -0
- package/lib/http/middleware/response/enrichExpressLikeSend.middleware.d.ts.map +1 -0
- package/lib/http/middleware/response/parse.middleware.d.ts +31 -0
- package/lib/http/middleware/response/parse.middleware.d.ts.map +1 -0
- package/lib/http/openApiV3Generator/openApiV3Generator.d.ts +17 -0
- package/lib/http/openApiV3Generator/openApiV3Generator.d.ts.map +1 -0
- package/lib/http/rateLimit/index.d.ts +2 -0
- package/lib/http/rateLimit/index.d.ts.map +1 -0
- package/lib/http/rateLimit/rateLimiter.d.ts +66 -0
- package/lib/http/rateLimit/rateLimiter.d.ts.map +1 -0
- package/lib/http/router/discriminateBody.d.ts +43 -0
- package/lib/http/router/discriminateBody.d.ts.map +1 -0
- package/lib/http/router/expressLikeRouter.d.ts +240 -0
- package/lib/http/router/expressLikeRouter.d.ts.map +1 -0
- package/lib/http/router/routerSharedLogic.d.ts +50 -0
- package/lib/http/router/routerSharedLogic.d.ts.map +1 -0
- package/lib/http/router/unpackRouters.d.ts +7 -0
- package/lib/http/router/unpackRouters.d.ts.map +1 -0
- package/lib/http/telemetry/auditLogger.d.ts +21 -0
- package/lib/http/telemetry/auditLogger.d.ts.map +1 -0
- package/lib/http/telemetry/constants.d.ts +6 -0
- package/lib/http/telemetry/constants.d.ts.map +1 -0
- package/lib/http/telemetry/evaluateTelemetryOptions.d.ts +11 -0
- package/lib/http/telemetry/evaluateTelemetryOptions.d.ts.map +1 -0
- package/lib/http/telemetry/metricsDefinition.d.ts +3 -0
- package/lib/http/telemetry/metricsDefinition.d.ts.map +1 -0
- package/lib/http/telemetry/openTelemetryCollector.d.ts +53 -0
- package/lib/http/telemetry/openTelemetryCollector.d.ts.map +1 -0
- package/lib/http/telemetry/pinoLogger.d.ts +20 -0
- package/lib/http/telemetry/pinoLogger.d.ts.map +1 -0
- package/lib/http/telemetry/recordMetric.d.ts +5 -0
- package/lib/http/telemetry/recordMetric.d.ts.map +1 -0
- package/lib/http/types/apiDefinition.types.d.ts +471 -0
- package/lib/http/types/apiDefinition.types.d.ts.map +1 -0
- package/lib/http/types/contractDetails.types.d.ts +404 -0
- package/lib/http/types/contractDetails.types.d.ts.map +1 -0
- package/lib/http/types/docsConfiguration.types.d.ts +7 -0
- package/lib/http/types/docsConfiguration.types.d.ts.map +1 -0
- package/lib/http/types/expressLikeOptions.d.ts +224 -0
- package/lib/http/types/expressLikeOptions.d.ts.map +1 -0
- package/lib/http/types/expressLikeRouter.types.d.ts +127 -0
- package/lib/http/types/expressLikeRouter.types.d.ts.map +1 -0
- package/lib/http/types/openTelemetryCollector.types.d.ts +21 -0
- package/lib/http/types/openTelemetryCollector.types.d.ts.map +1 -0
- package/lib/http/types/router.types.d.ts +52 -0
- package/lib/http/types/router.types.d.ts.map +1 -0
- package/lib/http/types/sdk.types.d.ts +259 -0
- package/lib/http/types/sdk.types.d.ts.map +1 -0
- package/lib/http/types/typedHandler.types.d.ts +18 -0
- package/lib/http/types/typedHandler.types.d.ts.map +1 -0
- package/lib/mappers/guards/isSchemaResolutionFunction.d.ts +10 -0
- package/lib/mappers/guards/isSchemaResolutionFunction.d.ts.map +1 -0
- package/lib/mappers/index.d.ts +3 -68
- package/lib/mappers/index.d.ts.map +1 -0
- package/lib/mappers/mapServiceSchemas.d.ts +33 -0
- package/lib/mappers/mapServiceSchemas.d.ts.map +1 -0
- package/lib/mappers/mapper.d.ts +26 -0
- package/lib/mappers/mapper.d.ts.map +1 -0
- package/lib/mappers/types/schemaResolution.types.d.ts +9 -0
- package/lib/mappers/types/schemaResolution.types.d.ts.map +1 -0
- package/lib/objectstore/index.d.ts +3 -71
- package/lib/objectstore/index.d.ts.map +1 -0
- package/lib/objectstore/{index.d.mts → interfaces/objectstore.interface.d.ts} +3 -16
- package/lib/objectstore/interfaces/objectstore.interface.d.ts.map +1 -0
- package/lib/objectstore/objectstoreKey.d.ts +11 -0
- package/lib/objectstore/objectstoreKey.d.ts.map +1 -0
- package/lib/persistence/complianceEventSubscriber.d.ts +13 -0
- package/lib/persistence/complianceEventSubscriber.d.ts.map +1 -0
- package/lib/persistence/compliancePropertyBuilder.d.ts +26 -0
- package/lib/persistence/compliancePropertyBuilder.d.ts.map +1 -0
- package/lib/persistence/complianceTypes.d.ts +64 -0
- package/lib/persistence/complianceTypes.d.ts.map +1 -0
- package/lib/persistence/defineComplianceEntity.d.ts +19 -0
- package/lib/persistence/defineComplianceEntity.d.ts.map +1 -0
- package/lib/persistence/encryptedType.d.ts +85 -0
- package/lib/persistence/encryptedType.d.ts.map +1 -0
- package/lib/persistence/fieldEncryptor.d.ts +48 -0
- package/lib/persistence/fieldEncryptor.d.ts.map +1 -0
- package/lib/persistence/index.d.ts +10 -403
- package/lib/persistence/index.d.ts.map +1 -0
- package/lib/persistence/index.js.map +1 -1
- package/lib/persistence/index.mjs.map +1 -1
- package/lib/persistence/rls.d.ts +56 -0
- package/lib/persistence/rls.d.ts.map +1 -0
- package/lib/persistence/tenantEm.d.ts +60 -0
- package/lib/persistence/tenantEm.d.ts.map +1 -0
- package/lib/persistence/tenantFilter.d.ts +47 -0
- package/lib/persistence/tenantFilter.d.ts.map +1 -0
- package/lib/secrets/index.d.ts +2 -0
- package/lib/secrets/index.d.ts.map +1 -0
- package/lib/secrets/secretsAccessor.d.ts +17 -0
- package/lib/secrets/secretsAccessor.d.ts.map +1 -0
- package/lib/services/complianceDataService.d.ts +47 -0
- package/lib/services/complianceDataService.d.ts.map +1 -0
- package/lib/services/configInjector.d.ts +43 -0
- package/lib/services/configInjector.d.ts.map +1 -0
- package/lib/services/guards/isConstructed.d.ts +3 -0
- package/lib/services/guards/isConstructed.d.ts.map +1 -0
- package/lib/services/guards/isConstructedSingleton.d.ts +3 -0
- package/lib/services/guards/isConstructedSingleton.d.ts.map +1 -0
- package/lib/services/guards/isConstructor.d.ts +3 -0
- package/lib/services/guards/isConstructor.d.ts.map +1 -0
- package/lib/services/index.d.ts +10 -184
- package/lib/services/index.d.ts.map +1 -0
- package/lib/services/retentionService.d.ts +31 -0
- package/lib/services/retentionService.d.ts.map +1 -0
- package/lib/services/runRetentionEnforcement.d.ts +19 -0
- package/lib/services/runRetentionEnforcement.d.ts.map +1 -0
- package/lib/services/types/configInjector.types.d.ts +39 -0
- package/lib/services/types/configInjector.types.d.ts.map +1 -0
- package/lib/services/types/entityManager.types.d.ts +4 -0
- package/lib/services/types/entityManager.types.d.ts.map +1 -0
- package/lib/services/types/service.types.d.ts +5 -0
- package/lib/services/types/service.types.d.ts.map +1 -0
- package/lib/ws/asyncApiV3Generator/asyncApiV3Generator.d.ts +12 -0
- package/lib/ws/asyncApiV3Generator/asyncApiV3Generator.d.ts.map +1 -0
- package/lib/ws/index.d.ts +4 -67
- package/lib/ws/index.d.ts.map +1 -0
- package/lib/ws/index.js.map +1 -1
- package/lib/ws/index.mjs.map +1 -1
- package/lib/ws/types/eventSchema.types.d.ts +28 -0
- package/lib/ws/types/eventSchema.types.d.ts.map +1 -0
- package/lib/ws/webSocketLike.d.ts +18 -0
- package/lib/ws/webSocketLike.d.ts.map +1 -0
- package/package.json +33 -33
- package/lib/apiDefinition.types-DF_crhB0.d.mts +0 -1092
- package/lib/apiDefinition.types-DW4lfZqy.d.ts +0 -1092
- package/lib/http/index.d.mts +0 -1244
- package/lib/mappers/index.d.mts +0 -68
- package/lib/openTelemetryCollector-BS-ej09T.d.mts +0 -70
- package/lib/openTelemetryCollector-BS-ej09T.d.ts +0 -70
- package/lib/persistence/index.d.mts +0 -403
- package/lib/services/index.d.mts +0 -185
- package/lib/ttlCache.interface-CEOkrt8d.d.mts +0 -77
- package/lib/ttlCacheRecord.types-oX0ti5SP.d.ts +0 -25
- package/lib/ws/index.d.mts +0 -67
package/lib/http/index.mjs
CHANGED
|
@@ -92,8 +92,9 @@ function isTypedHandler(maybeTypedHandler) {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
// src/http/middleware/request/createContext.middleware.ts
|
|
95
|
-
import { getEnvVar } from "@forklaunch/common";
|
|
96
|
-
import { context, trace } from "@opentelemetry/api";
|
|
95
|
+
import { getEnvVar as getEnvVar2 } from "@forklaunch/common";
|
|
96
|
+
import { context, trace as trace2 } from "@opentelemetry/api";
|
|
97
|
+
import { ATTR_SERVICE_NAME as OTEL_ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
|
|
97
98
|
import { v4 } from "uuid";
|
|
98
99
|
|
|
99
100
|
// src/http/telemetry/constants.ts
|
|
@@ -107,6 +108,331 @@ var ATTR_API_NAME = "api.name";
|
|
|
107
108
|
var ATTR_CORRELATION_ID = "correlation.id";
|
|
108
109
|
var ATTR_APPLICATION_ID = "application_id";
|
|
109
110
|
|
|
111
|
+
// src/http/telemetry/openTelemetryCollector.ts
|
|
112
|
+
import { getEnvVar } from "@forklaunch/common";
|
|
113
|
+
import { HyperExpressInstrumentation } from "@forklaunch/opentelemetry-instrumentation-hyper-express";
|
|
114
|
+
import {
|
|
115
|
+
metrics
|
|
116
|
+
} from "@opentelemetry/api";
|
|
117
|
+
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
|
|
118
|
+
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
|
|
119
|
+
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
120
|
+
import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
|
|
121
|
+
import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
|
|
122
|
+
import { resourceFromAttributes } from "@opentelemetry/resources";
|
|
123
|
+
import { BatchLogRecordProcessor } from "@opentelemetry/sdk-logs";
|
|
124
|
+
import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
|
|
125
|
+
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
126
|
+
import {
|
|
127
|
+
ATTR_SERVICE_NAME as ATTR_SERVICE_NAME2
|
|
128
|
+
} from "@opentelemetry/semantic-conventions";
|
|
129
|
+
import dotenv from "dotenv";
|
|
130
|
+
|
|
131
|
+
// src/http/guards/isForklaunchRequest.ts
|
|
132
|
+
function isForklaunchRequest(request) {
|
|
133
|
+
return request != null && typeof request === "object" && "contractDetails" in request;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// src/http/telemetry/pinoLogger.ts
|
|
137
|
+
import { isNever } from "@forklaunch/common";
|
|
138
|
+
import { trace } from "@opentelemetry/api";
|
|
139
|
+
import { logs } from "@opentelemetry/api-logs";
|
|
140
|
+
import pino from "pino";
|
|
141
|
+
|
|
142
|
+
// src/http/guards/isLoggerMeta.ts
|
|
143
|
+
function isLoggerMeta(arg) {
|
|
144
|
+
return typeof arg === "object" && arg !== null && "_meta" in arg;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/http/telemetry/pinoLogger.ts
|
|
148
|
+
function meta(meta2) {
|
|
149
|
+
return meta2;
|
|
150
|
+
}
|
|
151
|
+
function mapSeverity(level) {
|
|
152
|
+
switch (level) {
|
|
153
|
+
case "silent":
|
|
154
|
+
return 0;
|
|
155
|
+
case "trace":
|
|
156
|
+
return 1;
|
|
157
|
+
case "debug":
|
|
158
|
+
return 5;
|
|
159
|
+
case "info":
|
|
160
|
+
return 9;
|
|
161
|
+
case "warn":
|
|
162
|
+
return 13;
|
|
163
|
+
case "error":
|
|
164
|
+
return 17;
|
|
165
|
+
case "fatal":
|
|
166
|
+
return 21;
|
|
167
|
+
default:
|
|
168
|
+
isNever(level);
|
|
169
|
+
return 0;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function normalizeLogArgs(args) {
|
|
173
|
+
let message = "";
|
|
174
|
+
const metaObjects = [];
|
|
175
|
+
for (const arg of args) {
|
|
176
|
+
if (typeof arg === "string" && message === "") {
|
|
177
|
+
message = arg;
|
|
178
|
+
} else if (arg instanceof Error) {
|
|
179
|
+
metaObjects.push({
|
|
180
|
+
err: {
|
|
181
|
+
message: arg.message,
|
|
182
|
+
name: arg.name,
|
|
183
|
+
stack: arg.stack,
|
|
184
|
+
...Object.keys(arg).length > 0 ? arg : {}
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
} else if (arg && typeof arg === "object" && !Array.isArray(arg)) {
|
|
188
|
+
metaObjects.push(arg);
|
|
189
|
+
} else {
|
|
190
|
+
message += ` ${String(arg)}`;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const metadata = Object.assign({}, ...metaObjects);
|
|
194
|
+
return [metadata, message.trim()];
|
|
195
|
+
}
|
|
196
|
+
function safePrettyFormat(level, args, timestamp) {
|
|
197
|
+
try {
|
|
198
|
+
const [metadata, message] = normalizeLogArgs(args);
|
|
199
|
+
const formattedTimestamp = timestamp || (/* @__PURE__ */ new Date()).toISOString();
|
|
200
|
+
return `[${formattedTimestamp}] ${level.toUpperCase()}: ${message}${Object.keys(metadata).length > 0 ? `
|
|
201
|
+
${JSON.stringify(metadata, null, 2)}` : ""}`;
|
|
202
|
+
} catch (error) {
|
|
203
|
+
const fallbackMessage = args.map((arg) => {
|
|
204
|
+
try {
|
|
205
|
+
if (typeof arg === "string") return arg;
|
|
206
|
+
if (arg === null) return "null";
|
|
207
|
+
if (arg === void 0) return "undefined";
|
|
208
|
+
return JSON.stringify(arg);
|
|
209
|
+
} catch {
|
|
210
|
+
return "[Circular/Non-serializable Object]";
|
|
211
|
+
}
|
|
212
|
+
}).join(" ");
|
|
213
|
+
return `[${(/* @__PURE__ */ new Date()).toISOString()}] ${level.toUpperCase()}: ${fallbackMessage} [Pretty Print Error: ${error instanceof Error ? error.message : "Unknown error"}]`;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
var PinoLogger = class _PinoLogger {
|
|
217
|
+
_pinoLogger;
|
|
218
|
+
_meta;
|
|
219
|
+
constructor(level, meta2 = {}) {
|
|
220
|
+
this._pinoLogger = pino({
|
|
221
|
+
level: level || "info",
|
|
222
|
+
formatters: {
|
|
223
|
+
level(label) {
|
|
224
|
+
return { level: label };
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
timestamp: pino.stdTimeFunctions.isoTime,
|
|
228
|
+
transport: {
|
|
229
|
+
target: "pino-pretty",
|
|
230
|
+
options: {
|
|
231
|
+
colorize: true,
|
|
232
|
+
errorLikeObjectKeys: ["err", "error"],
|
|
233
|
+
ignore: "pid,hostname",
|
|
234
|
+
translateTime: "SYS:standard"
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
this._meta = meta2;
|
|
239
|
+
}
|
|
240
|
+
log(level, ...args) {
|
|
241
|
+
let meta2 = {};
|
|
242
|
+
const filteredArgs = args.filter((arg) => {
|
|
243
|
+
if (isLoggerMeta(arg)) {
|
|
244
|
+
Object.assign(meta2, arg);
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
return true;
|
|
248
|
+
});
|
|
249
|
+
const [errorMetadata] = normalizeLogArgs(filteredArgs);
|
|
250
|
+
Object.assign(meta2, errorMetadata);
|
|
251
|
+
const activeSpan = trace.getActiveSpan();
|
|
252
|
+
if (activeSpan) {
|
|
253
|
+
const activeSpanContext = activeSpan.spanContext();
|
|
254
|
+
meta2.trace_id = activeSpanContext.traceId;
|
|
255
|
+
meta2.span_id = activeSpanContext.spanId;
|
|
256
|
+
meta2.trace_flags = activeSpanContext.traceFlags;
|
|
257
|
+
meta2 = {
|
|
258
|
+
// @ts-expect-error accessing private property
|
|
259
|
+
...activeSpan.attributes,
|
|
260
|
+
...meta2
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
meta2 = {
|
|
264
|
+
"api.name": "none",
|
|
265
|
+
"correlation.id": "none",
|
|
266
|
+
...meta2
|
|
267
|
+
};
|
|
268
|
+
this._pinoLogger[level](...normalizeLogArgs(filteredArgs));
|
|
269
|
+
const formattedBody = safePrettyFormat(level, filteredArgs);
|
|
270
|
+
try {
|
|
271
|
+
logs.getLogger(process.env.OTEL_SERVICE_NAME ?? "unknown").emit({
|
|
272
|
+
severityText: level,
|
|
273
|
+
severityNumber: mapSeverity(level),
|
|
274
|
+
body: formattedBody,
|
|
275
|
+
attributes: { ...this._meta, ...meta2 }
|
|
276
|
+
});
|
|
277
|
+
} catch (error) {
|
|
278
|
+
console.error("Failed to emit OpenTelemetry log:", error);
|
|
279
|
+
console.log(
|
|
280
|
+
`[${(/* @__PURE__ */ new Date()).toISOString()}] ${level.toUpperCase()}:`,
|
|
281
|
+
...filteredArgs
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
error = (msg, ...args) => this.log("error", msg, ...args);
|
|
286
|
+
info = (msg, ...args) => this.log("info", msg, ...args);
|
|
287
|
+
debug = (msg, ...args) => this.log("debug", msg, ...args);
|
|
288
|
+
warn = (msg, ...args) => this.log("warn", msg, ...args);
|
|
289
|
+
trace = (msg, ...args) => this.log("trace", msg, ...args);
|
|
290
|
+
child(meta2 = {}) {
|
|
291
|
+
return new _PinoLogger(this._pinoLogger.level, { ...this._meta, ...meta2 });
|
|
292
|
+
}
|
|
293
|
+
getBaseLogger() {
|
|
294
|
+
return this._pinoLogger;
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
function logger(level, meta2 = {}) {
|
|
298
|
+
return new PinoLogger(level, meta2);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// src/http/telemetry/openTelemetryCollector.ts
|
|
302
|
+
var OpenTelemetryCollector = class {
|
|
303
|
+
_logger;
|
|
304
|
+
_serviceName;
|
|
305
|
+
_metrics;
|
|
306
|
+
// scoped creation and create this in middleware when api execute. Also add correlation id
|
|
307
|
+
constructor(serviceName, level, metricDefinitions) {
|
|
308
|
+
this._serviceName = serviceName;
|
|
309
|
+
this._logger = logger(level || "info");
|
|
310
|
+
this._metrics = {};
|
|
311
|
+
for (const [metricId, metricType] of Object.entries(
|
|
312
|
+
metricDefinitions ?? {}
|
|
313
|
+
)) {
|
|
314
|
+
switch (metricType) {
|
|
315
|
+
case "counter":
|
|
316
|
+
this._metrics[metricId] = metrics.getMeter(this._serviceName).createCounter(metricId);
|
|
317
|
+
break;
|
|
318
|
+
case "gauge":
|
|
319
|
+
this._metrics[metricId] = metrics.getMeter(this._serviceName).createGauge(metricId);
|
|
320
|
+
break;
|
|
321
|
+
case "histogram":
|
|
322
|
+
this._metrics[metricId] = metrics.getMeter(this._serviceName).createHistogram(metricId);
|
|
323
|
+
break;
|
|
324
|
+
case "upDownCounter":
|
|
325
|
+
this._metrics[metricId] = metrics.getMeter(this._serviceName).createUpDownCounter(metricId);
|
|
326
|
+
break;
|
|
327
|
+
case "observableCounter":
|
|
328
|
+
this._metrics[metricId] = metrics.getMeter(this._serviceName).createObservableCounter(metricId);
|
|
329
|
+
break;
|
|
330
|
+
case "observableGauge":
|
|
331
|
+
this._metrics[metricId] = metrics.getMeter(this._serviceName).createObservableGauge(metricId);
|
|
332
|
+
break;
|
|
333
|
+
case "observableUpDownCounter":
|
|
334
|
+
this._metrics[metricId] = metrics.getMeter(this._serviceName).createObservableUpDownCounter(metricId);
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
this.log(
|
|
339
|
+
"info",
|
|
340
|
+
"OpenTelemetry Collector (Traces + Logs + Metrics) started"
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
log(level, ...args) {
|
|
344
|
+
this._logger.log(level, ...args);
|
|
345
|
+
}
|
|
346
|
+
info = (msg, ...args) => {
|
|
347
|
+
this._logger.log("info", msg, ...args);
|
|
348
|
+
};
|
|
349
|
+
error = (msg, ...args) => {
|
|
350
|
+
this._logger.log("error", msg, ...args);
|
|
351
|
+
};
|
|
352
|
+
warn = (msg, ...args) => {
|
|
353
|
+
this._logger.log("warn", msg, ...args);
|
|
354
|
+
};
|
|
355
|
+
debug = (msg, ...args) => {
|
|
356
|
+
this._logger.log("debug", msg, ...args);
|
|
357
|
+
};
|
|
358
|
+
trace = (msg, ...args) => {
|
|
359
|
+
this._logger.log("trace", msg, ...args);
|
|
360
|
+
};
|
|
361
|
+
getMetric(metricId) {
|
|
362
|
+
return this._metrics[metricId];
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
dotenv.config({ path: getEnvVar("DOTENV_FILE_PATH") });
|
|
366
|
+
function parseOtelHeaders() {
|
|
367
|
+
const headersEnv = getEnvVar("OTEL_EXPORTER_OTLP_HEADERS");
|
|
368
|
+
if (!headersEnv) return void 0;
|
|
369
|
+
const headers = {};
|
|
370
|
+
for (const pair of headersEnv.split(",")) {
|
|
371
|
+
const [key, ...valueParts] = pair.split("=");
|
|
372
|
+
if (key && valueParts.length > 0) {
|
|
373
|
+
headers[key.trim()] = valueParts.join("=").trim();
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return Object.keys(headers).length > 0 ? headers : void 0;
|
|
377
|
+
}
|
|
378
|
+
var otelHeaders = parseOtelHeaders();
|
|
379
|
+
new NodeSDK({
|
|
380
|
+
resource: resourceFromAttributes({
|
|
381
|
+
[ATTR_SERVICE_NAME2]: getEnvVar("OTEL_SERVICE_NAME")
|
|
382
|
+
}),
|
|
383
|
+
traceExporter: new OTLPTraceExporter({
|
|
384
|
+
url: `${getEnvVar("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/traces`,
|
|
385
|
+
headers: otelHeaders
|
|
386
|
+
}),
|
|
387
|
+
metricReader: new PeriodicExportingMetricReader({
|
|
388
|
+
exporter: new OTLPMetricExporter({
|
|
389
|
+
url: `${getEnvVar("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/metrics`,
|
|
390
|
+
headers: otelHeaders
|
|
391
|
+
}),
|
|
392
|
+
exportIntervalMillis: 5e3
|
|
393
|
+
}),
|
|
394
|
+
logRecordProcessors: [
|
|
395
|
+
new BatchLogRecordProcessor({
|
|
396
|
+
exporter: new OTLPLogExporter({
|
|
397
|
+
url: `${getEnvVar("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/logs`,
|
|
398
|
+
headers: otelHeaders
|
|
399
|
+
})
|
|
400
|
+
})
|
|
401
|
+
],
|
|
402
|
+
instrumentations: [
|
|
403
|
+
new HttpInstrumentation({
|
|
404
|
+
applyCustomAttributesOnSpan: (span, request) => {
|
|
405
|
+
span.setAttribute(
|
|
406
|
+
ATTR_SERVICE_NAME2,
|
|
407
|
+
getEnvVar("OTEL_SERVICE_NAME") ?? "unknown"
|
|
408
|
+
);
|
|
409
|
+
if (isForklaunchRequest(request)) {
|
|
410
|
+
span.setAttribute(ATTR_API_NAME, request.contractDetails?.name);
|
|
411
|
+
span.setAttribute(ATTR_CORRELATION_ID, request.context.correlationId);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}),
|
|
415
|
+
new ExpressInstrumentation(),
|
|
416
|
+
new HyperExpressInstrumentation()
|
|
417
|
+
]
|
|
418
|
+
}).start();
|
|
419
|
+
var httpRequestsTotalCounter = metrics.getMeter(getEnvVar("OTEL_SERVICE_NAME") || "unknown").createCounter("http_requests_total", {
|
|
420
|
+
description: "Number of HTTP requests"
|
|
421
|
+
});
|
|
422
|
+
var httpServerDurationHistogram = metrics.getMeter(getEnvVar("OTEL_SERVICE_NAME") || "unknown").createHistogram("http_server_duration", {
|
|
423
|
+
description: "Duration of HTTP server requests",
|
|
424
|
+
unit: "s"
|
|
425
|
+
});
|
|
426
|
+
var httpRequestDurationMsHistogram = metrics.getMeter(getEnvVar("OTEL_SERVICE_NAME") || "unknown").createHistogram("http_request_duration_ms", {
|
|
427
|
+
description: "Duration of HTTP requests in milliseconds"
|
|
428
|
+
});
|
|
429
|
+
var httpErrorsTotalCounter = metrics.getMeter(getEnvVar("OTEL_SERVICE_NAME") || "unknown").createCounter("http_errors_total", {
|
|
430
|
+
description: "Total number of HTTP errors (4xx/5xx)"
|
|
431
|
+
});
|
|
432
|
+
var httpRequestsInFlightCounter = metrics.getMeter(getEnvVar("OTEL_SERVICE_NAME") || "unknown").createUpDownCounter("http_requests_in_flight", {
|
|
433
|
+
description: "Number of HTTP requests currently in flight"
|
|
434
|
+
});
|
|
435
|
+
|
|
110
436
|
// src/http/middleware/request/createContext.middleware.ts
|
|
111
437
|
function createContext(schemaValidator) {
|
|
112
438
|
return function setContext(req, res, next) {
|
|
@@ -117,16 +443,30 @@ function createContext(schemaValidator) {
|
|
|
117
443
|
}
|
|
118
444
|
res.setHeader("x-correlation-id", correlationId);
|
|
119
445
|
req.context = {
|
|
120
|
-
correlationId
|
|
446
|
+
correlationId,
|
|
447
|
+
requestStartTime: Date.now()
|
|
448
|
+
};
|
|
449
|
+
const serviceName = getEnvVar2("OTEL_SERVICE_NAME") || "unknown";
|
|
450
|
+
const inFlightAttrs = {
|
|
451
|
+
[OTEL_ATTR_SERVICE_NAME]: serviceName
|
|
121
452
|
};
|
|
122
|
-
|
|
453
|
+
let inFlightActive = true;
|
|
454
|
+
const decrementInFlight = () => {
|
|
455
|
+
if (!inFlightActive) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
httpRequestsInFlightCounter.add(-1, inFlightAttrs);
|
|
459
|
+
inFlightActive = false;
|
|
460
|
+
};
|
|
461
|
+
httpRequestsInFlightCounter.add(1, inFlightAttrs);
|
|
462
|
+
res.on("finish", decrementInFlight);
|
|
463
|
+
res.on("close", decrementInFlight);
|
|
464
|
+
res.on("error", decrementInFlight);
|
|
465
|
+
const span = trace2.getSpan(context.active());
|
|
123
466
|
if (span != null) {
|
|
124
467
|
req.context.span = span;
|
|
125
468
|
req.context.span?.setAttribute(ATTR_CORRELATION_ID, correlationId);
|
|
126
|
-
req.context.span?.setAttribute(
|
|
127
|
-
ATTR_SERVICE_NAME,
|
|
128
|
-
getEnvVar("OTEL_SERVICE_NAME")
|
|
129
|
-
);
|
|
469
|
+
req.context.span?.setAttribute(ATTR_SERVICE_NAME, serviceName);
|
|
130
470
|
}
|
|
131
471
|
next?.();
|
|
132
472
|
};
|
|
@@ -387,254 +727,89 @@ async function discriminateAuthMethod(auth, openTelemetryCollector) {
|
|
|
387
727
|
};
|
|
388
728
|
} else {
|
|
389
729
|
let jwks;
|
|
390
|
-
if ("jwksPublicKeyUrl" in jwt) {
|
|
391
|
-
jwks = await getCachedJwks(jwt.jwksPublicKeyUrl);
|
|
392
|
-
} else if ("jwksPublicKey" in jwt) {
|
|
393
|
-
jwks = [jwt.jwksPublicKey];
|
|
394
|
-
}
|
|
395
|
-
verificationFunction = async (token) => {
|
|
396
|
-
for (const key of jwks) {
|
|
397
|
-
try {
|
|
398
|
-
const { payload } = await jwtVerify(token, key);
|
|
399
|
-
return payload;
|
|
400
|
-
} catch {
|
|
401
|
-
cachedJwks.value = null;
|
|
402
|
-
cachedJwks.lastUpdated = null;
|
|
403
|
-
cachedJwks.ttl = DEFAULT_TTL;
|
|
404
|
-
continue;
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
authMethod = {
|
|
410
|
-
type: "jwt",
|
|
411
|
-
auth: {
|
|
412
|
-
decodeResource: auth.decodeResource,
|
|
413
|
-
verificationFunction
|
|
414
|
-
}
|
|
415
|
-
};
|
|
416
|
-
} else if (isHmacMethod(auth)) {
|
|
417
|
-
authMethod = {
|
|
418
|
-
type: "hmac",
|
|
419
|
-
auth: {
|
|
420
|
-
secretKeys: auth.hmac.secretKeys,
|
|
421
|
-
verificationFunction: async ({
|
|
422
|
-
method,
|
|
423
|
-
path,
|
|
424
|
-
body,
|
|
425
|
-
timestamp,
|
|
426
|
-
nonce,
|
|
427
|
-
signature,
|
|
428
|
-
secretKey
|
|
429
|
-
}) => {
|
|
430
|
-
const computedSignature = createHmacToken({
|
|
431
|
-
method,
|
|
432
|
-
path,
|
|
433
|
-
body,
|
|
434
|
-
timestamp,
|
|
435
|
-
nonce,
|
|
436
|
-
secretKey
|
|
437
|
-
});
|
|
438
|
-
const isValid = computedSignature === signature;
|
|
439
|
-
if (!isValid) {
|
|
440
|
-
const errorInfo = {
|
|
441
|
-
method,
|
|
442
|
-
path,
|
|
443
|
-
timestamp: timestamp.toISOString(),
|
|
444
|
-
nonce,
|
|
445
|
-
receivedSignature: signature,
|
|
446
|
-
computedSignature
|
|
447
|
-
};
|
|
448
|
-
openTelemetryCollector?.debug("[HMAC Verification Failed]", {
|
|
449
|
-
...errorInfo,
|
|
450
|
-
bodyType: body ? typeof body : "undefined",
|
|
451
|
-
body: body ? safeStringify2(body) : "undefined"
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
return isValid;
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
};
|
|
458
|
-
}
|
|
459
|
-
if (authMethod == null) {
|
|
460
|
-
throw new Error("Invalid auth method");
|
|
461
|
-
}
|
|
462
|
-
return authMethod;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
// src/http/guards/hasFeatureChecks.ts
|
|
466
|
-
function hasFeatureChecks(maybeFeatureAuth) {
|
|
467
|
-
return typeof maybeFeatureAuth === "object" && maybeFeatureAuth !== null && "requiredFeatures" in maybeFeatureAuth && Array.isArray(maybeFeatureAuth.requiredFeatures) && maybeFeatureAuth.requiredFeatures.length > 0;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
// src/http/guards/hasSubscriptionChecks.ts
|
|
471
|
-
function hasSubscriptionChecks(maybeSubscriptionAuth) {
|
|
472
|
-
return typeof maybeSubscriptionAuth === "object" && maybeSubscriptionAuth !== null && "requireActiveSubscription" in maybeSubscriptionAuth && maybeSubscriptionAuth.requireActiveSubscription === true;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
// src/http/telemetry/pinoLogger.ts
|
|
476
|
-
import { isNever } from "@forklaunch/common";
|
|
477
|
-
import { trace as trace2 } from "@opentelemetry/api";
|
|
478
|
-
import { logs } from "@opentelemetry/api-logs";
|
|
479
|
-
import pino from "pino";
|
|
480
|
-
|
|
481
|
-
// src/http/guards/isLoggerMeta.ts
|
|
482
|
-
function isLoggerMeta(arg) {
|
|
483
|
-
return typeof arg === "object" && arg !== null && "_meta" in arg;
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
// src/http/telemetry/pinoLogger.ts
|
|
487
|
-
function meta(meta2) {
|
|
488
|
-
return meta2;
|
|
489
|
-
}
|
|
490
|
-
function mapSeverity(level) {
|
|
491
|
-
switch (level) {
|
|
492
|
-
case "silent":
|
|
493
|
-
return 0;
|
|
494
|
-
case "trace":
|
|
495
|
-
return 1;
|
|
496
|
-
case "debug":
|
|
497
|
-
return 5;
|
|
498
|
-
case "info":
|
|
499
|
-
return 9;
|
|
500
|
-
case "warn":
|
|
501
|
-
return 13;
|
|
502
|
-
case "error":
|
|
503
|
-
return 17;
|
|
504
|
-
case "fatal":
|
|
505
|
-
return 21;
|
|
506
|
-
default:
|
|
507
|
-
isNever(level);
|
|
508
|
-
return 0;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
function normalizeLogArgs(args) {
|
|
512
|
-
let message = "";
|
|
513
|
-
const metaObjects = [];
|
|
514
|
-
for (const arg of args) {
|
|
515
|
-
if (typeof arg === "string" && message === "") {
|
|
516
|
-
message = arg;
|
|
517
|
-
} else if (arg instanceof Error) {
|
|
518
|
-
metaObjects.push({
|
|
519
|
-
err: {
|
|
520
|
-
message: arg.message,
|
|
521
|
-
name: arg.name,
|
|
522
|
-
stack: arg.stack,
|
|
523
|
-
...Object.keys(arg).length > 0 ? arg : {}
|
|
524
|
-
}
|
|
525
|
-
});
|
|
526
|
-
} else if (arg && typeof arg === "object" && !Array.isArray(arg)) {
|
|
527
|
-
metaObjects.push(arg);
|
|
528
|
-
} else {
|
|
529
|
-
message += ` ${String(arg)}`;
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
const metadata = Object.assign({}, ...metaObjects);
|
|
533
|
-
return [metadata, message.trim()];
|
|
534
|
-
}
|
|
535
|
-
function safePrettyFormat(level, args, timestamp) {
|
|
536
|
-
try {
|
|
537
|
-
const [metadata, message] = normalizeLogArgs(args);
|
|
538
|
-
const formattedTimestamp = timestamp || (/* @__PURE__ */ new Date()).toISOString();
|
|
539
|
-
return `[${formattedTimestamp}] ${level.toUpperCase()}: ${message}${Object.keys(metadata).length > 0 ? `
|
|
540
|
-
${JSON.stringify(metadata, null, 2)}` : ""}`;
|
|
541
|
-
} catch (error) {
|
|
542
|
-
const fallbackMessage = args.map((arg) => {
|
|
543
|
-
try {
|
|
544
|
-
if (typeof arg === "string") return arg;
|
|
545
|
-
if (arg === null) return "null";
|
|
546
|
-
if (arg === void 0) return "undefined";
|
|
547
|
-
return JSON.stringify(arg);
|
|
548
|
-
} catch {
|
|
549
|
-
return "[Circular/Non-serializable Object]";
|
|
550
|
-
}
|
|
551
|
-
}).join(" ");
|
|
552
|
-
return `[${(/* @__PURE__ */ new Date()).toISOString()}] ${level.toUpperCase()}: ${fallbackMessage} [Pretty Print Error: ${error instanceof Error ? error.message : "Unknown error"}]`;
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
var PinoLogger = class _PinoLogger {
|
|
556
|
-
_pinoLogger;
|
|
557
|
-
_meta;
|
|
558
|
-
constructor(level, meta2 = {}) {
|
|
559
|
-
this._pinoLogger = pino({
|
|
560
|
-
level: level || "info",
|
|
561
|
-
formatters: {
|
|
562
|
-
level(label) {
|
|
563
|
-
return { level: label };
|
|
564
|
-
}
|
|
565
|
-
},
|
|
566
|
-
timestamp: pino.stdTimeFunctions.isoTime,
|
|
567
|
-
transport: {
|
|
568
|
-
target: "pino-pretty",
|
|
569
|
-
options: {
|
|
570
|
-
colorize: true,
|
|
571
|
-
errorLikeObjectKeys: ["err", "error"],
|
|
572
|
-
ignore: "pid,hostname",
|
|
573
|
-
translateTime: "SYS:standard"
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
});
|
|
577
|
-
this._meta = meta2;
|
|
578
|
-
}
|
|
579
|
-
log(level, ...args) {
|
|
580
|
-
let meta2 = {};
|
|
581
|
-
const filteredArgs = args.filter((arg) => {
|
|
582
|
-
if (isLoggerMeta(arg)) {
|
|
583
|
-
Object.assign(meta2, arg);
|
|
584
|
-
return false;
|
|
585
|
-
}
|
|
586
|
-
return true;
|
|
587
|
-
});
|
|
588
|
-
const [errorMetadata] = normalizeLogArgs(filteredArgs);
|
|
589
|
-
Object.assign(meta2, errorMetadata);
|
|
590
|
-
const activeSpan = trace2.getActiveSpan();
|
|
591
|
-
if (activeSpan) {
|
|
592
|
-
const activeSpanContext = activeSpan.spanContext();
|
|
593
|
-
meta2.trace_id = activeSpanContext.traceId;
|
|
594
|
-
meta2.span_id = activeSpanContext.spanId;
|
|
595
|
-
meta2.trace_flags = activeSpanContext.traceFlags;
|
|
596
|
-
meta2 = {
|
|
597
|
-
// @ts-expect-error accessing private property
|
|
598
|
-
...activeSpan.attributes,
|
|
599
|
-
...meta2
|
|
730
|
+
if ("jwksPublicKeyUrl" in jwt) {
|
|
731
|
+
jwks = await getCachedJwks(jwt.jwksPublicKeyUrl);
|
|
732
|
+
} else if ("jwksPublicKey" in jwt) {
|
|
733
|
+
jwks = [jwt.jwksPublicKey];
|
|
734
|
+
}
|
|
735
|
+
verificationFunction = async (token) => {
|
|
736
|
+
for (const key of jwks) {
|
|
737
|
+
try {
|
|
738
|
+
const { payload } = await jwtVerify(token, key);
|
|
739
|
+
return payload;
|
|
740
|
+
} catch {
|
|
741
|
+
cachedJwks.value = null;
|
|
742
|
+
cachedJwks.lastUpdated = null;
|
|
743
|
+
cachedJwks.ttl = DEFAULT_TTL;
|
|
744
|
+
continue;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
600
747
|
};
|
|
601
748
|
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
749
|
+
authMethod = {
|
|
750
|
+
type: "jwt",
|
|
751
|
+
auth: {
|
|
752
|
+
decodeResource: auth.decodeResource,
|
|
753
|
+
verificationFunction
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
} else if (isHmacMethod(auth)) {
|
|
757
|
+
authMethod = {
|
|
758
|
+
type: "hmac",
|
|
759
|
+
auth: {
|
|
760
|
+
secretKeys: auth.hmac.secretKeys,
|
|
761
|
+
verificationFunction: async ({
|
|
762
|
+
method,
|
|
763
|
+
path,
|
|
764
|
+
body,
|
|
765
|
+
timestamp,
|
|
766
|
+
nonce,
|
|
767
|
+
signature,
|
|
768
|
+
secretKey
|
|
769
|
+
}) => {
|
|
770
|
+
const computedSignature = createHmacToken({
|
|
771
|
+
method,
|
|
772
|
+
path,
|
|
773
|
+
body,
|
|
774
|
+
timestamp,
|
|
775
|
+
nonce,
|
|
776
|
+
secretKey
|
|
777
|
+
});
|
|
778
|
+
const isValid = computedSignature === signature;
|
|
779
|
+
if (!isValid) {
|
|
780
|
+
const errorInfo = {
|
|
781
|
+
method,
|
|
782
|
+
path,
|
|
783
|
+
timestamp: timestamp.toISOString(),
|
|
784
|
+
nonce,
|
|
785
|
+
receivedSignature: signature,
|
|
786
|
+
computedSignature
|
|
787
|
+
};
|
|
788
|
+
openTelemetryCollector?.debug("[HMAC Verification Failed]", {
|
|
789
|
+
...errorInfo,
|
|
790
|
+
bodyType: body ? typeof body : "undefined",
|
|
791
|
+
body: body ? safeStringify2(body) : "undefined"
|
|
792
|
+
});
|
|
793
|
+
}
|
|
794
|
+
return isValid;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
606
797
|
};
|
|
607
|
-
this._pinoLogger[level](...normalizeLogArgs(filteredArgs));
|
|
608
|
-
const formattedBody = safePrettyFormat(level, filteredArgs);
|
|
609
|
-
try {
|
|
610
|
-
logs.getLogger(process.env.OTEL_SERVICE_NAME ?? "unknown").emit({
|
|
611
|
-
severityText: level,
|
|
612
|
-
severityNumber: mapSeverity(level),
|
|
613
|
-
body: formattedBody,
|
|
614
|
-
attributes: { ...this._meta, ...meta2 }
|
|
615
|
-
});
|
|
616
|
-
} catch (error) {
|
|
617
|
-
console.error("Failed to emit OpenTelemetry log:", error);
|
|
618
|
-
console.log(
|
|
619
|
-
`[${(/* @__PURE__ */ new Date()).toISOString()}] ${level.toUpperCase()}:`,
|
|
620
|
-
...filteredArgs
|
|
621
|
-
);
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
error = (msg, ...args) => this.log("error", msg, ...args);
|
|
625
|
-
info = (msg, ...args) => this.log("info", msg, ...args);
|
|
626
|
-
debug = (msg, ...args) => this.log("debug", msg, ...args);
|
|
627
|
-
warn = (msg, ...args) => this.log("warn", msg, ...args);
|
|
628
|
-
trace = (msg, ...args) => this.log("trace", msg, ...args);
|
|
629
|
-
child(meta2 = {}) {
|
|
630
|
-
return new _PinoLogger(this._pinoLogger.level, { ...this._meta, ...meta2 });
|
|
631
798
|
}
|
|
632
|
-
|
|
633
|
-
|
|
799
|
+
if (authMethod == null) {
|
|
800
|
+
throw new Error("Invalid auth method");
|
|
634
801
|
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
802
|
+
return authMethod;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
// src/http/guards/hasFeatureChecks.ts
|
|
806
|
+
function hasFeatureChecks(maybeFeatureAuth) {
|
|
807
|
+
return typeof maybeFeatureAuth === "object" && maybeFeatureAuth !== null && "requiredFeatures" in maybeFeatureAuth && Array.isArray(maybeFeatureAuth.requiredFeatures) && maybeFeatureAuth.requiredFeatures.length > 0;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
// src/http/guards/hasSubscriptionChecks.ts
|
|
811
|
+
function hasSubscriptionChecks(maybeSubscriptionAuth) {
|
|
812
|
+
return typeof maybeSubscriptionAuth === "object" && maybeSubscriptionAuth !== null && "requireActiveSubscription" in maybeSubscriptionAuth && maybeSubscriptionAuth.requireActiveSubscription === true;
|
|
638
813
|
}
|
|
639
814
|
|
|
640
815
|
// src/http/middleware/request/auth.middleware.ts
|
|
@@ -927,159 +1102,6 @@ async function parseRequestAuth(req, res, next) {
|
|
|
927
1102
|
|
|
928
1103
|
// src/http/middleware/request/enrichDetails.middleware.ts
|
|
929
1104
|
import { getEnvVar as getEnvVar3 } from "@forklaunch/common";
|
|
930
|
-
|
|
931
|
-
// src/http/telemetry/openTelemetryCollector.ts
|
|
932
|
-
import { getEnvVar as getEnvVar2 } from "@forklaunch/common";
|
|
933
|
-
import { HyperExpressInstrumentation } from "@forklaunch/opentelemetry-instrumentation-hyper-express";
|
|
934
|
-
import {
|
|
935
|
-
metrics
|
|
936
|
-
} from "@opentelemetry/api";
|
|
937
|
-
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
|
|
938
|
-
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
|
|
939
|
-
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
940
|
-
import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
|
|
941
|
-
import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
|
|
942
|
-
import { resourceFromAttributes } from "@opentelemetry/resources";
|
|
943
|
-
import { BatchLogRecordProcessor } from "@opentelemetry/sdk-logs";
|
|
944
|
-
import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
|
|
945
|
-
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
946
|
-
import {
|
|
947
|
-
ATTR_SERVICE_NAME as ATTR_SERVICE_NAME2
|
|
948
|
-
} from "@opentelemetry/semantic-conventions";
|
|
949
|
-
import dotenv from "dotenv";
|
|
950
|
-
|
|
951
|
-
// src/http/guards/isForklaunchRequest.ts
|
|
952
|
-
function isForklaunchRequest(request) {
|
|
953
|
-
return request != null && typeof request === "object" && "contractDetails" in request;
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
// src/http/telemetry/openTelemetryCollector.ts
|
|
957
|
-
var OpenTelemetryCollector = class {
|
|
958
|
-
_logger;
|
|
959
|
-
_serviceName;
|
|
960
|
-
_metrics;
|
|
961
|
-
// scoped creation and create this in middleware when api execute. Also add correlation id
|
|
962
|
-
constructor(serviceName, level, metricDefinitions) {
|
|
963
|
-
this._serviceName = serviceName;
|
|
964
|
-
this._logger = logger(level || "info");
|
|
965
|
-
this._metrics = {};
|
|
966
|
-
for (const [metricId, metricType] of Object.entries(
|
|
967
|
-
metricDefinitions ?? {}
|
|
968
|
-
)) {
|
|
969
|
-
switch (metricType) {
|
|
970
|
-
case "counter":
|
|
971
|
-
this._metrics[metricId] = metrics.getMeter(this._serviceName).createCounter(metricId);
|
|
972
|
-
break;
|
|
973
|
-
case "gauge":
|
|
974
|
-
this._metrics[metricId] = metrics.getMeter(this._serviceName).createGauge(metricId);
|
|
975
|
-
break;
|
|
976
|
-
case "histogram":
|
|
977
|
-
this._metrics[metricId] = metrics.getMeter(this._serviceName).createHistogram(metricId);
|
|
978
|
-
break;
|
|
979
|
-
case "upDownCounter":
|
|
980
|
-
this._metrics[metricId] = metrics.getMeter(this._serviceName).createUpDownCounter(metricId);
|
|
981
|
-
break;
|
|
982
|
-
case "observableCounter":
|
|
983
|
-
this._metrics[metricId] = metrics.getMeter(this._serviceName).createObservableCounter(metricId);
|
|
984
|
-
break;
|
|
985
|
-
case "observableGauge":
|
|
986
|
-
this._metrics[metricId] = metrics.getMeter(this._serviceName).createObservableGauge(metricId);
|
|
987
|
-
break;
|
|
988
|
-
case "observableUpDownCounter":
|
|
989
|
-
this._metrics[metricId] = metrics.getMeter(this._serviceName).createObservableUpDownCounter(metricId);
|
|
990
|
-
break;
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
this.log(
|
|
994
|
-
"info",
|
|
995
|
-
"OpenTelemetry Collector (Traces + Logs + Metrics) started"
|
|
996
|
-
);
|
|
997
|
-
}
|
|
998
|
-
log(level, ...args) {
|
|
999
|
-
this._logger.log(level, ...args);
|
|
1000
|
-
}
|
|
1001
|
-
info = (msg, ...args) => {
|
|
1002
|
-
this._logger.log("info", msg, ...args);
|
|
1003
|
-
};
|
|
1004
|
-
error = (msg, ...args) => {
|
|
1005
|
-
this._logger.log("error", msg, ...args);
|
|
1006
|
-
};
|
|
1007
|
-
warn = (msg, ...args) => {
|
|
1008
|
-
this._logger.log("warn", msg, ...args);
|
|
1009
|
-
};
|
|
1010
|
-
debug = (msg, ...args) => {
|
|
1011
|
-
this._logger.log("debug", msg, ...args);
|
|
1012
|
-
};
|
|
1013
|
-
trace = (msg, ...args) => {
|
|
1014
|
-
this._logger.log("trace", msg, ...args);
|
|
1015
|
-
};
|
|
1016
|
-
getMetric(metricId) {
|
|
1017
|
-
return this._metrics[metricId];
|
|
1018
|
-
}
|
|
1019
|
-
};
|
|
1020
|
-
dotenv.config({ path: getEnvVar2("DOTENV_FILE_PATH") });
|
|
1021
|
-
function parseOtelHeaders() {
|
|
1022
|
-
const headersEnv = getEnvVar2("OTEL_EXPORTER_OTLP_HEADERS");
|
|
1023
|
-
if (!headersEnv) return void 0;
|
|
1024
|
-
const headers = {};
|
|
1025
|
-
for (const pair of headersEnv.split(",")) {
|
|
1026
|
-
const [key, ...valueParts] = pair.split("=");
|
|
1027
|
-
if (key && valueParts.length > 0) {
|
|
1028
|
-
headers[key.trim()] = valueParts.join("=").trim();
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
return Object.keys(headers).length > 0 ? headers : void 0;
|
|
1032
|
-
}
|
|
1033
|
-
var otelHeaders = parseOtelHeaders();
|
|
1034
|
-
new NodeSDK({
|
|
1035
|
-
resource: resourceFromAttributes({
|
|
1036
|
-
[ATTR_SERVICE_NAME2]: getEnvVar2("OTEL_SERVICE_NAME")
|
|
1037
|
-
}),
|
|
1038
|
-
traceExporter: new OTLPTraceExporter({
|
|
1039
|
-
url: `${getEnvVar2("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/traces`,
|
|
1040
|
-
headers: otelHeaders
|
|
1041
|
-
}),
|
|
1042
|
-
metricReader: new PeriodicExportingMetricReader({
|
|
1043
|
-
exporter: new OTLPMetricExporter({
|
|
1044
|
-
url: `${getEnvVar2("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/metrics`,
|
|
1045
|
-
headers: otelHeaders
|
|
1046
|
-
}),
|
|
1047
|
-
exportIntervalMillis: 5e3
|
|
1048
|
-
}),
|
|
1049
|
-
logRecordProcessors: [
|
|
1050
|
-
new BatchLogRecordProcessor(
|
|
1051
|
-
new OTLPLogExporter({
|
|
1052
|
-
url: `${getEnvVar2("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/logs`,
|
|
1053
|
-
headers: otelHeaders
|
|
1054
|
-
})
|
|
1055
|
-
)
|
|
1056
|
-
],
|
|
1057
|
-
instrumentations: [
|
|
1058
|
-
new HttpInstrumentation({
|
|
1059
|
-
applyCustomAttributesOnSpan: (span, request) => {
|
|
1060
|
-
span.setAttribute(
|
|
1061
|
-
ATTR_SERVICE_NAME2,
|
|
1062
|
-
getEnvVar2("OTEL_SERVICE_NAME") ?? "unknown"
|
|
1063
|
-
);
|
|
1064
|
-
if (isForklaunchRequest(request)) {
|
|
1065
|
-
span.setAttribute(ATTR_API_NAME, request.contractDetails?.name);
|
|
1066
|
-
span.setAttribute(ATTR_CORRELATION_ID, request.context.correlationId);
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
}),
|
|
1070
|
-
new ExpressInstrumentation(),
|
|
1071
|
-
new HyperExpressInstrumentation()
|
|
1072
|
-
]
|
|
1073
|
-
}).start();
|
|
1074
|
-
var httpRequestsTotalCounter = metrics.getMeter(getEnvVar2("OTEL_SERVICE_NAME") || "unknown").createCounter("http_requests_total", {
|
|
1075
|
-
description: "Number of HTTP requests"
|
|
1076
|
-
});
|
|
1077
|
-
var httpServerDurationHistogram = metrics.getMeter(getEnvVar2("OTEL_SERVICE_NAME") || "unknown").createHistogram("http_server_duration", {
|
|
1078
|
-
description: "Duration of HTTP server requests",
|
|
1079
|
-
unit: "s"
|
|
1080
|
-
});
|
|
1081
|
-
|
|
1082
|
-
// src/http/middleware/request/enrichDetails.middleware.ts
|
|
1083
1105
|
function enrichDetails(path, contractDetails, requestSchema, responseSchemas, openTelemetryCollector, globalOptions) {
|
|
1084
1106
|
return (req, res, next) => {
|
|
1085
1107
|
req.originalPath = path;
|
|
@@ -3789,14 +3811,21 @@ function recordMetric(req, res) {
|
|
|
3789
3811
|
if (res.metricRecorded) {
|
|
3790
3812
|
return;
|
|
3791
3813
|
}
|
|
3792
|
-
|
|
3793
|
-
|
|
3814
|
+
const serviceName = getEnvVar4("OTEL_SERVICE_NAME") || "unknown";
|
|
3815
|
+
const attrs = {
|
|
3816
|
+
[ATTR_SERVICE_NAME3]: serviceName,
|
|
3794
3817
|
[ATTR_APPLICATION_ID]: getEnvVar4("OTEL_APPLICATION_ID"),
|
|
3795
3818
|
[ATTR_API_NAME]: req.contractDetails?.name,
|
|
3796
3819
|
[ATTR_HTTP_REQUEST_METHOD3]: req.method,
|
|
3797
3820
|
[ATTR_HTTP_ROUTE3]: req.originalPath,
|
|
3798
3821
|
[ATTR_HTTP_RESPONSE_STATUS_CODE3]: Number(res.statusCode) || 0
|
|
3799
|
-
}
|
|
3822
|
+
};
|
|
3823
|
+
httpRequestsTotalCounter.add(1, attrs);
|
|
3824
|
+
const durationMs = req.context?.requestStartTime != null ? Date.now() - req.context.requestStartTime : 0;
|
|
3825
|
+
httpRequestDurationMsHistogram.record(durationMs, attrs);
|
|
3826
|
+
if (Number(res.statusCode) >= 400) {
|
|
3827
|
+
httpErrorsTotalCounter.add(1, attrs);
|
|
3828
|
+
}
|
|
3800
3829
|
res.metricRecorded = true;
|
|
3801
3830
|
}
|
|
3802
3831
|
|
|
@@ -4438,6 +4467,9 @@ export {
|
|
|
4438
4467
|
getCachedJwks,
|
|
4439
4468
|
getCodeForStatus,
|
|
4440
4469
|
head,
|
|
4470
|
+
httpErrorsTotalCounter,
|
|
4471
|
+
httpRequestDurationMsHistogram,
|
|
4472
|
+
httpRequestsInFlightCounter,
|
|
4441
4473
|
httpRequestsTotalCounter,
|
|
4442
4474
|
httpServerDurationHistogram,
|
|
4443
4475
|
isClientError,
|