Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript Stubgen Command #503

Open
wants to merge 53 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
d5d66ff
switch to golem forks
noise64 Jun 14, 2024
6298e10
npm audit fix
noise64 Jun 14, 2024
e1d34d4
update comp-js
noise64 Jun 14, 2024
4dc66a3
bump version
noise64 Jun 14, 2024
dbca60f
fix build
noise64 Jun 14, 2024
7d20f6c
fix codegen test
noise64 Jun 14, 2024
7c255cb
Merge pull request #1 from golemcloud/update-and-use-forked-comp-js
noise64 Jun 14, 2024
8d5d28b
unit test setup
nicoburniske Jun 17, 2024
fda9da3
kind of working stubgen
nicoburniske Jun 17, 2024
604ec15
before custom export
nicoburniske Jun 17, 2024
b7295e4
fix module names
nicoburniske Jun 17, 2024
273c770
move more functions to printer
nicoburniske Jun 17, 2024
56b1da5
simplify generate_interface
nicoburniske Jun 17, 2024
bf8bc7d
improve guest interface generation
nicoburniske Jun 18, 2024
daf6329
everything working guest generation except resources
nicoburniske Jun 18, 2024
51f4e71
add interface definitions for resource exports
nicoburniske Jun 18, 2024
ccc2d83
improve unit test
nicoburniske Jun 18, 2024
19897a1
test and resource interface improvements
nicoburniske Jun 18, 2024
fdebdd7
remove unused and todo
nicoburniske Jun 18, 2024
0091edb
more unit test
nicoburniske Jun 18, 2024
17e62f3
stubgen import test
nicoburniske Jun 18, 2024
fdb6899
rpc tests
nicoburniske Jun 18, 2024
53d6d59
remove push + format in favor of uwrite! macros
nicoburniske Jun 18, 2024
e6fe9a7
rename base to instance
nicoburniske Jun 19, 2024
7aecd57
update lib exports
nicoburniske Jun 19, 2024
4970671
integrate command into jco cli
nicoburniske Jun 19, 2024
f8ca2bd
minor clippy warnings
nicoburniske Jun 19, 2024
232bdf7
allow inline interface
nicoburniske Jun 19, 2024
fe03a51
use anyhow instead of unimplemented panic
nicoburniske Jun 19, 2024
8412740
improve stubgen rpc test to use common types
nicoburniske Jun 19, 2024
b8542a0
cargo fmt
nicoburniske Jun 19, 2024
4b871c6
replace Guest with World
nicoburniske Jun 19, 2024
2fc0781
remove nested TsInterface definition and make resource processing exp…
nicoburniske Jun 19, 2024
196454b
clippy fixes
nicoburniske Jun 19, 2024
64f4b7f
Merge pull request #2 from golemcloud/ts_gen
nicoburniske Jun 19, 2024
207bf6c
bump version
nicoburniske Jun 19, 2024
f63bf48
convert methods to lower camel case
nicoburniske Jul 25, 2024
242cf40
Merge remote-tracking branch 'upstream/main' into updates-from-upstream
noise64 Aug 1, 2024
6754c3e
update
noise64 Aug 1, 2024
6696a83
fix submodules
noise64 Aug 2, 2024
52cb142
format
noise64 Aug 2, 2024
5f0feb4
Merge pull request #3 from golemcloud/updates-from-upstream
noise64 Aug 2, 2024
d48342d
Merge remote-tracking branch 'upstream/main'
noise64 Aug 26, 2024
c2de337
fix imports
noise64 Aug 26, 2024
fad2987
fmt
noise64 Aug 26, 2024
9ae1f0a
Merge pull request #4 from golemcloud/update-upstream
noise64 Aug 26, 2024
5987ba8
disable docs flow
noise64 Aug 26, 2024
085e0b3
update componentize-js
noise64 Aug 26, 2024
55fd140
fix js identifier function export
nicoburniske Sep 20, 2024
4d96e6a
Merge pull request #7 from golemcloud/export_js_identifier_func
nicoburniske Sep 20, 2024
2c6e565
Merge branch 'bca_main' into ts_stubgen
nicoburniske Sep 20, 2024
4e73c91
update package.json
nicoburniske Sep 20, 2024
22e4261
Merge branch 'main' into ts_stubgen
nicoburniske Sep 30, 2024
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
2 changes: 2 additions & 0 deletions Cargo.lock

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

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ strip = true
anyhow = "1.0.89"
base64 = "0.22.1"
heck = "0.5.0"
indexmap = "2.4.0"
log = "0.4.22"
semver = "1.0.23"
js-component-bindgen = { path = "./crates/js-component-bindgen" }
Expand All @@ -57,4 +58,5 @@ wit-parser = "0.217.0"
xshell = "0.2.6"

[dev-dependencies]
anyhow = { workspace = true }
anyhow = { workspace = true }
xshell = { workspace = true }
90 changes: 58 additions & 32 deletions crates/js-component-bindgen-component/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use std::path::PathBuf;

use anyhow::Result;
use js_component_bindgen::{generate_types, source::wit_parser::Resolve, transpile};
use js_component_bindgen::{
generate_types, generate_typescript_stubs,
source::wit_parser::{PackageId, Resolve},
transpile,
};

