use crate::protocols::VersionProtocol;
use crate::{FxIndexMap, import_export::*};
use rustc_hash::FxHashMap;
use serde::Deserialize;
use std::collections::BTreeMap;
use std::path::PathBuf;
pub type DependenciesMap<T> = BTreeMap<String, T>;
pub type EnginesMap = FxIndexMap<String, VersionProtocol>;
pub type ScriptsMap = FxIndexMap<String, String>;
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[serde(rename_all = "camelCase")]
pub struct PackageJson {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[cfg(feature = "protocols")]
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<semver::Version>,
#[cfg(not(feature = "protocols"))]
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "type")]
pub type_of: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scripts: Option<ScriptsMap>,
#[serde(skip_serializing_if = "Option::is_none")]
pub main: Option<PathBuf>,
#[serde(skip_serializing_if = "Option::is_none")]
pub module: Option<PathBuf>,
#[serde(skip_serializing_if = "Option::is_none")]
pub browser: Option<BrowserField>,
#[serde(skip_serializing_if = "Option::is_none")]
pub imports: Option<ImportExportMap>,
#[serde(skip_serializing_if = "Option::is_none")]
pub exports: Option<ImportExportField>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dependencies: Option<DependenciesMap<VersionProtocol>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dependencies_meta: Option<DependenciesMap<DependencyMetaField>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dev_dependencies: Option<DependenciesMap<VersionProtocol>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub peer_dependencies: Option<DependenciesMap<VersionProtocol>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub peer_dependencies_meta: Option<DependenciesMap<PeerDependencyMetaField>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bundle_dependencies: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub optional_dependencies: Option<DependenciesMap<VersionProtocol>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub resolutions: Option<DependenciesMap<VersionProtocol>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dev_engines: Option<DevEnginesField>,
#[serde(skip_serializing_if = "Option::is_none")]
pub engines: Option<EnginesMap>,
#[serde(skip_serializing_if = "Option::is_none")]
pub package_manager: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub workspaces: Option<WorkspacesField>,
#[serde(skip_serializing_if = "Option::is_none")]
pub catalog: Option<DependenciesMap<VersionProtocol>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub catalogs: Option<BTreeMap<String, DependenciesMap<VersionProtocol>>>,
#[serde(flatten)]
pub other_fields: FxHashMap<String, serde_json::Value>,
}
#[derive(Clone, Debug, Deserialize, PartialEq)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[serde(untagged)]
pub enum BrowserField {
String(String),
Map(FxHashMap<PathBuf, serde_json::Value>),
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[serde(rename_all = "camelCase")]
pub struct DependencyMetaField {
#[serde(skip_serializing_if = "Option::is_none")]
pub injected: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub built: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub optional: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub unplugged: Option<bool>,
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[serde(rename_all = "camelCase")]
pub struct PeerDependencyMetaField {
#[serde(skip_serializing_if = "Option::is_none")]
pub optional: Option<bool>,
}
#[derive(Clone, Debug, Deserialize, PartialEq)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[serde(untagged, rename_all = "camelCase")]
pub enum WorkspacesField {
Globs(Vec<String>),
Config {
#[serde(skip_serializing_if = "Option::is_none")]
catalog: Option<DependenciesMap<VersionProtocol>>,
#[serde(skip_serializing_if = "Option::is_none")]
catalogs: Option<BTreeMap<String, DependenciesMap<VersionProtocol>>>,
packages: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
nohoist: Option<Vec<String>>,
},
}
#[derive(Clone, Debug, Deserialize, PartialEq)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[serde(untagged)]
pub enum OneOrMany<T> {
One(T),
Many(Vec<T>),
}
impl<T> OneOrMany<T> {
pub fn list(&self) -> Vec<&T> {
match self {
Self::One(inner) => vec![inner],
Self::Many(inner) => Vec::from_iter(inner),
}
}
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[serde(rename_all = "camelCase")]
pub struct DevEngineField {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub on_fail: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<VersionProtocol>,
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[serde(rename_all = "camelCase")]
pub struct DevEnginesField {
#[serde(skip_serializing_if = "Option::is_none")]
pub cpu: Option<OneOrMany<DevEngineField>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub libc: Option<OneOrMany<DevEngineField>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub os: Option<OneOrMany<DevEngineField>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub package_manager: Option<OneOrMany<DevEngineField>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub runtime: Option<OneOrMany<DevEngineField>>,
}