Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions compiler-rs/Cargo.lock

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

3 changes: 3 additions & 0 deletions compiler-rs/clients_schema_to_openapi/.spectral.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ rules:
oas3-api-servers: off # OpenAPI "servers" must be present and non-empty array.
info-contact: off # Info object must have "contact" object.
info-description: off # Info "description" must be present and non-empty string.
operation-description: off # Info "description" must be present and non-empty string.
operation-tag-defined: off # Operation tags must be defined in global tags.

# oas3-valid-media-example: off
3,141 changes: 2,277 additions & 864 deletions compiler-rs/clients_schema_to_openapi/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion compiler-rs/clients_schema_to_openapi/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"@stoplight/spectral-cli": "^6.10.1",
"@stoplight/spectral-cli": "^6.14.3",
"json-diff": "^1.0.6"
}
}
8 changes: 6 additions & 2 deletions compiler-rs/clients_schema_to_openapi/src/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ use openapiv3::{Components, Parameter, ReferenceOr, RequestBody, Response, Schem
use crate::utils::SchemaName;

// Separator used to combine parts of a component path.
// See https://github.com/elastic/elasticsearch-specification/issues/4183
pub const SEPARATOR: char = ':';
// OpenAPI says `$ref` must comply with RFC 3968 (escaping reserved chars),
// but also restricts the keys in `components` to match `^[a-zA-Z0-9\.\-_]+$`.
//
// See https://spec.openapis.org/oas/v3.1.1.html#reference-object
// and https://spec.openapis.org/oas/v3.1.1.html#fixed-fields-5
pub const SEPARATOR: char = '-';

pub struct TypesAndComponents<'a> {
pub model: &'a clients_schema::IndexedModel,
Expand Down
50 changes: 35 additions & 15 deletions compiler-rs/clients_schema_to_openapi/src/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ use openapiv3::{
RequestBody, Response, Responses, StatusCode, Example
};
use clients_schema::SchemaExample;
use serde_json::json;

use crate::components::TypesAndComponents;

Expand All @@ -40,12 +39,12 @@ pub fn add_endpoint(
out: &mut Paths,
) -> anyhow::Result<()> {
if endpoint.request.is_none() {
tracing::warn!("Endpoint {} is missing a request -- ignored", &endpoint.name);
// tracing::warn!("Endpoint {} is missing a request -- ignored", &endpoint.name);
return Ok(());
}

if endpoint.response.is_none() {
tracing::warn!("Endpoint {} is missing a response -- ignored", &endpoint.name);
// tracing::warn!("Endpoint {} is missing a response -- ignored", &endpoint.name);
return Ok(());
}

Expand Down Expand Up @@ -122,28 +121,48 @@ pub fn add_endpoint(
// This function converts the IndexMap<String, SchemaExample> examples of
// schema.json to IndexMap<String, ReferenceOr<Example>> which is the format
// that OpenAPI expects.
fn get_openapi_examples(schema_examples: IndexMap<String, SchemaExample>) -> IndexMap<String, ReferenceOr<Example>> {
fn get_openapi_examples(schema_examples: &IndexMap<String, SchemaExample>) -> IndexMap<String, ReferenceOr<Example>> {
let mut openapi_examples = indexmap! {};
for (name, schema_example) in schema_examples {
let example = match &schema_example.value {
None => None,
// Examples should be objects - https://spec.openapis.org/oas/v3.1.1.html#example-object
// Disabled for now, as some examples use multi-line json as in the Kibana console.
Some(text) => Some(serde_json::Value::String(text.clone())),
// Some(text) => {
// match serde_json::from_str::<serde_json::Value>(&text) {
// Ok(json) => {
// Some(json)
// }
// // Cannot parse json: assume it's text (e.g. cat requests)
// // but should be validated by looking at the media-type
// Err(err) => {
// tracing::warn!("Cannot parse example: {}\n{}", err, text);
// Some(serde_json::Value::String(text.clone()))
// }
// }
// }
};

let openapi_example = Example {
value: Some(json!(schema_example.value)),
value: example,
description: schema_example.description.clone(),
summary: schema_example.summary.clone(),
external_value: None,
extensions: Default::default(),
};
openapi_examples.insert(name.clone(), ReferenceOr::Item(openapi_example));
}
return openapi_examples;
openapi_examples
}


let mut request_examples: IndexMap<String, ReferenceOr<Example>> = indexmap! {};
// If this endpoint request has examples in schema.json, convert them to the
// OpenAPI format and add them to the endpoint request in the OpenAPI document.
if request.examples.is_some() {
request_examples = get_openapi_examples(request.examples.as_ref().unwrap().clone());
}
let request_examples = if let Some(examples) = &request.examples {
get_openapi_examples(examples)
} else {
IndexMap::new()
};

let request_body = tac.convert_request(request)?.map(|schema| {
let media = MediaType {
Expand Down Expand Up @@ -176,12 +195,13 @@ pub fn add_endpoint(
// FIXME: buggy for responses with no body
// TODO: handle binary responses
let response_def = tac.model.get_response(endpoint.response.as_ref().unwrap())?;
let mut response_examples: IndexMap<String, ReferenceOr<Example>> = indexmap! {};
// If this endpoint response has examples in schema.json, convert them to the
// OpenAPI format and add them to the endpoint response in the OpenAPI document.
if response_def.examples.is_some() {
response_examples = get_openapi_examples(response_def.examples.as_ref().unwrap().clone());
}
let response_examples = if let Some(examples) = &response_def.examples {
get_openapi_examples(examples)
} else {
IndexMap::new()
};
let response = Response {
description: "".to_string(),
headers: Default::default(),
Expand Down
6 changes: 4 additions & 2 deletions compiler-rs/clients_schema_to_openapi/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,15 @@ pub trait SchemaName {
}

impl SchemaName for TypeName {
// Use '.' as the separator: names and paths must be RFC 3986 compliant,
// and ':' output by `TypeName.toString()` is a reserved character.
fn schema_name(&self) -> String {
format!("{}", self)
format!("{}.{}", self.namespace, self.name)
}

fn schema_ref(&self) -> ReferenceOr<Schema> {
ReferenceOr::Reference {
reference: format!("#/components/schemas/{}", self),
reference: format!("#/components/schemas/{}.{}", self.namespace, self.name),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler-rs/compiler-wasm-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ serde_json = { workspace = true }
anyhow = { workspace = true }

console_error_panic_hook = { workspace = true, optional = true }
tracing-wasm = "0.2.1"

[dev-dependencies]
wasm-bindgen-test = { workspace = true }
Expand Down
61 changes: 57 additions & 4 deletions compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,68 @@ module.exports.convert_schema_to_openapi = function(json, flavor) {
}
};

function handleError(f, args) {
try {
return f.apply(this, args);
} catch (e) {
wasm.__wbindgen_exn_store(addHeapObject(e));
}
}

module.exports.__wbindgen_string_new = function(arg0, arg1) {
const ret = getStringFromWasm0(arg0, arg1);
return addHeapObject(ret);
};

module.exports.__wbg_log_c9486ca5d8e2cbe8 = function(arg0, arg1) {
let deferred0_0;
let deferred0_1;
try {
deferred0_0 = arg0;
deferred0_1 = arg1;
console.log(getStringFromWasm0(arg0, arg1));
} finally {
wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
}
};

module.exports.__wbg_log_aba5996d9bde071f = function(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) {
let deferred0_0;
let deferred0_1;
try {
deferred0_0 = arg0;
deferred0_1 = arg1;
console.log(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3), getStringFromWasm0(arg4, arg5), getStringFromWasm0(arg6, arg7));
} finally {
wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
}
};

module.exports.__wbg_mark_40e050a77cc39fea = function(arg0, arg1) {
performance.mark(getStringFromWasm0(arg0, arg1));
};

module.exports.__wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};

module.exports.__wbg_measure_aa7a73f17813f708 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
let deferred0_0;
let deferred0_1;
let deferred1_0;
let deferred1_1;
try {
deferred0_0 = arg0;
deferred0_1 = arg1;
deferred1_0 = arg2;
deferred1_1 = arg3;
performance.measure(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3));
} finally {
wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
}
}, arguments) };

module.exports.__wbg_new_abda76e883ba8a5f = function() {
const ret = new Error();
return addHeapObject(ret);
Expand All @@ -179,10 +236,6 @@ module.exports.__wbg_error_f851667af71bcfc6 = function(arg0, arg1) {
}
};

module.exports.__wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};

const path = require('path').join(__dirname, 'compiler_wasm_lib_bg.wasm');
const bytes = require('fs').readFileSync(path);

Expand Down
Binary file modified compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export function __wbindgen_add_to_stack_pointer(a: number): number;
export function __wbindgen_malloc(a: number, b: number): number;
export function __wbindgen_realloc(a: number, b: number, c: number, d: number): number;
export function __wbindgen_free(a: number, b: number, c: number): void;
export function __wbindgen_exn_store(a: number): void;
10 changes: 8 additions & 2 deletions compiler-rs/compiler-wasm-lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use clients_schema::transform::ExpandConfig;

#[wasm_bindgen]
pub fn convert_schema_to_openapi(json: &str, flavor: &str) -> Result<String, String> {
set_panic_hook();
setup_hooks();
convert0(json, flavor).map_err(|err| err.to_string())
}

Expand Down Expand Up @@ -50,7 +50,7 @@ fn convert0(json: &str, flavor: &str) -> anyhow::Result<String> {
Ok(result)
}

pub fn set_panic_hook() {
pub fn setup_hooks() {
// When the `console_error_panic_hook` feature is enabled, we can call the
// `set_panic_hook` function at least once during initialization, and then
// we will get better error messages if our code ever panics.
Expand All @@ -59,4 +59,10 @@ pub fn set_panic_hook() {
// https://github.com/rustwasm/console_error_panic_hook#readme
#[cfg(feature = "console_error_panic_hook")]
console_error_panic_hook::set_once();

use std::sync::Once;
static SET_TRACING: Once = Once::new();
SET_TRACING.call_once(|| {
tracing_wasm::set_as_global_default();
});
}
Loading
Loading