diff --git a/backend/parsers/windmill-parser-ts/src/lib.rs b/backend/parsers/windmill-parser-ts/src/lib.rs index 2024f4880c..8ace23a1d3 100644 --- a/backend/parsers/windmill-parser-ts/src/lib.rs +++ b/backend/parsers/windmill-parser-ts/src/lib.rs @@ -29,12 +29,36 @@ use wasm_bindgen::prelude::*; struct ImportsFinder { imports: HashSet, + skip_type_only: bool, } impl Visit for ImportsFinder { noop_visit_type!(); fn visit_import_decl(&mut self, n: &swc_ecma_ast::ImportDecl) { + if self.skip_type_only { + if n.type_only { + return; + } + if n.specifiers.len() > 0 { + let mut is_type_only = true; + + for specifier in n.specifiers.iter() { + match specifier { + swc_ecma_ast::ImportSpecifier::Named( + swc_ecma_ast::ImportNamedSpecifier { is_type_only, .. }, + ) if *is_type_only => (), + _ => { + is_type_only = false; + break; + } + } + } + if is_type_only { + return; + } + } + } if let Some(ref s) = n.src.raw { let s = s.to_string(); if s.starts_with("'") && s.ends_with("'") { @@ -46,7 +70,7 @@ impl Visit for ImportsFinder { } } -pub fn parse_expr_for_imports(code: &str) -> anyhow::Result> { +pub fn parse_expr_for_imports(code: &str, skip_type_only: bool) -> anyhow::Result> { let cm: Lrc = Default::default(); let fm = cm.new_source_file(FileName::Custom("main.d.ts".into()).into(), code.into()); let mut tss = TsSyntax::default(); @@ -72,7 +96,7 @@ pub fn parse_expr_for_imports(code: &str) -> anyhow::Result> { anyhow::anyhow!("Error while parsing code, it is invalid TypeScript: {err_s}, {e:?}") })?; - let mut visitor = ImportsFinder { imports: HashSet::new() }; + let mut visitor = ImportsFinder { imports: HashSet::new(), skip_type_only }; visitor.visit_module(&expr); let mut imports: Vec<_> = visitor.imports.into_iter().collect(); @@ -318,7 +342,7 @@ lazy_static::lazy_static! { } pub fn remove_pinned_imports(code: &str) -> anyhow::Result { - let mut imports = parse_expr_for_imports(code)?; + let mut imports = parse_expr_for_imports(code, false)?; imports.sort_by_key(|f| 0 - (f.len() as i32)); let mut content = code.to_string(); for import in imports { diff --git a/backend/parsers/windmill-parser-ts/tests/tests.rs b/backend/parsers/windmill-parser-ts/tests/tests.rs new file mode 100644 index 0000000000..f0ffc2d7c2 --- /dev/null +++ b/backend/parsers/windmill-parser-ts/tests/tests.rs @@ -0,0 +1,19 @@ +mod tests { + use windmill_parser_ts::parse_expr_for_imports; + + #[test] + fn test_imports() { + let code = r#" + import { foo } from "bar"; + import type { foo } from "bar2"; + import { type foo, bar } from "bar3"; + import { bar, type foo } from "bar7"; + + import { type foo, type bar } from "bar4"; + import * as foo from "bar5"; + import foo from "bar6"; + "#; + let imports = parse_expr_for_imports(code, true).unwrap(); + assert_eq!(imports, vec!["bar", "bar3", "bar5", "bar6", "bar7"]); + } +} diff --git a/backend/parsers/windmill-parser-wasm/src/lib.rs b/backend/parsers/windmill-parser-wasm/src/lib.rs index 4270c28c60..2ca730cf72 100644 --- a/backend/parsers/windmill-parser-wasm/src/lib.rs +++ b/backend/parsers/windmill-parser-wasm/src/lib.rs @@ -41,7 +41,7 @@ pub fn parse_outputs(code: &str) -> String { #[cfg(feature = "ts-parser")] #[wasm_bindgen] pub fn parse_ts_imports(code: &str) -> String { - let parsed = parse_expr_for_imports(code); + let parsed = parse_expr_for_imports(code, false); let r = if let Ok(parsed) = parsed { json!({ "imports": parsed }) } else { diff --git a/backend/parsers/windmill-parser-wasm/tests/wasm.rs b/backend/parsers/windmill-parser-wasm/tests/wasm.rs index e8dc1e986b..35845e179a 100644 --- a/backend/parsers/windmill-parser-wasm/tests/wasm.rs +++ b/backend/parsers/windmill-parser-wasm/tests/wasm.rs @@ -339,7 +339,7 @@ fn test_parse_imports() -> anyhow::Result<()> { import { bar } from \"bar/foo/d\"; import { bar as baroof } from \"bar\"; "; - let mut l = parse_expr_for_imports(code)?; + let mut l = parse_expr_for_imports(code, false)?; l.sort(); assert_eq!( l, @@ -360,7 +360,7 @@ fn test_parse_imports_dts() -> anyhow::Result<()> { let code = " export type foo = number "; - let mut l = parse_expr_for_imports(code)?; + let mut l = parse_expr_for_imports(code, false)?; l.sort(); assert_eq!(l, vec![] as Vec); diff --git a/backend/windmill-worker/src/worker_lockfiles.rs b/backend/windmill-worker/src/worker_lockfiles.rs index 47bb07c438..7fee5932e4 100644 --- a/backend/windmill-worker/src/worker_lockfiles.rs +++ b/backend/windmill-worker/src/worker_lockfiles.rs @@ -188,7 +188,7 @@ fn try_normalize(path: &Path) -> Option { fn parse_ts_relative_imports(raw_code: &str, script_path: &str) -> error::Result> { let mut relative_imports = vec![]; - let r = parse_expr_for_imports(raw_code)?; + let r = parse_expr_for_imports(raw_code, true)?; for import in r { let import = import.trim_end_matches(".ts"); if import.starts_with("/") {