node-version-use 2.3.0 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -84
- package/assets/bin/node +0 -0
- package/assets/installBinaries.cjs +95 -18
- package/assets/postinstall.cjs +16 -1
- package/dist/cjs/assets/installBinaries.cjs +95 -18
- package/dist/cjs/assets/installBinaries.cjs.map +1 -1
- package/dist/cjs/assets/postinstall.cjs +16 -1
- package/dist/cjs/assets/postinstall.cjs.map +1 -1
- package/dist/cjs/commands/default.js +30 -4
- package/dist/cjs/commands/default.js.map +1 -1
- package/dist/cjs/commands/setup.d.cts +2 -3
- package/dist/cjs/commands/setup.d.ts +2 -3
- package/dist/cjs/commands/setup.js +9 -84
- package/dist/cjs/commands/setup.js.map +1 -1
- package/dist/cjs/compat.js.map +1 -1
- package/dist/cjs/index.js +2 -5
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/assets/installBinaries.cjs +78 -18
- package/dist/esm/assets/installBinaries.cjs.map +1 -1
- package/dist/esm/assets/postinstall.cjs +16 -1
- package/dist/esm/assets/postinstall.cjs.map +1 -1
- package/dist/esm/commands/default.js +30 -4
- package/dist/esm/commands/default.js.map +1 -1
- package/dist/esm/commands/setup.d.ts +2 -3
- package/dist/esm/commands/setup.js +9 -84
- package/dist/esm/commands/setup.js.map +1 -1
- package/dist/esm/compat.js.map +1 -1
- package/dist/esm/index.js +2 -5
- package/dist/esm/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -36,21 +36,24 @@ function removeIfExistsSync(filePath) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
39
|
+
* Move a file out of the way (works even if running on Windows)
|
|
40
|
+
* First tries to unlink; if that fails (Windows locked), rename to .old-timestamp
|
|
41
41
|
*/ function moveOutOfWay(filePath) {
|
|
42
42
|
if (!fs.existsSync(filePath)) return;
|
|
43
|
+
// First try to unlink (works on Unix, fails on Windows if running)
|
|
44
|
+
try {
|
|
45
|
+
fs.unlinkSync(filePath);
|
|
46
|
+
return;
|
|
47
|
+
} catch (_e) {
|
|
48
|
+
// Unlink failed (likely Windows locked file), try rename
|
|
49
|
+
}
|
|
50
|
+
// Rename to .old-timestamp as fallback
|
|
43
51
|
const timestamp = Date.now();
|
|
44
52
|
const oldPath = `${filePath}.old-${timestamp}`;
|
|
45
53
|
try {
|
|
46
54
|
fs.renameSync(filePath, oldPath);
|
|
47
|
-
} catch (
|
|
48
|
-
|
|
49
|
-
try {
|
|
50
|
-
fs.unlinkSync(filePath);
|
|
51
|
-
} catch (_e2) {
|
|
52
|
-
// ignore - will fail on atomic rename instead
|
|
53
|
-
}
|
|
55
|
+
} catch (_e2) {
|
|
56
|
+
// Both unlink and rename failed - will fail on atomic rename instead
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
59
|
/**
|
|
@@ -96,6 +99,38 @@ function removeIfExistsSync(filePath) {
|
|
|
96
99
|
const content = fs.readFileSync(src);
|
|
97
100
|
fs.writeFileSync(dest, content);
|
|
98
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Sync all shims by copying the nvu binary to all other files in the bin directory
|
|
104
|
+
* All shims (node, npm, npx, corepack, eslint, etc.) are copies of the same binary
|
|
105
|
+
*/ module.exports.syncAllShims = function syncAllShims(binDir) {
|
|
106
|
+
const isWindows = process.platform === 'win32' || /^(msys|cygwin)$/.test(process.env.OSTYPE);
|
|
107
|
+
const ext = isWindows ? '.exe' : '';
|
|
108
|
+
// Source: nvu binary
|
|
109
|
+
const nvuSource = path.join(binDir, `nvu${ext}`);
|
|
110
|
+
if (!fs.existsSync(nvuSource)) return;
|
|
111
|
+
try {
|
|
112
|
+
const entries = fs.readdirSync(binDir);
|
|
113
|
+
for (const name of entries){
|
|
114
|
+
// Skip nvu itself and nvu.json
|
|
115
|
+
if (name === `nvu${ext}` || name === 'nvu.json') continue;
|
|
116
|
+
// On Windows, only process .exe files
|
|
117
|
+
if (isWindows && !name.endsWith('.exe')) continue;
|
|
118
|
+
const shimPath = path.join(binDir, name);
|
|
119
|
+
const stat = fs.statSync(shimPath);
|
|
120
|
+
if (!stat.isFile()) continue;
|
|
121
|
+
// Move existing file out of the way (Windows compatibility)
|
|
122
|
+
moveOutOfWay(shimPath);
|
|
123
|
+
// Copy nvu binary to shim
|
|
124
|
+
copyFileSync(nvuSource, shimPath);
|
|
125
|
+
// Make executable on Unix
|
|
126
|
+
if (!isWindows) {
|
|
127
|
+
fs.chmodSync(shimPath, 0o755);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
} catch (_e) {
|
|
131
|
+
// Ignore errors - shim sync is best effort
|
|
132
|
+
}
|
|
133
|
+
};
|
|
99
134
|
/**
|
|
100
135
|
* Atomic rename with fallback to copy+delete for cross-device moves
|
|
101
136
|
*/ function atomicRename(src, dest, callback) {
|
|
@@ -278,38 +313,63 @@ function removeIfExistsSync(filePath) {
|
|
|
278
313
|
}
|
|
279
314
|
const extractedBinaryName = `${archiveBaseName}${isWindows ? '.exe' : ''}`;
|
|
280
315
|
const binDir = path.join(storagePath, 'bin');
|
|
316
|
+
const nvuJsonPath = path.join(binDir, 'nvu.json');
|
|
281
317
|
// check if we need to upgrade
|
|
282
318
|
if (!options.force) {
|
|
283
319
|
try {
|
|
284
|
-
// already installed
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
320
|
+
// already installed - read nvu.json
|
|
321
|
+
const nvuJson = JSON.parse(fs.readFileSync(nvuJsonPath, 'utf8'));
|
|
322
|
+
if (nvuJson.binaryVersion === BINARY_VERSION) {
|
|
323
|
+
callback(null, false);
|
|
324
|
+
return;
|
|
290
325
|
}
|
|
291
326
|
} catch (_err) {}
|
|
292
327
|
}
|
|
293
328
|
// Create directories
|
|
294
329
|
mkdirp.sync(storagePath);
|
|
295
330
|
mkdirp.sync(binDir);
|
|
331
|
+
mkdirp.sync(path.join(storagePath, 'cache'));
|
|
296
332
|
// Clean up old .old-* files from previous installs
|
|
297
333
|
cleanupOldFiles(binDir);
|
|
298
334
|
const downloadUrl = `https://github.com/${GITHUB_REPO}/releases/download/binary-v${BINARY_VERSION}/${archiveBaseName}${isWindows ? '.zip' : '.tar.gz'}`;
|
|
299
|
-
const
|
|
335
|
+
const cachePath = path.join(storagePath, 'cache', `${archiveBaseName}${isWindows ? '.zip' : '.tar.gz'}`);
|
|
336
|
+
// Check cache first
|
|
337
|
+
if (fs.existsSync(cachePath)) {
|
|
338
|
+
console.log('Using cached binary...');
|
|
339
|
+
// Use cached file
|
|
340
|
+
extractAndInstall(cachePath, binDir, extractedBinaryName, (err)=>{
|
|
341
|
+
if (err) return callback(err);
|
|
342
|
+
// save binary version for upgrade checks
|
|
343
|
+
fs.writeFileSync(nvuJsonPath, JSON.stringify({
|
|
344
|
+
binaryVersion: BINARY_VERSION
|
|
345
|
+
}, null, 2), 'utf8');
|
|
346
|
+
console.log('Binary installed successfully!');
|
|
347
|
+
callback(null, true);
|
|
348
|
+
});
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
// Download to temp file
|
|
300
352
|
console.log(`Downloading binary for ${process.platform}-${process.arch}...`);
|
|
353
|
+
const tempPath = path.join(tmpdir(), `nvu-binary-${Date.now()}${isWindows ? '.zip' : '.tar.gz'}`);
|
|
301
354
|
getFile(downloadUrl, tempPath, (err)=>{
|
|
302
355
|
if (err) {
|
|
303
356
|
removeIfExistsSync(tempPath);
|
|
304
357
|
callback(new Error(`No prebuilt binary available for ${process.platform}-${process.arch}. Download: ${downloadUrl}. Error: ${err.message}`));
|
|
305
358
|
return;
|
|
306
359
|
}
|
|
307
|
-
|
|
360
|
+
// Copy to cache for future use
|
|
361
|
+
try {
|
|
362
|
+
copyFileSync(tempPath, cachePath);
|
|
363
|
+
} catch (_e) {
|
|
364
|
+
// Cache write failed, continue anyway
|
|
365
|
+
}
|
|
308
366
|
extractAndInstall(tempPath, binDir, extractedBinaryName, (err)=>{
|
|
309
367
|
removeIfExistsSync(tempPath);
|
|
310
368
|
if (err) return callback(err);
|
|
311
369
|
// save binary version for upgrade checks
|
|
312
|
-
fs.writeFileSync(
|
|
370
|
+
fs.writeFileSync(nvuJsonPath, JSON.stringify({
|
|
371
|
+
binaryVersion: BINARY_VERSION
|
|
372
|
+
}, null, 2), 'utf8');
|
|
313
373
|
console.log('Binary installed successfully!');
|
|
314
374
|
callback(null, true);
|
|
315
375
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/assets/installBinaries.cts"],"sourcesContent":["const envPathKey = require('env-path-key');\nconst fs = require('fs');\nconst { safeRmSync } = require('fs-remove-compat');\nconst getFile = require('get-file-compat');\nconst mkdirp = require('mkdirp-classic');\nconst os = require('os');\nconst path = require('path');\nconst Queue = require('queue-cb');\nconst moduleRoot = require('module-root-sync');\n\nconst root = moduleRoot(__dirname);\n\n// Configuration\nconst GITHUB_REPO = 'kmalakoff/node-version-use';\nconst BINARY_VERSION = require(path.join(root, 'package.json')).binaryVersion;\n\nconst isWindows = process.platform === 'win32' || /^(msys|cygwin)$/.test(process.env.OSTYPE);\n\ntype Callback = (err?: Error | null) => void;\n\ninterface PlatformMap {\n [key: string]: string;\n}\n\nconst hasHomedir = typeof os.homedir === 'function';\nfunction homedir(): string {\n if (hasHomedir) return os.homedir();\n const home = require('homedir-polyfill');\n return home();\n}\n\n// Allow NVU_HOME override for testing\nconst storagePath = (process.env.NVU_HOME || path.join(homedir(), '.nvu')) as string;\n\nconst hasTmpdir = typeof os.tmpdir === 'function';\nfunction tmpdir(): string {\n if (hasTmpdir) return os.tmpdir();\n const osShim = require('os-shim');\n return osShim.tmpdir();\n}\n\nfunction removeIfExistsSync(filePath: string): void {\n if (fs.existsSync(filePath)) {\n try {\n fs.unlinkSync(filePath);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n}\n\n/**\n * On Windows, rename a file out of the way instead of deleting.\n * This works even if the file is currently running.\n */\nfunction moveOutOfWay(filePath: string): void {\n if (!fs.existsSync(filePath)) return;\n\n const timestamp = Date.now();\n const oldPath = `${filePath}.old-${timestamp}`;\n\n try {\n fs.renameSync(filePath, oldPath);\n } catch (_e) {\n // If rename fails, try delete as fallback (works on Unix)\n try {\n fs.unlinkSync(filePath);\n } catch (_e2) {\n // ignore - will fail on atomic rename instead\n }\n }\n}\n\n/**\n * Clean up old .old-* files from previous installs\n */\nfunction cleanupOldFiles(dir: string): void {\n try {\n const entries = fs.readdirSync(dir);\n for (const entry of entries) {\n if (entry.includes('.old-')) {\n try {\n fs.unlinkSync(path.join(dir, entry));\n } catch (_e) {\n // ignore - file may still be in use\n }\n }\n }\n } catch (_e) {\n // ignore if dir doesn't exist\n }\n}\n\n/**\n * Get the platform-specific archive base name (without extension)\n */\nfunction getArchiveBaseName(): string | null {\n const { platform, arch } = process;\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) return null;\n return `nvu-binary-${platformName}-${archName}`;\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) {\n fs.rename(src, dest, (err) => {\n if (!err) return callback(null);\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 * Extract archive to a directory (callback-based)\n */\nfunction extractArchive(archivePath: string, dest: string, callback: Callback) {\n const Iterator = isWindows ? require('zip-iterator') : require('tar-iterator');\n const stream = isWindows ? fs.createReadStream(archivePath) : fs.createReadStream(archivePath).pipe(require('zlib').createGunzip());\n let iterator = new Iterator(stream);\n\n // one by one\n const links = [];\n iterator.forEach(\n (entry, callback) => {\n if (entry.type === 'link') {\n links.unshift(entry);\n callback();\n } else if (entry.type === 'symlink') {\n links.push(entry);\n callback();\n } else entry.create(dest, callback);\n },\n { callbacks: true, concurrency: 1 },\n (_err) => {\n // create links after directories and files\n const queue = new Queue();\n for (let index = 0; index < links.length; index++) {\n const entry = links[index];\n queue.defer(entry.create.bind(entry, dest));\n }\n queue.await((err) => {\n iterator.destroy();\n iterator = null;\n callback(err);\n });\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) {\n const ext = isWindows ? '.exe' : '';\n\n // Create temp extraction directory\n const tempExtractDir = path.join(tmpdir(), `nvu-extract-${Date.now()}`);\n mkdirp.sync(tempExtractDir);\n\n extractArchive(archivePath, tempExtractDir, (err) => {\n if (err) {\n safeRmSync(tempExtractDir);\n callback(err);\n return;\n }\n\n const extractedPath = path.join(tempExtractDir, binaryName);\n if (!fs.existsSync(extractedPath)) {\n safeRmSync(tempExtractDir);\n callback(new Error(`Extracted binary not found: ${binaryName}. ${archivePath} ${tempExtractDir}`));\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) fs.chmodSync(tempDest, 0o755);\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 removeIfExistsSync(tempPath);\n }\n safeRmSync(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 safeRmSync(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 // Move existing file out of the way (works even if running on Windows)\n moveOutOfWay(finalDest);\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 */\nmodule.exports.printInstructions = function printInstructions(): void {\n const _nvuBinPath = path.join(storagePath, 'bin');\n\n console.log('nvu binaries installed in ~/.nvu/bin/');\n\n const pathKey = envPathKey();\n const envPath = process.env[pathKey] || '';\n if (envPath.indexOf('.nvu/bin') >= 0) return; // path exists\n\n // provide instructions for path setup\n console.log('');\n console.log('============================================================');\n console.log(' Global node setup');\n console.log('============================================================');\n console.log('');\n if (isWindows) {\n console.log(' # Edit your PowerShell profile');\n console.log(' # Open with: notepad $PROFILE');\n console.log(' # Add this line:');\n console.log(' $env:PATH = \"$HOME\\\\.nvu\\\\bin;$env:APPDATA\\\\npm;$env:PATH\"');\n console.log('');\n console.log(' # This adds:');\n console.log(' # ~/.nvu/bin - node/npm version switching shims');\n console.log(' # %APPDATA%/npm - globally installed npm packages (like nvu)');\n } else {\n console.log(' # For bash (~/.bashrc):');\n console.log(' echo \\'export PATH=\"$HOME/.nvu/bin:$PATH\"\\' >> ~/.bashrc');\n console.log('');\n console.log(' # For zsh (~/.zshrc):');\n console.log(' echo \\'export PATH=\"$HOME/.nvu/bin:$PATH\"\\' >> ~/.zshrc');\n console.log('');\n console.log(' # For fish (~/.config/fish/config.fish):');\n console.log(\" echo 'set -gx PATH $HOME/.nvu/bin $PATH' >> ~/.config/fish/config.fish\");\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 */\nmodule.exports.installBinaries = function installBinaries(options, callback): void {\n const archiveBaseName = getArchiveBaseName();\n\n if (!archiveBaseName) {\n callback(new Error('Unsupported platform/architecture for binary.'));\n return;\n }\n\n const extractedBinaryName = `${archiveBaseName}${isWindows ? '.exe' : ''}`;\n const binDir = path.join(storagePath, 'bin');\n\n // check if we need to upgrade\n if (!options.force) {\n try {\n // already installed\n if (fs.statSync(binDir)) {\n if (fs.readFileSync(path.join(binDir, 'version.txt'), 'utf8') === BINARY_VERSION) {\n callback(null, false);\n return;\n }\n }\n } catch (_err) {}\n }\n\n // Create directories\n mkdirp.sync(storagePath);\n mkdirp.sync(binDir);\n\n // Clean up old .old-* files from previous installs\n cleanupOldFiles(binDir);\n\n const downloadUrl = `https://github.com/${GITHUB_REPO}/releases/download/binary-v${BINARY_VERSION}/${archiveBaseName}${isWindows ? '.zip' : '.tar.gz'}`;\n const tempPath = path.join(tmpdir(), `nvu-binary-${Date.now()}${isWindows ? '.zip' : '.tar.gz'}`);\n\n console.log(`Downloading binary for ${process.platform}-${process.arch}...`);\n\n getFile(downloadUrl, tempPath, (err) => {\n if (err) {\n removeIfExistsSync(tempPath);\n callback(new Error(`No prebuilt binary available for ${process.platform}-${process.arch}. Download: ${downloadUrl}. Error: ${err.message}`));\n return;\n }\n\n console.log('Extracting binary...');\n\n extractAndInstall(tempPath, binDir, extractedBinaryName, (err) => {\n removeIfExistsSync(tempPath);\n if (err) return callback(err);\n\n // save binary version for upgrade checks\n fs.writeFileSync(path.join(binDir, 'version.txt'), BINARY_VERSION, 'utf8');\n console.log('Binary installed successfully!');\n callback(null, true);\n });\n });\n};\n"],"names":["envPathKey","require","fs","safeRmSync","getFile","mkdirp","os","path","Queue","moduleRoot","root","__dirname","GITHUB_REPO","BINARY_VERSION","join","binaryVersion","isWindows","process","platform","test","env","OSTYPE","hasHomedir","homedir","home","storagePath","NVU_HOME","hasTmpdir","tmpdir","osShim","removeIfExistsSync","filePath","existsSync","unlinkSync","_e","moveOutOfWay","timestamp","Date","now","oldPath","renameSync","_e2","cleanupOldFiles","dir","entries","readdirSync","entry","includes","getArchiveBaseName","arch","platformMap","darwin","linux","win32","archMap","x64","arm64","amd64","platformName","archName","copyFileSync","src","dest","content","readFileSync","writeFileSync","atomicRename","callback","rename","err","code","copyErr","extractArchive","archivePath","Iterator","stream","createReadStream","pipe","createGunzip","iterator","links","forEach","type","unshift","push","create","callbacks","concurrency","_err","queue","index","length","defer","bind","await","destroy","extractAndInstall","destDir","binaryName","ext","tempExtractDir","sync","extractedPath","Error","binaries","installError","i","name","tempDest","chmodSync","j","tempPath","renameError","doRename","finalDest","module","exports","printInstructions","_nvuBinPath","console","log","pathKey","envPath","indexOf","installBinaries","options","archiveBaseName","extractedBinaryName","binDir","force","statSync","downloadUrl","message"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/assets/installBinaries.cts"],"sourcesContent":["const envPathKey = require('env-path-key');\nconst fs = require('fs');\nconst { safeRmSync } = require('fs-remove-compat');\nconst getFile = require('get-file-compat');\nconst mkdirp = require('mkdirp-classic');\nconst os = require('os');\nconst path = require('path');\nconst Queue = require('queue-cb');\nconst moduleRoot = require('module-root-sync');\n\nconst root = moduleRoot(__dirname);\n\n// Configuration\nconst GITHUB_REPO = 'kmalakoff/node-version-use';\nconst BINARY_VERSION = require(path.join(root, 'package.json')).binaryVersion;\n\nconst isWindows = process.platform === 'win32' || /^(msys|cygwin)$/.test(process.env.OSTYPE);\n\ntype Callback = (err?: Error | null) => void;\n\ninterface PlatformMap {\n [key: string]: string;\n}\n\nconst hasHomedir = typeof os.homedir === 'function';\nfunction homedir(): string {\n if (hasHomedir) return os.homedir();\n const home = require('homedir-polyfill');\n return home();\n}\n\n// Allow NVU_HOME override for testing\nconst storagePath = (process.env.NVU_HOME || path.join(homedir(), '.nvu')) as string;\n\nconst hasTmpdir = typeof os.tmpdir === 'function';\nfunction tmpdir(): string {\n if (hasTmpdir) return os.tmpdir();\n const osShim = require('os-shim');\n return osShim.tmpdir();\n}\n\nfunction removeIfExistsSync(filePath: string): void {\n if (fs.existsSync(filePath)) {\n try {\n fs.unlinkSync(filePath);\n } catch (_e) {\n // ignore cleanup errors\n }\n }\n}\n\n/**\n * Move a file out of the way (works even if running on Windows)\n * First tries to unlink; if that fails (Windows locked), rename to .old-timestamp\n */\nfunction moveOutOfWay(filePath: string): void {\n if (!fs.existsSync(filePath)) return;\n\n // First try to unlink (works on Unix, fails on Windows if running)\n try {\n fs.unlinkSync(filePath);\n return;\n } catch (_e) {\n // Unlink failed (likely Windows locked file), try rename\n }\n\n // Rename to .old-timestamp as fallback\n const timestamp = Date.now();\n const oldPath = `${filePath}.old-${timestamp}`;\n\n try {\n fs.renameSync(filePath, oldPath);\n } catch (_e2) {\n // Both unlink and rename failed - will fail on atomic rename instead\n }\n}\n\n/**\n * Clean up old .old-* files from previous installs\n */\nfunction cleanupOldFiles(dir: string): void {\n try {\n const entries = fs.readdirSync(dir);\n for (const entry of entries) {\n if (entry.includes('.old-')) {\n try {\n fs.unlinkSync(path.join(dir, entry));\n } catch (_e) {\n // ignore - file may still be in use\n }\n }\n }\n } catch (_e) {\n // ignore if dir doesn't exist\n }\n}\n\n/**\n * Get the platform-specific archive base name (without extension)\n */\nfunction getArchiveBaseName(): string | null {\n const { platform, arch } = process;\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) return null;\n return `nvu-binary-${platformName}-${archName}`;\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 * Sync all shims by copying the nvu binary to all other files in the bin directory\n * All shims (node, npm, npx, corepack, eslint, etc.) are copies of the same binary\n */\nmodule.exports.syncAllShims = function syncAllShims(binDir: string): void {\n const isWindows = process.platform === 'win32' || /^(msys|cygwin)$/.test(process.env.OSTYPE);\n const ext = isWindows ? '.exe' : '';\n\n // Source: nvu binary\n const nvuSource = path.join(binDir, `nvu${ext}`);\n if (!fs.existsSync(nvuSource)) return;\n\n try {\n const entries = fs.readdirSync(binDir);\n for (const name of entries) {\n // Skip nvu itself and nvu.json\n if (name === `nvu${ext}` || name === 'nvu.json') continue;\n\n // On Windows, only process .exe files\n if (isWindows && !name.endsWith('.exe')) continue;\n\n const shimPath = path.join(binDir, name);\n const stat = fs.statSync(shimPath);\n if (!stat.isFile()) continue;\n\n // Move existing file out of the way (Windows compatibility)\n moveOutOfWay(shimPath);\n\n // Copy nvu binary to shim\n copyFileSync(nvuSource, shimPath);\n\n // Make executable on Unix\n if (!isWindows) {\n fs.chmodSync(shimPath, 0o755);\n }\n }\n } catch (_e) {\n // Ignore errors - shim sync is best effort\n }\n};\n\n/**\n * Atomic rename with fallback to copy+delete for cross-device moves\n */\nfunction atomicRename(src: string, dest: string, callback: Callback) {\n fs.rename(src, dest, (err) => {\n if (!err) return callback(null);\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 * Extract archive to a directory (callback-based)\n */\nfunction extractArchive(archivePath: string, dest: string, callback: Callback) {\n const Iterator = isWindows ? require('zip-iterator') : require('tar-iterator');\n const stream = isWindows ? fs.createReadStream(archivePath) : fs.createReadStream(archivePath).pipe(require('zlib').createGunzip());\n let iterator = new Iterator(stream);\n\n // one by one\n const links = [];\n iterator.forEach(\n (entry, callback) => {\n if (entry.type === 'link') {\n links.unshift(entry);\n callback();\n } else if (entry.type === 'symlink') {\n links.push(entry);\n callback();\n } else entry.create(dest, callback);\n },\n { callbacks: true, concurrency: 1 },\n (_err) => {\n // create links after directories and files\n const queue = new Queue();\n for (let index = 0; index < links.length; index++) {\n const entry = links[index];\n queue.defer(entry.create.bind(entry, dest));\n }\n queue.await((err) => {\n iterator.destroy();\n iterator = null;\n callback(err);\n });\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) {\n const ext = isWindows ? '.exe' : '';\n\n // Create temp extraction directory\n const tempExtractDir = path.join(tmpdir(), `nvu-extract-${Date.now()}`);\n mkdirp.sync(tempExtractDir);\n\n extractArchive(archivePath, tempExtractDir, (err) => {\n if (err) {\n safeRmSync(tempExtractDir);\n callback(err);\n return;\n }\n\n const extractedPath = path.join(tempExtractDir, binaryName);\n if (!fs.existsSync(extractedPath)) {\n safeRmSync(tempExtractDir);\n callback(new Error(`Extracted binary not found: ${binaryName}. ${archivePath} ${tempExtractDir}`));\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) fs.chmodSync(tempDest, 0o755);\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 removeIfExistsSync(tempPath);\n }\n safeRmSync(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 safeRmSync(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 // Move existing file out of the way (works even if running on Windows)\n moveOutOfWay(finalDest);\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 */\nmodule.exports.printInstructions = function printInstructions(): void {\n const _nvuBinPath = path.join(storagePath, 'bin');\n\n console.log('nvu binaries installed in ~/.nvu/bin/');\n\n const pathKey = envPathKey();\n const envPath = process.env[pathKey] || '';\n if (envPath.indexOf('.nvu/bin') >= 0) return; // path exists\n\n // provide instructions for path setup\n console.log('');\n console.log('============================================================');\n console.log(' Global node setup');\n console.log('============================================================');\n console.log('');\n if (isWindows) {\n console.log(' # Edit your PowerShell profile');\n console.log(' # Open with: notepad $PROFILE');\n console.log(' # Add this line:');\n console.log(' $env:PATH = \"$HOME\\\\.nvu\\\\bin;$env:APPDATA\\\\npm;$env:PATH\"');\n console.log('');\n console.log(' # This adds:');\n console.log(' # ~/.nvu/bin - node/npm version switching shims');\n console.log(' # %APPDATA%/npm - globally installed npm packages (like nvu)');\n } else {\n console.log(' # For bash (~/.bashrc):');\n console.log(' echo \\'export PATH=\"$HOME/.nvu/bin:$PATH\"\\' >> ~/.bashrc');\n console.log('');\n console.log(' # For zsh (~/.zshrc):');\n console.log(' echo \\'export PATH=\"$HOME/.nvu/bin:$PATH\"\\' >> ~/.zshrc');\n console.log('');\n console.log(' # For fish (~/.config/fish/config.fish):');\n console.log(\" echo 'set -gx PATH $HOME/.nvu/bin $PATH' >> ~/.config/fish/config.fish\");\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 */\nmodule.exports.installBinaries = function installBinaries(options, callback): void {\n const archiveBaseName = getArchiveBaseName();\n\n if (!archiveBaseName) {\n callback(new Error('Unsupported platform/architecture for binary.'));\n return;\n }\n\n const extractedBinaryName = `${archiveBaseName}${isWindows ? '.exe' : ''}`;\n const binDir = path.join(storagePath, 'bin');\n const nvuJsonPath = path.join(binDir, 'nvu.json');\n\n // check if we need to upgrade\n if (!options.force) {\n try {\n // already installed - read nvu.json\n const nvuJson = JSON.parse(fs.readFileSync(nvuJsonPath, 'utf8'));\n if (nvuJson.binaryVersion === BINARY_VERSION) {\n callback(null, false);\n return;\n }\n } catch (_err) {}\n }\n\n // Create directories\n mkdirp.sync(storagePath);\n mkdirp.sync(binDir);\n mkdirp.sync(path.join(storagePath, 'cache'));\n\n // Clean up old .old-* files from previous installs\n cleanupOldFiles(binDir);\n\n const downloadUrl = `https://github.com/${GITHUB_REPO}/releases/download/binary-v${BINARY_VERSION}/${archiveBaseName}${isWindows ? '.zip' : '.tar.gz'}`;\n const cachePath = path.join(storagePath, 'cache', `${archiveBaseName}${isWindows ? '.zip' : '.tar.gz'}`);\n\n // Check cache first\n if (fs.existsSync(cachePath)) {\n console.log('Using cached binary...');\n\n // Use cached file\n extractAndInstall(cachePath, binDir, extractedBinaryName, (err) => {\n if (err) return callback(err);\n\n // save binary version for upgrade checks\n fs.writeFileSync(nvuJsonPath, JSON.stringify({ binaryVersion: BINARY_VERSION }, null, 2), 'utf8');\n console.log('Binary installed successfully!');\n callback(null, true);\n });\n return;\n }\n\n // Download to temp file\n console.log(`Downloading binary for ${process.platform}-${process.arch}...`);\n const tempPath = path.join(tmpdir(), `nvu-binary-${Date.now()}${isWindows ? '.zip' : '.tar.gz'}`);\n\n getFile(downloadUrl, tempPath, (err) => {\n if (err) {\n removeIfExistsSync(tempPath);\n callback(new Error(`No prebuilt binary available for ${process.platform}-${process.arch}. Download: ${downloadUrl}. Error: ${err.message}`));\n return;\n }\n\n // Copy to cache for future use\n try {\n copyFileSync(tempPath, cachePath);\n } catch (_e) {\n // Cache write failed, continue anyway\n }\n\n extractAndInstall(tempPath, binDir, extractedBinaryName, (err) => {\n removeIfExistsSync(tempPath);\n if (err) return callback(err);\n\n // save binary version for upgrade checks\n fs.writeFileSync(nvuJsonPath, JSON.stringify({ binaryVersion: BINARY_VERSION }, null, 2), 'utf8');\n console.log('Binary installed successfully!');\n callback(null, true);\n });\n });\n};\n"],"names":["envPathKey","require","fs","safeRmSync","getFile","mkdirp","os","path","Queue","moduleRoot","root","__dirname","GITHUB_REPO","BINARY_VERSION","join","binaryVersion","isWindows","process","platform","test","env","OSTYPE","hasHomedir","homedir","home","storagePath","NVU_HOME","hasTmpdir","tmpdir","osShim","removeIfExistsSync","filePath","existsSync","unlinkSync","_e","moveOutOfWay","timestamp","Date","now","oldPath","renameSync","_e2","cleanupOldFiles","dir","entries","readdirSync","entry","includes","getArchiveBaseName","arch","platformMap","darwin","linux","win32","archMap","x64","arm64","amd64","platformName","archName","copyFileSync","src","dest","content","readFileSync","writeFileSync","module","exports","syncAllShims","binDir","ext","nvuSource","name","endsWith","shimPath","stat","statSync","isFile","chmodSync","atomicRename","callback","rename","err","code","copyErr","extractArchive","archivePath","Iterator","stream","createReadStream","pipe","createGunzip","iterator","links","forEach","type","unshift","push","create","callbacks","concurrency","_err","queue","index","length","defer","bind","await","destroy","extractAndInstall","destDir","binaryName","tempExtractDir","sync","extractedPath","Error","binaries","installError","i","tempDest","j","tempPath","renameError","doRename","finalDest","printInstructions","_nvuBinPath","console","log","pathKey","envPath","indexOf","installBinaries","options","archiveBaseName","extractedBinaryName","nvuJsonPath","force","nvuJson","JSON","parse","downloadUrl","cachePath","stringify","message"],"mappings":"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"}
|
|
@@ -9,7 +9,17 @@
|
|
|
9
9
|
* 2. Extract to temp directory
|
|
10
10
|
* 3. Atomic rename to final location
|
|
11
11
|
*/ const exit = require('exit-compat');
|
|
12
|
-
const
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const os = require('os');
|
|
14
|
+
const { installBinaries, printInstructions, syncAllShims } = require('./installBinaries.cjs');
|
|
15
|
+
const hasHomedir = typeof os.homedir === 'function';
|
|
16
|
+
function homedir() {
|
|
17
|
+
if (hasHomedir) return os.homedir();
|
|
18
|
+
const home = require('homedir-polyfill');
|
|
19
|
+
return home();
|
|
20
|
+
}
|
|
21
|
+
// Allow NVU_HOME override for testing
|
|
22
|
+
const storagePath = process.env.NVU_HOME || path.join(homedir(), '.nvu');
|
|
13
23
|
/**
|
|
14
24
|
* Main installation function
|
|
15
25
|
*/ function main() {
|
|
@@ -21,8 +31,13 @@ const { installBinaries, printInstructions } = require('./installBinaries.cjs');
|
|
|
21
31
|
return;
|
|
22
32
|
}
|
|
23
33
|
if (installed) {
|
|
34
|
+
// Sync all shims to the new binary version
|
|
35
|
+
const binDir = path.join(storagePath, 'bin');
|
|
36
|
+
syncAllShims(binDir);
|
|
24
37
|
printInstructions();
|
|
25
38
|
console.log('postinstall: Binary installed successfully!');
|
|
39
|
+
} else {
|
|
40
|
+
console.log('postinstall: Binaries already up to date.');
|
|
26
41
|
}
|
|
27
42
|
exit(0);
|
|
28
43
|
});
|
|
@@ -1 +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 exit = require('exit-compat');\nconst { installBinaries, printInstructions } = require('./installBinaries.cjs');\n\n/**\n * Main installation function\n */\nfunction main(): void {\n installBinaries({}, (err, installed) => {\n if (err) {\n console.log(`postinstall warning: Failed to install binary: ${err.message || err}`);\n console.log('You can still use nvu with explicit versions: nvu 18 npm test');\n exit(1);\n return;\n }\n\n if (installed) {\n printInstructions();\n console.log('postinstall: Binary installed successfully!');\n }\n exit(0);\n });\n}\n\nmain();\n"],"names":["exit","require","installBinaries","printInstructions","main","err","installed","console","log","message"],"mappings":"AAAA;;;;;;;;;;CAUC,GAED,MAAMA,OAAOC,QAAQ;AACrB,MAAM,
|
|
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 exit = require('exit-compat');\nconst path = require('path');\nconst os = require('os');\nconst { installBinaries, printInstructions, syncAllShims } = require('./installBinaries.cjs');\n\nconst hasHomedir = typeof os.homedir === 'function';\nfunction homedir(): string {\n if (hasHomedir) return os.homedir();\n const home = require('homedir-polyfill');\n return home();\n}\n\n// Allow NVU_HOME override for testing\nconst storagePath = process.env.NVU_HOME || path.join(homedir(), '.nvu');\n\n/**\n * Main installation function\n */\nfunction main(): void {\n installBinaries({}, (err, installed) => {\n if (err) {\n console.log(`postinstall warning: Failed to install binary: ${err.message || err}`);\n console.log('You can still use nvu with explicit versions: nvu 18 npm test');\n exit(1);\n return;\n }\n\n if (installed) {\n // Sync all shims to the new binary version\n const binDir = path.join(storagePath, 'bin');\n syncAllShims(binDir);\n\n printInstructions();\n console.log('postinstall: Binary installed successfully!');\n } else {\n console.log('postinstall: Binaries already up to date.');\n }\n exit(0);\n });\n}\n\nmain();\n"],"names":["exit","require","path","os","installBinaries","printInstructions","syncAllShims","hasHomedir","homedir","home","storagePath","process","env","NVU_HOME","join","main","err","installed","console","log","message","binDir"],"mappings":"AAAA;;;;;;;;;;CAUC,GAED,MAAMA,OAAOC,QAAQ;AACrB,MAAMC,OAAOD,QAAQ;AACrB,MAAME,KAAKF,QAAQ;AACnB,MAAM,EAAEG,eAAe,EAAEC,iBAAiB,EAAEC,YAAY,EAAE,GAAGL,QAAQ;AAErE,MAAMM,aAAa,OAAOJ,GAAGK,OAAO,KAAK;AACzC,SAASA;IACP,IAAID,YAAY,OAAOJ,GAAGK,OAAO;IACjC,MAAMC,OAAOR,QAAQ;IACrB,OAAOQ;AACT;AAEA,sCAAsC;AACtC,MAAMC,cAAcC,QAAQC,GAAG,CAACC,QAAQ,IAAIX,KAAKY,IAAI,CAACN,WAAW;AAEjE;;CAEC,GACD,SAASO;IACPX,gBAAgB,CAAC,GAAG,CAACY,KAAKC;QACxB,IAAID,KAAK;YACPE,QAAQC,GAAG,CAAC,CAAC,+CAA+C,EAAEH,IAAII,OAAO,IAAIJ,KAAK;YAClFE,QAAQC,GAAG,CAAC;YACZnB,KAAK;YACL;QACF;QAEA,IAAIiB,WAAW;YACb,2CAA2C;YAC3C,MAAMI,SAASnB,KAAKY,IAAI,CAACJ,aAAa;YACtCJ,aAAae;YAEbhB;YACAa,QAAQC,GAAG,CAAC;QACd,OAAO;YACLD,QAAQC,GAAG,CAAC;QACd;QACAnB,KAAK;IACP;AACF;AAEAe"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import exit from 'exit-compat';
|
|
2
2
|
import fs from 'fs';
|
|
3
|
+
import Module from 'module';
|
|
3
4
|
import path from 'path';
|
|
4
5
|
import { mkdirpSync } from '../compat.js';
|
|
5
6
|
import { storagePath } from '../constants.js';
|
|
6
7
|
import { findInstalledVersions } from '../lib/findInstalledVersions.js';
|
|
7
8
|
import loadNodeVersionInstall from '../lib/loadNodeVersionInstall.js';
|
|
9
|
+
const _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;
|
|
10
|
+
const { syncAllShims } = _require('../assets/installBinaries.cjs');
|
|
8
11
|
/**
|
|
9
12
|
* nvu default [version]
|
|
10
13
|
*
|
|
@@ -13,6 +16,7 @@ import loadNodeVersionInstall from '../lib/loadNodeVersionInstall.js';
|
|
|
13
16
|
*/ export default function defaultCmd(args) {
|
|
14
17
|
const defaultFilePath = path.join(storagePath, 'default');
|
|
15
18
|
const versionsPath = path.join(storagePath, 'installed');
|
|
19
|
+
const binDir = path.join(storagePath, 'bin');
|
|
16
20
|
// If no version provided, display current default
|
|
17
21
|
if (args.length === 0) {
|
|
18
22
|
if (fs.existsSync(defaultFilePath)) {
|
|
@@ -26,6 +30,13 @@ import loadNodeVersionInstall from '../lib/loadNodeVersionInstall.js';
|
|
|
26
30
|
return;
|
|
27
31
|
}
|
|
28
32
|
const version = args[0].trim();
|
|
33
|
+
// Special case: "system" means use system Node (no installation needed)
|
|
34
|
+
if (version === 'system') {
|
|
35
|
+
fs.writeFileSync(defaultFilePath, 'system\n', 'utf8');
|
|
36
|
+
console.log('Default Node version set to: system');
|
|
37
|
+
exit(0);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
29
40
|
// Validate version format (basic check, indexOf for Node 0.8+ compat)
|
|
30
41
|
if (!version || version.indexOf('-') === 0) {
|
|
31
42
|
console.log('Usage: nvu default <version>');
|
|
@@ -41,16 +52,16 @@ import loadNodeVersionInstall from '../lib/loadNodeVersionInstall.js';
|
|
|
41
52
|
const matches = findInstalledVersions(versionsPath, version);
|
|
42
53
|
if (matches.length > 0) {
|
|
43
54
|
// Version is installed - resolve to exact and set default
|
|
44
|
-
setDefaultToExact(defaultFilePath, matches);
|
|
55
|
+
setDefaultToExact(defaultFilePath, matches, binDir);
|
|
45
56
|
} else {
|
|
46
57
|
// Version not installed - auto-install it
|
|
47
58
|
console.log(`Node ${version} is not installed. Installing...`);
|
|
48
|
-
autoInstallAndSetDefault(version, versionsPath, defaultFilePath);
|
|
59
|
+
autoInstallAndSetDefault(version, versionsPath, defaultFilePath, binDir);
|
|
49
60
|
}
|
|
50
61
|
}
|
|
51
62
|
/**
|
|
52
63
|
* Set the default to the highest matching installed version
|
|
53
|
-
*/ function setDefaultToExact(defaultFilePath, matches) {
|
|
64
|
+
*/ function setDefaultToExact(defaultFilePath, matches, binDir) {
|
|
54
65
|
// matches are sorted by findInstalledVersions, take the last (highest)
|
|
55
66
|
let exactVersion = matches[matches.length - 1];
|
|
56
67
|
// Ensure it has v prefix for consistency
|
|
@@ -60,11 +71,13 @@ import loadNodeVersionInstall from '../lib/loadNodeVersionInstall.js';
|
|
|
60
71
|
// Write the exact version
|
|
61
72
|
fs.writeFileSync(defaultFilePath, `${exactVersion}\n`, 'utf8');
|
|
62
73
|
console.log(`Default Node version set to: ${exactVersion}`);
|
|
74
|
+
// Sync all shims (first time setup)
|
|
75
|
+
syncAllShimsIfNeeded(binDir);
|
|
63
76
|
exit(0);
|
|
64
77
|
}
|
|
65
78
|
/**
|
|
66
79
|
* Auto-install the version and then set it as default
|
|
67
|
-
*/ function autoInstallAndSetDefault(version, versionsPath, defaultFilePath) {
|
|
80
|
+
*/ function autoInstallAndSetDefault(version, versionsPath, defaultFilePath, binDir) {
|
|
68
81
|
loadNodeVersionInstall((err, nodeVersionInstall)=>{
|
|
69
82
|
if (err || !nodeVersionInstall) {
|
|
70
83
|
console.error('Failed to load node-version-install:', err ? err.message : 'Module not available');
|
|
@@ -101,7 +114,20 @@ import loadNodeVersionInstall from '../lib/loadNodeVersionInstall.js';
|
|
|
101
114
|
fs.writeFileSync(defaultFilePath, `${installedVersion}\n`, 'utf8');
|
|
102
115
|
console.log(`Node ${installedVersion} installed successfully.`);
|
|
103
116
|
console.log(`Default Node version set to: ${installedVersion}`);
|
|
117
|
+
// Sync all shims (first time setup)
|
|
118
|
+
syncAllShimsIfNeeded(binDir);
|
|
104
119
|
exit(0);
|
|
105
120
|
});
|
|
106
121
|
});
|
|
107
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Sync all shims if this is the first time setting a default
|
|
125
|
+
* First time is detected by checking if ~/.nvu/bin/nvu exists
|
|
126
|
+
*/ function syncAllShimsIfNeeded(binDir) {
|
|
127
|
+
const isWindows = process.platform === 'win32' || /^(msys|cygwin)$/.test(process.env.OSTYPE);
|
|
128
|
+
const nvuPath = path.join(binDir, `nvu${isWindows ? '.exe' : ''}`);
|
|
129
|
+
// Only sync if nvu binary exists (first time setup)
|
|
130
|
+
if (fs.existsSync(nvuPath)) {
|
|
131
|
+
syncAllShims(binDir);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/commands/default.ts"],"sourcesContent":["import exit from 'exit-compat';\nimport fs from 'fs';\nimport path from 'path';\nimport { mkdirpSync } from '../compat.ts';\nimport { storagePath } from '../constants.ts';\nimport { findInstalledVersions } from '../lib/findInstalledVersions.ts';\nimport loadNodeVersionInstall from '../lib/loadNodeVersionInstall.ts';\n\n/**\n * nvu default [version]\n *\n * Set or display the global default Node version.\n * This is used when no .nvmrc or .nvurc is found in the project.\n */\nexport default function defaultCmd(args: string[]): void {\n const defaultFilePath = path.join(storagePath, 'default');\n const versionsPath = path.join(storagePath, 'installed');\n\n // If no version provided, display current default\n if (args.length === 0) {\n if (fs.existsSync(defaultFilePath)) {\n const currentVersion = fs.readFileSync(defaultFilePath, 'utf8').trim();\n console.log(`Current default: ${currentVersion}`);\n } else {\n console.log('No default version set.');\n console.log('Usage: nvu default <version>');\n }\n exit(0);\n return;\n }\n\n const version = args[0].trim();\n\n // Validate version format (basic check, indexOf for Node 0.8+ compat)\n if (!version || version.indexOf('-') === 0) {\n console.log('Usage: nvu default <version>');\n console.log('Example: nvu default 20');\n exit(1);\n return;\n }\n\n // Ensure storage directory exists\n if (!fs.existsSync(storagePath)) {\n mkdirpSync(storagePath);\n }\n\n // Check if any installed versions match\n const matches = findInstalledVersions(versionsPath, version);\n\n if (matches.length > 0) {\n // Version is installed - resolve to exact and set default\n setDefaultToExact(defaultFilePath, matches);\n } else {\n // Version not installed - auto-install it\n console.log(`Node ${version} is not installed. Installing...`);\n autoInstallAndSetDefault(version, versionsPath, defaultFilePath);\n }\n}\n\n/**\n * Set the default to the highest matching installed version\n */\nfunction setDefaultToExact(defaultFilePath: string, matches: string[]): void {\n // matches are sorted by findInstalledVersions, take the last (highest)\n let exactVersion = matches[matches.length - 1];\n\n // Ensure it has v prefix for consistency\n if (exactVersion.indexOf('v') !== 0) {\n exactVersion = `v${exactVersion}`;\n }\n\n // Write the exact version\n fs.writeFileSync(defaultFilePath, `${exactVersion}\\n`, 'utf8');\n console.log(`Default Node version set to: ${exactVersion}`);\n\n exit(0);\n}\n\n/**\n * Auto-install the version and then set it as default\n */\nfunction autoInstallAndSetDefault(version: string, versionsPath: string, defaultFilePath: string): void {\n loadNodeVersionInstall((err, nodeVersionInstall) => {\n if (err || !nodeVersionInstall) {\n console.error('Failed to load node-version-install:', err ? err.message : 'Module not available');\n exit(1);\n return;\n }\n\n nodeVersionInstall(\n version,\n {\n installPath: versionsPath,\n },\n (installErr, results) => {\n if (installErr) {\n console.error(`Failed to install Node ${version}:`, installErr.message);\n exit(1);\n return;\n }\n\n // Get the installed version from results\n let installedVersion: string;\n if (results && results.length > 0) {\n installedVersion = results[0].version;\n } else {\n // Fallback: re-scan installed versions\n const matches = findInstalledVersions(versionsPath, version);\n if (matches.length === 0) {\n console.error('Installation completed but version not found');\n exit(1);\n return;\n }\n installedVersion = matches[matches.length - 1];\n }\n\n // Ensure it has v prefix for consistency\n if (installedVersion.indexOf('v') !== 0) {\n installedVersion = `v${installedVersion}`;\n }\n\n // Write the exact version\n fs.writeFileSync(defaultFilePath, `${installedVersion}\\n`, 'utf8');\n console.log(`Node ${installedVersion} installed successfully.`);\n console.log(`Default Node version set to: ${installedVersion}`);\n\n exit(0);\n }\n );\n });\n}\n"],"names":["exit","fs","path","mkdirpSync","storagePath","findInstalledVersions","loadNodeVersionInstall","defaultCmd","args","defaultFilePath","join","versionsPath","length","existsSync","currentVersion","readFileSync","trim","console","log","version","indexOf","matches","setDefaultToExact","autoInstallAndSetDefault","exactVersion","
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/commands/default.ts"],"sourcesContent":["import exit from 'exit-compat';\nimport fs from 'fs';\nimport Module from 'module';\nimport path from 'path';\nimport { mkdirpSync } from '../compat.ts';\nimport { storagePath } from '../constants.ts';\nimport { findInstalledVersions } from '../lib/findInstalledVersions.ts';\nimport loadNodeVersionInstall from '../lib/loadNodeVersionInstall.ts';\n\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\nconst { syncAllShims } = _require('../assets/installBinaries.cjs');\n\n/**\n * nvu default [version]\n *\n * Set or display the global default Node version.\n * This is used when no .nvmrc or .nvurc is found in the project.\n */\nexport default function defaultCmd(args: string[]): void {\n const defaultFilePath = path.join(storagePath, 'default');\n const versionsPath = path.join(storagePath, 'installed');\n const binDir = path.join(storagePath, 'bin');\n\n // If no version provided, display current default\n if (args.length === 0) {\n if (fs.existsSync(defaultFilePath)) {\n const currentVersion = fs.readFileSync(defaultFilePath, 'utf8').trim();\n console.log(`Current default: ${currentVersion}`);\n } else {\n console.log('No default version set.');\n console.log('Usage: nvu default <version>');\n }\n exit(0);\n return;\n }\n\n const version = args[0].trim();\n\n // Special case: \"system\" means use system Node (no installation needed)\n if (version === 'system') {\n fs.writeFileSync(defaultFilePath, 'system\\n', 'utf8');\n console.log('Default Node version set to: system');\n exit(0);\n return;\n }\n\n // Validate version format (basic check, indexOf for Node 0.8+ compat)\n if (!version || version.indexOf('-') === 0) {\n console.log('Usage: nvu default <version>');\n console.log('Example: nvu default 20');\n exit(1);\n return;\n }\n\n // Ensure storage directory exists\n if (!fs.existsSync(storagePath)) {\n mkdirpSync(storagePath);\n }\n\n // Check if any installed versions match\n const matches = findInstalledVersions(versionsPath, version);\n\n if (matches.length > 0) {\n // Version is installed - resolve to exact and set default\n setDefaultToExact(defaultFilePath, matches, binDir);\n } else {\n // Version not installed - auto-install it\n console.log(`Node ${version} is not installed. Installing...`);\n autoInstallAndSetDefault(version, versionsPath, defaultFilePath, binDir);\n }\n}\n\n/**\n * Set the default to the highest matching installed version\n */\nfunction setDefaultToExact(defaultFilePath: string, matches: string[], binDir: string): void {\n // matches are sorted by findInstalledVersions, take the last (highest)\n let exactVersion = matches[matches.length - 1];\n\n // Ensure it has v prefix for consistency\n if (exactVersion.indexOf('v') !== 0) {\n exactVersion = `v${exactVersion}`;\n }\n\n // Write the exact version\n fs.writeFileSync(defaultFilePath, `${exactVersion}\\n`, 'utf8');\n console.log(`Default Node version set to: ${exactVersion}`);\n\n // Sync all shims (first time setup)\n syncAllShimsIfNeeded(binDir);\n\n exit(0);\n}\n\n/**\n * Auto-install the version and then set it as default\n */\nfunction autoInstallAndSetDefault(version: string, versionsPath: string, defaultFilePath: string, binDir: string): void {\n loadNodeVersionInstall((err, nodeVersionInstall) => {\n if (err || !nodeVersionInstall) {\n console.error('Failed to load node-version-install:', err ? err.message : 'Module not available');\n exit(1);\n return;\n }\n\n nodeVersionInstall(\n version,\n {\n installPath: versionsPath,\n },\n (installErr, results) => {\n if (installErr) {\n console.error(`Failed to install Node ${version}:`, installErr.message);\n exit(1);\n return;\n }\n\n // Get the installed version from results\n let installedVersion: string;\n if (results && results.length > 0) {\n installedVersion = results[0].version;\n } else {\n // Fallback: re-scan installed versions\n const matches = findInstalledVersions(versionsPath, version);\n if (matches.length === 0) {\n console.error('Installation completed but version not found');\n exit(1);\n return;\n }\n installedVersion = matches[matches.length - 1];\n }\n\n // Ensure it has v prefix for consistency\n if (installedVersion.indexOf('v') !== 0) {\n installedVersion = `v${installedVersion}`;\n }\n\n // Write the exact version\n fs.writeFileSync(defaultFilePath, `${installedVersion}\\n`, 'utf8');\n console.log(`Node ${installedVersion} installed successfully.`);\n console.log(`Default Node version set to: ${installedVersion}`);\n\n // Sync all shims (first time setup)\n syncAllShimsIfNeeded(binDir);\n\n exit(0);\n }\n );\n });\n}\n\n/**\n * Sync all shims if this is the first time setting a default\n * First time is detected by checking if ~/.nvu/bin/nvu exists\n */\nfunction syncAllShimsIfNeeded(binDir: string): void {\n const isWindows = process.platform === 'win32' || /^(msys|cygwin)$/.test(process.env.OSTYPE);\n const nvuPath = path.join(binDir, `nvu${isWindows ? '.exe' : ''}`);\n\n // Only sync if nvu binary exists (first time setup)\n if (fs.existsSync(nvuPath)) {\n syncAllShims(binDir);\n }\n}\n"],"names":["exit","fs","Module","path","mkdirpSync","storagePath","findInstalledVersions","loadNodeVersionInstall","_require","require","createRequire","url","syncAllShims","defaultCmd","args","defaultFilePath","join","versionsPath","binDir","length","existsSync","currentVersion","readFileSync","trim","console","log","version","writeFileSync","indexOf","matches","setDefaultToExact","autoInstallAndSetDefault","exactVersion","syncAllShimsIfNeeded","err","nodeVersionInstall","error","message","installPath","installErr","results","installedVersion","isWindows","process","platform","test","env","OSTYPE","nvuPath"],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* nvu setup
|
|
2
|
+
* nvu setup
|
|
3
3
|
*
|
|
4
4
|
* Install/reinstall nvu binaries to ~/.nvu/bin
|
|
5
|
-
* With --shims: create shims for existing global packages
|
|
6
5
|
*/
|
|
7
|
-
export default function setupCmd(
|
|
6
|
+
export default function setupCmd(_args: string[]): void;
|
|
@@ -1,100 +1,25 @@
|
|
|
1
1
|
import exit from 'exit-compat';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import getopts from 'getopts-compat';
|
|
4
2
|
import Module from 'module';
|
|
5
3
|
import path from 'path';
|
|
6
|
-
import { readdirWithTypes } from '../compat.js';
|
|
7
4
|
import { storagePath } from '../constants.js';
|
|
8
|
-
import { findInstalledVersions } from '../lib/findInstalledVersions.js';
|
|
9
5
|
const _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;
|
|
10
|
-
const { installBinaries, printInstructions } = _require('../assets/installBinaries.cjs');
|
|
6
|
+
const { installBinaries, printInstructions, syncAllShims } = _require('../assets/installBinaries.cjs');
|
|
11
7
|
/**
|
|
12
|
-
* nvu setup
|
|
8
|
+
* nvu setup
|
|
13
9
|
*
|
|
14
10
|
* Install/reinstall nvu binaries to ~/.nvu/bin
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const options = getopts(args, {
|
|
18
|
-
boolean: [
|
|
19
|
-
'force'
|
|
20
|
-
]
|
|
21
|
-
});
|
|
22
|
-
installBinaries(options, (err, installed)=>{
|
|
11
|
+
*/ export default function setupCmd(_args) {
|
|
12
|
+
installBinaries({}, (err, installed)=>{
|
|
23
13
|
if (err) {
|
|
24
14
|
console.error(`Setup failed: ${err.message || err}`);
|
|
25
15
|
exit(1);
|
|
26
16
|
return;
|
|
27
17
|
}
|
|
18
|
+
// Sync all shims to the new binary
|
|
19
|
+
const binDir = path.join(storagePath, 'bin');
|
|
20
|
+
syncAllShims(binDir);
|
|
28
21
|
printInstructions();
|
|
29
|
-
if (!installed) console.log('Use --force to reinstall.');
|
|
30
|
-
|
|
31
|
-
const binDir = path.join(storagePath, 'bin');
|
|
32
|
-
createShimsForGlobalPackages(binDir);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
22
|
+
if (!installed) console.log('Use --force to reinstall binaries.');
|
|
23
|
+
exit(0);
|
|
35
24
|
});
|
|
36
25
|
}
|
|
37
|
-
/**
|
|
38
|
-
* Create shims for all global packages in the default Node version
|
|
39
|
-
*/ function createShimsForGlobalPackages(binDir) {
|
|
40
|
-
// Read default version
|
|
41
|
-
const defaultPath = path.join(storagePath, 'default');
|
|
42
|
-
if (!fs.existsSync(defaultPath)) {
|
|
43
|
-
console.log('No default Node version set.');
|
|
44
|
-
console.log('Set one with: nvu default <version>');
|
|
45
|
-
exit(1);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
const defaultVersion = fs.readFileSync(defaultPath, 'utf8').trim();
|
|
49
|
-
const versionsDir = path.join(storagePath, 'installed');
|
|
50
|
-
// Resolve to exact version
|
|
51
|
-
const matches = findInstalledVersions(versionsDir, defaultVersion);
|
|
52
|
-
if (matches.length === 0) {
|
|
53
|
-
console.log(`Default version ${defaultVersion} is not installed.`);
|
|
54
|
-
exit(1);
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
const resolvedVersion = matches[matches.length - 1];
|
|
58
|
-
const nodeBinDir = path.join(versionsDir, resolvedVersion, 'bin');
|
|
59
|
-
if (!fs.existsSync(nodeBinDir)) {
|
|
60
|
-
console.log(`No bin directory found for ${resolvedVersion}`);
|
|
61
|
-
exit(1);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
// Get the node shim to copy from
|
|
65
|
-
const nodeShim = path.join(binDir, 'node');
|
|
66
|
-
if (!fs.existsSync(nodeShim)) {
|
|
67
|
-
console.log('Node shim not found. Run: nvu setup');
|
|
68
|
-
exit(1);
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
// Scan binaries in Node's bin directory
|
|
72
|
-
const entries = readdirWithTypes(nodeBinDir);
|
|
73
|
-
let created = 0;
|
|
74
|
-
let skipped = 0;
|
|
75
|
-
for(let i = 0; i < entries.length; i++){
|
|
76
|
-
const entry = entries[i];
|
|
77
|
-
const name = entry.name;
|
|
78
|
-
// Skip our routing shims (node/npm/npx) - don't overwrite them
|
|
79
|
-
if (name === 'node' || name === 'npm' || name === 'npx') continue;
|
|
80
|
-
const shimPath = path.join(binDir, name);
|
|
81
|
-
// Skip if shim already exists
|
|
82
|
-
if (fs.existsSync(shimPath)) {
|
|
83
|
-
skipped++;
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
// Copy the node shim
|
|
87
|
-
try {
|
|
88
|
-
const shimContent = fs.readFileSync(nodeShim);
|
|
89
|
-
fs.writeFileSync(shimPath, shimContent);
|
|
90
|
-
fs.chmodSync(shimPath, 493); // 0755
|
|
91
|
-
console.log(`Created shim: ${name}`);
|
|
92
|
-
created++;
|
|
93
|
-
} catch (err) {
|
|
94
|
-
console.error(`Failed to create shim for ${name}: ${err.message}`);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
console.log('');
|
|
98
|
-
console.log(`Done. Created ${created} shims, skipped ${skipped} (already exists).`);
|
|
99
|
-
exit(0);
|
|
100
|
-
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/commands/setup.ts"],"sourcesContent":["import exit from 'exit-compat';\nimport
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/commands/setup.ts"],"sourcesContent":["import exit from 'exit-compat';\nimport Module from 'module';\nimport path from 'path';\nimport { storagePath } from '../constants.ts';\n\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\nconst { installBinaries, printInstructions, syncAllShims } = _require('../assets/installBinaries.cjs');\n\n/**\n * nvu setup\n *\n * Install/reinstall nvu binaries to ~/.nvu/bin\n */\nexport default function setupCmd(_args: string[]): void {\n installBinaries({}, (err, installed) => {\n if (err) {\n console.error(`Setup failed: ${err.message || err}`);\n exit(1);\n return;\n }\n\n // Sync all shims to the new binary\n const binDir = path.join(storagePath, 'bin');\n syncAllShims(binDir);\n\n printInstructions();\n if (!installed) console.log('Use --force to reinstall binaries.');\n\n exit(0);\n });\n}\n"],"names":["exit","Module","path","storagePath","_require","require","createRequire","url","installBinaries","printInstructions","syncAllShims","setupCmd","_args","err","installed","console","error","message","binDir","join","log"],"mappings":"AAAA,OAAOA,UAAU,cAAc;AAC/B,OAAOC,YAAY,SAAS;AAC5B,OAAOC,UAAU,OAAO;AACxB,SAASC,WAAW,QAAQ,kBAAkB;AAE9C,MAAMC,WAAW,OAAOC,YAAY,cAAcJ,OAAOK,aAAa,CAAC,YAAYC,GAAG,IAAIF;AAC1F,MAAM,EAAEG,eAAe,EAAEC,iBAAiB,EAAEC,YAAY,EAAE,GAAGN,SAAS;AAEtE;;;;CAIC,GACD,eAAe,SAASO,SAASC,KAAe;IAC9CJ,gBAAgB,CAAC,GAAG,CAACK,KAAKC;QACxB,IAAID,KAAK;YACPE,QAAQC,KAAK,CAAC,CAAC,cAAc,EAAEH,IAAII,OAAO,IAAIJ,KAAK;YACnDb,KAAK;YACL;QACF;QAEA,mCAAmC;QACnC,MAAMkB,SAAShB,KAAKiB,IAAI,CAAChB,aAAa;QACtCO,aAAaQ;QAEbT;QACA,IAAI,CAACK,WAAWC,QAAQK,GAAG,CAAC;QAE5BpB,KAAK;IACP;AACF"}
|
package/dist/esm/compat.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/compat.ts"],"sourcesContent":["/**\n * Compatibility Layer for Node.js 0.8+\n * Local to this package - contains only needed functions.\n */\nimport fs from 'fs';\nimport _Module from 'module';\nimport os from 'os';\nimport path from 'path';\n\n// Use existing require in CJS, or createRequire in ESM (Node 12.2+)\nconst _require = typeof require === 'undefined' ? _Module.createRequire(import.meta.url) : require;\n\nexport function homedir(): string {\n return typeof os.homedir === 'function' ? os.homedir() : require('homedir-polyfill')();\n}\n\nexport function tmpdir(): string {\n return typeof os.tmpdir === 'function' ? os.tmpdir() : require('os-shim').tmpdir();\n}\n\n/**\n * String.prototype.endsWith wrapper for Node.js 0.8+\n * - Uses native endsWith on Node 4.0+ / ES2015+\n * - Falls back to lastIndexOf on Node 0.8-3.x\n */\nconst hasEndsWith = typeof String.prototype.endsWith === 'function';\
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/compat.ts"],"sourcesContent":["/**\n * Compatibility Layer for Node.js 0.8+\n * Local to this package - contains only needed functions.\n */\nimport fs from 'fs';\nimport _Module from 'module';\nimport os from 'os';\nimport path from 'path';\n\n// Use existing require in CJS, or createRequire in ESM (Node 12.2+)\nconst _require = typeof require === 'undefined' ? _Module.createRequire(import.meta.url) : require;\n\nexport function homedir(): string {\n return typeof os.homedir === 'function' ? os.homedir() : require('homedir-polyfill')();\n}\n\nexport function tmpdir(): string {\n return typeof os.tmpdir === 'function' ? os.tmpdir() : require('os-shim').tmpdir();\n}\n\n/**\n * String.prototype.endsWith wrapper for Node.js 0.8+\n * - Uses native endsWith on Node 4.0+ / ES2015+\n * - Falls back to lastIndexOf on Node 0.8-3.x\n */\nconst hasEndsWith = typeof String.prototype.endsWith === 'function';\nexport function stringEndsWith(str: string, search: string, position?: number): boolean {\n if (hasEndsWith) {\n return str.endsWith(search, position);\n }\n const len = position === undefined ? str.length : position;\n return str.lastIndexOf(search) === len - search.length;\n}\n\n/**\n * Recursive mkdir for Node.js 0.8+\n */\nexport function mkdirpSync(dir: string): void {\n const mkdirp = _require('mkdirp-classic');\n mkdirp.sync(dir);\n}\n\n/**\n * Recursive rm for Node.js 0.8+\n */\nexport function rmSync(dir: string): void {\n const safeRmSync = _require('fs-remove-compat').safeRmSync;\n safeRmSync(dir);\n}\n\n/**\n * Read directory entries with types for Node.js 0.8+\n * Returns array of {name, isDirectory()}\n */\nexport interface DirEntry {\n name: string;\n isDirectory(): boolean;\n}\n\nexport function readdirWithTypes(dir: string): DirEntry[] {\n const names = fs.readdirSync(dir);\n return names.map((name) => {\n const fullPath = path.join(dir, name);\n let stat: fs.Stats;\n try {\n stat = fs.statSync(fullPath);\n } catch (_e) {\n // If stat fails, treat as non-directory\n return { name: name, isDirectory: () => false };\n }\n return {\n name: name,\n isDirectory: () => stat.isDirectory(),\n };\n });\n}\n"],"names":["fs","_Module","os","path","_require","require","createRequire","url","homedir","tmpdir","hasEndsWith","String","prototype","endsWith","stringEndsWith","str","search","position","len","undefined","length","lastIndexOf","mkdirpSync","dir","mkdirp","sync","rmSync","safeRmSync","readdirWithTypes","names","readdirSync","map","name","fullPath","join","stat","statSync","_e","isDirectory"],"mappings":"AAAA;;;CAGC,GACD,OAAOA,QAAQ,KAAK;AACpB,OAAOC,aAAa,SAAS;AAC7B,OAAOC,QAAQ,KAAK;AACpB,OAAOC,UAAU,OAAO;AAExB,oEAAoE;AACpE,MAAMC,WAAW,OAAOC,YAAY,cAAcJ,QAAQK,aAAa,CAAC,YAAYC,GAAG,IAAIF;AAE3F,OAAO,SAASG;IACd,OAAO,OAAON,GAAGM,OAAO,KAAK,aAAaN,GAAGM,OAAO,KAAKH,QAAQ;AACnE;AAEA,OAAO,SAASI;IACd,OAAO,OAAOP,GAAGO,MAAM,KAAK,aAAaP,GAAGO,MAAM,KAAKJ,QAAQ,WAAWI,MAAM;AAClF;AAEA;;;;CAIC,GACD,MAAMC,cAAc,OAAOC,OAAOC,SAAS,CAACC,QAAQ,KAAK;AACzD,OAAO,SAASC,eAAeC,GAAW,EAAEC,MAAc,EAAEC,QAAiB;IAC3E,IAAIP,aAAa;QACf,OAAOK,IAAIF,QAAQ,CAACG,QAAQC;IAC9B;IACA,MAAMC,MAAMD,aAAaE,YAAYJ,IAAIK,MAAM,GAAGH;IAClD,OAAOF,IAAIM,WAAW,CAACL,YAAYE,MAAMF,OAAOI,MAAM;AACxD;AAEA;;CAEC,GACD,OAAO,SAASE,WAAWC,GAAW;IACpC,MAAMC,SAASpB,SAAS;IACxBoB,OAAOC,IAAI,CAACF;AACd;AAEA;;CAEC,GACD,OAAO,SAASG,OAAOH,GAAW;IAChC,MAAMI,aAAavB,SAAS,oBAAoBuB,UAAU;IAC1DA,WAAWJ;AACb;AAWA,OAAO,SAASK,iBAAiBL,GAAW;IAC1C,MAAMM,QAAQ7B,GAAG8B,WAAW,CAACP;IAC7B,OAAOM,MAAME,GAAG,CAAC,CAACC;QAChB,MAAMC,WAAW9B,KAAK+B,IAAI,CAACX,KAAKS;QAChC,IAAIG;QACJ,IAAI;YACFA,OAAOnC,GAAGoC,QAAQ,CAACH;QACrB,EAAE,OAAOI,IAAI;YACX,wCAAwC;YACxC,OAAO;gBAAEL,MAAMA;gBAAMM,aAAa,IAAM;YAAM;QAChD;QACA,OAAO;YACLN,MAAMA;YACNM,aAAa,IAAMH,KAAKG,WAAW;QACrC;IACF;AACF"}
|