diff --git a/napi/parser/src/lib.rs b/napi/parser/src/lib.rs index fbca1d0ea4ce1..d219918848ed2 100644 --- a/napi/parser/src/lib.rs +++ b/napi/parser/src/lib.rs @@ -56,7 +56,7 @@ fn parse<'a>( let source_type = options .source_filename .as_ref() - .map(|name| SourceType::from_path(name).unwrap()) + .and_then(|name| SourceType::from_path(name).ok()) .unwrap_or_default(); let source_type = match options.source_type.as_deref() { Some("script") => source_type.with_script(true), diff --git a/napi/transform/src/isolated_declaration.rs b/napi/transform/src/isolated_declaration.rs new file mode 100644 index 0000000000000..d3dc14794aed7 --- /dev/null +++ b/napi/transform/src/isolated_declaration.rs @@ -0,0 +1,42 @@ +use std::sync::Arc; + +use napi_derive::napi; + +use oxc_allocator::Allocator; +use oxc_codegen::CodeGenerator; +use oxc_diagnostics::{Error, NamedSource}; +use oxc_isolated_declarations::IsolatedDeclarations; +use oxc_parser::Parser; +use oxc_span::SourceType; + +#[napi(object)] +pub struct IsolatedDeclarationsResult { + pub source_text: String, + pub errors: Vec, +} + +/// TypeScript Isolated Declarations for Standalone DTS Emit +#[allow(clippy::needless_pass_by_value)] +#[napi] +pub fn isolated_declaration(filename: String, source_text: String) -> IsolatedDeclarationsResult { + let source_type = SourceType::from_path(&filename).unwrap_or_default().with_typescript(true); + let allocator = Allocator::default(); + let parser_ret = Parser::new(&allocator, &source_text, source_type).parse(); + let transformed_ret = IsolatedDeclarations::new(&allocator).build(&parser_ret.program); + let printed = CodeGenerator::new().build(&transformed_ret.program).source_text; + + let mut errors = vec![]; + if !parser_ret.errors.is_empty() || !transformed_ret.errors.is_empty() { + let source = Arc::new(NamedSource::new(filename, source_text.to_string())); + errors.extend( + parser_ret + .errors + .into_iter() + .chain(transformed_ret.errors) + .map(|diagnostic| Error::from(diagnostic).with_source_code(Arc::clone(&source))) + .map(|error| format!("{error:?}")), + ); + } + + IsolatedDeclarationsResult { source_text: printed, errors } +} diff --git a/napi/transform/src/lib.rs b/napi/transform/src/lib.rs index 99bfeab129814..37cec7e610364 100644 --- a/napi/transform/src/lib.rs +++ b/napi/transform/src/lib.rs @@ -1,44 +1,4 @@ -pub mod transformer; +mod isolated_declaration; +mod transformer; -use std::sync::Arc; - -use napi_derive::napi; - -use oxc_allocator::Allocator; -use oxc_codegen::CodeGenerator; -use oxc_diagnostics::{Error, NamedSource}; -use oxc_isolated_declarations::IsolatedDeclarations; -use oxc_parser::Parser; -use oxc_span::SourceType; - -#[napi(object)] -pub struct IsolatedDeclarationsResult { - pub source_text: String, - pub errors: Vec, -} - -/// TypeScript Isolated Declarations for Standalone DTS Emit -#[allow(clippy::needless_pass_by_value)] -#[napi] -pub fn isolated_declaration(filename: String, source_text: String) -> IsolatedDeclarationsResult { - let source_type = SourceType::from_path(&filename).unwrap_or_default().with_typescript(true); - let allocator = Allocator::default(); - let parser_ret = Parser::new(&allocator, &source_text, source_type).parse(); - let transformed_ret = IsolatedDeclarations::new(&allocator).build(&parser_ret.program); - let printed = CodeGenerator::new().build(&transformed_ret.program).source_text; - - let mut errors = vec![]; - if !parser_ret.errors.is_empty() || !transformed_ret.errors.is_empty() { - let source = Arc::new(NamedSource::new(filename, source_text.to_string())); - errors.extend( - parser_ret - .errors - .into_iter() - .chain(transformed_ret.errors) - .map(|diagnostic| Error::from(diagnostic).with_source_code(Arc::clone(&source))) - .map(|error| format!("{error:?}")), - ); - } - - IsolatedDeclarationsResult { source_text: printed, errors } -} +pub use crate::{isolated_declaration::*, transformer::*}; diff --git a/napi/transform/src/transformer.rs b/napi/transform/src/transformer.rs index de82c804a0e42..5d9841b58cfce 100644 --- a/napi/transform/src/transformer.rs +++ b/napi/transform/src/transformer.rs @@ -1,13 +1,14 @@ use std::path::Path; use napi_derive::napi; + use oxc_allocator::Allocator; use oxc_codegen::CodeGenerator; use oxc_parser::Parser; use oxc_span::SourceType; use oxc_transformer::{ - ArrowFunctionsOptions, ES2015Options, ReactJsxRuntime, ReactOptions, TransformOptions, - Transformer, TypeScriptOptions, + ArrowFunctionsOptions, ES2015Options, ReactJsxRuntime, ReactOptions, Transformer, + TypeScriptOptions, }; #[napi(object)] @@ -92,7 +93,9 @@ impl From for ES2015Options { } #[napi(object)] -pub struct TransformBindingOptions { +pub struct TransformOptions { + #[napi(ts_type = "'script' | 'module' | 'unambiguous' | undefined")] + pub source_type: Option, pub typescript: Option, pub react: Option, pub es2015: Option, @@ -104,13 +107,13 @@ pub struct TransformBindingOptions { pub sourcemap: Option, } -impl From for TransformOptions { - fn from(options: TransformBindingOptions) -> Self { - TransformOptions { +impl From for oxc_transformer::TransformOptions { + fn from(options: TransformOptions) -> Self { + Self { typescript: options.typescript.map(Into::into).unwrap_or_default(), react: options.react.map(Into::into).unwrap_or_default(), es2015: options.es2015.map(Into::into).unwrap_or_default(), - ..TransformOptions::default() + ..Self::default() } } } @@ -137,13 +140,18 @@ pub struct TransformResult { pub fn transform( filename: String, source_text: String, - options: Option, + options: Option, ) -> TransformResult { let sourcemap = options.as_ref().is_some_and(|x| x.sourcemap.unwrap_or_default()); let mut errors = vec![]; - let source_path = Path::new(&filename); - let source_type = SourceType::from_path(source_path).unwrap_or_default(); + let source_type = SourceType::from_path(&filename).unwrap_or_default(); + let source_type = match options.as_ref().and_then(|options| options.source_type.as_deref()) { + Some("script") => source_type.with_script(true), + Some("module") => source_type.with_module(true), + _ => source_type, + }; + let allocator = Allocator::default(); let parser_ret = Parser::new(&allocator, &source_text, source_type).parse(); if !parser_ret.errors.is_empty() { @@ -154,7 +162,7 @@ pub fn transform( let transform_options = options.map(Into::into).unwrap_or_default(); let ret = Transformer::new( &allocator, - source_path, + Path::new(&filename), source_type, &source_text, parser_ret.trivias.clone(), @@ -168,7 +176,7 @@ pub fn transform( let mut codegen = CodeGenerator::new(); if sourcemap { - codegen = codegen.enable_source_map(source_path.to_string_lossy().as_ref(), &source_text); + codegen = codegen.enable_source_map(&filename, &source_text); } let ret = codegen.build(&program);