Skip to content

Instantly share code, notes, and snippets.

@AlmogBaku
Last active October 17, 2021 19:39
Show Gist options
  • Save AlmogBaku/8f7e17c61cf18f0811fb353a3d52b568 to your computer and use it in GitHub Desktop.
Save AlmogBaku/8f7e17c61cf18f0811fb353a3d52b568 to your computer and use it in GitHub Desktop.
Filter OpenAPI JSON by tags

Usage

node filter.js <swagger.json> <tags,seperated,by,commas>

How does it work?

  1. Iterate over the ".paths"
  2. If has relevant tag, keep it. Otherwise, delete it
  3. For relevant paths: recursively fetch for references
  4. Recurcively look for references in the "definitions", and build a complete reference map
  5. Remove any definition which is not required by the map we built
const fs = require('fs')
const args = process.argv.slice(2)
if (args.length !== 2) {
console.error('must have 2 args: node filter.js <swagger.json> <tags,seperated,by,commas>')
return
}
let swg = JSON.parse(fs.readFileSync(args[0], 'utf8'))
let tags = args[1].split(',')
let refs = []
function findValuesHelper (obj, key, list) {
if (!obj) return list
if (obj instanceof Array) {
for (const i in obj) {
list = list.concat(findValuesHelper(obj[i], key, []))
}
return list
}
if (obj[key]) list.push(obj[key])
if (typeof obj == 'object') {
for (const child of Object.keys(obj)) {
list = list.concat(findValuesHelper(obj[child], key, []))
}
}
return list
}
function findRefs (o) {
refs = findValuesHelper(o, '$ref', [])
for (const i in refs) {
refs[i] = refs[i].replace('#/definitions/', '')
}
return refs
}
function arrayUnique (array) {
var a = array.concat()
for (var i = 0; i < a.length; ++i) {
for (var j = i + 1; j < a.length; ++j) {
if (a[i] === a[j])
a.splice(j--, 1)
}
}
return a
}
for (const [pn, p] of Object.entries(swg.paths)) {
for (const [on, o] of Object.entries(p)) {
if (!(o.tags !== undefined && o.tags.filter(t => tags.includes(t)).length > 0)) {
if (on !== 'parameters') {
delete swg.paths[pn][on]
}
continue
}
refs = arrayUnique([...refs, ...findRefs(o)])
}
const l = Object.keys(p).length
if (l === 0 || (l ===1 && p["parameters"] !== undefined)) {
delete swg.paths[pn]
}
}
function getDefsRecursive (obj, refs) {
for (const [r, o] of Object.entries(obj)) {
if (!(refs.includes(r))) {
continue
}
let oRefs = findRefs(o)
if (oRefs.length > 0) {
refs = arrayUnique([...refs, ...getDefsRecursive(obj, oRefs)])
}
}
return refs
}
refs = getDefsRecursive(swg.definitions, refs)
for (const i in swg.definitions) {
if (!refs.includes(i)) {
delete swg.definitions[i]
}
}
console.log(JSON.stringify(swg))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment