lean_ctx_patterns/
prisma.rs1use crate::ansi::strip_ansi;
4
5pub fn compress(cmd: &str, output: &str) -> Option<String> {
6 let trimmed = output.trim();
7 if trimmed.is_empty() {
8 return Some("ok".to_string());
9 }
10
11 if cmd.contains("generate") {
12 return Some(compress_generate(trimmed));
13 }
14 if cmd.contains("migrate") {
15 return Some(compress_migrate(trimmed));
16 }
17 if cmd.contains("db push") || cmd.contains("db pull") {
18 return Some(compress_db_sync(trimmed));
19 }
20 if cmd.contains("studio") {
21 return Some("Prisma Studio started".to_string());
22 }
23 if cmd.contains("format") {
24 return Some(compress_format(trimmed));
25 }
26 if cmd.contains("validate") {
27 return Some(compress_validate(trimmed));
28 }
29
30 Some(compact_lines(trimmed, 10))
31}
32
33fn compress_generate(output: &str) -> String {
34 let mut generated = Vec::new();
35 for line in output.lines() {
36 let trimmed = line.trim();
37 let plain = strip_ansi(trimmed);
38 if plain.contains("Generated") || plain.contains("generated") {
39 generated.push(plain);
40 }
41 }
42 if generated.is_empty() {
43 return strip_noise(output);
44 }
45 generated.join("\n")
46}
47
48fn compress_migrate(output: &str) -> String {
49 let mut results = Vec::new();
50 let mut migration_name = String::new();
51
52 for line in output.lines() {
53 let plain = strip_ansi(line.trim());
54 if plain.contains("migration") && plain.contains("created") {
55 migration_name.clone_from(&plain);
56 }
57 if plain.contains("applied")
58 || plain.contains("Already in sync")
59 || plain.contains("Database is up to date")
60 {
61 results.push(plain);
62 }
63 }
64
65 if results.is_empty() && migration_name.is_empty() {
66 return strip_noise(output);
67 }
68
69 let mut parts = Vec::new();
70 if !migration_name.is_empty() {
71 parts.push(migration_name);
72 }
73 parts.extend(results);
74 parts.join("\n")
75}
76
77fn compress_db_sync(output: &str) -> String {
78 let lines: Vec<String> = output
79 .lines()
80 .map(|l| strip_ansi(l.trim()))
81 .filter(|l| !l.is_empty() && !l.contains("warn") && !l.starts_with("Prisma schema"))
82 .collect();
83
84 if lines.is_empty() {
85 return "ok (synced)".to_string();
86 }
87 lines.join("\n")
88}
89
90fn compress_format(output: &str) -> String {
91 if output.contains("already formatted") || output.contains("unchanged") {
92 return "ok (already formatted)".to_string();
93 }
94 strip_noise(output)
95}
96
97fn compress_validate(output: &str) -> String {
98 let plain = strip_ansi(output.trim());
99 if plain.contains("valid") && !plain.contains("invalid") {
100 return "ok (schema valid)".to_string();
101 }
102 compact_lines(&plain, 10)
103}
104
105fn strip_noise(output: &str) -> String {
106 output
107 .lines()
108 .map(|l| strip_ansi(l.trim()))
109 .filter(|l| !l.is_empty() && !l.contains("████") && !l.contains("▀") && !l.contains("━"))
110 .collect::<Vec<_>>()
111 .join("\n")
112}
113
114fn compact_lines(text: &str, max: usize) -> String {
115 let lines: Vec<&str> = text.lines().filter(|l| !l.trim().is_empty()).collect();
116 if lines.len() <= max {
117 return lines.join("\n");
118 }
119 format!(
120 "{}\n{}",
121 lines[..max].join("\n"),
122 super::elision_marker(lines.len() - max)
123 )
124}