#![allow(nonstandard_style, ambiguous_glob_reexports, incomplete_features)]
#![feature(adt_const_params)]
extern crate bun_sha_hmac as bun_sha;
extern crate self as bun_install;
extern crate bun_analytics as analytics;
extern crate bun_core as bun_output;
pub(crate) mod bun_schema {
pub(crate) use bun_options_types::schema::api;
}
pub(crate) mod bun_json {
pub(crate) use bun_ast::{Expr, ExprData, G::Property, e as E};
pub(crate) use bun_parsers::json::*;
}
pub(crate) mod bun_fs {
pub(crate) use bun_resolver::fs::*;
}
pub(crate) mod bun_progress {
pub(crate) use bun_core::Progress::{Node, Progress};
}
pub(crate) mod bun_bunfig {
pub(crate) use bun_options_types::context as Arguments;
}
use core::cell::Cell;
use core::fmt;
pub mod ini;
#[path = "patch.rs"]
#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
pub mod patch_parser;
pub mod npm;
#[path = "PackageManifestMap.rs"]
pub mod package_manifest_map;
pub mod resolution;
pub use resolution as resolution_real;
pub mod auto_installer;
#[path = "ConfigVersion.rs"]
pub mod config_version;
pub mod dependency;
#[path = "ExternalSlice.rs"]
pub mod external_slice;
pub mod hosted_git_info;
pub mod integrity;
pub mod padding_checker;
pub mod postinstall_optimizer;
pub mod versioned_url;
pub mod extract_tarball;
#[path = "lockfile.rs"]
pub mod lockfile_real;
#[path = "NetworkTask.rs"]
pub mod network_task;
#[path = "PackageManager.rs"]
pub mod package_manager_real;
#[path = "PackageManagerTask.rs"]
pub mod package_manager_task;
#[path = "TarballStream.rs"]
pub mod tarball_stream;
pub use lockfile_real::{DEFAULT_TRUSTED_DEPENDENCIES_LIST, default_trusted_dependencies};
#[path = "bin.rs"]
pub mod bin_real;
pub mod hoisted_install;
pub mod isolated_install;
pub mod lifecycle_script_runner;
pub mod migration;
#[path = "PackageInstall.rs"]
pub mod package_install;
#[path = "PackageInstaller.rs"]
pub mod package_installer;
pub mod patch_install;
pub mod pnpm;
#[path = "repository.rs"]
pub mod repository_real;
pub mod yarn;
pub use repository_real as repository;
pub use bin_real as bin;
pub mod lockfile {
pub use crate::lockfile_real::*;
pub use crate::Origin;
pub use crate::lockfile_real::LockfileFormat as Format;
pub use crate::lockfile_real::Serializer::SerializerLoadResult;
pub use crate::lockfile_real::package_index::Entry as PackageIndexEntry;
pub use crate::resolution::Tag as ScriptsListKind;
pub(crate) type PackageListEntry = crate::lockfile_real::Package;
pub mod package {
pub use crate::lockfile_real::package::meta::{HasInstallScript, Meta};
pub use crate::lockfile_real::package::*;
pub mod scripts {
pub use crate::lockfile_real::package::scripts::*;
}
}
pub use package::{HasInstallScript, Meta};
pub mod tree {
pub use crate::lockfile_real::tree::IteratorPathStyle as PathStyle;
pub use crate::lockfile_real::tree::*;
}
}
pub use package_manager_real::update_request;
pub use update_request::UpdateRequest;
pub mod package_manager {
pub use crate::package_manager_real::package_manager_options::LogLevel;
pub use crate::package_manager_real::*;
pub use crate::update_request;
#[allow(non_snake_case)]
pub mod Options {
pub use crate::package_manager_real::package_manager_options::*;
pub use crate::package_manager_real::package_manager_options::open_global_dir;
}
pub use crate::package_manager_real::workspace_package_json_cache;
pub use workspace_package_json_cache::{
GetJSONOptions as GetJsonOptions, GetResult as GetJsonResult,
MapEntry as WorkspacePackageJsonCacheEntry, WorkspacePackageJSONCache,
};
pub enum ManifestCacheOptions<'a> {
Ids(&'a [crate::PackageID]),
Names(&'a [&'a [u8]]),
}
pub type ManifestCacheRequest<'a> = ManifestCacheOptions<'a>;
pub use crate::package_manifest_map::CacheBehavior as ManifestLoad;
pub mod audit {
pub use crate::package_manager_real::command_line_arguments::AuditLevel;
}
pub use crate::package_manager_real::security_scanner;
}
pub(crate) mod install {
pub(crate) use crate::*;
}
#[path = "bin_linking_shim_included.rs"]
pub mod _bin_linking_shim;
#[cfg(windows)]
#[path = "windows-shim/bun_shim_impl.rs"]
pub mod _bun_shim_impl;
pub mod windows_shim {
pub use crate::_bin_linking_shim as bin_linking_shim;
#[cfg(windows)]
pub use crate::_bun_shim_impl as bun_shim_impl;
pub use bin_linking_shim::{
BinLinkingShim, Decoded, EMBEDDED_EXECUTABLE_DATA, Flags, Shebang,
embedded_executable_data, loose_decode,
};
}
#[path = "resolvers/folder_resolver.rs"]
pub mod _folder_resolver;
pub mod resolvers {
pub mod folder_resolver {
pub use crate::_folder_resolver::*;
}
}
pub use npm as Npm;
pub use resolution::Resolution;
pub use bun_install_types::NodeLinker::PnpmMatcher;
pub use bun_collections::identity_context::ArrayIdentityContext;
pub use bun_collections::identity_context::IdentityContext;
pub use external::ExternalPackageNameHashList;
pub use external::ExternalSlice;
pub use external::ExternalStringList;
pub use external::ExternalStringMap;
pub use external::VersionSlice;
pub use external_slice as external;
pub use dependency::Behavior;
pub use dependency::{Dependency, DependencyExt, TagExt, ValueExt, VersionExt};
pub use integrity::Integrity;
pub use bin::Bin;
pub use lockfile_real::bun_lock as TextLockfile;
pub use patch_install as patch;
#[doc(hidden)]
pub fn parse_text_lockfile_for_tests(
text: &'static str,
) -> core::result::Result<lockfile_real::Lockfile, TextLockfile::ParseError> {
let source = bun_ast::Source::init_path_string("bun.lock", text);
initialize_store();
bun_core::StackCheck::configure_thread();
let bump = bun_alloc::Arena::new();
let mut log = bun_ast::Log::default();
let root = crate::bun_json::parse_package_json_utf8(&source, &mut log, &bump)
.expect("test support: fixture must be valid JSON");
let mut lockfile = lockfile_real::Lockfile::default();
TextLockfile::parse_into_binary_lockfile(&mut lockfile, root, &source, &mut log, None)?;
Ok(lockfile)
}
pub use dependency::Tag as DependencyVersionTag;
pub use extract_tarball::ExtractTarball;
pub use lockfile::{LoadResult, LoadStep, Lockfile, PatchedDep};
pub use package_manager::Options::LogLevel;
pub use package_manager::{
GetJsonOptions, GetJsonResult, ManifestCacheOptions, ManifestCacheRequest, ManifestLoad,
WorkspaceFilter, WorkspacePackageJsonCacheEntry,
};
pub use repository::{Repository, RepositoryExt};
pub use resolution::Tag as ResolutionTag;
pub use _folder_resolver::FolderResolution;
pub use lifecycle_script_runner::LifecycleScriptSubprocess;
pub use network_task::NetworkTask;
pub use package_install::PackageInstall;
pub use package_manager_task::Task;
pub use package_manifest_map::PackageManifestMap;
pub use postinstall_optimizer::PostinstallOptimizer;
pub use tarball_stream::TarballStream;
pub use isolated_install::FileCopier;
pub use isolated_install::Store;
pub use package_manager_real::security_scanner::SecurityScanSubprocess;
pub use patch_install::PatchTask;
pub use package_manager_real::package_manager_directories::CacheDirAndSubpath;
pub use package_manager_real::{
AsyncNetworkTaskQueue, CommandLineArguments, PackageManager, PatchTaskQueue, RootPackageId,
Subcommand,
};
pub type PackageManagerDoStub = package_manager_real::package_manager_options::Do;
pub use package_manager_real::package_manager_options::{Access, AuthType};
pub struct RunTasksCallbacks<E = (), R = (), M = (), D = ()> {
pub on_extract: E,
pub on_resolve: R,
pub on_package_manifest_error: M,
pub on_package_download_error: D,
pub progress_bar: bool,
pub manifests_only: bool,
}
impl<E: Default, R: Default, M: Default, D: Default> Default for RunTasksCallbacks<E, R, M, D> {
fn default() -> Self {
Self {
on_extract: E::default(),
on_resolve: R::default(),
on_package_manifest_error: M::default(),
on_package_download_error: D::default(),
progress_bar: false,
manifests_only: false,
}
}
}
#[derive(Default)]
pub struct PackageJSON {
pub name: Box<[u8]>,
pub version: Box<[u8]>,
pub arch: npm::Architecture,
pub os: npm::OperatingSystem,
pub package_manager_package_id: PackageID,
pub dependencies: PackageJSONDependencyMap,
}
#[derive(Default)]
pub struct PackageJSONDependencyMap {
pub map: bun_collections::ArrayHashMap<bun_semver::String, Dependency>,
pub source_buf: &'static [u8],
}
pub mod ci_info {
pub(crate) fn detect_ci_name() -> Option<&'static [u8]> {
if bun_core::env_var::CI::get().is_some() {
return Some(b"ci");
}
None
}
}
#[allow(non_snake_case)]
pub mod ShellCompletions {
#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
pub enum Shell {
#[default]
Unknown,
Bash,
Zsh,
Fish,
Pwsh,
}
impl Shell {
pub fn from_env(shell: &[u8]) -> Shell {
use bun_core::strings;
let basename = bun_paths::basename(shell);
if strings::eql_comptime(basename, b"bash") {
Shell::Bash
} else if strings::eql_comptime(basename, b"zsh") {
Shell::Zsh
} else if strings::eql_comptime(basename, b"fish") {
Shell::Fish
} else if strings::eql_comptime(basename, b"pwsh")
|| strings::eql_comptime(basename, b"powershell")
{
Shell::Pwsh
} else {
Shell::Unknown
}
}
}
}
pub struct RunCommand;
pub static PRETEND_TO_BE_NODE: core::sync::atomic::AtomicBool =
core::sync::atomic::AtomicBool::new(false);
use bun_core::ZStr;
impl RunCommand {
#[cfg(not(windows))]
const SHELLS_TO_SEARCH: &'static [&'static [u8]] = &[b"bash", b"sh", b"zsh"];
#[cfg(not(windows))]
pub const BUN_NODE_DIR: &'static str = {
use const_format::concatcp;
const TMP: &str = if cfg!(target_os = "macos") {
"/private/tmp"
} else if cfg!(target_os = "android") {
"/data/local/tmp"
} else {
"/tmp"
};
const SUFFIX: &str = if cfg!(debug_assertions) {
"/bun-node-debug"
} else if bun_core::env::GIT_SHA_SHORT.is_empty() {
"/bun-node"
} else {
concatcp!("/bun-node-", bun_core::env::GIT_SHA_SHORT)
};
concatcp!(TMP, SUFFIX)
};
fn find_shell_impl<'a>(
buf: &'a mut bun_paths::PathBuffer,
path: &[u8],
cwd: &[u8],
) -> Option<&'a ZStr> {
#[cfg(windows)]
{
let _ = (buf, path, cwd);
return Some(bun_core::zstr!("C:\\Windows\\System32\\cmd.exe"));
}
#[cfg(not(windows))]
{
for shell in Self::SHELLS_TO_SEARCH {
if let Some(found) = bun_which::which(buf, path, cwd, shell) {
let len = found.len();
return Some(ZStr::from_buf(buf, len));
}
}
const HARDCODED_POPULAR_ONES: &[&ZStr] = &[
bun_core::zstr!("/bin/bash"),
bun_core::zstr!("/usr/bin/bash"),
bun_core::zstr!("/usr/local/bin/bash"), bun_core::zstr!("/bin/sh"),
bun_core::zstr!("/usr/bin/sh"), bun_core::zstr!("/usr/bin/zsh"),
bun_core::zstr!("/usr/local/bin/zsh"),
bun_core::zstr!("/system/bin/sh"), ];
for &shell in HARDCODED_POPULAR_ONES {
if bun_sys::is_executable_file_path(shell) {
let body = shell.as_bytes();
buf[..body.len()].copy_from_slice(body);
buf[body.len()] = 0;
return Some(ZStr::from_buf(buf, body.len()));
}
}
None
}
}
pub fn find_shell(path: &[u8], cwd: &[u8]) -> Option<&'static [u8]> {
static ONCE: std::sync::OnceLock<Option<Vec<u8>>> = std::sync::OnceLock::new();
ONCE.get_or_init(|| {
let mut scratch = bun_paths::PathBuffer::uninit();
let found = Self::find_shell_impl(&mut scratch, path, cwd)?;
Some(found.as_bytes_with_nul().to_vec())
})
.as_deref()
}
#[cold]
pub fn create_fake_temporary_node_executable(
path: &mut Vec<u8>,
optional_bun_path: &mut &[u8],
) -> Result<(), bun_core::Error> {
if PRETEND_TO_BE_NODE.load(core::sync::atomic::Ordering::Relaxed) {
return Ok(());
}
#[cfg(not(windows))]
{
use const_format::concatcp;
let argv0: &ZStr = bun_core::argv().get(0).unwrap_or(bun_core::zstr!("bun"));
let argv0_z: &ZStr = if argv0.as_bytes().first() == Some(&b'/') {
*optional_bun_path = argv0.as_bytes();
argv0
} else if optional_bun_path.is_empty() {
let self_path = bun_core::self_exe_path()?;
if !self_path.as_bytes().is_empty() {
*optional_bun_path = self_path.as_bytes();
self_path
} else {
argv0
}
} else {
unsafe { ZStr::from_raw(optional_bun_path.as_ptr(), optional_bun_path.len()) }
};
#[cfg(debug_assertions)]
{
let _ = bun_sys::delete_tree_absolute(Self::BUN_NODE_DIR.as_bytes());
}
const NODE_LINK: &ZStr = {
const B: &[u8] = concatcp!(RunCommand::BUN_NODE_DIR, "/node\0").as_bytes();
ZStr::from_static(B)
};
const BUN_LINK: &ZStr = {
const B: &[u8] = concatcp!(RunCommand::BUN_NODE_DIR, "/bun\0").as_bytes();
ZStr::from_static(B)
};
const DIR_Z: &ZStr = {
const B: &[u8] = concatcp!(RunCommand::BUN_NODE_DIR, "\0").as_bytes();
ZStr::from_static(B)
};
match bun_sys::mkdir(DIR_Z, 0o700) {
Ok(()) => {}
Err(e) if e.get_errno() == bun_sys::E::EEXIST => match bun_sys::lstat(DIR_Z) {
Ok(st)
if bun_sys::kind_from_mode(st.st_mode as bun_sys::Mode)
== bun_sys::FileKind::Directory
&& st.st_uid == bun_sys::c::getuid()
&& (st.st_mode as bun_sys::Mode) & 0o022 == 0 => {}
_ => return Ok(()),
},
Err(_) => return Ok(()),
}
for dest in [NODE_LINK, BUN_LINK] {
let mut replaced = false;
loop {
match bun_sys::symlink(argv0_z, dest) {
Ok(()) => break,
Err(e) if e.get_errno() == bun_sys::E::EEXIST => {
let mut buf = bun_paths::PathBuffer::uninit();
let matches = bun_sys::readlink(dest, &mut buf)
.map(|n| &buf[..n] == argv0_z.as_bytes())
.unwrap_or(false);
if matches || replaced {
break;
}
let _ = bun_sys::unlink(dest);
replaced = true;
}
Err(_) => return Ok(()),
}
}
}
if !path.is_empty() && *path.last().unwrap() != bun_paths::DELIMITER {
path.push(bun_paths::DELIMITER);
}
path.extend_from_slice(Self::BUN_NODE_DIR.as_bytes());
path.push(bun_paths::DELIMITER);
Ok(())
}
#[cfg(windows)]
{
use bun_core::strings;
use bun_sys::windows as win;
let mut target_path_buffer = bun_paths::WPathBuffer::default();
let prefix: &[u16] = strings::w!("\\??\\");
let len = unsafe {
win::GetTempPathW(
(target_path_buffer.len() - prefix.len()) as u32,
target_path_buffer.as_mut_ptr().add(prefix.len()),
)
} as usize;
if len == 0 {
return Ok(());
}
target_path_buffer[..prefix.len()].copy_from_slice(prefix);
let dir_name_str: &str = if cfg!(debug_assertions) {
"bun-node-debug"
} else if bun_core::env::GIT_SHA_SHORT.is_empty() {
"bun-node"
} else {
const_format::concatcp!("bun-node-", bun_core::env::GIT_SHA_SHORT)
};
let mut dir_name_buf = [0u16; 64];
for (i, b) in dir_name_str.bytes().enumerate() {
debug_assert!(b < 0x80, "dir_name is ASCII-only");
dir_name_buf[i] = b as u16;
}
let dir_name: &[u16] = &dir_name_buf[..dir_name_str.len()];
target_path_buffer[prefix.len() + len..][..dir_name.len()].copy_from_slice(dir_name);
let dir_slice_len = prefix.len() + len + dir_name.len();
#[cfg(debug_assertions)]
{
let dir_slice_u8 = bun_core::immutable::to_utf8_alloc_with_type(
&target_path_buffer[..dir_slice_len],
);
let _ = bun_sys::delete_tree_absolute(&dir_slice_u8);
let _ = bun_sys::Dir::cwd().make_dir(&dir_slice_u8);
}
let image_path = win::exe_path_w();
for name in [strings::w!("\\node.exe\0"), strings::w!("\\bun.exe\0")] {
target_path_buffer[dir_slice_len..][..name.len()].copy_from_slice(name);
if win::CreateHardLinkW(target_path_buffer.as_ptr(), image_path.as_ptr(), None) == 0
{
match win::Win32Error::get() {
win::Win32Error::ALREADY_EXISTS => {}
_ => {
target_path_buffer[dir_slice_len] = 0;
let dir_w =
bun_core::WStr::from_buf(&target_path_buffer[..], dir_slice_len);
let _ = bun_sys::mkdir_w(dir_w);
target_path_buffer[dir_slice_len] = b'\\' as u16;
if win::CreateHardLinkW(
target_path_buffer.as_ptr(),
image_path.as_ptr(),
None,
) == 0
{
return Ok(());
}
}
}
}
}
if !path.is_empty() && *path.last().unwrap() != bun_paths::DELIMITER {
path.push(bun_paths::DELIMITER);
}
strings::to_utf8_append_to_list(path, &target_path_buffer[prefix.len()..dir_slice_len]);
path.push(bun_paths::DELIMITER);
let _ = optional_bun_path;
Ok(())
}
}
}
fn install_runner_arena() -> &'static bun_alloc::Arena {
static ONCE: std::sync::Once = std::sync::Once::new();
static ARENA: bun_core::RacyCell<::core::mem::MaybeUninit<bun_alloc::Arena>> =
bun_core::RacyCell::new(::core::mem::MaybeUninit::uninit());
ONCE.call_once(|| {
unsafe { (*ARENA.get()).write(bun_alloc::Arena::new()) };
});
unsafe { (*ARENA.get()).assume_init_ref() }
}
impl RunCommand {
pub fn configure_env_for_run(
ctx: &mut bun_options_types::context::ContextData,
this_transpiler: &mut ::core::mem::MaybeUninit<bun_transpiler::Transpiler<'static>>,
env: Option<*mut bun_dotenv::Loader<'static>>,
_log_errors: bool,
store_root_fd: bool,
) -> Result<*mut (), bun_core::Error> {
use bun_core::Global;
let args = ctx.args.clone();
this_transpiler.write(bun_transpiler::Transpiler::init(
install_runner_arena(),
ctx.log,
args,
env,
)?);
let this_transpiler = unsafe { this_transpiler.assume_init_mut() };
this_transpiler.options.env.behavior =
bun_options_types::schema::api::DotEnvBehavior::load_all;
this_transpiler.resolver.care_about_bin_folder = true;
this_transpiler.resolver.care_about_scripts = true;
this_transpiler.resolver.store_fd = store_root_fd;
let env_loader = this_transpiler.env_mut();
if bun_io::parent_death_watchdog::is_enabled() {
let _ = env_loader.map.put(b"BUN_FEATURE_FLAG_NO_ORPHANS", b"1");
}
let _ = env_loader.map.put_default(
b"npm_config_user_agent",
const_format::concatcp!(
"bun/",
Global::package_json_version,
" npm/? node/v",
bun_core::env::REPORTED_NODEJS_VERSION,
" ",
Global::os_name,
" ",
Global::arch_name,
)
.as_bytes(),
);
if env_loader.get(b"npm_execpath").is_none() {
if let Ok(self_exe) = bun_core::self_exe_path() {
let _ = env_loader
.map
.put_default(b"npm_execpath", self_exe.as_bytes());
}
}
Ok(core::ptr::null_mut())
}
}
pub(crate) const BUN_HASH_TAG: &[u8] = b".bun-tag-";
pub(crate) const MAX_HEX_HASH_LEN: usize = {
let mut n = u64::MAX;
let mut len = 0usize;
while n != 0 {
n >>= 4;
len += 1;
}
len
};
const _: () = assert!(MAX_HEX_HASH_LEN == 16);
pub(crate) const MAX_BUNTAG_HASH_BUF_LEN: usize = MAX_HEX_HASH_LEN + BUN_HASH_TAG.len() + 1;
pub(crate) type BuntagHashBuf = [u8; MAX_BUNTAG_HASH_BUF_LEN];
pub(crate) fn buntaghashbuf_make(buf: &mut BuntagHashBuf, patch_hash: u64) -> &mut [u8] {
buf[0..BUN_HASH_TAG.len()].copy_from_slice(BUN_HASH_TAG);
let mut tmp = [0u8; 16];
let digits = bun_core::fmt::u64_hex_var_lower(&mut tmp, patch_hash);
buf[BUN_HASH_TAG.len()..BUN_HASH_TAG.len() + digits.len()].copy_from_slice(digits);
let digits_len = digits.len();
buf[BUN_HASH_TAG.len() + digits_len] = 0;
&mut buf[..BUN_HASH_TAG.len() + digits_len]
}
pub struct StorePathFormatter<'a> {
str: &'a [u8],
}
impl<'a> StorePathFormatter<'a> {
pub fn write_to<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
for &c in self.str {
match c {
b'/' | b'\\' => w.write_all(b"+")?,
_ => w.write_all(core::slice::from_ref(&c))?,
}
}
Ok(())
}
}
impl<'a> fmt::Display for StorePathFormatter<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut buf = Vec::with_capacity(self.str.len());
self.write_to(&mut buf).map_err(|_| fmt::Error)?;
f.write_str(bun_core::str_utf8(&buf).ok_or(fmt::Error)?)
}
}
pub(crate) fn fmt_store_path(str: &[u8]) -> StorePathFormatter<'_> {
StorePathFormatter { str }
}
pub(crate) static ALIGNMENT_BYTES_TO_REPEAT_BUFFER: [u8; 144] = [0u8; 144];
pub(crate) fn initialize_store() {
bun_ast::initialize_store_or_reset();
}
pub(crate) fn initialize_mini_store() {
use bun_alloc::Arena;
struct MiniStore {
heap: Arena,
memory_store: bun_ast::ASTMemoryAllocator,
}
thread_local! {
static INSTANCE: Cell<Option<*mut MiniStore>> = const { Cell::new(None) };
}
INSTANCE.with(|instance| {
if instance.get().is_none() {
let heap = Arena::new();
let memory_store = bun_ast::ASTMemoryAllocator::new(&heap);
let mini_store = bun_core::heap::into_raw(Box::new(MiniStore { heap, memory_store }));
unsafe {
(*mini_store).memory_store.reset();
(*mini_store).memory_store.push();
}
instance.set(Some(mini_store));
} else {
let mini_store = unsafe { &mut *instance.get().unwrap() };
let _ = &mini_store.heap;
mini_store
.memory_store
.reset_retain_with_limit(8 * 1024 * 1024);
mini_store.memory_store.push();
}
});
}
pub use bun_install_types::{
DependencyID, INVALID_DEPENDENCY_ID, INVALID_PACKAGE_ID, PackageID, PackageNameHash,
TruncatedPackageNameHash,
};
pub(crate) const invalid_package_id: PackageID = INVALID_PACKAGE_ID;
pub(crate) const invalid_dependency_id: DependencyID = INVALID_DEPENDENCY_ID;
pub const bun_hash_tag: &[u8] = BUN_HASH_TAG;
pub(crate) type PackageNameAndVersionHash = u64;
pub(crate) struct Aligner;
impl Aligner {
pub(crate) fn write<T, W: bun_io::Write>(writer: &mut W, pos: u64) -> bun_io::Result<usize> {
let to_write = Self::skip_amount::<T>(pos as usize);
let remainder: &[u8] = &ALIGNMENT_BYTES_TO_REPEAT_BUFFER
[0..to_write.min(ALIGNMENT_BYTES_TO_REPEAT_BUFFER.len())];
writer.write_all(remainder)?;
Ok(to_write)
}
pub(crate) fn write_with_align<W: bun_io::Write>(
align: usize,
writer: &mut W,
pos: u64,
) -> bun_io::Result<usize> {
let to_write = Self::skip_amount_with_align(align, pos as usize);
let remainder: &[u8] = &ALIGNMENT_BYTES_TO_REPEAT_BUFFER
[0..to_write.min(ALIGNMENT_BYTES_TO_REPEAT_BUFFER.len())];
writer.write_all(remainder)?;
Ok(to_write)
}
#[inline]
pub(crate) fn skip_amount<T>(pos: usize) -> usize {
Self::skip_amount_with_align(core::mem::align_of::<T>(), pos)
}
#[inline]
pub(crate) fn skip_amount_with_align(align: usize, pos: usize) -> usize {
pos.next_multiple_of(align) - pos
}
}
#[repr(u8)]
#[derive(Copy, Clone, Eq, PartialEq, Debug, Default)]
pub enum Origin {
#[default]
Local = 0,
Npm = 1,
Tarball = 2,
}
pub use bun_install_types::resolver_hooks::{Features, PreinstallState};
#[derive(Default)]
pub struct ExtractDataJson {
pub path: Box<[u8]>,
pub buf: Vec<u8>,
}
#[derive(Default)]
pub struct ExtractData {
pub url: Box<[u8]>,
pub resolved: Box<[u8]>,
pub json: Option<ExtractDataJson>,
pub integrity: Integrity,
}
#[derive(Clone, Default)]
pub struct DependencyInstallContext {
pub tree_id: lockfile::tree::Id,
pub path: Vec<u8>,
pub dependency_id: DependencyID,
}
#[derive(Clone)]
pub enum TaskCallbackContext {
Dependency(DependencyID),
DependencyInstallContext(DependencyInstallContext),
IsolatedPackageInstallContext(isolated_install::EntryId),
RootDependency(DependencyID),
RootRequestId(PackageID),
}
#[derive(strum::IntoStaticStr, Debug, Copy, Clone, Eq, PartialEq)]
pub(crate) enum PackageManifestError {
PackageManifestHTTP400,
PackageManifestHTTP401,
PackageManifestHTTP402,
PackageManifestHTTP403,
PackageManifestHTTP404,
PackageManifestHTTP4xx,
PackageManifestHTTP5xx,
}
bun_core::impl_tag_error!(PackageManifestError);
bun_core::named_error_set!(PackageManifestError);