bvm-core 1.1.35 → 1.1.37

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/dist/bvm-shim.js CHANGED
@@ -1,14 +1,15 @@
1
1
  const path = require('path');
2
- const { spawn } = require('child_process');
2
+ const { spawn, spawnSync } = require('child_process');
3
3
  const os = require('os');
4
4
  const fs = require('fs');
5
5
 
6
6
  /**
7
7
  * BVM Shim for Windows (JavaScript version)
8
+ * Features: Physical Execution Proxy - No Drift, Full Compatibility.
8
9
  */
9
10
 
10
11
  const BVM_DIR = process.env.BVM_DIR || path.join(os.homedir(), '.bvm');
11
- const CMD = process.argv[2] ? process.argv[2].replace(/\.exe$/i, '').replace(/\.cmd$/i, '') : 'bun';
12
+ const CMD = process.argv[2] ? process.argv[2].replace(/\.(exe|cmd|bat|ps1)$/i, '') : 'bun';
12
13
  const ARGS = process.argv.slice(3);
13
14
 
14
15
  function resolveVersion() {
@@ -50,57 +51,154 @@ function resolveVersion() {
50
51
  return '';
51
52
  }
52
53
 
53
- // Simple synchronous execution for performance
54
54
  const version = resolveVersion();
55
55
  if (!version) {
56
- console.error("BVM Error: No Bun version is active or default is set.");
56
+ console.error("BVM Error: No Bun version is active.");
57
57
  process.exit(1);
58
58
  }
59
59
 
60
60
  const versionDir = path.join(BVM_DIR, 'versions', version);
61
61
  const binDir = path.join(versionDir, 'bin');
62
- const realExecutable = path.join(binDir, CMD + '.exe');
62
+ const bunExe = path.join(binDir, 'bun.exe');
63
63
 
64
- if (!fs.existsSync(realExecutable)) {
65
- console.error("BVM Error: Command '" + CMD + "' not found in Bun " + version + " at " + realExecutable);
64
+ let realExecutable = '';
65
+ let isShellScript = false;
66
+
67
+ // 1. Core Logic: Resolve the PHYSICAL executable
68
+ if (CMD === 'bun') {
69
+ realExecutable = bunExe;
70
+ } else if (CMD === 'bunx') {
71
+ // Windows Bun doesn't have a physical bunx.exe, it's 'bun x'
72
+ realExecutable = bunExe;
73
+ ARGS.unshift('x');
74
+ } else {
75
+ // For 3rd party tools, find the physical shim created by Bun in the version dir
76
+ const extensions = ['.exe', '.cmd', '.bat', '.ps1'];
77
+ for (const ext of extensions) {
78
+ const p = path.join(binDir, CMD + ext);
79
+ if (fs.existsSync(p)) {
80
+ realExecutable = p;
81
+ isShellScript = (ext !== '.exe');
82
+ break;
83
+ }
84
+ }
85
+ }
86
+
87
+ if (!realExecutable || !fs.existsSync(realExecutable)) {
88
+ // Strict version isolation:
89
+ // If a tool isn't physically present in this version's bin dir,
90
+ // do NOT fall back to `bun x <tool>` (that would bypass isolation).
91
+ console.error(`BVM Error: Command '${CMD}' not found in Bun ${version}.`);
66
92
  process.exit(127);
93
+ } else if (isShellScript) {
94
+ // JIT SELF-HEALING: If we are about to run a shell script (shim),
95
+ // ensure it's not broken by relative path drift.
96
+ try {
97
+ let content = fs.readFileSync(realExecutable, 'utf8');
98
+ // console.log("[DEBUG] Checking shim:", realExecutable);
99
+ if (content.includes('%~dp0\\..') || content.includes('$PSScriptRoot\\..')) {
100
+ console.log(`[bvm] Fixing broken shim: ${realExecutable}`);
101
+ const binDir = path.dirname(realExecutable);
102
+ const nodeModulesPeer = path.join(binDir, '..', 'node_modules');
103
+ const nodeModulesNested = path.join(binDir, '..', 'install', 'global', 'node_modules');
104
+
105
+ let nodeModulesBase = '';
106
+ if (fs.existsSync(nodeModulesPeer)) nodeModulesBase = nodeModulesPeer;
107
+ else if (fs.existsSync(nodeModulesNested)) nodeModulesBase = nodeModulesNested;
108
+
109
+ if (nodeModulesBase) {
110
+ const absNodeModules = path.resolve(nodeModulesBase).replace(/\//g, '\\');
111
+ const oldPatterns = [
112
+ '%~dp0\\..\\node_modules',
113
+ '%dp0%\\..\\node_modules',
114
+ '%~dp0\\..\\install\\global\\node_modules',
115
+ '%dp0%\\..\\install\\global\\node_modules',
116
+ '$PSScriptRoot\\..\\node_modules',
117
+ '$PSScriptRoot\\..\\install\\global\\node_modules'
118
+ ];
119
+
120
+ let fixed = false;
121
+ for (const pat of oldPatterns) {
122
+ if (content.includes(pat)) {
123
+ content = content.split(pat).join(absNodeModules);
124
+ fixed = true;
125
+ }
126
+ }
127
+
128
+ if (fixed) {
129
+ fs.writeFileSync(realExecutable, content, 'utf8');
130
+ console.log(`[bvm] Shim fixed. New target: ${absNodeModules}`);
131
+ } else {
132
+ console.log(`[bvm] Failed to fix shim patterns.`);
133
+ }
134
+ } else {
135
+ console.log(`[bvm] Could not find node_modules in peer or nested location.`);
136
+ }
137
+ }
138
+ } catch (e) {
139
+ console.error(`[bvm] JIT Fix Error: ${e.message}`);
140
+ }
67
141
  }
68
142
 
69
- process.env.BUN_INSTALL = versionDir;
70
- process.env.PATH = binDir + path.delimiter + process.env.PATH;
143
+ // 2. CONFIGURE ENVIRONMENT
144
+ const bunfigPath = path.join(versionDir, 'bunfig.toml');
145
+ const env = Object.assign({}, process.env, {
146
+ BUN_INSTALL: versionDir,
147
+ BUN_INSTALL_GLOBAL_DIR: versionDir,
148
+ BUN_INSTALL_GLOBAL_BIN: binDir,
149
+ BUN_CONFIG_FILE: bunfigPath, // Force bun to use version-specific bunfig
150
+ PATH: binDir + path.delimiter + process.env.PATH
151
+ });
152
+
153
+ // 3. EXECUTE THE PHYSICAL ORIGINAL
154
+ const child = spawn(realExecutable, ARGS, {
155
+ stdio: 'inherit',
156
+ shell: isShellScript,
157
+ env: env
158
+ });
71
159
 
72
- const child = spawn(realExecutable, ARGS, { stdio: 'inherit', shell: false });
73
160
  child.on('exit', (code) => {
74
- if (code === 0 && (CMD === 'bun' || CMD === 'bunx')) {
75
- const isGlobal = ARGS.includes('-g') || ARGS.includes('--global');
76
- const isInstall = ARGS.includes('install') || ARGS.includes('add') || ARGS.includes('remove') || ARGS.includes('upgrade');
161
+ // AUTOMATIC REHASH: Ensure new commands are exposed immediately after installation
162
+ const installCmds = ['install', 'i', 'add', 'a', 'remove', 'rm', 'uninstall', 'upgrade', 'link', 'unlink'];
163
+
164
+ let needRehash = false;
165
+
166
+ if (CMD === 'bun' && ARGS.length > 0) {
167
+ const subCmd = ARGS[0];
168
+ const hasGlobalFlag = ARGS.includes('-g') || ARGS.includes('--global');
77
169
 
78
- if (isGlobal && isInstall) {
79
- try {
80
- fixShims(binDir, versionDir);
81
- } catch(e) {}
170
+ // For install/add/remove commands, only rehash if -g/--global is present
171
+ if (['install', 'i', 'add', 'a', 'remove', 'rm', 'uninstall', 'upgrade'].includes(subCmd)) {
172
+ needRehash = hasGlobalFlag;
173
+ }
174
+ // For link/unlink, always rehash
175
+ else if (['link', 'unlink'].includes(subCmd)) {
176
+ needRehash = true;
82
177
  }
83
178
  }
84
- process.exit(code ?? 0);
85
- });
86
-
87
- function fixShims(binDir, versionDir) {
88
- try {
89
- const files = fs.readdirSync(binDir);
90
- for (const file of files) {
91
- if (file.endsWith('.cmd')) {
92
- const filePath = path.join(binDir, file);
93
- let content = fs.readFileSync(filePath, 'utf8');
94
- if (content.includes('%~dp0\\..')) {
95
- content = content.split('%~dp0\\..').join(versionDir);
96
- fs.writeFileSync(filePath, content, 'utf8');
179
+
180
+ if (code === 0 && needRehash) {
181
+ const bvmCmd = path.join(BVM_DIR, 'bin', 'bvm.cmd');
182
+ if (fs.existsSync(bvmCmd)) {
183
+ try {
184
+ console.log('[bvm] Updating command registry...');
185
+ // Use synchronous call so user sees completion
186
+ const result = spawnSync(bvmCmd, ['rehash', '--silent'], {
187
+ stdio: 'inherit',
188
+ env: Object.assign({}, process.env, { BVM_DIR })
189
+ });
190
+ if (result.status === 0) {
191
+ console.log('[bvm] Done! New commands are now available.');
97
192
  }
193
+ } catch(e) {
194
+ // Silent fail - rehash is not critical
98
195
  }
99
196
  }
100
- } catch(e) {}
101
- }
197
+ }
198
+ process.exit(code ?? 0);
199
+ });
102
200
 
103
201
  child.on('error', (err) => {
104
- console.error("BVM Error: Failed to start child process: " + err.message);
202
+ console.error("BVM Error: " + err.message);
105
203
  process.exit(1);
106
204
  });
package/dist/bvm-shim.sh CHANGED
@@ -58,7 +58,30 @@ REAL_EXECUTABLE="$VERSION_DIR/bin/$CMD_NAME"
58
58
  if [ -x "$REAL_EXECUTABLE" ]; then
59
59
  export BUN_INSTALL="$VERSION_DIR"
60
60
  export PATH="$VERSION_DIR/bin:$PATH"
61
- exec "$REAL_EXECUTABLE" "$@"
61
+
62
+ # Inject version-specific config if present
63
+ if [ -f "$VERSION_DIR/bunfig.toml" ]; then
64
+ export BUN_CONFIG_FILE="$VERSION_DIR/bunfig.toml"
65
+ fi
66
+
67
+ # Execute the command
68
+ "$REAL_EXECUTABLE" "$@"
69
+ EXIT_CODE=$?
70
+
71
+ # Auto-Rehash Logic
72
+ if [ "$CMD_NAME" = "bun" ] && [ $EXIT_CODE -eq 0 ]; then
73
+ case "$1" in
74
+ install|i|add|a|remove|rm|upgrade|link|unlink)
75
+ (export BVM_DIR="$BVM_DIR"; "$BVM_DIR/bin/bvm" rehash --silent >/dev/null 2>&1 & disown)
76
+ ;;
77
+ esac
78
+ fi
79
+
80
+ exit $EXIT_CODE
81
+ elif [ "$CMD_NAME" = "bunx" ] && [ -x "$VERSION_DIR/bin/bun" ]; then
82
+ export BUN_INSTALL="$VERSION_DIR"
83
+ export PATH="$VERSION_DIR/bin:$PATH"
84
+ exec "$VERSION_DIR/bin/bun" x "$@"
62
85
  else
63
86
  echo "BVM Error: Command '$CMD_NAME' not found in Bun $VERSION." >&2
64
87
  exit 127