Skip to content

Commit

Permalink
move utility
Browse files Browse the repository at this point in the history
Signed-off-by: Utkarsh Srivastava <[email protected]>
  • Loading branch information
tangledbytes committed Jun 26, 2021
1 parent da22eff commit cb004b5
Show file tree
Hide file tree
Showing 10 changed files with 359 additions and 173 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@

# Dependency directories (remove the comment below to include it)
# vendor/
node_modules

*.yaml
openapi-jsonschema*

150 changes: 0 additions & 150 deletions .golangci.yml

This file was deleted.

28 changes: 7 additions & 21 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,24 +1,10 @@
check:
golangci-lint run
make: linux darwin windows

check-clean-cache:
golangci-lint cache clean
darwin:
nexe index.js -t darwin-x64 -o kubeopenapi-jsonschema-darwin

protoc-setup:
wget -P meshes https://raw.githubusercontent.com/layer5io/meshery/master/meshes/meshops.proto
linux:
nexe index.js -t linux-x64 -o kubeopenapi-jsonschema

proto:
protoc -I meshes/ meshes/meshops.proto --go_out=plugins=grpc:./meshes/





site:
$(jekyll) serve --drafts --livereload

build:
$(jekyll) build --drafts

docker:
docker run --name site -d --rm -p 4000:4000 -v `pwd`:"/srv/jekyll" jekyll/jekyll:4.0.0 bash -c "bundle install; jekyll serve --drafts --livereload"
windows:
nexe index.js -t windows-x64 -o kubeopenapi-jsonschema
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# layer5-repo-template
This repository is used as the boilerplate for consistency across all Layer5 repos.
# KubeOpenAPI - JSON Schema

This is a very basic node based CLI for converting OpenAPI schema to JSON Schema Draft 4


```
Usage: openapi-jsonschema [options]
Options:
-t, --type [type] set type of input, can be either yaml or json (default: "yaml")
-l, --location <location> location of the schema
-f, --filter [query] give a query if a OpenAPISchema is nested
--kubernetes enable kubernetes specific filters (default: false)
-o [output-format] output format (default: "json")
--o-filter [output-filter] output filter query
--silent skip output (default: false)
-h, --help display help for command
```

## Example

Download the binaries from the github releases. Only linux-x64, darwin-x64 and windows-x64 binaries are released

```bash
openapi-jsonschema --location ./istio.yaml -t yaml --filter '$[?(@.kind=="CustomResourceDefinition" && @.spec.names.kind=="EnvoyFilter")]..validation.openAPIV3Schema.properties.spec' -o yaml --o-filter '$[0]'
```

<div>&nbsp;</div>

Expand Down
14 changes: 14 additions & 0 deletions helper/createQuery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* CreateQuery generates a jsonpath based query
* @param {string} query jsonpath query
* @param {boolean} isKubernetes is the query to be generated for K8s CRD
* @returns {string} generated query
*/
function CreateQuery(query = "", isKubernetes = true) {
if (isKubernetes || !query)
return `$[?(@.kind=="CustomResourceDefinition")]..validation.openAPIV3Schema`;

return query;
}

module.exports = CreateQuery;
18 changes: 18 additions & 0 deletions helper/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const { dump } = require("js-yaml");
const jp = require("jsonpath");

/**
* Output takes in the data that needs to be printed and
* an output format
* @param {*} 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));
}

module.exports = Output;
87 changes: 87 additions & 0 deletions helper/toJSONSchema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// @ts-check
const toJSONSchema = require("@openapi-contrib/openapi-schema-to-json-schema");
const yaml = require("js-yaml");
const { readFileSync, writeFileSync } = require("fs");
const { tmpdir } = require("os");
const path = require("path");
const jp = require("jsonpath");

/**
* convertAllSchemasToJSONSchema takes in the OpenAPIV3 Schemas in an array
* and return an array of an equivalent JSON Schema Draft 4 schemas
* @param {any[]} schemas array of schemas in JSON format
* @returns {any[]} JSON Schema draft 4 formatted schemas
*/
function convertAllSchemasToJSONSchema(schemas) {
if (Array.isArray(schemas))
return schemas.map((schema) => toJSONSchema(schema));

return [];
}

/**
* 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
* @param {string} location
* @param {string} query jsonpath based query
* @returns {any[]}
*/
function readSchema(location, query) {
const data = readFileSync(location, "utf-8");
const parsed = JSON.parse(data);

return jp.query(parsed, query);
}

/**
* setupFiles takes the location of the files and convert them into json
* and return the new location
* @param {string} location
* @param {"yaml" | "json"} type
* @returns {string} location of the schema files
*/
function setupFiles(location, type) {
if (type === "json") return location;

if (type === "yaml") {
try {
// Create a file name
const filename = `ucnv-${Math.random().toString(36).substr(2, 5)}.json`;

// Create destination path
const dest = path.join(tmpdir(), filename);

// Read file into memory and convert into json
const doc = yaml.loadAll(readFileSync(location, "utf-8"));

// Write the converted file to the disk
writeFileSync(dest, JSON.stringify(doc));

return dest;
} catch (error) {
return "";
}
}
}

/**
* ToJSONSchema will convert he OpenAPIV3 based schema to JSONSchema Draft 4 schemas
* @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
*/
function ToJSONSchema(location, type = "yaml", query = "") {
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);

return convertAllSchemasToJSONSchema(schemas);
}

module.exports = ToJSONSchema;
33 changes: 33 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// @ts-check
const { program } = require("commander");
const CreateQuery = require("./helper/createQuery");
const Output = require("./helper/output");
const ToJSONSchema = require("./helper/toJSONSchema");

program
.option(
"-t, --type [type]",
"set type of input, can be either yaml or json",
"yaml"
)
.option("-l, --location <location>", "location of the schema")
.option("-f, --filter [query]", "give a query if a OpenAPISchema is nested")
.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);

program.parse(process.argv);

const options = program.opts();

Output(
ToJSONSchema(
options.location,
options.type,
CreateQuery(options.filter, options.kubernetes)
),
options.o,
options.oFilter,
options.silent
);
Loading

0 comments on commit cb004b5

Please sign in to comment.