UNPKG

unmock-core

Version:

[![npm](https://img.shields.io/npm/v/unmock-core.svg)][npmjs] [![CircleCI](https://circleci.com/gh/unmock/unmock-js.svg?style=svg)](https://circleci.com/gh/unmock/unmock-js) [![codecov](https://codecov.io/gh/unmock/unmock-js/branch/dev/graph/badge.svg)](h

130 lines 5.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const debug_1 = require("debug"); const url = require("url"); const XRegExp = require("xregexp"); const util_1 = require("./util"); const debugLog = debug_1.default("unmock:matcher"); class OASMatcher { constructor({ schema }) { this.schema = schema; this.endpointToRegexMapping = OASMatcher.buildRegexpForPaths(this.schema); } static normalizeRequestPathToServerPath(reqPath, serverPathPrefix) { const pathSuffix = serverPathPrefix.endsWith("/") ? "" : "/"; const serverPathRegex = new RegExp(`^${serverPathPrefix + pathSuffix}`); return reqPath.replace(serverPathRegex, "/"); } static buildRegexpForPaths(schema) { const mapping = {}; const paths = schema.paths; if (paths === undefined || paths.length === 0) { return mapping; } Object.keys(paths).forEach((path) => { const pathParameters = util_1.getPathParametersFromPath(path); let newPath = ""; if (pathParameters.length === 0) { newPath = path; } else { const schemaParameters = util_1.getPathParametersFromSchema(paths, path); newPath = util_1.buildPathRegexStringFromParameters(path, schemaParameters, pathParameters); } const newPathRegex = XRegExp(`^${newPath}$`, "gi"); mapping[path] = newPathRegex; }); return mapping; } matchToOperationObject(sreq) { const { matches, reqPathWithoutServerPrefix } = this.matchesServer(sreq); if (!matches) { debugLog(`Could not find a matching server.`); return undefined; } if (reqPathWithoutServerPrefix === undefined) { throw new Error("Expected to get a path without the server path prefix"); } debugLog(`Matched server, looking for match for ${reqPathWithoutServerPrefix}`); const matchingPathItemOrUndef = this.findMatchingPathItem(reqPathWithoutServerPrefix); if (matchingPathItemOrUndef === undefined) { return undefined; } const requestMethod = sreq.method.toLowerCase(); debugLog(`Matched path object, looking for match for ${requestMethod}`); const matchingPath = matchingPathItemOrUndef; return matchingPath[requestMethod]; } findEndpoint(reqPath) { const paths = this.schema.paths; if (paths === undefined || paths.length === 0) { return undefined; } const servers = this.schema.servers; if (servers !== undefined && servers.length > 0) { for (const server of servers) { const serverUrl = url.parse(server.url); if (serverUrl.pathname === undefined) { throw Error(`Got undefined pathname for server URL: ${server.url}`); } const serverPathname = serverUrl.pathname; if (reqPath.startsWith(serverPathname)) { reqPath = OASMatcher.normalizeRequestPathToServerPath(reqPath, serverPathname); break; } } } const directMatch = paths[reqPath]; if (directMatch !== undefined) { debugLog(`Found direct path match for ${reqPath}`); return { schemaEndpoint: reqPath, normalizedEndpoint: reqPath }; } const definedPaths = Object.keys(paths); debugLog(`Searching for match for ${reqPath} for ${definedPaths}`); for (const pathItemKey of Object.keys(paths)) { const pathRegex = this.endpointToRegexMapping[pathItemKey]; if (XRegExp.test(reqPath, pathRegex)) { return { schemaEndpoint: pathItemKey, normalizedEndpoint: reqPath }; } } return undefined; } findMatchingPathItem(reqPath) { const maybePathItemKey = this.findEndpoint(reqPath); return maybePathItemKey !== undefined ? this.schema.paths[maybePathItemKey.schemaEndpoint] : undefined; } matchesServer(sreq) { const servers = this.schema.servers; if (servers === undefined || servers.length === 0) { debugLog("No servers to match"); return { matches: false }; } for (const server of servers) { const serverUrl = url.parse(server.url); if (serverUrl.protocol === undefined || !/^https?:$/.test(serverUrl.protocol)) { throw new Error(`Unknown protocol: ${serverUrl.protocol}`); } const protocol = serverUrl.protocol.replace(":", ""); debugLog(`Testing: ${protocol} vs. ${sreq.protocol}, ${serverUrl.hostname} ` + `vs ${sreq.host}, ${sreq.pathname} vs ${serverUrl.pathname}`); if (serverUrl.pathname === undefined) { throw new Error("Got undefined pathname"); } if (protocol === sreq.protocol && serverUrl.hostname === sreq.host && sreq.pathname.startsWith(serverUrl.pathname)) { const reqPathWithoutServerPrefix = OASMatcher.normalizeRequestPathToServerPath(sreq.pathname, serverUrl.pathname); return { matches: true, reqPathWithoutServerPrefix, }; } } return { matches: false }; } } exports.OASMatcher = OASMatcher; //# sourceMappingURL=matcher.js.map