fn0-ski 0.1.2

Minimal Winter CG Compatible Runtime
use base64::prelude::*;

const SOURCE_MAP_PREFIX: &[u8] =
    b"//# sourceMappingURL=data:application/json;charset=utf-8;base64,";

pub fn extract_source_map(code: &[u8]) -> Option<Vec<u8>> {
    let range = find_source_map_range(code)?;
    let source_map_comment = &code[range];
    let base64_data = source_map_comment.split_at(SOURCE_MAP_PREFIX.len()).1;
    BASE64_STANDARD.decode(base64_data).ok()
}

fn find_source_map_range(code: &[u8]) -> Option<std::ops::Range<usize>> {
    fn last_non_blank_line_range(code: &[u8]) -> Option<std::ops::Range<usize>> {
        let mut hit_non_whitespace = false;
        let mut end = code.len();
        for i in (0..code.len()).rev() {
            let is_whitespace =
                code[i] == b' ' || code[i] == b'\t' || code[i] == b'\r' || code[i] == b'\n';
            if !hit_non_whitespace && is_whitespace {
                end = i;
            }
            hit_non_whitespace = hit_non_whitespace || !is_whitespace;
            if hit_non_whitespace && code[i] == b'\n' {
                return Some(i + 1..end);
            }
        }
        if hit_non_whitespace {
            return Some(0..end);
        }
        None
    }

    let range = last_non_blank_line_range(code)?;
    if code[range.clone()].starts_with(SOURCE_MAP_PREFIX) {
        Some(range)
    } else {
        None
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_extract_source_map() {
        let code = b"console.log('hello');\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozfQ==";
        let result = extract_source_map(code);
        assert!(result.is_some());
        let decoded = result.unwrap();
        assert_eq!(decoded, b"{\"version\":3}");
    }

    #[test]
    fn test_no_source_map() {
        let code = b"console.log('hello');";
        let result = extract_source_map(code);
        assert!(result.is_none());
    }

    #[test]
    fn test_with_trailing_newline() {
        let code = b"console.log('hello');\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozfQ==\n";
        let result = extract_source_map(code);
        assert!(result.is_some());
    }
}