Skip to content

Commit

Permalink
Add import-esm flag (#192)
Browse files Browse the repository at this point in the history
Add "import-esm" feature to make `import`s have a `.js` extension
  • Loading branch information
escritorio-gustavo committed Jan 22, 2024
1 parent f86ccb5 commit 1c33a86
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 3 deletions.
Binary file modified README.md
Binary file not shown.
1 change: 1 addition & 0 deletions ts-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ indexmap-impl = ["indexmap"]
ordered-float-impl = ["ordered-float"]
heapless-impl = ["heapless"]
no-serde-warnings = ["ts-rs-macros/no-serde-warnings"]
import-esm = []

[dev-dependencies]
serde = { version = "1.0", features = ["derive"] }
Expand Down
12 changes: 9 additions & 3 deletions ts-rs/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,18 @@ fn generate_imports<T: TS + ?Sized + 'static>(out: &mut String) -> Result<(), Ex
fn import_path(from: &Path, import: &Path) -> String {
let rel_path =
diff_paths(import, from.parent().unwrap()).expect("failed to calculate import path");
match rel_path.components().next() {
let path = match rel_path.components().next() {
Some(Component::Normal(_)) => format!("./{}", rel_path.to_string_lossy()),
_ => rel_path.to_string_lossy().into(),
};

let path_without_extension = path.trim_end_matches(".ts");

if cfg!(feature = "import-esm") {
format!("{}.js", path_without_extension)
} else {
path_without_extension.to_owned()
}
.trim_end_matches(".ts")
.to_owned()
}

// Construct a relative path from a provided base directory path to the provided path.
Expand Down
5 changes: 5 additions & 0 deletions ts-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
//! - generate necessary imports when exporting to multiple files
//! - serde compatibility
//! - generic types
//! - support for ESM imports
//!
//! ## limitations
//! - generic fields cannot be inlined or flattened (#56)
Expand Down Expand Up @@ -112,6 +113,10 @@
//! When `serde-compat` is enabled, warnings are printed during build if unsupported serde
//! attributes are encountered. Enabling this feature silences these warnings.
//!
//! - `import-esm`
//!
//! `import` statements in the generated file will have the `.js` extension in the end of
//! the path to conform to the ES Modules spec. (e.g.: `import { MyStruct } from "./my_struct.js"`)
//!
//! If there's a type you're dealing with which doesn't implement `TS`, use `#[ts(type = "..")]` or open a PR.
//!
Expand Down
13 changes: 13 additions & 0 deletions ts-rs/tests/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ fn test_def() {
let text = std::fs::read_to_string(TestEnum::EXPORT_TO.unwrap()).unwrap();

// Checks to make sure imports are ordered and deduplicated
#[cfg(feature = "import-esm")]
assert_eq!(text,
concat!(
"// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.\n",
"import type { TestTypeA } from \"./ts_rs_test_type_a.js\";\n",
"import type { TestTypeB } from \"./ts_rs_test_type_b.js\";\n",
"\n",
"export type TestEnum = { \"C\": { value: TestTypeB<number> } } | {\n",
" \"A1\": { value: TestTypeA<number> };\n",
"} | { \"A2\": { value: TestTypeA<number> } };\n"
)
);
#[cfg(not(feature = "import-esm"))]
assert_eq!(text,
concat!(
"// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.\n",
Expand Down

0 comments on commit 1c33a86

Please sign in to comment.