diff --git a/crates/oxc/src/napi/transform.rs b/crates/oxc/src/napi/transform.rs index d37ae5db6588ac..3d761b2ccee3b4 100644 --- a/crates/oxc/src/napi/transform.rs +++ b/crates/oxc/src/napi/transform.rs @@ -89,9 +89,11 @@ pub struct TransformOptions { pub inject: Option>>>, } -impl From for oxc_transformer::TransformOptions { - fn from(options: TransformOptions) -> Self { - Self { +impl TryFrom for oxc_transformer::TransformOptions { + type Error = String; + + fn try_from(options: TransformOptions) -> Result { + Ok(Self { cwd: options.cwd.map(PathBuf::from).unwrap_or_default(), typescript: options .typescript @@ -99,7 +101,7 @@ impl From for oxc_transformer::TransformOptions { .unwrap_or_default(), jsx: options.jsx.map(Into::into).unwrap_or_default(), ..Self::default() - } + }) } } diff --git a/crates/oxc_transformer/src/options/babel/env/targets.rs b/crates/oxc_transformer/src/options/babel/env/targets.rs index 554074dbee3893..b044f627f9d8ff 100644 --- a/crates/oxc_transformer/src/options/babel/env/targets.rs +++ b/crates/oxc_transformer/src/options/babel/env/targets.rs @@ -3,8 +3,6 @@ use std::str::FromStr; use rustc_hash::FxHashMap; use serde::Deserialize; -use oxc_diagnostics::Error; - pub use browserslist::Version; use crate::options::{BrowserslistQuery, Engine, EngineTargets}; @@ -35,7 +33,7 @@ pub enum BabelTargetsValue { } impl TryFrom for EngineTargets { - type Error = Error; + type Error = String; fn try_from(value: BabelTargets) -> Result { match value { BabelTargets::String(s) => BrowserslistQuery::Single(s).exec(), @@ -52,7 +50,7 @@ impl TryFrom for EngineTargets { continue; }; let BabelTargetsValue::String(v) = value else { - return Err(Error::msg(format!("{value:?} is not a string for {key}."))); + return Err(format!("{value:?} is not a string for {key}.")); }; // TODO: Implement this target. if key == "node" && v == "current" { @@ -66,16 +64,14 @@ impl TryFrom for EngineTargets { // : // Supported environments: android, chrome, deno, edge, electron, firefox, ie, ios, node, opera, rhino, safari, samsung. let Ok(engine) = Engine::from_str(&key) else { - return Err(Error::msg(format!("engine '{key}' is not supported."))); + return Err(format!("engine '{key}' is not supported.")); }; match Version::parse(&v) { Ok(version) => { engine_targets.insert(engine, version); } Err(err) => { - return Err(oxc_diagnostics::Error::msg(format!( - "Failed to parse `{v}` for `{key}`\n{err:?}" - ))) + return Err(format!("Failed to parse `{v}` for `{key}`\n{err:?}")) } } } diff --git a/crates/oxc_transformer/src/options/browserslist_query.rs b/crates/oxc_transformer/src/options/browserslist_query.rs index da02331912eb28..84acb91de264cf 100644 --- a/crates/oxc_transformer/src/options/browserslist_query.rs +++ b/crates/oxc_transformer/src/options/browserslist_query.rs @@ -3,8 +3,6 @@ use std::sync::OnceLock; use dashmap::DashMap; use serde::Deserialize; -use oxc_diagnostics::{Error, OxcDiagnostic}; - use super::EngineTargets; #[derive(Debug, Clone, Deserialize, Eq, PartialEq, PartialOrd, Ord, Hash)] @@ -20,7 +18,7 @@ fn cache() -> &'static DashMap { } impl BrowserslistQuery { - pub fn exec(&self) -> Result { + pub fn exec(&self) -> Result { if let Some(v) = cache().get(self) { return Ok(v.clone()); } @@ -50,9 +48,7 @@ impl BrowserslistQuery { .collect::>(); EngineTargets::parse_versions(versions) } - Err(err) => { - return Err(OxcDiagnostic::error(format!("failed to resolve query: {err}")).into()) - } + Err(err) => return Err(format!("failed to resolve query: {err}")), }; cache().insert(self.clone(), result.clone()); diff --git a/crates/oxc_transformer/src/options/engine.rs b/crates/oxc_transformer/src/options/engine.rs index d3217970faa570..699f84ac184d42 100644 --- a/crates/oxc_transformer/src/options/engine.rs +++ b/crates/oxc_transformer/src/options/engine.rs @@ -2,7 +2,6 @@ use std::{str::FromStr, sync::OnceLock}; use browserslist::Version; use cow_utils::CowUtils; -use oxc_diagnostics::Error; use rustc_hash::FxHashMap; use serde::Deserialize; @@ -38,17 +37,17 @@ impl Engine { /// /// * No matching target /// * Invalid version - pub fn parse_name_and_version(s: &str) -> Result<(Engine, Version), Error> { + pub fn parse_name_and_version(s: &str) -> Result<(Engine, Version), String> { let s = s.cow_to_ascii_lowercase(); for (name, engine) in engines() { if let Some(v) = s.strip_prefix(name) { return Version::from_str(v).map(|version| (*engine,version)) - .map_err(|_| Error::msg( - r#"All version numbers must be in the format "X", "X.Y", or "X.Y.Z" where X, Y, and Z are non-negative integers."#, - )); + .map_err(|_| + String::from(r#"All version numbers must be in the format "X", "X.Y", or "X.Y.Z" where X, Y, and Z are non-negative integers."#), + ); } } - Err(Error::msg(format!("Invalid target '{s}'."))) + Err(format!("Invalid target '{s}'.")) } } diff --git a/crates/oxc_transformer/src/options/engine_targets.rs b/crates/oxc_transformer/src/options/engine_targets.rs index ddbc9eaf0e4311..d5724b29655f89 100644 --- a/crates/oxc_transformer/src/options/engine_targets.rs +++ b/crates/oxc_transformer/src/options/engine_targets.rs @@ -8,8 +8,6 @@ use browserslist::Version; use rustc_hash::FxHashMap; use serde::Deserialize; -use oxc_diagnostics::Error; - use super::{ babel::BabelTargets, engine::Engine, @@ -42,7 +40,7 @@ impl EngineTargets { /// # Errors /// /// * Query is invalid. - pub fn try_from_query(query: &str) -> Result { + pub fn try_from_query(query: &str) -> Result { BrowserslistQuery::Single(query.to_string()).exec() } diff --git a/crates/oxc_transformer/src/options/env.rs b/crates/oxc_transformer/src/options/env.rs index a148068ae8571a..8d1011897894ae 100644 --- a/crates/oxc_transformer/src/options/env.rs +++ b/crates/oxc_transformer/src/options/env.rs @@ -1,6 +1,5 @@ use std::str::FromStr; -use oxc_diagnostics::Error; use serde::Deserialize; use crate::{ @@ -101,11 +100,14 @@ impl EnvOptions { /// * When the query failed to parse. /// /// [browserslist]: - pub fn from_browserslist_query(query: &str) -> Result { + pub fn from_browserslist_query(query: &str) -> Result { EngineTargets::try_from_query(query).map(Self::from) } - pub(crate) fn from_target(s: &str) -> Result { + /// # Errors + /// + /// * When the query failed to parse. + pub fn from_target(s: &str) -> Result { if s.contains(',') { Self::from_target_list(&s.split(',').collect::>()) } else { @@ -113,7 +115,10 @@ impl EnvOptions { } } - pub(crate) fn from_target_list>(list: &[S]) -> Result { + /// # Errors + /// + /// * When the query failed to parse. + pub fn from_target_list>(list: &[S]) -> Result { let mut es_target = None; let mut engine_targets = EngineTargets::default(); @@ -122,14 +127,14 @@ impl EnvOptions { // Parse `esXXXX`. if let Ok(target) = ESTarget::from_str(s) { if let Some(target) = es_target { - return Err(Error::msg(format!("'{target}' is already specified."))); + return Err(format!("'{target}' is already specified.")); } es_target = Some(target); } else { // Parse `chromeXX`, `edgeXX` etc. let (engine, version) = Engine::parse_name_and_version(s)?; if engine_targets.insert(engine, version).is_some() { - return Err(Error::msg(format!("'{s}' is already specified."))); + return Err(format!("'{s}' is already specified.")); } } } diff --git a/crates/oxc_transformer/src/options/mod.rs b/crates/oxc_transformer/src/options/mod.rs index 04085fb6eb9d65..076fcdb4f441d2 100644 --- a/crates/oxc_transformer/src/options/mod.rs +++ b/crates/oxc_transformer/src/options/mod.rs @@ -10,8 +10,6 @@ mod module; use std::path::PathBuf; -use oxc_diagnostics::Error; - use crate::{ common::helper_loader::{HelperLoaderMode, HelperLoaderOptions}, compiler_assumptions::CompilerAssumptions, @@ -97,7 +95,7 @@ impl TransformOptions { /// * Same targets specified multiple times. /// * No matching target. /// * Invalid version. - pub fn from_target(s: &str) -> Result { + pub fn from_target(s: &str) -> Result { EnvOptions::from_target(s).map(|env| Self { env, ..Self::default() }) } @@ -115,7 +113,7 @@ impl TransformOptions { /// * Same targets specified multiple times. /// * No matching target. /// * Invalid version. - pub fn from_target_list>(list: &[S]) -> Result { + pub fn from_target_list>(list: &[S]) -> Result { EnvOptions::from_target_list(list).map(|env| Self { env, ..Self::default() }) } } @@ -129,13 +127,13 @@ impl From for TransformOptions { } impl TryFrom<&BabelOptions> for TransformOptions { - type Error = Vec; + type Error = Vec; /// If the `options` contains any unknown fields, they will be returned as a list of errors. fn try_from(options: &BabelOptions) -> Result { - let mut errors = Vec::::new(); - errors.extend(options.plugins.errors.iter().map(|err| Error::msg(err.clone()))); - errors.extend(options.presets.errors.iter().map(|err| Error::msg(err.clone()))); + let mut errors = Vec::::new(); + errors.extend(options.plugins.errors.iter().map(Clone::clone)); + errors.extend(options.presets.errors.iter().map(Clone::clone)); let typescript = options .presets diff --git a/napi/transform/index.d.ts b/napi/transform/index.d.ts index 9fd1aca75d5cbc..ba8aeec642a2fb 100644 --- a/napi/transform/index.d.ts +++ b/napi/transform/index.d.ts @@ -203,6 +203,7 @@ export interface TransformOptions { typescript?: TypeScriptOptions /** Configure how TSX and JSX are transformed. */ jsx?: JsxOptions + target?: string | Array /** Define Plugin */ define?: Record /** Inject Plugin */ diff --git a/napi/transform/src/transformer.rs b/napi/transform/src/transformer.rs index 0e5dca677e12ee..29886efb6dbeb5 100644 --- a/napi/transform/src/transformer.rs +++ b/napi/transform/src/transformer.rs @@ -84,8 +84,11 @@ impl Compiler { .transpose()? .map(InjectGlobalVariablesConfig::new); - let transform_options = - options.map(oxc::transformer::TransformOptions::from).unwrap_or_default(); + let transform_options = match options { + Some(options) => oxc::transformer::TransformOptions::try_from(options) + .map_err(|err| vec![OxcDiagnostic::error(err)])?, + None => oxc::transformer::TransformOptions::default(), + }; Ok(Self { transform_options, diff --git a/tasks/transform_conformance/src/test_case.rs b/tasks/transform_conformance/src/test_case.rs index 88758d2eedd992..f34a48f8d189b7 100644 --- a/tasks/transform_conformance/src/test_case.rs +++ b/tasks/transform_conformance/src/test_case.rs @@ -8,7 +8,7 @@ use oxc::parser::ParseOptions; use oxc::{ allocator::Allocator, codegen::{CodeGenerator, CodegenOptions}, - diagnostics::{Error, NamedSource, OxcDiagnostic}, + diagnostics::{NamedSource, OxcDiagnostic}, parser::Parser, span::{SourceType, VALID_EXTENSIONS}, transformer::{BabelOptions, HelperLoaderMode, TransformOptions}, @@ -27,7 +27,7 @@ pub struct TestCase { pub path: PathBuf, options: BabelOptions, source_type: SourceType, - transform_options: Result>, + transform_options: Result>, pub errors: Vec, }