mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
fix(sourcemap): using serde_json::to_string to quote sourcemap string (#2889)
This commit is contained in:
parent
21a5e4433f
commit
28fae2e80a
6 changed files with 60 additions and 17 deletions
|
|
@ -33,7 +33,7 @@ fn main() -> std::io::Result<()> {
|
|||
.build(&ret.program);
|
||||
|
||||
if let Some(source_map) = source_map {
|
||||
let result = source_map.to_json_string();
|
||||
let result = source_map.to_json_string().unwrap();
|
||||
let hash = BASE64_STANDARD.encode(format!(
|
||||
"{}\0{}{}\0{}",
|
||||
source_text.len(),
|
||||
|
|
|
|||
|
|
@ -130,5 +130,5 @@ fn test_concat_sourcemap_builder() {
|
|||
])
|
||||
);
|
||||
|
||||
assert_eq!(sm.to_json_string(), sm.to_json_string());
|
||||
assert_eq!(sm.to_json_string().unwrap(), sm.to_json_string().unwrap());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use crate::error::{Error, Result};
|
||||
/// Port from https://github.com/getsentry/rust-sourcemap/blob/master/src/encoder.rs
|
||||
/// It is a helper for encode `SourceMap` to vlq sourcemap string, but here some different.
|
||||
/// - Quote `source_content` at parallel.
|
||||
|
|
@ -5,7 +6,9 @@
|
|||
use crate::{token::TokenChunk, SourceMap, Token};
|
||||
use rayon::prelude::*;
|
||||
|
||||
pub fn encode(sourcemap: &SourceMap) -> String {
|
||||
// Here using `serde_json::to_string` to serialization `names/source_contents/sources`.
|
||||
// It will escape the string to avoid invalid JSON string.
|
||||
pub fn encode(sourcemap: &SourceMap) -> Result<String> {
|
||||
let mut buf = String::new();
|
||||
buf.push_str("{\"version\":3,");
|
||||
if let Some(file) = sourcemap.get_file() {
|
||||
|
|
@ -14,20 +17,35 @@ pub fn encode(sourcemap: &SourceMap) -> String {
|
|||
buf.push_str("\",");
|
||||
}
|
||||
buf.push_str("\"names\":[");
|
||||
buf.push_str(&sourcemap.names.iter().map(|x| format!("{x:?}")).collect::<Vec<_>>().join(","));
|
||||
let names = sourcemap
|
||||
.names
|
||||
.iter()
|
||||
.map(|x| serde_json::to_string(x.as_ref()))
|
||||
.collect::<std::result::Result<Vec<_>, serde_json::Error>>()
|
||||
.map_err(Error::from)?;
|
||||
buf.push_str(&names.join(","));
|
||||
buf.push_str("],\"sources\":[");
|
||||
buf.push_str(&sourcemap.sources.iter().map(|x| format!("{x:?}")).collect::<Vec<_>>().join(","));
|
||||
let sources = sourcemap
|
||||
.sources
|
||||
.iter()
|
||||
.map(|x| serde_json::to_string(x.as_ref()))
|
||||
.collect::<std::result::Result<Vec<_>, serde_json::Error>>()
|
||||
.map_err(Error::from)?;
|
||||
buf.push_str(&sources.join(","));
|
||||
// Quote `source_content` at parallel.
|
||||
if let Some(source_contents) = &sourcemap.source_contents {
|
||||
buf.push_str("],\"sourcesContent\":[");
|
||||
buf.push_str(
|
||||
&source_contents.par_iter().map(|x| format!("{x:?}")).collect::<Vec<_>>().join(","),
|
||||
);
|
||||
let quote_source_contents = source_contents
|
||||
.par_iter()
|
||||
.map(|x| serde_json::to_string(x.as_ref()))
|
||||
.collect::<std::result::Result<Vec<_>, serde_json::Error>>()
|
||||
.map_err(Error::from)?;
|
||||
buf.push_str("e_source_contents.join(","));
|
||||
}
|
||||
buf.push_str("],\"mappings\":\"");
|
||||
buf.push_str(&serialize_sourcemap_mappings(sourcemap));
|
||||
buf.push_str("\"}");
|
||||
buf
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
|
|
@ -130,9 +148,26 @@ fn test_encode() {
|
|||
"mappings": "AAAA,GAAIA,GAAI,EACR,IAAIA,GAAK,EAAG,CACVC,MAAM"
|
||||
}"#;
|
||||
let sm = SourceMap::from_json_string(input).unwrap();
|
||||
let sm2 = SourceMap::from_json_string(&sm.to_json_string()).unwrap();
|
||||
let sm2 = SourceMap::from_json_string(&sm.to_json_string().unwrap()).unwrap();
|
||||
|
||||
for (tok1, tok2) in sm.get_tokens().zip(sm2.get_tokens()) {
|
||||
assert_eq!(tok1, tok2);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encode_escape_string() {
|
||||
// '\0' should be escaped.
|
||||
let sm = SourceMap::new(
|
||||
None,
|
||||
vec!["\0".into()],
|
||||
vec!["\0".into()],
|
||||
Some(vec!["\0".into()]),
|
||||
vec![],
|
||||
None,
|
||||
);
|
||||
assert_eq!(
|
||||
sm.to_json_string().unwrap(),
|
||||
r#"{"version":3,"names":["\u0000"],"sources":["\u0000"],"sourcesContent":["\u0000"],"mappings":""}"#
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,21 +31,29 @@ impl SourceMap {
|
|||
}
|
||||
|
||||
/// Convert `SourceMap` to vlq sourcemap string.
|
||||
#[allow(clippy::missing_errors_doc)]
|
||||
/// # Errors
|
||||
///
|
||||
/// The `serde_json` deserialize Error.
|
||||
pub fn from_json_string(value: &str) -> Result<Self> {
|
||||
decode(value)
|
||||
}
|
||||
|
||||
/// Convert the vlq sourcemap string to `SourceMap`.
|
||||
pub fn to_json_string(&self) -> String {
|
||||
/// # Errors
|
||||
///
|
||||
/// The `serde_json` serialization Error.
|
||||
pub fn to_json_string(&self) -> Result<String> {
|
||||
encode(self)
|
||||
}
|
||||
|
||||
/// Convert `SourceMap` to vlq sourcemap data url.
|
||||
pub fn to_data_url(&self) -> String {
|
||||
/// # Errors
|
||||
///
|
||||
/// The `serde_json` serialization Error.
|
||||
pub fn to_data_url(&self) -> Result<String> {
|
||||
let base_64_str =
|
||||
base64_simd::Base64::STANDARD.encode_to_boxed_str(self.to_json_string().as_bytes());
|
||||
format!("data:application/json;charset=utf-8;base64,{base_64_str}")
|
||||
base64_simd::Base64::STANDARD.encode_to_boxed_str(self.to_json_string()?.as_bytes());
|
||||
Ok(format!("data:application/json;charset=utf-8;base64,{base_64_str}"))
|
||||
}
|
||||
|
||||
pub fn get_file(&self) -> Option<&str> {
|
||||
|
|
|
|||
|
|
@ -85,5 +85,5 @@ fn test_sourcemap_builder() {
|
|||
|
||||
let expected =
|
||||
r#"{"version":3,"names":["x"],"sources":["baz.js"],"sourcesContent":[""],"mappings":""}"#;
|
||||
assert_eq!(expected, sm.to_json_string());
|
||||
assert_eq!(expected, sm.to_json_string().unwrap());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ fn bench_sourcemap(criterion: &mut Criterion) {
|
|||
for i in 0..1 {
|
||||
concat_sourcemap_builder.add_sourcemap(&sourcemap, line * i);
|
||||
}
|
||||
concat_sourcemap_builder.into_sourcemap().to_json_string();
|
||||
concat_sourcemap_builder.into_sourcemap().to_json_string().unwrap();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue