Skip to main content

lean_ctx_patterns/
prisma.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use 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}