use forge::signal::compactor;
use once_cell::sync::Lazy;
use regex::Regex;
static VERSION_HEADER_RE: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?m)^[^\n]*wrangler \d+\.\d+\.\d+[^\n]*\n?").unwrap());
static BUNDLING_RE: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?m)^[^\n]*(Bundling|bundling)[^\n]*\n?").unwrap());
static BINDINGS_HEADER_RE: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"(?m)^Your worker has access to the following bindings:[^\n]*\n?").unwrap()
});
static UPLOAD_FILES_RE: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?m)^[^\n]*Uploaded \d+ files?[^\n]*\n?").unwrap());
static WATCHING_RE: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?m)^[^\n]*(Watching|watching) for[^\n]*\n?").unwrap());
pub fn compress_deploy(raw: &str) -> String {
let cleaned = compactor::normalise(raw);
let s = VERSION_HEADER_RE.replace_all(&cleaned, "");
let s = BUNDLING_RE.replace_all(&s, "");
let s = UPLOAD_FILES_RE.replace_all(&s, "");
let s = WATCHING_RE.replace_all(&s, "");
let useful: Vec<&str> = s
.lines()
.filter(|l| {
let t = l.trim();
!t.is_empty()
&& (t.contains("workers.dev")
|| t.contains("Deployed")
|| t.contains("deployed")
|| t.contains("Total Upload")
|| t.contains("Gzip")
|| t.contains("Script size")
|| t.contains("error")
|| t.contains("Error")
|| t.contains("warn")
|| t.contains("Warn")
|| t.contains("✅")
|| t.contains("✨")
|| t.starts_with("Published")
|| t.starts_with("Binding:"))
})
.collect();
if useful.is_empty() {
return compactor::collapse_blanks(&s);
}
useful.join("\n")
}
pub fn compress_build(raw: &str) -> String {
let cleaned = compactor::normalise(raw);
let s = VERSION_HEADER_RE.replace_all(&cleaned, "");
let s = BUNDLING_RE.replace_all(&s, "");
let s = BINDINGS_HEADER_RE.replace_all(&s, "");
let useful: Vec<&str> = s
.lines()
.filter(|l| {
let t = l.trim();
!t.is_empty()
&& (t.contains("Built")
|| t.contains("Total Upload")
|| t.contains("Gzip")
|| t.contains("output")
|| t.contains("error")
|| t.contains("Error")
|| t.contains("warn"))
})
.collect();
if useful.is_empty() {
return compactor::collapse_blanks(&s);
}
useful.join("\n")
}
pub fn compress_dev(raw: &str) -> String {
let cleaned = compactor::normalise(raw);
let s = VERSION_HEADER_RE.replace_all(&cleaned, "");
compactor::collapse_blanks(&s)
}
pub fn compress_tail(raw: &str) -> String {
let cleaned = compactor::normalise(raw);
let lines: Vec<&str> = cleaned
.lines()
.filter(|l| {
let t = l.trim();
!t.is_empty()
&& !t.starts_with("Connected to")
&& !t.starts_with("Waiting for")
&& !t.contains("Listening on")
})
.collect();
if lines.len() > 50 {
return format!(
"{}\n… [{} more log lines] …",
lines[..50].join("\n"),
lines.len() - 50
);
}
lines.join("\n")
}
pub fn compress_storage(raw: &str) -> String {
let cleaned = compactor::normalise(raw);
let s = VERSION_HEADER_RE.replace_all(&cleaned, "");
compactor::collapse_blanks(&s)
}
pub fn compress_wrangler(subcmd: &str, raw: &str) -> String {
let sub = subcmd.trim();
if sub.starts_with("deploy") || sub.starts_with("publish") {
return compress_deploy(raw);
}
if sub.starts_with("build") {
return compress_build(raw);
}
if sub.starts_with("dev") {
return compress_dev(raw);
}
if sub.starts_with("tail") {
return compress_tail(raw);
}
if sub.starts_with("kv") || sub.starts_with("r2") || sub.starts_with("d1") {
return compress_storage(raw);
}
let cleaned = compactor::normalise(raw);
let s = VERSION_HEADER_RE.replace_all(&cleaned, "");
compactor::collapse_blanks(&s)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deploy_keeps_url_and_size() {
let raw = "⛅️ wrangler 3.40.0\n--------------------\nTotal Upload: 42.3 KiB / gzip: 12.1 KiB\nUploaded my-worker (1.23 sec)\nPublished my-worker (0.45 sec)\n https://my-worker.my-account.workers.dev\n";
let out = compress_deploy(raw);
assert!(out.contains("workers.dev"), "{out}");
assert!(out.contains("Total Upload"), "{out}");
assert!(out.contains("Published"), "{out}");
}
#[test]
fn deploy_strips_bundling_noise() {
let raw = "⛅️ wrangler 3.40.0\nBundling with esbuild...\nTotal Upload: 10 KiB / gzip: 4 KiB\nPublished worker (0.5 sec)\n https://worker.example.workers.dev\n";
let out = compress_deploy(raw);
assert!(!out.contains("Bundling"), "{out}");
assert!(!out.contains("wrangler 3"), "{out}");
assert!(out.contains("Total Upload"), "{out}");
}
#[test]
fn tail_truncates_long_log_stream() {
let lines: Vec<String> = (0..60)
.map(|i| format!("{{\"level\":\"log\",\"message\":\"event-{i}\"}}"))
.collect();
let out = compress_tail(&lines.join("\n"));
assert!(out.contains("more log lines"), "{out}");
}
#[test]
fn tail_strips_connection_lines() {
let raw = "Connected to my-worker at https://...\nWaiting for logs...\n{\"level\":\"log\",\"message\":\"hello\"}\n";
let out = compress_tail(raw);
assert!(!out.contains("Connected to"), "{out}");
assert!(!out.contains("Waiting for"), "{out}");
assert!(out.contains("hello"), "{out}");
}
}