use std::fs;
use std::path::PathBuf;
use serde_json::Value;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TsConfigProvider {
pub cwd: PathBuf,
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct TsConfigData {
pub options: Value,
pub file_names: Vec<PathBuf>,
pub project_references: Vec<PathBuf>,
}
impl TsConfigProvider {
pub fn new(cwd: impl Into<PathBuf>) -> Self {
Self { cwd: cwd.into() }
}
pub fn get_by_config_filename(&self, config_filename: &str) -> Result<TsConfigData, String> {
let config_path = self.cwd.join(config_filename);
if !config_path.exists() {
return Err(format!(
"Could not find legacy compiler configuration file \"{config_filename}\"."
));
}
let content = fs::read_to_string(&config_path)
.map_err(|error| format!("Failed to read \"{}\": {error}", config_path.display()))?;
let value: Value = serde_json::from_str(&content).map_err(|error| {
format!(
"Failed to parse legacy compiler configuration file \"{}\": {error}",
config_path.display()
)
})?;
let options = value
.get("compilerOptions")
.cloned()
.unwrap_or_else(|| Value::Object(Default::default()));
let file_names = value
.get("files")
.and_then(Value::as_array)
.map(|files| {
files
.iter()
.filter_map(Value::as_str)
.map(PathBuf::from)
.collect()
})
.unwrap_or_default();
let project_references = value
.get("references")
.and_then(Value::as_array)
.map(|refs| {
refs.iter()
.filter_map(|reference| reference.get("path").and_then(Value::as_str))
.map(PathBuf::from)
.collect()
})
.unwrap_or_default();
Ok(TsConfigData {
options,
file_names,
project_references,
})
}
}