node-version-use 2.1.4 → 2.1.5

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.
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /**
2
3
  * Postinstall script for node-version-use
3
4
  *
@@ -8,36 +9,32 @@
8
9
  * 1. Download to temp file
9
10
  * 2. Extract to temp directory
10
11
  * 3. Atomic rename to final location
11
- */ "use strict";
12
- Object.defineProperty(exports, "__esModule", {
13
- value: true
14
- });
15
- var _child_process = require("child_process");
16
- var _exitcompat = /*#__PURE__*/ _interop_require_default(require("exit-compat"));
17
- var _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
18
- var _mkdirpclassic = /*#__PURE__*/ _interop_require_default(require("mkdirp-classic"));
19
- var _module = /*#__PURE__*/ _interop_require_default(require("module"));
20
- var _os = /*#__PURE__*/ _interop_require_default(require("os"));
21
- var _path = /*#__PURE__*/ _interop_require_default(require("path"));
22
- var _url = /*#__PURE__*/ _interop_require_default(require("url"));
23
- var _compatts = require("../compat.js");
24
- function _interop_require_default(obj) {
25
- return obj && obj.__esModule ? obj : {
26
- default: obj
27
- };
12
+ */ var spawn = require('child_process').spawn;
13
+ var exit = require('exit-compat');
14
+ var fs = require('fs');
15
+ var mkdirp = require('mkdirp-classic');
16
+ var os = require('os');
17
+ var path = require('path');
18
+ var hasHomedir = typeof os.homedir === 'function';
19
+ function homedir() {
20
+ if (hasHomedir) {
21
+ return os.homedir();
22
+ }
23
+ var home = require('homedir-polyfill');
24
+ return home();
28
25
  }
29
- // CJS/ESM compatibility
30
- var _require = typeof require === 'undefined' ? _module.default.createRequire(require("url").pathToFileURL(__filename).toString()) : require;
31
- var __dirname = _path.default.dirname(typeof __filename !== 'undefined' ? __filename : _url.default.fileURLToPath(require("url").pathToFileURL(__filename).toString()));
26
+ module.exports = {
27
+ homedir: homedir
28
+ };
32
29
  // Configuration
33
30
  var GITHUB_REPO = 'kmalakoff/node-version-use';
34
31
  // Path is relative to dist/cjs/scripts/ at runtime
35
- var BINARY_VERSION = _require(_path.default.join(__dirname, '..', '..', '..', 'package.json')).binaryVersion;
32
+ var BINARY_VERSION = require(path.join(__dirname, '..', 'package.json')).binaryVersion;
36
33
  /**
37
34
  * Get the platform-specific archive base name (without extension)
38
35
  */ function getArchiveBaseName() {
39
- var platform = _os.default.platform();
40
- var arch = _os.default.arch();
36
+ var platform = os.platform();
37
+ var arch = os.arch();
41
38
  var platformMap = {
42
39
  darwin: 'darwin',
43
40
  linux: 'linux',
@@ -58,25 +55,25 @@ var BINARY_VERSION = _require(_path.default.join(__dirname, '..', '..', '..', 'p
58
55
  /**
59
56
  * Get the extracted binary name (includes .exe on Windows)
60
57
  */ function getExtractedBinaryName(archiveBaseName) {
61
- var ext = _os.default.platform() === 'win32' ? '.exe' : '';
58
+ var ext = os.platform() === 'win32' ? '.exe' : '';
62
59
  return archiveBaseName + ext;
63
60
  }
64
61
  /**
65
62
  * Get the download URL for the binary archive
66
63
  */ function getDownloadUrl(archiveBaseName) {
67
- var ext = _os.default.platform() === 'win32' ? '.zip' : '.tar.gz';
64
+ var ext = os.platform() === 'win32' ? '.zip' : '.tar.gz';
68
65
  return "https://github.com/".concat(GITHUB_REPO, "/releases/download/binary-v").concat(BINARY_VERSION, "/").concat(archiveBaseName).concat(ext);
69
66
  }
70
67
  /**
71
68
  * Copy file
72
69
  */ function copyFileSync(src, dest) {
73
- var content = _fs.default.readFileSync(src);
74
- _fs.default.writeFileSync(dest, content);
70
+ var content = fs.readFileSync(src);
71
+ fs.writeFileSync(dest, content);
75
72
  }
76
73
  /**
77
74
  * Atomic rename with fallback to copy+delete for cross-device moves
78
75
  */ function atomicRename(src, dest, callback) {
79
- _fs.default.rename(src, dest, function(err) {
76
+ fs.rename(src, dest, function(err) {
80
77
  if (!err) {
81
78
  callback(null);
82
79
  return;
@@ -85,7 +82,7 @@ var BINARY_VERSION = _require(_path.default.join(__dirname, '..', '..', '..', 'p
85
82
  if (err.code === 'EXDEV') {
86
83
  try {
87
84
  copyFileSync(src, dest);
88
- _fs.default.unlinkSync(src);
85
+ fs.unlinkSync(src);
89
86
  callback(null);
90
87
  } catch (copyErr) {
91
88
  callback(copyErr);
@@ -98,28 +95,28 @@ var BINARY_VERSION = _require(_path.default.join(__dirname, '..', '..', '..', 'p
98
95
  /**
99
96
  * Remove directory recursively
100
97
  */ function rmRecursive(dir) {
101
- if (!_fs.default.existsSync(dir)) return;
102
- var files = _fs.default.readdirSync(dir);
98
+ if (!fs.existsSync(dir)) return;
99
+ var files = fs.readdirSync(dir);
103
100
  for(var i = 0; i < files.length; i++){
104
- var filePath = _path.default.join(dir, files[i]);
105
- var stat = _fs.default.statSync(filePath);
101
+ var filePath = path.join(dir, files[i]);
102
+ var stat = fs.statSync(filePath);
106
103
  if (stat.isDirectory()) {
107
104
  rmRecursive(filePath);
108
105
  } else {
109
- _fs.default.unlinkSync(filePath);
106
+ fs.unlinkSync(filePath);
110
107
  }
111
108
  }
112
- _fs.default.rmdirSync(dir);
109
+ fs.rmdirSync(dir);
113
110
  }
114
111
  /**
115
112
  * Get temp directory
116
113
  */ function getTmpDir() {
117
- return typeof _os.default.tmpdir === 'function' ? _os.default.tmpdir() : process.env.TMPDIR || process.env.TMP || process.env.TEMP || '/tmp';
114
+ return typeof os.tmpdir === 'function' ? os.tmpdir() : process.env.TMPDIR || process.env.TMP || process.env.TEMP || '/tmp';
118
115
  }
119
116
  /**
120
117
  * Download using curl (macOS, Linux, Windows 10+)
121
118
  */ function downloadWithCurl(downloadUrl, destPath, callback) {
122
- var curl = (0, _child_process.spawn)('curl', [
119
+ var curl = spawn('curl', [
123
120
  '-L',
124
121
  '-f',
125
122
  '-s',
@@ -147,7 +144,7 @@ var BINARY_VERSION = _require(_path.default.join(__dirname, '..', '..', '..', 'p
147
144
  * Download using PowerShell (Windows 7+ fallback)
148
145
  */ function downloadWithPowerShell(downloadUrl, destPath, callback) {
149
146
  var psCommand = 'Invoke-WebRequest -Uri "'.concat(downloadUrl, '" -OutFile "').concat(destPath, '" -UseBasicParsing');
150
- var ps = (0, _child_process.spawn)('powershell', [
147
+ var ps = spawn('powershell', [
151
148
  '-NoProfile',
152
149
  '-Command',
153
150
  psCommand
@@ -174,7 +171,7 @@ var BINARY_VERSION = _require(_path.default.join(__dirname, '..', '..', '..', 'p
174
171
  return;
175
172
  }
176
173
  // If curl failed and we're on Windows, try PowerShell
177
- if (_os.default.platform() === 'win32' && (err === null || err === void 0 ? void 0 : (_err_message = err.message) === null || _err_message === void 0 ? void 0 : _err_message.indexOf('ENOENT')) >= 0) {
174
+ if (os.platform() === 'win32' && (err === null || err === void 0 ? void 0 : (_err_message = err.message) === null || _err_message === void 0 ? void 0 : _err_message.indexOf('ENOENT')) >= 0) {
178
175
  downloadWithPowerShell(downloadUrl, destPath, callback);
179
176
  return;
180
177
  }
@@ -184,10 +181,10 @@ var BINARY_VERSION = _require(_path.default.join(__dirname, '..', '..', '..', 'p
184
181
  /**
185
182
  * Extract archive to a directory (callback-based)
186
183
  */ function extractArchive(archivePath, destDir, callback) {
187
- var platform = _os.default.platform();
184
+ var platform = os.platform();
188
185
  if (platform === 'win32') {
189
186
  // Windows: extract zip using PowerShell
190
- var ps = (0, _child_process.spawn)('powershell', [
187
+ var ps = spawn('powershell', [
191
188
  '-Command',
192
189
  "Expand-Archive -Path '".concat(archivePath, "' -DestinationPath '").concat(destDir, "' -Force")
193
190
  ]);
@@ -200,7 +197,7 @@ var BINARY_VERSION = _require(_path.default.join(__dirname, '..', '..', '..', 'p
200
197
  });
201
198
  } else {
202
199
  // Unix: extract tar.gz
203
- var tar = (0, _child_process.spawn)('tar', [
200
+ var tar = spawn('tar', [
204
201
  '-xzf',
205
202
  archivePath,
206
203
  '-C',
@@ -221,20 +218,20 @@ var BINARY_VERSION = _require(_path.default.join(__dirname, '..', '..', '..', 'p
221
218
  * 2. Copy binary to temp files in destination directory
222
219
  * 3. Atomic rename temp files to final names
223
220
  */ function extractAndInstall(archivePath, destDir, binaryName, callback) {
224
- var platform = _os.default.platform();
221
+ var platform = os.platform();
225
222
  var isWindows = platform === 'win32';
226
223
  var ext = isWindows ? '.exe' : '';
227
224
  // Create temp extraction directory
228
- var tempExtractDir = _path.default.join(getTmpDir(), "nvu-extract-".concat(Date.now()));
229
- _mkdirpclassic.default.sync(tempExtractDir);
225
+ var tempExtractDir = path.join(getTmpDir(), "nvu-extract-".concat(Date.now()));
226
+ mkdirp.sync(tempExtractDir);
230
227
  extractArchive(archivePath, tempExtractDir, function(extractErr) {
231
228
  if (extractErr) {
232
229
  rmRecursive(tempExtractDir);
233
230
  callback(extractErr);
234
231
  return;
235
232
  }
236
- var extractedPath = _path.default.join(tempExtractDir, binaryName);
237
- if (!_fs.default.existsSync(extractedPath)) {
233
+ var extractedPath = path.join(tempExtractDir, binaryName);
234
+ if (!fs.existsSync(extractedPath)) {
238
235
  rmRecursive(tempExtractDir);
239
236
  callback(new Error("Extracted binary not found: ".concat(binaryName)));
240
237
  return;
@@ -252,13 +249,13 @@ var BINARY_VERSION = _require(_path.default.join(__dirname, '..', '..', '..', 'p
252
249
  // This ensures the temp files are on the same filesystem for atomic rename
253
250
  for(var i = 0; i < binaries.length; i++){
254
251
  var name = binaries[i];
255
- var tempDest = _path.default.join(destDir, "".concat(name, ".tmp-").concat(timestamp).concat(ext));
252
+ var tempDest = path.join(destDir, "".concat(name, ".tmp-").concat(timestamp).concat(ext));
256
253
  try {
257
254
  // Copy to temp file in destination directory
258
255
  copyFileSync(extractedPath, tempDest);
259
256
  // Set permissions on Unix
260
257
  if (!isWindows) {
261
- _fs.default.chmodSync(tempDest, 493);
258
+ fs.chmodSync(tempDest, 493);
262
259
  }
263
260
  } catch (err) {
264
261
  installError = err;
@@ -268,10 +265,10 @@ var BINARY_VERSION = _require(_path.default.join(__dirname, '..', '..', '..', 'p
268
265
  if (installError) {
269
266
  // Clean up any temp files we created
270
267
  for(var j = 0; j < binaries.length; j++){
271
- var tempPath = _path.default.join(destDir, "".concat(binaries[j], ".tmp-").concat(timestamp).concat(ext));
272
- if (_fs.default.existsSync(tempPath)) {
268
+ var tempPath = path.join(destDir, "".concat(binaries[j], ".tmp-").concat(timestamp).concat(ext));
269
+ if (fs.existsSync(tempPath)) {
273
270
  try {
274
- _fs.default.unlinkSync(tempPath);
271
+ fs.unlinkSync(tempPath);
275
272
  } catch (_e) {
276
273
  // ignore cleanup errors
277
274
  }
@@ -291,12 +288,12 @@ var BINARY_VERSION = _require(_path.default.join(__dirname, '..', '..', '..', 'p
291
288
  return;
292
289
  }
293
290
  var name = binaries[index];
294
- var tempDest = _path.default.join(destDir, "".concat(name, ".tmp-").concat(timestamp).concat(ext));
295
- var finalDest = _path.default.join(destDir, "".concat(name).concat(ext));
291
+ var tempDest = path.join(destDir, "".concat(name, ".tmp-").concat(timestamp).concat(ext));
292
+ var finalDest = path.join(destDir, "".concat(name).concat(ext));
296
293
  // Remove existing file if present (for atomic replacement)
297
- if (_fs.default.existsSync(finalDest)) {
294
+ if (fs.existsSync(finalDest)) {
298
295
  try {
299
- _fs.default.unlinkSync(finalDest);
296
+ fs.unlinkSync(finalDest);
300
297
  } catch (_e) {
301
298
  // ignore cleanup errors
302
299
  }
@@ -314,9 +311,9 @@ var BINARY_VERSION = _require(_path.default.join(__dirname, '..', '..', '..', 'p
314
311
  /**
315
312
  * Print setup instructions
316
313
  */ function printInstructions(installed) {
317
- var homedirPath = (0, _compatts.homedir)();
318
- var nvuBinPath = _path.default.join(homedirPath, '.nvu', 'bin');
319
- var platform = _os.default.platform();
314
+ var homedirPath = homedir();
315
+ var nvuBinPath = path.join(homedirPath, '.nvu', 'bin');
316
+ var platform = os.platform();
320
317
  console.log('');
321
318
  console.log('============================================================');
322
319
  if (installed) {
@@ -357,29 +354,29 @@ var BINARY_VERSION = _require(_path.default.join(__dirname, '..', '..', '..', 'p
357
354
  var archiveBaseName = getArchiveBaseName();
358
355
  if (!archiveBaseName) {
359
356
  console.log('postinstall: Unsupported platform/architecture for binary.');
360
- console.log("Platform: ".concat(_os.default.platform(), ", Arch: ").concat(_os.default.arch()));
357
+ console.log("Platform: ".concat(os.platform(), ", Arch: ").concat(os.arch()));
361
358
  console.log('Binary not installed. You can still use nvu with explicit versions: nvu 18 npm test');
362
- (0, _exitcompat.default)(0);
359
+ exit(0);
363
360
  return;
364
361
  }
365
362
  var extractedBinaryName = getExtractedBinaryName(archiveBaseName);
366
- var homedirPath = (0, _compatts.homedir)();
367
- var nvuDir = _path.default.join(homedirPath, '.nvu');
368
- var binDir = _path.default.join(nvuDir, 'bin');
363
+ var homedirPath = homedir();
364
+ var nvuDir = path.join(homedirPath, '.nvu');
365
+ var binDir = path.join(nvuDir, 'bin');
369
366
  // Create directories
370
- _mkdirpclassic.default.sync(nvuDir);
371
- _mkdirpclassic.default.sync(binDir);
367
+ mkdirp.sync(nvuDir);
368
+ mkdirp.sync(binDir);
372
369
  var downloadUrl = getDownloadUrl(archiveBaseName);
373
- var ext = _os.default.platform() === 'win32' ? '.zip' : '.tar.gz';
374
- var tempPath = _path.default.join(getTmpDir(), "nvu-binary-".concat(Date.now()).concat(ext));
375
- console.log("postinstall: Downloading binary for ".concat(_os.default.platform(), "-").concat(_os.default.arch(), "..."));
370
+ var ext = os.platform() === 'win32' ? '.zip' : '.tar.gz';
371
+ var tempPath = path.join(getTmpDir(), "nvu-binary-".concat(Date.now()).concat(ext));
372
+ console.log("postinstall: Downloading binary for ".concat(os.platform(), "-").concat(os.arch(), "..."));
376
373
  downloadFile(downloadUrl, tempPath, function(downloadErr) {
377
374
  if (downloadErr) {
378
375
  var _downloadErr_message;
379
376
  // Clean up temp file if it exists
380
- if (_fs.default.existsSync(tempPath)) {
377
+ if (fs.existsSync(tempPath)) {
381
378
  try {
382
- _fs.default.unlinkSync(tempPath);
379
+ fs.unlinkSync(tempPath);
383
380
  } catch (_e) {
384
381
  // ignore cleanup errors
385
382
  }
@@ -398,15 +395,15 @@ var BINARY_VERSION = _require(_path.default.join(__dirname, '..', '..', '..', 'p
398
395
  console.log('To install binaries manually: cd node_modules/node-version-use/binary && make install');
399
396
  }
400
397
  printInstructions(false);
401
- (0, _exitcompat.default)(0);
398
+ exit(0);
402
399
  return;
403
400
  }
404
401
  console.log('postinstall: Extracting binary...');
405
402
  extractAndInstall(tempPath, binDir, extractedBinaryName, function(extractErr) {
406
403
  // Clean up temp file
407
- if (_fs.default.existsSync(tempPath)) {
404
+ if (fs.existsSync(tempPath)) {
408
405
  try {
409
- _fs.default.unlinkSync(tempPath);
406
+ fs.unlinkSync(tempPath);
410
407
  } catch (_e) {
411
408
  // ignore cleanup errors
412
409
  }
@@ -415,12 +412,12 @@ var BINARY_VERSION = _require(_path.default.join(__dirname, '..', '..', '..', 'p
415
412
  console.log("postinstall warning: Failed to extract binary: ".concat(extractErr.message || extractErr));
416
413
  console.log('You can still use nvu with explicit versions: nvu 18 npm test');
417
414
  printInstructions(false);
418
- (0, _exitcompat.default)(0);
415
+ exit(0);
419
416
  return;
420
417
  }
421
418
  console.log('postinstall: Binary installed successfully!');
422
419
  printInstructions(true);
423
- (0, _exitcompat.default)(0);
420
+ exit(0);
424
421
  });
425
422
  });
426
423
  }
@@ -0,0 +1,425 @@
1
+ "use strict";
2
+ /**
3
+ * Postinstall script for node-version-use
4
+ *
5
+ * Downloads the platform-specific binary and installs it to ~/.nvu/bin/
6
+ * This enables transparent Node version switching.
7
+ *
8
+ * Uses safe atomic download pattern:
9
+ * 1. Download to temp file
10
+ * 2. Extract to temp directory
11
+ * 3. Atomic rename to final location
12
+ */ var spawn = require('child_process').spawn;
13
+ var exit = require('exit-compat');
14
+ var fs = require('fs');
15
+ var mkdirp = require('mkdirp-classic');
16
+ var os = require('os');
17
+ var path = require('path');
18
+ var hasHomedir = typeof os.homedir === 'function';
19
+ function homedir() {
20
+ if (hasHomedir) {
21
+ return os.homedir();
22
+ }
23
+ var home = require('homedir-polyfill');
24
+ return home();
25
+ }
26
+ module.exports = {
27
+ homedir: homedir
28
+ };
29
+ // Configuration
30
+ var GITHUB_REPO = 'kmalakoff/node-version-use';
31
+ // Path is relative to dist/cjs/scripts/ at runtime
32
+ var BINARY_VERSION = require(path.join(__dirname, '..', 'package.json')).binaryVersion;
33
+ /**
34
+ * Get the platform-specific archive base name (without extension)
35
+ */ function getArchiveBaseName() {
36
+ var platform = os.platform();
37
+ var arch = os.arch();
38
+ var platformMap = {
39
+ darwin: 'darwin',
40
+ linux: 'linux',
41
+ win32: 'win32'
42
+ };
43
+ var archMap = {
44
+ x64: 'x64',
45
+ arm64: 'arm64',
46
+ amd64: 'x64'
47
+ };
48
+ var platformName = platformMap[platform];
49
+ var archName = archMap[arch];
50
+ if (!platformName || !archName) {
51
+ return null;
52
+ }
53
+ return "nvu-binary-".concat(platformName, "-").concat(archName);
54
+ }
55
+ /**
56
+ * Get the extracted binary name (includes .exe on Windows)
57
+ */ function getExtractedBinaryName(archiveBaseName) {
58
+ var ext = os.platform() === 'win32' ? '.exe' : '';
59
+ return archiveBaseName + ext;
60
+ }
61
+ /**
62
+ * Get the download URL for the binary archive
63
+ */ function getDownloadUrl(archiveBaseName) {
64
+ var ext = os.platform() === 'win32' ? '.zip' : '.tar.gz';
65
+ return "https://github.com/".concat(GITHUB_REPO, "/releases/download/binary-v").concat(BINARY_VERSION, "/").concat(archiveBaseName).concat(ext);
66
+ }
67
+ /**
68
+ * Copy file
69
+ */ function copyFileSync(src, dest) {
70
+ var content = fs.readFileSync(src);
71
+ fs.writeFileSync(dest, content);
72
+ }
73
+ /**
74
+ * Atomic rename with fallback to copy+delete for cross-device moves
75
+ */ function atomicRename(src, dest, callback) {
76
+ fs.rename(src, dest, function(err) {
77
+ if (!err) {
78
+ callback(null);
79
+ return;
80
+ }
81
+ // Cross-device link error - fall back to copy + delete
82
+ if (err.code === 'EXDEV') {
83
+ try {
84
+ copyFileSync(src, dest);
85
+ fs.unlinkSync(src);
86
+ callback(null);
87
+ } catch (copyErr) {
88
+ callback(copyErr);
89
+ }
90
+ return;
91
+ }
92
+ callback(err);
93
+ });
94
+ }
95
+ /**
96
+ * Remove directory recursively
97
+ */ function rmRecursive(dir) {
98
+ if (!fs.existsSync(dir)) return;
99
+ var files = fs.readdirSync(dir);
100
+ for(var i = 0; i < files.length; i++){
101
+ var filePath = path.join(dir, files[i]);
102
+ var stat = fs.statSync(filePath);
103
+ if (stat.isDirectory()) {
104
+ rmRecursive(filePath);
105
+ } else {
106
+ fs.unlinkSync(filePath);
107
+ }
108
+ }
109
+ fs.rmdirSync(dir);
110
+ }
111
+ /**
112
+ * Get temp directory
113
+ */ function getTmpDir() {
114
+ return typeof os.tmpdir === 'function' ? os.tmpdir() : process.env.TMPDIR || process.env.TMP || process.env.TEMP || '/tmp';
115
+ }
116
+ /**
117
+ * Download using curl (macOS, Linux, Windows 10+)
118
+ */ function downloadWithCurl(downloadUrl, destPath, callback) {
119
+ var curl = spawn('curl', [
120
+ '-L',
121
+ '-f',
122
+ '-s',
123
+ '-o',
124
+ destPath,
125
+ downloadUrl
126
+ ]);
127
+ curl.on('close', function(code) {
128
+ if (code !== 0) {
129
+ // curl exit codes: 22 = HTTP error (4xx/5xx), 56 = receive error (often 404 with -f)
130
+ if (code === 22 || code === 56) {
131
+ callback(new Error('HTTP 404'));
132
+ } else {
133
+ callback(new Error("curl failed with exit code ".concat(code)));
134
+ }
135
+ return;
136
+ }
137
+ callback(null);
138
+ });
139
+ curl.on('error', function(err) {
140
+ callback(err);
141
+ });
142
+ }
143
+ /**
144
+ * Download using PowerShell (Windows 7+ fallback)
145
+ */ function downloadWithPowerShell(downloadUrl, destPath, callback) {
146
+ var psCommand = 'Invoke-WebRequest -Uri "'.concat(downloadUrl, '" -OutFile "').concat(destPath, '" -UseBasicParsing');
147
+ var ps = spawn('powershell', [
148
+ '-NoProfile',
149
+ '-Command',
150
+ psCommand
151
+ ]);
152
+ ps.on('close', function(code) {
153
+ if (code !== 0) {
154
+ callback(new Error("PowerShell download failed with exit code ".concat(code)));
155
+ return;
156
+ }
157
+ callback(null);
158
+ });
159
+ ps.on('error', function(err) {
160
+ callback(err);
161
+ });
162
+ }
163
+ /**
164
+ * Download a file - tries curl first, falls back to PowerShell on Windows
165
+ * Node 0.8's OpenSSL doesn't support TLS 1.2+ required by GitHub
166
+ */ function downloadFile(downloadUrl, destPath, callback) {
167
+ downloadWithCurl(downloadUrl, destPath, function(err) {
168
+ var _err_message;
169
+ if (!err) {
170
+ callback(null);
171
+ return;
172
+ }
173
+ // If curl failed and we're on Windows, try PowerShell
174
+ if (os.platform() === 'win32' && (err === null || err === void 0 ? void 0 : (_err_message = err.message) === null || _err_message === void 0 ? void 0 : _err_message.indexOf('ENOENT')) >= 0) {
175
+ downloadWithPowerShell(downloadUrl, destPath, callback);
176
+ return;
177
+ }
178
+ callback(err);
179
+ });
180
+ }
181
+ /**
182
+ * Extract archive to a directory (callback-based)
183
+ */ function extractArchive(archivePath, destDir, callback) {
184
+ var platform = os.platform();
185
+ if (platform === 'win32') {
186
+ // Windows: extract zip using PowerShell
187
+ var ps = spawn('powershell', [
188
+ '-Command',
189
+ "Expand-Archive -Path '".concat(archivePath, "' -DestinationPath '").concat(destDir, "' -Force")
190
+ ]);
191
+ ps.on('close', function(code) {
192
+ if (code !== 0) {
193
+ callback(new Error('Failed to extract archive'));
194
+ return;
195
+ }
196
+ callback(null);
197
+ });
198
+ } else {
199
+ // Unix: extract tar.gz
200
+ var tar = spawn('tar', [
201
+ '-xzf',
202
+ archivePath,
203
+ '-C',
204
+ destDir
205
+ ]);
206
+ tar.on('close', function(code) {
207
+ if (code !== 0) {
208
+ callback(new Error('Failed to extract archive'));
209
+ return;
210
+ }
211
+ callback(null);
212
+ });
213
+ }
214
+ }
215
+ /**
216
+ * Install binaries using atomic rename pattern
217
+ * 1. Extract to temp directory
218
+ * 2. Copy binary to temp files in destination directory
219
+ * 3. Atomic rename temp files to final names
220
+ */ function extractAndInstall(archivePath, destDir, binaryName, callback) {
221
+ var platform = os.platform();
222
+ var isWindows = platform === 'win32';
223
+ var ext = isWindows ? '.exe' : '';
224
+ // Create temp extraction directory
225
+ var tempExtractDir = path.join(getTmpDir(), "nvu-extract-".concat(Date.now()));
226
+ mkdirp.sync(tempExtractDir);
227
+ extractArchive(archivePath, tempExtractDir, function(extractErr) {
228
+ if (extractErr) {
229
+ rmRecursive(tempExtractDir);
230
+ callback(extractErr);
231
+ return;
232
+ }
233
+ var extractedPath = path.join(tempExtractDir, binaryName);
234
+ if (!fs.existsSync(extractedPath)) {
235
+ rmRecursive(tempExtractDir);
236
+ callback(new Error("Extracted binary not found: ".concat(binaryName)));
237
+ return;
238
+ }
239
+ // Binary names to install
240
+ var binaries = [
241
+ 'node',
242
+ 'npm',
243
+ 'npx',
244
+ 'corepack'
245
+ ];
246
+ var timestamp = Date.now();
247
+ var installError = null;
248
+ // Step 1: Copy extracted binary to temp files in destination directory
249
+ // This ensures the temp files are on the same filesystem for atomic rename
250
+ for(var i = 0; i < binaries.length; i++){
251
+ var name = binaries[i];
252
+ var tempDest = path.join(destDir, "".concat(name, ".tmp-").concat(timestamp).concat(ext));
253
+ try {
254
+ // Copy to temp file in destination directory
255
+ copyFileSync(extractedPath, tempDest);
256
+ // Set permissions on Unix
257
+ if (!isWindows) {
258
+ fs.chmodSync(tempDest, 493);
259
+ }
260
+ } catch (err) {
261
+ installError = err;
262
+ break;
263
+ }
264
+ }
265
+ if (installError) {
266
+ // Clean up any temp files we created
267
+ for(var j = 0; j < binaries.length; j++){
268
+ var tempPath = path.join(destDir, "".concat(binaries[j], ".tmp-").concat(timestamp).concat(ext));
269
+ if (fs.existsSync(tempPath)) {
270
+ try {
271
+ fs.unlinkSync(tempPath);
272
+ } catch (_e) {
273
+ // ignore cleanup errors
274
+ }
275
+ }
276
+ }
277
+ rmRecursive(tempExtractDir);
278
+ callback(installError);
279
+ return;
280
+ }
281
+ // Step 2: Atomic rename temp files to final names
282
+ var renameError = null;
283
+ function doRename(index) {
284
+ if (index >= binaries.length) {
285
+ // All renames complete
286
+ rmRecursive(tempExtractDir);
287
+ callback(renameError);
288
+ return;
289
+ }
290
+ var name = binaries[index];
291
+ var tempDest = path.join(destDir, "".concat(name, ".tmp-").concat(timestamp).concat(ext));
292
+ var finalDest = path.join(destDir, "".concat(name).concat(ext));
293
+ // Remove existing file if present (for atomic replacement)
294
+ if (fs.existsSync(finalDest)) {
295
+ try {
296
+ fs.unlinkSync(finalDest);
297
+ } catch (_e) {
298
+ // ignore cleanup errors
299
+ }
300
+ }
301
+ atomicRename(tempDest, finalDest, function(err) {
302
+ if (err && !renameError) {
303
+ renameError = err;
304
+ }
305
+ doRename(index + 1);
306
+ });
307
+ }
308
+ doRename(0);
309
+ });
310
+ }
311
+ /**
312
+ * Print setup instructions
313
+ */ function printInstructions(installed) {
314
+ var homedirPath = homedir();
315
+ var nvuBinPath = path.join(homedirPath, '.nvu', 'bin');
316
+ var platform = os.platform();
317
+ console.log('');
318
+ console.log('============================================================');
319
+ if (installed) {
320
+ console.log(' nvu binaries installed to ~/.nvu/bin/');
321
+ } else {
322
+ console.log(' nvu installed (binaries not yet available)');
323
+ }
324
+ console.log('============================================================');
325
+ console.log('');
326
+ console.log('To enable transparent Node version switching, add to your shell profile:');
327
+ console.log('');
328
+ if (platform === 'win32') {
329
+ console.log(' PowerShell (add to $PROFILE):');
330
+ console.log(' $env:PATH = "'.concat(nvuBinPath, ';$env:PATH"'));
331
+ console.log('');
332
+ console.log(' CMD (run as administrator):');
333
+ console.log(' setx PATH "'.concat(nvuBinPath, ';%PATH%"'));
334
+ } else {
335
+ console.log(' # For bash (~/.bashrc):');
336
+ console.log(' export PATH="$HOME/.nvu/bin:$PATH"');
337
+ console.log('');
338
+ console.log(' # For zsh (~/.zshrc):');
339
+ console.log(' export PATH="$HOME/.nvu/bin:$PATH"');
340
+ console.log('');
341
+ console.log(' # For fish (~/.config/fish/config.fish):');
342
+ console.log(' set -gx PATH $HOME/.nvu/bin $PATH');
343
+ }
344
+ console.log('');
345
+ console.log('Then restart your terminal or source your shell profile.');
346
+ console.log('');
347
+ console.log("Without this, 'nvu 18 npm test' still works - you just won't have");
348
+ console.log("transparent 'node' command override.");
349
+ console.log('============================================================');
350
+ }
351
+ /**
352
+ * Main installation function
353
+ */ function main() {
354
+ var archiveBaseName = getArchiveBaseName();
355
+ if (!archiveBaseName) {
356
+ console.log('postinstall: Unsupported platform/architecture for binary.');
357
+ console.log("Platform: ".concat(os.platform(), ", Arch: ").concat(os.arch()));
358
+ console.log('Binary not installed. You can still use nvu with explicit versions: nvu 18 npm test');
359
+ exit(0);
360
+ return;
361
+ }
362
+ var extractedBinaryName = getExtractedBinaryName(archiveBaseName);
363
+ var homedirPath = homedir();
364
+ var nvuDir = path.join(homedirPath, '.nvu');
365
+ var binDir = path.join(nvuDir, 'bin');
366
+ // Create directories
367
+ mkdirp.sync(nvuDir);
368
+ mkdirp.sync(binDir);
369
+ var downloadUrl = getDownloadUrl(archiveBaseName);
370
+ var ext = os.platform() === 'win32' ? '.zip' : '.tar.gz';
371
+ var tempPath = path.join(getTmpDir(), "nvu-binary-".concat(Date.now()).concat(ext));
372
+ console.log("postinstall: Downloading binary for ".concat(os.platform(), "-").concat(os.arch(), "..."));
373
+ downloadFile(downloadUrl, tempPath, function(downloadErr) {
374
+ if (downloadErr) {
375
+ var _downloadErr_message;
376
+ // Clean up temp file if it exists
377
+ if (fs.existsSync(tempPath)) {
378
+ try {
379
+ fs.unlinkSync(tempPath);
380
+ } catch (_e) {
381
+ // ignore cleanup errors
382
+ }
383
+ }
384
+ if (((_downloadErr_message = downloadErr.message) === null || _downloadErr_message === void 0 ? void 0 : _downloadErr_message.indexOf('404')) >= 0) {
385
+ console.log('postinstall: Binaries not yet published to GitHub releases.');
386
+ console.log('');
387
+ console.log('To build and install binaries locally:');
388
+ console.log(' cd node_modules/node-version-use/binary');
389
+ console.log(' make install');
390
+ console.log('');
391
+ console.log('Or wait for the next release which will include pre-built binaries.');
392
+ } else {
393
+ console.log("postinstall warning: Failed to install binary: ".concat(downloadErr.message || downloadErr));
394
+ console.log('You can still use nvu with explicit versions: nvu 18 npm test');
395
+ console.log('To install binaries manually: cd node_modules/node-version-use/binary && make install');
396
+ }
397
+ printInstructions(false);
398
+ exit(0);
399
+ return;
400
+ }
401
+ console.log('postinstall: Extracting binary...');
402
+ extractAndInstall(tempPath, binDir, extractedBinaryName, function(extractErr) {
403
+ // Clean up temp file
404
+ if (fs.existsSync(tempPath)) {
405
+ try {
406
+ fs.unlinkSync(tempPath);
407
+ } catch (_e) {
408
+ // ignore cleanup errors
409
+ }
410
+ }
411
+ if (extractErr) {
412
+ console.log("postinstall warning: Failed to extract binary: ".concat(extractErr.message || extractErr));
413
+ console.log('You can still use nvu with explicit versions: nvu 18 npm test');
414
+ printInstructions(false);
415
+ exit(0);
416
+ return;
417
+ }
418
+ console.log('postinstall: Binary installed successfully!');
419
+ printInstructions(true);
420
+ exit(0);
421
+ });
422
+ });
423
+ }
424
+ main();
425
+ /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/assets/postinstall.cts"],"sourcesContent":["/**\n * Postinstall script for node-version-use\n *\n * Downloads the platform-specific binary and installs it to ~/.nvu/bin/\n * This enables transparent Node version switching.\n *\n * Uses safe atomic download pattern:\n * 1. Download to temp file\n * 2. Extract to temp directory\n * 3. Atomic rename to final location\n */\n\nconst { spawn } = require('child_process');\nconst exit = require('exit-compat');\nconst fs = require('fs');\nconst mkdirp = require('mkdirp-classic');\nconst os = require('os');\nconst path = require('path');\n\nconst hasHomedir = typeof os.homedir === 'function';\nfunction homedir(): string {\n if (hasHomedir) {\n return os.homedir();\n }\n var home = require('homedir-polyfill');\n return home();\n}\n\nmodule.exports = { homedir };\n\n// Configuration\nconst GITHUB_REPO = 'kmalakoff/node-version-use';\n// Path is relative to dist/cjs/scripts/ at runtime\nconst BINARY_VERSION = require(path.join(__dirname, '..', 'package.json')).binaryVersion;\n\ntype Callback = (err?: Error | null) => void;\n\ninterface PlatformMap {\n [key: string]: string;\n}\n\n/**\n * Get the platform-specific archive base name (without extension)\n */\nfunction getArchiveBaseName(): string | null {\n const platform = os.platform();\n const arch = os.arch();\n\n const platformMap: PlatformMap = {\n darwin: 'darwin',\n linux: 'linux',\n win32: 'win32',\n };\n\n const archMap: PlatformMap = {\n x64: 'x64',\n arm64: 'arm64',\n amd64: 'x64',\n };\n\n const platformName = platformMap[platform];\n const archName = archMap[arch];\n\n if (!platformName || !archName) {\n return null;\n }\n\n return `nvu-binary-${platformName}-${archName}`;\n}\n\n/**\n * Get the extracted binary name (includes .exe on Windows)\n */\nfunction getExtractedBinaryName(archiveBaseName: string): string {\n const ext = os.platform() === 'win32' ? '.exe' : '';\n return archiveBaseName + ext;\n}\n\n/**\n * Get the download URL for the binary archive\n */\nfunction getDownloadUrl(archiveBaseName: string): string {\n const ext = os.platform() === 'win32' ? '.zip' : '.tar.gz';\n return `https://github.com/${GITHUB_REPO}/releases/download/binary-v${BINARY_VERSION}/${archiveBaseName}${ext}`;\n}\n\n/**\n * Copy file\n */\nfunction copyFileSync(src: string, dest: string): void {\n const content = fs.readFileSync(src);\n fs.writeFileSync(dest, content);\n}\n\n/**\n * Atomic rename with fallback to copy+delete for cross-device moves\n */\nfunction atomicRename(src: string, dest: string, callback: Callback): void {\n fs.rename(src, dest, (err) => {\n if (!err) {\n callback(null);\n return;\n }\n\n // Cross-device link error - fall back to copy + delete\n if ((err as NodeJS.ErrnoException).code === 'EXDEV') {\n try {\n copyFileSync(src, dest);\n fs.unlinkSync(src);\n callback(null);\n } catch (copyErr) {\n callback(copyErr as Error);\n }\n return;\n }\n\n callback(err);\n });\n}\n\n/**\n * Remove directory recursively\n */\nfunction rmRecursive(dir: string): void {\n if (!fs.existsSync(dir)) return;\n\n const files = fs.readdirSync(dir);\n for (let i = 0; i < files.length; i++) {\n const filePath = path.join(dir, files[i]);\n const stat = fs.statSync(filePath);\n if (stat.isDirectory()) {\n rmRecursive(filePath);\n } else {\n fs.unlinkSync(filePath);\n }\n }\n fs.rmdirSync(dir);\n}\n\n/**\n * Get temp directory\n */\nfunction getTmpDir(): string {\n return typeof os.tmpdir === 'function' ? os.tmpdir() : process.env.TMPDIR || process.env.TMP || process.env.TEMP || '/tmp';\n}\n\n/**\n * Download using curl (macOS, Linux, Windows 10+)\n */\nfunction downloadWithCurl(downloadUrl: string, destPath: string, callback: Callback): void {\n const curl = spawn('curl', ['-L', '-f', '-s', '-o', destPath, downloadUrl]);\n\n curl.on('close', (code) => {\n if (code !== 0) {\n // curl exit codes: 22 = HTTP error (4xx/5xx), 56 = receive error (often 404 with -f)\n if (code === 22 || code === 56) {\n callback(new Error('HTTP 404'));\n } else {\n callback(new Error(`curl failed with exit code ${code}`));\n }\n return;\n }\n callback(null);\n });\n\n curl.on('error', (err) => {\n callback(err);\n });\n}\n\n/**\n * Download using PowerShell (Windows 7+ fallback)\n */\nfunction downloadWithPowerShell(downloadUrl: string, destPath: string, callback: Callback): void {\n const psCommand = `Invoke-WebRequest -Uri \"${downloadUrl}\" -OutFile \"${destPath}\" -UseBasicParsing`;\n const ps = spawn('powershell', ['-NoProfile', '-Command', psCommand]);\n\n ps.on('close', (code) => {\n if (code !== 0) {\n callback(new Error(`PowerShell download failed with exit code ${code}`));\n return;\n }\n callback(null);\n });\n\n ps.on('error', (err) => {\n callback(err);\n });\n}\n\n/**\n * Download a file - tries curl first, falls back to PowerShell on Windows\n * Node 0.8's OpenSSL doesn't support TLS 1.2+ required by GitHub\n */\nfunction downloadFile(downloadUrl: string, destPath: string, callback: Callback): void {\n downloadWithCurl(downloadUrl, destPath, (err) => {\n if (!err) {\n callback(null);\n return;\n }\n\n // If curl failed and we're on Windows, try PowerShell\n if (os.platform() === 'win32' && err?.message?.indexOf('ENOENT') >= 0) {\n downloadWithPowerShell(downloadUrl, destPath, callback);\n return;\n }\n\n callback(err);\n });\n}\n\n/**\n * Extract archive to a directory (callback-based)\n */\nfunction extractArchive(archivePath: string, destDir: string, callback: Callback): void {\n const platform = os.platform();\n\n if (platform === 'win32') {\n // Windows: extract zip using PowerShell\n const ps = spawn('powershell', ['-Command', `Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force`]);\n ps.on('close', (code) => {\n if (code !== 0) {\n callback(new Error('Failed to extract archive'));\n return;\n }\n callback(null);\n });\n } else {\n // Unix: extract tar.gz\n const tar = spawn('tar', ['-xzf', archivePath, '-C', destDir]);\n tar.on('close', (code) => {\n if (code !== 0) {\n callback(new Error('Failed to extract archive'));\n return;\n }\n callback(null);\n });\n }\n}\n\n/**\n * Install binaries using atomic rename pattern\n * 1. Extract to temp directory\n * 2. Copy binary to temp files in destination directory\n * 3. Atomic rename temp files to final names\n */\nfunction extractAndInstall(archivePath: string, destDir: string, binaryName: string, callback: Callback): void {\n const platform = os.platform();\n const isWindows = platform === 'win32';\n const ext = isWindows ? '.exe' : '';\n\n // Create temp extraction directory\n const tempExtractDir = path.join(getTmpDir(), `nvu-extract-${Date.now()}`);\n mkdirp.sync(tempExtractDir);\n\n extractArchive(archivePath, tempExtractDir, (extractErr) => {\n if (extractErr) {\n rmRecursive(tempExtractDir);\n callback(extractErr);\n return;\n }\n\n const extractedPath = path.join(tempExtractDir, binaryName);\n if (!fs.existsSync(extractedPath)) {\n rmRecursive(tempExtractDir);\n callback(new Error(`Extracted binary not found: ${binaryName}`));\n return;\n }\n\n // Binary names to install\n const binaries = ['node', 'npm', 'npx', 'corepack'];\n const timestamp = Date.now();\n let installError: Error | null = null;\n\n // Step 1: Copy extracted binary to temp files in destination directory\n // This ensures the temp files are on the same filesystem for atomic rename\n for (let i = 0; i < binaries.length; i++) {\n const name = binaries[i];\n const tempDest = path.join(destDir, `${name}.tmp-${timestamp}${ext}`);\n\n try {\n // Copy to temp file in destination directory\n copyFileSync(extractedPath, tempDest);\n\n // Set permissions on Unix\n if (!isWindows) {\n fs.chmodSync(tempDest, 0o755);\n }\n } catch (err) {\n installError = err as Error;\n break;\n }\n }\n\n if (installError) {\n // Clean up any temp files we created\n for (let j = 0; j < binaries.length; j++) {\n const tempPath = path.join(destDir, `${binaries[j]}.tmp-${timestamp}${ext}`);\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n }\n rmRecursive(tempExtractDir);\n callback(installError);\n return;\n }\n\n // Step 2: Atomic rename temp files to final names\n let renameError: Error | null = null;\n\n function doRename(index: number): void {\n if (index >= binaries.length) {\n // All renames complete\n rmRecursive(tempExtractDir);\n callback(renameError);\n return;\n }\n\n const name = binaries[index];\n const tempDest = path.join(destDir, `${name}.tmp-${timestamp}${ext}`);\n const finalDest = path.join(destDir, `${name}${ext}`);\n\n // Remove existing file if present (for atomic replacement)\n if (fs.existsSync(finalDest)) {\n try {\n fs.unlinkSync(finalDest);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n\n atomicRename(tempDest, finalDest, (err) => {\n if (err && !renameError) {\n renameError = err;\n }\n doRename(index + 1);\n });\n }\n\n doRename(0);\n });\n}\n\n/**\n * Print setup instructions\n */\nfunction printInstructions(installed: boolean): void {\n const homedirPath = homedir();\n const nvuBinPath = path.join(homedirPath, '.nvu', 'bin');\n const platform = os.platform();\n\n console.log('');\n console.log('============================================================');\n if (installed) {\n console.log(' nvu binaries installed to ~/.nvu/bin/');\n } else {\n console.log(' nvu installed (binaries not yet available)');\n }\n console.log('============================================================');\n console.log('');\n console.log('To enable transparent Node version switching, add to your shell profile:');\n console.log('');\n\n if (platform === 'win32') {\n console.log(' PowerShell (add to $PROFILE):');\n console.log(` $env:PATH = \"${nvuBinPath};$env:PATH\"`);\n console.log('');\n console.log(' CMD (run as administrator):');\n console.log(` setx PATH \"${nvuBinPath};%PATH%\"`);\n } else {\n console.log(' # For bash (~/.bashrc):');\n console.log(' export PATH=\"$HOME/.nvu/bin:$PATH\"');\n console.log('');\n console.log(' # For zsh (~/.zshrc):');\n console.log(' export PATH=\"$HOME/.nvu/bin:$PATH\"');\n console.log('');\n console.log(' # For fish (~/.config/fish/config.fish):');\n console.log(' set -gx PATH $HOME/.nvu/bin $PATH');\n }\n\n console.log('');\n console.log('Then restart your terminal or source your shell profile.');\n console.log('');\n console.log(\"Without this, 'nvu 18 npm test' still works - you just won't have\");\n console.log(\"transparent 'node' command override.\");\n console.log('============================================================');\n}\n\n/**\n * Main installation function\n */\nfunction main(): void {\n const archiveBaseName = getArchiveBaseName();\n\n if (!archiveBaseName) {\n console.log('postinstall: Unsupported platform/architecture for binary.');\n console.log(`Platform: ${os.platform()}, Arch: ${os.arch()}`);\n console.log('Binary not installed. You can still use nvu with explicit versions: nvu 18 npm test');\n exit(0);\n return;\n }\n\n const extractedBinaryName = getExtractedBinaryName(archiveBaseName);\n\n const homedirPath = homedir();\n const nvuDir = path.join(homedirPath, '.nvu');\n const binDir = path.join(nvuDir, 'bin');\n\n // Create directories\n mkdirp.sync(nvuDir);\n mkdirp.sync(binDir);\n\n const downloadUrl = getDownloadUrl(archiveBaseName);\n const ext = os.platform() === 'win32' ? '.zip' : '.tar.gz';\n const tempPath = path.join(getTmpDir(), `nvu-binary-${Date.now()}${ext}`);\n\n console.log(`postinstall: Downloading binary for ${os.platform()}-${os.arch()}...`);\n\n downloadFile(downloadUrl, tempPath, (downloadErr) => {\n if (downloadErr) {\n // Clean up temp file if it exists\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n\n if (downloadErr.message?.indexOf('404') >= 0) {\n console.log('postinstall: Binaries not yet published to GitHub releases.');\n console.log('');\n console.log('To build and install binaries locally:');\n console.log(' cd node_modules/node-version-use/binary');\n console.log(' make install');\n console.log('');\n console.log('Or wait for the next release which will include pre-built binaries.');\n } else {\n console.log(`postinstall warning: Failed to install binary: ${downloadErr.message || downloadErr}`);\n console.log('You can still use nvu with explicit versions: nvu 18 npm test');\n console.log('To install binaries manually: cd node_modules/node-version-use/binary && make install');\n }\n printInstructions(false);\n exit(0);\n return;\n }\n\n console.log('postinstall: Extracting binary...');\n\n extractAndInstall(tempPath, binDir, extractedBinaryName, (extractErr) => {\n // Clean up temp file\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n\n if (extractErr) {\n console.log(`postinstall warning: Failed to extract binary: ${extractErr.message || extractErr}`);\n console.log('You can still use nvu with explicit versions: nvu 18 npm test');\n printInstructions(false);\n exit(0);\n return;\n }\n\n console.log('postinstall: Binary installed successfully!');\n printInstructions(true);\n exit(0);\n });\n });\n}\n\nmain();\n"],"names":["spawn","require","exit","fs","mkdirp","os","path","hasHomedir","homedir","home","module","exports","GITHUB_REPO","BINARY_VERSION","join","__dirname","binaryVersion","getArchiveBaseName","platform","arch","platformMap","darwin","linux","win32","archMap","x64","arm64","amd64","platformName","archName","getExtractedBinaryName","archiveBaseName","ext","getDownloadUrl","copyFileSync","src","dest","content","readFileSync","writeFileSync","atomicRename","callback","rename","err","code","unlinkSync","copyErr","rmRecursive","dir","existsSync","files","readdirSync","i","length","filePath","stat","statSync","isDirectory","rmdirSync","getTmpDir","tmpdir","process","env","TMPDIR","TMP","TEMP","downloadWithCurl","downloadUrl","destPath","curl","on","Error","downloadWithPowerShell","psCommand","ps","downloadFile","message","indexOf","extractArchive","archivePath","destDir","tar","extractAndInstall","binaryName","isWindows","tempExtractDir","Date","now","sync","extractErr","extractedPath","binaries","timestamp","installError","name","tempDest","chmodSync","j","tempPath","_e","renameError","doRename","index","finalDest","printInstructions","installed","homedirPath","nvuBinPath","console","log","main","extractedBinaryName","nvuDir","binDir","downloadErr"],"mappings":"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"}
@@ -8,22 +8,27 @@
8
8
  * 1. Download to temp file
9
9
  * 2. Extract to temp directory
10
10
  * 3. Atomic rename to final location
11
- */ import { spawn } from 'child_process';
12
- import exit from 'exit-compat';
13
- import fs from 'fs';
14
- import mkdirp from 'mkdirp-classic';
15
- import Module from 'module';
16
- import os from 'os';
17
- import path from 'path';
18
- import url from 'url';
19
- import { homedir } from '../compat.js';
20
- // CJS/ESM compatibility
21
- const _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;
22
- const __dirname = path.dirname(typeof __filename !== 'undefined' ? __filename : url.fileURLToPath(import.meta.url));
11
+ */ const { spawn } = require('child_process');
12
+ const exit = require('exit-compat');
13
+ const fs = require('fs');
14
+ const mkdirp = require('mkdirp-classic');
15
+ const os = require('os');
16
+ const path = require('path');
17
+ const hasHomedir = typeof os.homedir === 'function';
18
+ function homedir() {
19
+ if (hasHomedir) {
20
+ return os.homedir();
21
+ }
22
+ var home = require('homedir-polyfill');
23
+ return home();
24
+ }
25
+ module.exports = {
26
+ homedir
27
+ };
23
28
  // Configuration
24
29
  const GITHUB_REPO = 'kmalakoff/node-version-use';
25
30
  // Path is relative to dist/cjs/scripts/ at runtime
26
- const BINARY_VERSION = _require(path.join(__dirname, '..', '..', '..', 'package.json')).binaryVersion;
31
+ const BINARY_VERSION = require(path.join(__dirname, '..', 'package.json')).binaryVersion;
27
32
  /**
28
33
  * Get the platform-specific archive base name (without extension)
29
34
  */ function getArchiveBaseName() {
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/assets/postinstall.cts"],"sourcesContent":["/**\n * Postinstall script for node-version-use\n *\n * Downloads the platform-specific binary and installs it to ~/.nvu/bin/\n * This enables transparent Node version switching.\n *\n * Uses safe atomic download pattern:\n * 1. Download to temp file\n * 2. Extract to temp directory\n * 3. Atomic rename to final location\n */\n\nconst { spawn } = require('child_process');\nconst exit = require('exit-compat');\nconst fs = require('fs');\nconst mkdirp = require('mkdirp-classic');\nconst os = require('os');\nconst path = require('path');\n\nconst hasHomedir = typeof os.homedir === 'function';\nfunction homedir(): string {\n if (hasHomedir) {\n return os.homedir();\n }\n var home = require('homedir-polyfill');\n return home();\n}\n\nmodule.exports = { homedir };\n\n// Configuration\nconst GITHUB_REPO = 'kmalakoff/node-version-use';\n// Path is relative to dist/cjs/scripts/ at runtime\nconst BINARY_VERSION = require(path.join(__dirname, '..', 'package.json')).binaryVersion;\n\ntype Callback = (err?: Error | null) => void;\n\ninterface PlatformMap {\n [key: string]: string;\n}\n\n/**\n * Get the platform-specific archive base name (without extension)\n */\nfunction getArchiveBaseName(): string | null {\n const platform = os.platform();\n const arch = os.arch();\n\n const platformMap: PlatformMap = {\n darwin: 'darwin',\n linux: 'linux',\n win32: 'win32',\n };\n\n const archMap: PlatformMap = {\n x64: 'x64',\n arm64: 'arm64',\n amd64: 'x64',\n };\n\n const platformName = platformMap[platform];\n const archName = archMap[arch];\n\n if (!platformName || !archName) {\n return null;\n }\n\n return `nvu-binary-${platformName}-${archName}`;\n}\n\n/**\n * Get the extracted binary name (includes .exe on Windows)\n */\nfunction getExtractedBinaryName(archiveBaseName: string): string {\n const ext = os.platform() === 'win32' ? '.exe' : '';\n return archiveBaseName + ext;\n}\n\n/**\n * Get the download URL for the binary archive\n */\nfunction getDownloadUrl(archiveBaseName: string): string {\n const ext = os.platform() === 'win32' ? '.zip' : '.tar.gz';\n return `https://github.com/${GITHUB_REPO}/releases/download/binary-v${BINARY_VERSION}/${archiveBaseName}${ext}`;\n}\n\n/**\n * Copy file\n */\nfunction copyFileSync(src: string, dest: string): void {\n const content = fs.readFileSync(src);\n fs.writeFileSync(dest, content);\n}\n\n/**\n * Atomic rename with fallback to copy+delete for cross-device moves\n */\nfunction atomicRename(src: string, dest: string, callback: Callback): void {\n fs.rename(src, dest, (err) => {\n if (!err) {\n callback(null);\n return;\n }\n\n // Cross-device link error - fall back to copy + delete\n if ((err as NodeJS.ErrnoException).code === 'EXDEV') {\n try {\n copyFileSync(src, dest);\n fs.unlinkSync(src);\n callback(null);\n } catch (copyErr) {\n callback(copyErr as Error);\n }\n return;\n }\n\n callback(err);\n });\n}\n\n/**\n * Remove directory recursively\n */\nfunction rmRecursive(dir: string): void {\n if (!fs.existsSync(dir)) return;\n\n const files = fs.readdirSync(dir);\n for (let i = 0; i < files.length; i++) {\n const filePath = path.join(dir, files[i]);\n const stat = fs.statSync(filePath);\n if (stat.isDirectory()) {\n rmRecursive(filePath);\n } else {\n fs.unlinkSync(filePath);\n }\n }\n fs.rmdirSync(dir);\n}\n\n/**\n * Get temp directory\n */\nfunction getTmpDir(): string {\n return typeof os.tmpdir === 'function' ? os.tmpdir() : process.env.TMPDIR || process.env.TMP || process.env.TEMP || '/tmp';\n}\n\n/**\n * Download using curl (macOS, Linux, Windows 10+)\n */\nfunction downloadWithCurl(downloadUrl: string, destPath: string, callback: Callback): void {\n const curl = spawn('curl', ['-L', '-f', '-s', '-o', destPath, downloadUrl]);\n\n curl.on('close', (code) => {\n if (code !== 0) {\n // curl exit codes: 22 = HTTP error (4xx/5xx), 56 = receive error (often 404 with -f)\n if (code === 22 || code === 56) {\n callback(new Error('HTTP 404'));\n } else {\n callback(new Error(`curl failed with exit code ${code}`));\n }\n return;\n }\n callback(null);\n });\n\n curl.on('error', (err) => {\n callback(err);\n });\n}\n\n/**\n * Download using PowerShell (Windows 7+ fallback)\n */\nfunction downloadWithPowerShell(downloadUrl: string, destPath: string, callback: Callback): void {\n const psCommand = `Invoke-WebRequest -Uri \"${downloadUrl}\" -OutFile \"${destPath}\" -UseBasicParsing`;\n const ps = spawn('powershell', ['-NoProfile', '-Command', psCommand]);\n\n ps.on('close', (code) => {\n if (code !== 0) {\n callback(new Error(`PowerShell download failed with exit code ${code}`));\n return;\n }\n callback(null);\n });\n\n ps.on('error', (err) => {\n callback(err);\n });\n}\n\n/**\n * Download a file - tries curl first, falls back to PowerShell on Windows\n * Node 0.8's OpenSSL doesn't support TLS 1.2+ required by GitHub\n */\nfunction downloadFile(downloadUrl: string, destPath: string, callback: Callback): void {\n downloadWithCurl(downloadUrl, destPath, (err) => {\n if (!err) {\n callback(null);\n return;\n }\n\n // If curl failed and we're on Windows, try PowerShell\n if (os.platform() === 'win32' && err?.message?.indexOf('ENOENT') >= 0) {\n downloadWithPowerShell(downloadUrl, destPath, callback);\n return;\n }\n\n callback(err);\n });\n}\n\n/**\n * Extract archive to a directory (callback-based)\n */\nfunction extractArchive(archivePath: string, destDir: string, callback: Callback): void {\n const platform = os.platform();\n\n if (platform === 'win32') {\n // Windows: extract zip using PowerShell\n const ps = spawn('powershell', ['-Command', `Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force`]);\n ps.on('close', (code) => {\n if (code !== 0) {\n callback(new Error('Failed to extract archive'));\n return;\n }\n callback(null);\n });\n } else {\n // Unix: extract tar.gz\n const tar = spawn('tar', ['-xzf', archivePath, '-C', destDir]);\n tar.on('close', (code) => {\n if (code !== 0) {\n callback(new Error('Failed to extract archive'));\n return;\n }\n callback(null);\n });\n }\n}\n\n/**\n * Install binaries using atomic rename pattern\n * 1. Extract to temp directory\n * 2. Copy binary to temp files in destination directory\n * 3. Atomic rename temp files to final names\n */\nfunction extractAndInstall(archivePath: string, destDir: string, binaryName: string, callback: Callback): void {\n const platform = os.platform();\n const isWindows = platform === 'win32';\n const ext = isWindows ? '.exe' : '';\n\n // Create temp extraction directory\n const tempExtractDir = path.join(getTmpDir(), `nvu-extract-${Date.now()}`);\n mkdirp.sync(tempExtractDir);\n\n extractArchive(archivePath, tempExtractDir, (extractErr) => {\n if (extractErr) {\n rmRecursive(tempExtractDir);\n callback(extractErr);\n return;\n }\n\n const extractedPath = path.join(tempExtractDir, binaryName);\n if (!fs.existsSync(extractedPath)) {\n rmRecursive(tempExtractDir);\n callback(new Error(`Extracted binary not found: ${binaryName}`));\n return;\n }\n\n // Binary names to install\n const binaries = ['node', 'npm', 'npx', 'corepack'];\n const timestamp = Date.now();\n let installError: Error | null = null;\n\n // Step 1: Copy extracted binary to temp files in destination directory\n // This ensures the temp files are on the same filesystem for atomic rename\n for (let i = 0; i < binaries.length; i++) {\n const name = binaries[i];\n const tempDest = path.join(destDir, `${name}.tmp-${timestamp}${ext}`);\n\n try {\n // Copy to temp file in destination directory\n copyFileSync(extractedPath, tempDest);\n\n // Set permissions on Unix\n if (!isWindows) {\n fs.chmodSync(tempDest, 0o755);\n }\n } catch (err) {\n installError = err as Error;\n break;\n }\n }\n\n if (installError) {\n // Clean up any temp files we created\n for (let j = 0; j < binaries.length; j++) {\n const tempPath = path.join(destDir, `${binaries[j]}.tmp-${timestamp}${ext}`);\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n }\n rmRecursive(tempExtractDir);\n callback(installError);\n return;\n }\n\n // Step 2: Atomic rename temp files to final names\n let renameError: Error | null = null;\n\n function doRename(index: number): void {\n if (index >= binaries.length) {\n // All renames complete\n rmRecursive(tempExtractDir);\n callback(renameError);\n return;\n }\n\n const name = binaries[index];\n const tempDest = path.join(destDir, `${name}.tmp-${timestamp}${ext}`);\n const finalDest = path.join(destDir, `${name}${ext}`);\n\n // Remove existing file if present (for atomic replacement)\n if (fs.existsSync(finalDest)) {\n try {\n fs.unlinkSync(finalDest);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n\n atomicRename(tempDest, finalDest, (err) => {\n if (err && !renameError) {\n renameError = err;\n }\n doRename(index + 1);\n });\n }\n\n doRename(0);\n });\n}\n\n/**\n * Print setup instructions\n */\nfunction printInstructions(installed: boolean): void {\n const homedirPath = homedir();\n const nvuBinPath = path.join(homedirPath, '.nvu', 'bin');\n const platform = os.platform();\n\n console.log('');\n console.log('============================================================');\n if (installed) {\n console.log(' nvu binaries installed to ~/.nvu/bin/');\n } else {\n console.log(' nvu installed (binaries not yet available)');\n }\n console.log('============================================================');\n console.log('');\n console.log('To enable transparent Node version switching, add to your shell profile:');\n console.log('');\n\n if (platform === 'win32') {\n console.log(' PowerShell (add to $PROFILE):');\n console.log(` $env:PATH = \"${nvuBinPath};$env:PATH\"`);\n console.log('');\n console.log(' CMD (run as administrator):');\n console.log(` setx PATH \"${nvuBinPath};%PATH%\"`);\n } else {\n console.log(' # For bash (~/.bashrc):');\n console.log(' export PATH=\"$HOME/.nvu/bin:$PATH\"');\n console.log('');\n console.log(' # For zsh (~/.zshrc):');\n console.log(' export PATH=\"$HOME/.nvu/bin:$PATH\"');\n console.log('');\n console.log(' # For fish (~/.config/fish/config.fish):');\n console.log(' set -gx PATH $HOME/.nvu/bin $PATH');\n }\n\n console.log('');\n console.log('Then restart your terminal or source your shell profile.');\n console.log('');\n console.log(\"Without this, 'nvu 18 npm test' still works - you just won't have\");\n console.log(\"transparent 'node' command override.\");\n console.log('============================================================');\n}\n\n/**\n * Main installation function\n */\nfunction main(): void {\n const archiveBaseName = getArchiveBaseName();\n\n if (!archiveBaseName) {\n console.log('postinstall: Unsupported platform/architecture for binary.');\n console.log(`Platform: ${os.platform()}, Arch: ${os.arch()}`);\n console.log('Binary not installed. You can still use nvu with explicit versions: nvu 18 npm test');\n exit(0);\n return;\n }\n\n const extractedBinaryName = getExtractedBinaryName(archiveBaseName);\n\n const homedirPath = homedir();\n const nvuDir = path.join(homedirPath, '.nvu');\n const binDir = path.join(nvuDir, 'bin');\n\n // Create directories\n mkdirp.sync(nvuDir);\n mkdirp.sync(binDir);\n\n const downloadUrl = getDownloadUrl(archiveBaseName);\n const ext = os.platform() === 'win32' ? '.zip' : '.tar.gz';\n const tempPath = path.join(getTmpDir(), `nvu-binary-${Date.now()}${ext}`);\n\n console.log(`postinstall: Downloading binary for ${os.platform()}-${os.arch()}...`);\n\n downloadFile(downloadUrl, tempPath, (downloadErr) => {\n if (downloadErr) {\n // Clean up temp file if it exists\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n\n if (downloadErr.message?.indexOf('404') >= 0) {\n console.log('postinstall: Binaries not yet published to GitHub releases.');\n console.log('');\n console.log('To build and install binaries locally:');\n console.log(' cd node_modules/node-version-use/binary');\n console.log(' make install');\n console.log('');\n console.log('Or wait for the next release which will include pre-built binaries.');\n } else {\n console.log(`postinstall warning: Failed to install binary: ${downloadErr.message || downloadErr}`);\n console.log('You can still use nvu with explicit versions: nvu 18 npm test');\n console.log('To install binaries manually: cd node_modules/node-version-use/binary && make install');\n }\n printInstructions(false);\n exit(0);\n return;\n }\n\n console.log('postinstall: Extracting binary...');\n\n extractAndInstall(tempPath, binDir, extractedBinaryName, (extractErr) => {\n // Clean up temp file\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n\n if (extractErr) {\n console.log(`postinstall warning: Failed to extract binary: ${extractErr.message || extractErr}`);\n console.log('You can still use nvu with explicit versions: nvu 18 npm test');\n printInstructions(false);\n exit(0);\n return;\n }\n\n console.log('postinstall: Binary installed successfully!');\n printInstructions(true);\n exit(0);\n });\n });\n}\n\nmain();\n"],"names":["spawn","require","exit","fs","mkdirp","os","path","hasHomedir","homedir","home","module","exports","GITHUB_REPO","BINARY_VERSION","join","__dirname","binaryVersion","getArchiveBaseName","platform","arch","platformMap","darwin","linux","win32","archMap","x64","arm64","amd64","platformName","archName","getExtractedBinaryName","archiveBaseName","ext","getDownloadUrl","copyFileSync","src","dest","content","readFileSync","writeFileSync","atomicRename","callback","rename","err","code","unlinkSync","copyErr","rmRecursive","dir","existsSync","files","readdirSync","i","length","filePath","stat","statSync","isDirectory","rmdirSync","getTmpDir","tmpdir","process","env","TMPDIR","TMP","TEMP","downloadWithCurl","downloadUrl","destPath","curl","on","Error","downloadWithPowerShell","psCommand","ps","downloadFile","message","indexOf","extractArchive","archivePath","destDir","tar","extractAndInstall","binaryName","isWindows","tempExtractDir","Date","now","sync","extractErr","extractedPath","binaries","timestamp","installError","name","tempDest","chmodSync","j","tempPath","_e","renameError","doRename","index","finalDest","printInstructions","installed","homedirPath","nvuBinPath","console","log","main","extractedBinaryName","nvuDir","binDir","downloadErr"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-version-use",
3
- "version": "2.1.4",
3
+ "version": "2.1.5",
4
4
  "description": "Cross-platform solution for using multiple versions of node. Useful for compatibility testing",
5
5
  "keywords": [
6
6
  "node",
@@ -34,15 +34,15 @@
34
34
  "files": [
35
35
  "bin",
36
36
  "dist",
37
- "scripts"
37
+ "assets"
38
38
  ],
39
39
  "scripts": {
40
40
  "build": "tsds build",
41
+ "build:assets": "tsds build && mkdir -p assets && cp -R dist/cjs/assets/*.cjs assets/",
41
42
  "clean": "rm -rf .tmp dist",
42
43
  "format": "tsds format",
43
- "postinstall": "node scripts/postinstall.cjs",
44
+ "postinstall": "node assets/postinstall.cjs",
44
45
  "prepublishOnly": "tsds validate",
45
- "pretest": "node scripts/ensure-test-binaries.ts",
46
46
  "test": "tsds test:node --no-timeouts",
47
47
  "test:engines": "nvu engines tsds test:node --no-timeouts",
48
48
  "version": "tsds version"
@@ -53,7 +53,7 @@
53
53
  "fs-remove-compat": "^0.2.1",
54
54
  "getopts-compat": "^2.2.6",
55
55
  "homedir-polyfill": "^1.0.3",
56
- "install-module-linked": "^1.3.12",
56
+ "install-module-linked": "^1.3.13",
57
57
  "mkdirp-classic": "^0.5.3",
58
58
  "node-resolve-versions": "^1.3.11",
59
59
  "node-version-utils": "^1.3.15",
@@ -70,8 +70,8 @@
70
70
  "fs-remove-compat": "^0.2.1",
71
71
  "is-version": "^1.0.7",
72
72
  "mkdirp-classic": "^0.5.3",
73
- "node-version-install": "^1.5.0",
74
- "node-version-use": "^2.1.3",
73
+ "node-version-install": "^1.5.1",
74
+ "node-version-use": "^2.1.4",
75
75
  "os-shim": "^0.1.3",
76
76
  "pinkie-promise": "^2.0.1",
77
77
  "ts-dev-stack": "^1.21.3",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/scripts/postinstall.ts"],"sourcesContent":["/**\n * Postinstall script for node-version-use\n *\n * Downloads the platform-specific binary and installs it to ~/.nvu/bin/\n * This enables transparent Node version switching.\n *\n * Uses safe atomic download pattern:\n * 1. Download to temp file\n * 2. Extract to temp directory\n * 3. Atomic rename to final location\n */\n\nimport { spawn } from 'child_process';\nimport exit from 'exit-compat';\nimport fs from 'fs';\nimport mkdirp from 'mkdirp-classic';\nimport Module from 'module';\nimport os from 'os';\nimport path from 'path';\nimport url from 'url';\nimport { homedir } from '../compat.ts';\n\n// CJS/ESM compatibility\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\nconst __dirname = path.dirname(typeof __filename !== 'undefined' ? __filename : url.fileURLToPath(import.meta.url));\n\n// Configuration\nconst GITHUB_REPO = 'kmalakoff/node-version-use';\n// Path is relative to dist/cjs/scripts/ at runtime\nconst BINARY_VERSION = _require(path.join(__dirname, '..', '..', '..', 'package.json')).binaryVersion;\n\ntype Callback = (err?: Error | null) => void;\n\ninterface PlatformMap {\n [key: string]: string;\n}\n\n/**\n * Get the platform-specific archive base name (without extension)\n */\nfunction getArchiveBaseName(): string | null {\n const platform = os.platform();\n const arch = os.arch();\n\n const platformMap: PlatformMap = {\n darwin: 'darwin',\n linux: 'linux',\n win32: 'win32',\n };\n\n const archMap: PlatformMap = {\n x64: 'x64',\n arm64: 'arm64',\n amd64: 'x64',\n };\n\n const platformName = platformMap[platform];\n const archName = archMap[arch];\n\n if (!platformName || !archName) {\n return null;\n }\n\n return `nvu-binary-${platformName}-${archName}`;\n}\n\n/**\n * Get the extracted binary name (includes .exe on Windows)\n */\nfunction getExtractedBinaryName(archiveBaseName: string): string {\n const ext = os.platform() === 'win32' ? '.exe' : '';\n return archiveBaseName + ext;\n}\n\n/**\n * Get the download URL for the binary archive\n */\nfunction getDownloadUrl(archiveBaseName: string): string {\n const ext = os.platform() === 'win32' ? '.zip' : '.tar.gz';\n return `https://github.com/${GITHUB_REPO}/releases/download/binary-v${BINARY_VERSION}/${archiveBaseName}${ext}`;\n}\n\n/**\n * Copy file\n */\nfunction copyFileSync(src: string, dest: string): void {\n const content = fs.readFileSync(src);\n fs.writeFileSync(dest, content);\n}\n\n/**\n * Atomic rename with fallback to copy+delete for cross-device moves\n */\nfunction atomicRename(src: string, dest: string, callback: Callback): void {\n fs.rename(src, dest, (err) => {\n if (!err) {\n callback(null);\n return;\n }\n\n // Cross-device link error - fall back to copy + delete\n if ((err as NodeJS.ErrnoException).code === 'EXDEV') {\n try {\n copyFileSync(src, dest);\n fs.unlinkSync(src);\n callback(null);\n } catch (copyErr) {\n callback(copyErr as Error);\n }\n return;\n }\n\n callback(err);\n });\n}\n\n/**\n * Remove directory recursively\n */\nfunction rmRecursive(dir: string): void {\n if (!fs.existsSync(dir)) return;\n\n const files = fs.readdirSync(dir);\n for (let i = 0; i < files.length; i++) {\n const filePath = path.join(dir, files[i]);\n const stat = fs.statSync(filePath);\n if (stat.isDirectory()) {\n rmRecursive(filePath);\n } else {\n fs.unlinkSync(filePath);\n }\n }\n fs.rmdirSync(dir);\n}\n\n/**\n * Get temp directory\n */\nfunction getTmpDir(): string {\n return typeof os.tmpdir === 'function' ? os.tmpdir() : process.env.TMPDIR || process.env.TMP || process.env.TEMP || '/tmp';\n}\n\n/**\n * Download using curl (macOS, Linux, Windows 10+)\n */\nfunction downloadWithCurl(downloadUrl: string, destPath: string, callback: Callback): void {\n const curl = spawn('curl', ['-L', '-f', '-s', '-o', destPath, downloadUrl]);\n\n curl.on('close', (code) => {\n if (code !== 0) {\n // curl exit codes: 22 = HTTP error (4xx/5xx), 56 = receive error (often 404 with -f)\n if (code === 22 || code === 56) {\n callback(new Error('HTTP 404'));\n } else {\n callback(new Error(`curl failed with exit code ${code}`));\n }\n return;\n }\n callback(null);\n });\n\n curl.on('error', (err) => {\n callback(err);\n });\n}\n\n/**\n * Download using PowerShell (Windows 7+ fallback)\n */\nfunction downloadWithPowerShell(downloadUrl: string, destPath: string, callback: Callback): void {\n const psCommand = `Invoke-WebRequest -Uri \"${downloadUrl}\" -OutFile \"${destPath}\" -UseBasicParsing`;\n const ps = spawn('powershell', ['-NoProfile', '-Command', psCommand]);\n\n ps.on('close', (code) => {\n if (code !== 0) {\n callback(new Error(`PowerShell download failed with exit code ${code}`));\n return;\n }\n callback(null);\n });\n\n ps.on('error', (err) => {\n callback(err);\n });\n}\n\n/**\n * Download a file - tries curl first, falls back to PowerShell on Windows\n * Node 0.8's OpenSSL doesn't support TLS 1.2+ required by GitHub\n */\nfunction downloadFile(downloadUrl: string, destPath: string, callback: Callback): void {\n downloadWithCurl(downloadUrl, destPath, (err) => {\n if (!err) {\n callback(null);\n return;\n }\n\n // If curl failed and we're on Windows, try PowerShell\n if (os.platform() === 'win32' && err?.message?.indexOf('ENOENT') >= 0) {\n downloadWithPowerShell(downloadUrl, destPath, callback);\n return;\n }\n\n callback(err);\n });\n}\n\n/**\n * Extract archive to a directory (callback-based)\n */\nfunction extractArchive(archivePath: string, destDir: string, callback: Callback): void {\n const platform = os.platform();\n\n if (platform === 'win32') {\n // Windows: extract zip using PowerShell\n const ps = spawn('powershell', ['-Command', `Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force`]);\n ps.on('close', (code) => {\n if (code !== 0) {\n callback(new Error('Failed to extract archive'));\n return;\n }\n callback(null);\n });\n } else {\n // Unix: extract tar.gz\n const tar = spawn('tar', ['-xzf', archivePath, '-C', destDir]);\n tar.on('close', (code) => {\n if (code !== 0) {\n callback(new Error('Failed to extract archive'));\n return;\n }\n callback(null);\n });\n }\n}\n\n/**\n * Install binaries using atomic rename pattern\n * 1. Extract to temp directory\n * 2. Copy binary to temp files in destination directory\n * 3. Atomic rename temp files to final names\n */\nfunction extractAndInstall(archivePath: string, destDir: string, binaryName: string, callback: Callback): void {\n const platform = os.platform();\n const isWindows = platform === 'win32';\n const ext = isWindows ? '.exe' : '';\n\n // Create temp extraction directory\n const tempExtractDir = path.join(getTmpDir(), `nvu-extract-${Date.now()}`);\n mkdirp.sync(tempExtractDir);\n\n extractArchive(archivePath, tempExtractDir, (extractErr) => {\n if (extractErr) {\n rmRecursive(tempExtractDir);\n callback(extractErr);\n return;\n }\n\n const extractedPath = path.join(tempExtractDir, binaryName);\n if (!fs.existsSync(extractedPath)) {\n rmRecursive(tempExtractDir);\n callback(new Error(`Extracted binary not found: ${binaryName}`));\n return;\n }\n\n // Binary names to install\n const binaries = ['node', 'npm', 'npx', 'corepack'];\n const timestamp = Date.now();\n let installError: Error | null = null;\n\n // Step 1: Copy extracted binary to temp files in destination directory\n // This ensures the temp files are on the same filesystem for atomic rename\n for (let i = 0; i < binaries.length; i++) {\n const name = binaries[i];\n const tempDest = path.join(destDir, `${name}.tmp-${timestamp}${ext}`);\n\n try {\n // Copy to temp file in destination directory\n copyFileSync(extractedPath, tempDest);\n\n // Set permissions on Unix\n if (!isWindows) {\n fs.chmodSync(tempDest, 0o755);\n }\n } catch (err) {\n installError = err as Error;\n break;\n }\n }\n\n if (installError) {\n // Clean up any temp files we created\n for (let j = 0; j < binaries.length; j++) {\n const tempPath = path.join(destDir, `${binaries[j]}.tmp-${timestamp}${ext}`);\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n }\n rmRecursive(tempExtractDir);\n callback(installError);\n return;\n }\n\n // Step 2: Atomic rename temp files to final names\n let renameError: Error | null = null;\n\n function doRename(index: number): void {\n if (index >= binaries.length) {\n // All renames complete\n rmRecursive(tempExtractDir);\n callback(renameError);\n return;\n }\n\n const name = binaries[index];\n const tempDest = path.join(destDir, `${name}.tmp-${timestamp}${ext}`);\n const finalDest = path.join(destDir, `${name}${ext}`);\n\n // Remove existing file if present (for atomic replacement)\n if (fs.existsSync(finalDest)) {\n try {\n fs.unlinkSync(finalDest);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n\n atomicRename(tempDest, finalDest, (err) => {\n if (err && !renameError) {\n renameError = err;\n }\n doRename(index + 1);\n });\n }\n\n doRename(0);\n });\n}\n\n/**\n * Print setup instructions\n */\nfunction printInstructions(installed: boolean): void {\n const homedirPath = homedir();\n const nvuBinPath = path.join(homedirPath, '.nvu', 'bin');\n const platform = os.platform();\n\n console.log('');\n console.log('============================================================');\n if (installed) {\n console.log(' nvu binaries installed to ~/.nvu/bin/');\n } else {\n console.log(' nvu installed (binaries not yet available)');\n }\n console.log('============================================================');\n console.log('');\n console.log('To enable transparent Node version switching, add to your shell profile:');\n console.log('');\n\n if (platform === 'win32') {\n console.log(' PowerShell (add to $PROFILE):');\n console.log(` $env:PATH = \"${nvuBinPath};$env:PATH\"`);\n console.log('');\n console.log(' CMD (run as administrator):');\n console.log(` setx PATH \"${nvuBinPath};%PATH%\"`);\n } else {\n console.log(' # For bash (~/.bashrc):');\n console.log(' export PATH=\"$HOME/.nvu/bin:$PATH\"');\n console.log('');\n console.log(' # For zsh (~/.zshrc):');\n console.log(' export PATH=\"$HOME/.nvu/bin:$PATH\"');\n console.log('');\n console.log(' # For fish (~/.config/fish/config.fish):');\n console.log(' set -gx PATH $HOME/.nvu/bin $PATH');\n }\n\n console.log('');\n console.log('Then restart your terminal or source your shell profile.');\n console.log('');\n console.log(\"Without this, 'nvu 18 npm test' still works - you just won't have\");\n console.log(\"transparent 'node' command override.\");\n console.log('============================================================');\n}\n\n/**\n * Main installation function\n */\nfunction main(): void {\n const archiveBaseName = getArchiveBaseName();\n\n if (!archiveBaseName) {\n console.log('postinstall: Unsupported platform/architecture for binary.');\n console.log(`Platform: ${os.platform()}, Arch: ${os.arch()}`);\n console.log('Binary not installed. You can still use nvu with explicit versions: nvu 18 npm test');\n exit(0);\n return;\n }\n\n const extractedBinaryName = getExtractedBinaryName(archiveBaseName);\n\n const homedirPath = homedir();\n const nvuDir = path.join(homedirPath, '.nvu');\n const binDir = path.join(nvuDir, 'bin');\n\n // Create directories\n mkdirp.sync(nvuDir);\n mkdirp.sync(binDir);\n\n const downloadUrl = getDownloadUrl(archiveBaseName);\n const ext = os.platform() === 'win32' ? '.zip' : '.tar.gz';\n const tempPath = path.join(getTmpDir(), `nvu-binary-${Date.now()}${ext}`);\n\n console.log(`postinstall: Downloading binary for ${os.platform()}-${os.arch()}...`);\n\n downloadFile(downloadUrl, tempPath, (downloadErr) => {\n if (downloadErr) {\n // Clean up temp file if it exists\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n\n if (downloadErr.message?.indexOf('404') >= 0) {\n console.log('postinstall: Binaries not yet published to GitHub releases.');\n console.log('');\n console.log('To build and install binaries locally:');\n console.log(' cd node_modules/node-version-use/binary');\n console.log(' make install');\n console.log('');\n console.log('Or wait for the next release which will include pre-built binaries.');\n } else {\n console.log(`postinstall warning: Failed to install binary: ${downloadErr.message || downloadErr}`);\n console.log('You can still use nvu with explicit versions: nvu 18 npm test');\n console.log('To install binaries manually: cd node_modules/node-version-use/binary && make install');\n }\n printInstructions(false);\n exit(0);\n return;\n }\n\n console.log('postinstall: Extracting binary...');\n\n extractAndInstall(tempPath, binDir, extractedBinaryName, (extractErr) => {\n // Clean up temp file\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n\n if (extractErr) {\n console.log(`postinstall warning: Failed to extract binary: ${extractErr.message || extractErr}`);\n console.log('You can still use nvu with explicit versions: nvu 18 npm test');\n printInstructions(false);\n exit(0);\n return;\n }\n\n console.log('postinstall: Binary installed successfully!');\n printInstructions(true);\n exit(0);\n });\n });\n}\n\nmain();\n"],"names":["_require","require","Module","createRequire","__dirname","path","dirname","__filename","url","fileURLToPath","GITHUB_REPO","BINARY_VERSION","join","binaryVersion","getArchiveBaseName","platform","os","arch","platformMap","darwin","linux","win32","archMap","x64","arm64","amd64","platformName","archName","getExtractedBinaryName","archiveBaseName","ext","getDownloadUrl","copyFileSync","src","dest","content","fs","readFileSync","writeFileSync","atomicRename","callback","rename","err","code","unlinkSync","copyErr","rmRecursive","dir","existsSync","files","readdirSync","i","length","filePath","stat","statSync","isDirectory","rmdirSync","getTmpDir","tmpdir","process","env","TMPDIR","TMP","TEMP","downloadWithCurl","downloadUrl","destPath","curl","spawn","on","Error","downloadWithPowerShell","psCommand","ps","downloadFile","message","indexOf","extractArchive","archivePath","destDir","tar","extractAndInstall","binaryName","isWindows","tempExtractDir","Date","now","mkdirp","sync","extractErr","extractedPath","binaries","timestamp","installError","name","tempDest","chmodSync","j","tempPath","_e","renameError","doRename","index","finalDest","printInstructions","installed","homedirPath","homedir","nvuBinPath","console","log","main","exit","extractedBinaryName","nvuDir","binDir","downloadErr"],"mappings":"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"}
@@ -1,12 +0,0 @@
1
- /**
2
- * Postinstall script for node-version-use
3
- *
4
- * Downloads the platform-specific binary and installs it to ~/.nvu/bin/
5
- * This enables transparent Node version switching.
6
- *
7
- * Uses safe atomic download pattern:
8
- * 1. Download to temp file
9
- * 2. Extract to temp directory
10
- * 3. Atomic rename to final location
11
- */
12
- export {};
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/scripts/postinstall.ts"],"sourcesContent":["/**\n * Postinstall script for node-version-use\n *\n * Downloads the platform-specific binary and installs it to ~/.nvu/bin/\n * This enables transparent Node version switching.\n *\n * Uses safe atomic download pattern:\n * 1. Download to temp file\n * 2. Extract to temp directory\n * 3. Atomic rename to final location\n */\n\nimport { spawn } from 'child_process';\nimport exit from 'exit-compat';\nimport fs from 'fs';\nimport mkdirp from 'mkdirp-classic';\nimport Module from 'module';\nimport os from 'os';\nimport path from 'path';\nimport url from 'url';\nimport { homedir } from '../compat.ts';\n\n// CJS/ESM compatibility\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\nconst __dirname = path.dirname(typeof __filename !== 'undefined' ? __filename : url.fileURLToPath(import.meta.url));\n\n// Configuration\nconst GITHUB_REPO = 'kmalakoff/node-version-use';\n// Path is relative to dist/cjs/scripts/ at runtime\nconst BINARY_VERSION = _require(path.join(__dirname, '..', '..', '..', 'package.json')).binaryVersion;\n\ntype Callback = (err?: Error | null) => void;\n\ninterface PlatformMap {\n [key: string]: string;\n}\n\n/**\n * Get the platform-specific archive base name (without extension)\n */\nfunction getArchiveBaseName(): string | null {\n const platform = os.platform();\n const arch = os.arch();\n\n const platformMap: PlatformMap = {\n darwin: 'darwin',\n linux: 'linux',\n win32: 'win32',\n };\n\n const archMap: PlatformMap = {\n x64: 'x64',\n arm64: 'arm64',\n amd64: 'x64',\n };\n\n const platformName = platformMap[platform];\n const archName = archMap[arch];\n\n if (!platformName || !archName) {\n return null;\n }\n\n return `nvu-binary-${platformName}-${archName}`;\n}\n\n/**\n * Get the extracted binary name (includes .exe on Windows)\n */\nfunction getExtractedBinaryName(archiveBaseName: string): string {\n const ext = os.platform() === 'win32' ? '.exe' : '';\n return archiveBaseName + ext;\n}\n\n/**\n * Get the download URL for the binary archive\n */\nfunction getDownloadUrl(archiveBaseName: string): string {\n const ext = os.platform() === 'win32' ? '.zip' : '.tar.gz';\n return `https://github.com/${GITHUB_REPO}/releases/download/binary-v${BINARY_VERSION}/${archiveBaseName}${ext}`;\n}\n\n/**\n * Copy file\n */\nfunction copyFileSync(src: string, dest: string): void {\n const content = fs.readFileSync(src);\n fs.writeFileSync(dest, content);\n}\n\n/**\n * Atomic rename with fallback to copy+delete for cross-device moves\n */\nfunction atomicRename(src: string, dest: string, callback: Callback): void {\n fs.rename(src, dest, (err) => {\n if (!err) {\n callback(null);\n return;\n }\n\n // Cross-device link error - fall back to copy + delete\n if ((err as NodeJS.ErrnoException).code === 'EXDEV') {\n try {\n copyFileSync(src, dest);\n fs.unlinkSync(src);\n callback(null);\n } catch (copyErr) {\n callback(copyErr as Error);\n }\n return;\n }\n\n callback(err);\n });\n}\n\n/**\n * Remove directory recursively\n */\nfunction rmRecursive(dir: string): void {\n if (!fs.existsSync(dir)) return;\n\n const files = fs.readdirSync(dir);\n for (let i = 0; i < files.length; i++) {\n const filePath = path.join(dir, files[i]);\n const stat = fs.statSync(filePath);\n if (stat.isDirectory()) {\n rmRecursive(filePath);\n } else {\n fs.unlinkSync(filePath);\n }\n }\n fs.rmdirSync(dir);\n}\n\n/**\n * Get temp directory\n */\nfunction getTmpDir(): string {\n return typeof os.tmpdir === 'function' ? os.tmpdir() : process.env.TMPDIR || process.env.TMP || process.env.TEMP || '/tmp';\n}\n\n/**\n * Download using curl (macOS, Linux, Windows 10+)\n */\nfunction downloadWithCurl(downloadUrl: string, destPath: string, callback: Callback): void {\n const curl = spawn('curl', ['-L', '-f', '-s', '-o', destPath, downloadUrl]);\n\n curl.on('close', (code) => {\n if (code !== 0) {\n // curl exit codes: 22 = HTTP error (4xx/5xx), 56 = receive error (often 404 with -f)\n if (code === 22 || code === 56) {\n callback(new Error('HTTP 404'));\n } else {\n callback(new Error(`curl failed with exit code ${code}`));\n }\n return;\n }\n callback(null);\n });\n\n curl.on('error', (err) => {\n callback(err);\n });\n}\n\n/**\n * Download using PowerShell (Windows 7+ fallback)\n */\nfunction downloadWithPowerShell(downloadUrl: string, destPath: string, callback: Callback): void {\n const psCommand = `Invoke-WebRequest -Uri \"${downloadUrl}\" -OutFile \"${destPath}\" -UseBasicParsing`;\n const ps = spawn('powershell', ['-NoProfile', '-Command', psCommand]);\n\n ps.on('close', (code) => {\n if (code !== 0) {\n callback(new Error(`PowerShell download failed with exit code ${code}`));\n return;\n }\n callback(null);\n });\n\n ps.on('error', (err) => {\n callback(err);\n });\n}\n\n/**\n * Download a file - tries curl first, falls back to PowerShell on Windows\n * Node 0.8's OpenSSL doesn't support TLS 1.2+ required by GitHub\n */\nfunction downloadFile(downloadUrl: string, destPath: string, callback: Callback): void {\n downloadWithCurl(downloadUrl, destPath, (err) => {\n if (!err) {\n callback(null);\n return;\n }\n\n // If curl failed and we're on Windows, try PowerShell\n if (os.platform() === 'win32' && err?.message?.indexOf('ENOENT') >= 0) {\n downloadWithPowerShell(downloadUrl, destPath, callback);\n return;\n }\n\n callback(err);\n });\n}\n\n/**\n * Extract archive to a directory (callback-based)\n */\nfunction extractArchive(archivePath: string, destDir: string, callback: Callback): void {\n const platform = os.platform();\n\n if (platform === 'win32') {\n // Windows: extract zip using PowerShell\n const ps = spawn('powershell', ['-Command', `Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force`]);\n ps.on('close', (code) => {\n if (code !== 0) {\n callback(new Error('Failed to extract archive'));\n return;\n }\n callback(null);\n });\n } else {\n // Unix: extract tar.gz\n const tar = spawn('tar', ['-xzf', archivePath, '-C', destDir]);\n tar.on('close', (code) => {\n if (code !== 0) {\n callback(new Error('Failed to extract archive'));\n return;\n }\n callback(null);\n });\n }\n}\n\n/**\n * Install binaries using atomic rename pattern\n * 1. Extract to temp directory\n * 2. Copy binary to temp files in destination directory\n * 3. Atomic rename temp files to final names\n */\nfunction extractAndInstall(archivePath: string, destDir: string, binaryName: string, callback: Callback): void {\n const platform = os.platform();\n const isWindows = platform === 'win32';\n const ext = isWindows ? '.exe' : '';\n\n // Create temp extraction directory\n const tempExtractDir = path.join(getTmpDir(), `nvu-extract-${Date.now()}`);\n mkdirp.sync(tempExtractDir);\n\n extractArchive(archivePath, tempExtractDir, (extractErr) => {\n if (extractErr) {\n rmRecursive(tempExtractDir);\n callback(extractErr);\n return;\n }\n\n const extractedPath = path.join(tempExtractDir, binaryName);\n if (!fs.existsSync(extractedPath)) {\n rmRecursive(tempExtractDir);\n callback(new Error(`Extracted binary not found: ${binaryName}`));\n return;\n }\n\n // Binary names to install\n const binaries = ['node', 'npm', 'npx', 'corepack'];\n const timestamp = Date.now();\n let installError: Error | null = null;\n\n // Step 1: Copy extracted binary to temp files in destination directory\n // This ensures the temp files are on the same filesystem for atomic rename\n for (let i = 0; i < binaries.length; i++) {\n const name = binaries[i];\n const tempDest = path.join(destDir, `${name}.tmp-${timestamp}${ext}`);\n\n try {\n // Copy to temp file in destination directory\n copyFileSync(extractedPath, tempDest);\n\n // Set permissions on Unix\n if (!isWindows) {\n fs.chmodSync(tempDest, 0o755);\n }\n } catch (err) {\n installError = err as Error;\n break;\n }\n }\n\n if (installError) {\n // Clean up any temp files we created\n for (let j = 0; j < binaries.length; j++) {\n const tempPath = path.join(destDir, `${binaries[j]}.tmp-${timestamp}${ext}`);\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n }\n rmRecursive(tempExtractDir);\n callback(installError);\n return;\n }\n\n // Step 2: Atomic rename temp files to final names\n let renameError: Error | null = null;\n\n function doRename(index: number): void {\n if (index >= binaries.length) {\n // All renames complete\n rmRecursive(tempExtractDir);\n callback(renameError);\n return;\n }\n\n const name = binaries[index];\n const tempDest = path.join(destDir, `${name}.tmp-${timestamp}${ext}`);\n const finalDest = path.join(destDir, `${name}${ext}`);\n\n // Remove existing file if present (for atomic replacement)\n if (fs.existsSync(finalDest)) {\n try {\n fs.unlinkSync(finalDest);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n\n atomicRename(tempDest, finalDest, (err) => {\n if (err && !renameError) {\n renameError = err;\n }\n doRename(index + 1);\n });\n }\n\n doRename(0);\n });\n}\n\n/**\n * Print setup instructions\n */\nfunction printInstructions(installed: boolean): void {\n const homedirPath = homedir();\n const nvuBinPath = path.join(homedirPath, '.nvu', 'bin');\n const platform = os.platform();\n\n console.log('');\n console.log('============================================================');\n if (installed) {\n console.log(' nvu binaries installed to ~/.nvu/bin/');\n } else {\n console.log(' nvu installed (binaries not yet available)');\n }\n console.log('============================================================');\n console.log('');\n console.log('To enable transparent Node version switching, add to your shell profile:');\n console.log('');\n\n if (platform === 'win32') {\n console.log(' PowerShell (add to $PROFILE):');\n console.log(` $env:PATH = \"${nvuBinPath};$env:PATH\"`);\n console.log('');\n console.log(' CMD (run as administrator):');\n console.log(` setx PATH \"${nvuBinPath};%PATH%\"`);\n } else {\n console.log(' # For bash (~/.bashrc):');\n console.log(' export PATH=\"$HOME/.nvu/bin:$PATH\"');\n console.log('');\n console.log(' # For zsh (~/.zshrc):');\n console.log(' export PATH=\"$HOME/.nvu/bin:$PATH\"');\n console.log('');\n console.log(' # For fish (~/.config/fish/config.fish):');\n console.log(' set -gx PATH $HOME/.nvu/bin $PATH');\n }\n\n console.log('');\n console.log('Then restart your terminal or source your shell profile.');\n console.log('');\n console.log(\"Without this, 'nvu 18 npm test' still works - you just won't have\");\n console.log(\"transparent 'node' command override.\");\n console.log('============================================================');\n}\n\n/**\n * Main installation function\n */\nfunction main(): void {\n const archiveBaseName = getArchiveBaseName();\n\n if (!archiveBaseName) {\n console.log('postinstall: Unsupported platform/architecture for binary.');\n console.log(`Platform: ${os.platform()}, Arch: ${os.arch()}`);\n console.log('Binary not installed. You can still use nvu with explicit versions: nvu 18 npm test');\n exit(0);\n return;\n }\n\n const extractedBinaryName = getExtractedBinaryName(archiveBaseName);\n\n const homedirPath = homedir();\n const nvuDir = path.join(homedirPath, '.nvu');\n const binDir = path.join(nvuDir, 'bin');\n\n // Create directories\n mkdirp.sync(nvuDir);\n mkdirp.sync(binDir);\n\n const downloadUrl = getDownloadUrl(archiveBaseName);\n const ext = os.platform() === 'win32' ? '.zip' : '.tar.gz';\n const tempPath = path.join(getTmpDir(), `nvu-binary-${Date.now()}${ext}`);\n\n console.log(`postinstall: Downloading binary for ${os.platform()}-${os.arch()}...`);\n\n downloadFile(downloadUrl, tempPath, (downloadErr) => {\n if (downloadErr) {\n // Clean up temp file if it exists\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n\n if (downloadErr.message?.indexOf('404') >= 0) {\n console.log('postinstall: Binaries not yet published to GitHub releases.');\n console.log('');\n console.log('To build and install binaries locally:');\n console.log(' cd node_modules/node-version-use/binary');\n console.log(' make install');\n console.log('');\n console.log('Or wait for the next release which will include pre-built binaries.');\n } else {\n console.log(`postinstall warning: Failed to install binary: ${downloadErr.message || downloadErr}`);\n console.log('You can still use nvu with explicit versions: nvu 18 npm test');\n console.log('To install binaries manually: cd node_modules/node-version-use/binary && make install');\n }\n printInstructions(false);\n exit(0);\n return;\n }\n\n console.log('postinstall: Extracting binary...');\n\n extractAndInstall(tempPath, binDir, extractedBinaryName, (extractErr) => {\n // Clean up temp file\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n\n if (extractErr) {\n console.log(`postinstall warning: Failed to extract binary: ${extractErr.message || extractErr}`);\n console.log('You can still use nvu with explicit versions: nvu 18 npm test');\n printInstructions(false);\n exit(0);\n return;\n }\n\n console.log('postinstall: Binary installed successfully!');\n printInstructions(true);\n exit(0);\n });\n });\n}\n\nmain();\n"],"names":["spawn","exit","fs","mkdirp","Module","os","path","url","homedir","_require","require","createRequire","__dirname","dirname","__filename","fileURLToPath","GITHUB_REPO","BINARY_VERSION","join","binaryVersion","getArchiveBaseName","platform","arch","platformMap","darwin","linux","win32","archMap","x64","arm64","amd64","platformName","archName","getExtractedBinaryName","archiveBaseName","ext","getDownloadUrl","copyFileSync","src","dest","content","readFileSync","writeFileSync","atomicRename","callback","rename","err","code","unlinkSync","copyErr","rmRecursive","dir","existsSync","files","readdirSync","i","length","filePath","stat","statSync","isDirectory","rmdirSync","getTmpDir","tmpdir","process","env","TMPDIR","TMP","TEMP","downloadWithCurl","downloadUrl","destPath","curl","on","Error","downloadWithPowerShell","psCommand","ps","downloadFile","message","indexOf","extractArchive","archivePath","destDir","tar","extractAndInstall","binaryName","isWindows","tempExtractDir","Date","now","sync","extractErr","extractedPath","binaries","timestamp","installError","name","tempDest","chmodSync","j","tempPath","_e","renameError","doRename","index","finalDest","printInstructions","installed","homedirPath","nvuBinPath","console","log","main","extractedBinaryName","nvuDir","binDir","downloadErr"],"mappings":"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"}
@@ -1,27 +0,0 @@
1
- /**
2
- * Validates that binaries were downloaded by postinstall.
3
- * Called as pretest hook - fails if binaries are missing.
4
- */
5
- import fs from 'fs';
6
- import path from 'path';
7
- import { storagePath } from '../src/constants.ts';
8
-
9
- var BIN_DIR = path.join(storagePath, 'bin');
10
-
11
- // Check for platform-specific binary name
12
- var BINARY_NAME = process.platform === 'win32' ? 'node.exe' : 'node';
13
- var NODE_BINARY = path.join(BIN_DIR, BINARY_NAME);
14
-
15
- function main(): void {
16
- if (!fs.existsSync(NODE_BINARY)) {
17
- console.error('Error: nvu binaries not found at', BIN_DIR);
18
- console.error('');
19
- console.error('Binaries should have been downloaded by postinstall.');
20
- console.error('Try running: npm install');
21
- process.exit(1);
22
- }
23
-
24
- console.log('Binaries found at', BIN_DIR);
25
- }
26
-
27
- main();
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env node
2
- var fs = require('fs');
3
- var path = require('path');
4
- var compiled = path.join(__dirname, '..', 'dist', 'cjs', 'scripts', 'postinstall.js');
5
- if (fs.existsSync(compiled)) {
6
- require(compiled);
7
- } else {
8
- console.log('postinstall: Skipping (dist/ not built yet - run npm run build)');
9
- }
File without changes