diff --git a/Cargo.lock b/Cargo.lock index cb4534e3f..087e1f206 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1156,13 +1156,14 @@ dependencies = [ [[package]] name = "modularize_imports" -version = "0.68.6" +version = "0.68.7" dependencies = [ "convert_case", "handlebars", "once_cell", "regex", "serde", + "swc_atoms", "swc_cached", "swc_common", "swc_ecma_ast", diff --git a/packages/transform-imports/CHANGELOG.md b/packages/transform-imports/CHANGELOG.md index 80c658945..f2bef1e0e 100644 --- a/packages/transform-imports/CHANGELOG.md +++ b/packages/transform-imports/CHANGELOG.md @@ -1,5 +1,11 @@ # @swc/plugin-transform-imports +## 1.5.119 + +### Patch Changes + +- 1509e60: Support export all + ## 1.5.118 ### Patch Changes diff --git a/packages/transform-imports/README.md b/packages/transform-imports/README.md index ceb650be7..d17f0adb4 100644 --- a/packages/transform-imports/README.md +++ b/packages/transform-imports/README.md @@ -18,6 +18,12 @@ # @swc/plugin-transform-imports +## 1.5.119 + +### Patch Changes + +- 1509e60: Support export all + ## 1.5.118 ### Patch Changes diff --git a/packages/transform-imports/package.json b/packages/transform-imports/package.json index a36080028..5b8d1345f 100644 --- a/packages/transform-imports/package.json +++ b/packages/transform-imports/package.json @@ -1,6 +1,6 @@ { "name": "@swc/plugin-transform-imports", - "version": "1.5.118", + "version": "1.5.119", "description": "SWC plugin for https://www.npmjs.com/package/babel-plugin-transform-imports", "main": "swc_plugin_transform_imports.wasm", "scripts": { diff --git a/packages/transform-imports/transform/Cargo.toml b/packages/transform-imports/transform/Cargo.toml index 56c4ca625..6fe839cd7 100644 --- a/packages/transform-imports/transform/Cargo.toml +++ b/packages/transform-imports/transform/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" license = "Apache-2.0" name = "modularize_imports" repository = "https://github.com/swc-project/plugins.git" -version = "0.68.6" +version = "0.68.7" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -15,6 +15,7 @@ handlebars = "4.2.1" once_cell = "1.13.0" regex = "1.5" serde = "1" +swc_atoms = "0.6.5" swc_cached = "0.3.19" swc_common = "0.33.17" swc_ecma_ast = "0.112.2" diff --git a/packages/transform-imports/transform/src/lib.rs b/packages/transform-imports/transform/src/lib.rs index b1266c397..ae1deaade 100644 --- a/packages/transform-imports/transform/src/lib.rs +++ b/packages/transform-imports/transform/src/lib.rs @@ -5,6 +5,7 @@ use handlebars::{Context, Handlebars, Helper, HelperResult, Output, RenderContex use once_cell::sync::Lazy; use regex::{Captures, Regex}; use serde::{Deserialize, Serialize}; +use swc_atoms::Atom; use swc_cached::regex::CachedRegex; use swc_common::DUMMY_SP; use swc_ecma_ast::{ImportDecl, ImportSpecifier, ModuleExportName, *}; @@ -66,6 +67,84 @@ enum CtxData<'a> { } impl<'a> Rewriter<'a> { + fn new_path(&self, name_str: Option<&str>) -> Atom { + let mut ctx: HashMap<&str, CtxData> = HashMap::new(); + ctx.insert("matches", CtxData::Array(&self.group[..])); + if let Some(name_str) = name_str { + ctx.insert("member", CtxData::Plain(name_str)); + } + + let new_path = match &self.config.transform { + Transform::String(s) => self.renderer.render_template(s, &ctx).unwrap_or_else(|e| { + panic!("error rendering template for '{}': {}", self.key, e); + }), + Transform::Vec(v) => { + let mut result: Option = None; + + // We iterate over the items to find the first match + v.iter().any(|(k, val)| { + let mut key = k.to_string(); + if !key.starts_with('^') && !key.ends_with('$') { + key = format!("^{}$", key); + } + + // Create a clone of the context, as we need to insert the + // `memberMatches` key for each key we try. + let mut ctx_with_member_matches: HashMap<&str, CtxData> = HashMap::new(); + ctx_with_member_matches.insert("matches", CtxData::Array(&self.group[..])); + + if let Some(name_str) = name_str { + ctx_with_member_matches.insert("member", CtxData::Plain(name_str)); + } + let regex = CachedRegex::new(&key).expect("transform-imports: invalid regex"); + if let Some(name_str) = name_str { + let group = regex.captures(name_str); + + if let Some(group) = group { + let group = group + .iter() + .map(|x| x.map(|x| x.as_str()).unwrap_or_default()) + .collect::>() + .clone(); + ctx_with_member_matches + .insert("memberMatches", CtxData::Array(&group[..])); + + result = Some( + self.renderer + .render_template(val, &ctx_with_member_matches) + .unwrap_or_else(|e| { + panic!( + "error rendering template for '{}': {}", + self.key, e + ); + }), + ); + + true + } else { + false + } + } else { + false + } + }); + + if let Some(result) = result { + result + } else { + panic!( + "missing transform for import '{:?}' of package '{}'", + name_str, self.key + ); + } + } + }; + + let new_path = DUP_SLASH_REGEX.replace_all(&new_path, |_: &Captures| "/"); + + new_path.into() + } + fn rewrite_export(&self, old_decl: &NamedExport) -> Vec { if old_decl.type_only || old_decl.with.is_some() { return vec![old_decl.clone()]; @@ -82,76 +161,7 @@ impl<'a> Rewriter<'a> { ModuleExportName::Str(x) => x.value.as_ref(), }; - let mut ctx: HashMap<&str, CtxData> = HashMap::new(); - ctx.insert("matches", CtxData::Array(&self.group[..])); - ctx.insert("member", CtxData::Plain(name_str)); - - let new_path = match &self.config.transform { - Transform::String(s) => { - self.renderer.render_template(s, &ctx).unwrap_or_else(|e| { - panic!("error rendering template for '{}': {}", self.key, e); - }) - } - Transform::Vec(v) => { - let mut result: Option = None; - - // We iterate over the items to find the first match - v.iter().any(|(k, val)| { - let mut key = k.to_string(); - if !key.starts_with('^') && !key.ends_with('$') { - key = format!("^{}$", key); - } - - // Create a clone of the context, as we need to insert the - // `memberMatches` key for each key we try. - let mut ctx_with_member_matches: HashMap<&str, CtxData> = - HashMap::new(); - ctx_with_member_matches - .insert("matches", CtxData::Array(&self.group[..])); - ctx_with_member_matches.insert("member", CtxData::Plain(name_str)); - - let regex = CachedRegex::new(&key) - .expect("transform-imports: invalid regex"); - let group = regex.captures(name_str); - - if let Some(group) = group { - let group = group - .iter() - .map(|x| x.map(|x| x.as_str()).unwrap_or_default()) - .collect::>() - .clone(); - ctx_with_member_matches - .insert("memberMatches", CtxData::Array(&group[..])); - - result = Some( - self.renderer - .render_template(val, &ctx_with_member_matches) - .unwrap_or_else(|e| { - panic!( - "error rendering template for '{}': {}", - self.key, e - ); - }), - ); - - true - } else { - false - } - }); - - if let Some(result) = result { - result - } else { - panic!( - "missing transform for import '{:?}' of package '{}'", - named_spec.orig, self.key - ); - } - } - }; - - let new_path = DUP_SLASH_REGEX.replace_all(&new_path, |_: &Captures| "/"); + let new_path = self.new_path(Some(name_str)); let specifier = if self.config.skip_default_conversion { ExportSpecifier::Named(named_spec.clone()) } else { @@ -210,76 +220,7 @@ impl<'a> Rewriter<'a> { }) .unwrap_or_else(|| named_spec.local.as_ref()); - let mut ctx: HashMap<&str, CtxData> = HashMap::new(); - ctx.insert("matches", CtxData::Array(&self.group[..])); - ctx.insert("member", CtxData::Plain(name_str)); - - let new_path = match &self.config.transform { - Transform::String(s) => { - self.renderer.render_template(s, &ctx).unwrap_or_else(|e| { - panic!("error rendering template for '{}': {}", self.key, e); - }) - } - Transform::Vec(v) => { - let mut result: Option = None; - - // We iterate over the items to find the first match - v.iter().any(|(k, val)| { - let mut key = k.to_string(); - if !key.starts_with('^') && !key.ends_with('$') { - key = format!("^{}$", key); - } - - // Create a clone of the context, as we need to insert the - // `memberMatches` key for each key we try. - let mut ctx_with_member_matches: HashMap<&str, CtxData> = - HashMap::new(); - ctx_with_member_matches - .insert("matches", CtxData::Array(&self.group[..])); - ctx_with_member_matches.insert("member", CtxData::Plain(name_str)); - - let regex = CachedRegex::new(&key) - .expect("transform-imports: invalid regex"); - let group = regex.captures(name_str); - - if let Some(group) = group { - let group = group - .iter() - .map(|x| x.map(|x| x.as_str()).unwrap_or_default()) - .collect::>() - .clone(); - ctx_with_member_matches - .insert("memberMatches", CtxData::Array(&group[..])); - - result = Some( - self.renderer - .render_template(val, &ctx_with_member_matches) - .unwrap_or_else(|e| { - panic!( - "error rendering template for '{}': {}", - self.key, e - ); - }), - ); - - true - } else { - false - } - }); - - if let Some(result) = result { - result - } else { - panic!( - "missing transform for import '{}' of package '{}'", - named_spec.local, self.key - ); - } - } - }; - - let new_path = DUP_SLASH_REGEX.replace_all(&new_path, |_: &Captures| "/"); + let new_path = self.new_path(Some(name_str)); let specifier = if self.config.skip_default_conversion { ImportSpecifier::Named(named_spec.clone()) } else { @@ -370,6 +311,27 @@ impl Fold for FoldImports { } None => new_items.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(decl))), }, + + ModuleItem::ModuleDecl(ModuleDecl::ExportAll(e @ ExportAll { .. })) => { + match self.should_rewrite(&e.src.value) { + Some(rewriter) => { + let rewritten = rewriter.new_path(None); + new_items.push(ModuleItem::ModuleDecl(ModuleDecl::ExportAll( + ExportAll { + src: Box::new(Str { + span: e.src.span, + value: rewritten, + raw: None, + }), + ..e + }, + ))); + } + None => { + new_items.push(ModuleItem::ModuleDecl(ModuleDecl::ExportAll(e))); + } + } + } _ => { new_items.push(item); }