unmock-core
Version:
[][npmjs] [](https://circleci.com/gh/unmock/unmock-js) [](h
130 lines • 5.62 kB
JavaScript
;
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