use serde::Serialize;
#[derive(Debug, Clone, Copy, Serialize, PartialEq, Eq)]
#[allow(dead_code)] pub enum DebLayout {
PerAppInUsrLibNodeApps,
PerAppMinimal,
}
#[derive(Debug, Clone, Serialize)]
pub enum Pattern {
NoWholesaleNodeModulesWhenBundled,
SharedExternalsMatchPin,
PrivateNativeDepsDeclared,
NoBunBuildCompileForBunApps,
PrivateNativeDepsInPrivateModulesDir,
}
#[derive(Debug, Clone, Serialize)]
pub struct Blueprint {
pub version: u32,
pub manifest_schema: u32,
pub shared_externals: &'static [&'static str],
pub apt_dep_chain: &'static [&'static str],
pub deb_layout: DebLayout,
pub patterns: &'static [Pattern],
}
const SHARED_EXTERNALS: &[&str] = &[
"@anthropic-ai/sdk",
"openai",
"@google/genai",
"@mistralai/mistralai",
"zod",
"@ronomon/reed-solomon",
];
const APT_DEP_CHAIN: &[&str] = &["node-app-bun-runtime"];
#[allow(dead_code)] pub const V1: Blueprint = Blueprint {
version: 1,
manifest_schema: 2,
shared_externals: SHARED_EXTERNALS,
apt_dep_chain: APT_DEP_CHAIN,
deb_layout: DebLayout::PerAppInUsrLibNodeApps,
patterns: &[
Pattern::NoWholesaleNodeModulesWhenBundled,
Pattern::SharedExternalsMatchPin,
Pattern::PrivateNativeDepsDeclared,
Pattern::NoBunBuildCompileForBunApps,
],
};
pub const V2: Blueprint = Blueprint {
version: 2,
manifest_schema: 2,
shared_externals: SHARED_EXTERNALS,
apt_dep_chain: APT_DEP_CHAIN,
deb_layout: DebLayout::PerAppMinimal,
patterns: &[
Pattern::NoWholesaleNodeModulesWhenBundled,
Pattern::SharedExternalsMatchPin,
Pattern::PrivateNativeDepsDeclared,
Pattern::NoBunBuildCompileForBunApps,
Pattern::PrivateNativeDepsInPrivateModulesDir,
],
};
pub const CURRENT: Blueprint = V2;
pub const PLATFORM_PACKAGE: &str = "node";
pub fn apt_deps(app_type: &str) -> &'static [&'static str] {
match app_type {
"bun" => &["node-app-bun-runtime"],
"native" => &["node-runtime-abi-1"],
_ => &[],
}
}
pub fn recommends(app_type: &str) -> &'static [&'static str] {
match app_type {
"standalone" => &[PLATFORM_PACKAGE],
_ => &[],
}
}
#[cfg(test)]
mod dep_tests {
use super::*;
#[test]
fn deps_by_app_type_never_reference_econ_v1() {
assert_eq!(apt_deps("bun"), &["node-app-bun-runtime"]);
assert_eq!(apt_deps("native"), &["node-runtime-abi-1"]);
assert!(apt_deps("standalone").is_empty());
assert_eq!(recommends("standalone"), &["node"]);
assert!(recommends("bun").is_empty());
for t in ["bun", "native", "standalone"] {
for dep in apt_deps(t).iter().chain(recommends(t)) {
assert!(!dep.contains("econ-v1"), "{t} dep leaks econ-v1: {dep}");
}
}
assert_eq!(PLATFORM_PACKAGE, "node");
}
}