Skip to content

Commit

Permalink
feat: add module declaration support
Browse files Browse the repository at this point in the history
  • Loading branch information
lachieh committed Nov 26, 2024
1 parent 381df49 commit bb0b4c3
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 5 deletions.
2 changes: 2 additions & 0 deletions crates/js-component-bindgen-component/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ impl Guest for JsComponentBindgenComponent {
no_namespaced_exports: options.no_namespaced_exports.unwrap_or(false),
multi_memory: options.multi_memory.unwrap_or(false),
import_bindings: options.import_bindings.map(Into::into),
declare_imports: options.declare_imports.unwrap_or(false),
};

let js_component_bindgen::Transpiled {
Expand Down Expand Up @@ -160,6 +161,7 @@ impl Guest for JsComponentBindgenComponent {
no_namespaced_exports: false,
multi_memory: false,
import_bindings: None,
declare_imports: false,
};

let files = generate_types(name, resolve, world, opts).map_err(|e| e.to_string())?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ world js-component-bindgen {
/// Whether to generate namespaced exports like `foo as "local:package/foo"`.
/// These exports can break typescript builds.
no-namespaced-exports: option<bool>,

/// Whether to generate module declarations like `declare module "local:package/foo" {...`.
declare-imports: option<bool>,

/// Whether to output core Wasm utilizing multi-memory or to polyfill
/// this handling.
Expand Down Expand Up @@ -91,6 +94,8 @@ world js-component-bindgen {
map: option<maps>,
/// Features that should be enabled as part of feature gating
features: option<enabled-feature-set>,
/// Whether to generate module declarations like `declare module "local:package/foo" {...`.
declare-imports: option<bool>,
}

enum export-type {
Expand Down
2 changes: 2 additions & 0 deletions crates/js-component-bindgen/src/transpile_bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ pub struct TranspileOpts {
/// Whether to output core Wasm utilizing multi-memory or to polyfill
/// this handling.
pub multi_memory: bool,
/// Whether to generate module declarations like `declare module "local:package/foo" {...`.
pub declare_imports: bool,
}

#[derive(Default, Clone, Debug)]
Expand Down
21 changes: 16 additions & 5 deletions crates/js-component-bindgen/src/ts_bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ pub fn ts_bindgen(
*id,
files,
opts.instantiation.is_some(),
opts.declare_imports,
);
export_aliases.push((iface_name.to_lower_camel_case(), local_name));
}
Expand Down Expand Up @@ -368,7 +369,7 @@ impl TsBindgen {
files: &mut Files,
) -> String {
// in case an imported type is used as an exported type
let local_name = self.generate_interface(name, resolve, id, files);
let local_name = self.generate_interface(name, resolve, id, files, false);
uwriteln!(
self.import_object,
"{}: typeof {local_name},",
Expand All @@ -388,15 +389,15 @@ impl TsBindgen {
if iface_name == "*" {
uwrite!(self.import_object, "{}: ", maybe_quote_id(import_name));
let name = resolve.interfaces[id].name.as_ref().unwrap();
let local_name = self.generate_interface(name, resolve, id, files);
let local_name = self.generate_interface(name, resolve, id, files, false);
uwriteln!(self.import_object, "typeof {local_name},",);
return;
}
}
uwriteln!(self.import_object, "{}: {{", maybe_quote_id(import_name));
for (iface_name, &id) in ifaces {
let name = resolve.interfaces[id].name.as_ref().unwrap();
let local_name = self.generate_interface(name, resolve, id, files);
let local_name = self.generate_interface(name, resolve, id, files, false);
uwriteln!(
self.import_object,
"{}: typeof {local_name},",
Expand Down Expand Up @@ -428,8 +429,9 @@ impl TsBindgen {
id: InterfaceId,
files: &mut Files,
instantiation: bool,
declare_imports: bool,
) -> String {
let local_name = self.generate_interface(export_name, resolve, id, files);
let local_name = self.generate_interface(export_name, resolve, id, files, declare_imports);
if instantiation {
uwriteln!(
self.export_object,
Expand Down Expand Up @@ -472,6 +474,7 @@ impl TsBindgen {
resolve: &Resolve,
id: InterfaceId,
files: &mut Files,
declare_imports: bool,
) -> String {
let iface = resolve
.interfaces
Expand Down Expand Up @@ -522,7 +525,15 @@ impl TsBindgen {

let mut gen = self.ts_interface(resolve, false);

uwriteln!(gen.src, "export namespace {camel} {{");
uwriteln!(
gen.src,
"{}",
if declare_imports {
format!("declare module '{id_name}' {{")
} else {
format!("export namespace {camel} {{")
}
);
for (_, func) in resolve.interfaces[id].functions.iter() {
// Ensure that the function the world item for stability guarantees and exclude if they do not match
if !feature_gate_allowed(resolve, package, &func.stability, &func.name)
Expand Down
1 change: 1 addition & 0 deletions src/jco.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ program.command('types')
.option('-q, --quiet', 'disable output summary')
.option('--feature <feature>', 'enable one specific WIT feature (repeatable)', collectOptions, [])
.option('--all-features', 'enable all features')
.option('--declare-imports', 'declare imports as modules in the generated types')
.action(asyncAction(types));

program.command('run')
Expand Down
1 change: 1 addition & 0 deletions xtask/src/build/jco.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ fn transpile(component_path: &str, name: String, optimize: bool) -> Result<()> {
no_namespaced_exports: true,
multi_memory: true,
import_bindings: Some(BindingsMode::Js),
declare_imports: false,
};

let transpiled = js_component_bindgen::transpile(&adapted_component, opts)?;
Expand Down
1 change: 1 addition & 0 deletions xtask/src/generate/wasi_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub(crate) fn run() -> Result<()> {
no_namespaced_exports: true,
multi_memory: false,
import_bindings: Some(BindingsMode::Js),
declare_imports: false,
};

let files = generate_types(name, resolve, world, opts)?;
Expand Down

0 comments on commit bb0b4c3

Please sign in to comment.