UNPKG

apitally

Version:

Simple API monitoring & analytics for REST APIs built with Express, Fastify, Hono, Koa, and NestJS.

133 lines (132 loc) 5.11 kB
var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); // src/express/utils.js var regExpToParseExpressPathRegExp = /^\/\^\\?\/?(?:(:?[\w\\.-]*(?:\\\/:?[\w\\.-]*)*)|(\(\?:\\?\/?\([^)]+\)\)))\\\/.*/; var regExpToReplaceExpressPathRegExpParams = /\(\?:\\?\/?\([^)]+\)\)/; var regexpExpressParamRegexp = /\(\?:\\?\\?\/?\([^)]+\)\)/g; var regexpExpressPathParamRegexp = /(:[^)]+)\([^)]+\)/g; var EXPRESS_ROOT_PATH_REGEXP_VALUE = "/^\\/?(?=\\/|$)/i"; var STACK_ITEM_VALID_NAMES = [ "router", "bound dispatch", "mounted_app" ]; var getRouteMethods = /* @__PURE__ */ __name(function(route) { let methods = Object.keys(route.methods); methods = methods.filter((method) => method !== "_all"); methods = methods.map((method) => method.toUpperCase()); return methods; }, "getRouteMethods"); var getRouteMiddlewares = /* @__PURE__ */ __name(function(route) { return route.stack.map((item) => { return item.handle.name || "anonymous"; }); }, "getRouteMiddlewares"); var hasParams = /* @__PURE__ */ __name(function(expressPathRegExp) { return regexpExpressParamRegexp.test(expressPathRegExp); }, "hasParams"); var parseExpressRoute = /* @__PURE__ */ __name(function(route, basePath) { const paths = []; if (Array.isArray(route.path)) { paths.push(...route.path); } else { paths.push(route.path); } const endpoints = paths.map((path) => { const completePath = basePath && path === "/" ? basePath : `${basePath}${path}`; const endpoint = { path: completePath.replace(regexpExpressPathParamRegexp, "$1"), methods: getRouteMethods(route), middlewares: getRouteMiddlewares(route) }; return endpoint; }); return endpoints; }, "parseExpressRoute"); var parseExpressPath = /* @__PURE__ */ __name(function(expressPathRegExp, params) { let parsedRegExp = expressPathRegExp.toString(); let expressPathRegExpExec = regExpToParseExpressPathRegExp.exec(parsedRegExp); let paramIndex = 0; while (hasParams(parsedRegExp)) { const paramName = params[paramIndex].name; const paramId = `:${paramName}`; parsedRegExp = parsedRegExp.replace(regExpToReplaceExpressPathRegExpParams, (str) => { if (str.startsWith("(?:\\/")) { return `\\/${paramId}`; } return paramId; }); paramIndex++; } if (parsedRegExp !== expressPathRegExp.toString()) { expressPathRegExpExec = regExpToParseExpressPathRegExp.exec(parsedRegExp); } const parsedPath = expressPathRegExpExec[1].replace(/\\\//g, "/"); return parsedPath; }, "parseExpressPath"); var parseEndpoints = /* @__PURE__ */ __name(function(app, basePath, endpoints) { const stack = app.stack || app._router && app._router.stack; endpoints = endpoints || []; basePath = basePath || ""; if (!stack) { if (endpoints.length) { endpoints = addEndpoints(endpoints, [ { path: basePath, methods: [], middlewares: [] } ]); } } else { endpoints = parseStack(stack, basePath, endpoints); } return endpoints; }, "parseEndpoints"); var addEndpoints = /* @__PURE__ */ __name(function(currentEndpoints, endpointsToAdd) { endpointsToAdd.forEach((newEndpoint) => { const existingEndpoint = currentEndpoints.find((endpoint) => endpoint.path === newEndpoint.path); if (existingEndpoint !== void 0) { const newMethods = newEndpoint.methods.filter((method) => !existingEndpoint.methods.includes(method)); existingEndpoint.methods = existingEndpoint.methods.concat(newMethods); } else { currentEndpoints.push(newEndpoint); } }); return currentEndpoints; }, "addEndpoints"); var parseStack = /* @__PURE__ */ __name(function(stack, basePath, endpoints) { stack.forEach((stackItem) => { if (stackItem.route) { const newEndpoints = parseExpressRoute(stackItem.route, basePath); endpoints = addEndpoints(endpoints, newEndpoints); } else if (STACK_ITEM_VALID_NAMES.includes(stackItem.name)) { const isExpressPathRegexp = regExpToParseExpressPathRegExp.test(stackItem.regexp); let newBasePath = basePath; if (isExpressPathRegexp) { const parsedPath = parseExpressPath(stackItem.regexp, stackItem.keys); newBasePath += `/${parsedPath}`; } else if (!stackItem.path && stackItem.regexp && stackItem.regexp.toString() !== EXPRESS_ROOT_PATH_REGEXP_VALUE) { const regExpPath = ` RegExp(${stackItem.regexp}) `; newBasePath += `/${regExpPath}`; } endpoints = parseEndpoints(stackItem.handle, newBasePath, endpoints); } }); return endpoints; }, "parseStack"); var getEndpoints = /* @__PURE__ */ __name(function(app, basePath) { const endpoints = parseEndpoints(app); return endpoints.flatMap((route) => route.methods.filter((method) => ![ "HEAD", "OPTIONS" ].includes(method.toUpperCase())).map((method) => ({ method, path: (basePath + route.path).replace(/\/\//g, "/") }))); }, "getEndpoints"); export { getEndpoints, parseExpressPath }; //# sourceMappingURL=utils.js.map