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.
Files changed (64) hide show
  1. package/dist/common/client.cjs +75 -30
  2. package/dist/common/client.cjs.map +1 -1
  3. package/dist/common/client.d.cts +10 -8
  4. package/dist/common/client.d.ts +10 -8
  5. package/dist/common/client.js +75 -30
  6. package/dist/common/client.js.map +1 -1
  7. package/dist/common/consumerRegistry.cjs +86 -0
  8. package/dist/common/consumerRegistry.cjs.map +1 -0
  9. package/dist/common/consumerRegistry.d.cts +14 -0
  10. package/dist/common/consumerRegistry.d.ts +14 -0
  11. package/dist/common/consumerRegistry.js +63 -0
  12. package/dist/common/consumerRegistry.js.map +1 -0
  13. package/dist/common/types.cjs.map +1 -1
  14. package/dist/common/types.d.cts +12 -5
  15. package/dist/common/types.d.ts +12 -5
  16. package/dist/express/index.cjs +113 -49
  17. package/dist/express/index.cjs.map +1 -1
  18. package/dist/express/index.d.cts +2 -2
  19. package/dist/express/index.d.ts +2 -2
  20. package/dist/express/index.js +113 -49
  21. package/dist/express/index.js.map +1 -1
  22. package/dist/express/listEndpoints.cjs +16 -13
  23. package/dist/express/listEndpoints.cjs.map +1 -1
  24. package/dist/express/listEndpoints.d.cts +33 -2
  25. package/dist/express/listEndpoints.d.ts +33 -2
  26. package/dist/express/listEndpoints.js +16 -13
  27. package/dist/express/listEndpoints.js.map +1 -1
  28. package/dist/express/middleware.cjs +113 -49
  29. package/dist/express/middleware.cjs.map +1 -1
  30. package/dist/express/middleware.d.cts +5 -5
  31. package/dist/express/middleware.d.ts +5 -5
  32. package/dist/express/middleware.js +113 -49
  33. package/dist/express/middleware.js.map +1 -1
  34. package/dist/fastify/index.cjs +106 -37
  35. package/dist/fastify/index.cjs.map +1 -1
  36. package/dist/fastify/index.d.cts +2 -2
  37. package/dist/fastify/index.d.ts +2 -2
  38. package/dist/fastify/index.js +106 -37
  39. package/dist/fastify/index.js.map +1 -1
  40. package/dist/fastify/plugin.cjs +106 -37
  41. package/dist/fastify/plugin.cjs.map +1 -1
  42. package/dist/fastify/plugin.d.cts +3 -3
  43. package/dist/fastify/plugin.d.ts +3 -3
  44. package/dist/fastify/plugin.js +106 -37
  45. package/dist/fastify/plugin.js.map +1 -1
  46. package/dist/koa/index.cjs +98 -35
  47. package/dist/koa/index.cjs.map +1 -1
  48. package/dist/koa/index.d.cts +2 -2
  49. package/dist/koa/index.d.ts +2 -2
  50. package/dist/koa/index.js +98 -35
  51. package/dist/koa/index.js.map +1 -1
  52. package/dist/koa/middleware.cjs +98 -35
  53. package/dist/koa/middleware.cjs.map +1 -1
  54. package/dist/koa/middleware.d.cts +1 -1
  55. package/dist/koa/middleware.d.ts +1 -1
  56. package/dist/koa/middleware.js +98 -35
  57. package/dist/koa/middleware.js.map +1 -1
  58. package/dist/nestjs/index.cjs +113 -49
  59. package/dist/nestjs/index.cjs.map +1 -1
  60. package/dist/nestjs/index.d.cts +2 -2
  61. package/dist/nestjs/index.d.ts +2 -2
  62. package/dist/nestjs/index.js +113 -49
  63. package/dist/nestjs/index.js.map +1 -1
  64. 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 = /\(\?:\(\[\^\\\/]\+\?\)\)/g;
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
- endpoints = addEndpoints(endpoints, [
90
- {
91
- path: basePath,
92
- methods: [],
93
- middlewares: []
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((item) => item.path === newEndpoint.path);
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
- declare function getEndpoints(app: any): any[];
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
- declare function getEndpoints(app: any): any[];
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 = /\(\?:\(\[\^\\\/]\+\?\)\)/g;
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
- endpoints = addEndpoints(endpoints, [
68
- {
69
- path: basePath,
70
- methods: [],
71
- middlewares: []
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((item) => item.path === newEndpoint.path);
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":"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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"]}
@@ -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
- requestsDataQueue;
378
+ syncDataQueue;
323
379
  syncIntervalId;
324
- appInfo;
325
- appInfoSent = false;
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.requestsDataQueue = [];
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.sendRequestsData();
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 = "v1";
428
+ const version = "v2";
371
429
  return `${baseURL}/${version}/${this.clientId}/${this.env}/`;
372
430
  }
373
- async makeHubRequest(url, payload) {
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.sendRequestsData()
470
+ this.sendSyncData()
413
471
  ];
414
- if (!this.appInfoSent) {
415
- promises.push(this.sendAppInfo());
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
- setAppInfo(appInfo) {
431
- this.appInfo = appInfo;
432
- this.appInfoSent = false;
433
- this.sendAppInfo();
488
+ setStartupData(data) {
489
+ this.startupData = data;
490
+ this.startupDataSent = false;
491
+ this.sendStartupData();
434
492
  }
435
- async sendAppInfo() {
436
- if (this.appInfo) {
437
- this.logger.debug("Sending app info to Apitally Hub");
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.appInfo
499
+ ...this.startupData
442
500
  };
443
501
  try {
444
- await this.makeHubRequest("info", payload);
445
- this.appInfoSent = true;
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 app info to Apitally Hub (will retry)", {
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 sendRequestsData() {
458
- this.logger.debug("Sending requests data to Apitally Hub");
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.requestsDataQueue.push([
526
+ this.syncDataQueue.push([
468
527
  Date.now(),
469
528
  newPayload
470
529
  ]);
471
530
  const failedItems = [];
472
- while (this.requestsDataQueue.length > 0) {
473
- const queueItem = this.requestsDataQueue.shift();
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.makeHubRequest("requests", payload);
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 sending requests data to Apitally Hub (will retry)", {
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.requestsDataQueue = failedItems;
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 = /\(\?:\(\[\^\\\/]\+\?\)\)/g;
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
- endpoints = addEndpoints(endpoints, [
591
- {
592
- path: basePath,
593
- methods: [],
594
- middlewares: []
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((item) => item.path === newEndpoint.path);
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.setAppInfo(getAppInfo(app, config.appVersion));
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 String(req.apitallyConsumer);
806
+ return consumerFromStringOrObject(req.apitallyConsumer);
744
807
  } else if (req.consumerIdentifier) {
745
- return String(req.consumerIdentifier);
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");