pub(super) fn normalize_legacy_collection_header(input: &str) -> String {
let lines: Vec<&str> = input.lines().collect();
let Some(section_index) = lines.iter().position(|line| line.trim() == "---") else {
return input.to_string();
};
let mut header_indices = Vec::new();
let mut syntax_start = None;
for (index, line) in lines.iter().take(section_index).enumerate() {
let trimmed = line.trim();
if trimmed.is_empty() {
continue;
}
if is_collection_preamble_line(trimmed) {
syntax_start = Some(index);
break;
}
if is_request_line(trimmed) {
return input.to_string();
}
header_indices.push(index);
}
if header_indices.is_empty() {
return input.to_string();
}
if lines
.iter()
.take(section_index)
.enumerate()
.filter(|(index, _)| Some(*index) >= syntax_start)
.any(|(_, line)| {
let trimmed = line.trim();
!trimmed.is_empty() && !is_collection_preamble_line(trimmed)
})
{
return input.to_string();
}
let mut rewritten: Vec<String> = lines.iter().map(|line| (*line).to_string()).collect();
rewritten[header_indices[0]] = format!("name = {}", lines[header_indices[0]].trim());
if header_indices.len() > 1 {
let description = header_indices[1..]
.iter()
.map(|index| lines[*index].trim())
.collect::<Vec<_>>()
.join(" ");
rewritten[header_indices[1]] = format!("description = {}", description);
for index in &header_indices[2..] {
rewritten[*index].clear();
}
}
let mut output = rewritten.join("\n");
if input.ends_with('\n') {
output.push('\n');
}
output
}
fn is_collection_preamble_line(line: &str) -> bool {
let trimmed = line.trim_start();
trimmed.starts_with("name")
|| trimmed.starts_with("description")
|| trimmed.starts_with("env ")
|| trimmed.starts_with('$')
|| trimmed.starts_with('*')
|| trimmed.starts_with('?')
|| trimmed.starts_with('!')
|| trimmed.starts_with("scalar ")
|| trimmed.starts_with("schema ")
}
fn is_request_line(line: &str) -> bool {
let trimmed = line.trim_start();
trimmed.starts_with("GET ")
|| trimmed.starts_with("PUT ")
|| trimmed.starts_with("POST ")
|| trimmed.starts_with("PATCH ")
|| trimmed.starts_with("DELETE ")
|| trimmed.starts_with("OPTIONS ")
|| trimmed.starts_with("protocol ")
|| trimmed.starts_with("session ")
|| trimmed.starts_with("operation ")
|| trimmed.starts_with("variables ")
|| trimmed.starts_with("call ")
|| trimmed.starts_with("tool ")
|| trimmed.starts_with("arguments ")
|| trimmed == "receive"
|| trimmed.starts_with("within ")
|| trimmed.starts_with("protocol_version ")
|| trimmed.starts_with("client_name ")
|| trimmed.starts_with("client_version ")
|| trimmed.starts_with("capabilities ")
|| trimmed.starts_with('~')
|| trimmed.starts_with('&')
|| trimmed.starts_with('^')
|| trimmed.starts_with("<<")
|| trimmed.starts_with('>')
}