power-nvm.psm1
function Add-DirToPath($Path, [Switch] $Permanent) { Remove-DirFromPath $Path $newPath = @($Path) + ($env:Path -split ";"); $newPath = $newPath -join ";"; $env:Path = $newPath; if ($Permanent) { [Environment]::SetEnvironmentVariable('Path', $newPath, [EnvironmentVariableTarget]::Machine); } } function Add-NodeDirToPath() { Remove-NodeDirFromPath Add-DirToPath $env:NODE_DIR -Permanent } function Get-NodeVersionsDir() { $dir = Join-Path $env:NODE_DIR "versions"; if (!(Test-Path $dir)) { New-Item $dir -Type Directory } return $dir; } function Get-YesNo($Question) { do { $answer = Read-Host "$Question (Y/n)" } while (($answer -ne "y") -and ($answer -ne "n")); return $answer -eq "y"; } function Remove-DirFromPath($Path, [Switch] $Permanent) { $newPath = ($env:Path -split ";") | Where-Object { $_ -ne "$Path\" -and $_ -ne $Path } $env:PathBackup = $env:Path; $env:Path = $newPath -join ";"; if ($Permanent) { [Environment]::SetEnvironmentVariable('Path', $newPath, [EnvironmentVariableTarget]::Machine); } } function Remove-NodeDirFromPath() { if (!$env:NODE_DIR) { return; } Remove-DirFromPath $env:NODE_DIR -Permanent } <# .Synopsis Lists all installed node versions from this module. .Description Lists all node versions downloaded into node main dir under versions folder. .Parameter $Filter Node version to filter. .Example nvm ls .Example nvm ls 8 .Example nvm ls 8.4 .Example nvm ls 8.4.0 .Example nvm ls v8.4.0 .Example nvm ls v8 #> function Get-InstalledNode( [string] [ValidatePattern('^(v?\d{1,2}([.]\d+){0,2})|v$')] $Filter ) { $Filter = "v" + $Filter.ToString().Replace("v", ""); $dir = Get-NodeVersionsDir; Get-ChildItem $dir ` | Where-Object { $_.Name -like "$Filter*" } ` | Sort-Object -Property Name -Descending ` | Select-Object -Property @{name="Version"; expression={ $_.Name }} } <# .Synopsis List available node versions to download .Description Retrieves information from node dist index.json file listing available node versions to install. .Parameter $Filter Node version to filter. .Example nvm ls-remote .Example nvm ls-remote 8 .Example nvm ls-remote 8.4 .Example nvm ls-remote 8.4.0 .Example nvm ls-remote v8.4.0 .Example nvm ls-remote v8 #> function Get-NodeVersions( [string] [ValidatePattern('^v?\d{1,2}([.]\d+){0,2}$')] $Filter ) { $versions = Invoke-WebRequest -Uri https://nodejs.org/dist/index.json | ConvertFrom-Json $versions | Where-Object { $_.version.Contains($Filter) } | Select-Object -Property version,npm,date } <# .Synopsis Install node in versions folder under node main dir .Description Downloads node zip file and extracts to node main dir under versions folder. Then sets the path (of the current session) to the extracted folder. .Parameter $Version Node version to install. .Example nvm install latest .Example nvm install 8 .Example nvm install 8.4 .Example nvm install 8.4.0 .Example nvm install v8.4.0 .Example nvm install v8 #> function Install-Node( [string] [Parameter(mandatory=$true)] [ValidatePattern('^(v?\d{1,2}([.]\d+){0,2})|latest$')] $Version ) { $versions = Invoke-WebRequest -Uri https://nodejs.org/dist/index.json | ConvertFrom-Json; if ($Version -eq "latest") { $node = $versions | Select-Object -First 1 } else { $Version = "v" + $Version.ToString().Replace("v", ""); $node = $versions | Where-Object { $_.version.StartsWith($Version) } | Select-Object -First 1 } Write-Host "Installing..." $node | Select-Object -Property version,npm,v8,date | Format-List $versionToInstall = $node.version; $versionTag = $( if ([Environment]::Is64BitOperatingSystem) { "x64" } else { "x86" } ); $downloadUrl = "https://nodejs.org/dist/$versionToInstall/node-$versionToInstall-win-$versionTag.zip"; $dest = (Join-Path $env:TEMP "node-${versionToInstall}.zip"); Invoke-WebRequest $downloadUrl -OutFile $dest; $versionsDir = Get-NodeVersionsDir; try { 7z x $dest -o"$versionsDir" -r -aoa } catch { Expand-Archive $zip -DestinationPath "$versionsDir" -Force } $folder = Get-ChildItem $versionsDir | Where-Object { $_.Name -match "node-$versionToInstall" } $targetDir = (Join-Path $folder[0].Parent.FullName $versionToInstall); if (Test-Path $targetDir) { Remove-Item -Force -Recurse $targetDir; } Move-Item $folder[0].FullName $targetDir; } <# .Synopsis Copy files to main node dir .Description Copy the node version files to node dir making it the default installation. .Example nvm default latest .Example nvm default 8 .Example nvm default 8.4 .Example nvm default 8.4.0 .Example nvm default v8.4.0 .Example nvm default v8 #> function Set-NodeDefault( [string] [Parameter(mandatory=$true)] [ValidatePattern('^(v?\d{1,2}([.]\d+){0,2})|latest$')] $Version ) { $versionsDir = Get-NodeVersionsDir; if ($Version -eq "latest") { $versionToInstall = (Get-InstalledNode | Select-Object -First 1).Version; } else { $versionToInstall = (Get-InstalledNode $Version | Select-Object -First 1).Version; } $pathToInstall = (Join-Path $versionsDir $versionToInstall); Get-ChildItem $pathToInstall | ForEach-Object { Copy-Item $_.FullName $env:NODE_DIR -Recurse -Force } } <# .Synopsis Sets the dir where node is going to be installed .Description Sets the dir where node is going to be installed and versions downloaded to. .Parameter $Path A valid directory path, if it doesn't exist then it asks to create a new dir. .Example nvm setdir "C:\Program Files\nodejs" #> function Set-NodeDir( [string] [ValidateScript({ !(Test-Path $_ -PathType Leaf) })] [Parameter(Mandatory=$true)] $Path ) { $dir = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path); if ($env:NODE_DIR) { Remove-NodeDirFromPath } if (!(Test-Path $dir -PathType Container)) { Write-Host "$dir not found" do { $shouldCreate = Read-Host "This path doesn't exists, would you like to create? (Y/n)" } while (($shouldCreate -ne "y") -and ($shouldCreate -ne "n")); if ($shouldCreate -eq "y") { New-Item $dir -ItemType Directory } else { return; } } $env:NODE_DIR = $Path; [Environment]::SetEnvironmentVariable('NODE_DIR', $Path, [EnvironmentVariableTarget]::User); Add-NodeDirToPath } <# .Synopsis Install node in versions folder under node main dir .Description Downloads node zip file and extracts to node main dir under versions folder. Then sets the path (of the current session) to the extracted folder. .Parameter $Version Node version to install. .Example nvm install latest .Example nvm install 8 .Example nvm install 8.4 .Example nvm install 8.4.0 .Example nvm install v8.4.0 .Example nvm install v8 #> function Uninstall-Node( [string] [Parameter(mandatory=$true)] [ValidatePattern('^(v?\d{1,2}([.]\d+){0,2})|latest$')] $Version ) { $versionsDir = Get-NodeVersionsDir; if ($Version -eq "latest") { $versionToUninstall = (Get-InstalledNode | Select-Object -First 1).Version; } else { $versionToUninstall = (Get-InstalledNode $Version | Select-Object -First 1).Version; } $pathToUninstall = (Join-Path $versionsDir $versionToUninstall); Remove-Item $pathToUninstall -Recurse -Force } <# .Synopsis Set the default node installation on node dir .Description Copy the node version files to node dir making it the default installation. .Parameter $Version Node version to use. .Example nvm use default .Example nvm use latest .Example nvm use 8 .Example nvm use 8.4 .Example nvm use 8.4.0 .Example nvm use v8.4.0 .Example nvm use v8 #> function Use-Node( [string] [ValidatePattern('^(v?\d{1,2}([.]\d+){0,2})|latest|default$')] $Version ) { if (!$Version) { # Look for .nvmrc $nvmrc = Join-Path $pwd ".nvmrc"; if (Test-Path $nvmrc -PathType Leaf) { $rcVersion = (Get-Content $nvmrc) -split "`n" | Select-Object -First 1; if ($rcVersion) { return Use-Node $rcVersion; } throw ".nvmrc is empty"; } throw ".nvmrc file not found"; } $versionsDir = Get-NodeVersionsDir; if ($Version -ne "default") { if ($Version -eq "latest") { $versionToInstall = (Get-InstalledNode | Select-Object -First 1).Version; } else { $versionToInstall = (Get-InstalledNode $Version | Select-Object -First 1).Version; } $pathToInstall = (Join-Path $versionsDir $versionToInstall); } # Node might not yet be installed try { $currentNodeVersion = node -v; Remove-DirFromPath (join-path $versionsDir $currentNodeVersion) } catch { } if ($pathToInstall) { Add-DirToPath $pathToInstall; } node -v npm -v } $commandMap = @{ default = "Set-NodeDefault"; install = "Install-Node"; ls = "Get-InstalledNode"; "ls-remote" = "Get-NodeVersions"; setdir = "Set-NodeDir"; uninstall = "Uninstall-Node"; use = "Use-Node"; }; <# .Synopsis Helps manage node installations. .Description Manage node installations. COMMANDS nvm default nvm install nvm ls nvm ls-remote nvm setdir nvm use Pass `-help` to get more info (ex: `nvm use -help`) #> function nvm( [ValidateSet( "default", "install", "ls-remote", "ls", "setdir", "uninstall", "use" )] $Command, [Switch] $Help ) { if (!(Test-Path $env:NODE_DIR)) { if ($Command -ne "setdir") { Write-Host "Node dir must be set first, nvm setdir <Path>" return; } } if ($Command) { if ($Help) { & Get-Help $commandMap.$Command @args Write-Host "COMMAND" Write-Host " nvm $Command" } else { & $commandMap.$Command @args } } else { Get-Help nvm } } Export-ModuleMember -Function nvm ## Install if (!$env:NODE_DIR) { $dir = Join-Path $env:ProgramFiles "nodejs"; $env:NODE_DIR = $dir; } Set-NodeDir $env:NODE_DIR |