/// Calls [`write!`] with the passed arguments and unwraps the result.
///
Expand Down Expand Up @@ -112,39 +116,10 @@ impl Guest for JsComponentBindgenComponent {
name: String,
opts: TypeGenerationOptions,
) -> Result<Vec<(String, Vec<u8>)>, String> {
let mut resolve = Resolve::default();

// Add features if specified
match opts.features {
Some(EnabledFeatureSet::List(ref features)) => {
for f in features.into_iter() {
resolve.features.insert(f.to_string());
}
}
Some(EnabledFeatureSet::All) => {
resolve.all_features = true;
}
_ => {}
}

let ids = match opts.wit {
Wit::Source(source) => resolve
.push_str(format!("{name}.wit"), &source)
.map_err(|e| e.to_string())?,
Wit::Path(path) => {
let path = PathBuf::from(path);
if path.is_dir() {
resolve.push_dir(&path).map_err(|e| e.to_string())?.0
} else {
resolve.push_file(&path).map_err(|e| e.to_string())?
}
}
Wit::Binary(_) => todo!(),
};

let (resolve, id) = resolve_package(opts.wit, opts.features, Some(&name))?;
let world_string = opts.world.map(|world| world.to_string());
let world = resolve
.select_world(ids, world_string.as_deref())
.select_world(id, world_string.as_deref())
.map_err(|e| e.to_string())?;

let opts = js_component_bindgen::TranspileOpts {
Expand All @@ -166,4 +141,55 @@ impl Guest for JsComponentBindgenComponent {

Ok(files)
}

fn generate_typescript_stubs(opts: TypescriptStubOptions) -> Result<Files, String> {
let (resolve, id) = resolve_package(opts.wit, None, None).map_err(|e| e.to_string())?;
let world_string = opts.world.map(|world| world.to_string());
let world = resolve
.select_world(id, world_string.as_deref())
.map_err(|e| e.to_string())?;

let files = generate_typescript_stubs(resolve, world).map_err(|e| e.to_string())?;

Ok(files)
}
}

fn resolve_package(
wit: Wit,
features: Option<EnabledFeatureSet>,
name: Option<&str>,
) -> Result<(Resolve, PackageId), String> {
let name = name.unwrap_or("world");
let mut resolve = Resolve::default();

// Add features if specified
match features {
Some(EnabledFeatureSet::List(ref features)) => {
for f in features.into_iter() {
resolve.features.insert(f.to_string());
}
}
Some(EnabledFeatureSet::All) => {
resolve.all_features = true;
}
_ => {}
}

let id = match wit {
Wit::Source(source) => resolve
.push_str(format!("{name}.wit"), &source)
.map_err(|e| e.to_string())?,
Wit::Path(path) => {
let path = PathBuf::from(path);
if path.is_dir() {
resolve.push_dir(&path).map_err(|e| e.to_string())?.0
} else {
resolve.push_file(&path).map_err(|e| e.to_string())?
}
}
Wit::Binary(_) => todo!(),
};

Ok((resolve, id))
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ world js-component-bindgen {
features: option<enabled-feature-set>,
}

record typescript-stub-options {
/// wit to generate typing from
wit: wit,
/// world to generate typing for
%world: option<string>,
}

enum export-type {
function,
instance,
Expand All @@ -110,4 +117,6 @@ world js-component-bindgen {
export generate: func(component: list<u8>, options: generate-options) -> result<transpiled, string>;

export generate-types: func(name: string, options: type-generation-options) -> result<files, string>;

export generate-typescript-stubs: func(options: typescript-stub-options) -> result<files, string>;
}
3 changes: 2 additions & 1 deletion crates/js-component-bindgen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ base64 = { workspace = true }
heck = { workspace = true }
log = { workspace = true }
semver = { workspace = true }
wasm-encoder = { workspace = true }
wasmparser = { workspace = true }
wasmtime-environ = { workspace = true, features = ['component-model'] }
wit-bindgen-core = { workspace = true }
wit-component = { workspace = true }
wit-parser = { workspace = true }
indexmap = { workspace = true }
wasm-encoder = { workspace = true }
9 changes: 9 additions & 0 deletions crates/js-component-bindgen/src/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,12 @@ impl Files {
self.files.iter().map(|p| (p.0.as_str(), p.1.as_slice()))
}
}

impl IntoIterator for Files {
type Item = (String, Vec<u8>);
type IntoIter = std::collections::btree_map::IntoIter<String, Vec<u8>>;

fn into_iter(self) -> Self::IntoIter {
self.files.into_iter()
}
}
18 changes: 13 additions & 5 deletions crates/js-component-bindgen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod core;
mod files;
mod transpile_bindgen;
mod ts_bindgen;
mod ts_stubgen;

pub mod esm_bindgen;
pub mod function_bindgen;
Expand Down Expand Up @@ -70,11 +71,18 @@ pub fn generate_types(
ts_bindgen(&name, &resolve, world_id, &opts, &mut files)
.context("failed to generate Typescript bindings")?;

let mut files_out: Vec<(String, Vec<u8>)> = Vec::new();
for (name, source) in files.iter() {
files_out.push((name.to_string(), source.to_vec()));
}
Ok(files_out)
Ok(files.into_iter().collect())
}

pub fn generate_typescript_stubs(
resolve: Resolve,
world_id: WorldId,
) -> Result<Vec<(String, Vec<u8>)>, anyhow::Error> {
let mut files = files::Files::default();

ts_stubgen::ts_stubgen(&resolve, world_id, &mut files)?;

Ok(files.into_iter().collect())
}

/// Generate the JS transpilation bindgen for a given Wasm component binary
Expand Down
6 changes: 6 additions & 0 deletions crates/js-component-bindgen/src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ impl From<Source> for String {
}
}

impl AsRef<str> for Source {
fn as_ref(&self) -> &str {
&self.s
}
}

#[cfg(test)]
mod tests {
use super::Source;
Expand Down
Loading
Loading