apitally 0.7.0 → 0.8.1
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/dist/common/client.cjs +75 -30
- package/dist/common/client.cjs.map +1 -1
- package/dist/common/client.d.cts +10 -8
- package/dist/common/client.d.ts +10 -8
- package/dist/common/client.js +75 -30
- package/dist/common/client.js.map +1 -1
- package/dist/common/consumerRegistry.cjs +86 -0
- package/dist/common/consumerRegistry.cjs.map +1 -0
- package/dist/common/consumerRegistry.d.cts +14 -0
- package/dist/common/consumerRegistry.d.ts +14 -0
- package/dist/common/consumerRegistry.js +63 -0
- package/dist/common/consumerRegistry.js.map +1 -0
- package/dist/common/types.cjs.map +1 -1
- package/dist/common/types.d.cts +12 -5
- package/dist/common/types.d.ts +12 -5
- package/dist/express/index.cjs +113 -49
- package/dist/express/index.cjs.map +1 -1
- package/dist/express/index.d.cts +2 -2
- package/dist/express/index.d.ts +2 -2
- package/dist/express/index.js +113 -49
- package/dist/express/index.js.map +1 -1
- package/dist/express/listEndpoints.cjs +16 -13
- package/dist/express/listEndpoints.cjs.map +1 -1
- package/dist/express/listEndpoints.d.cts +33 -2
- package/dist/express/listEndpoints.d.ts +33 -2
- package/dist/express/listEndpoints.js +16 -13
- package/dist/express/listEndpoints.js.map +1 -1
- package/dist/express/middleware.cjs +113 -49
- package/dist/express/middleware.cjs.map +1 -1
- package/dist/express/middleware.d.cts +5 -5
- package/dist/express/middleware.d.ts +5 -5
- package/dist/express/middleware.js +113 -49
- package/dist/express/middleware.js.map +1 -1
- package/dist/fastify/index.cjs +106 -37
- package/dist/fastify/index.cjs.map +1 -1
- package/dist/fastify/index.d.cts +2 -2
- package/dist/fastify/index.d.ts +2 -2
- package/dist/fastify/index.js +106 -37
- package/dist/fastify/index.js.map +1 -1
- package/dist/fastify/plugin.cjs +106 -37
- package/dist/fastify/plugin.cjs.map +1 -1
- package/dist/fastify/plugin.d.cts +3 -3
- package/dist/fastify/plugin.d.ts +3 -3
- package/dist/fastify/plugin.js +106 -37
- package/dist/fastify/plugin.js.map +1 -1
- package/dist/koa/index.cjs +98 -35
- package/dist/koa/index.cjs.map +1 -1
- package/dist/koa/index.d.cts +2 -2
- package/dist/koa/index.d.ts +2 -2
- package/dist/koa/index.js +98 -35
- package/dist/koa/index.js.map +1 -1
- package/dist/koa/middleware.cjs +98 -35
- package/dist/koa/middleware.cjs.map +1 -1
- package/dist/koa/middleware.d.cts +1 -1
- package/dist/koa/middleware.d.ts +1 -1
- package/dist/koa/middleware.js +98 -35
- package/dist/koa/middleware.js.map +1 -1
- package/dist/nestjs/index.cjs +113 -49
- package/dist/nestjs/index.cjs.map +1 -1
- package/dist/nestjs/index.d.cts +2 -2
- package/dist/nestjs/index.d.ts +2 -2
- package/dist/nestjs/index.js +113 -49
- package/dist/nestjs/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -24,9 +24,10 @@ __export(listEndpoints_exports, {
|
|
|
24
24
|
default: () => listEndpoints_default
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(listEndpoints_exports);
|
|
27
|
-
var regExpToParseExpressPathRegExp = /^\/\^\\\/(?:(:?[\w\\.-]*(?:\\\/:?[\w\\.-]*)*)|(\(\?:\(
|
|
28
|
-
var regExpToReplaceExpressPathRegExpParams = /\(\?:\(
|
|
29
|
-
var regexpExpressParamRegexp = /\(\?:\(
|
|
27
|
+
var regExpToParseExpressPathRegExp = /^\/\^\\\/(?:(:?[\w\\.-]*(?:\\\/:?[\w\\.-]*)*)|(\(\?:\([^)]+\)\)))\\\/.*/;
|
|
28
|
+
var regExpToReplaceExpressPathRegExpParams = /\(\?:\([^)]+\)\)/;
|
|
29
|
+
var regexpExpressParamRegexp = /\(\?:\([^)]+\)\)/g;
|
|
30
|
+
var regexpExpressPathParamRegexp = /(:[^)]+)\([^)]+\)/g;
|
|
30
31
|
var EXPRESS_ROOT_PATH_REGEXP_VALUE = "/^\\/?(?=\\/|$)/i";
|
|
31
32
|
var STACK_ITEM_VALID_NAMES = [
|
|
32
33
|
"router",
|
|
@@ -57,7 +58,7 @@ var parseExpressRoute = /* @__PURE__ */ __name(function(route, basePath) {
|
|
|
57
58
|
const endpoints = paths.map((path) => {
|
|
58
59
|
const completePath = basePath && path === "/" ? basePath : `${basePath}${path}`;
|
|
59
60
|
const endpoint = {
|
|
60
|
-
path: completePath,
|
|
61
|
+
path: completePath.replace(regexpExpressPathParamRegexp, "$1"),
|
|
61
62
|
methods: getRouteMethods(route),
|
|
62
63
|
middlewares: getRouteMiddlewares(route)
|
|
63
64
|
};
|
|
@@ -66,8 +67,8 @@ var parseExpressRoute = /* @__PURE__ */ __name(function(route, basePath) {
|
|
|
66
67
|
return endpoints;
|
|
67
68
|
}, "parseExpressRoute");
|
|
68
69
|
var parseExpressPath = /* @__PURE__ */ __name(function(expressPathRegExp, params) {
|
|
69
|
-
let expressPathRegExpExec = regExpToParseExpressPathRegExp.exec(expressPathRegExp);
|
|
70
70
|
let parsedRegExp = expressPathRegExp.toString();
|
|
71
|
+
let expressPathRegExpExec = regExpToParseExpressPathRegExp.exec(parsedRegExp);
|
|
71
72
|
let paramIndex = 0;
|
|
72
73
|
while (hasParams(parsedRegExp)) {
|
|
73
74
|
const paramName = params[paramIndex].name;
|
|
@@ -86,13 +87,15 @@ var parseEndpoints = /* @__PURE__ */ __name(function(app, basePath, endpoints) {
|
|
|
86
87
|
endpoints = endpoints || [];
|
|
87
88
|
basePath = basePath || "";
|
|
88
89
|
if (!stack) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
if (endpoints.length) {
|
|
91
|
+
endpoints = addEndpoints(endpoints, [
|
|
92
|
+
{
|
|
93
|
+
path: basePath,
|
|
94
|
+
methods: [],
|
|
95
|
+
middlewares: []
|
|
96
|
+
}
|
|
97
|
+
]);
|
|
98
|
+
}
|
|
96
99
|
} else {
|
|
97
100
|
endpoints = parseStack(stack, basePath, endpoints);
|
|
98
101
|
}
|
|
@@ -100,7 +103,7 @@ var parseEndpoints = /* @__PURE__ */ __name(function(app, basePath, endpoints) {
|
|
|
100
103
|
}, "parseEndpoints");
|
|
101
104
|
var addEndpoints = /* @__PURE__ */ __name(function(currentEndpoints, endpointsToAdd) {
|
|
102
105
|
endpointsToAdd.forEach((newEndpoint) => {
|
|
103
|
-
const existingEndpoint = currentEndpoints.find((
|
|
106
|
+
const existingEndpoint = currentEndpoints.find((endpoint) => endpoint.path === newEndpoint.path);
|
|
104
107
|
if (existingEndpoint !== void 0) {
|
|
105
108
|
const newMethods = newEndpoint.methods.filter((method) => !existingEndpoint.methods.includes(method));
|
|
106
109
|
existingEndpoint.methods = existingEndpoint.methods.concat(newMethods);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/express/listEndpoints.js"],"sourcesContent":["// Adapted from https://github.com/AlbertoFdzM/express-list-endpoints/blob/ed926dd5186761e7b721ad20938ce6eb52d104d3/src/index.js\n\nconst regExpToParseExpressPathRegExp =\n /^\\/\\^\\\\\\/(?:(:?[\\w\\\\.-]*(?:\\\\\\/:?[\\w\\\\.-]*)*)|(\\(\\?:\\(\\[\\^\\\\\\/]\\+\\?\\)\\)))\\\\\\/.*/;\nconst regExpToReplaceExpressPathRegExpParams = /\\(\\?:\\(\\[\\^\\\\\\/]\\+\\?\\)\\)/;\nconst regexpExpressParamRegexp = /\\(\\?:\\(\\[\\^\\\\\\/]\\+\\?\\)\\)/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 */\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 {Object} 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 {Object} route Express route object to be parsed\n * @param {string} basePath The basePath the route is on\n * @return {Object[]} 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 const endpoints = paths.map((path) => {\n const completePath =\n basePath && path === \"/\" ? basePath : `${basePath}${path}`;\n\n const endpoint = {\n path: completePath,\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 {Object[]} params\n * @returns {string}\n */\nconst parseExpressPath = function (expressPathRegExp, params) {\n let expressPathRegExpExec =\n regExpToParseExpressPathRegExp.exec(expressPathRegExp);\n let parsedRegExp = expressPathRegExp.toString();\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 paramId,\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 {Object} app\n * @param {string} [basePath]\n * @param {Object[]} [endpoints]\n * @returns {Object[]}\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 endpoints = addEndpoints(endpoints, [\n {\n path: basePath,\n methods: [],\n middlewares: [],\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 {Object[]} currentEndpoints Array of current endpoints\n * @param {Object[]} endpointsToAdd New endpoints to be added to the array\n * @returns {Object[]} Updated endpoints array\n */\nconst addEndpoints = function (currentEndpoints, endpointsToAdd) {\n endpointsToAdd.forEach((newEndpoint) => {\n const existingEndpoint = currentEndpoints.find(\n (item) => item.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 {Object} stack\n * @param {string} basePath\n * @param {Object[]} endpoints\n * @returns {Object[]}\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\nconst getEndpoints = function (app) {\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: route.path,\n })),\n );\n};\n\nexport default getEndpoints;\n"],"mappings":"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","names":["regExpToParseExpressPathRegExp","regExpToReplaceExpressPathRegExpParams","regexpExpressParamRegexp","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","middlewares","parseExpressPath","params","expressPathRegExpExec","exec","parsedRegExp","toString","paramIndex","paramName","paramId","replace","parsedPath","parseEndpoints","app","_router","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/listEndpoints.js"],"sourcesContent":["// Adapted from https://github.com/AlbertoFdzM/express-list-endpoints/blob/305535d43008b46f34e18b01947762e039af6d2d/src/index.js\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 */\nconst 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 paramId,\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\nconst getEndpoints = function (app) {\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: route.path,\n })),\n );\n};\n\nexport default getEndpoints;\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","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,3 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
type Route = {
|
|
2
|
+
methods: Object;
|
|
3
|
+
path: string | string[];
|
|
4
|
+
stack: any[];
|
|
5
|
+
};
|
|
6
|
+
type Endpoint = {
|
|
7
|
+
/**
|
|
8
|
+
* Path name
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Path name
|
|
12
|
+
*/
|
|
13
|
+
path: string;
|
|
14
|
+
/**
|
|
15
|
+
* Methods handled
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Methods handled
|
|
19
|
+
*/
|
|
20
|
+
methods: string[];
|
|
21
|
+
/**
|
|
22
|
+
* Mounted middlewares
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Mounted middlewares
|
|
26
|
+
*/
|
|
27
|
+
middlewares: string[];
|
|
28
|
+
};
|
|
29
|
+
declare function getEndpoints(app: any): {
|
|
30
|
+
method: string;
|
|
31
|
+
path: string;
|
|
32
|
+
}[];
|
|
2
33
|
|
|
3
|
-
export { getEndpoints as default };
|
|
34
|
+
export { type Endpoint, type Route, getEndpoints as default };
|
|
@@ -1,3 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
type Route = {
|
|
2
|
+
methods: Object;
|
|
3
|
+
path: string | string[];
|
|
4
|
+
stack: any[];
|
|
5
|
+
};
|
|
6
|
+
type Endpoint = {
|
|
7
|
+
/**
|
|
8
|
+
* Path name
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Path name
|
|
12
|
+
*/
|
|
13
|
+
path: string;
|
|
14
|
+
/**
|
|
15
|
+
* Methods handled
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Methods handled
|
|
19
|
+
*/
|
|
20
|
+
methods: string[];
|
|
21
|
+
/**
|
|
22
|
+
* Mounted middlewares
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Mounted middlewares
|
|
26
|
+
*/
|
|
27
|
+
middlewares: string[];
|
|
28
|
+
};
|
|
29
|
+
declare function getEndpoints(app: any): {
|
|
30
|
+
method: string;
|
|
31
|
+
path: string;
|
|
32
|
+
}[];
|
|
2
33
|
|
|
3
|
-
export { getEndpoints as default };
|
|
34
|
+
export { type Endpoint, type Route, getEndpoints as default };
|
|
@@ -2,9 +2,10 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
4
|
// src/express/listEndpoints.js
|
|
5
|
-
var regExpToParseExpressPathRegExp = /^\/\^\\\/(?:(:?[\w\\.-]*(?:\\\/:?[\w\\.-]*)*)|(\(\?:\(
|
|
6
|
-
var regExpToReplaceExpressPathRegExpParams = /\(\?:\(
|
|
7
|
-
var regexpExpressParamRegexp = /\(\?:\(
|
|
5
|
+
var regExpToParseExpressPathRegExp = /^\/\^\\\/(?:(:?[\w\\.-]*(?:\\\/:?[\w\\.-]*)*)|(\(\?:\([^)]+\)\)))\\\/.*/;
|
|
6
|
+
var regExpToReplaceExpressPathRegExpParams = /\(\?:\([^)]+\)\)/;
|
|
7
|
+
var regexpExpressParamRegexp = /\(\?:\([^)]+\)\)/g;
|
|
8
|
+
var regexpExpressPathParamRegexp = /(:[^)]+)\([^)]+\)/g;
|
|
8
9
|
var EXPRESS_ROOT_PATH_REGEXP_VALUE = "/^\\/?(?=\\/|$)/i";
|
|
9
10
|
var STACK_ITEM_VALID_NAMES = [
|
|
10
11
|
"router",
|
|
@@ -35,7 +36,7 @@ var parseExpressRoute = /* @__PURE__ */ __name(function(route, basePath) {
|
|
|
35
36
|
const endpoints = paths.map((path) => {
|
|
36
37
|
const completePath = basePath && path === "/" ? basePath : `${basePath}${path}`;
|
|
37
38
|
const endpoint = {
|
|
38
|
-
path: completePath,
|
|
39
|
+
path: completePath.replace(regexpExpressPathParamRegexp, "$1"),
|
|
39
40
|
methods: getRouteMethods(route),
|
|
40
41
|
middlewares: getRouteMiddlewares(route)
|
|
41
42
|
};
|
|
@@ -44,8 +45,8 @@ var parseExpressRoute = /* @__PURE__ */ __name(function(route, basePath) {
|
|
|
44
45
|
return endpoints;
|
|
45
46
|
}, "parseExpressRoute");
|
|
46
47
|
var parseExpressPath = /* @__PURE__ */ __name(function(expressPathRegExp, params) {
|
|
47
|
-
let expressPathRegExpExec = regExpToParseExpressPathRegExp.exec(expressPathRegExp);
|
|
48
48
|
let parsedRegExp = expressPathRegExp.toString();
|
|
49
|
+
let expressPathRegExpExec = regExpToParseExpressPathRegExp.exec(parsedRegExp);
|
|
49
50
|
let paramIndex = 0;
|
|
50
51
|
while (hasParams(parsedRegExp)) {
|
|
51
52
|
const paramName = params[paramIndex].name;
|
|
@@ -64,13 +65,15 @@ var parseEndpoints = /* @__PURE__ */ __name(function(app, basePath, endpoints) {
|
|
|
64
65
|
endpoints = endpoints || [];
|
|
65
66
|
basePath = basePath || "";
|
|
66
67
|
if (!stack) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
if (endpoints.length) {
|
|
69
|
+
endpoints = addEndpoints(endpoints, [
|
|
70
|
+
{
|
|
71
|
+
path: basePath,
|
|
72
|
+
methods: [],
|
|
73
|
+
middlewares: []
|
|
74
|
+
}
|
|
75
|
+
]);
|
|
76
|
+
}
|
|
74
77
|
} else {
|
|
75
78
|
endpoints = parseStack(stack, basePath, endpoints);
|
|
76
79
|
}
|
|
@@ -78,7 +81,7 @@ var parseEndpoints = /* @__PURE__ */ __name(function(app, basePath, endpoints) {
|
|
|
78
81
|
}, "parseEndpoints");
|
|
79
82
|
var addEndpoints = /* @__PURE__ */ __name(function(currentEndpoints, endpointsToAdd) {
|
|
80
83
|
endpointsToAdd.forEach((newEndpoint) => {
|
|
81
|
-
const existingEndpoint = currentEndpoints.find((
|
|
84
|
+
const existingEndpoint = currentEndpoints.find((endpoint) => endpoint.path === newEndpoint.path);
|
|
82
85
|
if (existingEndpoint !== void 0) {
|
|
83
86
|
const newMethods = newEndpoint.methods.filter((method) => !existingEndpoint.methods.includes(method));
|
|
84
87
|
existingEndpoint.methods = existingEndpoint.methods.concat(newMethods);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/express/listEndpoints.js"],"sourcesContent":["// Adapted from https://github.com/AlbertoFdzM/express-list-endpoints/blob/ed926dd5186761e7b721ad20938ce6eb52d104d3/src/index.js\n\nconst regExpToParseExpressPathRegExp =\n /^\\/\\^\\\\\\/(?:(:?[\\w\\\\.-]*(?:\\\\\\/:?[\\w\\\\.-]*)*)|(\\(\\?:\\(\\[\\^\\\\\\/]\\+\\?\\)\\)))\\\\\\/.*/;\nconst regExpToReplaceExpressPathRegExpParams = /\\(\\?:\\(\\[\\^\\\\\\/]\\+\\?\\)\\)/;\nconst regexpExpressParamRegexp = /\\(\\?:\\(\\[\\^\\\\\\/]\\+\\?\\)\\)/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 */\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 {Object} 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 {Object} route Express route object to be parsed\n * @param {string} basePath The basePath the route is on\n * @return {Object[]} 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 const endpoints = paths.map((path) => {\n const completePath =\n basePath && path === \"/\" ? basePath : `${basePath}${path}`;\n\n const endpoint = {\n path: completePath,\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 {Object[]} params\n * @returns {string}\n */\nconst parseExpressPath = function (expressPathRegExp, params) {\n let expressPathRegExpExec =\n regExpToParseExpressPathRegExp.exec(expressPathRegExp);\n let parsedRegExp = expressPathRegExp.toString();\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 paramId,\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 {Object} app\n * @param {string} [basePath]\n * @param {Object[]} [endpoints]\n * @returns {Object[]}\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 endpoints = addEndpoints(endpoints, [\n {\n path: basePath,\n methods: [],\n middlewares: [],\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 {Object[]} currentEndpoints Array of current endpoints\n * @param {Object[]} endpointsToAdd New endpoints to be added to the array\n * @returns {Object[]} Updated endpoints array\n */\nconst addEndpoints = function (currentEndpoints, endpointsToAdd) {\n endpointsToAdd.forEach((newEndpoint) => {\n const existingEndpoint = currentEndpoints.find(\n (item) => item.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 {Object} stack\n * @param {string} basePath\n * @param {Object[]} endpoints\n * @returns {Object[]}\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\nconst getEndpoints = function (app) {\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: route.path,\n })),\n );\n};\n\nexport default getEndpoints;\n"],"mappings":";;;;AAEA,IAAMA,iCACJ;AACF,IAAMC,yCAAyC;AAC/C,IAAMC,2BAA2B;AAEjC,IAAMC,iCAAiC;AACvC,IAAMC,yBAAyB;EAAC;EAAU;EAAkB;;AAK5D,IAAMC,kBAAkB,gCAAUC,OAAK;AACrC,MAAIC,UAAUC,OAAOC,KAAKH,MAAMC,OAAO;AAEvCA,YAAUA,QAAQG,OAAO,CAACC,WAAWA,WAAW,MAAA;AAChDJ,YAAUA,QAAQK,IAAI,CAACD,WAAWA,OAAOE,YAAW,CAAA;AAEpD,SAAON;AACT,GAPwB;AAexB,IAAMO,sBAAsB,gCAAUR,OAAK;AACzC,SAAOA,MAAMS,MAAMH,IAAI,CAACI,SAAAA;AACtB,WAAOA,KAAKC,OAAOC,QAAQ;EAC7B,CAAA;AACF,GAJ4B;AAW5B,IAAMC,YAAY,gCAAUC,mBAAiB;AAC3C,SAAOlB,yBAAyBmB,KAAKD,iBAAAA;AACvC,GAFkB;AASlB,IAAME,oBAAoB,gCAAUhB,OAAOiB,UAAQ;AACjD,QAAMC,QAAQ,CAAA;AAEd,MAAIC,MAAMC,QAAQpB,MAAMqB,IAAI,GAAG;AAC7BH,UAAMI,KAAI,GAAItB,MAAMqB,IAAI;EAC1B,OAAO;AACLH,UAAMI,KAAKtB,MAAMqB,IAAI;EACvB;AAEA,QAAME,YAAYL,MAAMZ,IAAI,CAACe,SAAAA;AAC3B,UAAMG,eACJP,YAAYI,SAAS,MAAMJ,WAAW,GAAGA,QAAAA,GAAWI,IAAAA;AAEtD,UAAMI,WAAW;MACfJ,MAAMG;MACNvB,SAASF,gBAAgBC,KAAAA;MACzB0B,aAAalB,oBAAoBR,KAAAA;IACnC;AAEA,WAAOyB;EACT,CAAA;AAEA,SAAOF;AACT,GAvB0B;AA8B1B,IAAMI,mBAAmB,gCAAUb,mBAAmBc,QAAM;AAC1D,MAAIC,wBACFnC,+BAA+BoC,KAAKhB,iBAAAA;AACtC,MAAIiB,eAAejB,kBAAkBkB,SAAQ;AAC7C,MAAIC,aAAa;AAEjB,SAAOpB,UAAUkB,YAAAA,GAAe;AAC9B,UAAMG,YAAYN,OAAOK,UAAAA,EAAYrB;AACrC,UAAMuB,UAAU,IAAID,SAAAA;AAEpBH,mBAAeA,aAAaK,QAC1BzC,wCACAwC,OAAAA;AAGFF;EACF;AAEA,MAAIF,iBAAiBjB,kBAAkBkB,SAAQ,GAAI;AACjDH,4BAAwBnC,+BAA+BoC,KAAKC,YAAAA;EAC9D;AAEA,QAAMM,aAAaR,sBAAsB,CAAA,EAAGO,QAAQ,SAAS,GAAA;AAE7D,SAAOC;AACT,GAzByB;AAiCzB,IAAMC,iBAAiB,gCAAUC,KAAKtB,UAAUM,WAAS;AACvD,QAAMd,QAAQ8B,IAAI9B,SAAU8B,IAAIC,WAAWD,IAAIC,QAAQ/B;AAEvDc,cAAYA,aAAa,CAAA;AACzBN,aAAWA,YAAY;AAEvB,MAAI,CAACR,OAAO;AACVc,gBAAYkB,aAAalB,WAAW;MAClC;QACEF,MAAMJ;QACNhB,SAAS,CAAA;QACTyB,aAAa,CAAA;MACf;KACD;EACH,OAAO;AACLH,gBAAYmB,WAAWjC,OAAOQ,UAAUM,SAAAA;EAC1C;AAEA,SAAOA;AACT,GAnBuB;AA8BvB,IAAMkB,eAAe,gCAAUE,kBAAkBC,gBAAc;AAC7DA,iBAAeC,QAAQ,CAACC,gBAAAA;AACtB,UAAMC,mBAAmBJ,iBAAiBK,KACxC,CAACtC,SAASA,KAAKW,SAASyB,YAAYzB,IAAI;AAG1C,QAAI0B,qBAAqBE,QAAW;AAClC,YAAMC,aAAaJ,YAAY7C,QAAQG,OACrC,CAACC,WAAW,CAAC0C,iBAAiB9C,QAAQkD,SAAS9C,MAAAA,CAAAA;AAGjD0C,uBAAiB9C,UAAU8C,iBAAiB9C,QAAQmD,OAAOF,UAAAA;IAC7D,OAAO;AACLP,uBAAiBrB,KAAKwB,WAAAA;IACxB;EACF,CAAA;AAEA,SAAOH;AACT,GAlBqB;AA0BrB,IAAMD,aAAa,gCAAUjC,OAAOQ,UAAUM,WAAS;AACrDd,QAAMoC,QAAQ,CAACQ,cAAAA;AACb,QAAIA,UAAUrD,OAAO;AACnB,YAAMsD,eAAetC,kBAAkBqC,UAAUrD,OAAOiB,QAAAA;AAExDM,kBAAYkB,aAAalB,WAAW+B,YAAAA;IACtC,WAAWxD,uBAAuBqD,SAASE,UAAUzC,IAAI,GAAG;AAC1D,YAAM2C,sBAAsB7D,+BAA+BqB,KACzDsC,UAAUG,MAAM;AAGlB,UAAIC,cAAcxC;AAElB,UAAIsC,qBAAqB;AACvB,cAAMlB,aAAaV,iBAAiB0B,UAAUG,QAAQH,UAAUlD,IAAI;AAEpEsD,uBAAe,IAAIpB,UAAAA;MACrB,WACE,CAACgB,UAAUhC,QACXgC,UAAUG,UACVH,UAAUG,OAAOxB,SAAQ,MAAOnC,gCAChC;AACA,cAAM6D,aAAa,WAAWL,UAAUG,MAAM;AAE9CC,uBAAe,IAAIC,UAAAA;MACrB;AAEAnC,kBAAYe,eAAee,UAAU1C,QAAQ8C,aAAalC,SAAAA;IAC5D;EACF,CAAA;AAEA,SAAOA;AACT,GAhCmB;AAkCnB,IAAMoC,eAAe,gCAAUpB,KAAG;AAChC,QAAMhB,YAAYe,eAAeC,GAAAA;AACjC,SAAOhB,UAAUqC,QAAQ,CAAC5D,UACxBA,MAAMC,QACHG,OAAO,CAACC,WAAW,CAAC;IAAC;IAAQ;IAAW8C,SAAS9C,OAAOE,YAAW,CAAA,CAAA,EACnED,IAAI,CAACD,YAAY;IAChBA;IACAgB,MAAMrB,MAAMqB;EACd,EAAA,CAAA;AAEN,GAVqB;AAYrB,IAAA,wBAAesC;","names":["regExpToParseExpressPathRegExp","regExpToReplaceExpressPathRegExpParams","regexpExpressParamRegexp","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","middlewares","parseExpressPath","params","expressPathRegExpExec","exec","parsedRegExp","toString","paramIndex","paramName","paramId","replace","parsedPath","parseEndpoints","app","_router","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/listEndpoints.js"],"sourcesContent":["// Adapted from https://github.com/AlbertoFdzM/express-list-endpoints/blob/305535d43008b46f34e18b01947762e039af6d2d/src/index.js\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 */\nconst 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 paramId,\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\nconst getEndpoints = function (app) {\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: route.path,\n })),\n );\n};\n\nexport default getEndpoints;\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","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"]}
|
|
@@ -42,6 +42,62 @@ var import_perf_hooks = require("perf_hooks");
|
|
|
42
42
|
var import_crypto3 = require("crypto");
|
|
43
43
|
var import_fetch_retry = __toESM(require("fetch-retry"), 1);
|
|
44
44
|
|
|
45
|
+
// src/common/consumerRegistry.ts
|
|
46
|
+
var consumerFromStringOrObject = /* @__PURE__ */ __name((consumer) => {
|
|
47
|
+
var _a2, _b;
|
|
48
|
+
if (typeof consumer === "string") {
|
|
49
|
+
consumer = String(consumer).trim().substring(0, 128);
|
|
50
|
+
return consumer ? {
|
|
51
|
+
identifier: consumer
|
|
52
|
+
} : null;
|
|
53
|
+
} else {
|
|
54
|
+
consumer.identifier = String(consumer.identifier).trim().substring(0, 128);
|
|
55
|
+
consumer.name = (_a2 = consumer.name) == null ? void 0 : _a2.trim().substring(0, 64);
|
|
56
|
+
consumer.group = (_b = consumer.group) == null ? void 0 : _b.trim().substring(0, 64);
|
|
57
|
+
return consumer.identifier ? consumer : null;
|
|
58
|
+
}
|
|
59
|
+
}, "consumerFromStringOrObject");
|
|
60
|
+
var _ConsumerRegistry = class _ConsumerRegistry {
|
|
61
|
+
consumers;
|
|
62
|
+
updated;
|
|
63
|
+
constructor() {
|
|
64
|
+
this.consumers = /* @__PURE__ */ new Map();
|
|
65
|
+
this.updated = /* @__PURE__ */ new Set();
|
|
66
|
+
}
|
|
67
|
+
addOrUpdateConsumer(consumer) {
|
|
68
|
+
if (!consumer || !consumer.name && !consumer.group) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const existing = this.consumers.get(consumer.identifier);
|
|
72
|
+
if (!existing) {
|
|
73
|
+
this.consumers.set(consumer.identifier, consumer);
|
|
74
|
+
this.updated.add(consumer.identifier);
|
|
75
|
+
} else {
|
|
76
|
+
if (consumer.name && consumer.name !== existing.name) {
|
|
77
|
+
existing.name = consumer.name;
|
|
78
|
+
this.updated.add(consumer.identifier);
|
|
79
|
+
}
|
|
80
|
+
if (consumer.group && consumer.group !== existing.group) {
|
|
81
|
+
existing.group = consumer.group;
|
|
82
|
+
this.updated.add(consumer.identifier);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
getAndResetUpdatedConsumers() {
|
|
87
|
+
const data = [];
|
|
88
|
+
this.updated.forEach((identifier) => {
|
|
89
|
+
const consumer = this.consumers.get(identifier);
|
|
90
|
+
if (consumer) {
|
|
91
|
+
data.push(consumer);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
this.updated.clear();
|
|
95
|
+
return data;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
__name(_ConsumerRegistry, "ConsumerRegistry");
|
|
99
|
+
var ConsumerRegistry = _ConsumerRegistry;
|
|
100
|
+
|
|
45
101
|
// src/common/logging.ts
|
|
46
102
|
var import_winston = require("winston");
|
|
47
103
|
var getLogger = /* @__PURE__ */ __name(() => {
|
|
@@ -319,13 +375,14 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
319
375
|
clientId;
|
|
320
376
|
env;
|
|
321
377
|
instanceUuid;
|
|
322
|
-
|
|
378
|
+
syncDataQueue;
|
|
323
379
|
syncIntervalId;
|
|
324
|
-
|
|
325
|
-
|
|
380
|
+
startupData;
|
|
381
|
+
startupDataSent = false;
|
|
326
382
|
requestCounter;
|
|
327
383
|
validationErrorCounter;
|
|
328
384
|
serverErrorCounter;
|
|
385
|
+
consumerRegistry;
|
|
329
386
|
logger;
|
|
330
387
|
constructor({ clientId, env = "dev", logger }) {
|
|
331
388
|
if (_ApitallyClient.instance) {
|
|
@@ -341,10 +398,11 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
341
398
|
this.clientId = clientId;
|
|
342
399
|
this.env = env;
|
|
343
400
|
this.instanceUuid = (0, import_crypto3.randomUUID)();
|
|
344
|
-
this.
|
|
401
|
+
this.syncDataQueue = [];
|
|
345
402
|
this.requestCounter = new RequestCounter();
|
|
346
403
|
this.validationErrorCounter = new ValidationErrorCounter();
|
|
347
404
|
this.serverErrorCounter = new ServerErrorCounter();
|
|
405
|
+
this.consumerRegistry = new ConsumerRegistry();
|
|
348
406
|
this.logger = logger || getLogger();
|
|
349
407
|
this.startSync();
|
|
350
408
|
this.handleShutdown = this.handleShutdown.bind(this);
|
|
@@ -362,15 +420,15 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
362
420
|
}
|
|
363
421
|
async handleShutdown() {
|
|
364
422
|
this.stopSync();
|
|
365
|
-
await this.
|
|
423
|
+
await this.sendSyncData();
|
|
366
424
|
_ApitallyClient.instance = void 0;
|
|
367
425
|
}
|
|
368
426
|
getHubUrlPrefix() {
|
|
369
427
|
const baseURL = process.env.APITALLY_HUB_BASE_URL || "https://hub.apitally.io";
|
|
370
|
-
const version = "
|
|
428
|
+
const version = "v2";
|
|
371
429
|
return `${baseURL}/${version}/${this.clientId}/${this.env}/`;
|
|
372
430
|
}
|
|
373
|
-
async
|
|
431
|
+
async sendData(url, payload) {
|
|
374
432
|
const fetchWithRetry = (0, import_fetch_retry.default)(fetch, {
|
|
375
433
|
retries: 3,
|
|
376
434
|
retryDelay: 1e3,
|
|
@@ -409,10 +467,10 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
409
467
|
async sync() {
|
|
410
468
|
try {
|
|
411
469
|
const promises = [
|
|
412
|
-
this.
|
|
470
|
+
this.sendSyncData()
|
|
413
471
|
];
|
|
414
|
-
if (!this.
|
|
415
|
-
promises.push(this.
|
|
472
|
+
if (!this.startupDataSent) {
|
|
473
|
+
promises.push(this.sendStartupData());
|
|
416
474
|
}
|
|
417
475
|
await Promise.all(promises);
|
|
418
476
|
} catch (error) {
|
|
@@ -427,62 +485,63 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
427
485
|
this.syncIntervalId = void 0;
|
|
428
486
|
}
|
|
429
487
|
}
|
|
430
|
-
|
|
431
|
-
this.
|
|
432
|
-
this.
|
|
433
|
-
this.
|
|
488
|
+
setStartupData(data) {
|
|
489
|
+
this.startupData = data;
|
|
490
|
+
this.startupDataSent = false;
|
|
491
|
+
this.sendStartupData();
|
|
434
492
|
}
|
|
435
|
-
async
|
|
436
|
-
if (this.
|
|
437
|
-
this.logger.debug("Sending
|
|
493
|
+
async sendStartupData() {
|
|
494
|
+
if (this.startupData) {
|
|
495
|
+
this.logger.debug("Sending startup data to Apitally Hub");
|
|
438
496
|
const payload = {
|
|
439
497
|
instance_uuid: this.instanceUuid,
|
|
440
498
|
message_uuid: (0, import_crypto3.randomUUID)(),
|
|
441
|
-
...this.
|
|
499
|
+
...this.startupData
|
|
442
500
|
};
|
|
443
501
|
try {
|
|
444
|
-
await this.
|
|
445
|
-
this.
|
|
502
|
+
await this.sendData("startup", payload);
|
|
503
|
+
this.startupDataSent = true;
|
|
446
504
|
} catch (error) {
|
|
447
505
|
const handled = this.handleHubError(error);
|
|
448
506
|
if (!handled) {
|
|
449
507
|
this.logger.error(error.message);
|
|
450
|
-
this.logger.debug("Error while sending
|
|
508
|
+
this.logger.debug("Error while sending startup data to Apitally Hub (will retry)", {
|
|
451
509
|
error
|
|
452
510
|
});
|
|
453
511
|
}
|
|
454
512
|
}
|
|
455
513
|
}
|
|
456
514
|
}
|
|
457
|
-
async
|
|
458
|
-
this.logger.debug("
|
|
515
|
+
async sendSyncData() {
|
|
516
|
+
this.logger.debug("Synchronizing data with Apitally Hub");
|
|
459
517
|
const newPayload = {
|
|
460
518
|
time_offset: 0,
|
|
461
519
|
instance_uuid: this.instanceUuid,
|
|
462
520
|
message_uuid: (0, import_crypto3.randomUUID)(),
|
|
463
521
|
requests: this.requestCounter.getAndResetRequests(),
|
|
464
522
|
validation_errors: this.validationErrorCounter.getAndResetValidationErrors(),
|
|
465
|
-
server_errors: this.serverErrorCounter.getAndResetServerErrors()
|
|
523
|
+
server_errors: this.serverErrorCounter.getAndResetServerErrors(),
|
|
524
|
+
consumers: this.consumerRegistry.getAndResetUpdatedConsumers()
|
|
466
525
|
};
|
|
467
|
-
this.
|
|
526
|
+
this.syncDataQueue.push([
|
|
468
527
|
Date.now(),
|
|
469
528
|
newPayload
|
|
470
529
|
]);
|
|
471
530
|
const failedItems = [];
|
|
472
|
-
while (this.
|
|
473
|
-
const queueItem = this.
|
|
531
|
+
while (this.syncDataQueue.length > 0) {
|
|
532
|
+
const queueItem = this.syncDataQueue.shift();
|
|
474
533
|
if (queueItem) {
|
|
475
534
|
const [time, payload] = queueItem;
|
|
476
535
|
try {
|
|
477
536
|
const timeOffset = Date.now() - time;
|
|
478
537
|
if (timeOffset <= MAX_QUEUE_TIME) {
|
|
479
538
|
payload.time_offset = timeOffset / 1e3;
|
|
480
|
-
await this.
|
|
539
|
+
await this.sendData("sync", payload);
|
|
481
540
|
}
|
|
482
541
|
} catch (error) {
|
|
483
542
|
const handled = this.handleHubError(error);
|
|
484
543
|
if (!handled) {
|
|
485
|
-
this.logger.debug("Error while
|
|
544
|
+
this.logger.debug("Error while synchronizing data with Apitally Hub (will retry)", {
|
|
486
545
|
error
|
|
487
546
|
});
|
|
488
547
|
failedItems.push(queueItem);
|
|
@@ -490,7 +549,7 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
490
549
|
}
|
|
491
550
|
}
|
|
492
551
|
}
|
|
493
|
-
this.
|
|
552
|
+
this.syncDataQueue = failedItems;
|
|
494
553
|
}
|
|
495
554
|
handleHubError(error) {
|
|
496
555
|
if (error instanceof HTTPError) {
|
|
@@ -525,9 +584,10 @@ function getPackageVersion(name) {
|
|
|
525
584
|
__name(getPackageVersion, "getPackageVersion");
|
|
526
585
|
|
|
527
586
|
// src/express/listEndpoints.js
|
|
528
|
-
var regExpToParseExpressPathRegExp = /^\/\^\\\/(?:(:?[\w\\.-]*(?:\\\/:?[\w\\.-]*)*)|(\(\?:\(
|
|
529
|
-
var regExpToReplaceExpressPathRegExpParams = /\(\?:\(
|
|
530
|
-
var regexpExpressParamRegexp = /\(\?:\(
|
|
587
|
+
var regExpToParseExpressPathRegExp = /^\/\^\\\/(?:(:?[\w\\.-]*(?:\\\/:?[\w\\.-]*)*)|(\(\?:\([^)]+\)\)))\\\/.*/;
|
|
588
|
+
var regExpToReplaceExpressPathRegExpParams = /\(\?:\([^)]+\)\)/;
|
|
589
|
+
var regexpExpressParamRegexp = /\(\?:\([^)]+\)\)/g;
|
|
590
|
+
var regexpExpressPathParamRegexp = /(:[^)]+)\([^)]+\)/g;
|
|
531
591
|
var EXPRESS_ROOT_PATH_REGEXP_VALUE = "/^\\/?(?=\\/|$)/i";
|
|
532
592
|
var STACK_ITEM_VALID_NAMES = [
|
|
533
593
|
"router",
|
|
@@ -558,7 +618,7 @@ var parseExpressRoute = /* @__PURE__ */ __name(function(route, basePath) {
|
|
|
558
618
|
const endpoints = paths.map((path) => {
|
|
559
619
|
const completePath = basePath && path === "/" ? basePath : `${basePath}${path}`;
|
|
560
620
|
const endpoint = {
|
|
561
|
-
path: completePath,
|
|
621
|
+
path: completePath.replace(regexpExpressPathParamRegexp, "$1"),
|
|
562
622
|
methods: getRouteMethods(route),
|
|
563
623
|
middlewares: getRouteMiddlewares(route)
|
|
564
624
|
};
|
|
@@ -567,8 +627,8 @@ var parseExpressRoute = /* @__PURE__ */ __name(function(route, basePath) {
|
|
|
567
627
|
return endpoints;
|
|
568
628
|
}, "parseExpressRoute");
|
|
569
629
|
var parseExpressPath = /* @__PURE__ */ __name(function(expressPathRegExp, params) {
|
|
570
|
-
let expressPathRegExpExec = regExpToParseExpressPathRegExp.exec(expressPathRegExp);
|
|
571
630
|
let parsedRegExp = expressPathRegExp.toString();
|
|
631
|
+
let expressPathRegExpExec = regExpToParseExpressPathRegExp.exec(parsedRegExp);
|
|
572
632
|
let paramIndex = 0;
|
|
573
633
|
while (hasParams(parsedRegExp)) {
|
|
574
634
|
const paramName = params[paramIndex].name;
|
|
@@ -587,13 +647,15 @@ var parseEndpoints = /* @__PURE__ */ __name(function(app, basePath, endpoints) {
|
|
|
587
647
|
endpoints = endpoints || [];
|
|
588
648
|
basePath = basePath || "";
|
|
589
649
|
if (!stack) {
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
650
|
+
if (endpoints.length) {
|
|
651
|
+
endpoints = addEndpoints(endpoints, [
|
|
652
|
+
{
|
|
653
|
+
path: basePath,
|
|
654
|
+
methods: [],
|
|
655
|
+
middlewares: []
|
|
656
|
+
}
|
|
657
|
+
]);
|
|
658
|
+
}
|
|
597
659
|
} else {
|
|
598
660
|
endpoints = parseStack(stack, basePath, endpoints);
|
|
599
661
|
}
|
|
@@ -601,7 +663,7 @@ var parseEndpoints = /* @__PURE__ */ __name(function(app, basePath, endpoints) {
|
|
|
601
663
|
}, "parseEndpoints");
|
|
602
664
|
var addEndpoints = /* @__PURE__ */ __name(function(currentEndpoints, endpointsToAdd) {
|
|
603
665
|
endpointsToAdd.forEach((newEndpoint) => {
|
|
604
|
-
const existingEndpoint = currentEndpoints.find((
|
|
666
|
+
const existingEndpoint = currentEndpoints.find((endpoint) => endpoint.path === newEndpoint.path);
|
|
605
667
|
if (existingEndpoint !== void 0) {
|
|
606
668
|
const newMethods = newEndpoint.methods.filter((method) => !existingEndpoint.methods.includes(method));
|
|
607
669
|
existingEndpoint.methods = existingEndpoint.methods.concat(newMethods);
|
|
@@ -649,7 +711,7 @@ var useApitally = /* @__PURE__ */ __name((app, config) => {
|
|
|
649
711
|
const middleware = getMiddleware(app, client);
|
|
650
712
|
app.use(middleware);
|
|
651
713
|
setTimeout(() => {
|
|
652
|
-
client.
|
|
714
|
+
client.setStartupData(getAppInfo(app, config.appVersion));
|
|
653
715
|
}, 1e3);
|
|
654
716
|
}, "useApitally");
|
|
655
717
|
var getMiddleware = /* @__PURE__ */ __name((app, client) => {
|
|
@@ -678,8 +740,9 @@ var getMiddleware = /* @__PURE__ */ __name((app, client) => {
|
|
|
678
740
|
if (req.route) {
|
|
679
741
|
const responseTime = import_perf_hooks.performance.now() - startTime;
|
|
680
742
|
const consumer = getConsumer(req);
|
|
743
|
+
client.consumerRegistry.addOrUpdateConsumer(consumer);
|
|
681
744
|
client.requestCounter.addRequest({
|
|
682
|
-
consumer,
|
|
745
|
+
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
683
746
|
method: req.method,
|
|
684
747
|
path: req.route.path,
|
|
685
748
|
statusCode: res.statusCode,
|
|
@@ -700,7 +763,7 @@ var getMiddleware = /* @__PURE__ */ __name((app, client) => {
|
|
|
700
763
|
}
|
|
701
764
|
validationErrors.forEach((error) => {
|
|
702
765
|
client.validationErrorCounter.addValidationError({
|
|
703
|
-
consumer,
|
|
766
|
+
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
704
767
|
method: req.method,
|
|
705
768
|
path: req.route.path,
|
|
706
769
|
...error
|
|
@@ -710,7 +773,7 @@ var getMiddleware = /* @__PURE__ */ __name((app, client) => {
|
|
|
710
773
|
if (res.statusCode === 500 && res.locals.serverError) {
|
|
711
774
|
const serverError = res.locals.serverError;
|
|
712
775
|
client.serverErrorCounter.addServerError({
|
|
713
|
-
consumer,
|
|
776
|
+
consumer: consumer == null ? void 0 : consumer.identifier,
|
|
714
777
|
method: req.method,
|
|
715
778
|
path: req.route.path,
|
|
716
779
|
type: serverError.name,
|
|
@@ -740,9 +803,10 @@ var getMiddleware = /* @__PURE__ */ __name((app, client) => {
|
|
|
740
803
|
}, "getMiddleware");
|
|
741
804
|
var getConsumer = /* @__PURE__ */ __name((req) => {
|
|
742
805
|
if (req.apitallyConsumer) {
|
|
743
|
-
return
|
|
806
|
+
return consumerFromStringOrObject(req.apitallyConsumer);
|
|
744
807
|
} else if (req.consumerIdentifier) {
|
|
745
|
-
|
|
808
|
+
process.emitWarning("The consumerIdentifier property on the request object is deprecated. Use apitallyConsumer instead.", "DeprecationWarning");
|
|
809
|
+
return consumerFromStringOrObject(req.consumerIdentifier);
|
|
746
810
|
}
|
|
747
811
|
return null;
|
|
748
812
|
}, "getConsumer");
|