diff --git a/.gitattributes b/.gitattributes index 26eb69c228..d00f1cfd41 100644 --- a/.gitattributes +++ b/.gitattributes @@ -234,5 +234,6 @@ dist/* binary output/** linguist-generated=true output/schema/validation-errors.json linguist-generated=false +compiler-rs/compiler-wasm-lib/pkg/* linguist-generated=true #################################################################################################### diff --git a/Makefile b/Makefile index c161a0289a..7c7f848a5a 100644 --- a/Makefile +++ b/Makefile @@ -49,10 +49,11 @@ transform-expand-generics: ## Create a new schema with all generics expanded @npm run transform-expand-generics --prefix compiler transform-to-openapi: ## Generate the OpenAPI definition from the compiled schema - @npm run transform-to-openapi --prefix compiler + @npm run transform-to-openapi -- --schema output/schema/schema.json --flavor stack --output output/openapi/elasticsearch-openapi.json + @npm run transform-to-openapi -- --schema output/schema/schema.json --flavor serverless --output output/openapi/elasticsearch-serverless-openapi.json filter-for-serverless: ## Generate the serverless version from the compiled schema - @npm run --prefix compiler filter-by-availability -- --serverless --visibility=public --input ../output/schema/schema.json --output ../output/schema/schema-serverless.json + @npm run --prefix compiler filter-by-availability -- --serverless --visibility=public --input ../output/schema/schema.json --output ../output/output/openapi/elasticsearch-serverless-openapi.json dump-routes: ## Create a new schema with all generics expanded @npm run dump-routes --prefix compiler diff --git a/compiler-rs/Cargo.lock b/compiler-rs/Cargo.lock index dba3deee8a..9ca0a2f0eb 100644 --- a/compiler-rs/Cargo.lock +++ b/compiler-rs/Cargo.lock @@ -91,6 +91,38 @@ dependencies = [ "serde", ] +[[package]] +name = "argh" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ff18325c8a36b82f992e533ece1ec9f9a9db446bd1c14d4f936bac88fcd240" +dependencies = [ + "argh_derive", + "argh_shared", + "rust-fuzzy-search", +] + +[[package]] +name = "argh_derive" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b2b83a50d329d5d8ccc620f5c7064028828538bdf5646acd60dc1f767803" +dependencies = [ + "argh_shared", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "argh_shared" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a464143cc82dedcdc3928737445362466b7674b5db4e2eb8e869846d6d84f4f6" +dependencies = [ + "serde", +] + [[package]] name = "autocfg" version = "1.4.0" @@ -192,7 +224,7 @@ dependencies = [ "anyhow", "arcstr", "clap", - "derive_more", + "derive_more 1.0.0", "indexmap", "itertools", "once_cell", @@ -208,8 +240,9 @@ name = "clients_schema_to_openapi" version = "0.1.0" dependencies = [ "anyhow", - "clap", + "argh", "clients_schema", + "derive_more 2.0.1", "icu_segmenter", "indexmap", "itertools", @@ -230,6 +263,7 @@ name = "compiler-wasm-lib" version = "0.1.0" dependencies = [ "anyhow", + "argh", "clients_schema", "clients_schema_to_openapi", "console_error_panic_hook", @@ -283,7 +317,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" dependencies = [ - "derive_more-impl", + "derive_more-impl 1.0.0", +] + +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl 2.0.1", ] [[package]] @@ -297,6 +340,17 @@ dependencies = [ "syn", ] +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -905,6 +959,12 @@ dependencies = [ "vrd 0.0.7", ] +[[package]] +name = "rust-fuzzy-search" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a157657054ffe556d8858504af8a672a054a6e0bd9e8ee531059100c0fa11bb2" + [[package]] name = "rustc-demangle" version = "0.1.24" diff --git a/compiler-rs/Cargo.toml b/compiler-rs/Cargo.toml index 294ac02bc0..7644c40d1c 100644 --- a/compiler-rs/Cargo.toml +++ b/compiler-rs/Cargo.toml @@ -10,6 +10,7 @@ members = [ [workspace.dependencies] anyhow = "1" arcstr = "1" +argh = "0.1" clap = "4" console_error_panic_hook = "0.1" convert_case = "0.6" diff --git a/compiler-rs/clients_schema_to_openapi/Cargo.toml b/compiler-rs/clients_schema_to_openapi/Cargo.toml index 7fe52636cb..727b43ef8b 100644 --- a/compiler-rs/clients_schema_to_openapi/Cargo.toml +++ b/compiler-rs/clients_schema_to_openapi/Cargo.toml @@ -7,6 +7,8 @@ publish = false [dependencies] clients_schema = {path="../clients_schema"} +argh = { workspace = true } +derive_more = { version = "2", features = ["from_str"] } serde_json = { workspace = true } itertools = { workspace = true } icu_segmenter = { workspace = true } @@ -16,5 +18,3 @@ indexmap = { workspace = true } tracing = { workspace = true } tracing-subscriber = { workspace = true } -clap = { workspace = true, features = ["derive"] } - diff --git a/compiler-rs/clients_schema_to_openapi/src/cli.rs b/compiler-rs/clients_schema_to_openapi/src/cli.rs new file mode 100644 index 0000000000..b7a53eaea7 --- /dev/null +++ b/compiler-rs/clients_schema_to_openapi/src/cli.rs @@ -0,0 +1,62 @@ +use std::path::PathBuf; +use argh::FromArgs; +use clients_schema::Flavor; +use crate::Configuration; + +/// Convert schema.json to an OpenAPI schema +#[derive(Debug, FromArgs)] +pub struct Cli { + /// schema file to transform. + #[argh(option)] + pub schema: PathBuf, + + /// output file. + #[argh(option)] + pub output: PathBuf, + + //---- Fields from lib::Configuration + + /// the flavor to generate [all, stack, serverless - default = all] + #[argh(option, default = "SchemaFlavor::All")] + pub flavor: SchemaFlavor, + + /// add enum descriptions to property descriptions [default = true] + #[argh(option, default = "true")] + pub lift_enum_descriptions: bool, + + /// generate only this namespace (can be repeated) + #[argh(option)] + pub namespace: Vec, +} + +use derive_more::FromStr; + +#[derive(Debug, Clone, PartialEq, FromStr)] +pub enum SchemaFlavor { + /// No schema filtering + All, + /// Stack (stateful) flavor + Stack, + /// Serverless flavor + Serverless, +} + +impl From for Configuration { + fn from(val: Cli) -> Configuration { + let flavor = match val.flavor { + SchemaFlavor::All => None, + SchemaFlavor::Serverless => Some(Flavor::Serverless), + SchemaFlavor::Stack => Some(Flavor::Stack), + }; + + Configuration { + flavor, + lift_enum_descriptions: val.lift_enum_descriptions, + namespaces: if val.namespace.is_empty() { + None + } else { + Some(val.namespace) + }, + } + } +} diff --git a/compiler-rs/clients_schema_to_openapi/src/lib.rs b/compiler-rs/clients_schema_to_openapi/src/lib.rs index 34bbd5cf30..3fe4bb03e1 100644 --- a/compiler-rs/clients_schema_to_openapi/src/lib.rs +++ b/compiler-rs/clients_schema_to_openapi/src/lib.rs @@ -19,6 +19,7 @@ mod components; mod paths; mod schemas; mod utils; +pub mod cli; use indexmap::IndexMap; @@ -29,18 +30,10 @@ use crate::components::TypesAndComponents; pub struct Configuration { pub flavor: Option, + pub namespaces: Option>, pub lift_enum_descriptions: bool, } -impl Default for Configuration { - fn default() -> Self { - Self { - flavor: None, - lift_enum_descriptions: true, - } - } -} - /// Convert an API model into an OpenAPI v3 schema, optionally filtered for a given flavor pub fn convert_schema(mut schema: IndexedModel, config: Configuration) -> anyhow::Result { // Expand generics @@ -105,6 +98,11 @@ pub fn convert_expanded_schema(model: &IndexedModel, config: &Configuration) -> // Endpoints for endpoint in &model.endpoints { + if let Some(namespaces) = &config.namespaces { + if !namespaces.contains(&endpoint.name) { + continue; + } + } paths::add_endpoint(endpoint, &mut tac, &mut openapi.paths)?; } diff --git a/compiler-rs/clients_schema_to_openapi/src/main.rs b/compiler-rs/clients_schema_to_openapi/src/main.rs index 2cf3193172..1df140395a 100644 --- a/compiler-rs/clients_schema_to_openapi/src/main.rs +++ b/compiler-rs/clients_schema_to_openapi/src/main.rs @@ -15,18 +15,15 @@ // specific language governing permissions and limitations // under the License. -use std::path::{Path, PathBuf}; -use anyhow::bail; - -use clap::{Parser, ValueEnum}; -use clients_schema::Flavor; +use std::fs::File; +use clients_schema::IndexedModel; use tracing::Level; use tracing_subscriber::fmt::format::FmtSpan; use tracing_subscriber::FmtSubscriber; -use clients_schema_to_openapi::Configuration; +use clients_schema_to_openapi::cli::Cli; fn main() -> anyhow::Result<()> { - let cli = Cli::parse(); + let cli: Cli = argh::from_env(); let subscriber = FmtSubscriber::builder() .with_writer(std::io::stderr) @@ -35,139 +32,9 @@ fn main() -> anyhow::Result<()> { .finish(); tracing::subscriber::set_global_default(subscriber)?; - cli.run()?; - + let schema = IndexedModel::from_reader(File::open(&cli.schema)?)?; + let output = cli.output.clone(); + let openapi = clients_schema_to_openapi::convert_schema(schema, cli.into())?; + serde_json::to_writer_pretty(File::create(&output)?, &openapi)?; Ok(()) } - -// fn main() -> anyhow::Result<()> { -// -// let subscriber = FmtSubscriber::builder() -// .with_writer(std::io::stderr) -// .with_max_level(Level::TRACE) -// .with_span_events(FmtSpan::EXIT) -// .finish(); -// tracing::subscriber::set_global_default(subscriber)?; -// -// clients_schema_to_openapi::convert_schema_file( -// "../output/schema/schema-no-generics.json", -// None, -// |e| true, -// //|e| e.name == "search", -// //|e| e.name == "clear_scroll", -// //|e| e.name.starts_with("indices."), -// //|e| e.name == "indices.exists_alias" || e.name == "indices.delete_alias", -// //|e| &e.name[0..1] < "d", -// std::fs::File::create("../output/openapi/elasticsearch-openapi.json")? -// //std::io::stdout() -// )?; -// -// Ok(()) -// } - -impl Cli { - fn run(self) -> anyhow::Result<()> { - let json = if self.schema == Path::new("-") { - std::io::read_to_string(std::io::stdin())? - } else { - std::fs::read_to_string(self.schema)? - }; - - let model: clients_schema::IndexedModel = match serde_json::from_str(&json) { - Ok(indexed_model) => indexed_model, - Err(e) => bail!("cannot parse schema json: {}", e) - }; - - let flavor = match self.flavor { - Some(SchemaFlavor::All) | None => None, - Some(SchemaFlavor::Stack) => Some(Flavor::Stack), - Some(SchemaFlavor::Serverless) => Some(Flavor::Serverless), - }; - - let config = Configuration { - flavor, - ..Default::default() - }; - - let openapi = clients_schema_to_openapi::convert_schema(model, config)?; - - let output: Box = { - if let Some(output) = self.output { - if output == Path::new("-") { - Box::new(std::io::stdout()) - } else { - Box::new(std::fs::File::create(output)?) - } - } else { - Box::new(std::io::stdout()) - } - }; - let output = std::io::BufWriter::new(output); - - serde_json::to_writer_pretty(output, &openapi)?; - - Ok(()) - } -} - -#[derive(Debug, Parser)] -#[command(author, version, about, long_about = None)] -pub struct Cli { - /// Schema file to transform. Use '-' for stdin. - schema: PathBuf, - - #[arg(short, long)] - /// Output file. Defaults to stdout. - output: Option, - - /// Elasticsearch flavor to produce - #[arg(short, long)] - flavor: Option, -} - -#[derive(Debug, Clone, PartialEq, ValueEnum)] -pub enum SchemaFlavor { - /// No schema filtering - All, - /// Stack (stateful) flavor - Stack, - /// Serverless flavor - Serverless, - // /// Common subset to Stack and Serverless - // Common, -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_full() -> anyhow::Result<()> { - Cli { - schema: "../../output/schema/schema-no-generics.json".into(), - flavor: None, - output: Some("../../output/openapi/elasticsearch-openapi.json".into()), - } - .run() - } - - #[test] - fn test_serverless() -> anyhow::Result<()> { - Cli { - schema: "../../output/schema/schema-no-generics.json".into(), - flavor: Some(SchemaFlavor::Serverless), - output: Some("../../output/openapi/elasticsearch-serverless-openapi.json".into()), - } - .run() - } - - #[test] - fn test_serverless0() -> anyhow::Result<()> { - Cli { - schema: "../../output/schema/schema.json".into(), - flavor: Some(SchemaFlavor::Serverless), - output: Some("../../output/openapi/elasticsearch-serverless-openapi2.json".into()), - } - .run() - } -} diff --git a/compiler-rs/clients_schema_to_openapi/src/paths.rs b/compiler-rs/clients_schema_to_openapi/src/paths.rs index 7172ad34ce..922ea1169c 100644 --- a/compiler-rs/clients_schema_to_openapi/src/paths.rs +++ b/compiler-rs/clients_schema_to_openapi/src/paths.rs @@ -393,7 +393,7 @@ fn split_summary_desc(desc: &str) -> SplitDesc{ let segmenter = SentenceSegmenter::new(); let breakpoints: Vec = segmenter - .segment_str(&desc) + .segment_str(desc) .collect(); if breakpoints.len()<2{ diff --git a/compiler-rs/clients_schema_to_openapi/src/schemas.rs b/compiler-rs/clients_schema_to_openapi/src/schemas.rs index d7c47fabf0..9d4ebe5b4f 100644 --- a/compiler-rs/clients_schema_to_openapi/src/schemas.rs +++ b/compiler-rs/clients_schema_to_openapi/src/schemas.rs @@ -481,7 +481,7 @@ impl<'a> TypesAndComponents<'a> { pub fn property_description(&self, prop: &Property) -> anyhow::Result> { if self.config.lift_enum_descriptions { - Ok(lift_enum_descriptions(prop, &self.model)?.or_else(|| prop.description.clone())) + Ok(lift_enum_descriptions(prop, self.model)?.or_else(|| prop.description.clone())) } else { Ok(prop.description.clone()) } diff --git a/compiler-rs/compiler-wasm-lib/Cargo.toml b/compiler-rs/compiler-wasm-lib/Cargo.toml index 3d162ddf8c..23dd68d683 100644 --- a/compiler-rs/compiler-wasm-lib/Cargo.toml +++ b/compiler-rs/compiler-wasm-lib/Cargo.toml @@ -18,6 +18,7 @@ clients_schema_to_openapi = {path="../clients_schema_to_openapi"} serde_json = { workspace = true } anyhow = { workspace = true } tracing = "0.1" +argh = { workspace = true } console_error_panic_hook = { workspace = true, optional = true } tracing-wasm = "0.2.1" diff --git a/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib.d.ts b/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib.d.ts index a6545ee4ce..f0efbe39dd 100644 --- a/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib.d.ts +++ b/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib.d.ts @@ -1,3 +1,7 @@ /* tslint:disable */ /* eslint-disable */ -export function convert_schema_to_openapi(json: string, flavor: string): string; +/** + * Convert schema.json to OpenAPI. The `cwd` argument is the current directory to be used + * if not the system-defined one, as is the case when running with `npm rum --prefix compiler` + */ +export function convert_schema_to_openapi(args: string[], cwd?: string | null): void; diff --git a/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib.js b/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib.js index 178f4dd87f..706ad37970 100644 --- a/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib.js +++ b/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib.js @@ -2,6 +2,7 @@ let imports = {}; imports['__wbindgen_placeholder__'] = module.exports; let wasm; +const { readFileSync, writeFileSync } = require(`node:fs`); const { TextDecoder, TextEncoder } = require(`util`); let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); @@ -22,9 +23,18 @@ function getStringFromWasm0(ptr, len) { return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); } -function addToExternrefTable0(obj) { - const idx = wasm.__externref_table_alloc(); - wasm.__wbindgen_export_3.set(idx, obj); +const heap = new Array(128).fill(undefined); + +heap.push(undefined, null, true, false); + +let heap_next = heap.length; + +function addHeapObject(obj) { + if (heap_next === heap.length) heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + + heap[idx] = obj; return idx; } @@ -32,8 +42,7 @@ function handleError(f, args) { try { return f.apply(this, args); } catch (e) { - const idx = addToExternrefTable0(e); - wasm.__wbindgen_exn_store(idx); + wasm.__wbindgen_exn_store(addHeapObject(e)); } } @@ -102,36 +111,54 @@ function getDataViewMemory0() { return cachedDataViewMemory0; } -function takeFromExternrefTable0(idx) { - const value = wasm.__wbindgen_export_3.get(idx); - wasm.__externref_table_dealloc(idx); - return value; +function getObject(idx) { return heap[idx]; } + +function dropObject(idx) { + if (idx < 132) return; + heap[idx] = heap_next; + heap_next = idx; +} + +function takeObject(idx) { + const ret = getObject(idx); + dropObject(idx); + return ret; +} + +function isLikeNone(x) { + return x === undefined || x === null; +} + +function passArrayJsValueToWasm0(array, malloc) { + const ptr = malloc(array.length * 4, 4) >>> 0; + const mem = getDataViewMemory0(); + for (let i = 0; i < array.length; i++) { + mem.setUint32(ptr + 4 * i, addHeapObject(array[i]), true); + } + WASM_VECTOR_LEN = array.length; + return ptr; } /** - * @param {string} json - * @param {string} flavor - * @returns {string} + * Convert schema.json to OpenAPI. The `cwd` argument is the current directory to be used + * if not the system-defined one, as is the case when running with `npm rum --prefix compiler` + * @param {string[]} args + * @param {string | null} [cwd] */ -module.exports.convert_schema_to_openapi = function(json, flavor) { - let deferred4_0; - let deferred4_1; +module.exports.convert_schema_to_openapi = function(args, cwd) { try { - const ptr0 = passStringToWasm0(json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArrayJsValueToWasm0(args, wasm.__wbindgen_malloc); const len0 = WASM_VECTOR_LEN; - const ptr1 = passStringToWasm0(flavor, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len1 = WASM_VECTOR_LEN; - const ret = wasm.convert_schema_to_openapi(ptr0, len0, ptr1, len1); - var ptr3 = ret[0]; - var len3 = ret[1]; - if (ret[3]) { - ptr3 = 0; len3 = 0; - throw takeFromExternrefTable0(ret[2]); + var ptr1 = isLikeNone(cwd) ? 0 : passStringToWasm0(cwd, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len1 = WASM_VECTOR_LEN; + wasm.convert_schema_to_openapi(retptr, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + if (r1) { + throw takeObject(r0); } - deferred4_0 = ptr3; - deferred4_1 = len3; - return getStringFromWasm0(ptr3, len3); } finally { - wasm.__wbindgen_free(deferred4_0, deferred4_1, 1); + wasm.__wbindgen_add_to_stack_pointer(16); } }; @@ -194,31 +221,49 @@ module.exports.__wbg_measure_fb7825c11612c823 = function() { return handleError( module.exports.__wbg_new_8a6f238a6ece86ea = function() { const ret = new Error(); - return ret; + return addHeapObject(ret); +}; + +module.exports.__wbg_readFileSync_691af69453e7d4ec = function(arg0, arg1, arg2, arg3, arg4) { + const ret = readFileSync(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4)); + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); }; module.exports.__wbg_stack_0ed75d68575b0f3c = function(arg0, arg1) { - const ret = arg1.stack; + const ret = getObject(arg1).stack; const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len1 = WASM_VECTOR_LEN; getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); }; -module.exports.__wbindgen_init_externref_table = function() { - const table = wasm.__wbindgen_export_3; - const offset = table.grow(4); - table.set(0, undefined); - table.set(offset + 0, undefined); - table.set(offset + 1, null); - table.set(offset + 2, true); - table.set(offset + 3, false); - ; +module.exports.__wbg_writeFileSync_d2c5ed0808e00dc9 = function(arg0, arg1, arg2, arg3) { + writeFileSync(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3)); +}; + +module.exports.__wbindgen_object_drop_ref = function(arg0) { + takeObject(arg0); +}; + +module.exports.__wbindgen_string_get = function(arg0, arg1) { + const obj = getObject(arg1); + const ret = typeof(obj) === 'string' ? obj : undefined; + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); }; module.exports.__wbindgen_string_new = function(arg0, arg1) { const ret = getStringFromWasm0(arg0, arg1); - return ret; + return addHeapObject(ret); +}; + +module.exports.__wbindgen_throw = function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); }; const path = require('path').join(__dirname, 'compiler_wasm_lib_bg.wasm'); @@ -229,5 +274,3 @@ const wasmInstance = new WebAssembly.Instance(wasmModule, imports); wasm = wasmInstance.exports; module.exports.__wasm = wasm; -wasm.__wbindgen_start(); - diff --git a/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm b/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm index de0bc66937..05c7a75698 100644 Binary files a/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm and b/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm differ diff --git a/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm.d.ts b/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm.d.ts index 781fb0e13a..f9645942c4 100644 --- a/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm.d.ts +++ b/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm.d.ts @@ -1,12 +1,9 @@ /* tslint:disable */ /* eslint-disable */ export const memory: WebAssembly.Memory; -export const convert_schema_to_openapi: (a: number, b: number, c: number, d: number) => [number, number, number, number]; +export const convert_schema_to_openapi: (a: number, b: number, c: number, d: number, e: number) => void; export const __wbindgen_free: (a: number, b: number, c: number) => void; export const __wbindgen_exn_store: (a: number) => void; -export const __externref_table_alloc: () => number; -export const __wbindgen_export_3: WebAssembly.Table; export const __wbindgen_malloc: (a: number, b: number) => number; export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; -export const __externref_table_dealloc: (a: number) => void; -export const __wbindgen_start: () => void; +export const __wbindgen_add_to_stack_pointer: (a: number) => number; diff --git a/compiler-rs/compiler-wasm-lib/src/lib.rs b/compiler-rs/compiler-wasm-lib/src/lib.rs index 62ed5d3987..08245c18c4 100644 --- a/compiler-rs/compiler-wasm-lib/src/lib.rs +++ b/compiler-rs/compiler-wasm-lib/src/lib.rs @@ -15,33 +15,59 @@ // specific language governing permissions and limitations // under the License. -use anyhow::bail; -use clients_schema::{Flavor, IndexedModel}; +use std::path::PathBuf; +use argh::FromArgs; +use clients_schema::IndexedModel; use wasm_bindgen::prelude::*; -use clients_schema_to_openapi::Configuration; +use clients_schema_to_openapi::cli::Cli; +/// Minimal bindings to Node's `fs` module. +mod node_fs { + use wasm_bindgen::prelude::*; + + #[wasm_bindgen(module = "node:fs")] + extern "C" { + #[wasm_bindgen(js_name = "readFileSync")] + pub fn read_file_sync_to_string(path: &str, encoding: &str) -> String; + + #[wasm_bindgen(js_name = "writeFileSync")] + pub fn write_file_sync(path: &str, content: &str); + + #[wasm_bindgen(js_name = "readdirSync")] + pub fn read_dir_sync(path: &str) -> Vec; + } +} + +/// Convert schema.json to OpenAPI. The `cwd` argument is the current directory to be used +/// if not the system-defined one, as is the case when running with `npm rum --prefix compiler` #[wasm_bindgen] -pub fn convert_schema_to_openapi(json: &str, flavor: &str) -> Result { +pub fn convert_schema_to_openapi(args: Vec, cwd: Option) -> Result<(), String> { setup_hooks(); - convert0(json, flavor).map_err(|err| err.to_string()) + + let args = args.iter().map(String::as_str).collect::>(); + let cli = Cli::from_args(&["schema-to-openapi"], &args).map_err(|err| err.output)?; + convert0(cli, cwd).map_err(|err| err.to_string()) } -fn convert0(json: &str, flavor: &str) -> anyhow::Result { - let flavor = match flavor { - "all" => None, - "stack" => Some(Flavor::Stack), - "serverless" => Some(Flavor::Serverless), - _ => bail!("Unknown flavor {}", flavor), +pub fn convert0(cli: Cli, cwd: Option) -> anyhow::Result<()> { + let input = match cwd { + Some(ref cwd) => PathBuf::from(cwd).join(&cli.schema), + None => cli.schema.clone(), }; - let config = Configuration { - flavor, - ..Default::default() + let output = match cwd { + Some(ref cwd) => PathBuf::from(cwd).join(&cli.output), + None => cli.output.clone(), }; + + let json = node_fs::read_file_sync_to_string(&input.to_string_lossy(), "utf8"); let schema = IndexedModel::from_reader(json.as_bytes())?; - let openapi = clients_schema_to_openapi::convert_schema(schema, config)?; + + let openapi = clients_schema_to_openapi::convert_schema(schema, cli.into())?; + let result = serde_json::to_string_pretty(&openapi)?; - Ok(result) + node_fs::write_file_sync(&output.to_string_lossy(), &result); + Ok(()) } pub fn setup_hooks() { diff --git a/compiler/src/transform/schema-to-openapi.ts b/compiler/src/transform/schema-to-openapi.ts index 0f3dae3e72..ddb1e5eea1 100644 --- a/compiler/src/transform/schema-to-openapi.ts +++ b/compiler/src/transform/schema-to-openapi.ts @@ -18,30 +18,12 @@ */ import { convert_schema_to_openapi } from 'compiler-wasm-lib' -import { argv } from 'zx' -import { join } from 'path' -import { readFileSync, writeFileSync } from 'fs' -const inputPath = argv.input ?? join(__dirname, '..', '..', '..', 'output', 'schema', 'schema.json') -const outputPath = argv.output ?? join(__dirname, '..', '..', '..', 'output', 'openapi', 'elasticsearch-serverless-openapi.json') -const outputPathStack = argv.output ?? join(__dirname, '..', '..', '..', 'output', 'openapi', 'elasticsearch-openapi.json') +// Remove the 2 first args ("ts-node", "schema-to-openapi.ts") +const realArgs = process.argv.slice(2) -const inputText = readFileSync( - inputPath, - { encoding: 'utf8' } -) - -const output = convert_schema_to_openapi(inputText, 'serverless') -const outputStack = convert_schema_to_openapi(inputText, 'stack') - -writeFileSync( - outputPath, - output, - 'utf8' -) - -writeFileSync( - outputPathStack, - outputStack, - 'utf8' -) +try { + convert_schema_to_openapi(realArgs, '..') +} catch (e) { + console.log(e) +} diff --git a/package.json b/package.json index 3284efbed5..894d629b9b 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,7 @@ { + "scripts": { + "transform-to-openapi": "npm run transform-to-openapi --prefix compiler --" + }, "dependencies": { "@redocly/cli": "^1.34.3", "@stoplight/spectral-cli": "^6.14.2"