-
Notifications
You must be signed in to change notification settings - Fork 9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
116 additions
and
182 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
src/core/plugins/advanced-filter/fn/helper/extract-schemas.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* eslint-disable no-useless-escape */ | ||
|
||
import { List, Map, Set } from "immutable" | ||
|
||
const getNameMatcher = ({ fn, specSelectors }) => { | ||
const { schemaPathBaseRegex } = fn.schemaPathBase(specSelectors) | ||
return new RegExp(`(?<=${schemaPathBaseRegex}).*?(?=(?=\/)|$)`) | ||
} | ||
export const extractSchema = (schemaContainer, system) => { | ||
const nameMatcher = getNameMatcher(system) | ||
return schemaContainer | ||
.map(v => v.getIn(["schema", "$ref"], v.getIn(["schema", "items", "$ref"]))) | ||
.filter(ref => ref != null) | ||
.valueSeq() | ||
.toSet() | ||
.map(requestBodyRef => { | ||
const nameMatch = nameMatcher.exec(requestBodyRef) | ||
return nameMatch ? nameMatch[0] : nameMatch | ||
}) | ||
.filter(name => name != null) | ||
} | ||
export const extractSchemasFromOperations = (operations, system) => { | ||
const { fn, specSelectors } = system | ||
const isOAS3 = specSelectors.isOAS3() | ||
let schemaNamesForOperations = Set() | ||
operations.forEach((path) => { | ||
path.forEach(op => { | ||
schemaNamesForOperations = schemaNamesForOperations | ||
.union(fn.extractSchema(op.getIn(["requestBody", "content"], Map()), system)) | ||
.union(fn.extractSchema(op | ||
.getIn(["parameters"], List()) | ||
.filter(param => param.get("in") === "body"), system)) | ||
.union(fn.extractSchema(op | ||
.getIn(["responses"], Map()) | ||
.map(v => isOAS3 ? v.get("content") : v) | ||
.filter(content => content != null), system)) | ||
}) | ||
}) | ||
return schemaNamesForOperations | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export const extractTagsFromOperations = (operations) => { | ||
return operations | ||
.flatMap(method => method.map(op => op.get("tags"))) | ||
} |
10 changes: 10 additions & 0 deletions
10
src/core/plugins/advanced-filter/fn/helper/schema-path-base.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export const schemaPathBase = (specSelectors) => { | ||
const isOAS3 = specSelectors.isOAS3() | ||
const schemaPathBaseRegex = isOAS3 | ||
? "\\/components\\/schemas\\/" | ||
: "\\/definitions\\/" | ||
const schemaPathBase = isOAS3 | ||
? ["components", "schemas"] | ||
: ["definitions"] | ||
return { schemaPathBaseRegex, schemaPathBase } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,22 @@ | ||
import { applyMatchersToSpec } from "./apply-matchers" | ||
/* eslint-disable camelcase */ | ||
import { advancedFilterMatcher_operations } from "./matchers/operation-matcher" | ||
import { advancedFilterMatcher_operations, getMatchedOperationsSpec } from "./matchers/operation-matcher" | ||
import { advancedFilterMatcher_tags } from "./matchers/tag-matcher" | ||
import { advancedFilterMatcher_definitions } from "./matchers/definition-matcher" | ||
import { getRegularFilterExpr } from "./regular-filter-expr" | ||
import { schemaPathBase } from "./helper/schema-path-base" | ||
import { extractSchema, extractSchemasFromOperations } from "./helper/extract-schemas" | ||
import { extractTagsFromOperations } from "./helper/extract-tags" | ||
|
||
export default { | ||
advancedFilterMatcher_operations, | ||
advancedFilterMatcher_tags, | ||
advancedFilterMatcher_definitions, | ||
applyMatchersToSpec, | ||
getRegularFilterExpr, | ||
schemaPathBase, | ||
extractSchema, | ||
extractSchemasFromOperations, | ||
extractTagsFromOperations, | ||
getMatchedOperationsSpec | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 22 additions & 80 deletions
102
src/core/plugins/advanced-filter/fn/matchers/operation-matcher.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,93 +1,35 @@ | ||
import { fromJS, List, Map, Set } from "immutable" | ||
import { fromJS, Map } from "immutable" | ||
// taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping | ||
const escapeRegExp = (string) => { | ||
return string.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&") // $& means the whole matched string | ||
} | ||
/* eslint-disable camelcase */ | ||
/* eslint-disable no-useless-escape */ | ||
|
||
export const advancedFilterMatcher_operations = (spec, options, phrase, { specSelectors }) => { | ||
export const getMatchedOperationsSpec = (operationFilterPredicate, spec, options, phrase, { fn, specSelectors, getSystem }) => { | ||
const system = getSystem() | ||
const isOAS3 = specSelectors.isOAS3() | ||
const schemaPathBaseRegex = isOAS3 | ||
? "\\/components\\/schemas\\/" | ||
: "\\/definitions\\/" | ||
const schemaPathBase = isOAS3 | ||
? ["components", "schemas"] | ||
: ["definitions"] | ||
const { schemaPathBase } = fn.schemaPathBase(specSelectors) | ||
const partialSpecResult = fromJS(isOAS3 | ||
? { paths: {}, tags: [], components: { schemas: {} } } | ||
: { paths: {}, tags: [], definitions: {} }) | ||
const nameMatcher = new RegExp(`(?<=${schemaPathBaseRegex}).*?(?=(?=\/)|$)`) | ||
|
||
phrase = escapeRegExp(phrase) | ||
let expr | ||
try { | ||
expr = new RegExp( | ||
options.get("matchWholeWord") | ||
? `\\b${phrase}\\b` | ||
: phrase, | ||
!options.get("matchCase") ? "i" : "", | ||
) | ||
} catch { | ||
// TODO: add errors to state | ||
} | ||
const filteredPaths = operationFilterPredicate(spec.get("paths") || Map()) | ||
const filteredTags = fn.extractTagsFromOperations(filteredPaths) | ||
let schemaNamesForOperations = fn.extractSchemasFromOperations(filteredPaths, system) | ||
const filteredOperationSchemas = spec | ||
.getIn(schemaPathBase) | ||
.filter((schema, name) => schemaNamesForOperations.includes(name)) | ||
return partialSpecResult | ||
.set("paths", filteredPaths) | ||
.set("tags", filteredTags) | ||
.setIn(schemaPathBase, filteredOperationSchemas) | ||
} | ||
export const advancedFilterMatcher_operations = (spec, options, phrase, { getSystem }) => { | ||
const system = getSystem() | ||
const expr = system.fn.getRegularFilterExpr(options, escapeRegExp(phrase)) | ||
if (expr) { | ||
const filteredPaths = (spec.get("paths") || Map()) | ||
.filter((path, pathName) => expr.test(pathName)) | ||
const filteredTags = filteredPaths | ||
.flatMap(method => method.map(op => op.get("tags"))) | ||
let schemaNamesForOperations = Set() | ||
filteredPaths.forEach((path) => { | ||
path.forEach(op => { | ||
schemaNamesForOperations = schemaNamesForOperations | ||
.union(op | ||
.getIn(["requestBody", "content"], Map()) | ||
.map(v => v.getIn(["schema", "$ref"], v.getIn(["schema", "items", "$ref"]))) | ||
.filter(ref => ref != null) | ||
.valueSeq() | ||
.toSet() | ||
.map(requestBodyRef => { | ||
const nameMatch = nameMatcher.exec(requestBodyRef) | ||
return nameMatch ? nameMatch[0] : nameMatch | ||
}) | ||
.filter(name => name != null), | ||
) | ||
.union(op | ||
.getIn(["parameters"], List()) | ||
.filter(param => param.get("in") === "body") | ||
.map(v => v.getIn(["schema", "$ref"], v.getIn(["schema", "items", "$ref"]))) | ||
.filter(ref => ref != null) | ||
.valueSeq() | ||
.toSet() | ||
.map(requestBodyRef => { | ||
const nameMatch = nameMatcher.exec(requestBodyRef) | ||
return nameMatch ? nameMatch[0] : nameMatch | ||
}) | ||
.filter(name => name != null), | ||
) | ||
.union(op | ||
.getIn(["responses"], Map()) | ||
.map(v => isOAS3 ? v.get("content") : v) | ||
.filter(content => content != null) | ||
.map(content => content.getIn(["schema", "$ref"], content.getIn(["schema", "items", "$ref"]))) | ||
.filter(ref => ref != null) | ||
.valueSeq() | ||
.toSet() | ||
.map(requestBodyRef => { | ||
const nameMatch = nameMatcher.exec(requestBodyRef) | ||
return nameMatch ? nameMatch[0] : nameMatch | ||
}) | ||
.filter(name => name != null), | ||
) | ||
}) | ||
}) | ||
const filteredOperationSchemas = spec | ||
.getIn(schemaPathBase) | ||
.filter((schema, name) => schemaNamesForOperations.includes(name)) | ||
return partialSpecResult | ||
.set("paths", filteredPaths) | ||
.set("tags", filteredTags) | ||
.setIn(schemaPathBase, filteredOperationSchemas) | ||
return system.fn.getMatchedOperationsSpec( | ||
(ops) => ops.filter((path, pathName) => expr.test(pathName)), | ||
spec, options, phrase, system, | ||
) | ||
} | ||
return partialSpecResult | ||
} |
93 changes: 8 additions & 85 deletions
93
src/core/plugins/advanced-filter/fn/matchers/tag-matcher.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,95 +1,18 @@ | ||
import { fromJS, List, Map, Set } from "immutable" | ||
// taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping | ||
const escapeRegExp = (string) => { | ||
return string.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&") // $& means the whole matched string | ||
} | ||
/* eslint-disable camelcase */ | ||
/* eslint-disable no-useless-escape */ | ||
|
||
export const advancedFilterMatcher_tags = (spec, options, phrase, { specSelectors }) => { | ||
const isOAS3 = specSelectors.isOAS3() | ||
const schemaPathBaseRegex = isOAS3 | ||
? "\\/components\\/schemas\\/" | ||
: "\\/definitions\\/" | ||
const schemaPathBase = isOAS3 | ||
? ["components", "schemas"] | ||
: ["definitions"] | ||
const partialSpecResult = fromJS(isOAS3 | ||
? { paths: {}, tags: [], components: { schemas: {} } } | ||
: { paths: {}, tags: [], definitions: {} }) | ||
const nameMatcher = new RegExp(`(?<=${schemaPathBaseRegex}).*?(?=(?=\/)|$)`) | ||
|
||
phrase = escapeRegExp(phrase) | ||
let expr | ||
try { | ||
expr = new RegExp( | ||
options.get("matchWholeWord") | ||
? `\\b${phrase}\\b` | ||
: phrase, | ||
!options.get("matchCase") ? "i" : "", | ||
) | ||
} catch { | ||
// TODO: add errors to state | ||
} | ||
export const advancedFilterMatcher_tags = (spec, options, phrase, { getSystem }) => { | ||
const system = getSystem() | ||
const expr = system.fn.getRegularFilterExpr(options, escapeRegExp(phrase)) | ||
if (expr) { | ||
const filteredPaths = (spec.get("paths") || Map()) | ||
.map(path => path | ||
return system.fn.getMatchedOperationsSpec( | ||
(ops) => ops.map(path => path | ||
.filter(op => op.get("tags").filter(tag => expr.test(tag)).count() > 0), | ||
) | ||
.filter(method => method.count() > 0) | ||
const filteredTags = filteredPaths | ||
.flatMap(method => method.map(op => op.get("tags"))) | ||
let schemaNamesForOperations = Set() | ||
filteredPaths.forEach((path) => { | ||
path.forEach(op => { | ||
schemaNamesForOperations = schemaNamesForOperations | ||
.union(op | ||
.getIn(["requestBody", "content"], Map()) | ||
.map(v => v.getIn(["schema", "$ref"], v.getIn(["schema", "items", "$ref"]))) | ||
.valueSeq() | ||
.toSet() | ||
.map(requestBodyRef => { | ||
const nameMatch = nameMatcher.exec(requestBodyRef) | ||
return nameMatch ? nameMatch[0] : nameMatch | ||
}) | ||
.filter(name => name != null), | ||
) | ||
.union(op | ||
.getIn(["parameters"], List()) | ||
.filter(param => param.get("in") === "body") | ||
.map(v => v.getIn(["schema", "$ref"], v.getIn(["schema", "items", "$ref"]))) | ||
.filter(ref => ref != null) | ||
.valueSeq() | ||
.toSet() | ||
.map(requestBodyRef => { | ||
const nameMatch = nameMatcher.exec(requestBodyRef) | ||
return nameMatch ? nameMatch[0] : nameMatch | ||
}) | ||
.filter(name => name != null), | ||
) | ||
.union(op | ||
.getIn(["responses"], Map()) | ||
.map(v => isOAS3 ? v.get("content") : v) | ||
.filter(content => content != null) | ||
.map(content => content.getIn(["schema", "$ref"], content.getIn(["schema", "items", "$ref"]))) | ||
.filter(ref => ref != null) | ||
.valueSeq() | ||
.toSet() | ||
.map(requestBodyRef => { | ||
const nameMatch = nameMatcher.exec(requestBodyRef) | ||
return nameMatch ? nameMatch[0] : nameMatch | ||
}) | ||
.filter(name => name != null), | ||
) | ||
}) | ||
}) | ||
const filteredOperationSchemas = spec | ||
.getIn(schemaPathBase) | ||
.filter((schema, name) => schemaNamesForOperations.includes(name)) | ||
return partialSpecResult | ||
.set("paths", filteredPaths) | ||
.set("tags", filteredTags) | ||
.setIn(schemaPathBase, filteredOperationSchemas) | ||
), | ||
spec, options, phrase, system, | ||
) | ||
} | ||
return partialSpecResult | ||
} |
14 changes: 14 additions & 0 deletions
14
src/core/plugins/advanced-filter/fn/regular-filter-expr.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export const getRegularFilterExpr = (options, phrase) => { | ||
let expr | ||
try { | ||
expr = new RegExp( | ||
options.get("matchWholeWord") | ||
? `\\b${phrase}\\b` | ||
: phrase, | ||
!options.get("matchCase") ? "i" : "", | ||
) | ||
} catch { | ||
// TODO: add errors to state | ||
} | ||
return expr | ||
} |