Skip to content

Commit f6e42b6

Browse files
authored
feat(sourcemap): Add support for sourcemap debug IDs (#6221)
The sourcemap [`debugId` proposal](https://github.com/tc39/source-map/blob/main/proposals/debug-id.md) adds globally unique build or debug IDs to source maps and generated code, making build artifacts self-identifying. Support for debug IDs was added to [`rust-sourcemap`](getsentry/rust-sourcemap#66) in 2023 and Sentry have made use of this to aid in matching up source and sourcemap files without having to worry about path mismatches or release versions. I want to add debug ID support to Rolldown but it uses `oxc::sourcemap` so it looks like I need to start here first!
1 parent 9e62396 commit f6e42b6

File tree

3 files changed

+22
-1
lines changed

3 files changed

+22
-1
lines changed

crates/oxc_sourcemap/src/decode.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ pub struct JSONSourceMap {
2323
pub sources_content: Option<Vec<Option<String>>>,
2424
/// A list of symbol names used by the “mappings” entry.
2525
pub names: Vec<String>,
26+
/// An optional field containing the debugId for this sourcemap.
27+
pub debug_id: Option<String>,
2628
}
2729

2830
pub fn decode(json: JSONSourceMap) -> Result<SourceMap> {
@@ -38,6 +40,7 @@ pub fn decode(json: JSONSourceMap) -> Result<SourceMap> {
3840
tokens,
3941
token_chunks: None,
4042
x_google_ignore_list: None,
43+
debug_id: json.debug_id,
4144
})
4245
}
4346

crates/oxc_sourcemap/src/encode.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub fn encode(sourcemap: &SourceMap) -> JSONSourceMap {
2121
.as_ref()
2222
.map(|x| x.iter().map(ToString::to_string).map(Some).collect()),
2323
names: sourcemap.names.iter().map(ToString::to_string).collect(),
24+
debug_id: sourcemap.get_debug_id().map(ToString::to_string),
2425
}
2526
}
2627

@@ -76,6 +77,12 @@ pub fn encode_to_string(sourcemap: &SourceMap) -> String {
7677

7778
contents.push("],\"mappings\":\"".into());
7879
contents.push(serialize_sourcemap_mappings(sourcemap).into());
80+
81+
if let Some(debug_id) = sourcemap.get_debug_id() {
82+
contents.push("\",\"debugId\":\"".into());
83+
contents.push(debug_id.into());
84+
}
85+
7986
contents.push("\"}".into());
8087

8188
// Check we calculated number of segments required correctly
@@ -401,9 +408,10 @@ fn test_encode_escape_string() {
401408
None,
402409
);
403410
sm.set_x_google_ignore_list(vec![0]);
411+
sm.set_debug_id("56431d54-c0a6-451d-8ea2-ba5de5d8ca2e");
404412
assert_eq!(
405413
sm.to_json_string(),
406-
r#"{"version":3,"names":["name_length_greater_than_16_\u0000"],"sources":["\u0000"],"sourcesContent":["emoji-👀-\u0000"],"x_google_ignoreList":[0],"mappings":""}"#
414+
r#"{"version":3,"names":["name_length_greater_than_16_\u0000"],"sources":["\u0000"],"sourcesContent":["emoji-👀-\u0000"],"x_google_ignoreList":[0],"mappings":"","debugId":"56431d54-c0a6-451d-8ea2-ba5de5d8ca2e"}"#
407415
);
408416
}
409417

crates/oxc_sourcemap/src/sourcemap.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub struct SourceMap {
2121
/// The `x_google_ignoreList` field refers to the `sources` array, and lists the indices of all the known third-party sources in that source map.
2222
/// When parsing the source map, developer tools can use this to determine sections of the code that the browser loads and runs that could be automatically ignore-listed.
2323
pub(crate) x_google_ignore_list: Option<Vec<u32>>,
24+
pub(crate) debug_id: Option<String>,
2425
}
2526

2627
#[allow(clippy::cast_possible_truncation)]
@@ -43,6 +44,7 @@ impl SourceMap {
4344
tokens,
4445
token_chunks,
4546
x_google_ignore_list: None,
47+
debug_id: None,
4648
}
4749
}
4850

@@ -95,6 +97,14 @@ impl SourceMap {
9597
self.x_google_ignore_list = Some(x_google_ignore_list);
9698
}
9799

100+
pub fn set_debug_id(&mut self, debug_id: &str) {
101+
self.debug_id = Some(debug_id.into());
102+
}
103+
104+
pub fn get_debug_id(&self) -> Option<&str> {
105+
self.debug_id.as_deref()
106+
}
107+
98108
pub fn get_names(&self) -> impl Iterator<Item = &str> {
99109
self.names.iter().map(AsRef::as_ref)
100110
}

0 commit comments

Comments
 (0)