bunvm 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2025 Tarun Joshi
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,177 @@
1
+ # BVM - Bun Version Manager
2
+
3
+ **BVM** is a simple and fast CLI tool to manage multiple versions of [Bun](https://bun.sh), the all-in-one JavaScript runtime. Inspired by tools like `nvm` and `rvm`, BVM lets you easily install, switch, and manage different Bun versions.
4
+
5
+ > ⚠️ Currently in active development – contributions and feedback are welcome!
6
+
7
+ ---
8
+
9
+ ## 🚀 Features
10
+
11
+ - 📥 Install any version of Bun
12
+ - 🔁 Switch between installed versions seamlessly
13
+ - 📦 Uninstall versions you no longer need
14
+ - 📃 List installed and remote Bun versions
15
+ - 🐚 Auto-configure shell environment (bash, zsh, fish)
16
+ - 🧠 Lightweight and fast – built with Node.js and TypeScript
17
+ - 🔗 Automatic symlink management for `bun` and `bunx`
18
+ - ✨ Command completions support
19
+
20
+ ---
21
+
22
+ ## 🖥️ Platform Support
23
+
24
+ | Platform | Status | Tested |
25
+ |----------|--------|---------|
26
+ | Linux | ✅ Supported | ✅ Tested on Ubuntu/Debian |
27
+ | macOS | ⚠️ Should work | ❓ Not tested yet |
28
+ | Windows | ❓ Unknown | ❓ Not tested yet |
29
+
30
+ **Note**: BVM has been tested and works on Linux systems. macOS support should work but hasn't been tested yet. Windows support is planned but not implemented.
31
+
32
+ ---
33
+
34
+ ## 📦 Installation
35
+
36
+ ### Install from npm (Coming Soon)
37
+
38
+ ```bash
39
+ # With npm
40
+ npm install -g bvm
41
+
42
+ # With pnpm (recommended)
43
+ pnpm add -g bvm
44
+
45
+ # With yarn
46
+ yarn global add bvm
47
+
48
+ # Bun
49
+ bun add -g bvm
50
+ ```
51
+
52
+ ### Install from source
53
+
54
+ ```bash
55
+ git clone https://github.com/MrHacker26/bvm.git
56
+ cd bvm
57
+ pnpm install
58
+ pnpm build
59
+ pnpm link
60
+ ```
61
+
62
+ ---
63
+
64
+ ## 🛠️ Usage
65
+
66
+ Once installed, you can use `bvm` from anywhere in your terminal:
67
+
68
+ ```bash
69
+ bvm install <version> # Install a specific Bun version (alias: i)
70
+ bvm use <version> # Set a specific Bun version as active
71
+ bvm uninstall <version> # Remove an installed version (alias: u)
72
+ bvm list # List installed Bun versions (alias: ls)
73
+ bvm remote # List available remote Bun versions (alias: r)
74
+ bvm --help # Show help information
75
+ ```
76
+
77
+ ---
78
+
79
+ ## 📌 Examples
80
+
81
+ ```bash
82
+ # Install the latest Bun version
83
+ bvm install 1.0.12
84
+ # or use alias
85
+ bvm i 1.0.12
86
+
87
+ # Switch to a specific version
88
+ bvm use 1.0.12
89
+
90
+ # List all installed versions
91
+ bvm list
92
+ bvm ls # or use alias
93
+
94
+ # See what versions are available remotely
95
+ bvm remote
96
+ bvm r # or use alias
97
+
98
+ # Remove an old version
99
+ bvm uninstall 1.0.11
100
+ bvm u 1.0.11 # or use alias
101
+ ```
102
+
103
+ ---
104
+
105
+ ## 🛠️ Development
106
+
107
+ ### Prerequisites
108
+
109
+ - Node.js 18+
110
+ - pnpm (recommended) or npm
111
+
112
+ ### Setup
113
+
114
+ ```bash
115
+ # Clone the repository
116
+ git clone https://github.com/MrHacker26/bvm.git
117
+ cd bvm
118
+
119
+ # Install dependencies
120
+ pnpm install
121
+
122
+ # Build the project
123
+ pnpm build
124
+
125
+ # Link for local testing
126
+ pnpm link
127
+
128
+ # Run in development mode
129
+ pnpm dev
130
+ ```
131
+
132
+ ### Scripts
133
+
134
+ - `pnpm build` - Build the project with tsup
135
+ - `pnpm dev` - Run in development mode with tsx
136
+ - `pnpm clean` - Clean build directory
137
+ - `pnpm start` - Run the built CLI
138
+ - `pnpm format` - Format code with Prettier
139
+ - `pnpm lint` - Lint code with ESLint
140
+ - `pnpm lint:fix` - Fix linting issues
141
+
142
+ ---
143
+
144
+ ## 🤝 Contributing
145
+
146
+ Contributions are welcome! Please feel free to submit a Pull Request. Areas where help is needed:
147
+
148
+ - Testing on macOS and Windows
149
+ - Additional shell support
150
+ - Bug fixes and improvements
151
+ - Documentation updates
152
+
153
+ ---
154
+
155
+ ## 📄 License
156
+
157
+ MIT License - see [LICENSE](LICENSE) file for details.
158
+
159
+ ---
160
+
161
+ ## 🙏 Acknowledgments
162
+
163
+ - Inspired by [nvm](https://github.com/nvm-sh/nvm) and [rvm](https://rvm.io/)
164
+ - Built for the amazing [Bun](https://bun.sh) runtime
165
+ - Thanks to the TypeScript and Node.js communities
166
+
167
+ ---
168
+
169
+ ## 📞 Support
170
+
171
+ If you encounter any issues or have questions:
172
+
173
+ 1. Check the [Issues](https://github.com/MrHacker26/bvm/issues) page
174
+ 2. Create a new issue with details about your environment
175
+ 3. Include your platform, shell, and any error messages
176
+
177
+ **Happy Bunning! 🥖✨**
package/dist/bvm.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/bvm.js ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import{Command as Oe}from"commander";import{mkdirSync as Ve,existsSync as L}from"fs";import{join as Z}from"path";import U from"chalk";import{homedir as k}from"os";import{join as f}from"path";var S=f(k(),".bun"),y=f(S,"bin"),s=f(y,"bun"),x=f(y,"bunx"),ce=f(k(),".bvm"),p=f(ce,"versions"),le="https://api.github.com",H=`${le}/repos/oven-sh/bun/releases`,N=f(S,"_bun"),$=f(k(),".config","fish","config.fish");import w from"chalk";var n={log:e=>console.log(e),info:e=>console.log(`${w.blue("i")} ${e}`),success:e=>console.log(`${w.green("\u2705")} ${e}`),warn:e=>console.warn(`${w.yellow("\u26A0\uFE0F")} ${w.yellow(e)}`),error:e=>console.error(`${w.red("\u274C")} ${w.red(e)}`)};import{execSync as we}from"child_process";import{createReadStream as O,existsSync as ve,readdirSync as Se}from"fs";import l from"chalk";import{dirname as $e,join as j}from"path";import be from"axios";import{pipeline as xe}from"stream/promises";import Ne from"unzipper";import{chmod as Ie}from"fs/promises";import{createWriteStream as ue,existsSync as T,lstatSync as me,mkdirSync as pe,rmSync as fe,symlinkSync as de}from"fs";import{rm as ge,stat as he,unlink as Be}from"fs/promises";async function C(e,r){let t=ue(r);await new Promise((o,a)=>{t.on("finish",o),t.on("error",a),e.pipe(t)})}async function g(e){try{return await he(e),!0}catch{return!1}}async function b(e,r=!1){try{await g(e)&&(r?await ge(e,{recursive:!0,force:!0}):await Be(e))}catch(t){t.code!=="ENOENT"&&n.warn(`Failed to clean path: ${e}`)}}function I(e){let r=["B","KB","MB","GB"];if(e===0)return"0 B";let t=Math.floor(Math.log(e)/Math.log(1024));return`${(e/Math.pow(1024,t)).toFixed(1)} ${r[t]}`}function _(e){T(e)||pe(e,{recursive:!0})}function ye(e){if(T(e)){let r=me(e).isSymbolicLink();try{fe(e,{force:!0}),r||n.warn(`Replaced non-symlink file at ${e}`)}catch(t){n.warn(`Couldn't remove existing file at ${e}: ${t.message}`)}}}function M(e,r){T(e)&&(ye(r),de(e,r))}import z from"cli-progress";function V(){try{return we("bun --version",{encoding:"utf8",stdio:["pipe"]}).trim()||null}catch{return null}}function D(){return ve(p)?Se(p):[]}function F(e,r,t){let o=r===e,a=t.has(e);return o?`${l.magenta("v"+e)} ${l.yellow("\u2B50 (current)")}`:a?`${l.magenta("v"+e)} ${l.green("\u2713 (installed)")}`:`${l.magenta("v"+e)} ${l.red("\u2717 (not installed)")}`}function _e(){return`${process.platform}-${process.arch}`}function Ee(e){async function r(){console.log(l.red(`
3
+ Download interrupted. Cleaning up...`)),await b(e,!0),process.exit(1)}return process.once("SIGINT",r),()=>process.removeListener("SIGINT",r)}async function G(e,r){let t=_e(),o=`https://github.com/oven-sh/bun/releases/download/bun-v${e}/bun-${t}.zip`,a=`${r}.zip`,i=$e(r),c=j(i,`bun-${t}`),u=j(c,"bun"),v=Ee(i);try{let m=await be.get(o,{responseType:"stream"});if(m.status!==200)throw new Error(`Failed to download ZIP file. Status: ${m.status}`);let B=Number(m.headers["content-length"])||0,P=0,R=new z.SingleBar({format:`${l.magenta("Downloading")} {bar} {percentage}% | {downloaded}/{totalSize}`,barCompleteChar:"\u2588",barIncompleteChar:"\u2591",hideCursor:!0},z.Presets.shades_classic);if(B&&R.start(B,0,{downloaded:"0 B",totalSize:I(B)}),m.data.on("data",ae=>{P+=ae.length,B&&R.update(P,{downloaded:I(P),totalSize:I(B)})}),await C(m.data,a),B&&R.stop(),n.log(l.yellow("\u{1F4E6} Extracting...")),await xe(O(a),Ne.Extract({path:i})),!await g(u))throw new Error(`Expected binary not found at ${u}`);await C(O(u),r),await Ie(r,493),await b(c,!0),await b(a),n.success(`Downloaded Bun ${l.bold(`v${e}`)}`)}catch(m){n.error(`Failed to install Bun: ${m instanceof Error?m.message:m}`),await b(i,!0),process.exit(1)}finally{v()}}import{join as Te}from"path";import{existsSync as Ce}from"fs";import Me from"chalk";import{homedir as Le}from"os";import{join as d}from"path";import{readFile as K,writeFile as Y}from"fs/promises";import{execSync as Ue}from"child_process";async function J(){if(!await g(s)){n.error(`Bun binary not found at ${s}, skipping completions`);return}let e=X();if(!e){n.warn("Unknown shell. Please manually set up Bun completions.");return}try{Ue(`${s} completions`,{env:{...process.env,IS_BUN_AUTO_UPDATE:"true",SHELL:e},stdio:"ignore"})}catch(r){n.error(`Failed to set up ${e} completions: ${r}`)}}function X(){let e=process.env.SHELL??"";return e.includes("bash")?"bash":e.includes("zsh")?"zsh":e.includes("fish")?"fish":null}function Pe(e){let r=Le();switch(e){case"bash":{let t=process.env.XDG_CONFIG_HOME;return[d(r,".bashrc"),d(r,".bash_profile"),...t?[d(t,".bashrc"),d(t,".bash_profile"),d(t,"bashrc"),d(t,"bash_profile")]:[]]}case"zsh":return[d(r,".zshrc")];case"fish":return[d(r,".config","fish","config.fish")];default:return[]}}async function Re(){let e=[`set --export BUN_INSTALL "${S}"`,'set --export PATH "$BUN_INSTALL/bin" $PATH'];if(await g($))try{let r=await K($,"utf8"),t=e.filter(o=>!r.includes(o));if(t.length>0){let o=r+`
4
+ # bun
5
+ ${t.join(`
6
+ `)}
7
+ `;await Y($,o),n.success(`Updated ${$} with Bun configuration`)}}catch(r){let t=r instanceof Error?r.message:String(r);n.warn(`Could not update Fish config: ${t}`)}else n.warn("Fish config file not found. Please add Bun configuration manually.")}async function ke(e){if(!e){n.warn("Invalid shell provided");return}if(e==="fish"){await Re();return}let r=`export BUN_INSTALL="${S}"
8
+ `,t=`export PATH="$BUN_INSTALL/bin:$PATH"
9
+ `,o=`[ -s "${N}" ] && source "${N}"
10
+ `,a=Pe(e);for(let i of a)if(await g(i))try{let c=await K(i,"utf8"),u=!1,v=c;c.includes("BUN_INSTALL")||(v+=`
11
+ # bun
12
+ ${r}${t}`,u=!0),c.includes(N)||(v+=`
13
+ # bun completions
14
+ ${o}`,u=!0),u&&(await Y(i,v),n.success(`Updated ${i} with Bun configuration`));return}catch(c){let u=c instanceof Error?c.message:String(c);n.warn(`Could not update ${i}: ${u}`)}n.warn(`No writable ${e} config file found. Please add manually.`)}async function W(){let e=X();if(!e){n.warn("Unknown shell. Please manually add Bun to your shell config.");return}await ke(e)}async function E(e){let r=Te(p,e,"bun");if(!Ce(r)){n.error(`Bun version ${e} is not installed.`),n.info(`Run ${Me.cyan(`bvm install ${e}`)} to install it.`);return}try{_(y),M(r,s),M(r,x),await J(),n.success(`Now using Bun ${e}`)}catch(t){n.error(`Failed to switch Bun version: ${t.message}`)}}async function q(e){let r=Z(p,e),t=Z(r,"bun");if(L(r)&&L(t)){n.warn(`Bun ${U.green(`v${e}`)} is already installed.`);return}if(Ve(r,{recursive:!0}),n.log(`${U.cyan("\u{1F4E5} Installing")} Bun ${U.green(`v${e}`)}...`),await G(e,t),!L(s)||!L(x)){n.warn("No previously installed Bun versions found. Setting up environment..."),_(y);try{await W()}catch(o){n.error(`Failed to configure shell: ${o.message}. Please set up completions manually.`)}await E(e);return}n.success(`Installed Bun ${U.bold(`v${e}`)}`)}import Q from"chalk";import De from"axios";function ee(){try{let e=V();n.log(`Current Bun version: ${e??"none"}`);let r=D();if(r.length===0){n.warn("No Bun versions installed yet.");return}n.log(Q.green(`\u{1F680} Installed Bun versions:
15
+ `)),r.forEach(t=>{n.log(F(t,e,new Set(r)))})}catch{n.error("No Bun versions installed yet.")}}async function re(){try{let{data:e}=await De.get(H),r=e.map(({tag_name:i})=>i.replace(/^bun-v/,""));if(r.length===0){n.warn("No Bun versions found remotely.");return}let t=D(),o=new Set(t),a=V();n.log(Q.green(`\u{1F680} Available Bun versions:
16
+ `)),r.forEach(i=>{n.log(F(i,a,o))})}catch(e){n.error(`Error fetching remote versions: ${e instanceof Error?e.message:e}`)}}import{join as ne,resolve as te}from"path";import{existsSync as A,readlinkSync as Fe,rmSync as oe}from"fs";import Ae from"chalk";function ie(e){let r=ne(p,e),t=ne(r,"bun");if(!A(r)||!A(t)){n.warn(`Bun version ${e} is not installed.`);return}if(A(s))try{te(Fe(s))===te(t)&&(oe(s,{force:!0}),n.log(`\u{1F517} Removed active symlink for Bun ${e}.`))}catch{}try{oe(r,{recursive:!0,force:!0}),n.log(Ae.green(`\u{1F5D1}\uFE0F Bun ${e} has been uninstalled.`))}catch(o){n.error(`Failed to uninstall Bun ${e}: ${o.message}`)}}var se="1.0.0";var h=new Oe;h.name("bvm").description("Bun Version Manager - Manage multiple Bun versions").version(se);h.command("install <version>").alias("i").description("Install a specific Bun version").action(q);h.command("use <version>").description("Use a specific Bun version").action(E);h.command("uninstall <version>").alias("u").description("Uninstall a specific Bun version").action(ie);h.command("list").alias("ls").description("List installed Bun versions").action(ee);h.command("remote").alias("r").description("List remote Bun versions").action(re);h.parse();
17
+ //# sourceMappingURL=bvm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bvm.ts","../src/commands/install.ts","../src/lib/constants.ts","../src/lib/logger.ts","../src/lib/utils.ts","../src/lib/file.ts","../src/commands/use.ts","../src/lib/shell.ts","../src/commands/versions.ts","../src/commands/uninstall.ts","../package.json"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander'\nimport { installBun } from './commands/install'\nimport { useVersion } from './commands/use'\nimport { listRemoteVersions, listVersions } from './commands/versions'\nimport { uninstallBun } from './commands/uninstall'\nimport { version } from '../package.json'\n\nconst program = new Command()\n\nprogram\n .name('bvm')\n .description('Bun Version Manager - Manage multiple Bun versions')\n .version(version)\n\nprogram\n .command('install <version>')\n .alias('i')\n .description('Install a specific Bun version')\n .action(installBun)\n\nprogram\n .command('use <version>')\n .description('Use a specific Bun version')\n .action(useVersion)\n\nprogram\n .command('uninstall <version>')\n .alias('u')\n .description('Uninstall a specific Bun version')\n .action(uninstallBun)\n\nprogram\n .command('list')\n .alias('ls')\n .description('List installed Bun versions')\n .action(listVersions)\n\nprogram\n .command('remote')\n .alias('r')\n .description('List remote Bun versions')\n .action(listRemoteVersions)\n\nprogram.parse()\n","import { mkdirSync, existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport chalk from 'chalk'\nimport {\n BUN_VERSIONS_DIR,\n BUN_BIN_DIR,\n BUNX_SYMLINK,\n BUN_SYMLINK,\n} from '../lib/constants'\nimport { log } from '../lib/logger'\nimport { downloadBun } from '../lib/utils'\nimport { ensureDirectoryExists } from '../lib/file'\nimport { useVersion } from './use'\nimport { autoConfigureShell } from '../lib/shell'\n\nexport async function installBun(version: string): Promise<void> {\n const versionDir = join(BUN_VERSIONS_DIR, version)\n const bunBinaryPath = join(versionDir, 'bun')\n\n if (existsSync(versionDir) && existsSync(bunBinaryPath)) {\n log.warn(`Bun ${chalk.green(`v${version}`)} is already installed.`)\n return\n }\n\n mkdirSync(versionDir, { recursive: true })\n\n log.log(`${chalk.cyan('📥 Installing')} Bun ${chalk.green(`v${version}`)}...`)\n\n await downloadBun(version, bunBinaryPath)\n\n if (!existsSync(BUN_SYMLINK) || !existsSync(BUNX_SYMLINK)) {\n log.warn(\n `No previously installed Bun versions found. Setting up environment...`,\n )\n\n ensureDirectoryExists(BUN_BIN_DIR)\n\n try {\n await autoConfigureShell()\n } catch (err) {\n log.error(\n `Failed to configure shell: ${(err as Error).message}. Please set up completions manually.`,\n )\n }\n\n await useVersion(version)\n return\n }\n\n log.success(`Installed Bun ${chalk.bold(`v${version}`)}`)\n}\n","import { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport const BUN_DIR = join(homedir(), '.bun')\n\nexport const BUN_BIN_DIR = join(BUN_DIR, 'bin')\n\nexport const BUN_SYMLINK = join(BUN_BIN_DIR, 'bun')\n\nexport const BUNX_SYMLINK = join(BUN_BIN_DIR, 'bunx')\n\nexport const BVM_DIR = join(homedir(), '.bvm')\n\nexport const BUN_VERSIONS_DIR = join(BVM_DIR, 'versions')\n\nexport const GITHUB_API_URL = 'https://api.github.com'\n\nexport const GITHUB_RELEASES_URL = `${GITHUB_API_URL}/repos/oven-sh/bun/releases`\n\nexport const BUN_COMPLETION_FILE = join(BUN_DIR, '_bun')\n\nexport const FISH_CONFIG_PATH = join(\n homedir(),\n '.config',\n 'fish',\n 'config.fish',\n)\n","import chalk from 'chalk'\n\nexport const log = {\n log: (msg: string) => console.log(msg),\n info: (msg: string) => console.log(`${chalk.blue('i')} ${msg}`),\n success: (msg: string) => console.log(`${chalk.green('✅')} ${msg}`),\n warn: (msg: string) =>\n console.warn(`${chalk.yellow('⚠️')} ${chalk.yellow(msg)}`),\n error: (msg: string) => console.error(`${chalk.red('❌')} ${chalk.red(msg)}`),\n}\n","import { execSync } from 'node:child_process'\nimport { createReadStream, existsSync, readdirSync } from 'node:fs'\nimport { BUN_VERSIONS_DIR } from './constants'\nimport chalk from 'chalk'\nimport { dirname, join } from 'node:path'\nimport axios from 'axios'\nimport { log } from './logger'\nimport { pipeline } from 'node:stream/promises'\nimport unzipper from 'unzipper'\nimport { chmod } from 'node:fs/promises'\nimport { cleanPath, exists, formatBytes, streamToFile } from './file'\nimport cliProgress from 'cli-progress'\n\nexport function getCurrentBunVersion(): string | null {\n try {\n const output = execSync('bun --version', {\n encoding: 'utf8',\n stdio: ['pipe'],\n }).trim()\n return output || null\n } catch {\n return null\n }\n}\n\nexport function getInstalledBunVersions(): string[] {\n return existsSync(BUN_VERSIONS_DIR) ? readdirSync(BUN_VERSIONS_DIR) : []\n}\n\nexport function formatVersionInfo(\n version: string,\n currentVersion: string | null,\n installedVersions: Set<string>,\n): string {\n const isActive = currentVersion === version\n const isInstalled = installedVersions.has(version)\n\n if (isActive) {\n return `${chalk.magenta('v' + version)} ${chalk.yellow('⭐ (current)')}`\n }\n\n if (isInstalled) {\n return `${chalk.magenta('v' + version)} ${chalk.green('✓ (installed)')}`\n }\n\n return `${chalk.magenta('v' + version)} ${chalk.red('✗ (not installed)')}`\n}\n\nfunction getPlatformTarget(): string {\n return `${process.platform}-${process.arch}`\n}\n\nfunction registerCleanup(dir: string): () => void {\n async function cleanup() {\n console.log(chalk.red('\\nDownload interrupted. Cleaning up...'))\n await cleanPath(dir, true)\n process.exit(1)\n }\n\n process.once('SIGINT', cleanup)\n return () => process.removeListener('SIGINT', cleanup)\n}\n\nexport async function downloadBun(\n version: string,\n destPath: string,\n): Promise<void> {\n const target = getPlatformTarget()\n const url = `https://github.com/oven-sh/bun/releases/download/bun-v${version}/bun-${target}.zip`\n const zipPath = `${destPath}.zip`\n const destDir = dirname(destPath)\n const extractedDir = join(destDir, `bun-${target}`)\n const extractedBunPath = join(extractedDir, 'bun')\n\n const removeCleanupListener = registerCleanup(destDir)\n\n try {\n const response = await axios.get<NodeJS.ReadableStream>(url, {\n responseType: 'stream',\n })\n\n if (response.status !== 200) {\n throw new Error(`Failed to download ZIP file. Status: ${response.status}`)\n }\n\n const total = Number(response.headers['content-length']) || 0\n let downloaded = 0\n const progress = new cliProgress.SingleBar(\n {\n format: `${chalk.magenta('Downloading')} {bar} {percentage}% | {downloaded}/{totalSize}`,\n barCompleteChar: '█',\n barIncompleteChar: '░',\n hideCursor: true,\n },\n cliProgress.Presets.shades_classic,\n )\n\n if (total) {\n progress.start(total, 0, {\n downloaded: '0 B',\n totalSize: formatBytes(total),\n })\n }\n\n response.data.on('data', (chunk: Buffer) => {\n downloaded += chunk.length\n if (total) {\n progress.update(downloaded, {\n downloaded: formatBytes(downloaded),\n totalSize: formatBytes(total),\n })\n }\n })\n\n await streamToFile(response.data, zipPath)\n if (total) progress.stop()\n\n log.log(chalk.yellow('📦 Extracting...'))\n\n await pipeline(\n createReadStream(zipPath),\n unzipper.Extract({ path: destDir }),\n )\n\n if (!(await exists(extractedBunPath))) {\n throw new Error(`Expected binary not found at ${extractedBunPath}`)\n }\n\n await streamToFile(createReadStream(extractedBunPath), destPath)\n await chmod(destPath, 0o755)\n\n await cleanPath(extractedDir, true)\n await cleanPath(zipPath)\n\n log.success(`Downloaded Bun ${chalk.bold(`v${version}`)}`)\n } catch (error) {\n log.error(\n `Failed to install Bun: ${error instanceof Error ? error.message : error}`,\n )\n await cleanPath(destDir, true)\n process.exit(1)\n } finally {\n removeCleanupListener()\n }\n}\n","import {\n createWriteStream,\n existsSync,\n lstatSync,\n mkdirSync,\n rmSync,\n symlinkSync,\n} from 'node:fs'\nimport { rm, stat, unlink } from 'node:fs/promises'\nimport { log } from './logger'\n\nexport async function streamToFile(\n readable: NodeJS.ReadableStream,\n path: string,\n): Promise<void> {\n const writer = createWriteStream(path)\n await new Promise<void>((resolve, reject) => {\n writer.on('finish', resolve)\n writer.on('error', reject)\n readable.pipe(writer)\n })\n}\n\nexport async function exists(path: string): Promise<boolean> {\n try {\n await stat(path)\n return true\n } catch {\n return false\n }\n}\n\nexport async function cleanPath(\n path: string,\n isDirectory = false,\n): Promise<void> {\n try {\n if (await exists(path)) {\n if (isDirectory) {\n await rm(path, { recursive: true, force: true })\n } else {\n await unlink(path)\n }\n }\n } catch (error) {\n const err = error as NodeJS.ErrnoException\n if (err.code !== 'ENOENT') {\n log.warn(`Failed to clean path: ${path}`)\n }\n }\n}\n\nexport function formatBytes(bytes: number): string {\n const sizes = ['B', 'KB', 'MB', 'GB']\n if (bytes === 0) return '0 B'\n const i = Math.floor(Math.log(bytes) / Math.log(1024))\n return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${sizes[i]}`\n}\n\nexport function ensureDirectoryExists(dir: string): void {\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n}\n\nexport function removeExistingLink(path: string): void {\n if (existsSync(path)) {\n const isSymlink = lstatSync(path).isSymbolicLink()\n try {\n rmSync(path, { force: true })\n if (!isSymlink) {\n log.warn(`Replaced non-symlink file at ${path}`)\n }\n } catch (error) {\n log.warn(\n `Couldn't remove existing file at ${path}: ${(error as Error).message}`,\n )\n }\n }\n}\n\nexport function createSymlink(src: string, dest: string): void {\n if (existsSync(src)) {\n removeExistingLink(dest)\n symlinkSync(src, dest)\n }\n}\n","import { join } from 'node:path'\nimport { existsSync } from 'node:fs'\nimport chalk from 'chalk'\nimport { log } from '../lib/logger'\nimport {\n BUN_BIN_DIR,\n BUN_SYMLINK,\n BUN_VERSIONS_DIR,\n BUNX_SYMLINK,\n} from '../lib/constants'\nimport { createSymlink, ensureDirectoryExists } from '../lib/file'\nimport { setupCompletions } from '../lib/shell'\n\nexport async function useVersion(version: string): Promise<void> {\n const versionBin = join(BUN_VERSIONS_DIR, version, 'bun')\n\n if (!existsSync(versionBin)) {\n log.error(`Bun version ${version} is not installed.`)\n log.info(`Run ${chalk.cyan(`bvm install ${version}`)} to install it.`)\n return\n }\n\n try {\n ensureDirectoryExists(BUN_BIN_DIR)\n createSymlink(versionBin, BUN_SYMLINK)\n createSymlink(versionBin, BUNX_SYMLINK)\n await setupCompletions()\n\n log.success(`Now using Bun ${version}`)\n } catch (err) {\n log.error(`Failed to switch Bun version: ${(err as Error).message}`)\n }\n}\n","import { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { log } from './logger'\nimport { readFile, writeFile } from 'node:fs/promises'\nimport {\n BUN_COMPLETION_FILE,\n BUN_DIR,\n BUN_SYMLINK,\n FISH_CONFIG_PATH,\n} from './constants'\nimport { exists } from './file'\nimport { execSync } from 'node:child_process'\nimport { Shell } from './types'\n\nexport async function setupCompletions(): Promise<void> {\n if (!(await exists(BUN_SYMLINK))) {\n log.error(`Bun binary not found at ${BUN_SYMLINK}, skipping completions`)\n return\n }\n\n const shell = getShell()\n\n if (!shell) {\n log.warn('Unknown shell. Please manually set up Bun completions.')\n return\n }\n\n try {\n execSync(`${BUN_SYMLINK} completions`, {\n env: {\n ...process.env,\n IS_BUN_AUTO_UPDATE: 'true',\n SHELL: shell,\n },\n stdio: 'ignore',\n })\n } catch (error) {\n log.error(`Failed to set up ${shell} completions: ${error}`)\n }\n}\n\nfunction getShell(): Shell | null {\n const shellPath = process.env.SHELL ?? ''\n if (shellPath.includes('bash')) return 'bash'\n if (shellPath.includes('zsh')) return 'zsh'\n if (shellPath.includes('fish')) return 'fish'\n return null\n}\n\nexport function getShellConfigPath(shell: Shell): string[] {\n const home = homedir()\n switch (shell) {\n case 'bash': {\n const xdg = process.env.XDG_CONFIG_HOME\n return [\n join(home, '.bashrc'),\n join(home, '.bash_profile'),\n ...(xdg\n ? [\n join(xdg, '.bashrc'),\n join(xdg, '.bash_profile'),\n join(xdg, 'bashrc'),\n join(xdg, 'bash_profile'),\n ]\n : []),\n ]\n }\n case 'zsh':\n return [join(home, '.zshrc')]\n case 'fish':\n return [join(home, '.config', 'fish', 'config.fish')]\n default:\n return []\n }\n}\n\nasync function configureFish(): Promise<void> {\n const fishLines = [\n `set --export BUN_INSTALL \"${BUN_DIR}\"`,\n `set --export PATH \"$BUN_INSTALL/bin\" $PATH`,\n ]\n\n if (await exists(FISH_CONFIG_PATH)) {\n try {\n const content = await readFile(FISH_CONFIG_PATH, 'utf8')\n const missingLines = fishLines.filter((line) => !content.includes(line))\n\n if (missingLines.length > 0) {\n const newContent = content + `\\n# bun\\n${missingLines.join('\\n')}\\n`\n await writeFile(FISH_CONFIG_PATH, newContent)\n log.success(`Updated ${FISH_CONFIG_PATH} with Bun configuration`)\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n log.warn(`Could not update Fish config: ${message}`)\n }\n } else {\n log.warn(\n 'Fish config file not found. Please add Bun configuration manually.',\n )\n }\n}\n\nasync function configureShell(shell: Shell): Promise<void> {\n if (!shell) {\n log.warn('Invalid shell provided')\n return\n }\n\n if (shell === 'fish') {\n await configureFish()\n return\n }\n\n const bunInstallLine = `export BUN_INSTALL=\"${BUN_DIR}\"\\n`\n const pathLine = `export PATH=\"$BUN_INSTALL/bin:$PATH\"\\n`\n const completionLine = `[ -s \"${BUN_COMPLETION_FILE}\" ] && source \"${BUN_COMPLETION_FILE}\"\\n`\n\n const configPaths = getShellConfigPath(shell)\n\n for (const configPath of configPaths) {\n if (await exists(configPath)) {\n try {\n const content = await readFile(configPath, 'utf8')\n let updated = false\n let newContent = content\n\n if (!content.includes('BUN_INSTALL')) {\n newContent += `\\n# bun\\n${bunInstallLine}${pathLine}`\n updated = true\n }\n\n if (!content.includes(BUN_COMPLETION_FILE)) {\n newContent += `\\n# bun completions\\n${completionLine}`\n updated = true\n }\n\n if (updated) {\n await writeFile(configPath, newContent)\n log.success(`Updated ${configPath} with Bun configuration`)\n }\n return\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n log.warn(`Could not update ${configPath}: ${message}`)\n }\n }\n }\n\n log.warn(`No writable ${shell} config file found. Please add manually.`)\n}\n\nexport async function autoConfigureShell(): Promise<void> {\n const shell = getShell()\n if (!shell) {\n log.warn('Unknown shell. Please manually add Bun to your shell config.')\n return\n }\n\n await configureShell(shell)\n}\n","import {\n formatVersionInfo,\n getCurrentBunVersion,\n getInstalledBunVersions,\n} from '../lib/utils'\nimport { GITHUB_RELEASES_URL } from '../lib/constants'\nimport { log } from '../lib/logger'\nimport chalk from 'chalk'\nimport axios from 'axios'\n\ntype Release = { tag_name: string }\n\nexport function listVersions(): void {\n try {\n const currentVersion = getCurrentBunVersion()\n log.log(`Current Bun version: ${currentVersion ?? 'none'}`)\n\n const versions = getInstalledBunVersions()\n\n if (versions.length === 0) {\n log.warn('No Bun versions installed yet.')\n return\n }\n\n log.log(chalk.green('🚀 Installed Bun versions:\\n'))\n versions.forEach((version) => {\n log.log(formatVersionInfo(version, currentVersion, new Set(versions)))\n })\n } catch {\n log.error('No Bun versions installed yet.')\n }\n}\n\nexport async function listRemoteVersions(): Promise<void> {\n try {\n const { data } = await axios.get<Release[]>(GITHUB_RELEASES_URL)\n const versions = data.map(({ tag_name }) => tag_name.replace(/^bun-v/, ''))\n\n if (versions.length === 0) {\n log.warn('No Bun versions found remotely.')\n return\n }\n\n const installedVersions = getInstalledBunVersions()\n const installedVersionsSet = new Set(installedVersions)\n const activeVersion = getCurrentBunVersion()\n\n log.log(chalk.green('🚀 Available Bun versions:\\n'))\n versions.forEach((version) => {\n log.log(formatVersionInfo(version, activeVersion, installedVersionsSet))\n })\n } catch (err) {\n log.error(\n `Error fetching remote versions: ${err instanceof Error ? err.message : err}`,\n )\n }\n}\n","import { join, resolve } from 'node:path'\nimport { existsSync, readlinkSync, rmSync } from 'node:fs'\nimport { log } from '../lib/logger'\nimport { BUN_SYMLINK, BUN_VERSIONS_DIR } from '../lib/constants'\nimport chalk from 'chalk'\n\nexport function uninstallBun(version: string): void {\n const versionDir = join(BUN_VERSIONS_DIR, version)\n const bunBinaryPath = join(versionDir, 'bun')\n\n if (!existsSync(versionDir) || !existsSync(bunBinaryPath)) {\n log.warn(`Bun version ${version} is not installed.`)\n return\n }\n\n // If the version is in use, remove the symlink.\n if (existsSync(BUN_SYMLINK)) {\n try {\n const target = resolve(readlinkSync(BUN_SYMLINK))\n if (target === resolve(bunBinaryPath)) {\n rmSync(BUN_SYMLINK, { force: true })\n log.log(`🔗 Removed active symlink for Bun ${version}.`)\n }\n } catch {\n // Ignore readlinkSync errors.\n }\n }\n\n try {\n rmSync(versionDir, { recursive: true, force: true })\n log.log(chalk.green(`🗑️ Bun ${version} has been uninstalled.`))\n } catch (err) {\n log.error(`Failed to uninstall Bun ${version}: ${(err as Error).message}`)\n }\n}\n","{\n \"name\": \"bunvm\",\n \"version\": \"1.0.0\",\n \"description\": \"Bun Version Manager - Switch between different versions of Bun easily\",\n \"bin\": {\n \"bvm\": \"./dist/bvm.js\"\n },\n \"type\": \"module\",\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.js\",\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsx src/bvm.ts\",\n \"clean\": \"rm -rf dist\",\n \"prepublishOnly\": \"pnpm run clean && pnpm run build\",\n \"start\": \"node dist/bvm.js\",\n \"format\": \"prettier --write --ignore-path .gitignore --cache .\",\n \"lint\": \"eslint --ext .ts src --cache\",\n \"lint:fix\": \"eslint --ext .ts src --cache --fix\"\n },\n \"keywords\": [\n \"bun\",\n \"version\",\n \"manager\",\n \"version-manager\",\n \"bun version manager\",\n \"cli\",\n \"javascript\",\n \"typescript\",\n \"nodejs\"\n ],\n \"author\": \"Tarun Joshi\",\n \"license\": \"MIT\",\n \"homepage\": \"https://github.com/MrHacker26/bvm#readme\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/MrHacker26/bvm.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/MrHacker26/bvm/issues\"\n },\n \"files\": [\n \"dist\"\n ],\n \"packageManager\": \"pnpm@10.11.0\",\n \"dependencies\": {\n \"axios\": \"^1.9.0\",\n \"chalk\": \"^5.4.1\",\n \"cli-progress\": \"^3.12.0\",\n \"commander\": \"^13.1.0\",\n \"unzipper\": \"^0.12.3\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.27.0\",\n \"@types/cli-progress\": \"^3.11.6\",\n \"@types/node\": \"^22.15.18\",\n \"@types/unzipper\": \"^0.10.11\",\n \"@typescript-eslint/eslint-plugin\": \"^8.32.1\",\n \"@typescript-eslint/parser\": \"^8.32.1\",\n \"eslint\": \"^9.27.0\",\n \"globals\": \"^16.1.0\",\n \"prettier\": \"^3.5.3\",\n \"tsup\": \"^8.5.0\",\n \"tsx\": \"^4.19.4\",\n \"typescript\": \"^5.0.0\",\n \"typescript-eslint\": \"^8.32.1\"\n }\n}\n"],"mappings":"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","names":["Command","mkdirSync","existsSync","join","chalk","homedir","join","BUN_DIR","BUN_BIN_DIR","BUN_SYMLINK","BUNX_SYMLINK","BVM_DIR","BUN_VERSIONS_DIR","GITHUB_API_URL","GITHUB_RELEASES_URL","BUN_COMPLETION_FILE","FISH_CONFIG_PATH","chalk","log","msg","execSync","createReadStream","existsSync","readdirSync","chalk","dirname","join","axios","pipeline","unzipper","chmod","createWriteStream","existsSync","lstatSync","mkdirSync","rmSync","symlinkSync","rm","stat","unlink","streamToFile","readable","path","writer","createWriteStream","resolve","reject","exists","stat","cleanPath","isDirectory","rm","unlink","error","log","formatBytes","bytes","sizes","i","ensureDirectoryExists","dir","existsSync","mkdirSync","removeExistingLink","isSymlink","lstatSync","rmSync","createSymlink","src","dest","symlinkSync","cliProgress","getCurrentBunVersion","execSync","getInstalledBunVersions","existsSync","BUN_VERSIONS_DIR","readdirSync","formatVersionInfo","version","currentVersion","installedVersions","isActive","isInstalled","chalk","getPlatformTarget","registerCleanup","dir","cleanup","cleanPath","downloadBun","destPath","target","url","zipPath","destDir","dirname","extractedDir","join","extractedBunPath","removeCleanupListener","response","axios","total","downloaded","progress","formatBytes","chunk","streamToFile","log","pipeline","createReadStream","unzipper","exists","chmod","error","join","existsSync","chalk","homedir","join","readFile","writeFile","execSync","setupCompletions","exists","BUN_SYMLINK","log","shell","getShell","error","shellPath","getShellConfigPath","home","homedir","xdg","join","configureFish","fishLines","BUN_DIR","FISH_CONFIG_PATH","content","readFile","missingLines","line","newContent","writeFile","message","configureShell","bunInstallLine","pathLine","completionLine","BUN_COMPLETION_FILE","configPaths","configPath","updated","autoConfigureShell","useVersion","version","versionBin","join","BUN_VERSIONS_DIR","existsSync","log","chalk","ensureDirectoryExists","BUN_BIN_DIR","createSymlink","BUN_SYMLINK","BUNX_SYMLINK","setupCompletions","err","installBun","version","versionDir","join","BUN_VERSIONS_DIR","bunBinaryPath","existsSync","log","chalk","mkdirSync","downloadBun","BUN_SYMLINK","BUNX_SYMLINK","ensureDirectoryExists","BUN_BIN_DIR","autoConfigureShell","err","useVersion","chalk","axios","listVersions","currentVersion","getCurrentBunVersion","log","versions","getInstalledBunVersions","version","formatVersionInfo","listRemoteVersions","data","GITHUB_RELEASES_URL","tag_name","installedVersions","installedVersionsSet","activeVersion","err","join","resolve","existsSync","readlinkSync","rmSync","chalk","uninstallBun","version","versionDir","join","BUN_VERSIONS_DIR","bunBinaryPath","existsSync","log","BUN_SYMLINK","resolve","readlinkSync","rmSync","err","version","program","Command","version","installBun","useVersion","uninstallBun","listVersions","listRemoteVersions"]}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "bunvm",
3
+ "version": "1.0.0",
4
+ "description": "Bun Version Manager - Switch between different versions of Bun easily",
5
+ "bin": {
6
+ "bvm": "./dist/bvm.js"
7
+ },
8
+ "type": "module",
9
+ "main": "./dist/index.js",
10
+ "module": "./dist/index.js",
11
+ "scripts": {
12
+ "build": "tsup",
13
+ "dev": "tsx src/bvm.ts",
14
+ "clean": "rm -rf dist",
15
+ "prepublishOnly": "pnpm run clean && pnpm run build",
16
+ "start": "node dist/bvm.js",
17
+ "format": "prettier --write --ignore-path .gitignore --cache .",
18
+ "lint": "eslint --ext .ts src --cache",
19
+ "lint:fix": "eslint --ext .ts src --cache --fix"
20
+ },
21
+ "keywords": [
22
+ "bun",
23
+ "version",
24
+ "manager",
25
+ "version-manager",
26
+ "bun version manager",
27
+ "cli",
28
+ "javascript",
29
+ "typescript",
30
+ "nodejs"
31
+ ],
32
+ "author": "Tarun Joshi",
33
+ "license": "MIT",
34
+ "homepage": "https://github.com/MrHacker26/bvm#readme",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/MrHacker26/bvm.git"
38
+ },
39
+ "bugs": {
40
+ "url": "https://github.com/MrHacker26/bvm/issues"
41
+ },
42
+ "files": [
43
+ "dist"
44
+ ],
45
+ "packageManager": "pnpm@10.11.0",
46
+ "dependencies": {
47
+ "axios": "^1.9.0",
48
+ "chalk": "^5.4.1",
49
+ "cli-progress": "^3.12.0",
50
+ "commander": "^13.1.0",
51
+ "unzipper": "^0.12.3"
52
+ },
53
+ "devDependencies": {
54
+ "@eslint/js": "^9.27.0",
55
+ "@types/cli-progress": "^3.11.6",
56
+ "@types/node": "^22.15.18",
57
+ "@types/unzipper": "^0.10.11",
58
+ "@typescript-eslint/eslint-plugin": "^8.32.1",
59
+ "@typescript-eslint/parser": "^8.32.1",
60
+ "eslint": "^9.27.0",
61
+ "globals": "^16.1.0",
62
+ "prettier": "^3.5.3",
63
+ "tsup": "^8.5.0",
64
+ "tsx": "^4.19.4",
65
+ "typescript": "^5.0.0",
66
+ "typescript-eslint": "^8.32.1"
67
+ }
68
+ }