apitally 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -44
- package/dist/adonisjs/middleware.cjs +3 -0
- package/dist/adonisjs/middleware.cjs.map +1 -1
- package/dist/adonisjs/middleware.js +3 -0
- package/dist/adonisjs/middleware.js.map +1 -1
- package/dist/adonisjs/provider.cjs +18 -5
- package/dist/adonisjs/provider.cjs.map +1 -1
- package/dist/adonisjs/provider.js +18 -5
- package/dist/adonisjs/provider.js.map +1 -1
- package/dist/common/client.cjs +2 -2
- package/dist/common/client.cjs.map +1 -1
- package/dist/common/client.js +2 -2
- package/dist/common/client.js.map +1 -1
- package/dist/common/requestLogger.cjs +3 -0
- package/dist/common/requestLogger.cjs.map +1 -1
- package/dist/common/requestLogger.d.cts +1 -1
- package/dist/common/requestLogger.d.ts +1 -1
- package/dist/common/requestLogger.js +3 -0
- package/dist/common/requestLogger.js.map +1 -1
- package/dist/common/response.cjs +12 -6
- package/dist/common/response.cjs.map +1 -1
- package/dist/common/response.d.cts +3 -3
- package/dist/common/response.d.ts +3 -3
- package/dist/common/response.js +12 -6
- package/dist/common/response.js.map +1 -1
- package/dist/common/validationErrorCounter.cjs +2 -2
- package/dist/common/validationErrorCounter.cjs.map +1 -1
- package/dist/common/validationErrorCounter.js +2 -2
- package/dist/common/validationErrorCounter.js.map +1 -1
- package/dist/elysia/index.cjs +1582 -0
- package/dist/elysia/index.cjs.map +1 -0
- package/dist/elysia/index.d.cts +9 -0
- package/dist/elysia/index.d.ts +9 -0
- package/dist/elysia/index.js +1552 -0
- package/dist/elysia/index.js.map +1 -0
- package/dist/elysia/plugin.cjs +1576 -0
- package/dist/elysia/plugin.cjs.map +1 -0
- package/dist/elysia/plugin.d.cts +53 -0
- package/dist/elysia/plugin.d.ts +53 -0
- package/dist/elysia/plugin.js +1552 -0
- package/dist/elysia/plugin.js.map +1 -0
- package/dist/elysia/utils.cjs +98 -0
- package/dist/elysia/utils.cjs.map +1 -0
- package/dist/elysia/utils.d.cts +12 -0
- package/dist/elysia/utils.d.ts +12 -0
- package/dist/elysia/utils.js +78 -0
- package/dist/elysia/utils.js.map +1 -0
- package/dist/express/index.cjs +21 -5
- package/dist/express/index.cjs.map +1 -1
- package/dist/express/index.js +21 -5
- package/dist/express/index.js.map +1 -1
- package/dist/express/middleware.cjs +21 -5
- package/dist/express/middleware.cjs.map +1 -1
- package/dist/express/middleware.js +21 -5
- package/dist/express/middleware.js.map +1 -1
- package/dist/fastify/index.cjs +21 -5
- package/dist/fastify/index.cjs.map +1 -1
- package/dist/fastify/index.js +21 -5
- package/dist/fastify/index.js.map +1 -1
- package/dist/fastify/plugin.cjs +21 -5
- package/dist/fastify/plugin.cjs.map +1 -1
- package/dist/fastify/plugin.js +21 -5
- package/dist/fastify/plugin.js.map +1 -1
- package/dist/h3/index.cjs +16 -7
- package/dist/h3/index.cjs.map +1 -1
- package/dist/h3/index.js +16 -7
- package/dist/h3/index.js.map +1 -1
- package/dist/h3/plugin.cjs +16 -7
- package/dist/h3/plugin.cjs.map +1 -1
- package/dist/h3/plugin.js +16 -7
- package/dist/h3/plugin.js.map +1 -1
- package/dist/hono/index.cjs +17 -8
- package/dist/hono/index.cjs.map +1 -1
- package/dist/hono/index.js +17 -8
- package/dist/hono/index.js.map +1 -1
- package/dist/hono/middleware.cjs +17 -8
- package/dist/hono/middleware.cjs.map +1 -1
- package/dist/hono/middleware.js +17 -8
- package/dist/hono/middleware.js.map +1 -1
- package/dist/koa/index.cjs +5 -2
- package/dist/koa/index.cjs.map +1 -1
- package/dist/koa/index.js +5 -2
- package/dist/koa/index.js.map +1 -1
- package/dist/koa/middleware.cjs +5 -2
- package/dist/koa/middleware.cjs.map +1 -1
- package/dist/koa/middleware.js +5 -2
- package/dist/koa/middleware.js.map +1 -1
- package/dist/loggers/index.cjs +16 -3
- package/dist/loggers/index.cjs.map +1 -1
- package/dist/loggers/index.js +16 -3
- package/dist/loggers/index.js.map +1 -1
- package/dist/loggers/pino.cjs +16 -3
- package/dist/loggers/pino.cjs.map +1 -1
- package/dist/loggers/pino.js +16 -3
- package/dist/loggers/pino.js.map +1 -1
- package/dist/nestjs/index.cjs +113 -97
- package/dist/nestjs/index.cjs.map +1 -1
- package/dist/nestjs/index.js +113 -97
- package/dist/nestjs/index.js.map +1 -1
- package/package.json +23 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/elysia/plugin.ts","../../src/common/client.ts","../../src/common/consumerRegistry.ts","../../src/common/logging.ts","../../src/common/paramValidation.ts","../../src/common/requestCounter.ts","../../src/common/requestLogger.ts","../../src/common/sentry.ts","../../src/common/serverErrorCounter.ts","../../src/common/tempGzipFile.ts","../../src/common/validationErrorCounter.ts","../../src/common/headers.ts","../../src/common/response.ts","../../src/loggers/console.ts","../../src/loggers/utils.ts","../../src/loggers/pino.ts","../../src/loggers/winston.ts","../../src/common/packageVersions.ts","../../src/elysia/utils.ts"],"sourcesContent":["import { Context, Elysia, StatusMap, ValidationError } from \"elysia\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { performance } from \"node:perf_hooks\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport { parseContentLength } from \"../common/headers.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertHeaders } from \"../common/requestLogger.js\";\nimport {\n getResponseBody,\n measureResponseSize,\n teeResponse,\n} from \"../common/response.js\";\nimport { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nimport { patchConsole, patchWinston } from \"../loggers/index.js\";\nimport { getAppInfo } from \"./utils.js\";\n\nconst START_TIME_SYMBOL = Symbol(\"apitally.startTime\");\nconst REQUEST_BODY_SYMBOL = Symbol(\"apitally.requestBody\");\nconst RESPONSE_SYMBOL = Symbol(\"apitally.response\");\nconst ERROR_SYMBOL = Symbol(\"apitally.error\");\n\ndeclare global {\n interface Request {\n [START_TIME_SYMBOL]?: number;\n [REQUEST_BODY_SYMBOL]?: Buffer;\n [RESPONSE_SYMBOL]?: Response;\n [ERROR_SYMBOL]?: Readonly<Error>;\n }\n}\n\ninterface ApitallyContext {\n consumer?: ApitallyConsumer | string;\n}\n\nexport default function apitallyPlugin(config: ApitallyConfig) {\n const client = new ApitallyClient(config);\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\n\n if (client.requestLogger.enabled && client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n return (app: Elysia) => {\n const handler = app[\"~adapter\"].handler;\n const originalMapResponse = handler.mapResponse;\n const originalMapCompactResponse = handler.mapCompactResponse;\n const originalMapEarlyResponse = handler.mapEarlyResponse;\n\n const captureResponse = (response: unknown, request?: Request) => {\n if (request instanceof Request && response instanceof Response) {\n const [newResponse1, newResponse2] = teeResponse(response);\n request[RESPONSE_SYMBOL] = newResponse2;\n return newResponse1;\n } else {\n return response;\n }\n };\n\n handler.mapResponse = function wrappedMapResponse(\n response: unknown,\n set: Context[\"set\"],\n request?: Request,\n ) {\n const mappedResponse = originalMapResponse(response, set, request);\n const newResponse = captureResponse(mappedResponse, request);\n return newResponse;\n };\n handler.mapCompactResponse = function wrappedMapCompactResponse(\n response: unknown,\n request?: Request,\n ) {\n const mappedResponse = originalMapCompactResponse(response, request);\n const newResponse = captureResponse(mappedResponse, request);\n return newResponse;\n };\n handler.mapEarlyResponse = function wrappedMapEarlyResponse(\n response: unknown,\n set: Context[\"set\"],\n request?: Request,\n ) {\n const mappedResponse = originalMapEarlyResponse(response, set, request);\n const newResponse = captureResponse(mappedResponse, request);\n return newResponse;\n };\n\n return app\n .decorate(\"apitally\", {} as ApitallyContext)\n .onStart(() => {\n const appInfo = getAppInfo(app, config.appVersion);\n client.setStartupData(appInfo);\n })\n .onStop(async () => {\n await client.handleShutdown();\n })\n .onRequest(async ({ request }) => {\n if (!client.isEnabled() || request.method.toUpperCase() === \"OPTIONS\") {\n return;\n }\n\n logsContext.enterWith([]);\n request[START_TIME_SYMBOL] = performance.now();\n\n // Capture request body for logging if enabled\n if (\n client.requestLogger.enabled &&\n client.requestLogger.config.logRequestBody\n ) {\n const contentType = request.headers.get(\"content-type\");\n const requestSize =\n parseContentLength(request.headers.get(\"content-length\")) ?? 0;\n\n if (\n client.requestLogger.isSupportedContentType(contentType) &&\n requestSize <= client.requestLogger.maxBodySize\n ) {\n try {\n request[REQUEST_BODY_SYMBOL] = Buffer.from(\n await request.clone().arrayBuffer(),\n );\n } catch (error) {\n // ignore\n }\n }\n }\n })\n .onAfterResponse(async ({ request, set, route, apitally }) => {\n if (!client.isEnabled() || request.method.toUpperCase() === \"OPTIONS\") {\n return;\n }\n\n const startTime = request[START_TIME_SYMBOL];\n const responseTime = startTime ? performance.now() - startTime : 0;\n\n const requestBody = request[REQUEST_BODY_SYMBOL];\n const requestSize =\n parseContentLength(request.headers.get(\"content-length\")) ??\n requestBody?.length;\n\n const error = request[ERROR_SYMBOL];\n let response = request[RESPONSE_SYMBOL];\n let responseBody: Buffer | undefined;\n let responseSize: number | undefined;\n\n if (\n !response &&\n error &&\n \"toResponse\" in error &&\n typeof error.toResponse === \"function\"\n ) {\n try {\n response = error.toResponse();\n } catch (error) {\n // ignore\n }\n }\n\n if (response instanceof Response) {\n if (\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody &&\n client.requestLogger.isSupportedContentType(\n response.headers.get(\"content-type\"),\n )\n ) {\n responseBody = (await getResponseBody(response, false))[0];\n responseSize = responseBody.length;\n } else {\n responseSize = (await measureResponseSize(response, false))[0];\n }\n }\n\n const statusCode = response?.status ?? getStatusCode(set) ?? 200;\n const responseHeaders = response?.headers ?? set.headers;\n\n const consumer = apitally.consumer\n ? consumerFromStringOrObject(apitally.consumer)\n : null;\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (route) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: request.method,\n path: route,\n statusCode,\n responseTime,\n requestSize,\n responseSize,\n });\n\n // Handle server errors\n if (statusCode === 500 && error) {\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: request.method,\n path: route,\n type: error.name,\n msg: error.message,\n traceback: error.stack || \"\",\n });\n }\n\n // Handle validation errors\n if (\n (statusCode === 400 || statusCode === 422) &&\n error instanceof ValidationError\n ) {\n try {\n const parsedMessage = JSON.parse(error.message);\n client.validationErrorCounter.addValidationError({\n consumer: consumer?.identifier,\n method: request.method,\n path: route,\n loc:\n (parsedMessage.on ?? \"\") +\n \".\" +\n (parsedMessage.property ?? \"\"),\n msg: parsedMessage.message,\n type: \"\",\n });\n } catch (error) {\n // ignore\n }\n }\n }\n\n // Request logging\n if (client.requestLogger.enabled) {\n const logs = logsContext.getStore();\n client.requestLogger.logRequest(\n {\n timestamp: (Date.now() - responseTime) / 1000,\n method: request.method,\n path: route,\n url: request.url,\n headers: convertHeaders(\n Object.fromEntries(request.headers.entries()),\n ),\n size: requestSize,\n consumer: consumer?.identifier,\n body: requestBody,\n },\n {\n statusCode,\n responseTime: responseTime / 1000,\n headers: convertHeaders(responseHeaders),\n size: responseSize,\n body: responseBody,\n },\n error,\n logs,\n );\n }\n })\n .onError(({ request, error }) => {\n if (client.isEnabled() && error instanceof Error) {\n request[ERROR_SYMBOL] = error;\n }\n });\n };\n}\n\nfunction getStatusCode(set: Context[\"set\"]) {\n if (typeof set.status === \"number\") {\n return set.status;\n } else if (typeof set.status === \"string\") {\n return StatusMap[set.status];\n }\n}\n","import fetchRetry from \"fetch-retry\";\nimport { randomUUID } from \"node:crypto\";\n\nimport ConsumerRegistry from \"./consumerRegistry.js\";\nimport { Logger, getLogger } from \"./logging.js\";\nimport { isValidClientId, isValidEnv } from \"./paramValidation.js\";\nimport RequestCounter from \"./requestCounter.js\";\nimport RequestLogger from \"./requestLogger.js\";\nimport ServerErrorCounter from \"./serverErrorCounter.js\";\nimport {\n ApitallyConfig,\n StartupData,\n StartupPayload,\n SyncPayload,\n} from \"./types.js\";\nimport ValidationErrorCounter from \"./validationErrorCounter.js\";\n\nconst SYNC_INTERVAL = 60000; // 60 seconds\nconst INITIAL_SYNC_INTERVAL = 10000; // 10 seconds\nconst INITIAL_SYNC_INTERVAL_DURATION = 3600000; // 1 hour\nconst MAX_QUEUE_TIME = 3.6e6; // 1 hour\n\nclass HTTPError extends Error {\n public response: Response;\n\n constructor(response: Response) {\n const reason = response.status\n ? `status code ${response.status}`\n : \"an unknown error\";\n super(`Request failed with ${reason}`);\n this.response = response;\n }\n}\n\nexport class ApitallyClient {\n private clientId: string;\n private env: string;\n\n private static instance?: ApitallyClient;\n private instanceUuid: string;\n private syncDataQueue: SyncPayload[];\n private syncIntervalId?: NodeJS.Timeout;\n public startupData?: StartupData;\n private startupDataSent: boolean = false;\n private enabled: boolean = true;\n\n public requestCounter: RequestCounter;\n public requestLogger: RequestLogger;\n public validationErrorCounter: ValidationErrorCounter;\n public serverErrorCounter: ServerErrorCounter;\n public consumerRegistry: ConsumerRegistry;\n public logger: Logger;\n\n constructor({\n clientId,\n env = \"dev\",\n requestLogging,\n requestLoggingConfig,\n logger,\n }: ApitallyConfig) {\n if (ApitallyClient.instance) {\n throw new Error(\"Apitally client is already initialized\");\n }\n if (!isValidClientId(clientId)) {\n throw new Error(\n `Invalid Apitally client ID '${clientId}' (expecting hexadecimal UUID format)`,\n );\n }\n if (!isValidEnv(env)) {\n throw new Error(\n `Invalid env '${env}' (expecting 1-32 alphanumeric lowercase characters and hyphens only)`,\n );\n }\n if (requestLoggingConfig && !requestLogging) {\n console.warn(\n \"requestLoggingConfig is deprecated, use requestLogging instead.\",\n );\n }\n\n ApitallyClient.instance = this;\n this.clientId = clientId;\n this.env = env;\n this.instanceUuid = randomUUID();\n this.syncDataQueue = [];\n this.requestCounter = new RequestCounter();\n this.requestLogger = new RequestLogger(\n requestLogging ?? requestLoggingConfig,\n );\n this.validationErrorCounter = new ValidationErrorCounter();\n this.serverErrorCounter = new ServerErrorCounter();\n this.consumerRegistry = new ConsumerRegistry();\n this.logger = logger ?? getLogger();\n\n this.startSync();\n this.handleShutdown = this.handleShutdown.bind(this);\n }\n\n public static getInstance() {\n if (!ApitallyClient.instance) {\n throw new Error(\"Apitally client is not initialized\");\n }\n return ApitallyClient.instance;\n }\n\n public isEnabled() {\n return this.enabled;\n }\n\n public static async shutdown() {\n if (ApitallyClient.instance) {\n await ApitallyClient.instance.handleShutdown();\n }\n }\n\n public async handleShutdown() {\n this.enabled = false;\n this.stopSync();\n await this.sendSyncData();\n await this.sendLogData();\n await this.requestLogger.close();\n ApitallyClient.instance = undefined;\n }\n\n private getHubUrlPrefix() {\n const baseURL =\n process.env.APITALLY_HUB_BASE_URL || \"https://hub.apitally.io\";\n const version = \"v2\";\n return `${baseURL}/${version}/${this.clientId}/${this.env}/`;\n }\n\n private async sendData(url: string, payload: any) {\n const fetchWithRetry = fetchRetry(fetch, {\n retries: 3,\n retryDelay: 1000,\n retryOn: [408, 429, 500, 502, 503, 504],\n });\n const response = await fetchWithRetry(this.getHubUrlPrefix() + url, {\n method: \"POST\",\n body: JSON.stringify(payload),\n headers: { \"Content-Type\": \"application/json\" },\n });\n if (!response.ok) {\n throw new HTTPError(response);\n }\n }\n\n private startSync() {\n this.sync();\n this.syncIntervalId = setInterval(() => {\n this.sync();\n }, INITIAL_SYNC_INTERVAL);\n setTimeout(() => {\n clearInterval(this.syncIntervalId);\n this.syncIntervalId = setInterval(() => {\n this.sync();\n }, SYNC_INTERVAL);\n }, INITIAL_SYNC_INTERVAL_DURATION);\n }\n\n private async sync() {\n try {\n const promises = [this.sendSyncData(), this.sendLogData()];\n if (!this.startupDataSent) {\n promises.push(this.sendStartupData());\n }\n await Promise.all(promises);\n } catch (error) {\n this.logger.error(\"Error while syncing with Apitally Hub\", {\n error,\n });\n }\n }\n\n private stopSync() {\n if (this.syncIntervalId) {\n clearInterval(this.syncIntervalId);\n this.syncIntervalId = undefined;\n }\n }\n\n public setStartupData(data: StartupData) {\n this.startupData = data;\n this.startupDataSent = false;\n this.sendStartupData();\n }\n\n private async sendStartupData() {\n if (this.startupData) {\n this.logger.debug(\"Sending startup data to Apitally Hub\");\n const payload: StartupPayload = {\n instance_uuid: this.instanceUuid,\n message_uuid: randomUUID(),\n ...this.startupData,\n };\n try {\n await this.sendData(\"startup\", payload);\n this.startupDataSent = true;\n } catch (error) {\n const handled = this.handleHubError(error);\n if (!handled) {\n this.logger.error((error as Error).message);\n this.logger.debug(\n \"Error while sending startup data to Apitally Hub (will retry)\",\n { error },\n );\n }\n }\n }\n }\n\n private async sendSyncData() {\n this.logger.debug(\"Synchronizing data with Apitally Hub\");\n const newPayload: SyncPayload = {\n timestamp: Date.now() / 1000,\n instance_uuid: this.instanceUuid,\n message_uuid: randomUUID(),\n requests: this.requestCounter.getAndResetRequests(),\n validation_errors:\n this.validationErrorCounter.getAndResetValidationErrors(),\n server_errors: this.serverErrorCounter.getAndResetServerErrors(),\n consumers: this.consumerRegistry.getAndResetUpdatedConsumers(),\n };\n this.syncDataQueue.push(newPayload);\n\n let i = 0;\n while (this.syncDataQueue.length > 0) {\n const payload = this.syncDataQueue.shift();\n if (payload) {\n try {\n if (Date.now() - payload.timestamp * 1000 <= MAX_QUEUE_TIME) {\n if (i > 0) {\n await this.randomDelay();\n }\n await this.sendData(\"sync\", payload);\n i += 1;\n }\n } catch (error) {\n const handled = this.handleHubError(error);\n if (!handled) {\n this.logger.debug(\n \"Error while synchronizing data with Apitally Hub (will retry)\",\n { error },\n );\n this.syncDataQueue.push(payload);\n break;\n }\n }\n }\n }\n }\n\n private async sendLogData() {\n this.logger.debug(\"Sending request log data to Apitally Hub\");\n await this.requestLogger.rotateFile();\n\n const fetchWithRetry = fetchRetry(fetch, {\n retries: 3,\n retryDelay: 1000,\n retryOn: [408, 429, 500, 502, 503, 504],\n });\n\n let i = 0;\n let logFile;\n while ((logFile = this.requestLogger.getFile())) {\n if (i > 0) {\n await this.randomDelay();\n }\n\n try {\n const response = await fetchWithRetry(\n `${this.getHubUrlPrefix()}log?uuid=${logFile.uuid}`,\n {\n method: \"POST\",\n body: (await logFile.getContent()) as any,\n },\n );\n\n if (response.status === 402 && response.headers.has(\"Retry-After\")) {\n const retryAfter = parseInt(\n response.headers.get(\"Retry-After\") ?? \"0\",\n );\n if (retryAfter > 0) {\n this.requestLogger.suspendUntil = Date.now() + retryAfter * 1000;\n this.requestLogger.clear();\n return;\n }\n }\n\n if (!response.ok) {\n throw new HTTPError(response);\n }\n\n logFile.delete();\n } catch (error) {\n this.requestLogger.retryFileLater(logFile);\n break;\n }\n\n i++;\n if (i >= 10) break;\n }\n }\n\n private handleHubError(error: unknown) {\n if (error instanceof HTTPError) {\n if (error.response.status === 404) {\n this.logger.error(`Invalid Apitally client ID: '${this.clientId}'`);\n this.enabled = false;\n this.stopSync();\n return true;\n }\n if (error.response.status === 422) {\n this.logger.error(\"Received validation error from Apitally Hub\");\n return true;\n }\n }\n return false;\n }\n\n private async randomDelay() {\n const delay = 100 + Math.random() * 400;\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n}\n","import { ApitallyConsumer } from \"./types.js\";\n\nexport const consumerFromStringOrObject = (\n consumer: ApitallyConsumer | string,\n) => {\n if (typeof consumer === \"string\") {\n consumer = String(consumer).trim().substring(0, 128);\n return consumer ? { identifier: consumer } : null;\n } else {\n consumer.identifier = String(consumer.identifier).trim().substring(0, 128);\n consumer.name = consumer.name?.trim().substring(0, 64);\n consumer.group = consumer.group?.trim().substring(0, 64);\n return consumer.identifier ? consumer : null;\n }\n};\n\nexport default class ConsumerRegistry {\n private consumers: Map<string, ApitallyConsumer>;\n private updated: Set<string>;\n\n constructor() {\n this.consumers = new Map();\n this.updated = new Set();\n }\n\n public addOrUpdateConsumer(consumer?: ApitallyConsumer | null) {\n if (!consumer || (!consumer.name && !consumer.group)) {\n return;\n }\n const existing = this.consumers.get(consumer.identifier);\n if (!existing) {\n this.consumers.set(consumer.identifier, consumer);\n this.updated.add(consumer.identifier);\n } else {\n if (consumer.name && consumer.name !== existing.name) {\n existing.name = consumer.name;\n this.updated.add(consumer.identifier);\n }\n if (consumer.group && consumer.group !== existing.group) {\n existing.group = consumer.group;\n this.updated.add(consumer.identifier);\n }\n }\n }\n\n public getAndResetUpdatedConsumers() {\n const data: Array<ApitallyConsumer> = [];\n this.updated.forEach((identifier) => {\n const consumer = this.consumers.get(identifier);\n if (consumer) {\n data.push(consumer);\n }\n });\n this.updated.clear();\n return data;\n }\n}\n","import { createLogger, format, transports } from \"winston\";\n\nexport interface Logger {\n debug: (message: string, meta?: object) => void;\n info: (message: string, meta?: object) => void;\n warn: (message: string, meta?: object) => void;\n error: (message: string, meta?: object) => void;\n}\n\nexport function getLogger() {\n return createLogger({\n level: process.env.APITALLY_DEBUG ? \"debug\" : \"warn\",\n format: format.combine(\n format.colorize(),\n format.timestamp(),\n format.printf(\n (info) => `${info.timestamp} ${info.level}: ${info.message}`,\n ),\n ),\n transports: [new transports.Console()],\n });\n}\n","export function isValidClientId(clientId: string): boolean {\n const regexExp =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n return regexExp.test(clientId);\n}\n\nexport function isValidEnv(env: string): boolean {\n const regexExp = /^[\\w-]{1,32}$/;\n return regexExp.test(env);\n}\n","import { RequestInfo, RequestsItem } from \"./types.js\";\n\nexport default class RequestCounter {\n private requestCounts: Map<string, number>;\n private requestSizeSums: Map<string, number>;\n private responseSizeSums: Map<string, number>;\n private responseTimes: Map<string, Map<number, number>>;\n private requestSizes: Map<string, Map<number, number>>;\n private responseSizes: Map<string, Map<number, number>>;\n\n constructor() {\n this.requestCounts = new Map<string, number>();\n this.requestSizeSums = new Map<string, number>();\n this.responseSizeSums = new Map<string, number>();\n this.responseTimes = new Map<string, Map<number, number>>();\n this.requestSizes = new Map<string, Map<number, number>>();\n this.responseSizes = new Map<string, Map<number, number>>();\n }\n\n private getKey(requestInfo: RequestInfo) {\n return [\n requestInfo.consumer || \"\",\n requestInfo.method.toUpperCase(),\n requestInfo.path,\n requestInfo.statusCode,\n ].join(\"|\");\n }\n\n addRequest(requestInfo: RequestInfo) {\n const key = this.getKey(requestInfo);\n\n // Increment request count\n this.requestCounts.set(key, (this.requestCounts.get(key) || 0) + 1);\n\n // Add response time\n if (!this.responseTimes.has(key)) {\n this.responseTimes.set(key, new Map<number, number>());\n }\n const responseTimeMap = this.responseTimes.get(key)!;\n const responseTimeMsBin = Math.floor(requestInfo.responseTime / 10) * 10; // Rounded to nearest 10ms\n responseTimeMap.set(\n responseTimeMsBin,\n (responseTimeMap.get(responseTimeMsBin) || 0) + 1,\n );\n\n // Add request size\n if (requestInfo.requestSize !== undefined) {\n requestInfo.requestSize = Number(requestInfo.requestSize);\n this.requestSizeSums.set(\n key,\n (this.requestSizeSums.get(key) || 0) + requestInfo.requestSize,\n );\n if (!this.requestSizes.has(key)) {\n this.requestSizes.set(key, new Map<number, number>());\n }\n const requestSizeMap = this.requestSizes.get(key)!;\n const requestSizeKbBin = Math.floor(requestInfo.requestSize / 1000); // Rounded down to nearest KB\n requestSizeMap.set(\n requestSizeKbBin,\n (requestSizeMap.get(requestSizeKbBin) || 0) + 1,\n );\n }\n\n // Add response size\n if (requestInfo.responseSize !== undefined) {\n requestInfo.responseSize = Number(requestInfo.responseSize);\n this.responseSizeSums.set(\n key,\n (this.responseSizeSums.get(key) || 0) + requestInfo.responseSize,\n );\n if (!this.responseSizes.has(key)) {\n this.responseSizes.set(key, new Map<number, number>());\n }\n const responseSizeMap = this.responseSizes.get(key)!;\n const responseSizeKbBin = Math.floor(requestInfo.responseSize / 1000); // Rounded down to nearest KB\n responseSizeMap.set(\n responseSizeKbBin,\n (responseSizeMap.get(responseSizeKbBin) || 0) + 1,\n );\n }\n }\n\n getAndResetRequests() {\n const data: Array<RequestsItem> = [];\n this.requestCounts.forEach((count, key) => {\n const [consumer, method, path, statusCodeStr] = key.split(\"|\");\n const responseTimes =\n this.responseTimes.get(key) || new Map<number, number>();\n const requestSizes =\n this.requestSizes.get(key) || new Map<number, number>();\n const responseSizes =\n this.responseSizes.get(key) || new Map<number, number>();\n data.push({\n consumer: consumer || null,\n method,\n path,\n status_code: parseInt(statusCodeStr),\n request_count: count,\n request_size_sum: this.requestSizeSums.get(key) || 0,\n response_size_sum: this.responseSizeSums.get(key) || 0,\n response_times: Object.fromEntries(responseTimes),\n request_sizes: Object.fromEntries(requestSizes),\n response_sizes: Object.fromEntries(responseSizes),\n });\n });\n\n // Reset the counts and times\n this.requestCounts.clear();\n this.requestSizeSums.clear();\n this.responseSizeSums.clear();\n this.responseTimes.clear();\n this.requestSizes.clear();\n this.responseSizes.clear();\n\n return data;\n }\n}\n","import AsyncLock from \"async-lock\";\nimport { Buffer } from \"node:buffer\";\nimport { randomUUID } from \"node:crypto\";\nimport { unlinkSync, writeFileSync } from \"node:fs\";\nimport { IncomingHttpHeaders, OutgoingHttpHeaders } from \"node:http\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { getSentryEventId } from \"./sentry.js\";\nimport {\n truncateExceptionMessage,\n truncateExceptionStackTrace,\n} from \"./serverErrorCounter.js\";\nimport TempGzipFile from \"./tempGzipFile.js\";\n\nconst MAX_BODY_SIZE = 50_000; // 50 KB (uncompressed)\nconst MAX_FILE_SIZE = 1_000_000; // 1 MB (compressed)\nconst MAX_FILES = 50;\nconst MAX_PENDING_WRITES = 100;\nconst MAX_LOG_MSG_LENGTH = 2048;\nconst BODY_TOO_LARGE = Buffer.from(\"<body too large>\");\nconst BODY_MASKED = Buffer.from(\"<masked>\");\nconst MASKED = \"******\";\nconst ALLOWED_CONTENT_TYPES = [\n \"application/json\",\n \"application/problem+json\",\n \"application/vnd.api+json\",\n \"text/plain\",\n];\nconst EXCLUDE_PATH_PATTERNS = [\n /\\/_?healthz?$/i,\n /\\/_?health[_-]?checks?$/i,\n /\\/_?heart[_-]?beats?$/i,\n /\\/ping$/i,\n /\\/ready$/i,\n /\\/live$/i,\n];\nconst EXCLUDE_USER_AGENT_PATTERNS = [\n /health[-_ ]?check/i,\n /microsoft-azure-application-lb/i,\n /googlehc/i,\n /kube-probe/i,\n];\nconst MASK_QUERY_PARAM_PATTERNS = [\n /auth/i,\n /api-?key/i,\n /secret/i,\n /token/i,\n /password/i,\n /pwd/i,\n];\nconst MASK_HEADER_PATTERNS = [\n /auth/i,\n /api-?key/i,\n /secret/i,\n /token/i,\n /cookie/i,\n];\nconst MASK_BODY_FIELD_PATTERNS = [\n /password/i,\n /pwd/i,\n /token/i,\n /secret/i,\n /auth/i,\n /card[-_ ]?number/i,\n /ccv/i,\n /ssn/i,\n];\n\nexport type Request = {\n timestamp: number;\n method: string;\n path?: string;\n url: string;\n headers: [string, string][];\n size?: number;\n consumer?: string;\n body?: Buffer;\n};\n\nexport type Response = {\n statusCode: number;\n responseTime: number;\n headers: [string, string][];\n size?: number;\n body?: Buffer;\n};\n\nexport type LogRecord = {\n timestamp: number;\n logger?: string;\n level: string;\n message: string;\n};\n\nexport type RequestLoggingConfig = {\n enabled: boolean;\n logQueryParams: boolean;\n logRequestHeaders: boolean;\n logRequestBody: boolean;\n logResponseHeaders: boolean;\n logResponseBody: boolean;\n logException: boolean;\n captureLogs: boolean;\n maskQueryParams: RegExp[];\n maskHeaders: RegExp[];\n maskBodyFields: RegExp[];\n maskRequestBodyCallback?: (request: Request) => Buffer | null | undefined;\n maskResponseBodyCallback?: (\n request: Request,\n response: Response,\n ) => Buffer | null | undefined;\n excludePaths: RegExp[];\n excludeCallback?: (request: Request, response: Response) => boolean;\n};\n\nconst DEFAULT_CONFIG: RequestLoggingConfig = {\n enabled: false,\n logQueryParams: true,\n logRequestHeaders: false,\n logRequestBody: false,\n logResponseHeaders: true,\n logResponseBody: false,\n logException: true,\n captureLogs: false,\n maskQueryParams: [],\n maskHeaders: [],\n maskBodyFields: [],\n excludePaths: [],\n};\n\ntype RequestLogItem = {\n uuid: string;\n request: Request;\n response: Response;\n exception?: {\n type: string;\n message: string;\n stacktrace: string;\n sentryEventId?: string;\n };\n logs?: LogRecord[];\n};\n\nexport default class RequestLogger {\n public config: RequestLoggingConfig;\n public enabled: boolean;\n public suspendUntil: number | null = null;\n private pendingWrites: RequestLogItem[] = [];\n private currentFile: TempGzipFile | null = null;\n private files: TempGzipFile[] = [];\n private maintainIntervalId?: NodeJS.Timeout;\n private lock = new AsyncLock();\n\n constructor(config?: Partial<RequestLoggingConfig>) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.enabled = this.config.enabled && checkWritableFs();\n\n if (this.enabled) {\n this.maintainIntervalId = setInterval(() => {\n this.maintain();\n }, 1000);\n }\n }\n\n get maxBodySize() {\n return MAX_BODY_SIZE;\n }\n\n private shouldExcludePath(urlPath: string) {\n const patterns = [...this.config.excludePaths, ...EXCLUDE_PATH_PATTERNS];\n return matchPatterns(urlPath, patterns);\n }\n\n private shouldExcludeUserAgent(userAgent?: string) {\n return userAgent\n ? matchPatterns(userAgent, EXCLUDE_USER_AGENT_PATTERNS)\n : false;\n }\n\n private shouldMaskQueryParam(name: string) {\n const patterns = [\n ...this.config.maskQueryParams,\n ...MASK_QUERY_PARAM_PATTERNS,\n ];\n return matchPatterns(name, patterns);\n }\n\n private shouldMaskHeader(name: string) {\n const patterns = [...this.config.maskHeaders, ...MASK_HEADER_PATTERNS];\n return matchPatterns(name, patterns);\n }\n\n private shouldMaskBodyField(name: string) {\n const patterns = [\n ...this.config.maskBodyFields,\n ...MASK_BODY_FIELD_PATTERNS,\n ];\n return matchPatterns(name, patterns);\n }\n\n private hasSupportedContentType(headers: [string, string][]) {\n const contentType = headers.find(\n ([k]) => k.toLowerCase() === \"content-type\",\n )?.[1];\n return this.isSupportedContentType(contentType);\n }\n\n private hasJsonContentType(headers: [string, string][]) {\n const contentType = headers.find(\n ([k]) => k.toLowerCase() === \"content-type\",\n )?.[1];\n return contentType ? /\\bjson\\b/i.test(contentType) : null;\n }\n\n public isSupportedContentType(contentType?: string | null) {\n return (\n typeof contentType === \"string\" &&\n ALLOWED_CONTENT_TYPES.some((t) => contentType.startsWith(t))\n );\n }\n\n private maskQueryParams(search: string) {\n const params = new URLSearchParams(search);\n for (const [key] of params) {\n if (this.shouldMaskQueryParam(key)) {\n params.set(key, MASKED);\n }\n }\n return params.toString();\n }\n\n private maskHeaders(headers: [string, string][]): [string, string][] {\n return headers.map(([k, v]) => [k, this.shouldMaskHeader(k) ? MASKED : v]);\n }\n\n private maskBody(data: any): any {\n if (typeof data === \"object\" && data !== null && !Array.isArray(data)) {\n const result: any = {};\n for (const [key, value] of Object.entries(data)) {\n if (typeof value === \"string\" && this.shouldMaskBodyField(key)) {\n result[key] = MASKED;\n } else {\n result[key] = this.maskBody(value);\n }\n }\n return result;\n }\n if (Array.isArray(data)) {\n return data.map((item) => this.maskBody(item));\n }\n return data;\n }\n\n private applyMasking(item: RequestLogItem) {\n // Apply user-provided maskRequestBodyCallback function\n if (\n this.config.maskRequestBodyCallback &&\n item.request.body &&\n item.request.body !== BODY_TOO_LARGE\n ) {\n try {\n const maskedBody = this.config.maskRequestBodyCallback(item.request);\n item.request.body = maskedBody ?? BODY_MASKED;\n } catch {\n item.request.body = undefined;\n }\n }\n\n // Apply user-provided maskResponseBodyCallback function\n if (\n this.config.maskResponseBodyCallback &&\n item.response.body &&\n item.response.body !== BODY_TOO_LARGE\n ) {\n try {\n const maskedBody = this.config.maskResponseBodyCallback(\n item.request,\n item.response,\n );\n item.response.body = maskedBody ?? BODY_MASKED;\n } catch {\n item.response.body = undefined;\n }\n }\n\n // Check request and response body sizes\n if (item.request.body && item.request.body.length > MAX_BODY_SIZE) {\n item.request.body = BODY_TOO_LARGE;\n }\n if (item.response.body && item.response.body.length > MAX_BODY_SIZE) {\n item.response.body = BODY_TOO_LARGE;\n }\n\n // Mask request and response body fields\n for (const key of [\"request\", \"response\"] as const) {\n const bodyData = item[key].body;\n if (\n !bodyData ||\n bodyData === BODY_TOO_LARGE ||\n bodyData === BODY_MASKED\n ) {\n continue;\n }\n\n const headers = item[key].headers;\n const hasJsonContent = this.hasJsonContentType(headers);\n if (hasJsonContent === null || hasJsonContent) {\n try {\n const parsedBody = JSON.parse(bodyData.toString());\n const maskedBody = this.maskBody(parsedBody);\n item[key].body = Buffer.from(JSON.stringify(maskedBody));\n } catch {\n // If parsing fails, leave body as is\n }\n }\n }\n\n // Mask request and response headers\n item.request.headers = this.config.logRequestHeaders\n ? this.maskHeaders(item.request.headers)\n : [];\n item.response.headers = this.config.logResponseHeaders\n ? this.maskHeaders(item.response.headers)\n : [];\n\n // Mask query params\n const url = new URL(item.request.url);\n url.search = this.config.logQueryParams\n ? this.maskQueryParams(url.search)\n : \"\";\n item.request.url = url.toString();\n\n return item;\n }\n\n logRequest(\n request: Request,\n response: Response,\n error?: Error,\n logs?: LogRecord[],\n ) {\n if (!this.enabled || this.suspendUntil !== null) return;\n\n const url = new URL(request.url);\n const path = request.path ?? url.pathname;\n const userAgent = request.headers.find(\n ([k]) => k.toLowerCase() === \"user-agent\",\n )?.[1];\n\n if (\n this.shouldExcludePath(path) ||\n this.shouldExcludeUserAgent(userAgent) ||\n (this.config.excludeCallback?.(request, response) ?? false)\n ) {\n return;\n }\n\n if (\n !this.config.logRequestBody ||\n !this.hasSupportedContentType(request.headers)\n ) {\n request.body = undefined;\n }\n if (\n !this.config.logResponseBody ||\n !this.hasSupportedContentType(response.headers)\n ) {\n response.body = undefined;\n }\n\n if (request.size !== undefined && request.size < 0) {\n request.size = undefined;\n }\n if (response.size !== undefined && response.size < 0) {\n response.size = undefined;\n }\n\n const item: RequestLogItem = {\n uuid: randomUUID(),\n request: request,\n response: response,\n exception:\n error && this.config.logException\n ? {\n type: error.name,\n message: truncateExceptionMessage(error.message),\n stacktrace: truncateExceptionStackTrace(error.stack || \"\"),\n sentryEventId: getSentryEventId(),\n }\n : undefined,\n };\n\n if (logs && logs.length > 0) {\n item.logs = logs.map((log) => ({\n timestamp: log.timestamp,\n logger: log.logger,\n level: log.level,\n message: truncateLogMessage(log.message),\n }));\n }\n this.pendingWrites.push(item);\n\n if (this.pendingWrites.length > MAX_PENDING_WRITES) {\n this.pendingWrites.shift();\n }\n }\n\n async writeToFile() {\n if (!this.enabled || this.pendingWrites.length === 0) {\n return;\n }\n return this.lock.acquire(\"file\", async () => {\n if (!this.currentFile) {\n this.currentFile = new TempGzipFile();\n }\n while (this.pendingWrites.length > 0) {\n let item = this.pendingWrites.shift();\n if (item) {\n item = this.applyMasking(item);\n\n const finalItem = {\n uuid: item.uuid,\n request: skipEmptyValues(item.request),\n response: skipEmptyValues(item.response),\n exception: item.exception,\n logs: item.logs,\n };\n\n // Set up body serialization for JSON\n [finalItem.request.body, finalItem.response.body].forEach((body) => {\n if (body) {\n // @ts-expect-error Override Buffer's default JSON serialization\n body.toJSON = function () {\n return this.toString(\"base64\");\n };\n }\n });\n\n await this.currentFile.writeLine(\n Buffer.from(JSON.stringify(finalItem)),\n );\n }\n }\n });\n }\n\n getFile() {\n return this.files.shift();\n }\n\n retryFileLater(file: TempGzipFile) {\n this.files.unshift(file);\n }\n\n async rotateFile() {\n return this.lock.acquire(\"file\", async () => {\n if (this.currentFile) {\n await this.currentFile.close();\n this.files.push(this.currentFile);\n this.currentFile = null;\n }\n });\n }\n\n async maintain() {\n await this.writeToFile();\n if (this.currentFile && this.currentFile.size > MAX_FILE_SIZE) {\n await this.rotateFile();\n }\n while (this.files.length > MAX_FILES) {\n const file = this.files.shift();\n file?.delete();\n }\n if (this.suspendUntil !== null && this.suspendUntil < Date.now()) {\n this.suspendUntil = null;\n }\n }\n\n async clear() {\n this.pendingWrites = [];\n await this.rotateFile();\n this.files.forEach((file) => {\n file.delete();\n });\n this.files = [];\n }\n\n async close() {\n this.enabled = false;\n await this.clear();\n if (this.maintainIntervalId) {\n clearInterval(this.maintainIntervalId);\n }\n }\n}\n\nexport function convertHeaders(\n headers:\n | Headers\n | IncomingHttpHeaders\n | OutgoingHttpHeaders\n | Record<string, string | string[] | number | undefined>\n | undefined,\n) {\n if (!headers) {\n return [];\n }\n if (headers instanceof Headers) {\n return Array.from(headers.entries());\n }\n return Object.entries(headers).flatMap(([key, value]) => {\n if (value === undefined) {\n return [];\n }\n if (Array.isArray(value)) {\n return value.map((v) => [key, v]);\n }\n return [[key, value.toString()]];\n }) as [string, string][];\n}\n\nexport function convertBody(body: any, contentType?: string | null) {\n if (!body || !contentType) {\n return;\n }\n try {\n if (contentType.startsWith(\"application/json\")) {\n if (isValidJsonString(body)) {\n return Buffer.from(body);\n } else {\n return Buffer.from(JSON.stringify(body));\n }\n }\n if (contentType.startsWith(\"text/\") && typeof body === \"string\") {\n return Buffer.from(body);\n }\n } catch (error) {\n return;\n }\n}\n\nfunction isValidJsonString(body: any) {\n if (typeof body !== \"string\") {\n return false;\n }\n try {\n JSON.parse(body);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction matchPatterns(value: string, patterns: RegExp[]) {\n return patterns.some((pattern) => {\n return pattern.test(value);\n });\n}\n\nfunction skipEmptyValues<T extends Record<string, any>>(data: T) {\n return Object.fromEntries(\n Object.entries(data).filter(([_, v]) => {\n if (v == null || Number.isNaN(v)) return false;\n if (Array.isArray(v) || Buffer.isBuffer(v) || typeof v === \"string\") {\n return v.length > 0;\n }\n return true;\n }),\n ) as Partial<T>;\n}\n\nfunction truncateLogMessage(msg: string) {\n if (msg.length > MAX_LOG_MSG_LENGTH) {\n const suffix = \"... (truncated)\";\n return msg.slice(0, MAX_LOG_MSG_LENGTH - suffix.length) + suffix;\n }\n return msg;\n}\n\nfunction checkWritableFs() {\n try {\n const testPath = join(tmpdir(), `apitally-${randomUUID()}`);\n writeFileSync(testPath, \"test\");\n unlinkSync(testPath);\n return true;\n } catch (error) {\n return false;\n }\n}\n","import type * as Sentry from \"@sentry/node\";\n\nlet sentry: typeof Sentry | undefined;\n\n// Initialize Sentry when the module is loaded\n(async () => {\n try {\n sentry = await import(\"@sentry/node\");\n } catch (e) {\n // Sentry SDK is not installed, ignore\n }\n})();\n\n/**\n * Returns the last Sentry event ID if available\n */\nexport function getSentryEventId(): string | undefined {\n if (sentry && sentry.lastEventId) {\n return sentry.lastEventId();\n }\n return undefined;\n}\n","import { createHash } from \"node:crypto\";\n\nimport { getSentryEventId } from \"./sentry.js\";\nimport { ConsumerMethodPath, ServerError, ServerErrorsItem } from \"./types.js\";\n\nconst MAX_MSG_LENGTH = 2048;\nconst MAX_STACKTRACE_LENGTH = 65536;\n\nexport default class ServerErrorCounter {\n private errorCounts: Map<string, number>;\n private errorDetails: Map<string, ConsumerMethodPath & ServerError>;\n private sentryEventIds: Map<string, string>;\n\n constructor() {\n this.errorCounts = new Map();\n this.errorDetails = new Map();\n this.sentryEventIds = new Map();\n }\n\n public addServerError(serverError: ConsumerMethodPath & ServerError) {\n const key = this.getKey(serverError);\n if (!this.errorDetails.has(key)) {\n this.errorDetails.set(key, serverError);\n }\n this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);\n\n const sentryEventId = getSentryEventId();\n if (sentryEventId) {\n this.sentryEventIds.set(key, sentryEventId);\n }\n }\n\n public getAndResetServerErrors() {\n const data: Array<ServerErrorsItem> = [];\n this.errorCounts.forEach((count, key) => {\n const serverError = this.errorDetails.get(key);\n if (serverError) {\n data.push({\n consumer: serverError.consumer || null,\n method: serverError.method,\n path: serverError.path,\n type: serverError.type,\n msg: truncateExceptionMessage(serverError.msg),\n traceback: truncateExceptionStackTrace(serverError.traceback),\n sentry_event_id: this.sentryEventIds.get(key) || null,\n error_count: count,\n });\n }\n });\n this.errorCounts.clear();\n this.errorDetails.clear();\n this.sentryEventIds.clear();\n return data;\n }\n\n private getKey(serverError: ConsumerMethodPath & ServerError) {\n const hashInput = [\n serverError.consumer || \"\",\n serverError.method.toUpperCase(),\n serverError.path,\n serverError.type,\n serverError.msg.trim(),\n serverError.traceback.trim(),\n ].join(\"|\");\n return createHash(\"md5\").update(hashInput).digest(\"hex\");\n }\n}\n\nexport function truncateExceptionMessage(msg: string) {\n if (msg.length <= MAX_MSG_LENGTH) {\n return msg;\n }\n const suffix = \"... (truncated)\";\n const cutoff = MAX_MSG_LENGTH - suffix.length;\n return msg.substring(0, cutoff) + suffix;\n}\n\nexport function truncateExceptionStackTrace(stack: string) {\n const suffix = \"... (truncated) ...\";\n const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;\n const lines = stack.trim().split(\"\\n\");\n const truncatedLines: string[] = [];\n let length = 0;\n for (const line of lines) {\n if (length + line.length + 1 > cutoff) {\n truncatedLines.push(suffix);\n break;\n }\n truncatedLines.push(line);\n length += line.length + 1;\n }\n return truncatedLines.join(\"\\n\");\n}\n","import { Buffer } from \"node:buffer\";\nimport { randomUUID } from \"node:crypto\";\nimport { createWriteStream, readFile, WriteStream } from \"node:fs\";\nimport { unlink } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createGzip, Gzip } from \"node:zlib\";\n\nexport default class TempGzipFile {\n public uuid: string;\n private filePath: string;\n private gzip: Gzip;\n private writeStream: WriteStream;\n private readyPromise: Promise<void>;\n private closedPromise: Promise<void>;\n\n constructor() {\n this.uuid = randomUUID();\n this.filePath = join(tmpdir(), `apitally-${this.uuid}.gz`);\n this.writeStream = createWriteStream(this.filePath);\n this.readyPromise = new Promise<void>((resolve, reject) => {\n this.writeStream.once(\"ready\", resolve);\n this.writeStream.once(\"error\", reject);\n });\n this.closedPromise = new Promise<void>((resolve, reject) => {\n this.writeStream.once(\"close\", resolve);\n this.writeStream.once(\"error\", reject);\n });\n this.gzip = createGzip();\n this.gzip.pipe(this.writeStream);\n }\n\n get size() {\n return this.writeStream.bytesWritten;\n }\n\n async writeLine(data: Buffer) {\n await this.readyPromise;\n return new Promise<void>((resolve, reject) => {\n this.gzip.write(Buffer.concat([data, Buffer.from(\"\\n\")]), (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n }\n\n async getContent() {\n return new Promise<Buffer>((resolve, reject) => {\n readFile(this.filePath, (error, data) => {\n if (error) {\n reject(error);\n } else {\n resolve(data);\n }\n });\n });\n }\n\n async close() {\n await new Promise<void>((resolve) => {\n this.gzip.end(() => {\n resolve();\n });\n });\n await this.closedPromise;\n }\n\n async delete() {\n await this.close();\n await unlink(this.filePath);\n }\n}\n","import { createHash } from \"node:crypto\";\n\nimport {\n ConsumerMethodPath,\n ValidationError,\n ValidationErrorsItem,\n} from \"./types.js\";\n\nexport default class ValidationErrorCounter {\n private errorCounts: Map<string, number>;\n private errorDetails: Map<string, ConsumerMethodPath & ValidationError>;\n\n constructor() {\n this.errorCounts = new Map();\n this.errorDetails = new Map();\n }\n\n public addValidationError(\n validationError: ConsumerMethodPath & ValidationError,\n ) {\n const key = this.getKey(validationError);\n if (!this.errorDetails.has(key)) {\n this.errorDetails.set(key, validationError);\n }\n this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);\n }\n\n public getAndResetValidationErrors() {\n const data: Array<ValidationErrorsItem> = [];\n this.errorCounts.forEach((count, key) => {\n const validationError = this.errorDetails.get(key);\n if (validationError) {\n data.push({\n consumer: validationError.consumer || null,\n method: validationError.method,\n path: validationError.path,\n loc: validationError.loc.split(\".\").filter(Boolean),\n msg: validationError.msg,\n type: validationError.type,\n error_count: count,\n });\n }\n });\n this.errorCounts.clear();\n this.errorDetails.clear();\n return data;\n }\n\n private getKey(validationError: ConsumerMethodPath & ValidationError) {\n const hashInput = [\n validationError.consumer || \"\",\n validationError.method.toUpperCase(),\n validationError.path,\n validationError.loc.split(\".\").filter(Boolean),\n validationError.msg.trim(),\n validationError.type,\n ].join(\"|\");\n return createHash(\"md5\").update(hashInput).digest(\"hex\");\n }\n}\n","import { OutgoingHttpHeader } from \"node:http\";\n\nexport function parseContentLength(\n contentLength: OutgoingHttpHeader | undefined | null,\n): number | undefined {\n if (contentLength === undefined || contentLength === null) {\n return undefined;\n }\n if (typeof contentLength === \"number\") {\n return contentLength;\n }\n if (typeof contentLength === \"string\") {\n const parsed = parseInt(contentLength);\n return isNaN(parsed) ? undefined : parsed;\n }\n if (Array.isArray(contentLength)) {\n return parseContentLength(contentLength[0]);\n }\n return undefined;\n}\n\nexport function mergeHeaders(base: Headers, merge: Headers) {\n const mergedHeaders = new Headers(base);\n for (const [name, value] of merge)\n if (name === \"set-cookie\") mergedHeaders.append(name, value);\n else mergedHeaders.set(name, value);\n return mergedHeaders;\n}\n","export async function measureResponseSize(\n response: Response,\n tee: boolean = true,\n): Promise<[number, Response]> {\n const [newResponse1, newResponse2] = tee\n ? teeResponse(response)\n : [response, response];\n let size = 0;\n if (newResponse2.body) {\n let done = false;\n const reader = newResponse2.body.getReader();\n while (!done) {\n const result = await reader.read();\n done = result.done;\n if (!done && result.value) {\n size += result.value.byteLength;\n }\n }\n }\n return [size, newResponse1];\n}\n\nexport async function getResponseBody(\n response: Response,\n tee: boolean = true,\n): Promise<[Buffer, Response]> {\n const [newResponse1, newResponse2] = tee\n ? teeResponse(response)\n : [response, response];\n const responseBuffer = Buffer.from(await newResponse2.arrayBuffer());\n return [responseBuffer, newResponse1];\n}\n\nexport async function getResponseJson(\n response: Response,\n): Promise<[any, Response]> {\n const contentType = response.headers.get(\"content-type\");\n if (contentType?.includes(\"application/json\")) {\n const [newResponse1, newResponse2] = teeResponse(response);\n const responseJson = await newResponse2.json();\n return [responseJson, newResponse1];\n }\n return [null, response];\n}\n\nexport function teeResponse(response: Response): [Response, Response] {\n if (!response.body) {\n return [response, response];\n }\n const [stream1, stream2] = response.body.tee();\n const newResponse1 = new Response(stream1, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n const newResponse2 = new Response(stream2, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n return [newResponse1, newResponse2];\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { format } from \"node:util\";\n\nimport type { LogRecord } from \"../common/requestLogger.js\";\n\ntype LogLevel = \"log\" | \"warn\" | \"error\" | \"info\" | \"debug\";\n\nconst MAX_BUFFER_SIZE = 1000;\n\nlet isPatched = false;\nlet globalLogsContext: AsyncLocalStorage<LogRecord[]>;\n\nexport function patchConsole(logsContext: AsyncLocalStorage<LogRecord[]>) {\n globalLogsContext = logsContext;\n\n if (isPatched) {\n return;\n }\n\n const logMethods: LogLevel[] = [\"log\", \"warn\", \"error\", \"info\", \"debug\"];\n logMethods.forEach((method) => {\n const originalMethod = console[method];\n console[method] = function (...args: any[]) {\n captureLog(method, args);\n return originalMethod.apply(console, args);\n };\n });\n\n isPatched = true;\n}\n\nfunction captureLog(level: LogLevel, args: any[]) {\n const logs = globalLogsContext?.getStore();\n if (logs && logs.length < MAX_BUFFER_SIZE) {\n logs.push({\n timestamp: Date.now() / 1000,\n logger: \"console\",\n level,\n message: format(...args),\n });\n }\n}\n","import { format } from \"node:util\";\n\nexport function formatMessage(message: any, ...args: any[]) {\n return [message, ...args]\n .map(formatArg)\n .filter((arg) => arg !== \"\")\n .join(\"\\n\");\n}\n\nexport function removeKeys(obj: any, keys: string[]) {\n return Object.fromEntries(\n Object.entries(obj).filter(([key]) => !keys.includes(key)),\n );\n}\n\nfunction formatArg(arg: any) {\n if (typeof arg === \"string\") {\n return arg.trim();\n }\n if (arg instanceof Error) {\n return format(arg).trim();\n }\n if (arg === undefined || arg === null || isEmptyObject(arg)) {\n return \"\";\n }\n try {\n return JSON.stringify(arg);\n } catch {\n return format(arg).trim();\n }\n}\n\nfunction isEmptyObject(obj: any) {\n return (\n obj !== null &&\n typeof obj === \"object\" &&\n Object.getPrototypeOf(obj) === Object.prototype &&\n Object.keys(obj).length === 0\n );\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { formatMessage, removeKeys } from \"./utils.js\";\n\nconst MAX_BUFFER_SIZE = 1000;\n\nconst originalStreamSym = Symbol.for(\"apitally.originalStream\");\nconst logLevelMap: Record<number, string> = {\n 10: \"trace\",\n 20: \"debug\",\n 30: \"info\",\n 40: \"warn\",\n 50: \"error\",\n 60: \"fatal\",\n};\n\nexport async function patchPinoLogger(\n logger: any,\n logsContext: AsyncLocalStorage<LogRecord[]>,\n) {\n try {\n const pino = await import(\"pino\");\n if (!(pino.default.symbols.streamSym in logger)) {\n return;\n }\n if (!(originalStreamSym in logger)) {\n logger[originalStreamSym] = logger[pino.default.symbols.streamSym];\n }\n\n const originalStream = logger[originalStreamSym];\n if (originalStream) {\n const messageKey = logger[pino.default.symbols.messageKeySym];\n const captureStream = new ApitallyLogCaptureStream(\n logsContext,\n messageKey,\n );\n logger[pino.default.symbols.streamSym] = pino.default.multistream(\n [\n { level: 0, stream: originalStream },\n { level: 0, stream: captureStream },\n ],\n {\n levels: logger.levels,\n },\n );\n }\n } catch {\n // pino is not installed, silently ignore\n }\n}\n\nfunction filterLogs(obj: any, messageKey: string) {\n return obj[messageKey] !== \"request completed\";\n}\n\nclass ApitallyLogCaptureStream {\n private logsContext: AsyncLocalStorage<LogRecord[]>;\n private messageKey: string;\n\n constructor(logsContext: AsyncLocalStorage<LogRecord[]>, messageKey: string) {\n this.logsContext = logsContext;\n this.messageKey = messageKey;\n }\n\n write(msg: string): void {\n const logs = this.logsContext.getStore();\n if (!logs || !msg || logs.length >= MAX_BUFFER_SIZE) {\n return;\n }\n\n let obj: any;\n try {\n obj = JSON.parse(msg);\n } catch (e) {\n return;\n }\n if (\n obj === null ||\n typeof obj !== \"object\" ||\n !filterLogs(obj, this.messageKey)\n ) {\n return;\n }\n\n try {\n const message = obj[this.messageKey];\n const rest = removeKeys(obj, [\n \"hostname\",\n \"level\",\n this.messageKey,\n \"pid\",\n \"time\",\n \"reqId\",\n \"req\",\n \"res\",\n ]);\n const formattedMessage = formatMessage(message, rest);\n if (formattedMessage) {\n logs.push({\n timestamp: this.convertTime(obj.time),\n level: logLevelMap[obj.level] || \"info\",\n message: formattedMessage,\n });\n }\n } catch (e) {\n // ignore\n }\n }\n\n private convertTime(time: any): number {\n if (typeof time === \"number\" && !isNaN(time)) {\n return time / 1000; // Convert milliseconds to seconds\n }\n return Date.now() / 1000; // Fallback to current time\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { formatMessage, removeKeys } from \"./utils.js\";\n\nconst MAX_BUFFER_SIZE = 1000;\n\nlet isPatched = false;\nlet globalLogsContext: AsyncLocalStorage<LogRecord[]>;\n\nexport async function patchWinston(\n logsContext: AsyncLocalStorage<LogRecord[]>,\n) {\n globalLogsContext = logsContext;\n\n if (isPatched) {\n return;\n }\n\n try {\n // @ts-expect-error - file is not typed\n const loggerModule = await import(\"winston/lib/winston/logger.js\");\n if (loggerModule.default?.prototype?.write) {\n const originalWrite = loggerModule.default.prototype.write;\n loggerModule.default.prototype.write = function (info: any) {\n captureLog(info);\n return originalWrite.call(this, info);\n };\n }\n } catch {\n // winston is not installed, silently ignore\n }\n\n isPatched = true;\n}\n\nfunction captureLog(info: any) {\n const logs = globalLogsContext?.getStore();\n if (!logs || !info || logs.length >= MAX_BUFFER_SIZE) {\n return;\n }\n\n try {\n const rest = removeKeys(info, [\"timestamp\", \"level\", \"message\", \"splat\"]);\n const formattedMessage = formatMessage(info.message, rest);\n if (formattedMessage) {\n logs.push({\n timestamp: parseTimestamp(info.timestamp),\n level: info.level || \"info\",\n message: formattedMessage.trim(),\n });\n }\n } catch (e) {\n // ignore\n }\n}\n\nfunction parseTimestamp(timestamp: any) {\n if (timestamp) {\n const ts = new Date(timestamp).getTime();\n if (!isNaN(ts)) {\n return ts / 1000;\n }\n }\n return Date.now() / 1000;\n}\n","import { createRequire } from \"node:module\";\n\nexport function getPackageVersion(name: string): string | null {\n const packageJsonPath = `${name}/package.json`;\n try {\n return require(packageJsonPath).version || null;\n } catch (error) {\n try {\n const _require = createRequire(import.meta.url);\n return _require(packageJsonPath).version || null;\n } catch (error) {\n return null;\n }\n }\n}\n","import type { Elysia } from \"elysia\";\n\nimport { getPackageVersion } from \"../common/packageVersions.js\";\nimport type { StartupData } from \"../common/types.js\";\n\nexport function getAppInfo(app: Elysia, appVersion?: string): StartupData {\n const versions: Array<[string, string]> = [];\n if (process.versions.node) {\n versions.push([\"nodejs\", process.versions.node]);\n }\n if (process.versions.bun) {\n versions.push([\"bun\", process.versions.bun]);\n }\n const elysiaVersion = getPackageVersion(\"elysia\");\n const apitallyVersion = getPackageVersion(\"../..\");\n if (elysiaVersion) {\n versions.push([\"elysia\", elysiaVersion]);\n }\n if (apitallyVersion) {\n versions.push([\"apitally\", apitallyVersion]);\n }\n if (appVersion) {\n versions.push([\"app\", appVersion]);\n }\n\n return {\n paths: app.routes\n .map((route) => ({\n method: route.method.toUpperCase(),\n path: route.path,\n }))\n .filter(\n (route) =>\n route.method &&\n route.path &&\n ![\"HEAD\", \"OPTIONS\"].includes(route.method),\n ),\n versions: Object.fromEntries(versions),\n client: \"js:elysia\",\n };\n}\n"],"mappings":"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","names":["StatusMap","ValidationError","AsyncLocalStorage","performance","fetchRetry","randomUUID","consumerFromStringOrObject","consumer","_a","String","trim","substring","identifier","name","group","ConsumerRegistry","consumers","updated","Map","Set","addOrUpdateConsumer","existing","get","set","add","getAndResetUpdatedConsumers","data","forEach","push","clear","createLogger","format","transports","getLogger","createLogger","level","process","env","APITALLY_DEBUG","format","combine","colorize","timestamp","printf","info","message","transports","Console","isValidClientId","clientId","regexExp","test","isValidEnv","env","RequestCounter","requestCounts","requestSizeSums","responseSizeSums","responseTimes","requestSizes","responseSizes","Map","getKey","requestInfo","consumer","method","toUpperCase","path","statusCode","join","addRequest","key","set","get","has","responseTimeMap","responseTimeMsBin","Math","floor","responseTime","requestSize","undefined","Number","requestSizeMap","requestSizeKbBin","responseSize","responseSizeMap","responseSizeKbBin","getAndResetRequests","data","forEach","count","statusCodeStr","split","push","status_code","parseInt","request_count","request_size_sum","response_size_sum","response_times","Object","fromEntries","request_sizes","response_sizes","clear","AsyncLock","Buffer","randomUUID","unlinkSync","writeFileSync","tmpdir","join","sentry","e","getSentryEventId","lastEventId","undefined","createHash","MAX_MSG_LENGTH","MAX_STACKTRACE_LENGTH","ServerErrorCounter","errorCounts","errorDetails","sentryEventIds","Map","addServerError","serverError","key","getKey","has","set","get","sentryEventId","getSentryEventId","getAndResetServerErrors","data","forEach","count","push","consumer","method","path","type","msg","truncateExceptionMessage","traceback","truncateExceptionStackTrace","sentry_event_id","error_count","clear","hashInput","toUpperCase","trim","join","createHash","update","digest","length","suffix","cutoff","substring","stack","lines","split","truncatedLines","line","Buffer","randomUUID","createWriteStream","readFile","unlink","tmpdir","join","createGzip","TempGzipFile","uuid","filePath","gzip","writeStream","readyPromise","closedPromise","randomUUID","join","tmpdir","createWriteStream","Promise","resolve","reject","once","createGzip","pipe","size","bytesWritten","writeLine","data","write","Buffer","concat","from","error","getContent","readFile","close","end","delete","unlink","MAX_BODY_SIZE","MAX_FILE_SIZE","MAX_FILES","MAX_PENDING_WRITES","MAX_LOG_MSG_LENGTH","BODY_TOO_LARGE","Buffer","from","BODY_MASKED","MASKED","ALLOWED_CONTENT_TYPES","EXCLUDE_PATH_PATTERNS","EXCLUDE_USER_AGENT_PATTERNS","MASK_QUERY_PARAM_PATTERNS","MASK_HEADER_PATTERNS","MASK_BODY_FIELD_PATTERNS","DEFAULT_CONFIG","enabled","logQueryParams","logRequestHeaders","logRequestBody","logResponseHeaders","logResponseBody","logException","captureLogs","maskQueryParams","maskHeaders","maskBodyFields","excludePaths","RequestLogger","config","suspendUntil","pendingWrites","currentFile","files","maintainIntervalId","lock","AsyncLock","checkWritableFs","setInterval","maintain","maxBodySize","shouldExcludePath","urlPath","patterns","matchPatterns","shouldExcludeUserAgent","userAgent","shouldMaskQueryParam","name","shouldMaskHeader","shouldMaskBodyField","hasSupportedContentType","headers","_a","contentType","find","k","toLowerCase","isSupportedContentType","hasJsonContentType","test","some","t","startsWith","search","params","URLSearchParams","key","set","toString","map","v","maskBody","data","Array","isArray","result","value","Object","entries","item","applyMasking","maskRequestBodyCallback","request","body","maskedBody","undefined","maskResponseBodyCallback","response","length","bodyData","hasJsonContent","parsedBody","JSON","parse","stringify","url","URL","logRequest","error","logs","path","pathname","excludeCallback","size","uuid","randomUUID","exception","type","message","truncateExceptionMessage","stacktrace","truncateExceptionStackTrace","stack","sentryEventId","getSentryEventId","log","timestamp","logger","level","truncateLogMessage","push","shift","writeToFile","acquire","TempGzipFile","finalItem","skipEmptyValues","forEach","toJSON","writeLine","getFile","retryFileLater","file","unshift","rotateFile","close","delete","Date","now","clear","clearInterval","convertHeaders","Headers","flatMap","matchPatterns","value","patterns","some","pattern","test","skipEmptyValues","data","Object","fromEntries","entries","filter","_","v","Number","isNaN","Array","isArray","Buffer","isBuffer","length","truncateLogMessage","msg","MAX_LOG_MSG_LENGTH","suffix","slice","checkWritableFs","testPath","join","tmpdir","randomUUID","writeFileSync","unlinkSync","error","createHash","ValidationErrorCounter","errorCounts","errorDetails","Map","addValidationError","validationError","key","getKey","has","set","get","getAndResetValidationErrors","data","forEach","count","push","consumer","method","path","loc","split","filter","Boolean","msg","type","error_count","clear","hashInput","toUpperCase","trim","join","createHash","update","digest","SYNC_INTERVAL","INITIAL_SYNC_INTERVAL","INITIAL_SYNC_INTERVAL_DURATION","MAX_QUEUE_TIME","HTTPError","Error","response","reason","status","ApitallyClient","clientId","env","instanceUuid","syncDataQueue","syncIntervalId","startupData","startupDataSent","enabled","requestCounter","requestLogger","validationErrorCounter","serverErrorCounter","consumerRegistry","logger","requestLogging","requestLoggingConfig","instance","isValidClientId","isValidEnv","console","warn","randomUUID","RequestCounter","RequestLogger","ValidationErrorCounter","ServerErrorCounter","ConsumerRegistry","getLogger","startSync","handleShutdown","bind","getInstance","isEnabled","shutdown","stopSync","sendSyncData","sendLogData","close","undefined","getHubUrlPrefix","baseURL","process","APITALLY_HUB_BASE_URL","version","sendData","url","payload","fetchWithRetry","fetchRetry","fetch","retries","retryDelay","retryOn","method","body","JSON","stringify","headers","ok","sync","setInterval","setTimeout","clearInterval","promises","push","sendStartupData","Promise","all","error","setStartupData","data","debug","instance_uuid","message_uuid","handled","handleHubError","message","newPayload","timestamp","Date","now","requests","getAndResetRequests","validation_errors","getAndResetValidationErrors","server_errors","getAndResetServerErrors","consumers","getAndResetUpdatedConsumers","i","length","shift","randomDelay","rotateFile","logFile","getFile","uuid","getContent","has","retryAfter","parseInt","get","suspendUntil","clear","delete","retryFileLater","delay","Math","random","resolve","parseContentLength","contentLength","undefined","parsed","parseInt","isNaN","Array","isArray","measureResponseSize","response","tee","newResponse1","newResponse2","teeResponse","size","body","done","reader","getReader","result","read","value","byteLength","getResponseBody","responseBuffer","Buffer","from","arrayBuffer","teeResponse","response","body","stream1","stream2","tee","newResponse1","Response","status","statusText","headers","newResponse2","format","MAX_BUFFER_SIZE","isPatched","globalLogsContext","patchConsole","logsContext","logMethods","forEach","method","originalMethod","console","args","captureLog","apply","level","logs","getStore","length","push","timestamp","Date","now","logger","message","format","format","formatMessage","message","args","map","formatArg","filter","arg","join","removeKeys","obj","keys","Object","fromEntries","entries","key","includes","trim","Error","format","undefined","isEmptyObject","JSON","stringify","getPrototypeOf","prototype","length","originalStreamSym","Symbol","for","MAX_BUFFER_SIZE","isPatched","globalLogsContext","patchWinston","logsContext","_a","loggerModule","default","prototype","write","originalWrite","info","captureLog","call","logs","getStore","length","rest","removeKeys","formattedMessage","formatMessage","message","push","timestamp","parseTimestamp","level","trim","e","ts","Date","getTime","isNaN","now","createRequire","getPackageVersion","name","packageJsonPath","require","version","error","_require","createRequire","url","getAppInfo","app","appVersion","versions","process","node","push","bun","elysiaVersion","getPackageVersion","apitallyVersion","paths","routes","map","route","method","toUpperCase","path","filter","includes","Object","fromEntries","client","START_TIME_SYMBOL","Symbol","REQUEST_BODY_SYMBOL","RESPONSE_SYMBOL","ERROR_SYMBOL","config","client","ApitallyClient","logsContext","AsyncLocalStorage","requestLogger","enabled","captureLogs","patchConsole","patchWinston","app","handler","originalMapResponse","mapResponse","originalMapCompactResponse","mapCompactResponse","originalMapEarlyResponse","mapEarlyResponse","captureResponse","response","request","Request","Response","newResponse1","newResponse2","teeResponse","wrappedMapResponse","set","mappedResponse","newResponse","wrappedMapCompactResponse","wrappedMapEarlyResponse","decorate","onStart","appInfo","getAppInfo","appVersion","setStartupData","onStop","handleShutdown","onRequest","isEnabled","method","toUpperCase","enterWith","performance","now","logRequestBody","contentType","headers","get","requestSize","parseContentLength","isSupportedContentType","maxBodySize","Buffer","from","clone","arrayBuffer","error","onAfterResponse","route","apitally","startTime","responseTime","requestBody","length","responseBody","responseSize","toResponse","logResponseBody","getResponseBody","measureResponseSize","statusCode","status","getStatusCode","responseHeaders","consumer","consumerFromStringOrObject","consumerRegistry","addOrUpdateConsumer","requestCounter","addRequest","identifier","path","serverErrorCounter","addServerError","type","name","msg","message","traceback","stack","ValidationError","parsedMessage","JSON","parse","validationErrorCounter","addValidationError","loc","on","property","logs","getStore","logRequest","timestamp","Date","url","convertHeaders","Object","fromEntries","entries","size","body","onError","Error","apitallyPlugin","StatusMap"]}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/elysia/utils.ts
|
|
22
|
+
var utils_exports = {};
|
|
23
|
+
__export(utils_exports, {
|
|
24
|
+
getAppInfo: () => getAppInfo
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(utils_exports);
|
|
27
|
+
|
|
28
|
+
// src/common/packageVersions.ts
|
|
29
|
+
var import_node_module = require("module");
|
|
30
|
+
var import_meta = {};
|
|
31
|
+
function getPackageVersion(name) {
|
|
32
|
+
const packageJsonPath = `${name}/package.json`;
|
|
33
|
+
try {
|
|
34
|
+
return require(packageJsonPath).version || null;
|
|
35
|
+
} catch (error) {
|
|
36
|
+
try {
|
|
37
|
+
const _require = (0, import_node_module.createRequire)(import_meta.url);
|
|
38
|
+
return _require(packageJsonPath).version || null;
|
|
39
|
+
} catch (error2) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
__name(getPackageVersion, "getPackageVersion");
|
|
45
|
+
|
|
46
|
+
// src/elysia/utils.ts
|
|
47
|
+
function getAppInfo(app, appVersion) {
|
|
48
|
+
const versions = [];
|
|
49
|
+
if (process.versions.node) {
|
|
50
|
+
versions.push([
|
|
51
|
+
"nodejs",
|
|
52
|
+
process.versions.node
|
|
53
|
+
]);
|
|
54
|
+
}
|
|
55
|
+
if (process.versions.bun) {
|
|
56
|
+
versions.push([
|
|
57
|
+
"bun",
|
|
58
|
+
process.versions.bun
|
|
59
|
+
]);
|
|
60
|
+
}
|
|
61
|
+
const elysiaVersion = getPackageVersion("elysia");
|
|
62
|
+
const apitallyVersion = getPackageVersion("../..");
|
|
63
|
+
if (elysiaVersion) {
|
|
64
|
+
versions.push([
|
|
65
|
+
"elysia",
|
|
66
|
+
elysiaVersion
|
|
67
|
+
]);
|
|
68
|
+
}
|
|
69
|
+
if (apitallyVersion) {
|
|
70
|
+
versions.push([
|
|
71
|
+
"apitally",
|
|
72
|
+
apitallyVersion
|
|
73
|
+
]);
|
|
74
|
+
}
|
|
75
|
+
if (appVersion) {
|
|
76
|
+
versions.push([
|
|
77
|
+
"app",
|
|
78
|
+
appVersion
|
|
79
|
+
]);
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
paths: app.routes.map((route) => ({
|
|
83
|
+
method: route.method.toUpperCase(),
|
|
84
|
+
path: route.path
|
|
85
|
+
})).filter((route) => route.method && route.path && ![
|
|
86
|
+
"HEAD",
|
|
87
|
+
"OPTIONS"
|
|
88
|
+
].includes(route.method)),
|
|
89
|
+
versions: Object.fromEntries(versions),
|
|
90
|
+
client: "js:elysia"
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
__name(getAppInfo, "getAppInfo");
|
|
94
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
95
|
+
0 && (module.exports = {
|
|
96
|
+
getAppInfo
|
|
97
|
+
});
|
|
98
|
+
//# sourceMappingURL=utils.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/elysia/utils.ts","../../src/common/packageVersions.ts"],"sourcesContent":["import type { Elysia } from \"elysia\";\n\nimport { getPackageVersion } from \"../common/packageVersions.js\";\nimport type { StartupData } from \"../common/types.js\";\n\nexport function getAppInfo(app: Elysia, appVersion?: string): StartupData {\n const versions: Array<[string, string]> = [];\n if (process.versions.node) {\n versions.push([\"nodejs\", process.versions.node]);\n }\n if (process.versions.bun) {\n versions.push([\"bun\", process.versions.bun]);\n }\n const elysiaVersion = getPackageVersion(\"elysia\");\n const apitallyVersion = getPackageVersion(\"../..\");\n if (elysiaVersion) {\n versions.push([\"elysia\", elysiaVersion]);\n }\n if (apitallyVersion) {\n versions.push([\"apitally\", apitallyVersion]);\n }\n if (appVersion) {\n versions.push([\"app\", appVersion]);\n }\n\n return {\n paths: app.routes\n .map((route) => ({\n method: route.method.toUpperCase(),\n path: route.path,\n }))\n .filter(\n (route) =>\n route.method &&\n route.path &&\n ![\"HEAD\", \"OPTIONS\"].includes(route.method),\n ),\n versions: Object.fromEntries(versions),\n client: \"js:elysia\",\n };\n}\n","import { createRequire } from \"node:module\";\n\nexport function getPackageVersion(name: string): string | null {\n const packageJsonPath = `${name}/package.json`;\n try {\n return require(packageJsonPath).version || null;\n } catch (error) {\n try {\n const _require = createRequire(import.meta.url);\n return _require(packageJsonPath).version || null;\n } catch (error) {\n return null;\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAEA;;;;;;;ACFA,yBAA8B;AAA9B;AAEO,SAASA,kBAAkBC,MAAY;AAC5C,QAAMC,kBAAkB,GAAGD,IAAAA;AAC3B,MAAI;AACF,WAAOE,QAAQD,eAAAA,EAAiBE,WAAW;EAC7C,SAASC,OAAO;AACd,QAAI;AACF,YAAMC,eAAWC,kCAAc,YAAYC,GAAG;AAC9C,aAAOF,SAASJ,eAAAA,EAAiBE,WAAW;IAC9C,SAASC,QAAO;AACd,aAAO;IACT;EACF;AACF;AAZgBL;;;ADGT,SAASS,WAAWC,KAAaC,YAAmB;AACzD,QAAMC,WAAoC,CAAA;AAC1C,MAAIC,QAAQD,SAASE,MAAM;AACzBF,aAASG,KAAK;MAAC;MAAUF,QAAQD,SAASE;KAAK;EACjD;AACA,MAAID,QAAQD,SAASI,KAAK;AACxBJ,aAASG,KAAK;MAAC;MAAOF,QAAQD,SAASI;KAAI;EAC7C;AACA,QAAMC,gBAAgBC,kBAAkB,QAAA;AACxC,QAAMC,kBAAkBD,kBAAkB,OAAA;AAC1C,MAAID,eAAe;AACjBL,aAASG,KAAK;MAAC;MAAUE;KAAc;EACzC;AACA,MAAIE,iBAAiB;AACnBP,aAASG,KAAK;MAAC;MAAYI;KAAgB;EAC7C;AACA,MAAIR,YAAY;AACdC,aAASG,KAAK;MAAC;MAAOJ;KAAW;EACnC;AAEA,SAAO;IACLS,OAAOV,IAAIW,OACRC,IAAI,CAACC,WAAW;MACfC,QAAQD,MAAMC,OAAOC,YAAW;MAChCC,MAAMH,MAAMG;IACd,EAAA,EACCC,OACC,CAACJ,UACCA,MAAMC,UACND,MAAMG,QACN,CAAC;MAAC;MAAQ;MAAWE,SAASL,MAAMC,MAAM,CAAA;IAEhDZ,UAAUiB,OAAOC,YAAYlB,QAAAA;IAC7BmB,QAAQ;EACV;AACF;AAnCgBtB;","names":["getPackageVersion","name","packageJsonPath","require","version","error","_require","createRequire","url","getAppInfo","app","appVersion","versions","process","node","push","bun","elysiaVersion","getPackageVersion","apitallyVersion","paths","routes","map","route","method","toUpperCase","path","filter","includes","Object","fromEntries","client"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Elysia } from 'elysia';
|
|
2
|
+
import { StartupData } from '../common/types.cjs';
|
|
3
|
+
import '../common/logging.cjs';
|
|
4
|
+
import 'winston';
|
|
5
|
+
import '../common/requestLogger.cjs';
|
|
6
|
+
import 'node:buffer';
|
|
7
|
+
import 'node:http';
|
|
8
|
+
import '../common/tempGzipFile.cjs';
|
|
9
|
+
|
|
10
|
+
declare function getAppInfo(app: Elysia, appVersion?: string): StartupData;
|
|
11
|
+
|
|
12
|
+
export { getAppInfo };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Elysia } from 'elysia';
|
|
2
|
+
import { StartupData } from '../common/types.js';
|
|
3
|
+
import '../common/logging.js';
|
|
4
|
+
import 'winston';
|
|
5
|
+
import '../common/requestLogger.js';
|
|
6
|
+
import 'node:buffer';
|
|
7
|
+
import 'node:http';
|
|
8
|
+
import '../common/tempGzipFile.js';
|
|
9
|
+
|
|
10
|
+
declare function getAppInfo(app: Elysia, appVersion?: string): StartupData;
|
|
11
|
+
|
|
12
|
+
export { getAppInfo };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
4
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
5
|
+
}) : x)(function(x) {
|
|
6
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
7
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
// src/common/packageVersions.ts
|
|
11
|
+
import { createRequire } from "module";
|
|
12
|
+
function getPackageVersion(name) {
|
|
13
|
+
const packageJsonPath = `${name}/package.json`;
|
|
14
|
+
try {
|
|
15
|
+
return __require(packageJsonPath).version || null;
|
|
16
|
+
} catch (error) {
|
|
17
|
+
try {
|
|
18
|
+
const _require = createRequire(import.meta.url);
|
|
19
|
+
return _require(packageJsonPath).version || null;
|
|
20
|
+
} catch (error2) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
__name(getPackageVersion, "getPackageVersion");
|
|
26
|
+
|
|
27
|
+
// src/elysia/utils.ts
|
|
28
|
+
function getAppInfo(app, appVersion) {
|
|
29
|
+
const versions = [];
|
|
30
|
+
if (process.versions.node) {
|
|
31
|
+
versions.push([
|
|
32
|
+
"nodejs",
|
|
33
|
+
process.versions.node
|
|
34
|
+
]);
|
|
35
|
+
}
|
|
36
|
+
if (process.versions.bun) {
|
|
37
|
+
versions.push([
|
|
38
|
+
"bun",
|
|
39
|
+
process.versions.bun
|
|
40
|
+
]);
|
|
41
|
+
}
|
|
42
|
+
const elysiaVersion = getPackageVersion("elysia");
|
|
43
|
+
const apitallyVersion = getPackageVersion("../..");
|
|
44
|
+
if (elysiaVersion) {
|
|
45
|
+
versions.push([
|
|
46
|
+
"elysia",
|
|
47
|
+
elysiaVersion
|
|
48
|
+
]);
|
|
49
|
+
}
|
|
50
|
+
if (apitallyVersion) {
|
|
51
|
+
versions.push([
|
|
52
|
+
"apitally",
|
|
53
|
+
apitallyVersion
|
|
54
|
+
]);
|
|
55
|
+
}
|
|
56
|
+
if (appVersion) {
|
|
57
|
+
versions.push([
|
|
58
|
+
"app",
|
|
59
|
+
appVersion
|
|
60
|
+
]);
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
paths: app.routes.map((route) => ({
|
|
64
|
+
method: route.method.toUpperCase(),
|
|
65
|
+
path: route.path
|
|
66
|
+
})).filter((route) => route.method && route.path && ![
|
|
67
|
+
"HEAD",
|
|
68
|
+
"OPTIONS"
|
|
69
|
+
].includes(route.method)),
|
|
70
|
+
versions: Object.fromEntries(versions),
|
|
71
|
+
client: "js:elysia"
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
__name(getAppInfo, "getAppInfo");
|
|
75
|
+
export {
|
|
76
|
+
getAppInfo
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/common/packageVersions.ts","../../src/elysia/utils.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\n\nexport function getPackageVersion(name: string): string | null {\n const packageJsonPath = `${name}/package.json`;\n try {\n return require(packageJsonPath).version || null;\n } catch (error) {\n try {\n const _require = createRequire(import.meta.url);\n return _require(packageJsonPath).version || null;\n } catch (error) {\n return null;\n }\n }\n}\n","import type { Elysia } from \"elysia\";\n\nimport { getPackageVersion } from \"../common/packageVersions.js\";\nimport type { StartupData } from \"../common/types.js\";\n\nexport function getAppInfo(app: Elysia, appVersion?: string): StartupData {\n const versions: Array<[string, string]> = [];\n if (process.versions.node) {\n versions.push([\"nodejs\", process.versions.node]);\n }\n if (process.versions.bun) {\n versions.push([\"bun\", process.versions.bun]);\n }\n const elysiaVersion = getPackageVersion(\"elysia\");\n const apitallyVersion = getPackageVersion(\"../..\");\n if (elysiaVersion) {\n versions.push([\"elysia\", elysiaVersion]);\n }\n if (apitallyVersion) {\n versions.push([\"apitally\", apitallyVersion]);\n }\n if (appVersion) {\n versions.push([\"app\", appVersion]);\n }\n\n return {\n paths: app.routes\n .map((route) => ({\n method: route.method.toUpperCase(),\n path: route.path,\n }))\n .filter(\n (route) =>\n route.method &&\n route.path &&\n ![\"HEAD\", \"OPTIONS\"].includes(route.method),\n ),\n versions: Object.fromEntries(versions),\n client: \"js:elysia\",\n };\n}\n"],"mappings":";;;;;;;;;;AAAA,SAASA,qBAAqB;AAEvB,SAASC,kBAAkBC,MAAY;AAC5C,QAAMC,kBAAkB,GAAGD,IAAAA;AAC3B,MAAI;AACF,WAAOE,UAAQD,eAAAA,EAAiBE,WAAW;EAC7C,SAASC,OAAO;AACd,QAAI;AACF,YAAMC,WAAWC,cAAc,YAAYC,GAAG;AAC9C,aAAOF,SAASJ,eAAAA,EAAiBE,WAAW;IAC9C,SAASC,QAAO;AACd,aAAO;IACT;EACF;AACF;AAZgBL;;;ACGT,SAASS,WAAWC,KAAaC,YAAmB;AACzD,QAAMC,WAAoC,CAAA;AAC1C,MAAIC,QAAQD,SAASE,MAAM;AACzBF,aAASG,KAAK;MAAC;MAAUF,QAAQD,SAASE;KAAK;EACjD;AACA,MAAID,QAAQD,SAASI,KAAK;AACxBJ,aAASG,KAAK;MAAC;MAAOF,QAAQD,SAASI;KAAI;EAC7C;AACA,QAAMC,gBAAgBC,kBAAkB,QAAA;AACxC,QAAMC,kBAAkBD,kBAAkB,OAAA;AAC1C,MAAID,eAAe;AACjBL,aAASG,KAAK;MAAC;MAAUE;KAAc;EACzC;AACA,MAAIE,iBAAiB;AACnBP,aAASG,KAAK;MAAC;MAAYI;KAAgB;EAC7C;AACA,MAAIR,YAAY;AACdC,aAASG,KAAK;MAAC;MAAOJ;KAAW;EACnC;AAEA,SAAO;IACLS,OAAOV,IAAIW,OACRC,IAAI,CAACC,WAAW;MACfC,QAAQD,MAAMC,OAAOC,YAAW;MAChCC,MAAMH,MAAMG;IACd,EAAA,EACCC,OACC,CAACJ,UACCA,MAAMC,UACND,MAAMG,QACN,CAAC;MAAC;MAAQ;MAAWE,SAASL,MAAMC,MAAM,CAAA;IAEhDZ,UAAUiB,OAAOC,YAAYlB,QAAAA;IAC7BmB,QAAQ;EACV;AACF;AAnCgBtB;","names":["createRequire","getPackageVersion","name","packageJsonPath","require","version","error","_require","createRequire","url","getAppInfo","app","appVersion","versions","process","node","push","bun","elysiaVersion","getPackageVersion","apitallyVersion","paths","routes","map","route","method","toUpperCase","path","filter","includes","Object","fromEntries","client"]}
|
package/dist/express/index.cjs
CHANGED
|
@@ -3376,7 +3376,7 @@ var require_meta = __commonJS({
|
|
|
3376
3376
|
"node_modules/pino/lib/meta.js"(exports2, module2) {
|
|
3377
3377
|
"use strict";
|
|
3378
3378
|
module2.exports = {
|
|
3379
|
-
version: "9.
|
|
3379
|
+
version: "9.9.0"
|
|
3380
3380
|
};
|
|
3381
3381
|
}
|
|
3382
3382
|
});
|
|
@@ -4177,7 +4177,6 @@ var require_multistream = __commonJS({
|
|
|
4177
4177
|
var { DEFAULT_LEVELS } = require_constants();
|
|
4178
4178
|
var DEFAULT_INFO_LEVEL = DEFAULT_LEVELS.info;
|
|
4179
4179
|
function multistream(streamsArray, opts) {
|
|
4180
|
-
let counter = 0;
|
|
4181
4180
|
streamsArray = streamsArray || [];
|
|
4182
4181
|
opts = opts || {
|
|
4183
4182
|
dedupe: false
|
|
@@ -4192,10 +4191,12 @@ var require_multistream = __commonJS({
|
|
|
4192
4191
|
const res = {
|
|
4193
4192
|
write,
|
|
4194
4193
|
add,
|
|
4194
|
+
remove,
|
|
4195
4195
|
emit,
|
|
4196
4196
|
flushSync,
|
|
4197
4197
|
end,
|
|
4198
4198
|
minLevel: 0,
|
|
4199
|
+
lastId: 0,
|
|
4199
4200
|
streams: [],
|
|
4200
4201
|
clone,
|
|
4201
4202
|
[metadata]: true,
|
|
@@ -4279,7 +4280,7 @@ var require_multistream = __commonJS({
|
|
|
4279
4280
|
stream: stream_,
|
|
4280
4281
|
level,
|
|
4281
4282
|
levelVal: void 0,
|
|
4282
|
-
id:
|
|
4283
|
+
id: ++res.lastId
|
|
4283
4284
|
};
|
|
4284
4285
|
streams.unshift(dest_);
|
|
4285
4286
|
streams.sort(compareByLevel);
|
|
@@ -4287,6 +4288,17 @@ var require_multistream = __commonJS({
|
|
|
4287
4288
|
return res;
|
|
4288
4289
|
}
|
|
4289
4290
|
__name(add, "add");
|
|
4291
|
+
function remove(id) {
|
|
4292
|
+
const { streams } = this;
|
|
4293
|
+
const index = streams.findIndex((s) => s.id === id);
|
|
4294
|
+
if (index >= 0) {
|
|
4295
|
+
streams.splice(index, 1);
|
|
4296
|
+
streams.sort(compareByLevel);
|
|
4297
|
+
this.minLevel = streams.length > 0 ? streams[0].level : -1;
|
|
4298
|
+
}
|
|
4299
|
+
return res;
|
|
4300
|
+
}
|
|
4301
|
+
__name(remove, "remove");
|
|
4290
4302
|
function end() {
|
|
4291
4303
|
for (const { stream } of this.streams) {
|
|
4292
4304
|
if (typeof stream.flushSync === "function") {
|
|
@@ -4307,6 +4319,7 @@ var require_multistream = __commonJS({
|
|
|
4307
4319
|
return {
|
|
4308
4320
|
write,
|
|
4309
4321
|
add,
|
|
4322
|
+
remove,
|
|
4310
4323
|
minLevel: level,
|
|
4311
4324
|
streams,
|
|
4312
4325
|
clone,
|
|
@@ -5224,6 +5237,9 @@ var _RequestLogger = class _RequestLogger {
|
|
|
5224
5237
|
__name(_RequestLogger, "RequestLogger");
|
|
5225
5238
|
var RequestLogger = _RequestLogger;
|
|
5226
5239
|
function convertHeaders(headers) {
|
|
5240
|
+
if (!headers) {
|
|
5241
|
+
return [];
|
|
5242
|
+
}
|
|
5227
5243
|
if (headers instanceof Headers) {
|
|
5228
5244
|
return Array.from(headers.entries());
|
|
5229
5245
|
}
|
|
@@ -5339,7 +5355,7 @@ var _ValidationErrorCounter = class _ValidationErrorCounter {
|
|
|
5339
5355
|
consumer: validationError.consumer || null,
|
|
5340
5356
|
method: validationError.method,
|
|
5341
5357
|
path: validationError.path,
|
|
5342
|
-
loc: validationError.loc.split("."),
|
|
5358
|
+
loc: validationError.loc.split(".").filter(Boolean),
|
|
5343
5359
|
msg: validationError.msg,
|
|
5344
5360
|
type: validationError.type,
|
|
5345
5361
|
error_count: count
|
|
@@ -5355,7 +5371,7 @@ var _ValidationErrorCounter = class _ValidationErrorCounter {
|
|
|
5355
5371
|
validationError.consumer || "",
|
|
5356
5372
|
validationError.method.toUpperCase(),
|
|
5357
5373
|
validationError.path,
|
|
5358
|
-
validationError.loc,
|
|
5374
|
+
validationError.loc.split(".").filter(Boolean),
|
|
5359
5375
|
validationError.msg.trim(),
|
|
5360
5376
|
validationError.type
|
|
5361
5377
|
].join("|");
|