apitally 0.11.5 → 0.13.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 +43 -2
- package/dist/adonisjs/index.cjs +41 -0
- package/dist/adonisjs/index.cjs.map +1 -0
- package/dist/adonisjs/index.d.cts +14 -0
- package/dist/adonisjs/index.d.ts +14 -0
- package/dist/adonisjs/index.js +17 -0
- package/dist/adonisjs/index.js.map +1 -0
- package/dist/adonisjs/middleware.cjs +214 -0
- package/dist/adonisjs/middleware.cjs.map +1 -0
- package/dist/adonisjs/middleware.d.cts +21 -0
- package/dist/adonisjs/middleware.d.ts +21 -0
- package/dist/adonisjs/middleware.js +185 -0
- package/dist/adonisjs/middleware.js.map +1 -0
- package/dist/adonisjs/provider.cjs +1083 -0
- package/dist/adonisjs/provider.cjs.map +1 -0
- package/dist/adonisjs/provider.d.cts +28 -0
- package/dist/adonisjs/provider.d.ts +28 -0
- package/dist/adonisjs/provider.js +1057 -0
- package/dist/adonisjs/provider.js.map +1 -0
- package/dist/common/client.cjs +117 -106
- package/dist/common/client.cjs.map +1 -1
- package/dist/common/client.js +112 -101
- package/dist/common/client.js.map +1 -1
- package/dist/common/consumerRegistry.cjs.map +1 -1
- package/dist/common/consumerRegistry.js.map +1 -1
- package/dist/common/logging.cjs.map +1 -1
- package/dist/common/logging.js.map +1 -1
- package/dist/common/packageVersions.cjs.map +1 -1
- package/dist/common/packageVersions.js.map +1 -1
- package/dist/common/paramValidation.cjs.map +1 -1
- package/dist/common/paramValidation.js.map +1 -1
- package/dist/common/requestCounter.cjs.map +1 -1
- package/dist/common/requestCounter.js.map +1 -1
- package/dist/common/requestLogger.cjs +55 -2
- package/dist/common/requestLogger.cjs.map +1 -1
- package/dist/common/requestLogger.d.cts +2 -1
- package/dist/common/requestLogger.d.ts +2 -1
- package/dist/common/requestLogger.js +55 -2
- package/dist/common/requestLogger.js.map +1 -1
- package/dist/common/sentry.cjs +55 -0
- package/dist/common/sentry.cjs.map +1 -0
- package/dist/common/sentry.d.cts +6 -0
- package/dist/common/sentry.d.ts +6 -0
- package/dist/common/sentry.js +22 -0
- package/dist/common/sentry.js.map +1 -0
- package/dist/common/serverErrorCounter.cjs +58 -45
- package/dist/common/serverErrorCounter.cjs.map +1 -1
- package/dist/common/serverErrorCounter.d.cts +3 -6
- package/dist/common/serverErrorCounter.d.ts +3 -6
- package/dist/common/serverErrorCounter.js +53 -45
- package/dist/common/serverErrorCounter.js.map +1 -1
- package/dist/common/tempGzipFile.cjs.map +1 -1
- package/dist/common/tempGzipFile.js.map +1 -1
- package/dist/common/types.cjs.map +1 -1
- package/dist/common/utils.cjs +48 -0
- package/dist/common/utils.cjs.map +1 -0
- package/dist/common/utils.d.cts +5 -0
- package/dist/common/utils.d.ts +5 -0
- package/dist/common/utils.js +25 -0
- package/dist/common/utils.js.map +1 -0
- package/dist/common/validationErrorCounter.cjs.map +1 -1
- package/dist/common/validationErrorCounter.js.map +1 -1
- package/dist/express/index.cjs +143 -111
- package/dist/express/index.cjs.map +1 -1
- package/dist/express/index.js +138 -106
- package/dist/express/index.js.map +1 -1
- package/dist/express/middleware.cjs +143 -111
- package/dist/express/middleware.cjs.map +1 -1
- package/dist/express/middleware.js +138 -106
- package/dist/express/middleware.js.map +1 -1
- package/dist/express/utils.cjs.map +1 -1
- package/dist/express/utils.js.map +1 -1
- package/dist/fastify/index.cjs +139 -112
- package/dist/fastify/index.cjs.map +1 -1
- package/dist/fastify/index.js +134 -107
- package/dist/fastify/index.js.map +1 -1
- package/dist/fastify/plugin.cjs +139 -112
- package/dist/fastify/plugin.cjs.map +1 -1
- package/dist/fastify/plugin.js +134 -107
- package/dist/fastify/plugin.js.map +1 -1
- package/dist/hono/index.cjs +138 -108
- package/dist/hono/index.cjs.map +1 -1
- package/dist/hono/index.js +133 -103
- package/dist/hono/index.js.map +1 -1
- package/dist/hono/middleware.cjs +138 -108
- package/dist/hono/middleware.cjs.map +1 -1
- package/dist/hono/middleware.js +133 -103
- package/dist/hono/middleware.js.map +1 -1
- package/dist/koa/index.cjs +122 -109
- package/dist/koa/index.cjs.map +1 -1
- package/dist/koa/index.js +117 -104
- package/dist/koa/index.js.map +1 -1
- package/dist/koa/middleware.cjs +122 -109
- package/dist/koa/middleware.cjs.map +1 -1
- package/dist/koa/middleware.js +117 -104
- package/dist/koa/middleware.js.map +1 -1
- package/dist/nestjs/index.cjs +143 -111
- package/dist/nestjs/index.cjs.map +1 -1
- package/dist/nestjs/index.js +138 -106
- package/dist/nestjs/index.js.map +1 -1
- package/package.json +46 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["utils.js"],"sourcesContent":["// Adapted from https://github.com/AlbertoFdzM/express-list-endpoints/blob/305535d43008b46f34e18b01947762e039af6d2d/src/index.js\n// and also incorporated changes from https://github.com/AlbertoFdzM/express-list-endpoints/pull/96\n\n/**\n * @typedef {Object} Route\n * @property {Object} methods\n * @property {string | string[]} path\n * @property {any[]} stack\n *\n * @typedef {Object} Endpoint\n * @property {string} path Path name\n * @property {string[]} methods Methods handled\n * @property {string[]} middlewares Mounted middlewares\n */\n\nconst regExpToParseExpressPathRegExp =\n /^\\/\\^\\\\?\\/?(?:(:?[\\w\\\\.-]*(?:\\\\\\/:?[\\w\\\\.-]*)*)|(\\(\\?:\\\\?\\/?\\([^)]+\\)\\)))\\\\\\/.*/;\nconst regExpToReplaceExpressPathRegExpParams = /\\(\\?:\\\\?\\/?\\([^)]+\\)\\)/;\nconst regexpExpressParamRegexp = /\\(\\?:\\\\?\\\\?\\/?\\([^)]+\\)\\)/g;\nconst regexpExpressPathParamRegexp = /(:[^)]+)\\([^)]+\\)/g;\n\nconst EXPRESS_ROOT_PATH_REGEXP_VALUE = \"/^\\\\/?(?=\\\\/|$)/i\";\nconst STACK_ITEM_VALID_NAMES = [\"router\", \"bound dispatch\", \"mounted_app\"];\n\n/**\n * Returns all the verbs detected for the passed route\n * @param {Route} route\n */\nconst getRouteMethods = function (route) {\n let methods = Object.keys(route.methods);\n\n methods = methods.filter((method) => method !== \"_all\");\n methods = methods.map((method) => method.toUpperCase());\n\n return methods;\n};\n\n/**\n * Returns the names (or anonymous) of all the middlewares attached to the\n * passed route\n * @param {Route} route\n * @returns {string[]}\n */\nconst getRouteMiddlewares = function (route) {\n return route.stack.map((item) => {\n return item.handle.name || \"anonymous\";\n });\n};\n\n/**\n * Returns true if found regexp related with express params\n * @param {string} expressPathRegExp\n * @returns {boolean}\n */\nconst hasParams = function (expressPathRegExp) {\n return regexpExpressParamRegexp.test(expressPathRegExp);\n};\n\n/**\n * @param {Route} route Express route object to be parsed\n * @param {string} basePath The basePath the route is on\n * @return {Endpoint[]} Endpoints info\n */\nconst parseExpressRoute = function (route, basePath) {\n const paths = [];\n\n if (Array.isArray(route.path)) {\n paths.push(...route.path);\n } else {\n paths.push(route.path);\n }\n\n /** @type {Endpoint[]} */\n const endpoints = paths.map((path) => {\n const completePath =\n basePath && path === \"/\" ? basePath : `${basePath}${path}`;\n\n /** @type {Endpoint} */\n const endpoint = {\n path: completePath.replace(regexpExpressPathParamRegexp, \"$1\"),\n methods: getRouteMethods(route),\n middlewares: getRouteMiddlewares(route),\n };\n\n return endpoint;\n });\n\n return endpoints;\n};\n\n/**\n * @param {RegExp} expressPathRegExp\n * @param {any[]} params\n * @returns {string}\n */\nexport const parseExpressPath = function (expressPathRegExp, params) {\n let parsedRegExp = expressPathRegExp.toString();\n let expressPathRegExpExec = regExpToParseExpressPathRegExp.exec(parsedRegExp);\n let paramIndex = 0;\n\n while (hasParams(parsedRegExp)) {\n const paramName = params[paramIndex].name;\n const paramId = `:${paramName}`;\n\n parsedRegExp = parsedRegExp.replace(\n regExpToReplaceExpressPathRegExpParams,\n (str) => {\n // Express >= 4.20.0 uses a different RegExp for parameters: it\n // captures the slash as part of the parameter. We need to check\n // for this case and add the slash to the value that will replace\n // the parameter in the path.\n if (str.startsWith(\"(?:\\\\/\")) {\n return `\\\\/${paramId}`;\n }\n\n return paramId;\n },\n );\n\n paramIndex++;\n }\n\n if (parsedRegExp !== expressPathRegExp.toString()) {\n expressPathRegExpExec = regExpToParseExpressPathRegExp.exec(parsedRegExp);\n }\n\n const parsedPath = expressPathRegExpExec[1].replace(/\\\\\\//g, \"/\");\n\n return parsedPath;\n};\n\n/**\n * @param {import('express').Express | import('express').Router | any} app\n * @param {string} [basePath]\n * @param {Endpoint[]} [endpoints]\n * @returns {Endpoint[]}\n */\nconst parseEndpoints = function (app, basePath, endpoints) {\n const stack = app.stack || (app._router && app._router.stack);\n\n endpoints = endpoints || [];\n basePath = basePath || \"\";\n\n if (!stack) {\n if (endpoints.length) {\n endpoints = addEndpoints(endpoints, [\n {\n path: basePath,\n methods: [],\n middlewares: [],\n },\n ]);\n }\n } else {\n endpoints = parseStack(stack, basePath, endpoints);\n }\n\n return endpoints;\n};\n\n/**\n * Ensures the path of the new endpoints isn't yet in the array.\n * If the path is already in the array merges the endpoints with the existing\n * one, if not, it adds them to the array.\n *\n * @param {Endpoint[]} currentEndpoints Array of current endpoints\n * @param {Endpoint[]} endpointsToAdd New endpoints to be added to the array\n * @returns {Endpoint[]} Updated endpoints array\n */\nconst addEndpoints = function (currentEndpoints, endpointsToAdd) {\n endpointsToAdd.forEach((newEndpoint) => {\n const existingEndpoint = currentEndpoints.find(\n (endpoint) => endpoint.path === newEndpoint.path,\n );\n\n if (existingEndpoint !== undefined) {\n const newMethods = newEndpoint.methods.filter(\n (method) => !existingEndpoint.methods.includes(method),\n );\n\n existingEndpoint.methods = existingEndpoint.methods.concat(newMethods);\n } else {\n currentEndpoints.push(newEndpoint);\n }\n });\n\n return currentEndpoints;\n};\n\n/**\n * @param {any[]} stack\n * @param {string} basePath\n * @param {Endpoint[]} endpoints\n * @returns {Endpoint[]}\n */\nconst parseStack = function (stack, basePath, endpoints) {\n stack.forEach((stackItem) => {\n if (stackItem.route) {\n const newEndpoints = parseExpressRoute(stackItem.route, basePath);\n\n endpoints = addEndpoints(endpoints, newEndpoints);\n } else if (STACK_ITEM_VALID_NAMES.includes(stackItem.name)) {\n const isExpressPathRegexp = regExpToParseExpressPathRegExp.test(\n stackItem.regexp,\n );\n\n let newBasePath = basePath;\n\n if (isExpressPathRegexp) {\n const parsedPath = parseExpressPath(stackItem.regexp, stackItem.keys);\n\n newBasePath += `/${parsedPath}`;\n } else if (\n !stackItem.path &&\n stackItem.regexp &&\n stackItem.regexp.toString() !== EXPRESS_ROOT_PATH_REGEXP_VALUE\n ) {\n const regExpPath = ` RegExp(${stackItem.regexp}) `;\n\n newBasePath += `/${regExpPath}`;\n }\n\n endpoints = parseEndpoints(stackItem.handle, newBasePath, endpoints);\n }\n });\n\n return endpoints;\n};\n\nexport const getEndpoints = function (app, basePath) {\n const endpoints = parseEndpoints(app);\n return endpoints.flatMap((route) =>\n route.methods\n .filter((method) => ![\"HEAD\", \"OPTIONS\"].includes(method.toUpperCase()))\n .map((method) => ({\n method,\n path: (basePath + route.path).replace(/\\/\\//g, \"/\"),\n })),\n );\n};\n"],"mappings":"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","names":["regExpToParseExpressPathRegExp","regExpToReplaceExpressPathRegExpParams","regexpExpressParamRegexp","regexpExpressPathParamRegexp","EXPRESS_ROOT_PATH_REGEXP_VALUE","STACK_ITEM_VALID_NAMES","getRouteMethods","route","methods","Object","keys","filter","method","map","toUpperCase","getRouteMiddlewares","stack","item","handle","name","hasParams","expressPathRegExp","test","parseExpressRoute","basePath","paths","Array","isArray","path","push","endpoints","completePath","endpoint","replace","middlewares","parseExpressPath","params","parsedRegExp","toString","expressPathRegExpExec","exec","paramIndex","paramName","paramId","str","startsWith","parsedPath","parseEndpoints","app","_router","length","addEndpoints","parseStack","currentEndpoints","endpointsToAdd","forEach","newEndpoint","existingEndpoint","find","undefined","newMethods","includes","concat","stackItem","newEndpoints","isExpressPathRegexp","regexp","newBasePath","regExpPath","getEndpoints","flatMap"]}
|
|
1
|
+
{"version":3,"sources":["../../src/express/utils.js"],"sourcesContent":["// Adapted from https://github.com/AlbertoFdzM/express-list-endpoints/blob/305535d43008b46f34e18b01947762e039af6d2d/src/index.js\n// and also incorporated changes from https://github.com/AlbertoFdzM/express-list-endpoints/pull/96\n\n/**\n * @typedef {Object} Route\n * @property {Object} methods\n * @property {string | string[]} path\n * @property {any[]} stack\n *\n * @typedef {Object} Endpoint\n * @property {string} path Path name\n * @property {string[]} methods Methods handled\n * @property {string[]} middlewares Mounted middlewares\n */\n\nconst regExpToParseExpressPathRegExp =\n /^\\/\\^\\\\?\\/?(?:(:?[\\w\\\\.-]*(?:\\\\\\/:?[\\w\\\\.-]*)*)|(\\(\\?:\\\\?\\/?\\([^)]+\\)\\)))\\\\\\/.*/;\nconst regExpToReplaceExpressPathRegExpParams = /\\(\\?:\\\\?\\/?\\([^)]+\\)\\)/;\nconst regexpExpressParamRegexp = /\\(\\?:\\\\?\\\\?\\/?\\([^)]+\\)\\)/g;\nconst regexpExpressPathParamRegexp = /(:[^)]+)\\([^)]+\\)/g;\n\nconst EXPRESS_ROOT_PATH_REGEXP_VALUE = \"/^\\\\/?(?=\\\\/|$)/i\";\nconst STACK_ITEM_VALID_NAMES = [\"router\", \"bound dispatch\", \"mounted_app\"];\n\n/**\n * Returns all the verbs detected for the passed route\n * @param {Route} route\n */\nconst getRouteMethods = function (route) {\n let methods = Object.keys(route.methods);\n\n methods = methods.filter((method) => method !== \"_all\");\n methods = methods.map((method) => method.toUpperCase());\n\n return methods;\n};\n\n/**\n * Returns the names (or anonymous) of all the middlewares attached to the\n * passed route\n * @param {Route} route\n * @returns {string[]}\n */\nconst getRouteMiddlewares = function (route) {\n return route.stack.map((item) => {\n return item.handle.name || \"anonymous\";\n });\n};\n\n/**\n * Returns true if found regexp related with express params\n * @param {string} expressPathRegExp\n * @returns {boolean}\n */\nconst hasParams = function (expressPathRegExp) {\n return regexpExpressParamRegexp.test(expressPathRegExp);\n};\n\n/**\n * @param {Route} route Express route object to be parsed\n * @param {string} basePath The basePath the route is on\n * @return {Endpoint[]} Endpoints info\n */\nconst parseExpressRoute = function (route, basePath) {\n const paths = [];\n\n if (Array.isArray(route.path)) {\n paths.push(...route.path);\n } else {\n paths.push(route.path);\n }\n\n /** @type {Endpoint[]} */\n const endpoints = paths.map((path) => {\n const completePath =\n basePath && path === \"/\" ? basePath : `${basePath}${path}`;\n\n /** @type {Endpoint} */\n const endpoint = {\n path: completePath.replace(regexpExpressPathParamRegexp, \"$1\"),\n methods: getRouteMethods(route),\n middlewares: getRouteMiddlewares(route),\n };\n\n return endpoint;\n });\n\n return endpoints;\n};\n\n/**\n * @param {RegExp} expressPathRegExp\n * @param {any[]} params\n * @returns {string}\n */\nexport const parseExpressPath = function (expressPathRegExp, params) {\n let parsedRegExp = expressPathRegExp.toString();\n let expressPathRegExpExec = regExpToParseExpressPathRegExp.exec(parsedRegExp);\n let paramIndex = 0;\n\n while (hasParams(parsedRegExp)) {\n const paramName = params[paramIndex].name;\n const paramId = `:${paramName}`;\n\n parsedRegExp = parsedRegExp.replace(\n regExpToReplaceExpressPathRegExpParams,\n (str) => {\n // Express >= 4.20.0 uses a different RegExp for parameters: it\n // captures the slash as part of the parameter. We need to check\n // for this case and add the slash to the value that will replace\n // the parameter in the path.\n if (str.startsWith(\"(?:\\\\/\")) {\n return `\\\\/${paramId}`;\n }\n\n return paramId;\n },\n );\n\n paramIndex++;\n }\n\n if (parsedRegExp !== expressPathRegExp.toString()) {\n expressPathRegExpExec = regExpToParseExpressPathRegExp.exec(parsedRegExp);\n }\n\n const parsedPath = expressPathRegExpExec[1].replace(/\\\\\\//g, \"/\");\n\n return parsedPath;\n};\n\n/**\n * @param {import('express').Express | import('express').Router | any} app\n * @param {string} [basePath]\n * @param {Endpoint[]} [endpoints]\n * @returns {Endpoint[]}\n */\nconst parseEndpoints = function (app, basePath, endpoints) {\n const stack = app.stack || (app._router && app._router.stack);\n\n endpoints = endpoints || [];\n basePath = basePath || \"\";\n\n if (!stack) {\n if (endpoints.length) {\n endpoints = addEndpoints(endpoints, [\n {\n path: basePath,\n methods: [],\n middlewares: [],\n },\n ]);\n }\n } else {\n endpoints = parseStack(stack, basePath, endpoints);\n }\n\n return endpoints;\n};\n\n/**\n * Ensures the path of the new endpoints isn't yet in the array.\n * If the path is already in the array merges the endpoints with the existing\n * one, if not, it adds them to the array.\n *\n * @param {Endpoint[]} currentEndpoints Array of current endpoints\n * @param {Endpoint[]} endpointsToAdd New endpoints to be added to the array\n * @returns {Endpoint[]} Updated endpoints array\n */\nconst addEndpoints = function (currentEndpoints, endpointsToAdd) {\n endpointsToAdd.forEach((newEndpoint) => {\n const existingEndpoint = currentEndpoints.find(\n (endpoint) => endpoint.path === newEndpoint.path,\n );\n\n if (existingEndpoint !== undefined) {\n const newMethods = newEndpoint.methods.filter(\n (method) => !existingEndpoint.methods.includes(method),\n );\n\n existingEndpoint.methods = existingEndpoint.methods.concat(newMethods);\n } else {\n currentEndpoints.push(newEndpoint);\n }\n });\n\n return currentEndpoints;\n};\n\n/**\n * @param {any[]} stack\n * @param {string} basePath\n * @param {Endpoint[]} endpoints\n * @returns {Endpoint[]}\n */\nconst parseStack = function (stack, basePath, endpoints) {\n stack.forEach((stackItem) => {\n if (stackItem.route) {\n const newEndpoints = parseExpressRoute(stackItem.route, basePath);\n\n endpoints = addEndpoints(endpoints, newEndpoints);\n } else if (STACK_ITEM_VALID_NAMES.includes(stackItem.name)) {\n const isExpressPathRegexp = regExpToParseExpressPathRegExp.test(\n stackItem.regexp,\n );\n\n let newBasePath = basePath;\n\n if (isExpressPathRegexp) {\n const parsedPath = parseExpressPath(stackItem.regexp, stackItem.keys);\n\n newBasePath += `/${parsedPath}`;\n } else if (\n !stackItem.path &&\n stackItem.regexp &&\n stackItem.regexp.toString() !== EXPRESS_ROOT_PATH_REGEXP_VALUE\n ) {\n const regExpPath = ` RegExp(${stackItem.regexp}) `;\n\n newBasePath += `/${regExpPath}`;\n }\n\n endpoints = parseEndpoints(stackItem.handle, newBasePath, endpoints);\n }\n });\n\n return endpoints;\n};\n\nexport const getEndpoints = function (app, basePath) {\n const endpoints = parseEndpoints(app);\n return endpoints.flatMap((route) =>\n route.methods\n .filter((method) => ![\"HEAD\", \"OPTIONS\"].includes(method.toUpperCase()))\n .map((method) => ({\n method,\n path: (basePath + route.path).replace(/\\/\\//g, \"/\"),\n })),\n );\n};\n"],"mappings":"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","names":["regExpToParseExpressPathRegExp","regExpToReplaceExpressPathRegExpParams","regexpExpressParamRegexp","regexpExpressPathParamRegexp","EXPRESS_ROOT_PATH_REGEXP_VALUE","STACK_ITEM_VALID_NAMES","getRouteMethods","route","methods","Object","keys","filter","method","map","toUpperCase","getRouteMiddlewares","stack","item","handle","name","hasParams","expressPathRegExp","test","parseExpressRoute","basePath","paths","Array","isArray","path","push","endpoints","completePath","endpoint","replace","middlewares","parseExpressPath","params","parsedRegExp","toString","expressPathRegExpExec","exec","paramIndex","paramName","paramId","str","startsWith","parsedPath","parseEndpoints","app","_router","length","addEndpoints","parseStack","currentEndpoints","endpointsToAdd","forEach","newEndpoint","existingEndpoint","find","undefined","newMethods","includes","concat","stackItem","newEndpoints","isExpressPathRegexp","regexp","newBasePath","regExpPath","getEndpoints","flatMap"]}
|
package/dist/fastify/index.cjs
CHANGED
|
@@ -213,14 +213,116 @@ var RequestCounter = _RequestCounter;
|
|
|
213
213
|
// src/common/requestLogger.ts
|
|
214
214
|
var import_async_lock = __toESM(require("async-lock"), 1);
|
|
215
215
|
var import_buffer2 = require("buffer");
|
|
216
|
-
var
|
|
216
|
+
var import_crypto3 = require("crypto");
|
|
217
217
|
var import_fs2 = require("fs");
|
|
218
218
|
var import_os2 = require("os");
|
|
219
219
|
var import_path2 = require("path");
|
|
220
220
|
|
|
221
|
+
// src/common/sentry.ts
|
|
222
|
+
var sentry;
|
|
223
|
+
(async () => {
|
|
224
|
+
try {
|
|
225
|
+
sentry = await import("@sentry/node");
|
|
226
|
+
} catch (e) {
|
|
227
|
+
}
|
|
228
|
+
})();
|
|
229
|
+
function getSentryEventId() {
|
|
230
|
+
if (sentry && sentry.lastEventId) {
|
|
231
|
+
return sentry.lastEventId();
|
|
232
|
+
}
|
|
233
|
+
return void 0;
|
|
234
|
+
}
|
|
235
|
+
__name(getSentryEventId, "getSentryEventId");
|
|
236
|
+
|
|
237
|
+
// src/common/serverErrorCounter.ts
|
|
238
|
+
var import_crypto = require("crypto");
|
|
239
|
+
var MAX_MSG_LENGTH = 2048;
|
|
240
|
+
var MAX_STACKTRACE_LENGTH = 65536;
|
|
241
|
+
var _ServerErrorCounter = class _ServerErrorCounter {
|
|
242
|
+
errorCounts;
|
|
243
|
+
errorDetails;
|
|
244
|
+
sentryEventIds;
|
|
245
|
+
constructor() {
|
|
246
|
+
this.errorCounts = /* @__PURE__ */ new Map();
|
|
247
|
+
this.errorDetails = /* @__PURE__ */ new Map();
|
|
248
|
+
this.sentryEventIds = /* @__PURE__ */ new Map();
|
|
249
|
+
}
|
|
250
|
+
addServerError(serverError) {
|
|
251
|
+
const key = this.getKey(serverError);
|
|
252
|
+
if (!this.errorDetails.has(key)) {
|
|
253
|
+
this.errorDetails.set(key, serverError);
|
|
254
|
+
}
|
|
255
|
+
this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
|
|
256
|
+
const sentryEventId = getSentryEventId();
|
|
257
|
+
if (sentryEventId) {
|
|
258
|
+
this.sentryEventIds.set(key, sentryEventId);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
getAndResetServerErrors() {
|
|
262
|
+
const data = [];
|
|
263
|
+
this.errorCounts.forEach((count, key) => {
|
|
264
|
+
const serverError = this.errorDetails.get(key);
|
|
265
|
+
if (serverError) {
|
|
266
|
+
data.push({
|
|
267
|
+
consumer: serverError.consumer || null,
|
|
268
|
+
method: serverError.method,
|
|
269
|
+
path: serverError.path,
|
|
270
|
+
type: serverError.type,
|
|
271
|
+
msg: truncateExceptionMessage(serverError.msg),
|
|
272
|
+
traceback: truncateExceptionStackTrace(serverError.traceback),
|
|
273
|
+
sentry_event_id: this.sentryEventIds.get(key) || null,
|
|
274
|
+
error_count: count
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
this.errorCounts.clear();
|
|
279
|
+
this.errorDetails.clear();
|
|
280
|
+
return data;
|
|
281
|
+
}
|
|
282
|
+
getKey(serverError) {
|
|
283
|
+
const hashInput = [
|
|
284
|
+
serverError.consumer || "",
|
|
285
|
+
serverError.method.toUpperCase(),
|
|
286
|
+
serverError.path,
|
|
287
|
+
serverError.type,
|
|
288
|
+
serverError.msg.trim(),
|
|
289
|
+
serverError.traceback.trim()
|
|
290
|
+
].join("|");
|
|
291
|
+
return (0, import_crypto.createHash)("md5").update(hashInput).digest("hex");
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
__name(_ServerErrorCounter, "ServerErrorCounter");
|
|
295
|
+
var ServerErrorCounter = _ServerErrorCounter;
|
|
296
|
+
function truncateExceptionMessage(msg) {
|
|
297
|
+
if (msg.length <= MAX_MSG_LENGTH) {
|
|
298
|
+
return msg;
|
|
299
|
+
}
|
|
300
|
+
const suffix = "... (truncated)";
|
|
301
|
+
const cutoff = MAX_MSG_LENGTH - suffix.length;
|
|
302
|
+
return msg.substring(0, cutoff) + suffix;
|
|
303
|
+
}
|
|
304
|
+
__name(truncateExceptionMessage, "truncateExceptionMessage");
|
|
305
|
+
function truncateExceptionStackTrace(stack) {
|
|
306
|
+
const suffix = "... (truncated) ...";
|
|
307
|
+
const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;
|
|
308
|
+
const lines = stack.trim().split("\n");
|
|
309
|
+
const truncatedLines = [];
|
|
310
|
+
let length = 0;
|
|
311
|
+
for (const line of lines) {
|
|
312
|
+
if (length + line.length + 1 > cutoff) {
|
|
313
|
+
truncatedLines.push(suffix);
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
truncatedLines.push(line);
|
|
317
|
+
length += line.length + 1;
|
|
318
|
+
}
|
|
319
|
+
return truncatedLines.join("\n");
|
|
320
|
+
}
|
|
321
|
+
__name(truncateExceptionStackTrace, "truncateExceptionStackTrace");
|
|
322
|
+
|
|
221
323
|
// src/common/tempGzipFile.ts
|
|
222
324
|
var import_buffer = require("buffer");
|
|
223
|
-
var
|
|
325
|
+
var import_crypto2 = require("crypto");
|
|
224
326
|
var import_fs = require("fs");
|
|
225
327
|
var import_os = require("os");
|
|
226
328
|
var import_path = require("path");
|
|
@@ -233,7 +335,7 @@ var _TempGzipFile = class _TempGzipFile {
|
|
|
233
335
|
readyPromise;
|
|
234
336
|
closedPromise;
|
|
235
337
|
constructor() {
|
|
236
|
-
this.uuid = (0,
|
|
338
|
+
this.uuid = (0, import_crypto2.randomUUID)();
|
|
237
339
|
this.filePath = (0, import_path.join)((0, import_os.tmpdir)(), `apitally-${this.uuid}.gz`);
|
|
238
340
|
this.writeStream = (0, import_fs.createWriteStream)(this.filePath);
|
|
239
341
|
this.readyPromise = new Promise((resolve, reject) => {
|
|
@@ -340,6 +442,7 @@ var DEFAULT_CONFIG = {
|
|
|
340
442
|
logRequestBody: false,
|
|
341
443
|
logResponseHeaders: true,
|
|
342
444
|
logResponseBody: false,
|
|
445
|
+
logException: true,
|
|
343
446
|
maskQueryParams: [],
|
|
344
447
|
maskHeaders: [],
|
|
345
448
|
excludePaths: []
|
|
@@ -412,7 +515,7 @@ var _RequestLogger = class _RequestLogger {
|
|
|
412
515
|
this.shouldMaskHeader(k) ? MASKED : v
|
|
413
516
|
]);
|
|
414
517
|
}
|
|
415
|
-
logRequest(request, response) {
|
|
518
|
+
logRequest(request, response, error) {
|
|
416
519
|
var _a2, _b, _c;
|
|
417
520
|
if (!this.enabled || this.suspendUntil !== null) return;
|
|
418
521
|
const url = new URL(request.url);
|
|
@@ -458,9 +561,15 @@ var _RequestLogger = class _RequestLogger {
|
|
|
458
561
|
request.headers = this.config.logRequestHeaders ? this.maskHeaders(request.headers) : [];
|
|
459
562
|
response.headers = this.config.logResponseHeaders ? this.maskHeaders(response.headers) : [];
|
|
460
563
|
const item = {
|
|
461
|
-
uuid: (0,
|
|
564
|
+
uuid: (0, import_crypto3.randomUUID)(),
|
|
462
565
|
request: skipEmptyValues(request),
|
|
463
|
-
response: skipEmptyValues(response)
|
|
566
|
+
response: skipEmptyValues(response),
|
|
567
|
+
exception: error && this.config.logException ? {
|
|
568
|
+
type: error.name,
|
|
569
|
+
message: truncateExceptionMessage(error.message),
|
|
570
|
+
stacktrace: truncateExceptionStackTrace(error.stack || ""),
|
|
571
|
+
sentryEventId: getSentryEventId()
|
|
572
|
+
} : null
|
|
464
573
|
};
|
|
465
574
|
[
|
|
466
575
|
item.request.body,
|
|
@@ -612,7 +721,7 @@ function skipEmptyValues(data) {
|
|
|
612
721
|
__name(skipEmptyValues, "skipEmptyValues");
|
|
613
722
|
function checkWritableFs() {
|
|
614
723
|
try {
|
|
615
|
-
const testPath = (0, import_path2.join)((0, import_os2.tmpdir)(), `apitally-${(0,
|
|
724
|
+
const testPath = (0, import_path2.join)((0, import_os2.tmpdir)(), `apitally-${(0, import_crypto3.randomUUID)()}`);
|
|
616
725
|
(0, import_fs2.writeFileSync)(testPath, "test");
|
|
617
726
|
(0, import_fs2.unlinkSync)(testPath);
|
|
618
727
|
return true;
|
|
@@ -622,104 +731,6 @@ function checkWritableFs() {
|
|
|
622
731
|
}
|
|
623
732
|
__name(checkWritableFs, "checkWritableFs");
|
|
624
733
|
|
|
625
|
-
// src/common/serverErrorCounter.ts
|
|
626
|
-
var import_crypto3 = require("crypto");
|
|
627
|
-
var MAX_MSG_LENGTH = 2048;
|
|
628
|
-
var MAX_STACKTRACE_LENGTH = 65536;
|
|
629
|
-
var _ServerErrorCounter = class _ServerErrorCounter {
|
|
630
|
-
errorCounts;
|
|
631
|
-
errorDetails;
|
|
632
|
-
sentryEventIds;
|
|
633
|
-
sentry;
|
|
634
|
-
constructor() {
|
|
635
|
-
this.errorCounts = /* @__PURE__ */ new Map();
|
|
636
|
-
this.errorDetails = /* @__PURE__ */ new Map();
|
|
637
|
-
this.sentryEventIds = /* @__PURE__ */ new Map();
|
|
638
|
-
this.tryImportSentry();
|
|
639
|
-
}
|
|
640
|
-
addServerError(serverError) {
|
|
641
|
-
const key = this.getKey(serverError);
|
|
642
|
-
if (!this.errorDetails.has(key)) {
|
|
643
|
-
this.errorDetails.set(key, serverError);
|
|
644
|
-
}
|
|
645
|
-
this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
|
|
646
|
-
this.captureSentryEventId(key);
|
|
647
|
-
}
|
|
648
|
-
getAndResetServerErrors() {
|
|
649
|
-
const data = [];
|
|
650
|
-
this.errorCounts.forEach((count, key) => {
|
|
651
|
-
const serverError = this.errorDetails.get(key);
|
|
652
|
-
if (serverError) {
|
|
653
|
-
data.push({
|
|
654
|
-
consumer: serverError.consumer || null,
|
|
655
|
-
method: serverError.method,
|
|
656
|
-
path: serverError.path,
|
|
657
|
-
type: serverError.type,
|
|
658
|
-
msg: this.getTruncatedMessage(serverError.msg),
|
|
659
|
-
traceback: this.getTruncatedStack(serverError.traceback),
|
|
660
|
-
sentry_event_id: this.sentryEventIds.get(key) || null,
|
|
661
|
-
error_count: count
|
|
662
|
-
});
|
|
663
|
-
}
|
|
664
|
-
});
|
|
665
|
-
this.errorCounts.clear();
|
|
666
|
-
this.errorDetails.clear();
|
|
667
|
-
return data;
|
|
668
|
-
}
|
|
669
|
-
getKey(serverError) {
|
|
670
|
-
const hashInput = [
|
|
671
|
-
serverError.consumer || "",
|
|
672
|
-
serverError.method.toUpperCase(),
|
|
673
|
-
serverError.path,
|
|
674
|
-
serverError.type,
|
|
675
|
-
serverError.msg.trim(),
|
|
676
|
-
serverError.traceback.trim()
|
|
677
|
-
].join("|");
|
|
678
|
-
return (0, import_crypto3.createHash)("md5").update(hashInput).digest("hex");
|
|
679
|
-
}
|
|
680
|
-
getTruncatedMessage(msg) {
|
|
681
|
-
msg = msg.trim();
|
|
682
|
-
if (msg.length <= MAX_MSG_LENGTH) {
|
|
683
|
-
return msg;
|
|
684
|
-
}
|
|
685
|
-
const suffix = "... (truncated)";
|
|
686
|
-
const cutoff = MAX_MSG_LENGTH - suffix.length;
|
|
687
|
-
return msg.substring(0, cutoff) + suffix;
|
|
688
|
-
}
|
|
689
|
-
getTruncatedStack(stack) {
|
|
690
|
-
const suffix = "... (truncated) ...";
|
|
691
|
-
const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;
|
|
692
|
-
const lines = stack.trim().split("\n");
|
|
693
|
-
const truncatedLines = [];
|
|
694
|
-
let length = 0;
|
|
695
|
-
for (const line of lines) {
|
|
696
|
-
if (length + line.length + 1 > cutoff) {
|
|
697
|
-
truncatedLines.push(suffix);
|
|
698
|
-
break;
|
|
699
|
-
}
|
|
700
|
-
truncatedLines.push(line);
|
|
701
|
-
length += line.length + 1;
|
|
702
|
-
}
|
|
703
|
-
return truncatedLines.join("\n");
|
|
704
|
-
}
|
|
705
|
-
captureSentryEventId(serverErrorKey) {
|
|
706
|
-
if (this.sentry && this.sentry.lastEventId) {
|
|
707
|
-
const eventId = this.sentry.lastEventId();
|
|
708
|
-
if (eventId) {
|
|
709
|
-
this.sentryEventIds.set(serverErrorKey, eventId);
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
async tryImportSentry() {
|
|
714
|
-
try {
|
|
715
|
-
this.sentry = await import("@sentry/node");
|
|
716
|
-
} catch (e) {
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
};
|
|
720
|
-
__name(_ServerErrorCounter, "ServerErrorCounter");
|
|
721
|
-
var ServerErrorCounter = _ServerErrorCounter;
|
|
722
|
-
|
|
723
734
|
// src/common/validationErrorCounter.ts
|
|
724
735
|
var import_crypto4 = require("crypto");
|
|
725
736
|
var _ValidationErrorCounter = class _ValidationErrorCounter {
|
|
@@ -805,7 +816,7 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
805
816
|
throw new Error("Apitally client is already initialized");
|
|
806
817
|
}
|
|
807
818
|
if (!isValidClientId(clientId)) {
|
|
808
|
-
throw new Error(`Invalid client ID '${clientId}' (expecting
|
|
819
|
+
throw new Error(`Invalid Apitally client ID '${clientId}' (expecting hexadecimal UUID format)`);
|
|
809
820
|
}
|
|
810
821
|
if (!isValidEnv(env)) {
|
|
811
822
|
throw new Error(`Invalid env '${env}' (expecting 1-32 alphanumeric lowercase characters and hyphens only)`);
|
|
@@ -1061,6 +1072,25 @@ function getPackageVersion(name) {
|
|
|
1061
1072
|
}
|
|
1062
1073
|
__name(getPackageVersion, "getPackageVersion");
|
|
1063
1074
|
|
|
1075
|
+
// src/common/utils.ts
|
|
1076
|
+
function parseContentLength(contentLength) {
|
|
1077
|
+
if (contentLength === void 0 || contentLength === null) {
|
|
1078
|
+
return void 0;
|
|
1079
|
+
}
|
|
1080
|
+
if (typeof contentLength === "number") {
|
|
1081
|
+
return contentLength;
|
|
1082
|
+
}
|
|
1083
|
+
if (typeof contentLength === "string") {
|
|
1084
|
+
const parsed = parseInt(contentLength);
|
|
1085
|
+
return isNaN(parsed) ? void 0 : parsed;
|
|
1086
|
+
}
|
|
1087
|
+
if (Array.isArray(contentLength)) {
|
|
1088
|
+
return parseContentLength(contentLength[0]);
|
|
1089
|
+
}
|
|
1090
|
+
return void 0;
|
|
1091
|
+
}
|
|
1092
|
+
__name(parseContentLength, "parseContentLength");
|
|
1093
|
+
|
|
1064
1094
|
// src/fastify/plugin.ts
|
|
1065
1095
|
var apitallyPlugin = /* @__PURE__ */ __name(async (fastify, config) => {
|
|
1066
1096
|
const client = new ApitallyClient(config);
|
|
@@ -1108,11 +1138,8 @@ var apitallyPlugin = /* @__PURE__ */ __name(async (fastify, config) => {
|
|
|
1108
1138
|
if (client.isEnabled() && request.method.toUpperCase() !== "OPTIONS") {
|
|
1109
1139
|
const consumer = getConsumer(request);
|
|
1110
1140
|
const path = "routeOptions" in request ? request.routeOptions.url : request.routerPath;
|
|
1111
|
-
const requestSize = request.headers["content-length"];
|
|
1112
|
-
|
|
1113
|
-
if (Array.isArray(responseSize)) {
|
|
1114
|
-
responseSize = responseSize[0];
|
|
1115
|
-
}
|
|
1141
|
+
const requestSize = parseContentLength(request.headers["content-length"]);
|
|
1142
|
+
const responseSize = parseContentLength(reply.getHeader("content-length"));
|
|
1116
1143
|
const responseTime = getResponseTime(reply);
|
|
1117
1144
|
client.consumerRegistry.addOrUpdateConsumer(consumer);
|
|
1118
1145
|
client.requestCounter.addRequest({
|
|
@@ -1167,7 +1194,7 @@ var apitallyPlugin = /* @__PURE__ */ __name(async (fastify, config) => {
|
|
|
1167
1194
|
headers: convertHeaders(reply.getHeaders()),
|
|
1168
1195
|
size: Number(responseSize),
|
|
1169
1196
|
body: convertBody(reply.payload, (_a2 = reply.getHeader("content-type")) == null ? void 0 : _a2.toString())
|
|
1170
|
-
});
|
|
1197
|
+
}, reply.serverError);
|
|
1171
1198
|
}
|
|
1172
1199
|
}
|
|
1173
1200
|
done();
|