diff --git a/index.d.cts b/index.d.cts index a363b72..d4afd70 100644 --- a/index.d.cts +++ b/index.d.cts @@ -48,7 +48,7 @@ export class Preprocessor { * @param {PreprocessorOptions | undefined} options * @returns {string} */ - process(src: string, options?: PreprocessorOptions): string; + process(src: string, options?: PreprocessorOptions): { code: string; map: string; }; /** * @param {string} src * @param {PreprocessorOptions | undefined} options diff --git a/index.d.ts b/index.d.ts index 9008018..9f4c6fe 100644 --- a/index.d.ts +++ b/index.d.ts @@ -46,7 +46,7 @@ export class Preprocessor { * @param {PreprocessorOptions | undefined} options * @returns {string} */ - process(src: string, options?: PreprocessorOptions): string; + process(src: string, options?: PreprocessorOptions): { code: string; map: string; }; /** * @param {string} src * @param {PreprocessorOptions | undefined} options diff --git a/package-lock.json b/package-lock.json index 0adcea7..51c43f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "content-tag", - "version": "2.0.2", + "version": "2.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "content-tag", - "version": "2.0.2", + "version": "2.0.3", "license": "MIT", "devDependencies": { "@arethetypeswrong/cli": "^0.13.2", diff --git a/src/bindings.rs b/src/bindings.rs index afd7669..321fe2e 100644 --- a/src/bindings.rs +++ b/src/bindings.rs @@ -54,6 +54,20 @@ impl Options { } } +#[wasm_bindgen(getter_with_clone)] +pub struct CodeMapPair { + pub code: String, + pub map: String, +} + +#[wasm_bindgen] +impl CodeMapPair { + #[wasm_bindgen(constructor)] + pub fn new(code: String, map: String) -> Self { + Self { code, map } + } +} + #[wasm_bindgen] pub struct Preprocessor { // TODO: reusing this between calls result in incorrect spans; there may @@ -123,13 +137,13 @@ impl Preprocessor { Self {} } - pub fn process(&self, src: String, options: JsValue) -> Result { + pub fn process(&self, src: String, options: JsValue) -> Result { let options = Options::new(options); let preprocessor = CorePreprocessor::new(); let result = preprocessor.process(&src, options); match result { - Ok(output) => Ok(output), + Ok(output) => Ok(CodeMapPair::new(output.code, output.map)), Err(err) => Err(as_javascript_error(err, preprocessor.source_map()).into()), } } diff --git a/src/lib.rs b/src/lib.rs index 96701a6..15dc4ba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,11 +7,11 @@ use base64::{engine::general_purpose, Engine as _}; use std::path::PathBuf; use swc_common::comments::SingleThreadedComments; use swc_common::source_map::SourceMapGenConfig; -use swc_common::{self, sync::Lrc, FileName, SourceMap, Mark}; +use swc_common::{self, sync::Lrc, FileName, Mark, SourceMap}; use swc_core::common::GLOBALS; use swc_ecma_ast::{ - Ident, ImportDecl, ImportNamedSpecifier, ImportSpecifier, Module, ModuleDecl, - ModuleExportName, ModuleItem, + Ident, ImportDecl, ImportNamedSpecifier, ImportSpecifier, Module, ModuleDecl, ModuleExportName, + ModuleItem, }; use swc_ecma_codegen::Emitter; use swc_ecma_parser::{lexer::Lexer, Parser, StringInput, Syntax, TsConfig}; @@ -21,9 +21,9 @@ use swc_ecma_visit::{as_folder, VisitMutWith, VisitWith}; use uuid::Uuid; mod bindings; +mod locate; mod snippets; mod transform; -mod locate; #[derive(Default)] pub struct Options { @@ -36,6 +36,11 @@ pub struct Preprocessor { comments: SingleThreadedComments, } +pub struct CodeMapPair { + pub code: String, + pub map: String, +} + struct SourceMapConfig; impl SourceMapGenConfig for SourceMapConfig { fn file_name_to_source(&self, f: &swc_common::FileName) -> String { @@ -47,7 +52,6 @@ impl SourceMapGenConfig for SourceMapConfig { } } - impl Preprocessor { pub fn new() -> Self { Self { @@ -93,7 +97,7 @@ impl Preprocessor { &self, src: &str, options: Options, - ) -> Result { + ) -> Result { let target_specifier = "template"; let target_module = "@ember/template-compiler"; let filename = match options.filename { @@ -116,7 +120,11 @@ impl Preprocessor { GLOBALS.set(&Default::default(), || { let mut parsed_module = parser.parse_module()?; - let id = private_ident!(format!("{}_{}", target_specifier, Uuid::new_v4().to_string().replace("-", ""))); + let id = private_ident!(format!( + "{}_{}", + target_specifier, + Uuid::new_v4().to_string().replace("-", "") + )); let mut needs_import = false; parsed_module.visit_mut_with(&mut as_folder(transform::TransformVisitor::new( &id, @@ -132,13 +140,16 @@ impl Preprocessor { parsed_module.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, false)); - Ok(self.print(&parsed_module, options.inline_source_map)) + let codemap = self.print(&parsed_module, options.inline_source_map); + + Ok(codemap) }) } - fn print(&self, module: &Module, inline_source_map: bool) -> String { + fn print(&self, module: &Module, inline_source_map: bool) -> CodeMapPair { let mut buf = vec![]; let mut srcmap = vec![]; + let mut source_map_buffer = vec![]; let mut emitter = Emitter { cfg: Default::default(), cm: self.source_map.clone(), @@ -152,27 +163,30 @@ impl Preprocessor { }; emitter.emit_module(module).unwrap(); - if inline_source_map { - let mut source_map_buffer = vec![]; - self.source_map() - .build_source_map_with_config(&srcmap, None, SourceMapConfig {}) - .to_writer(&mut source_map_buffer) - .unwrap(); + self.source_map() + .build_source_map_with_config(&srcmap, None, SourceMapConfig {}) + .to_writer(&mut source_map_buffer) + .unwrap(); + if inline_source_map { let mut comment = "//# sourceMappingURL=data:application/json;base64," .to_owned() .into_bytes(); buf.append(&mut comment); let mut encoded = general_purpose::URL_SAFE_NO_PAD - .encode(source_map_buffer) + .encode(source_map_buffer.clone()) .into_bytes(); buf.append(&mut encoded); } let s = String::from_utf8_lossy(&buf); - s.to_string() + + CodeMapPair { + code: s.to_string(), + map: String::from_utf8(source_map_buffer.clone()).unwrap(), + } } pub fn source_map(&self) -> Lrc { @@ -209,7 +223,6 @@ fn insert_import( #[cfg(test)] mod test_helpers; - macro_rules! testcase { ($test_name:ident, $input:expr, $expected:expr) => { #[test] diff --git a/src/main.rs b/src/main.rs index 475bf03..7e43294 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,7 +27,7 @@ fn main() { ); match result { - Ok(output) => println!("{}", output), + Ok(output) => println!("{}", output.code), Err(err) => { let handler = Handler::with_tty_emitter(ColorConfig::Auto, true, false, Some(p.source_map())); diff --git a/src/test_helpers.rs b/src/test_helpers.rs index 0c85c97..c96eac3 100644 --- a/src/test_helpers.rs +++ b/src/test_helpers.rs @@ -11,7 +11,7 @@ pub fn testcase(input: &str, expected: &str) -> Result<(), swc_ecma_parser::erro let re = Regex::new(r"template_[0-9a-f]{32}").unwrap(); let p = Preprocessor::new(); let actual = p.process(input, Default::default())?; - let actual_santized = re.replace_all(&actual, "template_UUID"); + let actual_santized = re.replace_all(&actual.code, "template_UUID"); let normalized_expected = normalize(expected); if actual_santized != normalized_expected { panic!( @@ -19,6 +19,9 @@ pub fn testcase(input: &str, expected: &str) -> Result<(), swc_ecma_parser::erro format!("{}", Changeset::new(&actual_santized, &normalized_expected, "\n")) ); } + + assert!(!actual.map.is_empty(), "expected .map to not be empty"); + Ok(()) } diff --git a/test/parse.test.js b/test/parse.test.js index ac4b25a..2734c3e 100644 --- a/test/parse.test.js +++ b/test/parse.test.js @@ -173,7 +173,7 @@ describe(`parse`, function () { p.process( `const thing = "face";