Skip to content

Commit

Permalink
Log decoration - preliminary work:
Browse files Browse the repository at this point in the history
- Building out 'findOperation' class method on OAS. Enables ingestion of an log, and combines it with the existing oas spec to determine the target path
  • Loading branch information
gratcliff committed Jan 22, 2020
1 parent b490012 commit 78c1c83
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 4 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"node-status": "^1.0.0",
"oas-normalize": "1.0.0",
"open": "^7.0.0",
"path-to-regexp": "^6.1.0",
"prompt-sync": "^4.1.4",
"request": "^2.88.0",
"swagger-inline": "3.0.0",
Expand Down
6 changes: 2 additions & 4 deletions src/lib/get-user-variable.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ function getKey(user, property) {
return user[property] || null;
}

function getUserVariable(user, property, selectedApp = false) {
module.exports = function getUserVariable(user, property, selectedApp = false) {
if (user.keys) {
if (selectedApp) {
return getKey(
Expand All @@ -15,6 +15,4 @@ function getUserVariable(user, property, selectedApp = false) {
}

return getKey(user, property);
}

module.exports = getUserVariable;
};
83 changes: 83 additions & 0 deletions src/oas.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-disable max-classes-per-file */
const { pathToRegexp, match } = require('path-to-regexp');
const getPathOperation = require('./lib/get-path-operation');
const getUserVariable = require('./lib/get-user-variable');

Expand Down Expand Up @@ -101,6 +102,71 @@ function normalizedUrl(oas) {
return ensureProtocol(url);
}

function normalizePath(path) {
const curlBacketMatch = /{(.*?)}/;

return path
.split('/')
.map(p => {
const pathMatch = curlBacketMatch.exec(p);
if (pathMatch) return `:${pathMatch[1]}`;
return p;
})
.join('/');
}

function generatePathMatches(paths, pathName) {
return Object.keys(paths)
.map(path => {
const cleanedPath = normalizePath(path);
const matchStatement = match(cleanedPath, { decode: decodeURIComponent });
const matchResult = matchStatement(pathName);

return {
path,
ref: paths[path],
match: matchResult,
params: matchResult && Object.keys(matchResult.params).length ? matchResult.params : {},
};
})
.filter(p => p.match);
}

function filterPathMethods(pathMatches, targetMethod) {
const regExp = pathToRegexp(targetMethod);
return pathMatches
.map(p => {
const captures = Object.keys(p.ref).filter(r => regExp.exec(r));

if (captures.length) {
const method = captures[0];
return {
path: p.path,
ref: p.ref[method],
params: p.params,
};
}
return undefined;
})
.filter(p => p);
}

function findTargetPath(pathMatches) {
let minCount = Object.keys(pathMatches[0].params).length;
let candidate;

for (let m = 0; m < pathMatches.length; m += 1) {
const selection = pathMatches[m];
const paramCount = Object.keys(selection.params).length;
if (paramCount <= minCount) {
minCount = paramCount;
candidate = selection;
}
}

return candidate;
}

class Oas {
constructor(oas, user) {
Object.assign(this, oas);
Expand Down Expand Up @@ -128,6 +194,23 @@ class Oas {
const operation = getPathOperation(this, { swagger: { path }, api: { method } });
return new Operation(this, path, method, operation);
}

findOperation(logInput) {
const { url, method } = logInput.request.log.entries[0].request;
const { origin, pathname } = new URL(url);
const { servers, paths } = this;

const targetServer = servers.find(s => s.url === origin);
if (!targetServer) return undefined;

const annotatedPaths = generatePathMatches(paths, pathname);
if (!annotatedPaths.length) return undefined;

const includesMethod = filterPathMethods(annotatedPaths, method);
if (!includesMethod.length) return undefined;

return findTargetPath(includesMethod);
}
}

module.exports = Oas;
Expand Down

0 comments on commit 78c1c83

Please sign in to comment.