Skip to content

Commit

Permalink
add support for resolving "$ref" in the CLI
Browse files Browse the repository at this point in the history
Signed-off-by: Utkarsh Srivastava <[email protected]>
  • Loading branch information
tangledbytes committed Sep 28, 2021
1 parent 445c5fc commit 3cb700a
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 15 deletions.
10 changes: 6 additions & 4 deletions helper/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ const jp = require("jsonpath");
/**
* Output takes in the data that needs to be printed and
* an output format
* @param {*} data
* @param {Promise<any>} data
* @param {"json" | "yaml"} format output format
*/
function Output(data, format = "json", filter = "$", silent = false) {
if (silent) return;

data = jp.query(data, filter);
if (format === "yaml") return console.log(dump(data));
if (format === "json") return console.log(JSON.stringify(data, null, 2));
data.then(data => {
data = jp.query(data, filter);
if (format === "yaml") return console.log(dump(data));
if (format === "json") return console.log(JSON.stringify(data, null, 2));
})
}

module.exports = Output;
44 changes: 35 additions & 9 deletions helper/toJSONSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const { readFileSync, writeFileSync } = require("fs");
const { tmpdir } = require("os");
const path = require("path");
const jp = require("jsonpath");
const { Resolver } = require("@stoplight/json-ref-resolver");

/**
* convertAllSchemasToJSONSchema takes in the OpenAPIV3 Schemas in an array
Expand All @@ -23,17 +24,39 @@ function convertAllSchemasToJSONSchema(schemas) {
* readSchema will read schema file from the given location, it expects
* the schema to be in JSON format
*
* readSchema will also apply the given jsonpath filter to the read schema
* and will return only the filtered JSONs
* readSchema will also resolve the references if a resolveQuery is passed
* @param {string} location
* @param {string} query jsonpath based query
* @returns {any[]}
* @param {string} resolveQuery jsonpath based query - must resolve to EXACTLY one match or else is ignored
* @returns {Promise<any[]>}
*/
function readSchema(location, query) {
async function readSchema(location, resolveQuery) {
const data = readFileSync(location, "utf-8");
const parsed = JSON.parse(data);

return jp.query(parsed, query);
if (resolveQuery) {
const inner = jp.query(parsed, resolveQuery);

if (inner.length !== 1) return parsed;

const resolver = new Resolver();
const resolved = await resolver.resolve(inner[0], {});

if (resolved.errors.length) console.error(resolved.errors);

return resolved.result;
}

return parsed;
}

/**
* filterSchemas takes in an array of schemas and will return an array of filtered schemas
* @param {Array<any>} schemas - OpenAPI schema in JSON format
* @param {string} query jsonpath based query to filter out the data
* @returns {Array<any>}
*/
function filterSchemas(schemas, query) {
return jp.query(schemas, query);
}

/**
Expand Down Expand Up @@ -72,16 +95,19 @@ function setupFiles(location, type) {
* @param {string} location location of the schemas in open api v3 format
* @param {"yaml" | "json"} type encoding in which the openapi schema is present
* @param {string} query jsonpath query to filter the read schemas
* @param {string} resolve jsonpath query to reach to the root of the openAPI spec
*/
function ToJSONSchema(location, type = "yaml", query = "") {
async function ToJSONSchema(location, type = "yaml", query = "", resolve = "") {
if (type !== "yaml" && type !== "json")
throw Error('invalid type received: can be either "yaml" or "json"');

const source = setupFiles(location, type);

const schemas = readSchema(source, query);
const schemas = await readSchema(source, resolve);

const filtered = filterSchemas(schemas, query);

return convertAllSchemasToJSONSchema(schemas);
return convertAllSchemasToJSONSchema(filtered);
}

module.exports = ToJSONSchema;
6 changes: 4 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ program
.option("--kubernetes", "enable kubernetes specific filters", false)
.option("-o [output-format]", "output format", "json")
.option("--o-filter [output-filter]", "output filter query")
.option("--silent", "skip output", false);
.option("--silent", "skip output", false)
.option("--resolve [resolve-filter]", "root of the OpenAPI spec to resolve the $ref", "")

program.parse(process.argv);

Expand All @@ -25,7 +26,8 @@ Output(
ToJSONSchema(
options.location,
options.type,
CreateQuery(options.filter, options.kubernetes)
CreateQuery(options.filter, options.kubernetes),
options.resolve,
),
options.o,
options.oFilter,
Expand Down
114 changes: 114 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"license": "MIT",
"dependencies": {
"@openapi-contrib/openapi-schema-to-json-schema": "^3.1.1",
"@stoplight/json-ref-resolver": "^3.1.3",
"commander": "^7.2.0",
"js-yaml": "^4.1.0",
"jsonpath": "^1.1.1"
Expand Down

0 comments on commit 3cb700a

Please sign in to comment.