/
githubmirror
/
deno
Обзор
Документация
Войти
/
githubmirror
/
deno
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
cli/lib/args.rs
322 строки
10 KB
Bartek Iwańczuk
chore: remove the dead forked typescript-go integration (#35935)
10 июл 2026, 20:29
Не верифицирован
10 июл 2026, 20:29
1e4b28c
Код
Авторство
О чём код?
// Copyright 2018-2026 the Deno authors. MIT license. use std::io::BufReader; use std::io::Cursor; use std::path::Path; use std::path::PathBuf; use base64::prelude::BASE64_STANDARD; use base64::prelude::Engine; use deno_npm::resolution::PackageIdNotFoundError; use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot; use deno_npm_installer::process_state::NpmProcessState; use deno_npm_installer::process_state::NpmProcessStateFromEnvVarSys; use deno_npm_installer::process_state::NpmProcessStateKind; use deno_runtime::UNSTABLE_ENV_VAR_NAMES; use deno_runtime::colors; use deno_runtime::deno_node::ops::ipc::ChildIpcSerialization; use deno_runtime::deno_tls::deno_native_certs::load_native_certs; use deno_runtime::deno_tls::rustls; use deno_runtime::deno_tls::rustls::RootCertStore; use deno_runtime::deno_tls::rustls_pemfile; use deno_runtime::deno_tls::webpki_roots; use deno_semver::npm::NpmPackageReqReference; use serde::Deserialize; use serde::Serialize; use sys_traits::EnvVar; use thiserror::Error; pub fn npm_pkg_req_ref_to_binary_command( req_ref: &NpmPackageReqReference, ) -> &str { req_ref.sub_path().unwrap_or_else(|| &req_ref.req().name) } pub fn has_trace_permissions_enabled(sys: &impl EnvVar) -> bool { has_flag_env_var(sys, "DENO_TRACE_PERMISSIONS") } pub fn has_flag_env_var(sys: &impl EnvVar, name: &str) -> bool { match sys.env_var_os(name) { Some(value) => value == "1", None => false, } } /// Reads the node IPC channel configuration that `node:child_process.fork()` /// passes to a child process through `NODE_CHANNEL_FD` (and the optional /// `NODE_CHANNEL_SERIALIZATION_MODE`), returning the channel fd and /// serialization mode so the child can wire up `process.send()` / /// `process.on("message")`. The env vars are removed once read so they don't /// leak into grandchild processes. Returns `Ok(None)` when no channel was set. /// /// Shared by the `deno` CLI and the standalone (`denort`) runtime so the two /// entry points can't drift; the latter relies on this for IPC to work in a /// compiled binary's forked child (issue #26304). pub fn node_ipc_init( sys: &impl EnvVar, ) -> Result< Option<(i64, ChildIpcSerialization)>, deno_runtime::deno_core::anyhow::Error, > { let maybe_node_channel_fd = sys.env_var("NODE_CHANNEL_FD").ok(); let maybe_node_channel_serialization = if let Ok(serialization) = sys.env_var("NODE_CHANNEL_SERIALIZATION_MODE") { Some(serialization.parse::<ChildIpcSerialization>()?) } else { None }; if let Some(node_channel_fd) = maybe_node_channel_fd { // Remove so that child processes don't inherit these environment variables. // SAFETY: single-threaded at this point in startup unsafe { std::env::remove_var("NODE_CHANNEL_FD"); std::env::remove_var("NODE_CHANNEL_SERIALIZATION_MODE"); } let node_channel_fd = node_channel_fd.parse::<i64>()?; Ok(Some(( node_channel_fd, maybe_node_channel_serialization.unwrap_or(ChildIpcSerialization::Json), ))) } else { Ok(None) } } #[derive(Clone, Debug, Eq, PartialEq)] pub enum CaData { /// The string is a file path File(String), /// The string holds the actual certificate Bytes(Vec<u8>), } impl CaData { pub fn parse(input: String) -> Option<Self> { if let Some(x) = input.strip_prefix("base64:") { Some(CaData::Bytes(BASE64_STANDARD.decode(x).ok()?)) } else { Some(CaData::File(input)) } } } #[derive(Error, Debug, Clone, deno_error::JsError)] #[class(generic)] pub enum RootCertStoreLoadError { #[error( "Unknown certificate store \"{0}\" specified (allowed: \"system,mozilla\")" )] UnknownStore(String), #[error("Unable to add pem file to certificate store: {0}")] FailedAddPemFile(String), #[error("Failed opening CA file: {0}")] CaFileOpenError(String), #[error("Failed to load platform certificates: {0}")] FailedNativeCerts(String), } fn load_pem_certs( path: &Path, ) -> Result<Vec<rustls::pki_types::CertificateDer<'static>>, std::io::Error> { let file: std::fs::File = std::fs::File::open(path)?; let mut reader: BufReader<std::fs::File> = BufReader::new(file); rustls_pemfile::certs(&mut reader).collect() } /// Create and populate a root cert store based on the passed options and /// environment. pub fn get_root_cert_store( sys: &impl EnvVar, maybe_root_path: Option<PathBuf>, maybe_ca_stores: Option<Vec<String>>, maybe_ca_data: Option<CaData>, ) -> Result<RootCertStore, RootCertStoreLoadError> { let mut root_cert_store = RootCertStore::empty(); let ca_stores: Vec<String> = maybe_ca_stores .or_else(|| { let env_ca_store = sys.env_var("DENO_TLS_CA_STORE").ok()?; Some( env_ca_store .split(',') .map(|s| s.trim().to_string()) .filter(|s| !s.is_empty()) .collect(), ) }) .unwrap_or_else(|| vec!["mozilla".to_string()]); for store in ca_stores.iter() { match store.as_str() { "mozilla" => { root_cert_store.extend(webpki_roots::TLS_SERVER_ROOTS.to_vec()); } "system" => { let roots = load_native_certs().map_err(|err| { RootCertStoreLoadError::FailedNativeCerts(err.to_string()) })?; for root in roots { if let Err(err) = root_cert_store .add(rustls::pki_types::CertificateDer::from(root.0.clone())) { log::error!( "{}", colors::yellow(&format!( "Unable to add system certificate to certificate store: {:?}", err )) ); let hex_encoded_root = faster_hex::hex_string(&root.0); log::error!("{}", colors::gray(&hex_encoded_root)); } } } _ => { return Err(RootCertStoreLoadError::UnknownStore(store.clone())); } } } let ca_data = maybe_ca_data .or_else(|| sys.env_var("DENO_CERT").ok().and_then(CaData::parse)); if let Some(ca_data) = ca_data { let result = match ca_data { CaData::File(ca_file) => { let ca_file = if let Some(root) = &maybe_root_path { root.join(&ca_file) } else { PathBuf::from(ca_file) }; let certfile = std::fs::File::open(ca_file).map_err(|err| { RootCertStoreLoadError::CaFileOpenError(err.to_string()) })?; let mut reader = BufReader::new(certfile); rustls_pemfile::certs(&mut reader).collect::<Result<Vec<_>, _>>() } CaData::Bytes(data) => { let mut reader = BufReader::new(Cursor::new(data)); rustls_pemfile::certs(&mut reader).collect::<Result<Vec<_>, _>>() } }; match result { Ok(certs) => { root_cert_store.add_parsable_certificates(certs); } Err(e) => { return Err(RootCertStoreLoadError::FailedAddPemFile(e.to_string())); } } } if let Ok(extra_ca_certs_path) = sys.env_var("NODE_EXTRA_CA_CERTS") && !extra_ca_certs_path.is_empty() { let path: PathBuf = maybe_root_path.as_ref().map_or_else( || PathBuf::from(&extra_ca_certs_path), |root| root.join(&extra_ca_certs_path), ); match load_pem_certs(&path) { Ok(certs) => { root_cert_store.add_parsable_certificates(certs); } Err(e) => log::warn!( "{}", colors::yellow(&format!( "Warning: Ignoring extra certs from \"{extra_ca_certs_path}\", load failed: {e}" )) ), } } Ok(root_cert_store) } pub fn npm_process_state( sys: &impl NpmProcessStateFromEnvVarSys, ) -> Option<&'static NpmProcessState> { static NPM_PROCESS_STATE: std::sync::OnceLock<Option<NpmProcessState>> = std::sync::OnceLock::new(); NPM_PROCESS_STATE .get_or_init(|| { use deno_runtime::deno_process::NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME; let fd_or_path = sys.env_var_os(NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME)?; sys.env_remove_var(NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME); if fd_or_path.is_empty() { return None; } NpmProcessState::from_env_var(sys, fd_or_path) .inspect_err(|e| { log::error!("failed to resolve npm process state: {}", e); }) .ok() }) .as_ref() } pub fn resolve_npm_resolution_snapshot( sys: &impl NpmProcessStateFromEnvVarSys, ) -> Result<Option<ValidSerializedNpmResolutionSnapshot>, PackageIdNotFoundError> { if let Some(NpmProcessStateKind::Snapshot(snapshot)) = npm_process_state(sys).map(|s| &s.kind) { // TODO(bartlomieju): remove this clone Ok(Some(snapshot.clone().into_valid()?)) } else { Ok(None) } } #[derive(Clone, Default, Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct UnstableConfig { // TODO(bartlomieju): remove in Deno 2.5 pub legacy_flag_enabled: bool, // --unstable pub detect_cjs: bool, pub lazy_dynamic_imports: bool, pub raw_imports: bool, pub sloppy_imports: bool, pub npm_lazy_caching: bool, pub features: Vec<String>, // --unstabe-kv --unstable-cron } impl UnstableConfig { pub fn fill_with_env(&mut self, sys: &impl EnvVar) { fn maybe_set(sys: &impl EnvVar, value: &mut bool, var_name: &str) { if !*value && has_flag_env_var(sys, var_name) { *value = true; } } maybe_set( sys, &mut self.lazy_dynamic_imports, UNSTABLE_ENV_VAR_NAMES.lazy_dynamic_imports, ); maybe_set( sys, &mut self.npm_lazy_caching, UNSTABLE_ENV_VAR_NAMES.npm_lazy_caching, ); maybe_set( sys, &mut self.raw_imports, UNSTABLE_ENV_VAR_NAMES.raw_imports, ); maybe_set( sys, &mut self.sloppy_imports, UNSTABLE_ENV_VAR_NAMES.sloppy_imports, ); } pub fn enable_node_compat(&mut self) { self.sloppy_imports = true; self.detect_cjs = true; if !self.features.iter().any(|f| f == "node-globals") { self.features.push("node-globals".to_string()); } } }